Skip to content

Commit

Permalink
Refactor transition post genesis (#311)
Browse files Browse the repository at this point in the history
* rewrite per-block conversion pointer management

* remove unused method

* fix: a branch that can verge at genesis or post genesis (#314)

* fix: import cycle in conversion refactor (#315)

* fix shadowfork panic in OpenStorageTrie
  • Loading branch information
gballet committed Apr 15, 2024
1 parent ddd8a3e commit da9377f
Show file tree
Hide file tree
Showing 9 changed files with 389 additions and 320 deletions.
7 changes: 7 additions & 0 deletions consensus/beacon/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/overlay"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -358,6 +359,12 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
// The returned gas is not charged
state.Witness().TouchFullAccount(w.Address[:], true)
}

if chain.Config().IsPrague(header.Number, header.Time) {
fmt.Println("at block", header.Number, "performing transition?", state.Database().InTransition())
parent := chain.GetHeaderByHash(header.ParentHash)
overlay.OverlayVerkleTransition(state, parent.Root)
}
}

// FinalizeAndAssemble implements consensus.Engine, setting the final state and
Expand Down
6 changes: 6 additions & 0 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis

// Declare the end of the verkle transition if need be
if bc.chainConfig.Rules(head.Number, false /* XXX */, head.Time).IsPrague {
// TODO this only works when resuming a chain that has already gone
// through the conversion. All pointers should be saved to the DB
// for it to be able to recover if interrupted during the transition
// but that's left out to a later PR since there's not really a need
// right now.
bc.stateCache.InitTransitionStatus(true, true)
bc.stateCache.EndVerkleTransition()
}

Expand Down
7 changes: 7 additions & 0 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,15 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
}
var snaps *snapshot.Tree
triedb := state.NewDatabaseWithConfig(db, nil)
triedb.StartVerkleTransition(common.Hash{}, common.Hash{}, config, config.PragueTime, common.Hash{})
triedb.EndVerkleTransition()
//statedb, err := state.New(parent.Root(), triedb, snaps)
//if err != nil {
// panic(fmt.Sprintf("could not find state for block %d: err=%v, parent root=%x", parent.NumberU64(), err, parent.Root()))
//}
statedb.Database().SaveTransitionState(parent.Root())
for i := 0; i < n; i++ {
// XXX merge uncommment
statedb, err := state.New(parent.Root(), triedb, snaps)
if err != nil {
panic(fmt.Sprintf("could not find state for block %d: err=%v, parent root=%x", i, err, parent.Root()))
Expand Down
21 changes: 12 additions & 9 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func (ga *GenesisAlloc) deriveHash(cfg *params.ChainConfig, timestamp uint64) (c
// all the derived states will be discarded to not pollute disk.
db := state.NewDatabase(rawdb.NewMemoryDatabase())
if cfg.IsPrague(big.NewInt(int64(0)), timestamp) {
db.StartVerkleTransition(common.Hash{}, common.Hash{}, cfg, &timestamp, common.Hash{})
db.EndVerkleTransition()
}
statedb, err := state.New(types.EmptyRootHash, db, nil)
Expand All @@ -146,15 +147,17 @@ func (ga *GenesisAlloc) deriveHash(cfg *params.ChainConfig, timestamp uint64) (c
// flush is very similar with deriveHash, but the main difference is
// all the generated states will be persisted into the given database.
// Also, the genesis state specification will be flushed as well.
func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhash common.Hash, cfg *params.ChainConfig) error {
statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil)
if err != nil {
return err
func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhash common.Hash, cfg *params.ChainConfig, timestamp *uint64) error {
database := state.NewDatabaseWithNodeDB(db, triedb)
// End the verkle conversion at genesis if the fork block is 0
if timestamp != nil && cfg.IsPrague(big.NewInt(int64(0)), *timestamp) {
database.StartVerkleTransition(common.Hash{}, common.Hash{}, cfg, timestamp, common.Hash{})
database.EndVerkleTransition()
}

// End the verkle conversion at genesis if the fork block is 0
if triedb.IsVerkle() {
statedb.Database().EndVerkleTransition()
statedb, err := state.New(types.EmptyRootHash, database, nil)
if err != nil {
return err
}

for addr, account := range *ga {
Expand Down Expand Up @@ -221,7 +224,7 @@ func CommitGenesisState(db ethdb.Database, triedb *trie.Database, blockhash comm
return errors.New("not found")
}
}
return alloc.flush(db, triedb, blockhash, config)
return alloc.flush(db, triedb, blockhash, config, nil)
}

// GenesisAccount is an account in the state of the genesis block.
Expand Down Expand Up @@ -536,7 +539,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *trie.Database) (*types.Block
// All the checks has passed, flush the states derived from the genesis
// specification as well as the specification itself into the provided
// database.
if err := g.Alloc.flush(db, triedb, block.Hash(), g.Config); err != nil {
if err := g.Alloc.flush(db, triedb, block.Hash(), g.Config, &g.Timestamp); err != nil {
return nil, err
}
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), block.Difficulty())
Expand Down
Loading

0 comments on commit da9377f

Please sign in to comment.