From ee58cc79d9dd4631e87cad30338543324434f20d Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Tue, 7 Nov 2023 15:41:58 +0300 Subject: [PATCH] statedb: precompile check before onNewAccount --- cmd/geth/chaincmd.go | 2 +- core/state/statedb.go | 20 ++++++++++++++++++-- core/state_processor.go | 2 ++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 2627c6caf3..587856b2bf 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -215,7 +215,7 @@ func initGenesis(ctx *cli.Context) error { triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false) defer triedb.Close() - _, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + _, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides, nil) if err != nil { utils.Fatalf("Failed to write genesis block: %v", err) } diff --git a/core/state/statedb.go b/core/state/statedb.go index 1ea386876f..112f104783 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -123,6 +123,9 @@ type StateDB struct { // Preimages occurred seen by VM in the scope of block. preimages map[common.Hash][]byte + // Enabled precompile contracts + precompiles map[common.Address]struct{} + // Per-transaction access list accessList *accessList @@ -179,6 +182,7 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) stateObjectsDestruct: make(map[common.Address]*types.StateAccount), logs: make(map[common.Hash][]*types.Log), preimages: make(map[common.Hash][]byte), + precompiles: make(map[common.Address]struct{}), journal: newJournal(), accessList: newAccessList(), transientStorage: newTransientStorage(), @@ -656,9 +660,12 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) newobj = newObject(s, addr, nil) if prev == nil { s.journal.append(createObjectChange{account: &addr}) - // TODO: add isPrecompile check if s.logger != nil { - s.logger.OnNewAccount(addr) + // Precompiled contracts are touched during a call. + // Make sure we avoid emitting a new account event for them. + if _, ok := s.precompiles[addr]; !ok { + s.logger.OnNewAccount(addr) + } } } else { // The original account should be marked as destructed and all cached @@ -1372,6 +1379,15 @@ func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, d s.transientStorage = newTransientStorage() } +// PrepareBlock prepares the statedb for execution of a block. It tracks +// the addresses of enabled precompiles for debugging purposes. +func (s *StateDB) PrepareBlock(precompiles []common.Address) { + s.precompiles = make(map[common.Address]struct{}) + for _, addr := range precompiles { + s.precompiles[addr] = struct{}{} + } +} + // AddAddressToAccessList adds the given address to the access list func (s *StateDB) AddAddressToAccessList(addr common.Address) { if s.accessList.AddAddress(addr) { diff --git a/core/state_processor.go b/core/state_processor.go index 1517e2c0c9..e2e2fe1a02 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -75,11 +75,13 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg var ( context = NewEVMBlockContext(header, p.bc, nil) vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg) + rules = vmenv.ChainConfig().Rules(context.BlockNumber, context.Random != nil, context.Time) signer = types.MakeSigner(p.config, header.Number, header.Time) ) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) } + statedb.PrepareBlock(vm.ActivePrecompiles(rules)) // Iterate over and process the individual transactions for i, tx := range block.Transactions() { msg, err := TransactionToMessage(tx, signer, header.BaseFee)