From b39a075662e2ff86f2addf986ca8cbd708c903d3 Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Fri, 6 Jun 2025 15:53:22 -0400 Subject: [PATCH] Polygon, ensure that all statedb operations are traced correctly --- core/state/statedb.go | 4 ++++ core/state/statedb_hooked.go | 24 ++++++++++++++++++++++++ core/state_processor.go | 12 ++++++------ core/vm/interface.go | 10 ++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 51a2fc2193..cfb1514453 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1567,6 +1567,10 @@ func (s *StateDB) GetTrie() Trie { return s.trie } +func (s *StateDB) IsVerkle() bool { + return s.GetTrie().IsVerkle() +} + // commit gathers the state mutations accumulated along with the associated // trie changes, resetting all internal flags with the new state as the base. func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool) (*stateUpdate, error) { diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 579ebf744b..cc50bd09d8 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -20,6 +20,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/blockstm" "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" @@ -280,3 +281,26 @@ func (s *hookedStateDB) Finalise(deleteEmptyObjects bool) { } } } + +func (s *hookedStateDB) GetLogs(txHash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log { + return s.inner.GetLogs(txHash, blockNumber, blockHash) +} + +func (s *hookedStateDB) GetMVHashmap() *blockstm.MVHashMap { + return s.inner.GetMVHashmap() +} +func (s *hookedStateDB) SetMVHashmap(mvHashmap *blockstm.MVHashMap) { + s.inner.SetMVHashmap(mvHashmap) +} +func (s *hookedStateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { + return s.inner.IntermediateRoot(deleteEmptyObjects) +} +func (s *hookedStateDB) IsVerkle() bool { + return s.inner.IsVerkle() +} +func (s *hookedStateDB) TxIndex() int { + return s.inner.TxIndex() +} +func (s *hookedStateDB) SetTxContext(txHash common.Hash, txIndex int) { + s.inner.SetTxContext(txHash, txIndex) +} diff --git a/core/state_processor.go b/core/state_processor.go index f2c8d74004..874ee994e2 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -108,9 +108,9 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } - statedb.SetTxContext(tx.Hash(), i) + tracingStateDB.SetTxContext(tx.Hash(), i) - receipt, err := ApplyTransactionWithEVM(msg, gp, statedb, blockNumber, blockHash, tx, usedGas, evm, interruptCtx) + receipt, err := ApplyTransactionWithEVM(msg, gp, tracingStateDB, blockNumber, blockHash, tx, usedGas, evm, interruptCtx) if err != nil { return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } @@ -154,7 +154,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // ApplyTransactionWithEVM attempts to apply a transaction to the given state database // and uses the input parameters for its environment similar to ApplyTransaction. However, // this method takes an already created EVM instance as input. -func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, interruptCtx context.Context) (receipt *types.Receipt, err error) { +func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb vm.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, interruptCtx context.Context) (receipt *types.Receipt, err error) { if hooks := evm.Config.Tracer; hooks != nil { if hooks.OnTxStart != nil { hooks.OnTxStart(evm.GetVMContext(), tx, msg.From) @@ -229,7 +229,7 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, // Merge the tx-local access event into the "block-local" one, in order to collect // all values, so that the witness can be built. - if statedb.GetTrie().IsVerkle() { + if statedb.IsVerkle() { statedb.AccessEvents().Merge(evm.AccessEvents) } @@ -237,7 +237,7 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, } // MakeReceipt generates the receipt object for a transaction given its execution result. -func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte) *types.Receipt { +func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb vm.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte) *types.Receipt { // Create a new receipt for the transaction, storing the intermediate root and gas used // by the tx. receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: usedGas} @@ -273,7 +273,7 @@ func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, b // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(evm *vm.EVM, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, interruptCtx context.Context) (*types.Receipt, error) { +func ApplyTransaction(evm *vm.EVM, gp *GasPool, statedb vm.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, interruptCtx context.Context) (*types.Receipt, error) { msg, err := TransactionToMessage(tx, types.MakeSigner(evm.ChainConfig(), header.Number, header.Time), header.BaseFee) if err != nil { return nil, err diff --git a/core/vm/interface.go b/core/vm/interface.go index 57f35cb249..1921ead5f6 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -18,6 +18,7 @@ package vm import ( "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/blockstm" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/tracing" @@ -101,4 +102,13 @@ type StateDB interface { // Finalise must be invoked at the end of a transaction Finalise(bool) + + // Polygon Specific StateDB methods + GetMVHashmap() *blockstm.MVHashMap + SetMVHashmap(mvHashmap *blockstm.MVHashMap) + IntermediateRoot(deleteEmptyObjects bool) common.Hash + IsVerkle() bool + GetLogs(txHash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log + TxIndex() int + SetTxContext(txHash common.Hash, txIndex int) }