Skip to content

Commit d3a07a2

Browse files
committed
core/state: introduce the TransitionState object
1 parent d7db10d commit d3a07a2

File tree

13 files changed

+247
-75
lines changed

13 files changed

+247
-75
lines changed

consensus/beacon/consensus.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
396396
return nil, errors.New("post-state tree is not available")
397397
}
398398
vktPreTrie, okpre := preTrie.(*trie.VerkleTrie)
399-
vktPostTrie, okpost := postTrie.(*trie.VerkleTrie)
399+
vktPostTrie, okpost := state.GetTrie().(*trie.VerkleTrie)
400400

401401
// The witness is only attached iff both parent and current block are
402402
// using verkle tree.

core/blockchain.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,7 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine,
341341
if cfg == nil {
342342
cfg = DefaultConfig()
343343
}
344-
345-
// Open trie database with provided config
346-
enableVerkle, err := EnableVerkleAtGenesis(db, genesis)
347-
if err != nil {
348-
return nil, err
349-
}
350-
triedb := triedb.NewDatabase(db, cfg.triedbConfig(enableVerkle))
344+
triedb := triedb.NewDatabase(db, cfg.triedbConfig(genesis.IsVerkle()))
351345

352346
// Write the supplied genesis to the database if it has not been initialized
353347
// yet. The corresponding chain config will be returned, either from the

core/chain_makers.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,10 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
540540
return block, b.receipts
541541
}
542542

543+
sdb := state.NewDatabase(trdb, nil)
544+
543545
for i := 0; i < n; i++ {
544-
statedb, err := state.New(parent.Root(), state.NewDatabase(trdb, nil))
546+
statedb, err := state.New(parent.Root(), sdb)
545547
if err != nil {
546548
panic(err)
547549
}
@@ -579,6 +581,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
579581

580582
func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (common.Hash, ethdb.Database, []*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) {
581583
db := rawdb.NewMemoryDatabase()
584+
saveVerkleTransitionStatusAtVerlkeGenesis(db)
582585
cacheConfig := DefaultConfig().WithStateScheme(rawdb.PathScheme)
583586
cacheConfig.SnapshotLimit = 0
584587
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))

core/genesis.go

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package core
1818

