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  }