From 42836bfe97e7876e939ebb3357609cb285ddd562 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Tue, 19 Dec 2023 21:57:45 +0800 Subject: [PATCH] cleanup --- core/blockchain.go | 3 +-- core/evm.go | 37 ----------------------------- core/state/state_object.go | 3 +-- core/state/state_witness.go | 44 +++++++++++++++++----------------- core/state/statedb.go | 8 ++++--- core/state_processor.go | 47 ------------------------------------- 6 files changed, 30 insertions(+), 112 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 65714deb5e..280a1c2800 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -259,6 +259,7 @@ type BlockChain struct { forker *ForkChoice vmConfig vm.Config + // If this is non-nil, block witnesses are recorded during execution and dumped into the filepath it contains witnessRecordingPath atomic.Pointer[string] } @@ -1490,7 +1491,6 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types if err := bc.writeBlockWithState(block, receipts, st); err != nil { return NonStatTy, err } - currentBlock := bc.CurrentBlock() reorg, err := bc.forker.ReorgNeeded(currentBlock, block.Header()) if err != nil { @@ -1872,7 +1872,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) log.Info(fmt.Sprintf("block %d summary:\n%s", block.NumberU64(), statedb.GetWitness().Summary())) } } - //state.DumpBlockWithWitnessToFile(statedb.GetWitness(), block) followupInterrupt.Store(true) if err != nil { diff --git a/core/evm.go b/core/evm.go index 79650cd525..c4801dc797 100644 --- a/core/evm.go +++ b/core/evm.go @@ -17,7 +17,6 @@ package core import ( - "github.com/ethereum/go-ethereum/core/state" "math/big" "github.com/ethereum/go-ethereum/common" @@ -37,42 +36,6 @@ type ChainContext interface { GetHeader(common.Hash, uint64) *types.Header } -func NewStatelessEVMBlockContext(witness *state.Witness, header *types.Header, engine consensus.Engine) vm.BlockContext { - getBlockHash := func(num uint64) common.Hash { - return witness.GetBlockHash(num) - } - var ( - baseFee *big.Int - blobBaseFee *big.Int - random *common.Hash - ) - - beneficiary, _ := engine.Author(header) // Ignore error, we're past header validation - - if header.BaseFee != nil { - baseFee = new(big.Int).Set(header.BaseFee) - } - if header.ExcessBlobGas != nil { - blobBaseFee = eip4844.CalcBlobFee(*header.ExcessBlobGas) - } - if header.Difficulty.Cmp(common.Big0) == 0 { - random = &header.MixDigest - } - return vm.BlockContext{ - CanTransfer: CanTransfer, - Transfer: Transfer, - GetHash: getBlockHash, - Coinbase: beneficiary, - BlockNumber: new(big.Int).Set(header.Number), - Time: header.Time, - Difficulty: new(big.Int).Set(header.Difficulty), - BaseFee: baseFee, - BlobBaseFee: blobBaseFee, - GasLimit: header.GasLimit, - Random: random, - } -} - // NewEVMBlockContext creates a new context for use in the EVM. func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext { var ( diff --git a/core/state/state_object.go b/core/state/state_object.go index 41088a0a6c..eabde22722 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -204,7 +204,7 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash { value.SetBytes(content) } } - if s.db.prefetcher != nil { + if s.db.recordWitness && s.db.prefetcher != nil { // always prefetch to ensure that read storage slots will end up in the witness s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, [][]byte{key[:]}) } @@ -260,7 +260,6 @@ func (s *stateObject) finalise(prefetch bool) { slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure } } - if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash { s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, slotsToPrefetch) } diff --git a/core/state/state_witness.go b/core/state/state_witness.go index 1aeb297809..657e115bce 100644 --- a/core/state/state_witness.go +++ b/core/state/state_witness.go @@ -4,9 +4,7 @@ import ( "bytes" "fmt" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" "os" "path/filepath" @@ -125,10 +123,6 @@ func (w *Witness) AddCodeHash(hash common.Hash) { w.codes[hash] = []byte{} } -func (w Witness) Copy() Witness { - panic("not implemented") -} - func (w *Witness) LogSizeWithBlock(b *types.Block) { enc, _ := w.EncodeRLP() fmt.Printf("block %d witness+block size: %d\n", b.Number(), len(enc)) @@ -171,25 +165,33 @@ func (w *Witness) Summary() string { return b.String() } -func (w *Witness) PopulateMemoryDB() ethdb.Database { - db := rawdb.NewMemoryDatabase() - for codeHash, code := range w.codes { - rawdb.WriteCode(db, codeHash, code) - } - - for owner, owned := range w.lists { - for path, node := range owned { - rawdb.WriteTrieNode(db, owner, []byte(path), common.Hash{}, node, rawdb.PathScheme) - } - } - - return db -} - func (w *Witness) SetBlock(b *types.Block) { w.block = b } +func (w *Witness) Copy() *Witness { + var res Witness + res.block = w.block // we don't actually mutate the block in the witness so don't deep copy + + for blockNr, blockHash := range w.blockHashes { + res.blockHashes[blockNr] = blockHash + } + for codeHash, code := range w.codes { + cpy := make([]byte, len(code)) + copy(cpy, code) + res.codes[codeHash] = cpy + } + res.root = w.root + for owner, owned := range w.lists { + res.lists[owner] = make(map[string][]byte) + for path, node := range owned { + cpy := make([]byte, len(node)) + copy(cpy, node) + res.lists[owner][path] = cpy + } + } + return &res +} func NewWitness() *Witness { return &Witness{ block: nil, diff --git a/core/state/statedb.go b/core/state/statedb.go index 6474e2474d..cd34596e73 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -572,7 +572,7 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject { // flag set. This is needed by the state journal to revert to the correct s- // destructed object instead of wiping all knowledge about the state object. func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject { - if s.prefetcher != nil { + if s.recordWitness && s.prefetcher != nil { // always prefetch to ensure written/read accounts appear in the witness // regardless of whether snapshot is enabled s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, [][]byte{addr[:]}) @@ -733,8 +733,10 @@ func (s *StateDB) Copy() *StateDB { // miner to operate trie-backed only. snaps: s.snaps, snap: s.snap, - - witness: NewWitness(), // TODO: deep copy witness + } + if s.recordWitness { + state.recordWitness = true + state.witness = s.witness.Copy() } // Copy the dirty states, logs, and preimages for addr := range s.journal.dirties { diff --git a/core/state_processor.go b/core/state_processor.go index 157b845a0e..9a4333f723 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -104,53 +104,6 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg return receipts, allLogs, *usedGas, nil } -func (p *StateProcessor) ProcessStateless(witness *state.Witness, block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { - var ( - receipts types.Receipts - usedGas = new(uint64) - header = block.Header() - blockHash = block.Hash() - blockNumber = block.Number() - allLogs []*types.Log - gp = new(GasPool).AddGas(block.GasLimit()) - ) - // Mutate the block and state according to any hard-fork specs - if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { - misc.ApplyDAOHardFork(statedb) - } - var ( - context = NewStatelessEVMBlockContext(witness, header, p.engine) - vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg) - signer = types.MakeSigner(p.config, header.Number, header.Time) - ) - if beaconRoot := block.BeaconRoot(); beaconRoot != nil { - ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) - } - // Iterate over and process the individual transactions - for i, tx := range block.Transactions() { - msg, err := TransactionToMessage(tx, signer, header.BaseFee) - if err != nil { - return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) - } - statedb.SetTxContext(tx.Hash(), i) - receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv) - if err != nil { - return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) - } - receipts = append(receipts, receipt) - allLogs = append(allLogs, receipt.Logs...) - } - // Fail if Shanghai not enabled and len(withdrawals) is non-zero. - withdrawals := block.Withdrawals() - if len(withdrawals) > 0 && !p.config.IsShanghai(block.Number(), block.Time()) { - return nil, nil, 0, errors.New("withdrawals before shanghai") - } - // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) - p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), withdrawals) - - return receipts, allLogs, *usedGas, nil -} - func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) { // Create a new context to be used in the EVM environment. txContext := NewEVMTxContext(msg)