Skip to content

Commit

Permalink
Enable verkle mode via Cancun fork block in genesis config (ethereum#23)
Browse files Browse the repository at this point in the history
* add cancun fork to genesis.  enable verkle with cancun fork

* hack to create the statedb correctly when custom genesis is used

* address review
  • Loading branch information
jwasinger authored Oct 28, 2021
1 parent d814087 commit 688952b
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 45 deletions.
5 changes: 0 additions & 5 deletions cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ var (
ArgsUsage: "<genesisPath>",
Flags: []cli.Flag{
utils.DataDirFlag,
utils.VerkleFlag,
},
Category: "BLOCKCHAIN COMMANDS",
Description: `
Expand Down Expand Up @@ -201,10 +200,6 @@ func initGenesis(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

if ctx.GlobalBool(utils.VerkleFlag.Name) {
genesis.Config.UseVerkle = true
}

for _, name := range []string{"chaindata", "lightchaindata"} {
chaindb, err := stack.OpenDatabase(name, 0, 0, "", false)
if err != nil {
Expand Down
1 change: 0 additions & 1 deletion cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ var (
utils.MinerNotifyFullFlag,
configFileFlag,
utils.CatalystFlag,
utils.VerkleFlag,
}

rpcFlags = []cli.Flag{
Expand Down
1 change: 0 additions & 1 deletion cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.BloomFilterSizeFlag,
cli.HelpFlag,
utils.CatalystFlag,
utils.VerkleFlag,
},
},
}
Expand Down
14 changes: 1 addition & 13 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -775,11 +775,6 @@ var (
Name: "catalyst",
Usage: "Catalyst mode (eth2 integration testing)",
}

VerkleFlag = cli.BoolFlag{
Name: "verkle",
Usage: "Enable geth with verkle trees (EXPERIMENTAL)",
}
)

// MakeDataDir retrieves the currently requested data directory, terminating
Expand Down Expand Up @@ -1454,7 +1449,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
// Avoid conflicting network flags
CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RopstenFlag, RinkebyFlag, GoerliFlag, VerkleFlag)
CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RopstenFlag, RinkebyFlag, GoerliFlag)
CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
if ctx.GlobalString(GCModeFlag.Name) == "archive" && ctx.GlobalUint64(TxLookupLimitFlag.Name) != 0 {
Expand Down Expand Up @@ -1589,13 +1584,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
cfg.Genesis = core.DefaultGenesisBlock()
SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash)
case ctx.GlobalBool(VerkleFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 86 // 'V'
}
cfg.Genesis = core.DefaultVerkleGenesisBlock()
cfg.Genesis.Config.UseVerkle = true
SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash)
case ctx.GlobalBool(RopstenFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 3
Expand Down
1 change: 1 addition & 0 deletions consensus/misc/eip1559_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func copyConfig(original *params.ChainConfig) *params.ChainConfig {
BerlinBlock: original.BerlinBlock,
LondonBlock: original.LondonBlock,
CatalystBlock: original.CatalystBlock,
CancunBlock: original.CancunBlcok,
Ethash: original.Ethash,
Clique: original.Clique,
}
Expand Down
24 changes: 13 additions & 11 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,16 +225,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
futureBlocks, _ := lru.New(maxFutureBlocks)

bc := &BlockChain{
chainConfig: chainConfig,
cacheConfig: cacheConfig,
db: db,
triegc: prque.New(nil),
stateCache: state.NewDatabaseWithConfig(db, &trie.Config{
Cache: cacheConfig.TrieCleanLimit,
Journal: cacheConfig.TrieCleanJournal,
Preimages: cacheConfig.Preimages,
UseVerkle: chainConfig.UseVerkle,
}),
chainConfig: chainConfig,
cacheConfig: cacheConfig,
db: db,
triegc: prque.New(nil),
quit: make(chan struct{}),
shouldPreserve: shouldPreserve,
bodyCache: bodyCache,
Expand Down Expand Up @@ -279,8 +273,16 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
if err := bc.loadLastState(); err != nil {
return nil, err
}

// Make sure the state associated with the block is available
head := bc.CurrentBlock()
bc.stateCache = state.NewDatabaseWithConfig(db, &trie.Config{
Cache: cacheConfig.TrieCleanLimit,
Journal: cacheConfig.TrieCleanJournal,
Preimages: cacheConfig.Preimages,
UseVerkle: chainConfig.IsCancun(head.Header().Number),
})

if _, err := state.New(head.Root(), bc.stateCache, bc.snaps); err != nil {
// Head state is missing, before the state recovery, find out the
// disk layer point of snapshot(if it's enabled). Make sure the
Expand Down Expand Up @@ -371,7 +373,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
log.Warn("Enabling snapshot recovery", "chainhead", head.NumberU64(), "diskbase", *layer)
recover = true
}
bc.snaps, _ = snapshot.New(bc.db, bc.stateCache.TrieDB(), bc.cacheConfig.SnapshotLimit, head.Root(), !bc.cacheConfig.SnapshotWait, true, recover, bc.Config().UseVerkle)
bc.snaps, _ = snapshot.New(bc.db, bc.stateCache.TrieDB(), bc.cacheConfig.SnapshotLimit, head.Root(), !bc.cacheConfig.SnapshotWait, true, recover, chainConfig.IsCancun(head.Header().Number))
}
// Take ownership of this particular state
go bc.update()
Expand Down
23 changes: 20 additions & 3 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,25 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
// but the corresponding state is missing.
header := rawdb.ReadHeader(db, stored, 0)
var cfg *trie.Config = nil
if genesis.Config.UseVerkle {
cfg = &trie.Config{UseVerkle: true}
if genesis == nil {
// hacky: to open the statedb (check for missing genesis state below),
// we need to know whether verkle is enabled which requires us to read the
// chain config
storedcfg := rawdb.ReadChainConfig(db, stored)
if storedcfg == nil && storedcfg.CancunBlock != nil {
if storedcfg.CancunBlock.Cmp(big.NewInt(0)) != 0 {
panic("cancun block must be 0 (for now)")
}

var blockNumber *big.Int
if header != nil {
blockNumber = new(big.Int).Set(header.Number)
} else {
blockNumber = big.NewInt(0)
}

cfg = &trie.Config{UseVerkle: storedcfg.IsCancun(blockNumber)}
}
}
if _, err := state.New(header.Root, state.NewDatabaseWithConfig(db, cfg), nil); err != nil {
if genesis == nil {
Expand Down Expand Up @@ -265,7 +282,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
}
var trieCfg *trie.Config
if g.Config != nil {
trieCfg = &trie.Config{UseVerkle: g.Config.UseVerkle}
trieCfg = &trie.Config{UseVerkle: g.Config.IsCancun(big.NewInt(int64(g.Number)))}
}
statedb, err := state.New(common.Hash{}, state.NewDatabaseWithConfig(db, trieCfg), nil)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ func TestProcessStateless(t *testing.T) {
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
Ethash: new(params.EthashConfig),
UseVerkle: true,
CancunBlock: big.NewInt(0),
}
signer = types.LatestSigner(config)
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
Expand Down
2 changes: 1 addition & 1 deletion core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// associated witness costs.
inWitness := false
var codePage common.Hash
if in.evm.ChainConfig().UseVerkle {
if in.evm.chainRules.IsCancun {
index := trieUtils.GetTreeKeyCodeChunk(contract.Address().Bytes(), uint256.NewInt(pc/31))

var value [32]byte
Expand Down
2 changes: 1 addition & 1 deletion eth/tracers/tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func TestNoStepExec(t *testing.T) {
}

func TestIsPrecompile(t *testing.T) {
chaincfg := &params.ChainConfig{ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), DAOForkBlock: nil, DAOForkSupport: false, EIP150Block: big.NewInt(0), EIP150Hash: common.Hash{}, EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(100), ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(200), MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(300), LondonBlock: big.NewInt(0), CatalystBlock: nil, Ethash: new(params.EthashConfig), Clique: nil}
chaincfg := &params.ChainConfig{ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), DAOForkBlock: nil, DAOForkSupport: false, EIP150Block: big.NewInt(0), EIP150Hash: common.Hash{}, EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(100), ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(200), MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(300), LondonBlock: big.NewInt(0), CatalystBlock: nil, CancunBlock: nil, Ethash: new(params.EthashConfig), Clique: nil}
chaincfg.ByzantiumBlock = big.NewInt(100)
chaincfg.IstanbulBlock = big.NewInt(200)
chaincfg.BerlinBlock = big.NewInt(300)
Expand Down
21 changes: 13 additions & 8 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ var (
MuirGlacierBlock: big.NewInt(0),
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
CancunBlock: big.NewInt(0),
Ethash: new(EthashConfig),
}

Expand Down Expand Up @@ -244,16 +245,16 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, false}
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil}

// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, false}
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}

TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, false}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil}
TestRules = TestChainConfig.Rules(new(big.Int))
)

Expand Down Expand Up @@ -332,14 +333,13 @@ type ChainConfig struct {
MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin)
LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london)
CancunBlock *big.Int `json:"cancunBlock,omitempty"`

CatalystBlock *big.Int `json:"catalystBlock,omitempty"` // Catalyst switch block (nil = no fork, 0 = already on catalyst)

// Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty"`
Clique *CliqueConfig `json:"clique,omitempty"`

UseVerkle bool `json:"verkle,omitempty"` // true is verkle trees are used
}

// EthashConfig is the consensus engine configs for proof-of-work based sealing.
Expand Down Expand Up @@ -372,7 +372,7 @@ func (c *ChainConfig) String() string {
default:
engine = "unknown"
}
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Engine: %v, Verkle: %v}",
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Engine: %v, Cancun: %v}",
c.ChainID,
c.HomesteadBlock,
c.DAOForkBlock,
Expand All @@ -388,7 +388,7 @@ func (c *ChainConfig) String() string {
c.BerlinBlock,
c.LondonBlock,
engine,
c.UseVerkle,
c.CancunBlock,
)
}

Expand Down Expand Up @@ -432,6 +432,10 @@ func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
return isForked(c.MuirGlacierBlock, num)
}

func (c *ChainConfig) IsCancun(num *big.Int) bool {
return isForked(c.CancunBlock, num)
}

// IsPetersburg returns whether num is either
// - equal to or greater than the PetersburgBlock fork block,
// - OR is nil, and Constantinople is active
Expand Down Expand Up @@ -635,7 +639,7 @@ type Rules struct {
ChainID *big.Int
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon, IsCatalyst bool
IsBerlin, IsLondon, IsCatalyst, IsCancun bool
}

// Rules ensures c's ChainID is not nil.
Expand All @@ -657,5 +661,6 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
IsBerlin: c.IsBerlin(num),
IsLondon: c.IsLondon(num),
IsCatalyst: c.IsCatalyst(num),
IsCancun: c.IsCancun(num),
}
}

0 comments on commit 688952b

Please sign in to comment.