github.com/aergoio/aergo@v1.3.1/state/blockstate.go (about) 1 package state 2 3 import ( 4 "github.com/aergoio/aergo/consensus" 5 "github.com/aergoio/aergo/types" 6 "github.com/willf/bloom" 7 "sync" 8 ) 9 10 // BlockInfo contains BlockHash and StateRoot 11 type BlockInfo struct { 12 BlockHash types.BlockID 13 StateRoot types.HashID 14 } 15 16 // BlockState contains BlockInfo and statedb for block 17 type BlockState struct { 18 StateDB 19 BpReward []byte //final bp reward, increment when tx executes 20 receipts types.Receipts 21 CodeMap codeCache 22 CCProposal *consensus.ConfChangePropose 23 } 24 25 type codeCache struct { 26 Lock sync.Mutex 27 codes map[types.AccountID][]byte 28 } 29 30 // NewBlockInfo create new blockInfo contains blockNo, blockHash and blockHash of previous block 31 func NewBlockInfo(blockHash types.BlockID, stateRoot types.HashID) *BlockInfo { 32 return &BlockInfo{ 33 BlockHash: blockHash, 34 StateRoot: stateRoot, 35 } 36 } 37 38 // GetStateRoot return bytes of bi.StateRoot 39 func (bi *BlockInfo) GetStateRoot() []byte { 40 if bi == nil { 41 return nil 42 } 43 return bi.StateRoot.Bytes() 44 } 45 46 // NewBlockState create new blockState contains blockInfo, account states and undo states 47 func NewBlockState(states *StateDB) *BlockState { 48 return &BlockState{ 49 StateDB: *states, 50 CodeMap: codeCache{ 51 codes: make(map[types.AccountID][]byte), 52 }, 53 } 54 } 55 56 func (bs *BlockState) AddReceipt(r *types.Receipt) error { 57 if len(r.Events) > 0 { 58 rBloom := bloom.New(types.BloomBitBits, types.BloomHashKNum) 59 for _, e := range r.Events { 60 rBloom.Add(e.ContractAddress) 61 rBloom.Add([]byte(e.EventName)) 62 } 63 binary, _ := rBloom.GobEncode() 64 r.Bloom = binary[24:] 65 err := bs.receipts.MergeBloom(rBloom) 66 if err != nil { 67 return err 68 } 69 } 70 bs.receipts.Set(append(bs.receipts.Get(), r)) 71 return nil 72 } 73 74 func (bs *BlockState) Receipts() *types.Receipts { 75 if bs == nil { 76 return nil 77 } 78 return &bs.receipts 79 } 80 81 func (c *codeCache) Add(key types.AccountID, code []byte) { 82 c.Lock.Lock() 83 c.codes[key] = code 84 c.Lock.Unlock() 85 } 86 87 func (c *codeCache) Get(key types.AccountID) []byte { 88 c.Lock.Lock() 89 defer c.Lock.Unlock() 90 return c.codes[key] 91 } 92 93 func (c *codeCache) Remove(key types.AccountID) { 94 c.Lock.Lock() 95 delete(c.codes, key) 96 c.Lock.Unlock() 97 }