github.com/onflow/flow-go@v0.33.17/fvm/evm/handler/blockstore.go (about) 1 package handler 2 3 import ( 4 gethCommon "github.com/ethereum/go-ethereum/common" 5 "github.com/onflow/atree" 6 7 "github.com/onflow/flow-go/fvm/evm/types" 8 "github.com/onflow/flow-go/model/flow" 9 ) 10 11 var FlexLatestBlockKey = "LatestBlock" 12 13 type BlockStore struct { 14 led atree.Ledger 15 flexAddress flow.Address 16 blockProposal *types.Block 17 } 18 19 var _ types.BlockStore = &BlockStore{} 20 21 // NewBlockStore constructs a new block store 22 func NewBlockStore(led atree.Ledger, flexAddress flow.Address) (*BlockStore, error) { 23 return &BlockStore{ 24 led: led, 25 flexAddress: flexAddress, 26 }, nil 27 } 28 29 // BlockProposal returns the block proposal to be updated by the handler 30 func (bs *BlockStore) BlockProposal() (*types.Block, error) { 31 if bs.blockProposal != nil { 32 return bs.blockProposal, nil 33 } 34 35 lastExecutedBlock, err := bs.LatestBlock() 36 if err != nil { 37 return nil, err 38 } 39 40 parentHash, err := lastExecutedBlock.Hash() 41 if err != nil { 42 return nil, err 43 } 44 45 bs.blockProposal = &types.Block{ 46 Height: lastExecutedBlock.Height + 1, 47 ParentBlockHash: parentHash, 48 TotalSupply: lastExecutedBlock.TotalSupply, 49 TransactionHashes: make([]gethCommon.Hash, 0), 50 } 51 return bs.blockProposal, nil 52 } 53 54 // CommitBlockProposal commits the block proposal to the chain 55 func (bs *BlockStore) CommitBlockProposal() error { 56 bp, err := bs.BlockProposal() 57 if err != nil { 58 return err 59 } 60 61 blockBytes, err := bp.ToBytes() 62 if err != nil { 63 return types.NewFatalError(err) 64 } 65 66 err = bs.led.SetValue(bs.flexAddress[:], []byte(FlexLatestBlockKey), blockBytes) 67 if err != nil { 68 return types.NewFatalError(err) 69 } 70 71 bs.blockProposal = nil 72 73 return nil 74 } 75 76 // ResetBlockProposal resets the block proposal 77 func (bs *BlockStore) ResetBlockProposal() error { 78 bs.blockProposal = nil 79 return nil 80 } 81 82 // LatestBlock returns the latest executed block 83 func (bs *BlockStore) LatestBlock() (*types.Block, error) { 84 data, err := bs.led.GetValue(bs.flexAddress[:], []byte(FlexLatestBlockKey)) 85 if len(data) == 0 { 86 return types.GenesisBlock, err 87 } 88 if err != nil { 89 return nil, types.NewFatalError(err) 90 } 91 return types.NewBlockFromBytes(data) 92 } 93 94 // BlockHash returns the block hash for the last x blocks 95 // 96 // TODO: implement this properly to keep the last 256 block hashes 97 // and connect use it inside the handler to pass as a config to the emulator 98 func (bs *BlockStore) BlockHash(height int) (gethCommon.Hash, error) { 99 return gethCommon.Hash{}, nil 100 }