diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index eb5e74cab7..442c60ade4 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -272,13 +272,8 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa return err } } - - if chain.Config().IsAmsterdam(header.Number, header.Time) { - if header.BlockAccessListHash == nil { - // TODO: (self study). figure out if any of the header checks here overlap with the - // other location that I validate the block access list hash. - return fmt.Errorf("block access list hash must be set in header post-Amsterdam") - } + if chain.Config().IsAmsterdam(header.Number, header.Time) && header.BlockAccessListHash == nil { + return fmt.Errorf("block access list hash must be set post-Amsterdam") } return nil } diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index 6cbdad0c36..359d5e03ac 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -63,7 +63,6 @@ func latestBlobConfig(cfg *params.ChainConfig, time uint64) *BlobConfig { bc *params.BlobConfig ) switch { - case cfg.IsBPO5(london, time) && s.BPO5 != nil: bc = s.BPO5 case cfg.IsBPO4(london, time) && s.BPO4 != nil: diff --git a/core/block_access_list_creation.go b/core/block_access_list_tracer.go similarity index 74% rename from core/block_access_list_creation.go rename to core/block_access_list_tracer.go index cd87f3726d..49fe14ae10 100644 --- a/core/block_access_list_creation.go +++ b/core/block_access_list_tracer.go @@ -15,15 +15,11 @@ type accountPrestate struct { code []byte } -// BlockAccessListTracer constructs an EIP-7928 block access list from the -// execution of a block +// BlockAccessListTracer is a tracer which gathers state accesses/mutations +// from the execution of a block. It is used for constructing and verifying +// EIP-7928 block access lists. type BlockAccessListTracer struct { - // this is a set of access lists for each call scope. the overall block access lists - // is accrued at index 0, while the access lists of various nested execution - // scopes are in the proceeding indices. - // When an execution scope terminates in a non-reverting fashion, the changes are - // merged into the access list of the parent scope. - accessList *bal.ConstructionBlockAccessList + builder *bal.BlockAccessListBuilder // the access list index that changes are currently being recorded into balIdx uint16 @@ -32,7 +28,7 @@ type BlockAccessListTracer struct { // NewBlockAccessListTracer returns an BlockAccessListTracer and a set of hooks func NewBlockAccessListTracer() (*BlockAccessListTracer, *tracing.Hooks) { balTracer := &BlockAccessListTracer{ - accessList: bal.NewConstructionBlockAccessList(), + builder: bal.NewConstructionBlockAccessList(), } hooks := &tracing.Hooks{ OnBlockFinalization: balTracer.OnBlockFinalization, @@ -58,62 +54,62 @@ func NewBlockAccessListTracer() (*BlockAccessListTracer, *tracing.Hooks) { // AccessList returns the constructed access list. // It is assumed that this is only called after all the block state changes // have been executed and the block has been finalized. -func (a *BlockAccessListTracer) AccessList() *bal.ConstructionBlockAccessList { - return a.accessList +func (a *BlockAccessListTracer) AccessList() *bal.BlockAccessListBuilder { + return a.builder } func (a *BlockAccessListTracer) OnPreTxExecutionDone() { - a.accessList.FinalisePendingChanges(0) + a.builder.FinalisePendingChanges(0) a.balIdx++ } func (a *BlockAccessListTracer) TxEndHook(receipt *types.Receipt, err error) { - a.accessList.FinalisePendingChanges(a.balIdx) + a.builder.FinalisePendingChanges(a.balIdx) a.balIdx++ } func (a *BlockAccessListTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - a.accessList.EnterScope() + a.builder.EnterScope() } func (a *BlockAccessListTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { - a.accessList.ExitScope(reverted) + a.builder.ExitScope(reverted) } func (a *BlockAccessListTracer) OnCodeChange(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) { // TODO: if we don't have this equality check, some tests fail. should be investigated. // probably the tracer shouldn't invoke code change if the code didn't actually change tho. if prevCodeHash != codeHash { - a.accessList.CodeChange(addr, prevCode, code) + a.builder.CodeChange(addr, prevCode, code) } } func (a *BlockAccessListTracer) OnSelfDestruct(addr common.Address) { - a.accessList.SelfDestruct(addr) + a.builder.SelfDestruct(addr) } func (a *BlockAccessListTracer) OnBlockFinalization() { - a.accessList.FinalisePendingChanges(a.balIdx) + a.builder.FinalisePendingChanges(a.balIdx) } func (a *BlockAccessListTracer) OnBalanceChange(addr common.Address, prevBalance, newBalance *big.Int, _ tracing.BalanceChangeReason) { newU256 := new(uint256.Int).SetBytes(newBalance.Bytes()) prevU256 := new(uint256.Int).SetBytes(prevBalance.Bytes()) - a.accessList.BalanceChange(addr, prevU256, newU256) + a.builder.BalanceChange(addr, prevU256, newU256) } func (a *BlockAccessListTracer) OnNonceChange(addr common.Address, prev uint64, new uint64, reason tracing.NonceChangeReason) { - a.accessList.NonceChange(addr, prev, new) + a.builder.NonceChange(addr, prev, new) } func (a *BlockAccessListTracer) OnStorageRead(addr common.Address, key common.Hash) { - a.accessList.StorageRead(addr, key) + a.builder.StorageRead(addr, key) } func (a *BlockAccessListTracer) OnAcountRead(addr common.Address) { - a.accessList.AccountRead(addr) + a.builder.AccountRead(addr) } func (a *BlockAccessListTracer) OnStorageChange(addr common.Address, slot common.Hash, prev common.Hash, new common.Hash) { - a.accessList.StorageWrite(addr, slot, prev, new) + a.builder.StorageWrite(addr, slot, prev, new) } diff --git a/core/block_validator.go b/core/block_validator.go index 5812d40605..4b6284a002 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -114,8 +114,6 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { if v.config.IsAmsterdam(block.Number(), block.Time()) { if block.Body().AccessList == nil { return fmt.Errorf("access list not present in block body") - } else if block.Header().BlockAccessListHash == nil { - return fmt.Errorf("access list hash not present in block header") } else if *block.Header().BlockAccessListHash != block.Body().AccessList.Hash() { return fmt.Errorf("access list hash mismatch. local: %x. remote: %x\n", block.Body().AccessList.Hash(), *block.Header().BlockAccessListHash) } else if err := block.Body().AccessList.Validate(); err != nil { diff --git a/core/parallel_state_processor.go b/core/parallel_state_processor.go index f406562db4..0bdbf7ca46 100644 --- a/core/parallel_state_processor.go +++ b/core/parallel_state_processor.go @@ -125,7 +125,7 @@ func (p *ParallelStateProcessor) prepareExecResult(block *types.Block, allStateR postTxState.Finalise(true) balTracer.OnBlockFinalization() - diff, stateReads := balTracer.accessList.FinalizedIdxChanges() + diff, stateReads := balTracer.builder.FinalizedIdxChanges() allStateReads.Merge(stateReads) balIdx := len(block.Transactions()) + 1 @@ -278,7 +278,7 @@ func (p *ParallelStateProcessor) execTx(block *types.Block, tx *types.Transactio return &txExecResult{err: err} } - diff, accesses := balTracer.accessList.FinalizedIdxChanges() + diff, accesses := balTracer.builder.FinalizedIdxChanges() if err := db.BlockAccessList().ValidateStateDiff(txIdx+1, diff); err != nil { return &txExecResult{err: err} } @@ -335,7 +335,7 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat // TODO: weird that I have to manually call finalize here balTracer.OnPreTxExecutionDone() - diff, stateReads := balTracer.accessList.FinalizedIdxChanges() + diff, stateReads := balTracer.builder.FinalizedIdxChanges() if err := statedb.BlockAccessList().ValidateStateDiff(0, diff); err != nil { return nil, err } diff --git a/core/state/bal_reader.go b/core/state/bal_reader.go index 5642695d15..3bd343abf7 100644 --- a/core/state/bal_reader.go +++ b/core/state/bal_reader.go @@ -67,7 +67,7 @@ func (p *prestateResolver) account(addr common.Address) *types.StateAccount { return res.(*types.StateAccount) } -func (r *BALReader) initObjFromDiff(db *StateDB, addr common.Address, a *types.StateAccount, diff *bal.AccountState) *stateObject { +func (r *BALReader) initObjFromDiff(db *StateDB, addr common.Address, a *types.StateAccount, diff *bal.AccountMutations) *stateObject { var acct *types.StateAccount if a == nil { acct = &types.StateAccount{ @@ -104,7 +104,7 @@ func (r *BALReader) initObjFromDiff(db *StateDB, addr common.Address, a *types.S return obj } -func (s *BALReader) initMutatedObjFromDiff(db *StateDB, addr common.Address, a *types.StateAccount, diff *bal.AccountState) *stateObject { +func (s *BALReader) initMutatedObjFromDiff(db *StateDB, addr common.Address, a *types.StateAccount, diff *bal.AccountMutations) *stateObject { var acct *types.StateAccount if a == nil { acct = &types.StateAccount{ @@ -231,7 +231,7 @@ func (r *BALReader) StateRoot(prestate *StateDB) (root common.Hash, prestateLoad // changesAt returns all state changes at the given index. func (r *BALReader) changesAt(idx int) *bal.StateDiff { - res := &bal.StateDiff{make(map[common.Address]*bal.AccountState)} + res := &bal.StateDiff{make(map[common.Address]*bal.AccountMutations)} for addr, _ := range r.accesses { accountChanges := r.accountChangesAt(addr, idx) if accountChanges != nil { @@ -243,13 +243,13 @@ func (r *BALReader) changesAt(idx int) *bal.StateDiff { // accountChangesAt returns the state changes of an account at a given index, // or nil if there are no changes. -func (r *BALReader) accountChangesAt(addr common.Address, idx int) *bal.AccountState { +func (r *BALReader) accountChangesAt(addr common.Address, idx int) *bal.AccountMutations { acct, exist := r.accesses[addr] if !exist { return nil } - var res bal.AccountState + var res bal.AccountMutations for i := len(acct.BalanceChanges) - 1; i >= 0; i-- { if acct.BalanceChanges[i].TxIdx == uint16(idx) { @@ -321,13 +321,13 @@ func (r *BALReader) readAccount(db *StateDB, addr common.Address, idx int) *stat } // readAccountDiff returns the accumulated state changes of an account up through idx. -func (r *BALReader) readAccountDiff(addr common.Address, idx int) *bal.AccountState { +func (r *BALReader) readAccountDiff(addr common.Address, idx int) *bal.AccountMutations { diff, exist := r.accesses[addr] if !exist { return nil } - var res bal.AccountState + var res bal.AccountMutations for i := 0; i < len(diff.BalanceChanges) && diff.BalanceChanges[i].TxIdx <= uint16(idx); i++ { res.Balance = diff.BalanceChanges[i].Balance diff --git a/core/types/bal/bal.go b/core/types/bal/bal.go index 9f49ebce96..2164c70802 100644 --- a/core/types/bal/bal.go +++ b/core/types/bal/bal.go @@ -28,21 +28,21 @@ import ( // idxAccessListBuilder is responsible for producing the state accesses and // reads recorded within the scope of a single index in the access list. type idxAccessListBuilder struct { - // stores the tx-prestate values of any account/storage values which were modified - // - // TODO: it's a bit unfortunate that the prestate.StorageWrites is reused here to - // represent the prestate values of keys which were written and it would be nice to - // somehow make it clear that the field can contain both the mutated values or the - // prestate depending on the context (or find a cleaner solution entirely, instead - // of reusing the field here) - prestates map[common.Address]*AccountState + // stores the previous values of any account data that was modified in the + // current index. + prestates map[common.Address]*partialAccountState + // a stack which maintains a set of state mutations/reads for each EVM + // execution frame. + // + // + // TODO: how does this construction handle EVM errors which terminate execution of a transaction entirely. accessesStack []map[common.Address]*constructionAccountAccess } func newAccessListBuilder() *idxAccessListBuilder { return &idxAccessListBuilder{ - make(map[common.Address]*AccountState), + make(map[common.Address]*partialAccountState), []map[common.Address]*constructionAccountAccess{ make(map[common.Address]*constructionAccountAccess), }, @@ -65,7 +65,7 @@ func (c *idxAccessListBuilder) accountRead(address common.Address) { func (c *idxAccessListBuilder) storageWrite(address common.Address, key, prevVal, newVal common.Hash) { if _, ok := c.prestates[address]; !ok { - c.prestates[address] = &AccountState{} + c.prestates[address] = &AccountMutations{} } if c.prestates[address].StorageWrites == nil { c.prestates[address].StorageWrites = make(map[common.Hash]common.Hash) @@ -83,7 +83,7 @@ func (c *idxAccessListBuilder) storageWrite(address common.Address, key, prevVal func (c *idxAccessListBuilder) balanceChange(address common.Address, prev, cur *uint256.Int) { if _, ok := c.prestates[address]; !ok { - c.prestates[address] = &AccountState{} + c.prestates[address] = &AccountMutations{} } if c.prestates[address].Balance == nil { c.prestates[address].Balance = prev @@ -104,7 +104,7 @@ func (c *idxAccessListBuilder) codeChange(address common.Address, prev, cur []by } if _, ok := c.prestates[address]; !ok { - c.prestates[address] = &AccountState{} + c.prestates[address] = &AccountMutations{} } if c.prestates[address].Code == nil { c.prestates[address].Code = prev @@ -145,7 +145,7 @@ func (c *idxAccessListBuilder) selfDestruct(address common.Address) { func (c *idxAccessListBuilder) nonceChange(address common.Address, prev, cur uint64) { if _, ok := c.prestates[address]; !ok { - c.prestates[address] = &AccountState{} + c.prestates[address] = &AccountMutations{} } if c.prestates[address].Nonce == nil { c.prestates[address].Nonce = &prev @@ -186,7 +186,7 @@ func (c *idxAccessListBuilder) exitScope(reverted bool) { // state which was accessed. The idxAccessListBuilder instance should be discarded // after calling finalise. func (a *idxAccessListBuilder) finalise() (*StateDiff, StateAccesses) { - diff := &StateDiff{make(map[common.Address]*AccountState)} + diff := &StateDiff{make(map[common.Address]*AccountMutations)} stateAccesses := make(StateAccesses) for addr, access := range a.accessesStack[0] { @@ -224,7 +224,7 @@ func (a *idxAccessListBuilder) finalise() (*StateDiff, StateAccesses) { } stateAccesses[addr] = access.storageReads - diff.Mutations[addr] = &AccountState{ + diff.Mutations[addr] = &AccountMutations{ Balance: access.balance, Nonce: access.nonce, Code: access.code, @@ -235,15 +235,15 @@ func (a *idxAccessListBuilder) finalise() (*StateDiff, StateAccesses) { return diff, stateAccesses } -func (c *ConstructionBlockAccessList) FinalisePendingChanges(idx uint16) { - diff, accesses := c.nonFinalizedAccessList.finalise() - c.nonFinalizedAccessList = newAccessListBuilder() +func (c *BlockAccessListBuilder) FinalisePendingChanges(idx uint16) { + diff, accesses := c.idxBuilder.finalise() + c.idxBuilder = newAccessListBuilder() for addr, stateDiff := range diff.Mutations { - acctChanges, ok := c.Accounts[addr] + acctChanges, ok := c.FinalizedAccesses[addr] if !ok { acctChanges = &ConstructionAccountAccesses{} - c.Accounts[addr] = acctChanges + c.FinalizedAccesses[addr] = acctChanges } if stateDiff.Nonce != nil { @@ -286,10 +286,10 @@ func (c *ConstructionBlockAccessList) FinalisePendingChanges(idx uint16) { } } for addr, stateAccesses := range accesses { - acctAccess, ok := c.Accounts[addr] + acctAccess, ok := c.FinalizedAccesses[addr] if !ok { acctAccess = &ConstructionAccountAccesses{} - c.Accounts[addr] = acctAccess + c.FinalizedAccesses[addr] = acctAccess } for key := range stateAccesses { @@ -308,39 +308,39 @@ func (c *ConstructionBlockAccessList) FinalisePendingChanges(idx uint16) { c.lastFinalizedAccesses = accesses } -func (c *ConstructionBlockAccessList) StorageRead(address common.Address, key common.Hash) { - c.nonFinalizedAccessList.storageRead(address, key) +func (c *BlockAccessListBuilder) StorageRead(address common.Address, key common.Hash) { + c.idxBuilder.storageRead(address, key) } -func (c *ConstructionBlockAccessList) AccountRead(address common.Address) { - c.nonFinalizedAccessList.accountRead(address) +func (c *BlockAccessListBuilder) AccountRead(address common.Address) { + c.idxBuilder.accountRead(address) } -func (c *ConstructionBlockAccessList) StorageWrite(address common.Address, key, prevVal, newVal common.Hash) { - c.nonFinalizedAccessList.storageWrite(address, key, prevVal, newVal) +func (c *BlockAccessListBuilder) StorageWrite(address common.Address, key, prevVal, newVal common.Hash) { + c.idxBuilder.storageWrite(address, key, prevVal, newVal) } -func (c *ConstructionBlockAccessList) BalanceChange(address common.Address, prev, cur *uint256.Int) { - c.nonFinalizedAccessList.balanceChange(address, prev, cur) +func (c *BlockAccessListBuilder) BalanceChange(address common.Address, prev, cur *uint256.Int) { + c.idxBuilder.balanceChange(address, prev, cur) } -func (c *ConstructionBlockAccessList) NonceChange(address common.Address, prev, cur uint64) { - c.nonFinalizedAccessList.nonceChange(address, prev, cur) +func (c *BlockAccessListBuilder) NonceChange(address common.Address, prev, cur uint64) { + c.idxBuilder.nonceChange(address, prev, cur) } -func (c *ConstructionBlockAccessList) CodeChange(address common.Address, prev, cur []byte) { - c.nonFinalizedAccessList.codeChange(address, prev, cur) +func (c *BlockAccessListBuilder) CodeChange(address common.Address, prev, cur []byte) { + c.idxBuilder.codeChange(address, prev, cur) } -func (c *ConstructionBlockAccessList) SelfDestruct(address common.Address) { - c.nonFinalizedAccessList.selfDestruct(address) +func (c *BlockAccessListBuilder) SelfDestruct(address common.Address) { + c.idxBuilder.selfDestruct(address) } -func (c *ConstructionBlockAccessList) EnterScope() { - c.nonFinalizedAccessList.enterScope() +func (c *BlockAccessListBuilder) EnterScope() { + c.idxBuilder.enterScope() } -func (c *ConstructionBlockAccessList) ExitScope(reverted bool) { - c.nonFinalizedAccessList.exitScope(reverted) +func (c *BlockAccessListBuilder) ExitScope(reverted bool) { + c.idxBuilder.exitScope(reverted) } // TODO: the BalReader Validation method should accept the computed values as // a index/StateDiff/StateAccesses trio. -// BAL tracer maintains a ConstructionBlockAccessList. +// BAL tracer maintains a BlockAccessListBuilder. // For each BAL index, it instantiates an idxAccessListBuilder and // appends the result to the access list where appropriate @@ -505,31 +505,19 @@ func (c *constructionAccountAccess) NonceChange(cur uint64) { c.nonce = &cur } -// NewConstructionAccountAccesses initializes the account access object. -func NewConstructionAccountAccesses() *ConstructionAccountAccesses { - return &ConstructionAccountAccesses{ - StorageWrites: make(map[common.Hash]map[uint16]common.Hash), - StorageReads: make(map[common.Hash]struct{}), - BalanceChanges: make(map[uint16]*uint256.Int), - NonceChanges: make(map[uint16]uint64), - CodeChanges: make(map[uint16]CodeChange), - } -} +// BlockAccessListBuilder is used to build an EIP-7928 block access list +type BlockAccessListBuilder struct { + FinalizedAccesses map[common.Address]*ConstructionAccountAccesses -// ConstructionBlockAccessList contains post-block modified state and some state accessed -// in execution (account addresses and storage keys). -type ConstructionBlockAccessList struct { - Accounts map[common.Address]*ConstructionAccountAccesses - - nonFinalizedAccessList *idxAccessListBuilder + idxBuilder *idxAccessListBuilder lastFinalizedMutations *StateDiff lastFinalizedAccesses StateAccesses } // NewConstructionBlockAccessList instantiates an empty access list. -func NewConstructionBlockAccessList() *ConstructionBlockAccessList { - return &ConstructionBlockAccessList{ +func NewConstructionBlockAccessList() *BlockAccessListBuilder { + return &BlockAccessListBuilder{ make(map[common.Address]*ConstructionAccountAccesses), newAccessListBuilder(), nil, @@ -538,9 +526,9 @@ func NewConstructionBlockAccessList() *ConstructionBlockAccessList { } // Copy returns a deep copy of the access list. -func (c *ConstructionBlockAccessList) Copy() *ConstructionBlockAccessList { +func (c *BlockAccessListBuilder) Copy() *BlockAccessListBuilder { res := NewConstructionBlockAccessList() - for addr, aa := range c.Accounts { + for addr, aa := range c.FinalizedAccesses { var aaCopy ConstructionAccountAccesses slotWrites := make(map[common.Hash]map[uint16]common.Hash, len(aa.StorageWrites)) @@ -564,21 +552,28 @@ func (c *ConstructionBlockAccessList) Copy() *ConstructionBlockAccessList { Code: bytes.Clone(codeChange.Code), } } - res.Accounts[addr] = &aaCopy + res.FinalizedAccesses[addr] = &aaCopy } return res } -func (c *ConstructionBlockAccessList) FinalizedIdxChanges() (*StateDiff, StateAccesses) { +// FinalizedIdxChanges returns the state mutations and accesses recorded in the latest +// access list index that was finalized. +func (c *BlockAccessListBuilder) FinalizedIdxChanges() (*StateDiff, StateAccesses) { return c.lastFinalizedMutations, c.lastFinalizedAccesses } +// StateDiff contains state mutations occuring over one or more access list +// index. type StateDiff struct { - Mutations map[common.Address]*AccountState `json:"Mutations,omitempty"` + Mutations map[common.Address]*AccountMutations `json:"Mutations,omitempty"` } +// StateAccesses contains a set of accounts/storage that were accessed during the +// execution of one or more access list indices. type StateAccesses map[common.Address]map[common.Hash]struct{} +// Merge combines adds the accesses from other into s. func (s *StateAccesses) Merge(other StateAccesses) { for addr, accesses := range other { if _, ok := (*s)[addr]; !ok { @@ -590,18 +585,24 @@ func (s *StateAccesses) Merge(other StateAccesses) { } } -type AccountState struct { +type partialAccountState struct { + balance *uint256.Int `json:"Balance,omitempty"` + nonce *uint64 `json:"Nonce,omitempty"` + code ContractCode `json:"Code,omitempty"` + storage map[common.Hash]common.Hash `json:"StorageWrites,omitempty"` +} + +// AccountMutations contains mutations that were made to an account across +// one or more access list indices. +type AccountMutations struct { Balance *uint256.Int `json:"Balance,omitempty"` Nonce *uint64 `json:"Nonce,omitempty"` Code ContractCode `json:"Code,omitempty"` StorageWrites map[common.Hash]common.Hash `json:"StorageWrites,omitempty"` } -func (a *AccountState) Empty() bool { - return a.Balance == nil && a.Nonce == nil && a.Code == nil && len(a.StorageWrites) == 0 -} - -func (a *AccountState) String() string { +// String returns a human-readable JSON representation of the account mutations. +func (a *AccountMutations) String() string { var res bytes.Buffer enc := json.NewEncoder(&res) enc.SetIndent("", " ") @@ -609,39 +610,8 @@ func (a *AccountState) String() string { return res.String() } -// Merge the changes of a future AccountState into the caller, resulting in the -// combined state changes through next. -func (a *AccountState) Merge(next *AccountState) { - if next.Balance != nil { - a.Balance = next.Balance - } - if next.Nonce != nil { - a.Nonce = next.Nonce - } - if next.Code != nil { - a.Code = next.Code - } - if next.StorageWrites != nil { - if a.StorageWrites == nil { - a.StorageWrites = maps.Clone(next.StorageWrites) - } else { - for key, val := range next.StorageWrites { - a.StorageWrites[key] = val - } - } - } -} - -func NewEmptyAccountState() *AccountState { - return &AccountState{ - nil, - nil, - nil, - nil, - } -} - -func (a *AccountState) Eq(other *AccountState) bool { +// Eq returns whether the calling instance is equal to the provided one. +func (a *AccountMutations) Eq(other *AccountMutations) bool { if a.Balance != nil || other.Balance != nil { if a.Balance == nil || other.Balance == nil { return false @@ -678,8 +648,14 @@ func (a *AccountState) Eq(other *AccountState) bool { return true } -func (a *AccountState) Copy() *AccountState { - res := NewEmptyAccountState() +// Copy returns a deep-copy of the instance. +func (a *AccountMutations) Copy() *AccountMutations { + res := &AccountMutations{ + nil, + nil, + nil, + nil, + } if a.Nonce != nil { res.Nonce = new(uint64) *res.Nonce = *a.Nonce @@ -696,6 +672,7 @@ func (a *AccountState) Copy() *AccountState { return res } +// String returns the state diff as a formatted JSON string. func (s *StateDiff) String() string { var res bytes.Buffer enc := json.NewEncoder(&res) @@ -733,8 +710,9 @@ func (s *StateDiff) Merge(next *StateDiff) { } } +// Copy returns a deep copy of the StateDiff func (s *StateDiff) Copy() *StateDiff { - res := &StateDiff{make(map[common.Address]*AccountState)} + res := &StateDiff{make(map[common.Address]*AccountMutations)} for addr, accountDiff := range s.Mutations { cpy := accountDiff.Copy() res.Mutations[addr] = cpy diff --git a/core/types/bal/bal_encoding.go b/core/types/bal/bal_encoding.go index 4ce3c3bfe9..e375e953f7 100644 --- a/core/types/bal/bal_encoding.go +++ b/core/types/bal/bal_encoding.go @@ -38,7 +38,7 @@ import ( // These are objects used as input for the access list encoding. They mirror // the spec format. -// BlockAccessList is the encoding format of ConstructionBlockAccessList. +// BlockAccessList is the encoding format of BlockAccessListBuilder. type BlockAccessList []AccountAccess func (e BlockAccessList) EncodeRLP(_w io.Writer) error { @@ -245,11 +245,11 @@ func (e *AccountAccess) Copy() AccountAccess { } // EncodeRLP returns the RLP-encoded access list -func (c *ConstructionBlockAccessList) EncodeRLP(wr io.Writer) error { +func (c *BlockAccessListBuilder) EncodeRLP(wr io.Writer) error { return c.ToEncodingObj().EncodeRLP(wr) } -var _ rlp.Encoder = &ConstructionBlockAccessList{} +var _ rlp.Encoder = &BlockAccessListBuilder{} // toEncodingObj creates an instance of the ConstructionAccountAccesses of the type that is // used as input for the encoding. @@ -325,16 +325,16 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account // ToEncodingObj returns an instance of the access list expressed as the type // which is used as input for the encoding/decoding. -func (c *ConstructionBlockAccessList) ToEncodingObj() *BlockAccessList { +func (c *BlockAccessListBuilder) ToEncodingObj() *BlockAccessList { var addresses []common.Address - for addr := range c.Accounts { + for addr := range c.FinalizedAccesses { addresses = append(addresses, addr) } slices.SortFunc(addresses, common.Address.Cmp) var res BlockAccessList for _, addr := range addresses { - res = append(res, c.Accounts[addr].toEncodingObj(addr)) + res = append(res, c.FinalizedAccesses[addr].toEncodingObj(addr)) } return &res } diff --git a/core/types/bal/bal_test.go b/core/types/bal/bal_test.go index c1e55c046f..0a76d2fd6a 100644 --- a/core/types/bal/bal_test.go +++ b/core/types/bal/bal_test.go @@ -36,8 +36,8 @@ func equalBALs(a *BlockAccessList, b *BlockAccessList) bool { return true } -func makeTestConstructionBAL() *ConstructionBlockAccessList { - return &ConstructionBlockAccessList{ +func makeTestConstructionBAL() *BlockAccessListBuilder { + return &BlockAccessListBuilder{ map[common.Address]*ConstructionAccountAccesses{ common.BytesToAddress([]byte{0xff, 0xff}): { StorageWrites: map[common.Hash]map[uint16]common.Hash{