diff --git a/core/overlay/state_transition.go b/core/overlay/state_transition.go index b4eeec66b8..099d68cca5 100644 --- a/core/overlay/state_transition.go +++ b/core/overlay/state_transition.go @@ -17,11 +17,12 @@ package overlay import ( + "fmt" + "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie/bintrie" + "github.com/ethereum/go-ethereum/triedb/database" ) // TransitionState is a structure that holds the progress markers of the @@ -85,21 +86,26 @@ var ( // LoadTransitionState retrieves the Verkle transition state associated with // the given state root hash from the database. -func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash) *TransitionState { - stem := bintrie.GetBinaryTreeKeyStorageSlot(params.BinaryTransitionRegistryAddress, conversionProgressAddressKey[:]) - leaf := rawdb.ReadStorageTrieNode(db, common.Hash{}, stem[:bintrie.StemSize]) - if len(leaf) == 0 { - return &TransitionState{} - } - - node, err := bintrie.DeserializeNode(leaf, 0) +func LoadTransitionState(reader database.StateReader, root common.Hash) *TransitionState { + addrHash := crypto.Keccak256Hash(params.BinaryTransitionRegistryAddress[:]) + currentAccountBytes, err := reader.Storage(addrHash, conversionProgressAddressKey) if err != nil { - panic("could not deserialize conversion pointers contract storage") + panic(fmt.Errorf("error reading conversion account pointer: %w", err)) } - leafNode := node.(*bintrie.StemNode) - currentAccount := common.BytesToAddress(leafNode.Values[65][12:]) - currentSlotHash := common.BytesToHash(leafNode.Values[66]) - storageProcessed := len(leafNode.Values[67]) > 0 && leafNode.Values[67][0] != 0 + currentAccount := common.BytesToAddress(currentAccountBytes[12:]) + + currentSlotBytes, err := reader.Storage(addrHash, conversionProgressSlotKey) + if err != nil { + panic(fmt.Errorf("error reading conversion slot pointer: %w", err)) + } + currentSlotHash := common.BytesToHash(currentSlotBytes) + + storageProcessedBytes, err := reader.Storage(addrHash, conversionProgressStorageProcessed) + if err != nil { + panic(fmt.Errorf("error reading conversion storage processing completion status: %w", err)) + } + storageProcessed := storageProcessedBytes[0] == 1 + return &TransitionState{ CurrentAccountAddress: ¤tAccount, CurrentSlotHash: currentSlotHash, diff --git a/core/state/database.go b/core/state/database.go index fbc1c2dcf2..c94e62ba54 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -190,6 +190,7 @@ func (db *CachingDB) StateReader(stateRoot common.Hash) (StateReader, error) { readers = append(readers, newFlatReader(snap)) } } + var ts *overlay.TransitionState // Configure the state reader using the path database in path mode. // This reader offers improved performance but is optional and only // partially useful if the snapshot data in path database is not @@ -198,11 +199,12 @@ func (db *CachingDB) StateReader(stateRoot common.Hash) (StateReader, error) { reader, err := db.triedb.StateReader(stateRoot) if err == nil { readers = append(readers, newFlatReader(reader)) + ts = overlay.LoadTransitionState(reader, stateRoot) } } // Configure the trie reader, which is expected to be available as the // gatekeeper unless the state is corrupted. - tr, err := newTrieReader(stateRoot, db.triedb) + tr, err := newTrieReader(stateRoot, db.triedb, ts) if err != nil { return nil, err } @@ -246,7 +248,11 @@ func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) { if err != nil { return nil, fmt.Errorf("could not open the overlay tree: %w", err) } - ts := overlay.LoadTransitionState(db.TrieDB().Disk(), root) + reader, err := db.StateReader(root) + if err != nil { + return nil, fmt.Errorf("could not get reader for checking overlay status: %w", err) + } + ts := overlay.LoadTransitionState(reader, root) if !ts.InTransition() { // Use BinaryTrie instead of VerkleTrie when IsVerkle is set // (IsVerkle actually means Binary Trie mode in this codebase) diff --git a/core/state/reader.go b/core/state/reader.go index 6191cf7944..fd999b11ac 100644 --- a/core/state/reader.go +++ b/core/state/reader.go @@ -313,7 +313,7 @@ type trieReader struct { // newTrieReader constructs a trie reader of the specific state. An error will be // returned if the associated trie specified by root is not existent. -func newTrieReader(root common.Hash, db *triedb.Database) (*trieReader, error) { +func newTrieReader(root common.Hash, db *triedb.Database, ts *overlay.TransitionState) (*trieReader, error) { var ( tr Trie err error @@ -330,7 +330,6 @@ func newTrieReader(root common.Hash, db *triedb.Database) (*trieReader, error) { // Based on the transition status, determine if the overlay // tree needs to be created, or if a single, target tree is // to be picked. - ts := overlay.LoadTransitionState(db.Disk(), root) if ts.InTransition() { mpt, err := trie.NewStateTrie(trie.StateTrieID(ts.BaseRoot), db) if err != nil {