From 4282087fb0d84dc492ed0b462f143be7ad614b36 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Mon, 29 Sep 2025 21:50:48 +0800 Subject: [PATCH] bal execution refactor (wip) --- core/blockchain.go | 4 +- core/state/bal_reader.go | 2 + core/state/block_access_list_creation.go | 218 ----------------------- core/state/interface.go | 103 ----------- core/state/statedb.go | 2 +- tests/block_test_util.go | 4 +- 6 files changed, 6 insertions(+), 327 deletions(-) delete mode 100644 core/state/block_access_list_creation.go delete mode 100644 core/state/interface.go diff --git a/core/blockchain.go b/core/blockchain.go index a0be51bf5f..d35c78ae4a 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -210,8 +210,6 @@ type BlockChainConfig struct { // StateSizeTracking indicates whether the state size tracking is enabled. StateSizeTracking bool - // EnableBAL enables block access list creation and verification for post-Cancun blocks which contain access lists. - EnableBAL bool } // DefaultConfig returns the default config. @@ -1924,7 +1922,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness start := time.Now() // construct or verify block access lists if BALs are enabled and // we are post-selfdestruct removal fork. - enableBAL := (bc.cfg.EnableBAL && bc.chainConfig.IsCancun(block.Number(), block.Time())) || bc.chainConfig.IsAmsterdam(block.Number(), block.Time()) + enableBAL := (bc.cfg.EnableBALForTesting && bc.chainConfig.IsCancun(block.Number(), block.Time())) || bc.chainConfig.IsAmsterdam(block.Number(), block.Time()) blockHasAccessList := block.Body().AccessList != nil makeBAL := enableBAL && !blockHasAccessList validateBAL := enableBAL && blockHasAccessList diff --git a/core/state/bal_reader.go b/core/state/bal_reader.go index c59bf4c035..1c6820ad9c 100644 --- a/core/state/bal_reader.go +++ b/core/state/bal_reader.go @@ -168,6 +168,7 @@ func (r *BALReader) ModifiedAccounts() (res []common.Address) { } func (r *BALReader) ValidateStateReads(allReads bal.StateAccesses) error { + fmt.Printf("bal is %v\n", r.block.Body().AccessList.String()) // 1. remove any slots from 'allReads' which were written // 2. validate that the read set in the BAL matches 'allReads' exactly for addr, reads := range allReads { @@ -178,6 +179,7 @@ func (r *BALReader) ValidateStateReads(allReads bal.StateAccesses) error { } } + fmt.Printf("addr is %x\n", addr) expectedReads := r.accesses[addr].StorageReads if len(reads) != len(expectedReads) { return fmt.Errorf("mismatch between the number of computed reads and number of expected reads") diff --git a/core/state/block_access_list_creation.go b/core/state/block_access_list_creation.go deleted file mode 100644 index 6fddb17642..0000000000 --- a/core/state/block_access_list_creation.go +++ /dev/null @@ -1,218 +0,0 @@ -package state - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/stateless" - "github.com/ethereum/go-ethereum/core/tracing" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/types/bal" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie/utils" - "github.com/holiman/uint256" -) - -type AccessListCreationDB struct { - idx uint16 - inner BlockProcessingDB - accessList *bal.ConstructionBlockAccessList -} - -func NewBlockAccessListBuilder(db BlockProcessingDB) *AccessListCreationDB { - return &AccessListCreationDB{0, db, bal.NewConstructionBlockAccessList()} -} -func (a *AccessListCreationDB) SetAccessListIndex(idx int) { - a.idx = uint16(idx) -} - -// ConstructedBlockAccessList retrieves the access list that has been constructed -// by the StateDB instance, or nil if BAL construction was not enabled. -func (a *AccessListCreationDB) ConstructedBlockAccessList() *bal.ConstructionBlockAccessList { - return a.accessList -} - -func (a *AccessListCreationDB) CreateAccount(address common.Address) { - a.inner.CreateAccount(address) -} - -func (a *AccessListCreationDB) CreateContract(address common.Address) { - a.inner.CreateContract(address) -} - -func (a *AccessListCreationDB) SubBalance(address common.Address, u *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int { - return a.inner.SubBalance(address, u, reason) -} - -func (a *AccessListCreationDB) AddBalance(address common.Address, u *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int { - return a.inner.AddBalance(address, u, reason) -} - -func (a *AccessListCreationDB) GetBalance(address common.Address) *uint256.Int { - return a.inner.GetBalance(address) -} - -func (a *AccessListCreationDB) GetNonce(address common.Address) uint64 { - return a.inner.GetNonce(address) -} - -func (a *AccessListCreationDB) SetNonce(address common.Address, u uint64, reason tracing.NonceChangeReason) { - a.inner.SetNonce(address, u, reason) -} - -func (a *AccessListCreationDB) GetCodeHash(address common.Address) common.Hash { - return a.inner.GetCodeHash(address) -} - -func (a *AccessListCreationDB) GetCode(address common.Address) []byte { - return a.inner.GetCode(address) -} - -func (a *AccessListCreationDB) SetCode(addr common.Address, code []byte, reason tracing.CodeChangeReason) (prev []byte) { - return a.inner.SetCode(addr, code, reason) -} - -func (a *AccessListCreationDB) GetCodeSize(address common.Address) int { - return a.inner.GetCodeSize(address) -} - -func (a *AccessListCreationDB) AddRefund(u uint64) { - a.inner.AddRefund(u) -} - -func (a *AccessListCreationDB) SubRefund(u uint64) { - a.inner.SubRefund(u) -} - -func (a *AccessListCreationDB) GetRefund() uint64 { - return a.inner.GetRefund() -} - -func (a *AccessListCreationDB) GetStateAndCommittedState(address common.Address, hash common.Hash) (common.Hash, common.Hash) { - return a.inner.GetStateAndCommittedState(address, hash) -} - -func (a *AccessListCreationDB) GetState(address common.Address, hash common.Hash) common.Hash { - return a.inner.GetState(address, hash) -} - -func (a *AccessListCreationDB) SetState(address common.Address, hash common.Hash, hash2 common.Hash) common.Hash { - return a.inner.SetState(address, hash, hash2) -} - -func (a *AccessListCreationDB) GetStorageRoot(addr common.Address) common.Hash { - return a.inner.GetStorageRoot(addr) -} - -func (a *AccessListCreationDB) GetTransientState(addr common.Address, key common.Hash) common.Hash { - return a.inner.GetTransientState(addr, key) -} - -func (a *AccessListCreationDB) SetTransientState(addr common.Address, key, value common.Hash) { - a.inner.SetTransientState(addr, key, value) -} - -func (a *AccessListCreationDB) SelfDestruct(address common.Address) uint256.Int { - return a.inner.SelfDestruct(address) -} - -func (a *AccessListCreationDB) HasSelfDestructed(address common.Address) bool { - return a.inner.HasSelfDestructed(address) -} - -func (a *AccessListCreationDB) SelfDestruct6780(address common.Address) (uint256.Int, bool) { - return a.inner.SelfDestruct6780(address) -} - -func (a *AccessListCreationDB) Exist(address common.Address) bool { - return a.inner.Exist(address) -} - -func (a *AccessListCreationDB) Empty(address common.Address) bool { - return a.inner.Empty(address) -} - -func (a *AccessListCreationDB) AddressInAccessList(addr common.Address) bool { - return a.inner.AddressInAccessList(addr) -} - -func (a *AccessListCreationDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) { - return a.inner.SlotInAccessList(addr, slot) -} - -func (a *AccessListCreationDB) AddAddressToAccessList(addr common.Address) { - a.inner.AddAddressToAccessList(addr) -} - -func (a *AccessListCreationDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { - a.inner.AddSlotToAccessList(addr, slot) -} - -func (a *AccessListCreationDB) PointCache() *utils.PointCache { - return a.inner.PointCache() -} - -func (a *AccessListCreationDB) Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) { - a.inner.Prepare(rules, sender, coinbase, dest, precompiles, txAccesses) -} - -func (a *AccessListCreationDB) RevertToSnapshot(i int) { - a.inner.RevertToSnapshot(i) -} - -func (a *AccessListCreationDB) Snapshot() int { - return a.inner.Snapshot() -} - -func (a *AccessListCreationDB) AddLog(log *types.Log) { - a.inner.AddLog(log) -} - -func (a *AccessListCreationDB) AddPreimage(hash common.Hash, bytes []byte) { - a.inner.AddPreimage(hash, bytes) -} - -func (a *AccessListCreationDB) Witness() *stateless.Witness { - return a.inner.Witness() -} - -func (a *AccessListCreationDB) AccessEvents() *AccessEvents { - return a.inner.AccessEvents() -} - -func (a *AccessListCreationDB) TxIndex() int { - return a.inner.TxIndex() -} - -func (a *AccessListCreationDB) Finalise(b bool) (*bal.StateDiff, *bal.StateAccesses) { - diff, accesses := a.inner.Finalise(b) - a.accessList.ApplyDiff(uint(a.idx), diff) - a.accessList.ApplyAccesses(*accesses) // TODO: can remove the pointer on accesses (map is already a reference type) - return nil, nil // TODO: not sure what to do here. The diff has been applied to the access list so it is "owned" by the access list, not sure why a caller would need it... -} - -func (a *AccessListCreationDB) GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash, blockTime uint64) []*types.Log { - return a.inner.GetLogs(hash, blockNumber, blockHash, blockTime) -} - -func (a *AccessListCreationDB) IntermediateRoot(deleteEmpty bool) common.Hash { - return a.inner.IntermediateRoot(deleteEmpty) -} - -func (a *AccessListCreationDB) Database() Database { - return a.inner.Database() -} -func (a *AccessListCreationDB) GetTrie() Trie { - return a.inner.GetTrie() -} -func (s *AccessListCreationDB) SetTxContext(thash common.Hash, ti int) { - s.inner.SetTxContext(thash, ti) -} - -func (s *AccessListCreationDB) Error() error { - return s.inner.Error() -} - -func (s *AccessListCreationDB) Copy() BlockProcessingDB { - return &AccessListCreationDB{s.idx, s.inner.Copy(), s.accessList.Copy()} -} - -var _ BlockProcessingDB = &AccessListCreationDB{} diff --git a/core/state/interface.go b/core/state/interface.go deleted file mode 100644 index 13950361cb..0000000000 --- a/core/state/interface.go +++ /dev/null @@ -1,103 +0,0 @@ -package state - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/stateless" - "github.com/ethereum/go-ethereum/core/tracing" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/types/bal" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie/utils" - "github.com/holiman/uint256" -) - -type BlockProcessingDB interface { - CreateAccount(common.Address) - CreateContract(common.Address) - - SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) uint256.Int - AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) uint256.Int - GetBalance(common.Address) *uint256.Int - - GetNonce(common.Address) uint64 - SetNonce(common.Address, uint64, tracing.NonceChangeReason) - - GetCodeHash(common.Address) common.Hash - GetCode(common.Address) []byte - - // SetCode sets the new code for the address, and returns the previous code, if any. - SetCode(addr common.Address, code []byte, reason tracing.CodeChangeReason) (prev []byte) - GetCodeSize(common.Address) int - - AddRefund(uint64) - SubRefund(uint64) - GetRefund() uint64 - - GetStateAndCommittedState(common.Address, common.Hash) (common.Hash, common.Hash) - GetState(common.Address, common.Hash) common.Hash - SetState(common.Address, common.Hash, common.Hash) common.Hash - GetStorageRoot(addr common.Address) common.Hash - - GetTransientState(addr common.Address, key common.Hash) common.Hash - SetTransientState(addr common.Address, key, value common.Hash) - - SelfDestruct(common.Address) uint256.Int - HasSelfDestructed(common.Address) bool - - // SelfDestruct6780 is post-EIP6780 selfdestruct, which means that it's a - // send-all-to-beneficiary, unless the contract was created in this same - // transaction, in which case it will be destructed. - // This method returns the prior balance, along with a boolean which is - // true iff the object was indeed destructed. - SelfDestruct6780(common.Address) (uint256.Int, bool) - - // Exist reports whether the given account exists in - // Notably this also returns true for self-destructed accounts within the current transaction. - Exist(common.Address) bool - // Empty returns whether the given account is empty. Empty - // is defined according to EIP161 (balance = nonce = code = 0). - Empty(common.Address) bool - - AddressInAccessList(addr common.Address) bool - SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) - // AddAddressToAccessList adds the given address to the access list. This operation is safe to perform - // even if the feature/fork is not active yet - AddAddressToAccessList(addr common.Address) - // AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform - // even if the feature/fork is not active yet - AddSlotToAccessList(addr common.Address, slot common.Hash) - - // PointCache returns the point cache used in computations - PointCache() *utils.PointCache - - Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) - - RevertToSnapshot(int) - Snapshot() int - - AddLog(*types.Log) - AddPreimage(common.Hash, []byte) - - Witness() *stateless.Witness - - AccessEvents() *AccessEvents - - // Finalise must be invoked at the end of a transaction - Finalise(bool) (*bal.StateDiff, *bal.StateAccesses) - - // These two methods are not used in the EVM. however, I need them to be part of the interface - // so that block processing/production can use instances of this interface so that the StateDB - // wrapped with BAL creation functionality can be passed in case of BALs - GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash, blockTime uint64) []*types.Log - - IntermediateRoot(deleteEmpty bool) common.Hash - - Database() Database - GetTrie() Trie - SetTxContext(thash common.Hash, ti int) - Error() error - - TxIndex() int - - Copy() BlockProcessingDB -} diff --git a/core/state/statedb.go b/core/state/statedb.go index d24b559d16..606102a53c 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -778,7 +778,7 @@ func (s *StateDB) CreateContract(addr common.Address) { // Copy creates a deep, independent copy of the state. // Snapshots of the copied state cannot be applied to the copy. -func (s *StateDB) Copy() BlockProcessingDB { +func (s *StateDB) Copy() *StateDB { // Copy all the basic fields, initialize the memory ones state := &StateDB{ db: s.db, diff --git a/tests/block_test_util.go b/tests/block_test_util.go index caa44d4ba6..f694efd84d 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -158,8 +158,8 @@ func (t *BlockTest) createTestBlockChain(config *params.ChainConfig, snapshotter Tracer: tracer, StatelessSelfValidation: witness, }, - NoPrefetch: true, - EnableBAL: createAndVerifyBAL, + NoPrefetch: true, + EnableBALForTesting: createAndVerifyBAL, } if snapshotter { options.SnapshotLimit = 1