1919
import (
2020
"bytes"
21+
"encoding/gob"
2122
"encoding/json"
2223
"errors"
2324
"fmt"
@@ -145,6 +146,9 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
145146
emptyRoot = types.EmptyVerkleHash
146147
}
147148
db := rawdb.NewMemoryDatabase()
149+
if isVerkle {
150+
saveVerkleTransitionStatusAtVerlkeGenesis(db)
151+
}
148152
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil))
149153
if err != nil {
150154
return common.Hash{}, err
@@ -276,6 +280,24 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error {
276280
return cfg.CheckConfigForkOrder()
277281
}
278282

283+
// saveVerkleTransitionStatusAtVerlkeGenesis saves a conversion marker
284+
// representing a converted state, which is used in devnets that activate
285+
// verkle at genesis.
286+
func saveVerkleTransitionStatusAtVerlkeGenesis(db ethdb.Database) {
287+
saveVerkleTransitionStatus(db, common.Hash{}, &state.TransitionState{Ended: true})
288+
}
289+
290+
func saveVerkleTransitionStatus(db ethdb.Database, root common.Hash, ts *state.TransitionState) {
291+
var buf bytes.Buffer
292+
enc := gob.NewEncoder(&buf)
293+
err := enc.Encode(ts)
294+
if err != nil {
295+
log.Error("failed to encode transition state", "err", err)
296+
return
297+
}
298+
rawdb.WriteVerkleTransitionState(db, root, buf.Bytes())
299+
}
300+
279301
// SetupGenesisBlock writes or updates the genesis block in db.
280302
// The block that will be used is:
281303
//
@@ -299,6 +321,11 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
299321
if genesis != nil && genesis.Config == nil {
300322
return nil, common.Hash{}, nil, errGenesisNoConfig
301323
}
324+
// In case of verkle-at-genesis, we need to ensure that the conversion
325+
// markers are indicating that the conversion has completed.
326+
if genesis != nil && genesis.Config.VerkleTime != nil && *genesis.Config.VerkleTime == genesis.Timestamp {
327+
saveVerkleTransitionStatusAtVerlkeGenesis(db)
328+
}
302329
// Commit the genesis if the database is empty
303330
ghash := rawdb.ReadCanonicalHash(db, 0)
304331
if (ghash == common.Hash{}) {
@@ -446,7 +473,7 @@ func (g *Genesis) chainConfigOrDefault(ghash common.Hash, stored *params.ChainCo
446473
// IsVerkle indicates whether the state is already stored in a verkle
447474
// tree at genesis time.
448475
func (g *Genesis) IsVerkle() bool {
449-
return g.Config.IsVerkleGenesis()
476+
return g.Config.VerkleTime != nil && *g.Config.VerkleTime == g.Timestamp
450477
}
451478

452479
// ToBlock returns the genesis block according to genesis specification.
@@ -550,6 +577,9 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo
550577
if err != nil {
551578
return nil, err
552579
}
580+
if g.IsVerkle() {
581+
saveVerkleTransitionStatus(db, block.Root(), &state.TransitionState{Ended: true})
582+
}
553583
batch := db.NewBatch()
554584
rawdb.WriteGenesisStateSpec(batch, block.Hash(), blob)
555585
rawdb.WriteBlock(batch, block)
@@ -572,29 +602,6 @@ func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types.
572602
return block
573603
}
574604

575-
// EnableVerkleAtGenesis indicates whether the verkle fork should be activated
576-
// at genesis. This is a temporary solution only for verkle devnet testing, where
577-
// verkle fork is activated at genesis, and the configured activation date has
578-
// already passed.
579-
//
580-
// In production networks (mainnet and public testnets), verkle activation always
581-
// occurs after the genesis block, making this function irrelevant in those cases.
582-
func EnableVerkleAtGenesis(db ethdb.Database, genesis *Genesis) (bool, error) {
583-
if genesis != nil {
584-
if genesis.Config == nil {
585-
return false, errGenesisNoConfig
586-
}
587-
return genesis.Config.EnableVerkleAtGenesis, nil
588-
}
589-
if ghash := rawdb.ReadCanonicalHash(db, 0); ghash != (common.Hash{}) {
590-
chainCfg := rawdb.ReadChainConfig(db, ghash)
591-
if chainCfg != nil {
592-
return chainCfg.EnableVerkleAtGenesis, nil
593-
}
594-
}
595-
return false, nil
596-
}
597-
598605
// DefaultGenesisBlock returns the Ethereum main net genesis block.
599606
func DefaultGenesisBlock() *Genesis {
600607
return &Genesis{

core/genesis_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,6 @@ func TestVerkleGenesisCommit(t *testing.T) {
287287
OsakaTime: &verkleTime,
288288
VerkleTime: &verkleTime,
289289
TerminalTotalDifficulty: big.NewInt(0),
290-
EnableVerkleAtGenesis: true,
291290
Ethash: nil,
292291
Clique: nil,
293292
BlobScheduleConfig: &params.BlobScheduleConfig{
@@ -315,7 +314,7 @@ func TestVerkleGenesisCommit(t *testing.T) {
315314
}
316315

317316
db := rawdb.NewMemoryDatabase()
318-
317+
saveVerkleTransitionStatusAtVerlkeGenesis(db)
319318
config := *pathdb.Defaults
320319
config.NoAsyncFlush = true
321320

core/rawdb/accessors_overlay.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2025 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package rawdb
18+
19+
import (
20+
"github.com/ethereum/go-ethereum/common"
21+
"github.com/ethereum/go-ethereum/ethdb"
22+
)
23+
24+
func ReadVerkleTransitionState(db ethdb.KeyValueReader, hash common.Hash) ([]byte, error) {
25+
return db.Get(transitionStateKey(hash))
26+
}
27+
28+
func WriteVerkleTransitionState(db ethdb.KeyValueWriter, hash common.Hash, state []byte) error {
29+
return db.Put(transitionStateKey(hash), state)
30+
}

core/rawdb/schema.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ var (
158158
preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil)
159159
preimageHitsCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil)
160160
preimageMissCounter = metrics.NewRegisteredCounter("db/preimage/miss", nil)
161+
162+
// Verkle transition information
163+
VerkleTransitionStatePrefix = []byte("verkle-transition-state-")
161164
)
162165

163166
// LegacyTxLookupEntry is the legacy TxLookupEntry definition with some unnecessary
@@ -397,3 +400,8 @@ func storageHistoryIndexBlockKey(addressHash common.Hash, storageHash common.Has
397400
binary.BigEndian.PutUint32(buf[:], blockID)
398401
return append(append(append(StateHistoryStorageBlockPrefix, addressHash.Bytes()...), storageHash.Bytes()...), buf[:]...)
399402
}
403+
404+
// transitionStateKey = transitionStatusKey + hash
405+
func transitionStateKey(hash common.Hash) []byte {
406+
return append(VerkleTransitionStatePrefix, hash.Bytes()...)
407+
}

0 commit comments

Comments
 (0)