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 }