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

nil value for beacondb .State() method when root == params.BeaconConfig().ZeroHash #9851

Closed
kasey opened this issue Nov 3, 2021 · 0 comments · Fixed by #9852
Closed

nil value for beacondb .State() method when root == params.BeaconConfig().ZeroHash #9851

kasey opened this issue Nov 3, 2021 · 0 comments · Fixed by #9852
Assignees

Comments

@kasey
Copy link
Contributor

kasey commented Nov 3, 2021

🐞 Bug Report

Description

The stategen.StateManager interface defines methods to retrieve the state by root for initial sync and during regular block syncing, StateByRoot and StateByRootInitialSync. These methods both have identical logic to check if the zero root is being requested and retrieve the state from the database in that case. This happens in interop / when truly starting from genesis (not using initial sync) before the justified/finalized checkpoints have been set to roots beyond the genesis block's parent root. So in practice this is not a common problem, but the code is logically incorrect, as demonstrated by a simple program running against the database of a synced beacon node db:

package main

import (
        "context"

        log "github.com/sirupsen/logrus"

        "github.com/prysmaticlabs/prysm/beacon-chain/db/kv"
        "github.com/prysmaticlabs/prysm/config/params"
)

func main() {
        path := "/var/lib/prysm/prater"
        ctx := context.Background()
        db, err := kv.NewKVStore(ctx, path, &kv.Config{})

        if err != nil {
                log.Fatalf("error calling NewKVStore, err=%v", err)
        }
        state, err := db.State(ctx, params.BeaconConfig().ZeroHash)
        if err != nil {
                log.Fatalf("error calling State() method on db, err=%v", err)
        }
        if state == nil || state.IsNil() {
                log.Fatalf("got nil state from db.State")
        }
        log.Info("%#x", state.FinalizedCheckpoint().Root)
}
$ go run main.go
FATA[0000] got nil state from db.State                  
exit status 1

However the state can be fetched as expected using the beacondb GenesisState method. Suggested solution is to change StateByRoot/StateByRootInitialSync to use this method when the zero root is detected, in place of attempting to fetch the state via the zero root.

Has this worked before in a previous version?

unclear, it seems that this bug likely only occurs in edge cases, and it may be the case that something in the interop set up prevents it from happening.

🔬 Minimal Reproduction

run the program above

🔥 Error

$ go run main.go
FATA[0000] got nil state from db.State                  
exit status 1

What version of Prysm are you running? (Which release)

current develop branch

@kasey kasey self-assigned this Nov 3, 2021
prylabs-bulldozer bot pushed a commit that referenced this issue Nov 5, 2021
…tateByRootInitialSync (#9852)

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant