From c2cdd50666746f51b33d85de41024bd9a311d725 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:49:13 +0200 Subject: [PATCH] activate verkle on IsVerkle, not IsCancun --- consensus/ethash/consensus.go | 5 +++-- core/blockchain.go | 4 ++-- core/chain_makers.go | 2 +- core/genesis.go | 4 ++-- core/state_processor_test.go | 36 +++++++++++++++++------------------ core/state_transition.go | 2 +- core/vm/contracts.go | 2 ++ core/vm/evm.go | 10 ++++++---- core/vm/gas_table.go | 14 +++++++------- core/vm/instructions.go | 14 +++++++------- core/vm/interpreter.go | 3 +++ core/vm/jump_table_export.go | 3 ++- core/vm/operations_acl.go | 4 ++-- 13 files changed, 56 insertions(+), 47 deletions(-) diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 81563f8107..00bc136872 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -566,7 +566,8 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header r.Mul(r, blockReward) r.Div(r, big8) - if config.IsCancun(header.Number, header.Time) { + // This should not happen, but it's useful for replay tests + if config.IsVerkle(header.Number, header.Time) { uncleCoinbase := utils.GetTreeKeyBalance(uncle.Coinbase.Bytes()) state.Witness().TouchAddressOnReadAndComputeGas(uncleCoinbase) } @@ -575,7 +576,7 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header r.Div(blockReward, big32) reward.Add(reward, r) } - if config.IsCancun(header.Number, header.Time) { + if config.IsVerkle(header.Number, header.Time) { coinbase := utils.GetTreeKeyBalance(header.Coinbase.Bytes()) state.Witness().TouchAddressOnReadAndComputeGas(coinbase) coinbase[31] = utils.VersionLeafKey // mark version diff --git a/core/blockchain.go b/core/blockchain.go index 1e1a10f9bb..1c7dad957e 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -311,7 +311,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis head := bc.CurrentBlock() // Declare the end of the verkle transition is need be - if bc.chainConfig.Rules(head.Number, false /* XXX */, head.Time).IsCancun { + if bc.chainConfig.Rules(head.Number, false /* XXX */, head.Time).IsVerkle { bc.stateCache.EndVerkleTransition() } @@ -411,7 +411,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis Recovery: recover, NoBuild: bc.cacheConfig.SnapshotNoBuild, AsyncBuild: !bc.cacheConfig.SnapshotWait, - Verkle: chainConfig.IsCancun(head.Number, head.Time), + Verkle: chainConfig.IsVerkle(head.Number, head.Time), } bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root) } diff --git a/core/chain_makers.go b/core/chain_makers.go index 87dff7b564..03f98bade6 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -357,7 +357,7 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, if err != nil { panic(err) } - if genesis.Config != nil && genesis.Config.IsCancun(genesis.ToBlock().Number(), genesis.ToBlock().Time()) { + if genesis.Config != nil && genesis.Config.IsVerkle(genesis.ToBlock().Number(), genesis.ToBlock().Time()) { blocks, receipts, _, _ := GenerateVerkleChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen) return db, blocks, receipts } diff --git a/core/genesis.go b/core/genesis.go index 4dbc3ad963..acfd613fe5 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -127,7 +127,7 @@ func (ga *GenesisAlloc) deriveHash(cfg *params.ChainConfig, timestamp uint64) (c db := state.NewDatabase(rawdb.NewMemoryDatabase()) // XXX check this is the case // TODO remove the nil config check once we have rebased, it should never be nil - if cfg != nil && cfg.IsCancun(big.NewInt(int64(0)), timestamp) { + if cfg != nil && cfg.IsVerkle(big.NewInt(int64(0)), timestamp) { db.EndVerkleTransition() } statedb, err := state.New(types.EmptyRootHash, db, nil) @@ -547,7 +547,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *trie.Database) (*types.Block // Note the state changes will be committed in hash-based scheme, use Commit // if path-scheme is preferred. func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { - triedb := trie.NewDatabaseWithConfig(db, &trie.Config{Verkle: g.Config != nil && g.Config.IsCancun(big.NewInt(int64(g.Number)), g.Timestamp)}) + triedb := trie.NewDatabaseWithConfig(db, &trie.Config{Verkle: g.Config != nil && g.Config.IsVerkle(big.NewInt(int64(g.Number)), g.Timestamp)}) block, err := g.Commit(db, triedb) if err != nil { panic(err) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 57f17d4b53..4d56365d8b 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -437,24 +437,24 @@ var ( func TestProcessVerkle(t *testing.T) { var ( - cancuntime uint64 = 0 - shanghaiTime uint64 = 0 - config = ¶ms.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - Ethash: new(params.EthashConfig), - ShanghaiTime: &shanghaiTime, - CancunTime: &cancuntime, + config = ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Ethash: new(params.EthashConfig), + ShanghaiTime: u64(0), + VerkleTime: u64(0), + TerminalTotalDifficulty: common.Big0, + TerminalTotalDifficultyPassed: true, } signer = types.LatestSigner(config) testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") diff --git a/core/state_transition.go b/core/state_transition.go index a5fb83084a..14dd86e498 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -403,7 +403,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { } st.gasRemaining -= gas - if rules.IsCancun { + if rules.IsVerkle { targetAddr := msg.To originAddr := msg.From diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 6041be6c9f..2942755f3f 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -150,6 +150,8 @@ func init() { // ActivePrecompiles returns the precompiles enabled with the current configuration. func ActivePrecompiles(rules params.Rules) []common.Address { switch { + case rules.IsVerkle: + return PrecompiledAddressesBerlin case rules.IsCancun: return PrecompiledAddressesCancun case rules.IsBerlin: diff --git a/core/vm/evm.go b/core/vm/evm.go index a35f1094ba..f8f67c4ef7 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -41,6 +41,8 @@ type ( func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { var precompiles map[common.Address]PrecompiledContract switch { + case evm.chainRules.IsVerkle: + precompiles = PrecompiledContractsBerlin case evm.chainRules.IsCancun: precompiles = PrecompiledContractsCancun case evm.chainRules.IsBerlin: @@ -135,7 +137,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig chainConfig: chainConfig, chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time), } - if txCtx.Accesses == nil && chainConfig.IsCancun(blockCtx.BlockNumber, blockCtx.Time) { + if txCtx.Accesses == nil && chainConfig.IsVerkle(blockCtx.BlockNumber, blockCtx.Time) { txCtx.Accesses = state.NewAccessWitness(evm.StateDB.(*state.StateDB)) } evm.interpreter = NewEVMInterpreter(evm) @@ -145,7 +147,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig // Reset resets the EVM with a new transaction context.Reset // This is not threadsafe and should only be done very cautiously. func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) { - if txCtx.Accesses == nil && evm.chainRules.IsCancun { + if txCtx.Accesses == nil && evm.chainRules.IsVerkle { txCtx.Accesses = state.NewAccessWitness(evm.StateDB.(*state.StateDB)) } evm.TxContext = txCtx @@ -210,7 +212,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas var creation bool if !evm.StateDB.Exist(addr) { if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 { - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { // proof of absence tryConsumeGas(&gas, evm.Accesses.TouchAndChargeProofOfAbsence(caller.Address().Bytes())) } @@ -527,7 +529,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, } } - if err == nil && evm.chainRules.IsCancun { + if err == nil && evm.chainRules.IsVerkle { if !contract.UseGas(evm.Accesses.TouchAndChargeContractCreateCompleted(address.Bytes()[:], value.Sign() != 0)) { evm.StateDB.RevertToSnapshot(snapshot) err = ErrOutOfGas diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 899551d186..780b051826 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -100,7 +100,7 @@ var ( func gasExtCodeSize(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { usedGas := uint64(0) slot := stack.Back(0) - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { index := trieUtils.GetTreeKeyCodeSize(slot.Bytes()) usedGas += evm.TxContext.Accesses.TouchAddressOnReadAndComputeGas(index) } @@ -111,7 +111,7 @@ func gasExtCodeSize(evm *EVM, contract *Contract, stack *Stack, mem *Memory, mem func gasSLoad(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { usedGas := uint64(0) - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { where := stack.Back(0) index := trieUtils.GetTreeKeyStorageSlotWithEvaluatedAddress(contract.AddressPoint(), where.Bytes()) usedGas += evm.Accesses.TouchAddressOnReadAndComputeGas(index) @@ -423,7 +423,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { return 0, ErrGasUintOverflow } - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { if _, isPrecompile := evm.precompile(address); !isPrecompile { gas, overflow = math.SafeAdd(gas, evm.Accesses.TouchAndChargeMessageCall(address.Bytes()[:])) if overflow { @@ -463,7 +463,7 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { return 0, ErrGasUintOverflow } - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { address := common.Address(stack.Back(1).Bytes20()) if _, isPrecompile := evm.precompile(address); !isPrecompile { gas, overflow = math.SafeAdd(gas, evm.Accesses.TouchAndChargeMessageCall(address.Bytes())) @@ -488,7 +488,7 @@ func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { return 0, ErrGasUintOverflow } - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { address := common.Address(stack.Back(1).Bytes20()) if _, isPrecompile := evm.precompile(address); !isPrecompile { gas, overflow = math.SafeAdd(gas, evm.Accesses.TouchAndChargeMessageCall(address.Bytes())) @@ -513,7 +513,7 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { return 0, ErrGasUintOverflow } - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { address := common.Address(stack.Back(1).Bytes20()) if _, isPrecompile := evm.precompile(address); !isPrecompile { gas, overflow = math.SafeAdd(gas, evm.Accesses.TouchAndChargeMessageCall(address.Bytes())) @@ -542,7 +542,7 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me } } - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { // TODO turn this into a panic (when we are sure this method // will never execute when verkle is enabled) log.Warn("verkle witness accumulation not supported for selfdestruct") diff --git a/core/vm/instructions.go b/core/vm/instructions.go index eeb9fc6492..871922c101 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -346,7 +346,7 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.peek() cs := uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20())) - if interpreter.evm.chainRules.IsCancun { + if interpreter.evm.chainRules.IsVerkle { index := trieUtils.GetTreeKeyCodeSize(slot.Bytes()) statelessGas := interpreter.evm.Accesses.TouchAddressOnReadAndComputeGas(index) scope.Contract.UseGas(statelessGas) @@ -374,7 +374,7 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ } paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(scope.Contract.Code, uint64CodeOffset, length.Uint64()) - if interpreter.evm.chainRules.IsCancun { + if interpreter.evm.chainRules.IsVerkle { scope.Contract.UseGas(touchEachChunksOnReadAndChargeGas(copyOffset, nonPaddedCopyLength, scope.Contract, scope.Contract.Code, interpreter.evm.Accesses, scope.Contract.IsDeployment)) } scope.Memory.Set(memOffset.Uint64(), uint64(len(paddedCodeCopy)), paddedCodeCopy) @@ -465,7 +465,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) uint64CodeOffset = 0xffffffffffffffff } addr := common.Address(a.Bytes20()) - if interpreter.evm.chainRules.IsCancun { + if interpreter.evm.chainRules.IsVerkle { code := interpreter.evm.StateDB.GetCode(addr) contract := &Contract{ Code: code, @@ -680,7 +680,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) gas = scope.Contract.Gas ) - if interpreter.evm.chainRules.IsCancun { + if interpreter.evm.chainRules.IsVerkle { contractAddress := crypto.CreateAddress(scope.Contract.Address(), interpreter.evm.StateDB.GetNonce(scope.Contract.Address())) statelessGas := interpreter.evm.Accesses.TouchAndChargeContractCreateInit(contractAddress.Bytes()[:], value.Sign() != 0) if !tryConsumeGas(&gas, statelessGas) { @@ -734,7 +734,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) gas = scope.Contract.Gas ) - if interpreter.evm.chainRules.IsCancun { + if interpreter.evm.chainRules.IsVerkle { codeAndHash := &codeAndHash{code: input} contractAddress := crypto.CreateAddress2(scope.Contract.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) statelessGas := interpreter.evm.Accesses.TouchAndChargeContractCreateInit(contractAddress.Bytes()[:], endowment.Sign() != 0) @@ -998,7 +998,7 @@ func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by if *pc < codeLen { scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc]))) - if interpreter.evm.chainRules.IsCancun && *pc%31 == 0 { + if interpreter.evm.chainRules.IsVerkle && *pc%31 == 0 { // touch next chunk if PUSH1 is at the boundary. if so, *pc has // advanced past this boundary. statelessGas := touchEachChunksOnReadAndChargeGas(*pc+1, uint64(1), scope.Contract, scope.Contract.Code, interpreter.evm.Accesses, scope.Contract.IsDeployment) @@ -1025,7 +1025,7 @@ func makePush(size uint64, pushByteSize int) executionFunc { endMin = startMin + pushByteSize } - if interpreter.evm.chainRules.IsCancun { + if interpreter.evm.chainRules.IsVerkle { statelessGas := touchEachChunksOnReadAndChargeGas(uint64(startMin), uint64(pushByteSize), scope.Contract, scope.Contract.Code, interpreter.evm.Accesses, scope.Contract.IsDeployment) scope.Contract.UseGas(statelessGas) } diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 9050addbca..6563b17bd9 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -60,6 +60,9 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter { // If jump table was not initialised we set the default one. var table *JumpTable switch { + case evm.chainRules.IsVerkle: + // TODO replace with prooper instruction set when fork is specified + table = &shanghaiInstructionSet case evm.chainRules.IsCancun: table = &cancunInstructionSet case evm.chainRules.IsShanghai: diff --git a/core/vm/jump_table_export.go b/core/vm/jump_table_export.go index 6ea47d63a2..75bcb8d5bf 100644 --- a/core/vm/jump_table_export.go +++ b/core/vm/jump_table_export.go @@ -27,7 +27,8 @@ import ( func LookupInstructionSet(rules params.Rules) (JumpTable, error) { switch { case rules.IsVerkle: - return newCancunInstructionSet(), errors.New("verkle-fork not defined yet") + // TODO set to newCancunInstructionSet() when verkle-fork is defined + return newShanghaiInstructionSet(), errors.New("verkle-fork not defined yet") case rules.IsPrague: return newCancunInstructionSet(), errors.New("prague-fork not defined yet") case rules.IsCancun: diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index 114769abda..fe8446be3b 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -52,7 +52,7 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc { } value := common.Hash(y.Bytes32()) - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { index := trieUtils.GetTreeKeyStorageSlotWithEvaluatedAddress(contract.AddressPoint(), x.Bytes()) cost += evm.Accesses.TouchAddressOnWriteAndComputeGas(index) } @@ -111,7 +111,7 @@ func gasSLoadEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me slot := common.Hash(loc.Bytes32()) var gasUsed uint64 - if evm.chainRules.IsCancun { + if evm.chainRules.IsVerkle { where := stack.Back(0) addr := contract.Address() index := trieUtils.GetTreeKeyStorageSlot(addr[:], where)