github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/state/state.go (about) 1 package state 2 3 import ( 4 "context" 5 "math/big" 6 "sync" 7 8 "github.com/0xPolygon/supernets2-node/event" 9 "github.com/0xPolygon/supernets2-node/merkletree" 10 "github.com/0xPolygon/supernets2-node/state/metrics" 11 "github.com/0xPolygon/supernets2-node/state/runtime/executor/pb" 12 "github.com/ethereum/go-ethereum/common" 13 "github.com/ethereum/go-ethereum/core/types" 14 "github.com/jackc/pgx/v4" 15 ) 16 17 var ( 18 // ZeroHash is the hash 0x0000000000000000000000000000000000000000000000000000000000000000 19 ZeroHash = common.Hash{} 20 // ZeroAddress is the address 0x0000000000000000000000000000000000000000 21 ZeroAddress = common.Address{} 22 ) 23 24 // State is an implementation of the state 25 type State struct { 26 cfg Config 27 *PostgresStorage 28 executorClient pb.ExecutorServiceClient 29 tree *merkletree.StateTree 30 eventLog *event.EventLog 31 32 lastL2BlockSeen types.Block 33 newL2BlockEvents chan NewL2BlockEvent 34 newL2BlockEventHandlers []NewL2BlockEventHandler 35 } 36 37 // NewState creates a new State 38 func NewState(cfg Config, storage *PostgresStorage, executorClient pb.ExecutorServiceClient, stateTree *merkletree.StateTree, eventLog *event.EventLog) *State { 39 var once sync.Once 40 once.Do(func() { 41 metrics.Register() 42 }) 43 44 state := &State{ 45 cfg: cfg, 46 PostgresStorage: storage, 47 executorClient: executorClient, 48 tree: stateTree, 49 eventLog: eventLog, 50 newL2BlockEvents: make(chan NewL2BlockEvent), 51 newL2BlockEventHandlers: []NewL2BlockEventHandler{}, 52 } 53 54 return state 55 } 56 57 // BeginStateTransaction starts a state transaction 58 func (s *State) BeginStateTransaction(ctx context.Context) (pgx.Tx, error) { 59 tx, err := s.Begin(ctx) 60 if err != nil { 61 return nil, err 62 } 63 return tx, nil 64 } 65 66 // GetBalance from a given address 67 func (s *State) GetBalance(ctx context.Context, address common.Address, root common.Hash) (*big.Int, error) { 68 if s.tree == nil { 69 return nil, ErrStateTreeNil 70 } 71 return s.tree.GetBalance(ctx, address, root.Bytes()) 72 } 73 74 // GetCode from a given address 75 func (s *State) GetCode(ctx context.Context, address common.Address, root common.Hash) ([]byte, error) { 76 if s.tree == nil { 77 return nil, ErrStateTreeNil 78 } 79 return s.tree.GetCode(ctx, address, root.Bytes()) 80 } 81 82 // GetNonce returns the nonce of the given account at the given block number 83 func (s *State) GetNonce(ctx context.Context, address common.Address, root common.Hash) (uint64, error) { 84 if s.tree == nil { 85 return 0, ErrStateTreeNil 86 } 87 nonce, err := s.tree.GetNonce(ctx, address, root.Bytes()) 88 if err != nil { 89 return 0, err 90 } 91 return nonce.Uint64(), nil 92 } 93 94 // GetStorageAt from a given address 95 func (s *State) GetStorageAt(ctx context.Context, address common.Address, position *big.Int, root common.Hash) (*big.Int, error) { 96 if s.tree == nil { 97 return nil, ErrStateTreeNil 98 } 99 return s.tree.GetStorageAt(ctx, address, position, root.Bytes()) 100 } 101 102 // GetLastStateRoot returns the latest state root 103 func (s *State) GetLastStateRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error) { 104 lastBlockHeader, err := s.GetLastL2BlockHeader(ctx, dbTx) 105 if err != nil { 106 return common.Hash{}, err 107 } 108 return lastBlockHeader.Root, nil 109 } 110 111 // GetBalanceByStateRoot gets balance from the MT Service using the provided state root 112 func (s *State) GetBalanceByStateRoot(ctx context.Context, address common.Address, root common.Hash) (*big.Int, error) { 113 if s.tree == nil { 114 return nil, ErrStateTreeNil 115 } 116 balance, err := s.tree.GetBalance(ctx, address, root.Bytes()) 117 if err != nil && balance == nil { 118 balance = big.NewInt(0) 119 } 120 return balance, err 121 } 122 123 // GetNonceByStateRoot gets nonce from the MT Service using the provided state root 124 func (s *State) GetNonceByStateRoot(ctx context.Context, address common.Address, root common.Hash) (*big.Int, error) { 125 if s.tree == nil { 126 return nil, ErrStateTreeNil 127 } 128 return s.tree.GetNonce(ctx, address, root.Bytes()) 129 } 130 131 // GetTree returns State inner tree 132 func (s *State) GetTree() *merkletree.StateTree { 133 return s.tree 134 } 135 136 // FlushMerkleTree persists updates in the Merkle tree 137 func (s *State) FlushMerkleTree(ctx context.Context) error { 138 if s.tree == nil { 139 return ErrStateTreeNil 140 } 141 return s.tree.Flush(ctx) 142 }