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

eth: add debug_conversionStatus RPC call #392

Merged
merged 4 commits into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,11 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *trie.Database) Database {
}

func (db *cachingDB) InTransition() bool {
return db.CurrentTransitionState != nil && db.CurrentTransitionState.started && !db.CurrentTransitionState.ended
return db.CurrentTransitionState != nil && db.CurrentTransitionState.Started && !db.CurrentTransitionState.Ended
}

func (db *cachingDB) Transitioned() bool {
return db.CurrentTransitionState != nil && db.CurrentTransitionState.ended
return db.CurrentTransitionState != nil && db.CurrentTransitionState.Ended
}

// Fork implements the fork
Expand All @@ -236,7 +236,7 @@ func (db *cachingDB) StartVerkleTransition(originalRoot, translatedRoot common.H
|____| |___| /\___ \___ |____/\___ | __/|___| (____ |___| |__| |___| (____ /_____/ \/\_/ |__|___| /_____//_____/
|__|`)
db.CurrentTransitionState = &TransitionState{
started: true,
Started: true,
// initialize so that the first storage-less accounts are processed
StorageProcessed: true,
}
Expand All @@ -255,15 +255,15 @@ func (db *cachingDB) ReorgThroughVerkleTransition() {

func (db *cachingDB) InitTransitionStatus(started, ended bool) {
db.CurrentTransitionState = &TransitionState{
ended: ended,
started: started,
Ended: ended,
Started: started,
// TODO add other fields when we handle mid-transition interrupts
}
}

func (db *cachingDB) EndVerkleTransition() {
if !db.CurrentTransitionState.started {
db.CurrentTransitionState.started = true
if !db.CurrentTransitionState.Started {
db.CurrentTransitionState.Started = true
}

fmt.Println(`
Expand All @@ -273,14 +273,14 @@ func (db *cachingDB) EndVerkleTransition() {
| | | Y \ ___/ \ ___/| |_\ ___/| |_> | Y \/ __ \| | | | | Y \/ __ \_\___ \ | |__/ __ \| | / /_/ \ ___// /_/ |
|____| |___| /\___ \___ |____/\___ | __/|___| (____ |___| |__| |___| (____ /_____/ |____(____ |___| \____ |\___ \____ |
|__|`)
db.CurrentTransitionState.ended = true
db.CurrentTransitionState.Ended = true
}

type TransitionState struct {
CurrentAccountAddress *common.Address // addresss of the last translated account
CurrentSlotHash common.Hash // hash of the last translated storage slot
CurrentPreimageOffset int64 // next byte to read from the preimage file
started, ended bool
Started, Ended bool

// Mark whether the storage for an account has been processed. This is useful if the
// maximum number of leaves of the conversion is reached before the whole storage is
Expand All @@ -290,8 +290,8 @@ type TransitionState struct {

func (ts *TransitionState) Copy() *TransitionState {
ret := &TransitionState{
started: ts.started,
ended: ts.ended,
Started: ts.Started,
Ended: ts.Ended,
CurrentSlotHash: ts.CurrentSlotHash,
CurrentPreimageOffset: ts.CurrentPreimageOffset,
StorageProcessed: ts.StorageProcessed,
Expand Down Expand Up @@ -334,14 +334,14 @@ func (db *cachingDB) openMPTTrie(root common.Hash) (Trie, error) {
func (db *cachingDB) openVKTrie(root common.Hash) (Trie, error) {
payload, err := db.DiskDB().Get(trie.FlatDBVerkleNodeKeyPrefix)
if err != nil {
return trie.NewVerkleTrie(verkle.New(), db.triedb, db.addrToPoint, db.CurrentTransitionState.ended), nil
return trie.NewVerkleTrie(verkle.New(), db.triedb, db.addrToPoint, db.CurrentTransitionState.Ended), nil
}

r, err := verkle.ParseNode(payload, 0)
if err != nil {
panic(err)
}
return trie.NewVerkleTrie(r, db.triedb, db.addrToPoint, db.CurrentTransitionState.ended), err
return trie.NewVerkleTrie(r, db.triedb, db.addrToPoint, db.CurrentTransitionState.Ended), err
}

// OpenTrie opens the main account trie at a specific root hash.
Expand All @@ -364,7 +364,7 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {

// If the verkle conversion has ended, return a single
// verkle trie.
if db.CurrentTransitionState.ended {
if db.CurrentTransitionState.Ended {
log.Debug("transition ended, returning a simple verkle tree")
return vkt, nil
}
Expand Down Expand Up @@ -572,7 +572,7 @@ func (db *cachingDB) SaveTransitionState(root common.Hash) {
rawdb.WriteVerkleTransitionState(db.DiskDB(), root, buf.Bytes())
}

log.Debug("saving transition state", "storage processed", db.CurrentTransitionState.StorageProcessed, "addr", db.CurrentTransitionState.CurrentAccountAddress, "slot hash", db.CurrentTransitionState.CurrentSlotHash, "root", root, "ended", db.CurrentTransitionState.ended, "started", db.CurrentTransitionState.started)
log.Debug("saving transition state", "storage processed", db.CurrentTransitionState.StorageProcessed, "addr", db.CurrentTransitionState.CurrentAccountAddress, "slot hash", db.CurrentTransitionState.CurrentSlotHash, "root", root, "ended", db.CurrentTransitionState.Ended, "started", db.CurrentTransitionState.Started)
}
}

Expand All @@ -590,7 +590,7 @@ func (db *cachingDB) LoadTransitionState(root common.Hash) {
return
}

// if a state could be read from the db, attempt to decode it
// if a state could be read from the db, attempt to decode it
if len(data) > 0 {
var (
newts TransitionState
Expand All @@ -613,15 +613,15 @@ func (db *cachingDB) LoadTransitionState(root common.Hash) {
// as a verkle database.
log.Debug("no transition state found, starting fresh", "is verkle", db.triedb.IsVerkle())
// Start with a fresh state
ts = &TransitionState{ended: db.triedb.IsVerkle()}
ts = &TransitionState{Ended: db.triedb.IsVerkle()}
}
}

// Copy so that the CurrentAddress pointer in the map
// doesn't get overwritten.
db.CurrentTransitionState = ts.Copy()

log.Debug("loaded transition state", "storage processed", db.CurrentTransitionState.StorageProcessed, "addr", db.CurrentTransitionState.CurrentAccountAddress, "slot hash", db.CurrentTransitionState.CurrentSlotHash, "root", root, "ended", db.CurrentTransitionState.ended, "started", db.CurrentTransitionState.started)
log.Debug("loaded transition state", "storage processed", db.CurrentTransitionState.StorageProcessed, "addr", db.CurrentTransitionState.CurrentAccountAddress, "slot hash", db.CurrentTransitionState.CurrentSlotHash, "root", root, "ended", db.CurrentTransitionState.Ended, "started", db.CurrentTransitionState.Started)
debug.PrintStack()
}

Expand Down
40 changes: 40 additions & 0 deletions eth/api_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package eth

import (
"bytes"
"context"
"encoding/gob"
"errors"
"fmt"
"time"
Expand Down Expand Up @@ -432,3 +434,41 @@ func (api *DebugAPI) SetTrieFlushInterval(interval string) error {
func (api *DebugAPI) GetTrieFlushInterval() string {
return api.eth.blockchain.GetTrieFlushInterval().String()
}

type ConversionStatusResult struct {
Started bool `json:"started"`
Ended bool `json:"ended"`
}

func (api *DebugAPI) ConversionStatus(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*ConversionStatusResult, error) {
block, err := api.eth.APIBackend.BlockByNumberOrHash(ctx, blockNrOrHash)
if err != nil {
return nil, err
}
data, err := rawdb.ReadVerkleTransitionState(api.eth.ChainDb(), block.Root())
if err != nil {
if err.Error() == "pebble: not found" {
return &ConversionStatusResult{}, nil
}
Comment on lines +450 to +452
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we care about LevelDB? Or in this case it doesn't return an error and len(data)==0?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leveldb support is going to be dropped, I think we shouldn't worry about it

return nil, err
gballet marked this conversation as resolved.
Show resolved Hide resolved
}
log.Info("found entry", "data", data)
if len(data) == 0 {
log.Info("found no data")
// started and ended will be false as no conversion has started
return &ConversionStatusResult{}, nil
}

var (
ts state.TransitionState
buf = bytes.NewBuffer(data[:])
dec = gob.NewDecoder(buf)
)
// Decode transition state
err = dec.Decode(&ts)
if err != nil {
return nil, fmt.Errorf("failed to decode transition state, err=%v", err)
}

return &ConversionStatusResult{Started: ts.Started, Ended: ts.Ended}, nil
}
Loading