mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
Fix validateConsensus (#15548)
* Fix validateConsensus Reported by NuConstruct The stater package looks for a stateroot using the head state from the blockchain package. However, this state is very unlikely to have the poststateroot since that's only added after slot processing. I assume that essentially any REST endpoint that uses this mechanism to get head is broken if it needs to gather a state by stateroot. This PR is a placeholder to verify this is the issue, here I just check if the NSC already has the post-state since that will have already the processing state cached. * Add changelog * add fallback * Fix tests
This commit is contained in:
@@ -1008,9 +1008,29 @@ func (s *Server) validateConsensus(ctx context.Context, b *eth.GenericSignedBeac
|
||||
}
|
||||
|
||||
parentStateRoot := parentBlock.Block().StateRoot()
|
||||
parentState, err := s.Stater.State(ctx, parentStateRoot[:])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get parent state")
|
||||
// Check if the state is already cached
|
||||
parentState := transition.NextSlotState(parentBlockRoot[:], blk.Block().Slot())
|
||||
if parentState == nil {
|
||||
// The state is not advanced in the NSC, check first if the parent post-state is head
|
||||
headRoot, err := s.HeadFetcher.HeadRoot(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get head root")
|
||||
}
|
||||
if bytes.Equal(headRoot, parentBlockRoot[:]) {
|
||||
parentState, err = s.HeadFetcher.HeadState(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get head state")
|
||||
}
|
||||
parentState, err = transition.ProcessSlots(ctx, parentState, blk.Block().Slot())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not process slots to get parent state")
|
||||
}
|
||||
} else {
|
||||
parentState, err = s.Stater.State(ctx, parentStateRoot[:])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get parent state")
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err = transition.ExecuteStateTransition(ctx, parentState, blk)
|
||||
if err != nil {
|
||||
|
||||
@@ -3504,9 +3504,14 @@ func TestValidateConsensus(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
parentRoot, err := parentSbb.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
mockChainService := &chainMock.ChainService{
|
||||
State: parentState,
|
||||
Root: parentRoot[:],
|
||||
}
|
||||
server := &Server{
|
||||
Blocker: &testutil.MockBlocker{RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{parentRoot: parentSbb}},
|
||||
Stater: &testutil.MockStater{StatesByRoot: map[[32]byte]state.BeaconState{bytesutil.ToBytes32(parentBlock.Block.StateRoot): parentState}},
|
||||
Blocker: &testutil.MockBlocker{RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{parentRoot: parentSbb}},
|
||||
Stater: &testutil.MockStater{StatesByRoot: map[[32]byte]state.BeaconState{bytesutil.ToBytes32(parentBlock.Block.StateRoot): parentState}},
|
||||
HeadFetcher: mockChainService,
|
||||
}
|
||||
|
||||
require.NoError(t, server.validateConsensus(ctx, ð.GenericSignedBeaconBlock{
|
||||
|
||||
2
changelog/potuz_fix_stater.md
Normal file
2
changelog/potuz_fix_stater.md
Normal file
@@ -0,0 +1,2 @@
|
||||
### Fixed
|
||||
- Fix the validateConsensus endpoint handler.
|
||||
Reference in New Issue
Block a user