diff --git a/core/block_access_list_creation.go b/core/block_access_list_creation.go index e6179422b7..9f633d6aa2 100644 --- a/core/block_access_list_creation.go +++ b/core/block_access_list_creation.go @@ -1,6 +1,7 @@ package core import ( + "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" @@ -38,7 +39,7 @@ func NewBlockAccessListTracer(startIdx int) (*BlockAccessListTracer, *tracing.Ho OnExit: balTracer.OnExit, OnCodeChangeV2: balTracer.OnCodeChange, OnBalanceChange: balTracer.OnBalanceChange, - OnNonceChange: balTracer.OnNonceChange, + OnNonceChangeV2: balTracer.OnNonceChange, OnStorageChange: balTracer.OnStorageChange, OnColdAccountRead: balTracer.OnColdAccountRead, OnColdStorageRead: balTracer.OnColdStorageRead, @@ -74,6 +75,7 @@ func (a *BlockAccessListTracer) OnExit(depth int, output []byte, gasUsed uint64, parentAccessList := a.callAccessLists[len(a.callAccessLists)-2] scopeAccessList := a.callAccessLists[len(a.callAccessLists)-1] if reverted { + fmt.Printf("reverted \n%s\n", scopeAccessList.ToEncodingObj().String()) parentAccessList.MergeReads(scopeAccessList) } else { parentAccessList.Merge(scopeAccessList) @@ -84,6 +86,15 @@ func (a *BlockAccessListTracer) OnExit(depth int, output []byte, gasUsed uint64, func (a *BlockAccessListTracer) OnCodeChange(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) { if reason == tracing.CodeChangeSelfDestruct { + // TODO: not sure whether this will ever run post-Cancun. Prob should remove it if not + panic("FUCK") + a.selfdestructedAccount = &addr + return + } else if reason == tracing.CodeChangeContractCreation { + //fmt.Printf("contract creation code change: %x\n", code) + } else if len(code) == 0 { + fmt.Println("self-destruct happened here") + // this is the actual signal for a post-Cancun created-in-same-transaction selfdestruct.... a.selfdestructedAccount = &addr return } @@ -94,8 +105,16 @@ func (a *BlockAccessListTracer) OnBalanceChange(addr common.Address, prevBalance a.callAccessLists[len(a.callAccessLists)-1].BalanceChange(a.txIdx, addr, new(uint256.Int).SetBytes(newBalance.Bytes())) } -func (a *BlockAccessListTracer) OnNonceChange(addr common.Address, prev uint64, new uint64) { - a.callAccessLists[len(a.callAccessLists)-1].NonceChange(addr, a.txIdx, new) +func (a *BlockAccessListTracer) OnNonceChange(addr common.Address, prev uint64, new uint64, reason tracing.NonceChangeReason) { + if reason == tracing.NonceChangeContractCreator { + // NonceChange hook is called between the Enter/Exit of the contract creation + // so it would appear as if it has occurred within the creation initcode. + // if the initcode fails, the nonce update is not reverted, so record it directly + // on the parent execution scope. + a.callAccessLists[len(a.callAccessLists)-2].NonceChange(addr, a.txIdx, new) + } else { + a.callAccessLists[len(a.callAccessLists)-1].NonceChange(addr, a.txIdx, new) + } } func (a *BlockAccessListTracer) OnColdStorageRead(addr common.Address, key common.Hash) { diff --git a/core/parallel_state_processor.go b/core/parallel_state_processor.go index 7da5a0752a..80b6c95b21 100644 --- a/core/parallel_state_processor.go +++ b/core/parallel_state_processor.go @@ -61,6 +61,7 @@ func (p *ParallelStateProcessor) prepareExecResult(block *types.Block, allStateR balTracer, hooks := NewBlockAccessListTracer(len(block.Transactions()) + 1) tracingStateDB := state.NewHookedState(postTxState, hooks) context := NewEVMBlockContext(header, p.chain, nil) + postTxState.SetAccessListIndex(len(block.Transactions()) + 1) cfg := vm.Config{ Tracer: hooks, @@ -267,6 +268,7 @@ func (p *ParallelStateProcessor) execTx(block *types.Block, tx *types.Transactio } gp := new(GasPool) gp.SetGas(block.GasLimit()) + db.SetTxContext(tx.Hash(), txIdx) var gasUsed uint64 receipt, err := ApplyTransactionWithEVM(msg, gp, db, block.Number(), block.Hash(), context.Time, tx, &gasUsed, evm) if err != nil { @@ -288,6 +290,7 @@ func (p *ParallelStateProcessor) execTx(block *types.Block, tx *types.Transactio // Process performs EVM execution and state root computation for a block which is known // to contain an access list. func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResultWithMetrics, error) { + fmt.Printf("process block with bal\n%s\n", block.Body().AccessList.String()) var ( header = block.Header() resCh = make(chan *ProcessResultWithMetrics) diff --git a/core/state/statedb.go b/core/state/statedb.go index df4217891e..90d9e343e2 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1085,6 +1085,13 @@ func (s *StateDB) SetTxContext(thash common.Hash, ti int) { s.balIndex = ti + 1 } +// SetAccessListIndex sets the current index that state mutations will +// be reported as in the BAL. It is only relevant if this StateDB instance +// is being used in the BAL construction path. +func (s *StateDB) SetAccessListIndex(idx int) { + s.balIndex = idx +} + // SetTxSender sets the sender of the currently-executing transaction. func (s *StateDB) SetTxSender(sender common.Address) { s.sender = sender diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 5e53feb9c9..69e332cb09 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -17,8 +17,6 @@ package state import ( - "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/tracing" @@ -27,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" + "math/big" ) // hookedStateDB represents a statedb which emits calls to tracing-hooks diff --git a/core/types/bal/bal.go b/core/types/bal/bal.go index d0546cd9c3..22d2b1ea47 100644 --- a/core/types/bal/bal.go +++ b/core/types/bal/bal.go @@ -241,7 +241,8 @@ func mergeStorageWrites(cur, next map[common.Hash]map[uint16]common.Hash) map[co func (c *ConstructionBlockAccessList) MergeReads(childScope *ConstructionBlockAccessList) { for addr, accountAccess := range childScope.Accounts { if _, ok := c.Accounts[addr]; !ok { - c.Accounts[addr] = &ConstructionAccountAccess{StorageReads: accountAccess.StorageReads} + c.Accounts[addr] = NewConstructionAccountAccess() + c.Accounts[addr].StorageReads = accountAccess.StorageReads continue }