activate verkle on IsVerkle, not IsCancun

This commit is contained in:
Guillaume Ballet 2023-08-10 13:49:13 +02:00
parent f5a7321bef
commit c2cdd50666
13 changed files with 56 additions and 47 deletions

View file

@ -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

View file

@ -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)
}

View file

@ -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
}

View file

@ -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)

View file

@ -437,8 +437,6 @@ var (
func TestProcessVerkle(t *testing.T) {
var (
cancuntime uint64 = 0
shanghaiTime uint64 = 0
config = &params.ChainConfig{
ChainID: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
@ -453,8 +451,10 @@ func TestProcessVerkle(t *testing.T) {
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
Ethash: new(params.EthashConfig),
ShanghaiTime: &shanghaiTime,
CancunTime: &cancuntime,
ShanghaiTime: u64(0),
VerkleTime: u64(0),
TerminalTotalDifficulty: common.Big0,
TerminalTotalDifficultyPassed: true,
}
signer = types.LatestSigner(config)
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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")

View file

@ -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)
}

View file

@ -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:

View file

@ -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:

View file

@ -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)