github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/orgchain/storages/ledger_store.go (about) 1 package storages 2 3 import ( 4 "fmt" 5 "sync" 6 7 "math/big" 8 9 "sort" 10 11 "path" 12 13 "github.com/sixexorg/magnetic-ring/bactor" 14 "github.com/sixexorg/magnetic-ring/common" 15 "github.com/sixexorg/magnetic-ring/core/orgchain/types" 16 17 "github.com/ontio/ontology-eventbus/actor" 18 "github.com/sixexorg/magnetic-ring/log" 19 p2pcommon "github.com/sixexorg/magnetic-ring/p2pserver/common" 20 scom "github.com/sixexorg/magnetic-ring/store/orgchain/common" 21 "github.com/sixexorg/magnetic-ring/store/orgchain/states" 22 "github.com/sixexorg/magnetic-ring/store/storelaw" 23 ) 24 25 const ( 26 SYSTEM_VERSION = byte(1) //Version of ledger store 27 HEADER_INDEX_BATCH_SIZE = uint64(2000) //Bath size of saving header index 28 ) 29 30 var ( 31 //Storage save path. 32 DBDirBlock = "block" 33 DBDirState = "states" 34 DBDirAccountState = "account" 35 DBDirAccountRoot = "aroot" 36 DBDirVote = "vote" 37 DBDirUT = "ut" 38 MerkleTreeStorePath = "merkle_tree.db" 39 p2pActor *actor.PID 40 ) 41 42 func initActor() error { 43 var err error 44 if p2pActor == nil { 45 p2pActor, err = bactor.GetActorPid(bactor.P2PACTOR) 46 if err != nil { 47 log.Error(err.Error()) 48 return err 49 } 50 } 51 return nil 52 } 53 54 //LedgerStoreImp is main store struct fo ledger 55 type LedgerStoreImp struct { 56 blockStore *BlockStore //BlockStore for saving block & transaction data 57 //stateStore *StateStore //StateStore for saving state data, like balance, smart contract execution result, and so on. 58 accountStore *AccountStore 59 accountRootStore *AccountRootStore 60 voteStore *VoteStore 61 utStore *UTStore 62 63 storedIndexCount uint64 //record the count of have saved block index 64 currBlockHeight uint64 //Current block height 65 currBlockHash common.Hash //Current block hash 66 currBlock *types.Block 67 totalDifficulty *big.Int 68 headerCache map[common.Hash]*types.Header //BlockHash => Header 69 headerIndex map[uint64]common.Hash //Header index, Mapping header height => block hash 70 savingBlock bool //is saving block now 71 destroyedEnergy *big.Int 72 bonusCache map[uint64]uint64 73 lock sync.RWMutex 74 } 75 76 //NewLedgerStore return LedgerStoreImp instance 77 func NewLedgerStore(dataDir string) (*LedgerStoreImp, error) { 78 ledgerStore := &LedgerStoreImp{ 79 headerIndex: make(map[uint64]common.Hash), 80 headerCache: make(map[common.Hash]*types.Header, 0), 81 totalDifficulty: big.NewInt(0), 82 destroyedEnergy: big.NewInt(0), 83 bonusCache: make(map[uint64]uint64), 84 } 85 86 blockStore, err := NewBlockStore(path.Join(dataDir, DBDirBlock), true) 87 if err != nil { 88 return nil, fmt.Errorf("NewBlockStore error %s", err) 89 } 90 ledgerStore.blockStore = blockStore 91 92 accountState, err := NewAccountStore(path.Join(dataDir, DBDirAccountState)) 93 if err != nil { 94 return nil, fmt.Errorf("NewAccountStateStore error %s", err) 95 } 96 ledgerStore.accountStore = accountState 97 accountRoot, err := NewAccountRootStore(path.Join(dataDir, DBDirAccountRoot)) 98 if err != nil { 99 return nil, fmt.Errorf("NewAccountRootStore error %s", err) 100 } 101 ledgerStore.accountRootStore = accountRoot 102 103 voteStore, err := NewVoteStore(path.Join(dataDir, DBDirVote), byte(scom.ST_VOTE_STATE), byte(scom.ST_VOTE_RECORD)) 104 if err != nil { 105 return nil, fmt.Errorf("NewVoteStore error %s", err) 106 } 107 ledgerStore.voteStore = voteStore 108 109 utStore, err := NewUTStore(path.Join(dataDir, DBDirUT)) 110 if err != nil { 111 return nil, fmt.Errorf("NewUTStore error %s", err) 112 } 113 ledgerStore.utStore = utStore 114 /* 115 stateStore, err := NewStateStore(path.Join(dataDir, DBDirState), MerkleTreeStorePath) 116 if err != nil { 117 return nil, fmt.Errorf("NewStateStore error %s", err) 118 } 119 120 ledgerStore.stateStore = stateStore*/ 121 return ledgerStore, nil 122 } 123 124 func (this *LedgerStoreImp) ContainBlock(blockHash common.Hash) (bool, error) { 125 return this.blockStore.ContainBlock(blockHash) 126 127 } 128 func (this *LedgerStoreImp) GetBlockByHash(blockHash common.Hash) (*types.Block, error) { 129 this.lock.RLock() 130 defer this.lock.RUnlock() 131 block, err := this.blockStore.GetBlock(blockHash) 132 if err != nil { 133 return nil, err 134 } 135 return block, nil 136 } 137 138 func (this *LedgerStoreImp) verifyHeader(header *types.Header) error { 139 if header.Height == 1 { 140 return nil 141 } 142 prevHeader, err := this.GetHeaderByHash(header.PrevBlockHash) 143 if err != nil { 144 return err 145 } 146 if prevHeader == nil { 147 return fmt.Errorf("cannot find pre header by blockHash %s", header.PrevBlockHash.String()) 148 } 149 if prevHeader.Height+1 != header.Height { 150 return fmt.Errorf("block height is incorrect") 151 } 152 /* if prevHeader.Timestamp >= header.Timestamp { 153 return fmt.Errorf("block timestamp is incorrect") 154 }*/ 155 return nil 156 } 157 158 func (this *LedgerStoreImp) GetBlockHashByHeight(height uint64) (common.Hash, error) { 159 this.lock.RLock() 160 defer this.lock.RUnlock() 161 blockHash, err := this.blockStore.GetBlockHash(height) 162 if err != nil { 163 return common.Hash{}, err 164 } 165 return blockHash, err 166 } 167 func (this *LedgerStoreImp) GetBlockByHeight(height uint64) (*types.Block, error) { 168 this.lock.RLock() 169 defer this.lock.RUnlock() 170 blockHash, err := this.blockStore.GetBlockHash(height) 171 if err != nil { 172 return nil, err 173 } 174 return this.GetBlockByHash(blockHash) 175 } 176 177 func (this *LedgerStoreImp) setCurrentBlock(block *types.Block) { 178 this.lock.Lock() 179 defer this.lock.Unlock() 180 this.currBlockHash = block.Hash() 181 this.currBlockHeight = block.Header.Height 182 this.currBlock = block 183 if block.Header.Height%types.HWidth == 0 { 184 this.bonusCache[block.Header.Height] = block.Header.Bonus 185 } 186 } 187 func (this *LedgerStoreImp) setDestroyedEnergy(header *types.Header, feeSum *big.Int) { 188 this.lock.Lock() 189 defer this.lock.Unlock() 190 if header.Height%types.HWidth == 0 { 191 this.destroyedEnergy.SetUint64(0) 192 } 193 rat := new(big.Rat).Set(types.BonusRate) 194 rat.Mul(rat, new(big.Rat).SetInt(feeSum)) 195 rfTmp := big.NewFloat(0).SetRat(rat) 196 integer, _ := rfTmp.Uint64() 197 this.destroyedEnergy.Add(this.destroyedEnergy, big.NewInt(int64(integer))) 198 fmt.Printf("⭕ leagueStore destoryEnergy:%d feeSu,:%d \n ", this.destroyedEnergy.Uint64(), feeSum.Uint64()) 199 } 200 func (this *LedgerStoreImp) GetCurrentBlockInfo() *types.Block { 201 this.lock.RLock() 202 defer this.lock.RUnlock() 203 return this.currBlock 204 } 205 206 func (this *LedgerStoreImp) GetCurrentBlock() (uint64, common.Hash) { 207 this.lock.RLock() 208 defer this.lock.RUnlock() 209 return this.currBlockHeight, this.currBlockHash 210 } 211 212 //GetCurrentBlockHash return the current block hash 213 func (this *LedgerStoreImp) GetCurrentBlockHash() common.Hash { 214 this.lock.RLock() 215 defer this.lock.RUnlock() 216 return this.currBlockHash 217 } 218 219 //GetCurrentBlockHeight return the current block height 220 func (this *LedgerStoreImp) GetCurrentBlockHeight() uint64 { 221 this.lock.RLock() 222 defer this.lock.RUnlock() 223 return this.currBlockHeight 224 } 225 226 func (this *LedgerStoreImp) GetTransaction(txHash common.Hash, leagueId common.Address) (*types.Transaction, uint64, error) { 227 this.lock.RLock() 228 defer this.lock.RUnlock() 229 return this.blockStore.GetTransaction(txHash) 230 } 231 232 func (this *LedgerStoreImp) Restore() { 233 234 } 235 236 func (this *LedgerStoreImp) SaveAll(blockInfo *storelaw.OrgBlockInfo) error { 237 if this.isSavingBlock() { 238 //hash already saved or is saving 239 return nil 240 } 241 defer this.resetSavingBlock() 242 243 err := this.addStates(blockInfo.AccStates, blockInfo.Block.Header.Height) 244 if err != nil { 245 return err 246 } 247 err = this.addBlock(blockInfo.Block) 248 if err != nil { 249 return err 250 } 251 err = this.saveVotes(blockInfo.VoteStates, blockInfo.AccountVoteds, blockInfo.Block.Header.Height) 252 if err != nil { 253 return err 254 } 255 err = this.saveUT(blockInfo.UT, blockInfo.Block.Header.Height) 256 if err != nil { 257 return err 258 } 259 this.delHeaderCache(blockInfo.Block.Hash()) 260 if this.currBlockHeight > 0 { 261 prevBlock := &types.Block{} 262 common.DeepCopy(prevBlock, this.currBlock) 263 264 /* if actor.ConsensusPid != nil { 265 actor.ConsensusPid.Tell(blockInfo.Block) 266 }*/ 267 err := initActor() 268 if err == nil { 269 p2pActor.Tell(&p2pcommon.OrgPendingData{ 270 BANodeSrc: true, // true:ANode send staller false:staller send staller 271 OrgId: blockInfo.Block.Header.LeagueId, // orgid 272 Block: prevBlock, // tx 273 }) 274 fmt.Println("!!!!!") 275 } 276 /* fmt.Printf("⭕️ send to main radar the difficulty is %d the hash is %s \n", prevBlock.Header.Difficulty.Uint64(), prevBlock.Hash().String()) 277 fmt.Println("⭕️ send to 🚫 ", 278 prevBlock.Header.Version, 279 prevBlock.Header.PrevBlockHash.String(), 280 prevBlock.Header.BlockRoot.String(), 281 prevBlock.Header.LeagueId.ToString(), 282 prevBlock.Header.TxRoot.String(), 283 prevBlock.Header.StateRoot.String(), 284 prevBlock.Header.ReceiptsRoot.String(), 285 prevBlock.Header.Timestamp, 286 prevBlock.Header.Height, 287 prevBlock.Header.Difficulty.Uint64(), 288 prevBlock.Header.Coinbase.ToString(), 289 prevBlock.Header.Extra, 290 )*/ 291 } 292 this.setCurrentBlock(blockInfo.Block) 293 this.setDestroyedEnergy(blockInfo.Block.Header, blockInfo.FeeSum) 294 fmt.Printf("⭕ -----S---A---V---E----A---L---L--- Height:%d TxLen:%d blockHash:%s difficulty:%d bonus:%d bonusCache:%d \n", 295 blockInfo.Block.Header.Height, 296 blockInfo.Block.Transactions.Len(), 297 blockInfo.Block.Hash().String(), 298 blockInfo.Block.Header.Difficulty.Uint64(), 299 blockInfo.Block.Header.Bonus, 300 this.bonusCache[blockInfo.Height()], 301 ) 302 return nil 303 } 304 func (this *LedgerStoreImp) saveUT(ut *big.Int, height uint64) error { 305 amount := this.utStore.GetUTByHeight(height) 306 if amount.Cmp(ut) == 0 { 307 return nil 308 } 309 return this.utStore.Save(height, ut) 310 } 311 func (this *LedgerStoreImp) addStates(accountStates storelaw.AccountStaters, height uint64) error { 312 if accountStates == nil { 313 return nil 314 } 315 this.accountStore.NewBatch() 316 err := this.accountStore.BatchSave(accountStates) 317 if err != nil { 318 return err 319 } 320 if err = this.accountStore.CommitTo(); err != nil { 321 return err 322 } 323 sort.Sort(accountStates) 324 hashes := []common.Address{} 325 for _, v := range accountStates { 326 hashes = append(hashes, v.Account()) 327 } 328 asr := states.NewAccountStateRoot(height, hashes) 329 err = this.accountRootStore.Save(asr) 330 if err != nil { 331 return err 332 } 333 return nil 334 } 335 func (this *LedgerStoreImp) addBlock(block *types.Block) error { 336 currentHeight := this.GetCurrentBlockHeight() 337 blockHeight := block.Header.Height 338 if blockHeight <= currentHeight { 339 return nil 340 } 341 if blockHeight != currentHeight+1 { 342 return fmt.Errorf("block height %d not equal next block height %d", blockHeight, currentHeight+1) 343 } 344 err := this.saveBlock(block) 345 if err != nil { 346 return err 347 } 348 return nil 349 } 350 func (this *LedgerStoreImp) saveBlock(block *types.Block) error { 351 blockHash := block.Hash() 352 blockHeight := block.Header.Height 353 this.blockStore.NewBatch() 354 err := this.saveHeaderIndexList() 355 if err != nil { 356 return fmt.Errorf("saveHeaderIndexList error %s", err) 357 } 358 359 this.blockStore.SaveBlockHash(blockHeight, blockHash) 360 err = this.blockStore.SaveBlock(block) 361 if err != nil { 362 return fmt.Errorf("SaveBlock height %d hash %s error %s", blockHeight, blockHash.String(), err) 363 } 364 err = this.blockStore.CommitTo() 365 if err != nil { 366 return err 367 } 368 this.setHeaderIndex(blockHeight, blockHash) 369 //log.Info("this.totalDifficulty","difficulty",this.totalDifficulty,"block.Header.Difficulty",block.Header.Difficulty) 370 this.totalDifficulty.Add(this.totalDifficulty, block.Header.Difficulty) 371 return nil 372 } 373 func (this *LedgerStoreImp) saveVotes(voteStates []*storelaw.VoteState, AccountVoteds []*storelaw.AccountVoted, height uint64) error { 374 this.voteStore.NewBatch() 375 this.voteStore.SaveVotes(voteStates) 376 this.voteStore.SaveAccountVoted(AccountVoteds, height) 377 err := this.voteStore.CommitTo() 378 return err 379 } 380 func (this *LedgerStoreImp) RollbackToHeight(height uint64) error { 381 this.lock.RLock() 382 defer this.lock.RUnlock() 383 //accountState 384 asts, err := this.accountRootStore.GetRange(height, this.currBlockHeight) 385 if err != nil { 386 return err 387 } 388 //accountRoot 389 this.accountStore.NewBatch() 390 heights := []uint64{} 391 for k, v := range asts { 392 this.accountStore.BatchRemove(v.Height, v.Accounts) 393 heights = append(heights, asts[k].Height) 394 } 395 err = this.accountStore.CommitTo() 396 if err != nil { 397 return err 398 } 399 this.accountRootStore.NewBatch() 400 this.accountRootStore.BatchRemove(heights) 401 err = this.accountRootStore.CommitTo() 402 if err != nil { 403 return err 404 } 405 406 //block 407 this.blockStore.NewBatch() 408 for i := this.currBlockHeight; i > height; i-- { 409 hash, err := this.blockStore.GetBlockHash(i) 410 if err != nil { 411 return err 412 } 413 block, err := this.blockStore.GetBlock(hash) 414 if err != nil { 415 return err 416 } 417 418 delete(this.headerCache, hash) 419 delete(this.headerIndex, i) 420 this.currBlockHash = block.Header.PrevBlockHash 421 this.totalDifficulty.Sub(this.totalDifficulty, block.Header.Difficulty) 422 423 this.blockStore.RemoveBlockHash(i) 424 this.blockStore.RemoveHeader(hash) 425 for _, v := range block.Transactions { 426 this.blockStore.RemoveTransaction(v.Hash()) 427 } 428 } 429 err = this.blockStore.CommitTo() 430 431 block, err := this.GetBlockByHeight(height) 432 if err != nil { 433 return err 434 } 435 this.setCurrentBlock(block) 436 return nil 437 } 438 func (this *LedgerStoreImp) TotalDifficulty() *big.Int { 439 this.lock.RLock() 440 defer this.lock.RUnlock() 441 return this.totalDifficulty 442 } 443 func (this *LedgerStoreImp) GetDifficultyByBlockHash(hash common.Hash) (*big.Int, error) { 444 return this.blockStore.GetDifficultyByBlockHash(hash) 445 } 446 func (this *LedgerStoreImp) SaveAccount(state storelaw.AccountStater) error { 447 this.lock.Lock() 448 defer this.lock.Unlock() 449 return this.accountStore.Save(state) 450 } 451 func (this *LedgerStoreImp) isSavingBlock() bool { 452 this.lock.Lock() 453 defer this.lock.Unlock() 454 455 if !this.savingBlock { 456 this.savingBlock = true 457 return false 458 } 459 return true 460 } 461 462 func (this *LedgerStoreImp) resetSavingBlock() { 463 this.lock.Lock() 464 defer this.lock.Unlock() 465 this.savingBlock = false 466 } 467 468 ////////////////////Ledger4Validation/////////////////// 469 func (this *LedgerStoreImp) GetCurrentBlockHeight4V(leagueId common.Address) uint64 { 470 return this.GetCurrentBlockHeight() 471 } 472 func (this *LedgerStoreImp) GetCurrentHeaderHash4V(leagueId common.Address) common.Hash { 473 return this.GetCurrentHeaderHash() 474 } 475 func (this *LedgerStoreImp) GetBlockHashByHeight4V(leagueId common.Address, height uint64) (common.Hash, error) { 476 return this.GetBlockHashByHeight(height) 477 } 478 479 func (this *LedgerStoreImp) GetPrevAccount4V(height uint64, account, leagueId common.Address) (storelaw.AccountStater, error) { 480 this.lock.RLock() 481 defer this.lock.RUnlock() 482 return this.accountStore.GetPrev(height, account, leagueId) 483 } 484 func (this *LedgerStoreImp) ContainTx4V(txHash common.Hash) bool { 485 bool, err := this.blockStore.ContainTransaction(txHash) 486 if err != nil { 487 return false 488 } 489 return bool 490 } 491 func (this *LedgerStoreImp) GetVoteState(voteId common.Hash, height uint64) (*storelaw.VoteState, error) { 492 return this.voteStore.GetVoteState(voteId, height) 493 } 494 func (this *LedgerStoreImp) AlreadyVoted(voteId common.Hash, account common.Address) bool { 495 return this.voteStore.AlreadyVoted(voteId, account) 496 } 497 func (this *LedgerStoreImp) GetUTByHeight(height uint64, leagueId common.Address) *big.Int { 498 return this.utStore.GetUTByHeight(height) 499 } 500 func (this *LedgerStoreImp) GetHeaderBonus(leagueId common.Address) *big.Int { 501 return this.destroyedEnergy 502 } 503 func (this *LedgerStoreImp) GetAccountRange(start, end uint64, account, leagueId common.Address) (storelaw.AccountStaters, error) { 504 return this.accountStore.GetAccountRange(start, end, account) 505 } 506 func (this *LedgerStoreImp) GetBonus(leagueId common.Address) map[uint64]uint64 { 507 return this.bonusCache 508 } 509 510 ////////////////////Ledger4Validation///////////////////