Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: save and load transition state for block processing #324

Merged
merged 12 commits into from
Dec 8, 2023
1 change: 1 addition & 0 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error())
}
statedb.Database().SaveTransitionState(header.Root)
return nil
}

Expand Down
3 changes: 3 additions & 0 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
}

if bc.Config().IsPrague(block.Number(), block.Time()) {
bc.stateCache.LoadTransitionState(parent.Root)
}
if parent.Number.Uint64() == conversionBlock {
bc.StartVerkleTransition(parent.Root, emptyVerkleRoot, bc.Config(), &parent.Time, parent.Root)
bc.stateCache.SetLastMerkleRoot(parent.Root)
Expand Down
15 changes: 14 additions & 1 deletion core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,16 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *trie.Database) Database {
}

func (db *cachingDB) InTransition() bool {
if db.CurrentTransitionState == nil {
fmt.Println("nil transition state in in!")
}
gballet marked this conversation as resolved.
Show resolved Hide resolved
return db.CurrentTransitionState != nil && db.CurrentTransitionState.started && !db.CurrentTransitionState.ended
}

func (db *cachingDB) Transitioned() bool {
if db.CurrentTransitionState == nil {
fmt.Println("nil transition state in ed!")
}
gballet marked this conversation as resolved.
Show resolved Hide resolved
return db.CurrentTransitionState != nil && db.CurrentTransitionState.ended
}

Expand Down Expand Up @@ -244,6 +250,7 @@ func (db *cachingDB) ReorgThroughVerkleTransition() {
}

func (db *cachingDB) InitTransitionStatus(started, ended bool) {
fmt.Println("init-ing status", started, ended)
gballet marked this conversation as resolved.
Show resolved Hide resolved
db.CurrentTransitionState = &TransitionState{
ended: ended,
started: started,
Expand Down Expand Up @@ -342,10 +349,12 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {

// TODO separate both cases when I can be certain that it won't
// find a Verkle trie where is expects a Transitoion trie.
if db.CurrentTransitionState != nil && (db.CurrentTransitionState.started || db.CurrentTransitionState.ended) {
if db.InTransition() || db.Transitioned() {
fmt.Printf("opening tree: root=%x\n", root)
gballet marked this conversation as resolved.
Show resolved Hide resolved
// NOTE this is a kaustinen-only change, it will break replay
vkt, err := db.openVKTrie(root)
if err != nil {
fmt.Println("and vkt failed")
gballet marked this conversation as resolved.
Show resolved Hide resolved
return nil, err
}

Expand All @@ -359,6 +368,7 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
// trie and an overlay, verkle trie.
mpt, err = db.openMPTTrie(db.baseRoot)
if err != nil {
fmt.Println("and mpt failed")
return nil, err
gballet marked this conversation as resolved.
Show resolved Hide resolved
}

Expand Down Expand Up @@ -543,15 +553,18 @@ func (db *cachingDB) SaveTransitionState(root common.Hash) {
}

db.TransitionStatePerRoot[root] = db.CurrentTransitionState
fmt.Printf("saved transition state %x\n", root)
}

func (db *cachingDB) LoadTransitionState(root common.Hash) {
fmt.Printf("loading transition state %x %d\n", root, len(db.TransitionStatePerRoot))
gballet marked this conversation as resolved.
Show resolved Hide resolved
if db.TransitionStatePerRoot == nil {
db.TransitionStatePerRoot = make(map[common.Hash]*TransitionState)
}

ts, ok := db.TransitionStatePerRoot[root]
if !ok || ts == nil {
fmt.Println("starting with a fresh state")
// Start with a fresh state
ts = &TransitionState{ended: db.triedb.IsVerkle()}
}
Expand Down
13 changes: 11 additions & 2 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"errors"
"fmt"
"math/big"
"runtime/debug"
"sort"
"time"

Expand Down Expand Up @@ -1040,8 +1041,16 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
root := s.trie.Hash()

// Save the root of the MPT so that it can be used during the transition
if !s.Database().InTransition() && !s.Database().Transitioned() {
s.Database().SetLastMerkleRoot(root)
// if !s.Database().InTransition() && !s.Database().Transitioned() {
// s.Database().SetLastMerkleRoot(root)
// fmt.Printf("computed root=%x\n", root)
// }
gballet marked this conversation as resolved.
Show resolved Hide resolved
_, ismpt := s.trie.(*trie.StateTrie)
_, isvkt := s.trie.(*trie.VerkleTrie)
_, istrn := s.trie.(*trie.TransitionTrie)
fmt.Println("is MPT?", ismpt, isvkt, istrn)
if ismpt {
debug.PrintStack()
}

return root
Expand Down