github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/core/vm/election/electiondb.go (about)

     1  // Copyright 2019 The go-vnt Authors
     2  // This file is part of the go-vnt library.
     3  //
     4  // The go-vnt library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-vnt library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package election
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/binary"
    22  	"fmt"
    23  	"github.com/pkg/errors"
    24  	"github.com/vntchain/go-vnt/common"
    25  	inter "github.com/vntchain/go-vnt/core/vm/interface"
    26  	"github.com/vntchain/go-vnt/log"
    27  	"github.com/vntchain/go-vnt/rlp"
    28  	"math/big"
    29  	"reflect"
    30  )
    31  
    32  const (
    33  	VOTERPREFIX     = byte(0)
    34  	CANDIDATEPREFIX = byte(1)
    35  	STAKEPREFIX     = byte(2)
    36  	REWARDPREFIX    = byte(3)
    37  	ALLLOCKPREFIX   = byte(4)
    38  	PREFIXLENGTH    = 4 // key的结构为,4位表前缀,20位address,8位的value在struct中的位置
    39  )
    40  
    41  var KeyNotExistErr = errors.New("the key do not exist")
    42  
    43  type getFuncType func(key common.Hash) common.Hash
    44  type setFuncType func(key common.Hash, value common.Hash)
    45  
    46  func (ec electionContext) getVoter(addr common.Address) Voter {
    47  	return getVoterFrom(addr, ec.getFromDB)
    48  }
    49  
    50  func (ec electionContext) getCandidate(key common.Address) Candidate {
    51  	// var candidate Candidate
    52  	candidate := newCandidate()
    53  	var err error
    54  	if err := convertToStruct(CANDIDATEPREFIX, key, &candidate, ec.getFromDB); err == nil {
    55  		return candidate
    56  	}
    57  
    58  	log.Debug("Get Candidate From DB ", "addr", key.String(), "err", err)
    59  	return newCandidate()
    60  }
    61  
    62  func (ec electionContext) getStake(addr common.Address) Stake {
    63  	return getStakeFrom(addr, ec.getFromDB)
    64  }
    65  
    66  func (ec electionContext) updateLockAmount(value *big.Int, isAdd bool) error {
    67  	blockNum := ec.context.GetBlockNum()
    68  	if blockNum.Cmp(big.NewInt(ElectionStart)) <= 0 {
    69  		return nil
    70  	}
    71  	db := ec.context.GetStateDb()
    72  	re, err := getLock(db)
    73  	if err != nil && err != KeyNotExistErr {
    74  		log.Error("updateLockAmount, Get Lock Amount From DB ", "err", err)
    75  		return err
    76  	}
    77  	if isAdd {
    78  		re.Amount = big.NewInt(0).Add(re.Amount, value)
    79  	} else {
    80  		re.Amount = big.NewInt(0).Sub(re.Amount, value)
    81  	}
    82  
    83  	err = setLock(db, re)
    84  	if err != nil {
    85  		log.Error("updateLockAmount, Set Lock Amount To DB", "err", err, "value", value)
    86  		return err
    87  	}
    88  	return nil
    89  }
    90  
    91  func (ec electionContext) setVoter(voter Voter) error {
    92  	err := convertToKV(VOTERPREFIX, voter, ec.setToDB)
    93  	if err != nil {
    94  		log.Error("setVoter error", "err", err, "voter", voter)
    95  	}
    96  	return err
    97  }
    98  
    99  func (ec electionContext) setCandidate(candidate Candidate) error {
   100  	err := convertToKV(CANDIDATEPREFIX, candidate, ec.setToDB)
   101  	if err != nil {
   102  		log.Error("setCandidate error", "err", err, "candidate", candidate)
   103  	}
   104  	return err
   105  }
   106  
   107  func (ec electionContext) setStake(stake Stake) error {
   108  	err := convertToKV(STAKEPREFIX, stake, ec.setToDB)
   109  	if err != nil {
   110  		log.Error("setCandidate error", "err", err, "stake", stake)
   111  	}
   112  	return err
   113  }
   114  
   115  func (ec electionContext) setToDB(key common.Hash, value common.Hash) {
   116  	ec.context.GetStateDb().SetState(contractAddr, key, value)
   117  }
   118  
   119  func (ec electionContext) getFromDB(key common.Hash) common.Hash {
   120  	return ec.context.GetStateDb().GetState(contractAddr, key)
   121  }
   122  
   123  // getVoterFrom get a voter's information from a specific stateDB
   124  func getVoterFrom(addr common.Address, getFromDB getFuncType) Voter {
   125  	var voter Voter
   126  	var err error
   127  	if err = convertToStruct(VOTERPREFIX, addr, &voter, getFromDB); err == nil {
   128  		return voter
   129  	}
   130  
   131  	log.Debug("Get voter from DB ", "addr", addr.String(), "err", err)
   132  	return newVoter()
   133  }
   134  
   135  // getCandidateFrom get a candidate's information from a specific stateDB
   136  func getCandidateFrom(addr common.Address, getFromDB getFuncType) Candidate {
   137  	var (
   138  		ca  Candidate
   139  		err error
   140  	)
   141  	if err = convertToStruct(CANDIDATEPREFIX, addr, &ca, getFromDB); err == nil {
   142  		return ca
   143  	}
   144  
   145  	log.Debug("Get candidate from DB ", "addr", addr.String(), "err", err)
   146  	return newCandidate()
   147  }
   148  
   149  // getStakeFrom get a user's information from a specific stateDB
   150  func getStakeFrom(addr common.Address, getFromDB getFuncType) Stake {
   151  	var stake Stake
   152  	var err error
   153  	if err = convertToStruct(STAKEPREFIX, addr, &stake, getFromDB); err == nil {
   154  		return stake
   155  	}
   156  
   157  	log.Debug("Get stake from DB ", "addr", addr.String(), "err", err)
   158  	return Stake{}
   159  }
   160  
   161  func convertToKV(prefix byte, v interface{}, setToDB setFuncType) error {
   162  	var key common.Hash
   163  	key[0] = prefix
   164  
   165  	value := reflect.ValueOf(v)
   166  	if value.Kind() == reflect.Ptr {
   167  		value = reflect.ValueOf(v).Elem()
   168  	}
   169  	if value.Kind() != reflect.Struct {
   170  		return fmt.Errorf("error : v %v must be struct", v)
   171  	}
   172  	if !value.IsValid() {
   173  		return fmt.Errorf("error: value %v is not valid", v)
   174  	}
   175  
   176  	// 结构体的owner作为key
   177  	owner := value.FieldByName("Owner")
   178  	if owner.IsValid() && owner.CanInterface() {
   179  		if k, ok := owner.Interface().(common.Address); ok {
   180  			copy(key[PREFIXLENGTH:], k.Bytes())
   181  		} else {
   182  			return fmt.Errorf("error: owner %v is not address", owner)
   183  		}
   184  	} else {
   185  		copy(key[PREFIXLENGTH:], contractAddr.Bytes())
   186  	}
   187  
   188  	// 结构体中的每个元素都要分别存储
   189  	for i := 0; i < value.NumField(); i++ {
   190  		// 根据字段在结构体中的位置,对key进行相应的操作
   191  		binary.BigEndian.PutUint64(key[PREFIXLENGTH+common.AddressLength:], uint64(i))
   192  		fv := value.Field(i)
   193  		isArray := false
   194  
   195  		// 若元素为数组,数组中的每个元素也需要分别存储
   196  		if fv.Kind() == reflect.Array || fv.Kind() == reflect.Slice {
   197  			isArray = true
   198  			for j := 0; j < fv.Len(); j++ {
   199  				var subKey common.Hash
   200  				copy(subKey[:], key[:])
   201  				subv := fv.Index(j)
   202  				binary.BigEndian.PutUint32(subKey[PREFIXLENGTH+common.AddressLength:], uint32(j+1))
   203  				if !subv.IsValid() || (subv.Kind() != reflect.Struct && subv.Kind() != reflect.Ptr && subv.Kind() != reflect.Array) {
   204  					isArray = false
   205  					break
   206  				}
   207  				elem, err := rlp.EncodeToBytes(subv.Interface())
   208  				if err != nil {
   209  					return err
   210  				}
   211  				setToDB(subKey, common.BytesToHash(elem))
   212  			}
   213  		}
   214  		// 如果是数组,则数组开始的key,存储数组的长度
   215  		if isArray {
   216  			elem, err := rlp.EncodeToBytes(uint32(fv.Len()))
   217  			if err != nil {
   218  				return err
   219  			}
   220  			setToDB(key, common.BytesToHash(elem))
   221  			continue
   222  		}
   223  
   224  		if !fv.IsValid() || !fv.CanInterface() {
   225  			return fmt.Errorf("error: %v is not valid", fv)
   226  		}
   227  		// 普通元素存储rlp
   228  		elem, err := rlp.EncodeToBytes(fv.Interface())
   229  		if err != nil {
   230  			return err
   231  		}
   232  
   233  		// 如果要存储的字节过长,就拆分了存
   234  		// 0号位置存储切分的长度,后面按右对齐方式存储,若需要补空位,补在第一个元素处
   235  		valLen := len(elem)/32 + 1
   236  		var j int
   237  		for j = valLen - 1; j >= 0; j-- {
   238  			var subKey common.Hash
   239  			copy(subKey[:], key[:])
   240  			binary.BigEndian.PutUint32(subKey[PREFIXLENGTH+common.AddressLength:], uint32(j))
   241  			cutPos := len(elem) - 32
   242  			if cutPos < 0 {
   243  				setToDB(subKey, common.BytesToHash(elem))
   244  				break
   245  			}
   246  			tmpElem := elem[cutPos:]
   247  			elem = elem[:cutPos]
   248  			setToDB(subKey, common.BytesToHash(tmpElem))
   249  		}
   250  	}
   251  	return nil
   252  }
   253  
   254  func convertToStruct(prefix byte, addr common.Address, v interface{}, getFn getFuncType) error {
   255  	value := reflect.ValueOf(v)
   256  	if value.Kind() != reflect.Ptr {
   257  		return fmt.Errorf("error : v %v must be ptr", v)
   258  	}
   259  	value = value.Elem()
   260  
   261  	var key common.Hash
   262  	key[0] = prefix
   263  	copy(key[PREFIXLENGTH:], addr.Bytes())
   264  	// 结构体中的每个元素都要分别获取
   265  	for i := 0; i < value.NumField(); i++ {
   266  		// 根据字段在结构体中的位置,对key进行相应的操作
   267  		binary.BigEndian.PutUint64(key[PREFIXLENGTH+common.AddressLength:], uint64(i))
   268  		fv := value.Field(i)
   269  
   270  		if !fv.IsValid() || !fv.CanInterface() {
   271  			return fmt.Errorf("error: %v is not valid", fv)
   272  		}
   273  
   274  		// 从数据库中得到对应的数据
   275  		valByte := getFn(key)
   276  		if valByte == (common.Hash{}) {
   277  			return KeyNotExistErr
   278  		}
   279  		// 按照数据类型对数据进行解析后,赋值给struct
   280  		if _, ok := fv.Interface().(common.Address); ok {
   281  			var tmp common.Address
   282  			if err := rlp.DecodeBytes(valByte.Big().Bytes(), &tmp); err == nil {
   283  				value.Field(i).Set(reflect.ValueOf(tmp))
   284  			} else {
   285  				return fmt.Errorf("decode to common.Address error: %v", err)
   286  			}
   287  		} else if _, ok = fv.Interface().(bool); ok {
   288  			var tmp bool
   289  			if err := rlp.DecodeBytes(valByte.Big().Bytes(), &tmp); err == nil {
   290  				value.Field(i).Set(reflect.ValueOf(tmp))
   291  			} else {
   292  				return err
   293  			}
   294  		} else if _, ok = fv.Interface().(uint64); ok {
   295  			var tmp uint64
   296  			if err := rlp.DecodeBytes(valByte.Big().Bytes(), &tmp); err == nil {
   297  				value.Field(i).Set(reflect.ValueOf(tmp))
   298  			} else {
   299  				return err
   300  			}
   301  		} else if _, ok = fv.Interface().(*big.Int); ok {
   302  			var tmp *big.Int
   303  			if err := rlp.DecodeBytes(valByte.Big().Bytes(), &tmp); err == nil {
   304  				value.Field(i).Set(reflect.ValueOf(tmp))
   305  			} else {
   306  				return err
   307  			}
   308  		} else if _, ok = fv.Interface().([]common.Address); ok {
   309  			var tmp []common.Address
   310  			var valLen uint32
   311  
   312  			// 如果是数组,先解析出数组长度,然后获取数组中的元素
   313  			if err := rlp.DecodeBytes(valByte.Big().Bytes(), &valLen); err == nil {
   314  				for j := uint32(0); j < valLen; j++ {
   315  					var tmpArray common.Address
   316  					binary.BigEndian.PutUint32(key[PREFIXLENGTH+common.AddressLength:], uint32(j+1))
   317  					arrayByte := getFn(key)
   318  					if err = rlp.DecodeBytes(arrayByte.Big().Bytes(), &tmpArray); err == nil {
   319  						tmp = append(tmp, tmpArray)
   320  					} else {
   321  						return err
   322  					}
   323  				}
   324  				value.Field(i).Set(reflect.ValueOf(tmp))
   325  			} else {
   326  				return err
   327  			}
   328  		} else if _, ok := fv.Interface().([]byte); ok {
   329  			// 部分byte数组过长,是拆分了之后存储的
   330  			var val []byte
   331  			err := rlp.DecodeBytes(valByte.Big().Bytes(), &val)
   332  			if err == nil {
   333  				value.Field(i).Set(reflect.ValueOf(val))
   334  			} else {
   335  				val = valByte.Big().Bytes()
   336  				var tmp []byte
   337  				for j := 1; ; j++ {
   338  					binary.BigEndian.PutUint32(key[PREFIXLENGTH+common.AddressLength:], uint32(j))
   339  					arrayByte := getFn(key)
   340  					if arrayByte.Big().Sign() == 0 {
   341  						break
   342  					}
   343  					val = append(val, arrayByte.Bytes()...)
   344  					if err = rlp.DecodeBytes(val, &tmp); err == nil {
   345  						value.Field(i).Set(reflect.ValueOf(tmp))
   346  						break
   347  					}
   348  				}
   349  			}
   350  		}
   351  
   352  	}
   353  	return nil
   354  }
   355  
   356  func getAllCandidate(db inter.StateDB) CandidateList {
   357  	var result CandidateList
   358  	addrs := make(map[common.Address]struct{})
   359  	// 从数据库的value中找到所有的address
   360  	db.ForEachStorage(contractAddr, func(key common.Hash, value common.Hash) bool {
   361  		_, content, _, err := rlp.Split(value.Big().Bytes())
   362  		if err != nil {
   363  			// 这个地方长的bytes做过处理这里split会出错,所以这个错改成debug打印日志
   364  			log.Debug("rlp split error", "err", err)
   365  			return true
   366  		}
   367  		var addr common.Address
   368  		if len(content) == common.AddressLength {
   369  			addr = common.BytesToAddress(content)
   370  		} else if len(content) == common.AddressLength+1 {
   371  			if err := rlp.DecodeBytes(content, &addr); err != nil {
   372  				return true
   373  			}
   374  		}
   375  		if !bytes.Equal(addr.Bytes(), emptyAddress.Bytes()) {
   376  			addrs[addr] = struct{}{}
   377  		}
   378  		return true
   379  	})
   380  
   381  	// 用这些address尝试去数据库中找候选者,当没有这个地址的候选者时会报错
   382  	// 有可能并不是见证人所以报错
   383  	for addr := range addrs {
   384  		// var candidate Candidate
   385  		candidate := newCandidate()
   386  		err := convertToStruct(CANDIDATEPREFIX, addr, &candidate, genGetFunc(db))
   387  		if err != nil {
   388  			log.Debug("getAllCandidate maybe error", "address", addr, "err", err)
   389  			continue
   390  		}
   391  		result = append(result, candidate)
   392  	}
   393  
   394  	return result
   395  }
   396  
   397  func getAllProxy(db inter.StateDB) []*Voter {
   398  	var result []*Voter
   399  	addrs := make(map[common.Address]struct{})
   400  
   401  	db.ForEachStorage(contractAddr, func(key common.Hash, value common.Hash) bool {
   402  		if key[0] == VOTERPREFIX {
   403  			var addr common.Address
   404  			copy(addr[:], key[PREFIXLENGTH:PREFIXLENGTH+common.AddressLength])
   405  			addrs[addr] = struct{}{}
   406  		}
   407  		return true
   408  	})
   409  
   410  	for addr := range addrs {
   411  		var voter Voter
   412  		err := convertToStruct(VOTERPREFIX, addr, &voter, genGetFunc(db))
   413  		if err != nil {
   414  			log.Error("getAllProxy error", "address", addr, "err", err)
   415  		}
   416  
   417  		if voter.IsProxy {
   418  			result = append(result, &voter)
   419  		}
   420  	}
   421  	return result
   422  }
   423  
   424  // 第一次从db中读取key时,key不存在,返回特殊异常,外部创建kv
   425  func getLock(stateDB inter.StateDB) (AllLock, error) {
   426  	re := AllLock{big.NewInt(0)}
   427  	err := convertToStruct(ALLLOCKPREFIX, contractAddr, &re, genGetFunc(stateDB))
   428  	return re, err
   429  }
   430  
   431  func setLock(stateDB inter.StateDB, lock AllLock) error {
   432  	err := convertToKV(ALLLOCKPREFIX, lock, genSetFunc(stateDB))
   433  	if err != nil {
   434  		log.Error("setLock error", "err", err, "lock", lock)
   435  	}
   436  	return err
   437  }
   438  
   439  func getReward(stateDB inter.StateDB) Reward {
   440  	var re Reward
   441  	err := convertToStruct(REWARDPREFIX, contractAddr, &re, genGetFunc(stateDB))
   442  	if err != nil {
   443  		return Reward{big.NewInt(0)}
   444  	}
   445  	return re
   446  }
   447  
   448  func setReward(stateDB inter.StateDB, restBounty Reward) error {
   449  	return convertToKV(REWARDPREFIX, restBounty, genSetFunc(stateDB))
   450  }
   451  
   452  // genGetFunc generate universal get function for read from state db.
   453  func genGetFunc(stateDb inter.StateDB) getFuncType {
   454  	return func(key common.Hash) common.Hash {
   455  		return stateDb.GetState(contractAddr, key)
   456  	}
   457  }
   458  
   459  // genSetFunc generate universal get function for write state to state db.
   460  func genSetFunc(stateDb inter.StateDB) setFuncType {
   461  	return func(key common.Hash, value common.Hash) {
   462  		stateDb.SetState(contractAddr, key, value)
   463  	}
   464  }