prysm-pulse/beacon-chain/blockchain/stategenerator/state_generator.go

73 lines
1.7 KiB
Go
Raw Normal View History

package stategenerator
import (
"context"
"fmt"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/hashutil"
)
// GenerateStateFromSlot generates state from the last finalized epoch till the specified slot.
func GenerateStateFromSlot(ctx context.Context, db *db.BeaconDB, slot uint64) (*pb.BeaconState, error) {
fState, err := db.FinalizedState()
if err != nil {
return nil, err
}
if fState.Slot > slot {
return nil, fmt.Errorf(
"requested slot %d < current slot %d in the finalized beacon state",
fState.Slot,
slot,
)
}
pBlock, err := db.BlockBySlot(fState.Slot)
if err != nil {
return nil, fmt.Errorf("could not retrieve block: %v", err)
}
root, err := hashutil.HashBeaconBlock(pBlock)
if err != nil {
return nil, fmt.Errorf("could not tree hash parent block: %v", err)
}
// run N state transitions to generate state
for i := fState.Slot + 1; i <= slot; i++ {
exists, blk, err := db.HasBlockBySlot(i)
if !exists {
fState, err = state.ExecuteStateTransition(
ctx,
fState,
nil,
root,
true, /* sig verify */
)
if err != nil {
return nil, fmt.Errorf("could not execute state transition %v", err)
}
continue
}
fState, err = state.ExecuteStateTransition(
ctx,
fState,
blk,
root,
true, /* sig verify */
)
if err != nil {
return nil, fmt.Errorf("could not execute state transition %v", err)
}
root, err = hashutil.HashBeaconBlock(blk)
if err != nil {
return nil, fmt.Errorf("could not tree hash parent block: %v", err)
}
}
return fState, nil
}