Compare commits

...

9 Commits

Author SHA1 Message Date
terence tsao
e2422647d0 More errors. Still not done 2022-12-12 16:53:25 +08:00
terence tsao
f0ea14158e Merge branch 'develop' of github.com:prysmaticlabs/prysm into dev-payload-interfaces-no-panic 2022-12-12 16:02:04 +08:00
terence tsao
c228a3e0f6 Nishant's feedback 2022-12-12 16:01:27 +08:00
terence tsao
52d48b05f7 Started replacing panics with errors 2022-11-25 08:10:08 -08:00
terencechain
da7876a88a Merge branch 'develop' into inphi/dev-payload-interface 2022-11-25 07:35:08 -08:00
inphi
1863a16c25 fix test for fuzzing 2022-11-21 15:29:13 -05:00
inphi
99dba6d51b Fix spectest build errors 2022-11-21 14:52:55 -05:00
inphi
28c5d6d2cb Merge remote-tracking branch 'origin/develop' into inphi/dev-payload-interface 2022-11-21 14:40:15 -05:00
inphi
eeef4f473c Opaque payload header interface in beacon state
fixes #11604
2022-11-16 13:11:42 -05:00
90 changed files with 1273 additions and 480 deletions

View File

@@ -181,7 +181,7 @@ func (s *Service) HeadState(ctx context.Context) (state.BeaconState, error) {
span.AddAttributes(trace.BoolAttribute("cache_hit", ok)) span.AddAttributes(trace.BoolAttribute("cache_hit", ok))
if ok { if ok {
return s.headState(ctx), nil return s.headState(ctx)
} }
return s.cfg.StateGen.StateByRoot(ctx, s.headRoot()) return s.cfg.StateGen.StateByRoot(ctx, s.headRoot())
@@ -195,7 +195,11 @@ func (s *Service) HeadValidatorsIndices(ctx context.Context, epoch types.Epoch)
if !s.hasHeadState() { if !s.hasHeadState() {
return []types.ValidatorIndex{}, nil return []types.ValidatorIndex{}, nil
} }
return helpers.ActiveValidatorIndices(ctx, s.headState(ctx), epoch) hs, err := s.headState(ctx)
if err != nil {
return nil, err
}
return helpers.ActiveValidatorIndices(ctx, hs, epoch)
} }
// HeadGenesisValidatorsRoot returns genesis validators root of the head state. // HeadGenesisValidatorsRoot returns genesis validators root of the head state.

View File

@@ -198,7 +198,11 @@ func TestHeadState_CanRetrieve(t *testing.T) {
c.head = &head{state: s} c.head = &head{state: s}
headState, err := c.HeadState(context.Background()) headState, err := c.HeadState(context.Background())
require.NoError(t, err) require.NoError(t, err)
assert.DeepEqual(t, headState.ToProtoUnsafe(), s.ToProtoUnsafe(), "Incorrect head state received") s1, err := headState.ToProtoUnsafe()
require.NoError(t, err)
s2, err := s.ToProtoUnsafe()
require.NoError(t, err)
assert.DeepEqual(t, s1, s2, "Incorrect head state received")
} }
func TestGenesisTime_CanRetrieve(t *testing.T) { func TestGenesisTime_CanRetrieve(t *testing.T) {

View File

@@ -182,7 +182,7 @@ func (s *Service) getPayloadHash(ctx context.Context, root []byte) ([32]byte, er
// notifyNewPayload signals execution engine on a new payload. // notifyNewPayload signals execution engine on a new payload.
// It returns true if the EL has returned VALID for the block // It returns true if the EL has returned VALID for the block
func (s *Service) notifyNewPayload(ctx context.Context, postStateVersion int, func (s *Service) notifyNewPayload(ctx context.Context, postStateVersion int,
postStateHeader interfaces.ExecutionData, blk interfaces.SignedBeaconBlock) (bool, error) { postStateHeader interfaces.ExecutionDataHeader, blk interfaces.SignedBeaconBlock) (bool, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.notifyNewPayload") ctx, span := trace.StartSpan(ctx, "blockChain.notifyNewPayload")
defer span.End() defer span.End()
@@ -259,8 +259,12 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
} }
// Get previous randao. // Get previous randao.
st = st.Copy() st, err := st.Copy()
st, err := transition.ProcessSlotsIfPossible(ctx, st, slot) if err != nil {
log.WithError(err).Error("Could not copy state")
return false, emptyAttri, 0
}
st, err = transition.ProcessSlotsIfPossible(ctx, st, slot)
if err != nil { if err != nil {
log.WithError(err).Error("Could not process slots to get payload attribute") log.WithError(err).Error("Could not process slots to get payload attribute")
return false, emptyAttri, 0 return false, emptyAttri, 0

View File

@@ -201,11 +201,15 @@ func (s *Service) setHead(root [32]byte, block interfaces.SignedBeaconBlock, sta
if err != nil { if err != nil {
return err return err
} }
copiedState, err := state.Copy()
if err != nil {
return err
}
s.head = &head{ s.head = &head{
slot: block.Block().Slot(), slot: block.Block().Slot(),
root: root, root: root,
block: bCp, block: bCp,
state: state.Copy(), state: copiedState,
} }
return nil return nil
} }
@@ -258,7 +262,7 @@ func (s *Service) headBlock() (interfaces.SignedBeaconBlock, error) {
// This returns the head state. // This returns the head state.
// It does a full copy on head state for immutability. // It does a full copy on head state for immutability.
// This is a lock free version. // This is a lock free version.
func (s *Service) headState(ctx context.Context) state.BeaconState { func (s *Service) headState(ctx context.Context) (state.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.headState") ctx, span := trace.StartSpan(ctx, "blockChain.headState")
defer span.End() defer span.End()

View File

@@ -89,7 +89,13 @@ func TestSaveHead_Different(t *testing.T) {
pb, err := headBlock.Proto() pb, err := headBlock.Proto()
require.NoError(t, err) require.NoError(t, err)
assert.DeepEqual(t, newHeadSignedBlock, pb, "Head did not change") assert.DeepEqual(t, newHeadSignedBlock, pb, "Head did not change")
assert.DeepSSZEqual(t, headState.ToProto(), service.headState(ctx).ToProto(), "Head did not change") headStateProto, err := headState.ToProto()
require.NoError(t, err)
hs, err := service.headState(ctx)
require.NoError(t, err)
serviceHeadStateProto, err := hs.ToProto()
require.NoError(t, err)
assert.DeepSSZEqual(t, headStateProto, serviceHeadStateProto, "Head did not change")
} }
func TestSaveHead_Different_Reorg(t *testing.T) { func TestSaveHead_Different_Reorg(t *testing.T) {
@@ -147,7 +153,13 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
pb, err := headBlock.Proto() pb, err := headBlock.Proto()
require.NoError(t, err) require.NoError(t, err)
assert.DeepEqual(t, newHeadSignedBlock, pb, "Head did not change") assert.DeepEqual(t, newHeadSignedBlock, pb, "Head did not change")
assert.DeepSSZEqual(t, headState.ToProto(), service.headState(ctx).ToProto(), "Head did not change") headStateProto, err := headState.ToProto()
require.NoError(t, err)
hs, err := service.headState(ctx)
require.NoError(t, err)
serviceHeadStateProto, err := hs.ToProto()
require.NoError(t, err)
assert.DeepSSZEqual(t, headStateProto, serviceHeadStateProto, "Head did not change")
require.LogsContain(t, hook, "Chain reorg occurred") require.LogsContain(t, hook, "Chain reorg occurred")
require.LogsContain(t, hook, "distance=1") require.LogsContain(t, hook, "distance=1")
require.LogsContain(t, hook, "depth=1") require.LogsContain(t, hook, "depth=1")
@@ -501,7 +513,7 @@ func TestUpdateHead_noSavedChanges(t *testing.T) {
bellatrixState, _ := util.DeterministicGenesisStateBellatrix(t, 2) bellatrixState, _ := util.DeterministicGenesisStateBellatrix(t, 2)
require.NoError(t, beaconDB.SaveState(ctx, bellatrixState, bellatrixBlkRoot)) require.NoError(t, beaconDB.SaveState(ctx, bellatrixState, bellatrixBlkRoot))
service.cfg.StateGen.SaveFinalizedState(0, bellatrixBlkRoot, bellatrixState) require.NoError(t, service.cfg.StateGen.SaveFinalizedState(0, bellatrixBlkRoot, bellatrixState))
headRoot := service.headRoot() headRoot := service.headRoot()
require.Equal(t, [32]byte{}, headRoot) require.Equal(t, [32]byte{}, headRoot)

View File

@@ -338,7 +338,11 @@ func reportEpochMetrics(ctx context.Context, postState, headState state.BeaconSt
return err return err
} }
default: default:
return errors.Errorf("invalid state type provided: %T", headState.ToProtoUnsafe()) st, err := headState.ToProtoUnsafe()
if err != nil {
return err
}
return errors.Errorf("invalid state type provided: %T", st)
} }
prevEpochActiveBalances.Set(float64(b.ActivePrevEpoch)) prevEpochActiveBalances.Set(float64(b.ActivePrevEpoch))
prevEpochSourceBalances.Set(float64(b.PrevEpochAttested)) prevEpochSourceBalances.Set(float64(b.PrevEpochAttested))

View File

@@ -146,7 +146,8 @@ func TestStore_OnAttestation_Ok_DoublyLinkedTree(t *testing.T) {
att, err := util.GenerateAttestations(genesisState, pks, 1, 0, false) att, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err) require.NoError(t, err)
tRoot := bytesutil.ToBytes32(att[0].Data.Target.Root) tRoot := bytesutil.ToBytes32(att[0].Data.Target.Root)
copied := genesisState.Copy() copied, err := genesisState.Copy()
require.NoError(t, err)
copied, err = transition.ProcessSlots(ctx, copied, 1) copied, err = transition.ProcessSlots(ctx, copied, 1)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot)) require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
@@ -256,7 +257,11 @@ func TestStore_UpdateCheckpointState(t *testing.T) {
cached, err = service.checkpointStateCache.StateByCheckpoint(newCheckpoint) cached, err = service.checkpointStateCache.StateByCheckpoint(newCheckpoint)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, returned.ToProtoUnsafe(), cached.ToProtoUnsafe()) s1, err := returned.ToProtoUnsafe()
require.NoError(t, err)
s2, err := cached.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2)
} }
func TestAttEpoch_MatchPrevEpoch(t *testing.T) { func TestAttEpoch_MatchPrevEpoch(t *testing.T) {

View File

@@ -282,11 +282,11 @@ func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlo
return nil return nil
} }
func getStateVersionAndPayload(st state.BeaconState) (int, interfaces.ExecutionData, error) { func getStateVersionAndPayload(st state.BeaconState) (int, interfaces.ExecutionDataHeader, error) {
if st == nil { if st == nil {
return 0, nil, errors.New("nil state") return 0, nil, errors.New("nil state")
} }
var preStateHeader interfaces.ExecutionData var preStateHeader interfaces.ExecutionDataHeader
var err error var err error
preStateVersion := st.Version() preStateVersion := st.Version()
switch preStateVersion { switch preStateVersion {
@@ -344,7 +344,7 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []interfaces.SignedBeac
} }
type versionAndHeader struct { type versionAndHeader struct {
version int version int
header interfaces.ExecutionData header interfaces.ExecutionDataHeader
} }
preVersionAndHeaders := make([]*versionAndHeader, len(blks)) preVersionAndHeaders := make([]*versionAndHeader, len(blks))
postVersionAndHeaders := make([]*versionAndHeader, len(blks)) postVersionAndHeaders := make([]*versionAndHeader, len(blks))
@@ -366,7 +366,11 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []interfaces.SignedBeac
} }
// Save potential boundary states. // Save potential boundary states.
if slots.IsEpochStart(preState.Slot()) { if slots.IsEpochStart(preState.Slot()) {
boundaries[blockRoots[i]] = preState.Copy() st, err := preState.Copy()
if err != nil {
return err
}
boundaries[blockRoots[i]] = st
} }
jCheckpoints[i] = preState.CurrentJustifiedCheckpoint() jCheckpoints[i] = preState.CurrentJustifiedCheckpoint()
fCheckpoints[i] = preState.FinalizedCheckpoint() fCheckpoints[i] = preState.FinalizedCheckpoint()
@@ -476,8 +480,11 @@ func (s *Service) handleEpochBoundary(ctx context.Context, postState state.Beaco
defer span.End() defer span.End()
if postState.Slot()+1 == s.nextEpochBoundarySlot { if postState.Slot()+1 == s.nextEpochBoundarySlot {
copied := postState.Copy() copied, err := postState.Copy()
copied, err := transition.ProcessSlots(ctx, copied, copied.Slot()+1) if err != nil {
return err
}
copied, err = transition.ProcessSlots(ctx, copied, copied.Slot()+1)
if err != nil { if err != nil {
return err return err
} }
@@ -627,7 +634,7 @@ func (s *Service) pruneCanonicalAttsFromPool(ctx context.Context, r [32]byte, b
} }
// validateMergeTransitionBlock validates the merge transition block. // validateMergeTransitionBlock validates the merge transition block.
func (s *Service) validateMergeTransitionBlock(ctx context.Context, stateVersion int, stateHeader interfaces.ExecutionData, blk interfaces.SignedBeaconBlock) error { func (s *Service) validateMergeTransitionBlock(ctx context.Context, stateVersion int, stateHeader interfaces.ExecutionDataHeader, blk interfaces.SignedBeaconBlock) error {
// Skip validation if block is older than Bellatrix. // Skip validation if block is older than Bellatrix.
if blocks.IsPreBellatrixVersion(blk.Block().Version()) { if blocks.IsPreBellatrixVersion(blk.Block().Version()) {
return nil return nil
@@ -654,7 +661,7 @@ func (s *Service) validateMergeTransitionBlock(ctx context.Context, stateVersion
// Skip validation if the block is not a merge transition block. // Skip validation if the block is not a merge transition block.
// To reach here. The payload must be non-empty. If the state header is empty then it's at transition. // To reach here. The payload must be non-empty. If the state header is empty then it's at transition.
empty, err := consensusblocks.IsEmptyExecutionData(stateHeader) empty, err := consensusblocks.IsEmptyExecutionDataHeader(stateHeader)
if err != nil { if err != nil {
return err return err
} }
@@ -718,8 +725,12 @@ func (s *Service) fillMissingBlockPayloadId(ctx context.Context, ti time.Time) e
if err != nil { if err != nil {
return err return err
} else { } else {
hs, err := s.headState(ctx)
if err != nil {
return err
}
if _, err := s.notifyForkchoiceUpdate(ctx, &notifyForkchoiceUpdateArg{ if _, err := s.notifyForkchoiceUpdate(ctx, &notifyForkchoiceUpdateArg{
headState: s.headState(ctx), headState: hs,
headRoot: s.headRoot(), headRoot: s.headRoot(),
headBlock: headBlock.Block(), headBlock: headBlock.Block(),
}); err != nil { }); err != nil {

View File

@@ -66,7 +66,9 @@ func TestStore_OnBlock(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
st, err := util.NewBeaconState() st, err := util.NewBeaconState()
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot)) copiedSt, err := st.Copy()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copiedSt, validGenesisRoot))
roots, err := blockTree1(t, beaconDB, validGenesisRoot[:]) roots, err := blockTree1(t, beaconDB, validGenesisRoot[:])
require.NoError(t, err) require.NoError(t, err)
random := util.NewBeaconBlock() random := util.NewBeaconBlock()
@@ -76,11 +78,23 @@ func TestStore_OnBlock(t *testing.T) {
randomParentRoot, err := random.Block.HashTreeRoot() randomParentRoot, err := random.Block.HashTreeRoot()
assert.NoError(t, err) assert.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &ethpb.StateSummary{Slot: st.Slot(), Root: randomParentRoot[:]})) require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &ethpb.StateSummary{Slot: st.Slot(), Root: randomParentRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), randomParentRoot)) copiedSt1, err := st.Copy()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copiedSt1, randomParentRoot))
randomParentRoot2 := roots[1] randomParentRoot2 := roots[1]
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &ethpb.StateSummary{Slot: st.Slot(), Root: randomParentRoot2})) require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &ethpb.StateSummary{Slot: st.Slot(), Root: randomParentRoot2}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), bytesutil.ToBytes32(randomParentRoot2))) copiedSt2, err := st.Copy()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copiedSt2, bytesutil.ToBytes32(randomParentRoot2)))
c1, err := st.Copy()
require.NoError(t, err)
c2, err := st.Copy()
require.NoError(t, err)
c3, err := st.Copy()
require.NoError(t, err)
c4, err := st.Copy()
require.NoError(t, err)
tests := []struct { tests := []struct {
name string name string
blk *ethpb.SignedBeaconBlock blk *ethpb.SignedBeaconBlock
@@ -91,7 +105,7 @@ func TestStore_OnBlock(t *testing.T) {
{ {
name: "parent block root does not have a state", name: "parent block root does not have a state",
blk: util.NewBeaconBlock(), blk: util.NewBeaconBlock(),
s: st.Copy(), s: c1,
wantErrString: "could not reconstruct parent state", wantErrString: "could not reconstruct parent state",
}, },
{ {
@@ -102,7 +116,7 @@ func TestStore_OnBlock(t *testing.T) {
b.Block.Slot = params.BeaconConfig().FarFutureSlot b.Block.Slot = params.BeaconConfig().FarFutureSlot
return b return b
}(), }(),
s: st.Copy(), s: c2,
wantErrString: "is in the far distant future", wantErrString: "is in the far distant future",
}, },
{ {
@@ -112,7 +126,7 @@ func TestStore_OnBlock(t *testing.T) {
b.Block.ParentRoot = randomParentRoot[:] b.Block.ParentRoot = randomParentRoot[:]
return b return b
}(), }(),
s: st.Copy(), s: c3,
wantErrString: "is not a descendant of the current finalized block", wantErrString: "is not a descendant of the current finalized block",
}, },
{ {
@@ -123,7 +137,7 @@ func TestStore_OnBlock(t *testing.T) {
b.Block.ParentRoot = randomParentRoot2 b.Block.ParentRoot = randomParentRoot2
return b return b
}(), }(),
s: st.Copy(), s: c4,
wantErrString: "block is equal or earlier than finalized block, slot 0 < slot 0", wantErrString: "block is equal or earlier than finalized block, slot 0 < slot 0",
}, },
} }
@@ -157,7 +171,8 @@ func TestStore_OnBlockBatch(t *testing.T) {
st, keys := util.DeterministicGenesisState(t, 64) st, keys := util.DeterministicGenesisState(t, 64)
require.NoError(t, service.saveGenesisData(ctx, st)) require.NoError(t, service.saveGenesisData(ctx, st))
bState := st.Copy() bState, err := st.Copy()
require.NoError(t, err)
var blks []interfaces.SignedBeaconBlock var blks []interfaces.SignedBeaconBlock
var blkRoots [][32]byte var blkRoots [][32]byte
@@ -200,7 +215,8 @@ func TestStore_OnBlockBatch_NotifyNewPayload(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
st, keys := util.DeterministicGenesisState(t, 64) st, keys := util.DeterministicGenesisState(t, 64)
require.NoError(t, service.saveGenesisData(ctx, st)) require.NoError(t, service.saveGenesisData(ctx, st))
bState := st.Copy() bState, err := st.Copy()
require.NoError(t, err)
var blks []interfaces.SignedBeaconBlock var blks []interfaces.SignedBeaconBlock
var blkRoots [][32]byte var blkRoots [][32]byte
@@ -370,7 +386,9 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
st, err := util.NewBeaconState() st, err := util.NewBeaconState()
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot)) copied, err := st.Copy()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, validGenesisRoot))
// Define a tree branch, slot 63 <- 64 <- 65 // Define a tree branch, slot 63 <- 64 <- 65
b63 := util.NewBeaconBlock() b63 := util.NewBeaconBlock()
@@ -429,7 +447,9 @@ func TestFillForkChoiceMissingBlocks_FinalizedSibling(t *testing.T) {
st, err := util.NewBeaconState() st, err := util.NewBeaconState()
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot)) copied, err := st.Copy()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, validGenesisRoot))
roots, err := blockTree1(t, beaconDB, validGenesisRoot[:]) roots, err := blockTree1(t, beaconDB, validGenesisRoot[:])
require.NoError(t, err) require.NoError(t, err)
@@ -523,17 +543,25 @@ func blockTree1(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][]byt
if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil { if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil {
return nil, err return nil, err
} }
if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { copied1, err := st.Copy()
require.NoError(t, err)
if err := beaconDB.SaveState(context.Background(), copied1, bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
return nil, errors.Wrap(err, "could not save state") return nil, errors.Wrap(err, "could not save state")
} }
} }
if err := beaconDB.SaveState(context.Background(), st.Copy(), r1); err != nil { copied2, err := st.Copy()
require.NoError(t, err)
if err := beaconDB.SaveState(context.Background(), copied2, r1); err != nil {
return nil, err return nil, err
} }
if err := beaconDB.SaveState(context.Background(), st.Copy(), r7); err != nil { copied3, err := st.Copy()
require.NoError(t, err)
if err := beaconDB.SaveState(context.Background(), copied3, r7); err != nil {
return nil, err return nil, err
} }
if err := beaconDB.SaveState(context.Background(), st.Copy(), r8); err != nil { copied4, err := st.Copy()
require.NoError(t, err)
if err := beaconDB.SaveState(context.Background(), copied4, r8); err != nil {
return nil, err return nil, err
} }
return [][]byte{r0[:], r1[:], nil, r3[:], r4[:], r5[:], r6[:], r7[:], r8[:]}, nil return [][]byte{r0[:], r1[:], nil, r3[:], r4[:], r5[:], r6[:], r7[:], r8[:]}, nil
@@ -824,7 +852,8 @@ func TestOnBlock_CanFinalize_WithOnTick(t *testing.T) {
require.NoError(t, service.saveGenesisData(ctx, gs)) require.NoError(t, service.saveGenesisData(ctx, gs))
require.NoError(t, fcs.UpdateFinalizedCheckpoint(&forkchoicetypes.Checkpoint{Root: service.originBlockRoot})) require.NoError(t, fcs.UpdateFinalizedCheckpoint(&forkchoicetypes.Checkpoint{Root: service.originBlockRoot}))
testState := gs.Copy() testState, err := gs.Copy()
require.NoError(t, err)
for i := types.Slot(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ { for i := types.Slot(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ {
blk, err := util.GenerateFullBlock(testState, keys, util.DefaultBlockGenConfig(), i) blk, err := util.GenerateFullBlock(testState, keys, util.DefaultBlockGenConfig(), i)
require.NoError(t, err) require.NoError(t, err)
@@ -873,7 +902,8 @@ func TestOnBlock_CanFinalize(t *testing.T) {
gs, keys := util.DeterministicGenesisState(t, 32) gs, keys := util.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs)) require.NoError(t, service.saveGenesisData(ctx, gs))
testState := gs.Copy() testState, err := gs.Copy()
require.NoError(t, err)
for i := types.Slot(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ { for i := types.Slot(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ {
blk, err := util.GenerateFullBlock(testState, keys, util.DefaultBlockGenConfig(), i) blk, err := util.GenerateFullBlock(testState, keys, util.DefaultBlockGenConfig(), i)
require.NoError(t, err) require.NoError(t, err)
@@ -975,7 +1005,8 @@ func TestOnBlock_CallNewPayloadAndForkchoiceUpdated(t *testing.T) {
gs, keys := util.DeterministicGenesisState(t, 32) gs, keys := util.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs)) require.NoError(t, service.saveGenesisData(ctx, gs))
testState := gs.Copy() testState, err := gs.Copy()
require.NoError(t, err)
for i := types.Slot(1); i < params.BeaconConfig().SlotsPerEpoch; i++ { for i := types.Slot(1); i < params.BeaconConfig().SlotsPerEpoch; i++ {
blk, err := util.GenerateFullBlock(testState, keys, util.DefaultBlockGenConfig(), i) blk, err := util.GenerateFullBlock(testState, keys, util.DefaultBlockGenConfig(), i)
require.NoError(t, err) require.NoError(t, err)
@@ -1000,7 +1031,8 @@ func TestInsertFinalizedDeposits(t *testing.T) {
gs, _ := util.DeterministicGenesisState(t, 32) gs, _ := util.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs)) require.NoError(t, service.saveGenesisData(ctx, gs))
gs = gs.Copy() gs, err = gs.Copy()
require.NoError(t, err)
assert.NoError(t, gs.SetEth1Data(&ethpb.Eth1Data{DepositCount: 10})) assert.NoError(t, gs.SetEth1Data(&ethpb.Eth1Data{DepositCount: 10}))
assert.NoError(t, gs.SetEth1DepositIndex(8)) assert.NoError(t, gs.SetEth1DepositIndex(8))
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs)) assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
@@ -1034,11 +1066,13 @@ func TestInsertFinalizedDeposits_MultipleFinalizedRoutines(t *testing.T) {
gs, _ := util.DeterministicGenesisState(t, 32) gs, _ := util.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs)) require.NoError(t, service.saveGenesisData(ctx, gs))
gs = gs.Copy() gs, err = gs.Copy()
require.NoError(t, err)
assert.NoError(t, gs.SetEth1Data(&ethpb.Eth1Data{DepositCount: 7})) assert.NoError(t, gs.SetEth1Data(&ethpb.Eth1Data{DepositCount: 7}))
assert.NoError(t, gs.SetEth1DepositIndex(6)) assert.NoError(t, gs.SetEth1DepositIndex(6))
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs)) assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
gs2 := gs.Copy() gs2, err := gs.Copy()
require.NoError(t, err)
assert.NoError(t, gs2.SetEth1Data(&ethpb.Eth1Data{DepositCount: 15})) assert.NoError(t, gs2.SetEth1Data(&ethpb.Eth1Data{DepositCount: 15}))
assert.NoError(t, gs2.SetEth1DepositIndex(13)) assert.NoError(t, gs2.SetEth1DepositIndex(13))
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k', '2'}, gs2)) assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k', '2'}, gs2))

View File

@@ -109,7 +109,8 @@ func TestProcessAttestations_Ok(t *testing.T) {
atts, err := util.GenerateAttestations(genesisState, pks, 1, 0, false) atts, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err) require.NoError(t, err)
tRoot := bytesutil.ToBytes32(atts[0].Data.Target.Root) tRoot := bytesutil.ToBytes32(atts[0].Data.Target.Root)
copied := genesisState.Copy() copied, err := genesisState.Copy()
require.NoError(t, err)
copied, err = transition.ProcessSlots(ctx, copied, 1) copied, err = transition.ProcessSlots(ctx, copied, 1)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot)) require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
@@ -212,7 +213,8 @@ func TestService_ProcessAttestationsAndUpdateHead(t *testing.T) {
service.genesisTime = prysmTime.Now().Add(-2 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second) service.genesisTime = prysmTime.Now().Add(-2 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
genesisState, pks := util.DeterministicGenesisState(t, 64) genesisState, pks := util.DeterministicGenesisState(t, 64)
require.NoError(t, service.saveGenesisData(ctx, genesisState)) require.NoError(t, service.saveGenesisData(ctx, genesisState))
copied := genesisState.Copy() copied, err := genesisState.Copy()
require.NoError(t, err)
// Generate a new block for attesters to attest // Generate a new block for attesters to attest
blk, err := util.GenerateFullBlock(copied, pks, util.DefaultBlockGenConfig(), 1) blk, err := util.GenerateFullBlock(copied, pks, util.DefaultBlockGenConfig(), 1)
require.NoError(t, err) require.NoError(t, err)
@@ -269,7 +271,8 @@ func TestService_UpdateHead_NoAtts(t *testing.T) {
service.genesisTime = prysmTime.Now().Add(-2 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second) service.genesisTime = prysmTime.Now().Add(-2 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
genesisState, pks := util.DeterministicGenesisState(t, 64) genesisState, pks := util.DeterministicGenesisState(t, 64)
require.NoError(t, service.saveGenesisData(ctx, genesisState)) require.NoError(t, service.saveGenesisData(ctx, genesisState))
copied := genesisState.Copy() copied, err := genesisState.Copy()
require.NoError(t, err)
// Generate a new block // Generate a new block
blk, err := util.GenerateFullBlock(copied, pks, util.DefaultBlockGenConfig(), 1) blk, err := util.GenerateFullBlock(copied, pks, util.DefaultBlockGenConfig(), 1)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -431,7 +431,9 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState state.Beacon
} }
s.originBlockRoot = genesisBlkRoot s.originBlockRoot = genesisBlkRoot
s.cfg.StateGen.SaveFinalizedState(0 /*slot*/, genesisBlkRoot, genesisState) if err := s.cfg.StateGen.SaveFinalizedState(0 /*slot*/, genesisBlkRoot, genesisState); err != nil {
return err
}
if err := s.cfg.ForkChoiceStore.InsertNode(ctx, genesisState, genesisBlkRoot); err != nil { if err := s.cfg.ForkChoiceStore.InsertNode(ctx, genesisState, genesisBlkRoot); err != nil {
log.WithError(err).Fatal("Could not process genesis block for fork choice") log.WithError(err).Fatal("Could not process genesis block for fork choice")

View File

@@ -83,7 +83,9 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
srv.Stop() srv.Stop()
}) })
bState, _ := util.DeterministicGenesisState(t, 10) bState, _ := util.DeterministicGenesisState(t, 10)
pbState, err := state_native.ProtobufBeaconStatePhase0(bState.ToProtoUnsafe()) pbUnsafe, err := bState.ToProtoUnsafe()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStatePhase0(pbUnsafe)
require.NoError(t, err) require.NoError(t, err)
mockTrie, err := trie.NewTrie(0) mockTrie, err := trie.NewTrie(0)
require.NoError(t, err) require.NoError(t, err)
@@ -325,7 +327,11 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
assert.DeepEqual(t, headBlock, pb, "Head block incorrect") assert.DeepEqual(t, headBlock, pb, "Head block incorrect")
s, err := c.HeadState(ctx) s, err := c.HeadState(ctx)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, headState.ToProtoUnsafe(), s.ToProtoUnsafe(), "Head state incorrect") s1, err := headState.ToProtoUnsafe()
require.NoError(t, err)
s2, err := s.ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, s1, s2, "Head state incorrect")
assert.Equal(t, c.HeadSlot(), headBlock.Block.Slot, "Head slot incorrect") assert.Equal(t, c.HeadSlot(), headBlock.Block.Slot, "Head slot incorrect")
r, err := c.HeadRoot(context.Background()) r, err := c.HeadRoot(context.Background())
require.NoError(t, err) require.NoError(t, err)
@@ -380,7 +386,11 @@ func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
require.NoError(t, c.StartFromSavedState(headState)) require.NoError(t, c.StartFromSavedState(headState))
s, err := c.HeadState(ctx) s, err := c.HeadState(ctx)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, headState.ToProtoUnsafe(), s.ToProtoUnsafe(), "Head state incorrect") s1, err := headState.ToProtoUnsafe()
require.NoError(t, err)
s2, err := s.ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, s1, s2, "Head state incorrect")
assert.Equal(t, genesisRoot, c.originBlockRoot, "Genesis block root incorrect") assert.Equal(t, genesisRoot, c.originBlockRoot, "Genesis block root incorrect")
pb, err := c.head.block.Proto() pb, err := c.head.block.Proto()
require.NoError(t, err) require.NoError(t, err)

View File

@@ -33,9 +33,13 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
s, err = cache.StateByCheckpoint(cp1) s, err = cache.StateByCheckpoint(cp1)
require.NoError(t, err) require.NoError(t, err)
pbState1, err := state_native.ProtobufBeaconStatePhase0(s.ToProtoUnsafe()) pbs1, err := s.ToProtoUnsafe()
require.NoError(t, err) require.NoError(t, err)
pbstate, err := state_native.ProtobufBeaconStatePhase0(st.ToProtoUnsafe()) pbState1, err := state_native.ProtobufBeaconStatePhase0(pbs1)
require.NoError(t, err)
pbs2, err := st.ToProtoUnsafe()
require.NoError(t, err)
pbstate, err := state_native.ProtobufBeaconStatePhase0(pbs2)
require.NoError(t, err) require.NoError(t, err)
if !proto.Equal(pbState1, pbstate) { if !proto.Equal(pbState1, pbstate) {
t.Error("incorrectly cached state") t.Error("incorrectly cached state")
@@ -50,11 +54,19 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
s, err = cache.StateByCheckpoint(cp2) s, err = cache.StateByCheckpoint(cp2)
require.NoError(t, err) require.NoError(t, err)
assert.DeepEqual(t, st2.ToProto(), s.ToProto(), "incorrectly cached state") sProto, err := s.ToProto()
require.NoError(t, err)
st2Proto, err := st2.ToProto()
require.NoError(t, err)
assert.DeepEqual(t, st2Proto, sProto, "incorrectly cached state")
s, err = cache.StateByCheckpoint(cp1) s, err = cache.StateByCheckpoint(cp1)
require.NoError(t, err) require.NoError(t, err)
assert.DeepEqual(t, st.ToProto(), s.ToProto(), "incorrectly cached state") stProto, err := st.ToProto()
require.NoError(t, err)
sProto, err = s.ToProto()
require.NoError(t, err)
assert.DeepEqual(t, stProto, sProto, "incorrectly cached state")
} }
func TestCheckpointStateCache_MaxSize(t *testing.T) { func TestCheckpointStateCache_MaxSize(t *testing.T) {

View File

@@ -94,7 +94,11 @@ func (c *SkipSlotCache) Get(ctx context.Context, r [32]byte) (state.BeaconState,
if exists && item != nil { if exists && item != nil {
skipSlotCacheHit.Inc() skipSlotCacheHit.Inc()
span.AddAttributes(trace.BoolAttribute("hit", true)) span.AddAttributes(trace.BoolAttribute("hit", true))
return item.(state.BeaconState).Copy(), nil c, err := item.(state.BeaconState).Copy()
if err != nil {
return nil, err
}
return c, nil
} }
skipSlotCacheMiss.Inc() skipSlotCacheMiss.Inc()
span.AddAttributes(trace.BoolAttribute("hit", false)) span.AddAttributes(trace.BoolAttribute("hit", false))
@@ -132,10 +136,15 @@ func (c *SkipSlotCache) MarkNotInProgress(r [32]byte) {
} }
// Put the response in the cache. // Put the response in the cache.
func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state state.BeaconState) { func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state state.BeaconState) error {
if c.disabled { if c.disabled {
return return nil
} }
// Copy state so cached value is not mutated. // Copy state so cached value is not mutated.
c.cache.Add(r, state.Copy()) cpy, err := state.Copy()
if err != nil {
return err
}
c.cache.Add(r, cpy)
return nil
} }

View File

@@ -28,10 +28,14 @@ func TestSkipSlotCache_RoundTrip(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
c.Put(ctx, r, s) require.NoError(t, c.Put(ctx, r, s))
c.MarkNotInProgress(r) c.MarkNotInProgress(r)
res, err := c.Get(ctx, r) res, err := c.Get(ctx, r)
require.NoError(t, err) require.NoError(t, err)
assert.DeepEqual(t, res.ToProto(), s.ToProto(), "Expected equal protos to return from cache") resProto, err := res.ToProto()
require.NoError(t, err)
sProto, err := s.ToProto()
require.NoError(t, err)
assert.DeepEqual(t, resProto, sProto, "Expected equal protos to return from cache")
} }

View File

@@ -307,7 +307,8 @@ func TestProcessRewardsAndPenaltiesPrecompute_InactivityLeak(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
validators, balance, err = ProcessEpochParticipation(context.Background(), s, balance, validators) validators, balance, err = ProcessEpochParticipation(context.Background(), s, balance, validators)
require.NoError(t, err) require.NoError(t, err)
sCopy := s.Copy() sCopy, err := s.Copy()
require.NoError(t, err)
s, err = ProcessRewardsAndPenaltiesPrecompute(s, balance, validators) s, err = ProcessRewardsAndPenaltiesPrecompute(s, balance, validators)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -72,7 +72,8 @@ func TestTranslateParticipation(t *testing.T) {
func TestUpgradeToAltair(t *testing.T) { func TestUpgradeToAltair(t *testing.T) {
st, _ := util.DeterministicGenesisState(t, params.BeaconConfig().MaxValidatorsPerCommittee) st, _ := util.DeterministicGenesisState(t, params.BeaconConfig().MaxValidatorsPerCommittee)
preForkState := st.Copy() preForkState, err := st.Copy()
require.NoError(t, err)
aState, err := altair.UpgradeToAltair(context.Background(), st) aState, err := altair.UpgradeToAltair(context.Background(), st)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -41,7 +41,7 @@ func IsMergeTransitionComplete(st state.BeaconState) (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
isEmpty, err := blocks.IsEmptyExecutionData(h) isEmpty, err := blocks.IsEmptyExecutionDataHeader(h)
if err != nil { if err != nil {
return false, err return false, err
} }
@@ -96,8 +96,8 @@ func IsExecutionEnabled(st state.BeaconState, body interfaces.BeaconBlockBody) (
// IsExecutionEnabledUsingHeader returns true if the execution is enabled using post processed payload header and block body. // IsExecutionEnabledUsingHeader returns true if the execution is enabled using post processed payload header and block body.
// This is an optimized version of IsExecutionEnabled where beacon state is not required as an argument. // This is an optimized version of IsExecutionEnabled where beacon state is not required as an argument.
func IsExecutionEnabledUsingHeader(header interfaces.ExecutionData, body interfaces.BeaconBlockBody) (bool, error) { func IsExecutionEnabledUsingHeader(header interfaces.ExecutionDataHeader, body interfaces.BeaconBlockBody) (bool, error) {
isEmpty, err := blocks.IsEmptyExecutionData(header) isEmpty, err := blocks.IsEmptyExecutionDataHeader(header)
if err != nil { if err != nil {
return false, err return false, err
} }
@@ -120,7 +120,7 @@ func IsPreBellatrixVersion(v int) bool {
// # Verify consistency of the parent hash with respect to the previous execution payload header // # Verify consistency of the parent hash with respect to the previous execution payload header
// if is_merge_complete(state): // if is_merge_complete(state):
// assert payload.parent_hash == state.latest_execution_payload_header.block_hash // assert payload.parent_hash == state.latest_execution_payload_header.block_hash
func ValidatePayloadWhenMergeCompletes(st state.BeaconState, payload interfaces.ExecutionData) error { func ValidatePayloadWhenMergeCompletes(st state.BeaconState, payload interfaces.ExecutionDataHeader) error {
complete, err := IsMergeTransitionComplete(st) complete, err := IsMergeTransitionComplete(st)
if err != nil { if err != nil {
return err return err
@@ -223,7 +223,7 @@ func ProcessPayload(st state.BeaconState, payload interfaces.ExecutionData) (sta
} }
// ValidatePayloadHeaderWhenMergeCompletes validates the payload header when the merge completes. // ValidatePayloadHeaderWhenMergeCompletes validates the payload header when the merge completes.
func ValidatePayloadHeaderWhenMergeCompletes(st state.BeaconState, header interfaces.ExecutionData) error { func ValidatePayloadHeaderWhenMergeCompletes(st state.BeaconState, header interfaces.ExecutionDataHeader) error {
// Skip validation if the state is not merge compatible. // Skip validation if the state is not merge compatible.
complete, err := IsMergeTransitionComplete(st) complete, err := IsMergeTransitionComplete(st)
if err != nil { if err != nil {
@@ -244,7 +244,7 @@ func ValidatePayloadHeaderWhenMergeCompletes(st state.BeaconState, header interf
} }
// ValidatePayloadHeader validates the payload header. // ValidatePayloadHeader validates the payload header.
func ValidatePayloadHeader(st state.BeaconState, header interfaces.ExecutionData) error { func ValidatePayloadHeader(st state.BeaconState, header interfaces.ExecutionDataHeader) error {
// Validate header's random mix matches with state in current epoch // Validate header's random mix matches with state in current epoch
random, err := helpers.RandaoMix(st, time.CurrentEpoch(st)) random, err := helpers.RandaoMix(st, time.CurrentEpoch(st))
if err != nil { if err != nil {
@@ -266,7 +266,7 @@ func ValidatePayloadHeader(st state.BeaconState, header interfaces.ExecutionData
} }
// ProcessPayloadHeader processes the payload header. // ProcessPayloadHeader processes the payload header.
func ProcessPayloadHeader(st state.BeaconState, header interfaces.ExecutionData) (state.BeaconState, error) { func ProcessPayloadHeader(st state.BeaconState, header interfaces.ExecutionDataHeader) (state.BeaconState, error) {
if err := ValidatePayloadHeaderWhenMergeCompletes(st, header); err != nil { if err := ValidatePayloadHeaderWhenMergeCompletes(st, header); err != nil {
return nil, err return nil, err
} }

View File

@@ -737,7 +737,8 @@ func Test_ValidatePayloadHeader(t *testing.T) {
func Test_ValidatePayloadHeaderWhenMergeCompletes(t *testing.T) { func Test_ValidatePayloadHeaderWhenMergeCompletes(t *testing.T) {
st, _ := util.DeterministicGenesisStateBellatrix(t, 1) st, _ := util.DeterministicGenesisStateBellatrix(t, 1)
emptySt := st.Copy() emptySt, err := st.Copy()
require.NoError(t, err)
wrappedHeader, err := consensusblocks.WrappedExecutionPayloadHeader(&enginev1.ExecutionPayloadHeader{BlockHash: []byte{'a'}}) wrappedHeader, err := consensusblocks.WrappedExecutionPayloadHeader(&enginev1.ExecutionPayloadHeader{BlockHash: []byte{'a'}})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, st.SetLatestExecutionPayloadHeader(wrappedHeader)) require.NoError(t, st.SetLatestExecutionPayloadHeader(wrappedHeader))

View File

@@ -15,7 +15,8 @@ import (
func TestUpgradeToCapella(t *testing.T) { func TestUpgradeToCapella(t *testing.T) {
st, _ := util.DeterministicGenesisStateBellatrix(t, params.BeaconConfig().MaxValidatorsPerCommittee) st, _ := util.DeterministicGenesisStateBellatrix(t, params.BeaconConfig().MaxValidatorsPerCommittee)
preForkState := st.Copy() preForkState, err := st.Copy()
require.NoError(t, err)
mSt, err := capella.UpgradeToCapella(st) mSt, err := capella.UpgradeToCapella(st)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -14,7 +14,8 @@ import (
func TestUpgradeToBellatrix(t *testing.T) { func TestUpgradeToBellatrix(t *testing.T) {
st, _ := util.DeterministicGenesisStateAltair(t, params.BeaconConfig().MaxValidatorsPerCommittee) st, _ := util.DeterministicGenesisStateAltair(t, params.BeaconConfig().MaxValidatorsPerCommittee)
preForkState := st.Copy() preForkState, err := st.Copy()
require.NoError(t, err)
mSt, err := execution.UpgradeToBellatrix(st) mSt, err := execution.UpgradeToBellatrix(st)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -50,7 +50,9 @@ func TestExecuteAltairStateTransitionNoVerify_FullProcess(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1)) require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
nextSlotState, err := transition.ProcessSlots(context.Background(), beaconState.Copy(), beaconState.Slot()+1) c, err := beaconState.Copy()
require.NoError(t, err)
nextSlotState, err := transition.ProcessSlots(context.Background(), c, beaconState.Slot()+1)
require.NoError(t, err) require.NoError(t, err)
parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot() parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)
@@ -96,7 +98,8 @@ func TestExecuteAltairStateTransitionNoVerify_FullProcess(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
block.Block.StateRoot = stateRoot[:] block.Block.StateRoot = stateRoot[:]
c := beaconState.Copy() c, err = beaconState.Copy()
require.NoError(t, err)
sig, err := util.BlockSignatureAltair(c, block.Block, privKeys) sig, err := util.BlockSignatureAltair(c, block.Block, privKeys)
require.NoError(t, err) require.NoError(t, err)
block.Signature = sig.Marshal() block.Signature = sig.Marshal()
@@ -137,7 +140,9 @@ func TestExecuteAltairStateTransitionNoVerifySignature_CouldNotVerifyStateRoot(t
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1)) require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
nextSlotState, err := transition.ProcessSlots(context.Background(), beaconState.Copy(), beaconState.Slot()+1) c, err := beaconState.Copy()
require.NoError(t, err)
nextSlotState, err := transition.ProcessSlots(context.Background(), c, beaconState.Slot()+1)
require.NoError(t, err) require.NoError(t, err)
parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot() parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)
@@ -184,7 +189,8 @@ func TestExecuteAltairStateTransitionNoVerifySignature_CouldNotVerifyStateRoot(t
require.NoError(t, err) require.NoError(t, err)
block.Block.StateRoot = stateRoot[:] block.Block.StateRoot = stateRoot[:]
c := beaconState.Copy() c, err = beaconState.Copy()
require.NoError(t, err)
sig, err := util.BlockSignatureAltair(c, block.Block, privKeys) sig, err := util.BlockSignatureAltair(c, block.Block, privKeys)
require.NoError(t, err) require.NoError(t, err)
block.Signature = sig.Marshal() block.Signature = sig.Marshal()
@@ -235,7 +241,8 @@ func createFullAltairBlockWithOperations(t *testing.T) (state.BeaconState,
sCom, err := altair.NextSyncCommittee(context.Background(), beaconState) sCom, err := altair.NextSyncCommittee(context.Background(), beaconState)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, beaconState.SetCurrentSyncCommittee(sCom)) assert.NoError(t, beaconState.SetCurrentSyncCommittee(sCom))
tState := beaconState.Copy() tState, err := beaconState.Copy()
assert.NoError(t, err)
blk, err := util.GenerateFullBlockAltair(tState, privKeys, blk, err := util.GenerateFullBlockAltair(tState, privKeys,
&util.BlockGenConfig{NumAttestations: 1, NumVoluntaryExits: 0, NumDeposits: 0}, 1) &util.BlockGenConfig{NumAttestations: 1, NumVoluntaryExits: 0, NumDeposits: 0}, 1)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -52,7 +52,9 @@ func TestExecuteBellatrixStateTransitionNoVerify_FullProcess(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1)) require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
nextSlotState, err := transition.ProcessSlots(context.Background(), beaconState.Copy(), beaconState.Slot()+1) copied, err := beaconState.Copy()
require.NoError(t, err)
nextSlotState, err := transition.ProcessSlots(context.Background(), copied, beaconState.Slot()+1)
require.NoError(t, err) require.NoError(t, err)
parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot() parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)
@@ -98,7 +100,8 @@ func TestExecuteBellatrixStateTransitionNoVerify_FullProcess(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
block.Block.StateRoot = stateRoot[:] block.Block.StateRoot = stateRoot[:]
c := beaconState.Copy() c, err := beaconState.Copy()
require.NoError(t, err)
sig, err := util.BlockSignature(c, block.Block, privKeys) sig, err := util.BlockSignature(c, block.Block, privKeys)
require.NoError(t, err) require.NoError(t, err)
block.Signature = sig.Marshal() block.Signature = sig.Marshal()
@@ -139,7 +142,9 @@ func TestExecuteBellatrixStateTransitionNoVerifySignature_CouldNotVerifyStateRoo
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1)) require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
nextSlotState, err := transition.ProcessSlots(context.Background(), beaconState.Copy(), beaconState.Slot()+1) copied, err := beaconState.Copy()
require.NoError(t, err)
nextSlotState, err := transition.ProcessSlots(context.Background(), copied, beaconState.Slot()+1)
require.NoError(t, err) require.NoError(t, err)
parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot() parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)
@@ -186,7 +191,8 @@ func TestExecuteBellatrixStateTransitionNoVerifySignature_CouldNotVerifyStateRoo
require.NoError(t, err) require.NoError(t, err)
block.Block.StateRoot = stateRoot[:] block.Block.StateRoot = stateRoot[:]
c := beaconState.Copy() c, err := beaconState.Copy()
require.NoError(t, err)
sig, err := util.BlockSignature(c, block.Block, privKeys) sig, err := util.BlockSignature(c, block.Block, privKeys)
require.NoError(t, err) require.NoError(t, err)
block.Signature = sig.Marshal() block.Signature = sig.Marshal()

View File

@@ -25,7 +25,8 @@ func BenchmarkExecuteStateTransition_FullBlock(b *testing.B) {
defer undo() defer undo()
beaconState, err := benchmark.PreGenState1Epoch() beaconState, err := benchmark.PreGenState1Epoch()
require.NoError(b, err) require.NoError(b, err)
cleanStates := clonedStates(beaconState) cleanStates, err := clonedStates(beaconState)
require.NoError(b, err)
block, err := benchmark.PreGenFullBlock() block, err := benchmark.PreGenFullBlock()
require.NoError(b, err) require.NoError(b, err)
@@ -45,7 +46,8 @@ func BenchmarkExecuteStateTransition_WithCache(b *testing.B) {
beaconState, err := benchmark.PreGenState1Epoch() beaconState, err := benchmark.PreGenState1Epoch()
require.NoError(b, err) require.NoError(b, err)
cleanStates := clonedStates(beaconState) cleanStates, err := clonedStates(beaconState)
require.NoError(b, err)
block, err := benchmark.PreGenFullBlock() block, err := benchmark.PreGenFullBlock()
require.NoError(b, err) require.NoError(b, err)
@@ -88,7 +90,9 @@ func BenchmarkProcessEpoch_2FullEpochs(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
// ProcessEpochPrecompute is the optimized version of process epoch. It's enabled by default // ProcessEpochPrecompute is the optimized version of process epoch. It's enabled by default
// at run time. // at run time.
_, err := coreState.ProcessEpochPrecompute(context.Background(), beaconState.Copy()) copied, err := beaconState.Copy()
require.NoError(b, err)
_, err = coreState.ProcessEpochPrecompute(context.Background(), copied)
require.NoError(b, err) require.NoError(b, err)
} }
} }
@@ -124,7 +128,9 @@ func BenchmarkHashTreeRootState_FullState(b *testing.B) {
func BenchmarkMarshalState_FullState(b *testing.B) { func BenchmarkMarshalState_FullState(b *testing.B) {
beaconState, err := benchmark.PreGenstateFullEpochs() beaconState, err := benchmark.PreGenstateFullEpochs()
require.NoError(b, err) require.NoError(b, err)
natState, err := state_native.ProtobufBeaconStatePhase0(beaconState.ToProtoUnsafe()) pb, err := beaconState.ToProtoUnsafe()
require.NoError(b, err)
natState, err := state_native.ProtobufBeaconStatePhase0(pb)
require.NoError(b, err) require.NoError(b, err)
b.Run("Proto_Marshal", func(b *testing.B) { b.Run("Proto_Marshal", func(b *testing.B) {
b.ResetTimer() b.ResetTimer()
@@ -148,7 +154,9 @@ func BenchmarkMarshalState_FullState(b *testing.B) {
func BenchmarkUnmarshalState_FullState(b *testing.B) { func BenchmarkUnmarshalState_FullState(b *testing.B) {
beaconState, err := benchmark.PreGenstateFullEpochs() beaconState, err := benchmark.PreGenstateFullEpochs()
require.NoError(b, err) require.NoError(b, err)
natState, err := state_native.ProtobufBeaconStatePhase0(beaconState.ToProtoUnsafe()) pb, err := beaconState.ToProtoUnsafe()
require.NoError(b, err)
natState, err := state_native.ProtobufBeaconStatePhase0(pb)
require.NoError(b, err) require.NoError(b, err)
protoObject, err := proto.Marshal(natState) protoObject, err := proto.Marshal(natState)
require.NoError(b, err) require.NoError(b, err)
@@ -173,10 +181,14 @@ func BenchmarkUnmarshalState_FullState(b *testing.B) {
}) })
} }
func clonedStates(beaconState state.BeaconState) []state.BeaconState { func clonedStates(beaconState state.BeaconState) ([]state.BeaconState, error) {
clonedStates := make([]state.BeaconState, runAmount) clonedStates := make([]state.BeaconState, runAmount)
var err error
for i := 0; i < runAmount; i++ { for i := 0; i < runAmount; i++ {
clonedStates[i] = beaconState.Copy() clonedStates[i], err = beaconState.Copy()
if err != nil {
return nil, err
}
} }
return clonedStates return clonedStates, nil
} }

View File

@@ -20,7 +20,9 @@ func TestSkipSlotCache_OK(t *testing.T) {
transition.SkipSlotCache.Enable() transition.SkipSlotCache.Enable()
defer transition.SkipSlotCache.Disable() defer transition.SkipSlotCache.Disable()
bState, privs := util.DeterministicGenesisState(t, params.MinimalSpecConfig().MinGenesisActiveValidatorCount) bState, privs := util.DeterministicGenesisState(t, params.MinimalSpecConfig().MinGenesisActiveValidatorCount)
pbState, err := state_native.ProtobufBeaconStatePhase0(bState.ToProto()) bStateProto, err := bState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStatePhase0(bStateProto)
require.NoError(t, err) require.NoError(t, err)
originalState, err := state_native.InitializeFromProtoPhase0(pbState) originalState, err := state_native.InitializeFromProtoPhase0(pbState)
require.NoError(t, err) require.NoError(t, err)
@@ -42,12 +44,18 @@ func TestSkipSlotCache_OK(t *testing.T) {
bState, err = transition.ExecuteStateTransition(context.Background(), bState, wsb) bState, err = transition.ExecuteStateTransition(context.Background(), bState, wsb)
require.NoError(t, err, "Could not process state transition") require.NoError(t, err, "Could not process state transition")
assert.DeepEqual(t, originalState.ToProto(), bState.ToProto(), "Skipped slots cache leads to different states") originalStateProto, err := originalState.ToProto()
require.NoError(t, err)
bStateProto, err = bState.ToProto()
require.NoError(t, err)
assert.DeepEqual(t, originalStateProto, bStateProto, "Skipped slots cache leads to different states")
} }
func TestSkipSlotCache_ConcurrentMixup(t *testing.T) { func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
bState, privs := util.DeterministicGenesisState(t, params.MinimalSpecConfig().MinGenesisActiveValidatorCount) bState, privs := util.DeterministicGenesisState(t, params.MinimalSpecConfig().MinGenesisActiveValidatorCount)
pbState, err := state_native.ProtobufBeaconStatePhase0(bState.ToProto()) bStateProto, err := bState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStatePhase0(bStateProto)
require.NoError(t, err) require.NoError(t, err)
originalState, err := state_native.InitializeFromProtoPhase0(pbState) originalState, err := state_native.InitializeFromProtoPhase0(pbState)
require.NoError(t, err) require.NoError(t, err)
@@ -70,7 +78,9 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
// Create two shallow but different forks // Create two shallow but different forks
var s1, s0 state.BeaconState var s1, s0 state.BeaconState
{ {
blk, err := util.GenerateFullBlock(originalState.Copy(), privs, blkCfg, originalState.Slot()+10) c0, err := originalState.Copy()
require.NoError(t, err)
blk, err := util.GenerateFullBlock(c0, privs, blkCfg, originalState.Slot()+10)
require.NoError(t, err) require.NoError(t, err)
copy(blk.Block.Body.Graffiti, "block 1") copy(blk.Block.Body.Graffiti, "block 1")
signature, err := util.BlockSignature(originalState, blk.Block, privs) signature, err := util.BlockSignature(originalState, blk.Block, privs)
@@ -78,12 +88,14 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
blk.Signature = signature.Marshal() blk.Signature = signature.Marshal()
wsb, err := blocks.NewSignedBeaconBlock(blk) wsb, err := blocks.NewSignedBeaconBlock(blk)
require.NoError(t, err) require.NoError(t, err)
s1, err = transition.ExecuteStateTransition(context.Background(), originalState.Copy(), wsb) s1, err = transition.ExecuteStateTransition(context.Background(), c0, wsb)
require.NoError(t, err, "Could not run state transition") require.NoError(t, err, "Could not run state transition")
} }
{ {
blk, err := util.GenerateFullBlock(originalState.Copy(), privs, blkCfg, originalState.Slot()+10) c1, err := originalState.Copy()
require.NoError(t, err)
blk, err := util.GenerateFullBlock(c1, privs, blkCfg, originalState.Slot()+10)
require.NoError(t, err) require.NoError(t, err)
copy(blk.Block.Body.Graffiti, "block 2") copy(blk.Block.Body.Graffiti, "block 2")
signature, err := util.BlockSignature(originalState, blk.Block, privs) signature, err := util.BlockSignature(originalState, blk.Block, privs)
@@ -91,7 +103,7 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
blk.Signature = signature.Marshal() blk.Signature = signature.Marshal()
wsb, err := blocks.NewSignedBeaconBlock(blk) wsb, err := blocks.NewSignedBeaconBlock(blk)
require.NoError(t, err) require.NoError(t, err)
s0, err = transition.ExecuteStateTransition(context.Background(), originalState.Copy(), wsb) s0, err = transition.ExecuteStateTransition(context.Background(), c1, wsb)
require.NoError(t, err, "Could not run state transition") require.NoError(t, err, "Could not run state transition")
} }
@@ -116,28 +128,38 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
} else { } else {
st = s0 st = s0
} }
setups = append(setups, st.Copy()) c, err := st.Copy()
require.NoError(t, err)
setups = append(setups, c)
} }
problemSlot := s1.Slot() + 2 problemSlot := s1.Slot() + 2
expected1, err := transition.ProcessSlots(context.Background(), s1.Copy(), problemSlot) s1Copied, err := s1.Copy()
require.NoError(t, err)
expected1, err := transition.ProcessSlots(context.Background(), s1Copied, problemSlot)
require.NoError(t, err) require.NoError(t, err)
expectedRoot1, err := expected1.HashTreeRoot(context.Background()) expectedRoot1, err := expected1.HashTreeRoot(context.Background())
require.NoError(t, err) require.NoError(t, err)
t.Logf("chain 1 (even i) expected root %x at slot %d", expectedRoot1[:], problemSlot) t.Logf("chain 1 (even i) expected root %x at slot %d", expectedRoot1[:], problemSlot)
tmp1, err := transition.ProcessSlots(context.Background(), expected1.Copy(), problemSlot+1) expectedS1Copied, err := expected1.Copy()
require.NoError(t, err)
tmp1, err := transition.ProcessSlots(context.Background(), expectedS1Copied, problemSlot+1)
require.NoError(t, err) require.NoError(t, err)
gotRoot := tmp1.StateRoots()[problemSlot] gotRoot := tmp1.StateRoots()[problemSlot]
require.DeepEqual(t, expectedRoot1[:], gotRoot, "State roots for chain 1 are bad, expected root doesn't match") require.DeepEqual(t, expectedRoot1[:], gotRoot, "State roots for chain 1 are bad, expected root doesn't match")
expected2, err := transition.ProcessSlots(context.Background(), s0.Copy(), problemSlot) s0Copied, err := s0.Copy()
require.NoError(t, err)
expected2, err := transition.ProcessSlots(context.Background(), s0Copied, problemSlot)
require.NoError(t, err) require.NoError(t, err)
expectedRoot2, err := expected2.HashTreeRoot(context.Background()) expectedRoot2, err := expected2.HashTreeRoot(context.Background())
require.NoError(t, err) require.NoError(t, err)
t.Logf("chain 2 (odd i) expected root %x at slot %d", expectedRoot2[:], problemSlot) t.Logf("chain 2 (odd i) expected root %x at slot %d", expectedRoot2[:], problemSlot)
tmp2, err := transition.ProcessSlots(context.Background(), expected2.Copy(), problemSlot+1) expectedS2Copied, err := expected2.Copy()
require.NoError(t, err)
tmp2, err := transition.ProcessSlots(context.Background(), expectedS2Copied, problemSlot+1)
require.NoError(t, err) require.NoError(t, err)
gotRoot = tmp2.StateRoots()[problemSlot] gotRoot = tmp2.StateRoots()[problemSlot]
require.DeepEqual(t, expectedRoot2[:], gotRoot, "State roots for chain 2 are bad, expected root doesn't match") require.DeepEqual(t, expectedRoot2[:], gotRoot, "State roots for chain 2 are bad, expected root doesn't match")

View File

@@ -98,9 +98,13 @@ func TestGenesisState_HashEquality(t *testing.T) {
state, err := transition.GenesisBeaconState(context.Background(), deposits, 0, &ethpb.Eth1Data{BlockHash: make([]byte, 32)}) state, err := transition.GenesisBeaconState(context.Background(), deposits, 0, &ethpb.Eth1Data{BlockHash: make([]byte, 32)})
require.NoError(t, err) require.NoError(t, err)
pbState1, err := state_native.ProtobufBeaconStatePhase0(state1.ToProto()) state1Proto, err := state1.ToProto()
require.NoError(t, err) require.NoError(t, err)
pbstate, err := state_native.ProtobufBeaconStatePhase0(state.ToProto()) stateProto, err := state.ToProto()
require.NoError(t, err)
pbState1, err := state_native.ProtobufBeaconStatePhase0(state1Proto)
require.NoError(t, err)
pbstate, err := state_native.ProtobufBeaconStatePhase0(stateProto)
require.NoError(t, err) require.NoError(t, err)
root1, err1 := hash.HashProto(pbState1) root1, err1 := hash.HashProto(pbState1)

View File

@@ -41,7 +41,7 @@ func NextSlotState(_ context.Context, root []byte) (state.BeaconState, error) {
} }
nextSlotCacheHit.Inc() nextSlotCacheHit.Inc()
// Returning copied state. // Returning copied state.
return nsc.state.Copy(), nil return nsc.state.Copy()
} }
// UpdateNextSlotCache updates the `nextSlotCache`. It saves the input state after advancing the state slot by 1 // UpdateNextSlotCache updates the `nextSlotCache`. It saves the input state after advancing the state slot by 1
@@ -49,8 +49,12 @@ func NextSlotState(_ context.Context, root []byte) (state.BeaconState, error) {
// This is useful to call after successfully processing a block. // This is useful to call after successfully processing a block.
func UpdateNextSlotCache(ctx context.Context, root []byte, state state.BeaconState) error { func UpdateNextSlotCache(ctx context.Context, root []byte, state state.BeaconState) error {
// Advancing one slot by using a copied state. // Advancing one slot by using a copied state.
copied := state.Copy() copied, err := state.Copy()
copied, err := ProcessSlots(ctx, copied, copied.Slot()+1) if err != nil {
return err
}
copied, err = ProcessSlots(ctx, copied, copied.Slot()+1)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -239,7 +239,7 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
tracing.AnnotateError(span, ctx.Err()) tracing.AnnotateError(span, ctx.Err())
// Cache last best value. // Cache last best value.
if highestSlot < state.Slot() { if highestSlot < state.Slot() {
if SkipSlotCache.Put(ctx, key, state); err != nil { if err := SkipSlotCache.Put(ctx, key, state); err != nil {
log.WithError(err).Error("Failed to put skip slot cache value") log.WithError(err).Error("Failed to put skip slot cache value")
} }
} }
@@ -299,7 +299,10 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
} }
if highestSlot < state.Slot() { if highestSlot < state.Slot() {
SkipSlotCache.Put(ctx, key, state) err := SkipSlotCache.Put(ctx, key, state)
if err != nil {
return nil, err
}
} }
return state, nil return state, nil

View File

@@ -127,10 +127,12 @@ func CalculateStateRoot(
} }
// Copy state to avoid mutating the state reference. // Copy state to avoid mutating the state reference.
state = state.Copy() state, err := state.Copy()
if err != nil {
return [32]byte{}, err
}
// Execute per slots transition. // Execute per slots transition.
var err error
parentRoot := signed.Block().ParentRoot() parentRoot := signed.Block().ParentRoot()
state, err = ProcessSlotsUsingNextSlotCache(ctx, state, parentRoot[:], signed.Block().Slot()) state, err = ProcessSlotsUsingNextSlotCache(ctx, state, parentRoot[:], signed.Block().Slot())
if err != nil { if err != nil {

View File

@@ -39,7 +39,9 @@ func TestExecuteStateTransitionNoVerify_FullProcess(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1)) require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
nextSlotState, err := transition.ProcessSlots(context.Background(), beaconState.Copy(), beaconState.Slot()+1) copied, err := beaconState.Copy()
require.NoError(t, err)
nextSlotState, err := transition.ProcessSlots(context.Background(), copied, beaconState.Slot()+1)
require.NoError(t, err) require.NoError(t, err)
parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot() parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)
@@ -95,7 +97,9 @@ func TestExecuteStateTransitionNoVerifySignature_CouldNotVerifyStateRoot(t *test
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1)) require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
nextSlotState, err := transition.ProcessSlots(context.Background(), beaconState.Copy(), beaconState.Slot()+1) copied, err := beaconState.Copy()
require.NoError(t, err)
nextSlotState, err := transition.ProcessSlots(context.Background(), copied, beaconState.Slot()+1)
require.NoError(t, err) require.NoError(t, err)
parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot() parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)

View File

@@ -76,7 +76,9 @@ func TestExecuteStateTransition_FullProcess(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1)) require.NoError(t, beaconState.SetSlot(beaconState.Slot()-1))
nextSlotState, err := transition.ProcessSlots(context.Background(), beaconState.Copy(), beaconState.Slot()+1) copied, err := beaconState.Copy()
require.NoError(t, err)
nextSlotState, err := transition.ProcessSlots(context.Background(), copied, beaconState.Slot()+1)
require.NoError(t, err) require.NoError(t, err)
parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot() parentRoot, err := nextSlotState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)
@@ -339,7 +341,8 @@ func createFullBlockWithOperations(t *testing.T) (state.BeaconState,
require.NoError(t, beaconState.SetLatestBlockHeader(header)) require.NoError(t, beaconState.SetLatestBlockHeader(header))
parentRoot, err := beaconState.LatestBlockHeader().HashTreeRoot() parentRoot, err := beaconState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(beaconState.Slot()+1)) require.NoError(t, copied.SetSlot(beaconState.Slot()+1))
randaoReveal, err := util.RandaoReveal(copied, currentEpoch, privKeys) randaoReveal, err := util.RandaoReveal(copied, currentEpoch, privKeys)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -92,7 +92,9 @@ func Test_migrateStateValidators(t *testing.T) {
assert.NoError(t, hashErr) assert.NoError(t, hashErr)
individualHashes = append(individualHashes, hash[:]) individualHashes = append(individualHashes, hash[:])
} }
pbState, err := state_native.ProtobufBeaconStatePhase0(st.ToProtoUnsafe()) s, err := st.ToProtoUnsafe()
assert.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStatePhase0(s)
assert.NoError(t, err) assert.NoError(t, err)
validatorsFoundCount := 0 validatorsFoundCount := 0
for _, val := range pbState.Validators { for _, val := range pbState.Validators {
@@ -138,7 +140,11 @@ func Test_migrateStateValidators(t *testing.T) {
blockRoot := [32]byte{'A'} blockRoot := [32]byte{'A'}
rcvdState, err := dbStore.State(context.Background(), blockRoot) rcvdState, err := dbStore.State(context.Background(), blockRoot)
assert.NoError(t, err) assert.NoError(t, err)
require.DeepSSZEqual(t, rcvdState.ToProtoUnsafe(), state.ToProtoUnsafe(), "saved state with validators and retrieved state are not matching") s1, err := rcvdState.ToProtoUnsafe()
assert.NoError(t, err)
s2, err := state.ToProtoUnsafe()
assert.NoError(t, err)
require.DeepSSZEqual(t, s1, s2, "saved state with validators and retrieved state are not matching")
// find hashes of the validators that are set as part of the state // find hashes of the validators that are set as part of the state
var hashes []byte var hashes []byte
@@ -151,7 +157,9 @@ func Test_migrateStateValidators(t *testing.T) {
} }
// check if all the validators that were in the state, are stored properly in the validator bucket // check if all the validators that were in the state, are stored properly in the validator bucket
pbState, err := state_native.ProtobufBeaconStatePhase0(rcvdState.ToProtoUnsafe()) s3, err := rcvdState.ToProtoUnsafe()
assert.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStatePhase0(s3)
assert.NoError(t, err) assert.NoError(t, err)
validatorsFoundCount := 0 validatorsFoundCount := 0
for _, val := range pbState.Validators { for _, val := range pbState.Validators {
@@ -241,7 +249,11 @@ func Test_migrateAltairStateValidators(t *testing.T) {
blockRoot := [32]byte{'A'} blockRoot := [32]byte{'A'}
rcvdState, err := dbStore.State(context.Background(), blockRoot) rcvdState, err := dbStore.State(context.Background(), blockRoot)
assert.NoError(t, err) assert.NoError(t, err)
require.DeepSSZEqual(t, rcvdState.ToProtoUnsafe(), state.ToProtoUnsafe(), "saved state with validators and retrieved state are not matching") s1, err := rcvdState.ToProtoUnsafe()
assert.NoError(t, err)
s2, err := state.ToProtoUnsafe()
assert.NoError(t, err)
require.DeepSSZEqual(t, s1, s2, "saved state with validators and retrieved state are not matching")
// find hashes of the validators that are set as part of the state // find hashes of the validators that are set as part of the state
var hashes []byte var hashes []byte
@@ -254,7 +266,9 @@ func Test_migrateAltairStateValidators(t *testing.T) {
} }
// check if all the validators that were in the state, are stored properly in the validator bucket // check if all the validators that were in the state, are stored properly in the validator bucket
pbState, err := state_native.ProtobufBeaconStateAltair(rcvdState.ToProtoUnsafe()) s3, err := rcvdState.ToProtoUnsafe()
assert.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateAltair(s3)
assert.NoError(t, err) assert.NoError(t, err)
validatorsFoundCount := 0 validatorsFoundCount := 0
for _, val := range pbState.Validators { for _, val := range pbState.Validators {

View File

@@ -189,7 +189,11 @@ func getValidators(states []state.ReadOnlyBeaconState) ([][]byte, map[string]*et
validatorsEntries := make(map[string]*ethpb.Validator) // It's a map to make sure that you store only new validator entries. validatorsEntries := make(map[string]*ethpb.Validator) // It's a map to make sure that you store only new validator entries.
validatorKeys := make([][]byte, len(states)) // For every state, this stores a compressed list of validator keys. validatorKeys := make([][]byte, len(states)) // For every state, this stores a compressed list of validator keys.
for i, st := range states { for i, st := range states {
pb, ok := st.ToProtoUnsafe().(withValidators) p, err := st.ToProtoUnsafe()
if err != nil {
return nil, nil, err
}
pb, ok := p.(withValidators)
if !ok { if !ok {
return nil, nil, errors.New("could not cast state to interface with GetValidators()") return nil, nil, errors.New("could not cast state to interface with GetValidators()")
} }
@@ -228,7 +232,11 @@ func (s *Store) saveStatesEfficientInternal(ctx context.Context, tx *bolt.Tx, bl
// validator entries.To bring the gap closer, we empty the validators // validator entries.To bring the gap closer, we empty the validators
// just before Put() and repopulate that state with original validators. // just before Put() and repopulate that state with original validators.
// look at issue https://github.com/prysmaticlabs/prysm/issues/9262. // look at issue https://github.com/prysmaticlabs/prysm/issues/9262.
switch rawType := states[i].ToProtoUnsafe().(type) { p, err := states[i].ToProtoUnsafe()
if err != nil {
return err
}
switch rawType := p.(type) {
case *ethpb.BeaconState: case *ethpb.BeaconState:
pbState, err := statenative.ProtobufBeaconStatePhase0(rawType) pbState, err := statenative.ProtobufBeaconStatePhase0(rawType)
if err != nil { if err != nil {
@@ -534,15 +542,19 @@ func (s *Store) unmarshalState(_ context.Context, enc []byte, validatorEntries [
// marshal versioned state from struct type down to bytes. // marshal versioned state from struct type down to bytes.
func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, error) { func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, error) {
switch st.ToProtoUnsafe().(type) { p, err := st.ToProtoUnsafe()
if err != nil {
return nil, err
}
switch p.(type) {
case *ethpb.BeaconState: case *ethpb.BeaconState:
rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconState) rState, ok := p.(*ethpb.BeaconState)
if !ok { if !ok {
return nil, errors.New("non valid inner state") return nil, errors.New("non valid inner state")
} }
return encode(ctx, rState) return encode(ctx, rState)
case *ethpb.BeaconStateAltair: case *ethpb.BeaconStateAltair:
rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateAltair) rState, ok := p.(*ethpb.BeaconStateAltair)
if !ok { if !ok {
return nil, errors.New("non valid inner state") return nil, errors.New("non valid inner state")
} }
@@ -555,7 +567,7 @@ func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, er
} }
return snappy.Encode(nil, append(altairKey, rawObj...)), nil return snappy.Encode(nil, append(altairKey, rawObj...)), nil
case *ethpb.BeaconStateBellatrix: case *ethpb.BeaconStateBellatrix:
rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateBellatrix) rState, ok := p.(*ethpb.BeaconStateBellatrix)
if !ok { if !ok {
return nil, errors.New("non valid inner state") return nil, errors.New("non valid inner state")
} }
@@ -568,7 +580,7 @@ func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, er
} }
return snappy.Encode(nil, append(bellatrixKey, rawObj...)), nil return snappy.Encode(nil, append(bellatrixKey, rawObj...)), nil
case *ethpb.BeaconStateCapella: case *ethpb.BeaconStateCapella:
rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateCapella) rState, ok := p.(*ethpb.BeaconStateCapella)
if !ok { if !ok {
return nil, errors.New("non valid inner state") return nil, errors.New("non valid inner state")
} }

View File

@@ -44,7 +44,11 @@ func TestState_CanSaveRetrieve(t *testing.T) {
savedS, err := db.State(context.Background(), r) savedS, err := db.State(context.Background(), r)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, st.ToProtoUnsafe(), savedS.ToProtoUnsafe(), "saved state and retrieved state are not matching") s1, err := st.ToProtoUnsafe()
require.NoError(t, err)
s2, err := savedS.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2, "saved state and retrieved state are not matching")
savedS, err = db.State(context.Background(), [32]byte{'B'}) savedS, err = db.State(context.Background(), [32]byte{'B'})
require.NoError(t, err) require.NoError(t, err)
@@ -77,7 +81,11 @@ func TestState_CanSaveRetrieveValidatorEntries(t *testing.T) {
savedS, err := db.State(context.Background(), r) savedS, err := db.State(context.Background(), r)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, st.ToProtoUnsafe(), savedS.ToProtoUnsafe(), "saved state with validators and retrieved state are not matching") s1, err := st.ToProtoUnsafe()
require.NoError(t, err)
s2, err := savedS.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2, "saved state with validators and retrieved state are not matching")
// check if the index of the second state is still present. // check if the index of the second state is still present.
err = db.db.Update(func(tx *bolt.Tx) error { err = db.db.Update(func(tx *bolt.Tx) error {
@@ -129,7 +137,11 @@ func TestStateAltair_CanSaveRetrieveValidatorEntries(t *testing.T) {
savedS, err := db.State(context.Background(), r) savedS, err := db.State(context.Background(), r)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, st.ToProtoUnsafe(), savedS.ToProtoUnsafe(), "saved state with validators and retrieved state are not matching") s1, err := st.ToProtoUnsafe()
require.NoError(t, err)
s2, err := savedS.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2, "saved state with validators and retrieved state are not matching")
// check if the index of the second state is still present. // check if the index of the second state is still present.
err = db.db.Update(func(tx *bolt.Tx) error { err = db.db.Update(func(tx *bolt.Tx) error {
@@ -239,7 +251,11 @@ func TestState_CanSaveRetrieveValidatorEntriesWithoutCache(t *testing.T) {
savedS, err := db.State(context.Background(), r) savedS, err := db.State(context.Background(), r)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, st.ToProtoUnsafe(), savedS.ToProtoUnsafe(), "saved state with validators and retrieved state are not matching") s1, err := st.ToProtoUnsafe()
require.NoError(t, err)
s2, err := savedS.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2, "saved state with validators and retrieved state are not matching")
// check if the index of the second state is still present. // check if the index of the second state is still present.
err = db.db.Update(func(tx *bolt.Tx) error { err = db.db.Update(func(tx *bolt.Tx) error {
@@ -360,7 +376,11 @@ func TestGenesisState_CanSaveRetrieve(t *testing.T) {
savedGenesisS, err := db.GenesisState(context.Background()) savedGenesisS, err := db.GenesisState(context.Background())
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, st.ToProtoUnsafe(), savedGenesisS.ToProtoUnsafe(), "Did not retrieve saved state") s1, err := st.ToProtoUnsafe()
require.NoError(t, err)
s2, err := savedGenesisS.ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, s1, s2, "Did not retrieve saved state")
require.NoError(t, db.SaveGenesisBlockRoot(context.Background(), [32]byte{'C'})) require.NoError(t, db.SaveGenesisBlockRoot(context.Background(), [32]byte{'C'}))
} }
@@ -481,7 +501,8 @@ func TestStore_SaveDeleteState_CanGetHighestBelow(t *testing.T) {
st, err := util.NewBeaconState() st, err := util.NewBeaconState()
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, st.SetSlot(1)) require.NoError(t, st.SetSlot(1))
s0 := st.ToProtoUnsafe() s0, err := st.ToProtoUnsafe()
require.NoError(t, err)
require.NoError(t, db.SaveState(context.Background(), st, r)) require.NoError(t, db.SaveState(context.Background(), st, r))
b.Block.Slot = 100 b.Block.Slot = 100
@@ -493,7 +514,8 @@ func TestStore_SaveDeleteState_CanGetHighestBelow(t *testing.T) {
st, err = util.NewBeaconState() st, err = util.NewBeaconState()
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, st.SetSlot(100)) require.NoError(t, st.SetSlot(100))
s1 := st.ToProtoUnsafe() s1, err := st.ToProtoUnsafe()
require.NoError(t, err)
require.NoError(t, db.SaveState(context.Background(), st, r1)) require.NoError(t, db.SaveState(context.Background(), st, r1))
b.Block.Slot = 1000 b.Block.Slot = 1000
@@ -505,21 +527,27 @@ func TestStore_SaveDeleteState_CanGetHighestBelow(t *testing.T) {
st, err = util.NewBeaconState() st, err = util.NewBeaconState()
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, st.SetSlot(1000)) require.NoError(t, st.SetSlot(1000))
s2 := st.ToProtoUnsafe() s2, err := st.ToProtoUnsafe()
require.NoError(t, err)
require.NoError(t, db.SaveState(context.Background(), st, r2)) require.NoError(t, db.SaveState(context.Background(), st, r2))
highest, err := db.HighestSlotStatesBelow(context.Background(), 2) highest, err := db.HighestSlotStatesBelow(context.Background(), 2)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, highest[0].ToProtoUnsafe(), s0) want, err := highest[0].ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, want, s0)
highest, err = db.HighestSlotStatesBelow(context.Background(), 101) highest, err = db.HighestSlotStatesBelow(context.Background(), 101)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, highest[0].ToProtoUnsafe(), s1) want, err = highest[0].ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, want, s1)
highest, err = db.HighestSlotStatesBelow(context.Background(), 1001) highest, err = db.HighestSlotStatesBelow(context.Background(), 1001)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, highest[0].ToProtoUnsafe(), s2) want, err = highest[0].ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, want, s2)
} }
func TestStore_GenesisState_CanGetHighestBelow(t *testing.T) { func TestStore_GenesisState_CanGetHighestBelow(t *testing.T) {
@@ -546,14 +574,24 @@ func TestStore_GenesisState_CanGetHighestBelow(t *testing.T) {
highest, err := db.HighestSlotStatesBelow(context.Background(), 2) highest, err := db.HighestSlotStatesBelow(context.Background(), 2)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, highest[0].ToProtoUnsafe(), st.ToProtoUnsafe()) want, err := highest[0].ToProtoUnsafe()
require.NoError(t, err)
gotSt, err := st.ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, want, gotSt)
highest, err = db.HighestSlotStatesBelow(context.Background(), 1) highest, err = db.HighestSlotStatesBelow(context.Background(), 1)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, highest[0].ToProtoUnsafe(), genesisState.ToProtoUnsafe()) gs, err := genesisState.ToProtoUnsafe()
require.NoError(t, err)
want, err = highest[0].ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, want, gs)
highest, err = db.HighestSlotStatesBelow(context.Background(), 0) highest, err = db.HighestSlotStatesBelow(context.Background(), 0)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, highest[0].ToProtoUnsafe(), genesisState.ToProtoUnsafe()) want, err = highest[0].ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, want, gs)
} }
func TestStore_CleanUpDirtyStates_AboveThreshold(t *testing.T) { func TestStore_CleanUpDirtyStates_AboveThreshold(t *testing.T) {
@@ -680,7 +718,11 @@ func TestAltairState_CanSaveRetrieve(t *testing.T) {
savedS, err := db.State(context.Background(), r) savedS, err := db.State(context.Background(), r)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, st.ToProtoUnsafe(), savedS.ToProtoUnsafe()) s0, err := st.ToProtoUnsafe()
require.NoError(t, err)
s1, err := savedS.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s0, s1)
savedS, err = db.State(context.Background(), [32]byte{'B'}) savedS, err = db.State(context.Background(), [32]byte{'B'})
require.NoError(t, err) require.NoError(t, err)
@@ -830,8 +872,11 @@ func TestStateBellatrix_CanSaveRetrieveValidatorEntries(t *testing.T) {
savedS, err := db.State(context.Background(), r) savedS, err := db.State(context.Background(), r)
require.NoError(t, err) require.NoError(t, err)
s0, err := st.ToProtoUnsafe()
require.DeepSSZEqual(t, st.ToProtoUnsafe(), savedS.ToProtoUnsafe(), "saved state with validators and retrieved state are not matching") require.NoError(t, err)
s1, err := savedS.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s0, s1, "saved state with validators and retrieved state are not matching")
// check if the index of the second state is still present. // check if the index of the second state is still present.
err = db.db.Update(func(tx *bolt.Tx) error { err = db.db.Update(func(tx *bolt.Tx) error {
@@ -873,8 +918,11 @@ func TestBellatrixState_CanSaveRetrieve(t *testing.T) {
savedS, err := db.State(context.Background(), r) savedS, err := db.State(context.Background(), r)
require.NoError(t, err) require.NoError(t, err)
s0, err := st.ToProtoUnsafe()
require.DeepSSZEqual(t, st.ToProtoUnsafe(), savedS.ToProtoUnsafe()) require.NoError(t, err)
s1, err := savedS.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s0, s1)
savedS, err = db.State(context.Background(), [32]byte{'B'}) savedS, err = db.State(context.Background(), [32]byte{'B'})
require.NoError(t, err) require.NoError(t, err)

View File

@@ -551,7 +551,11 @@ func (s *Service) processChainStartIfReady(ctx context.Context, blockHash [32]by
// savePowchainData saves all powchain related metadata to disk. // savePowchainData saves all powchain related metadata to disk.
func (s *Service) savePowchainData(ctx context.Context) error { func (s *Service) savePowchainData(ctx context.Context) error {
pbState, err := statenative.ProtobufBeaconStatePhase0(s.preGenesisState.ToProtoUnsafe()) st, err := s.preGenesisState.ToProtoUnsafe()
if err != nil {
return err
}
pbState, err := statenative.ProtobufBeaconStatePhase0(st)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -777,7 +777,11 @@ func (s *Service) ensureValidPowchainData(ctx context.Context) error {
return errors.Wrap(err, "unable to retrieve eth1 data") return errors.Wrap(err, "unable to retrieve eth1 data")
} }
if eth1Data == nil || !eth1Data.ChainstartData.Chainstarted || !validateDepositContainers(eth1Data.DepositContainers) { if eth1Data == nil || !eth1Data.ChainstartData.Chainstarted || !validateDepositContainers(eth1Data.DepositContainers) {
pbState, err := native.ProtobufBeaconStatePhase0(s.preGenesisState.ToProtoUnsafe()) st, err := s.preGenesisState.ToProtoUnsafe()
if err != nil {
return err
}
pbState, err := native.ProtobufBeaconStatePhase0(st)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -115,7 +115,9 @@ func TestSszNetworkEncoder_DecodeWithMultipleFrames(t *testing.T) {
maxChunkSize := uint64(1 << 22) maxChunkSize := uint64(1 << 22)
encoder.MaxChunkSize = maxChunkSize encoder.MaxChunkSize = maxChunkSize
params.OverrideBeaconNetworkConfig(c) params.OverrideBeaconNetworkConfig(c)
_, err := e.EncodeWithMaxLength(buf, st.ToProtoUnsafe().(*ethpb.BeaconState)) pb, err := st.ToProtoUnsafe()
require.NoError(t, err)
_, err = e.EncodeWithMaxLength(buf, pb.(*ethpb.BeaconState))
require.NoError(t, err) require.NoError(t, err)
// Max snappy block size // Max snappy block size
if buf.Len() <= 76490 { if buf.Len() <= 76490 {

View File

@@ -492,8 +492,9 @@ func TestSubmitAttesterSlashing_AcrossFork(t *testing.T) {
}, },
} }
newBs := bs.Copy() newBs, err := bs.Copy()
newBs, err := transition.ProcessSlots(ctx, newBs, params.BeaconConfig().SlotsPerEpoch) require.NoError(t, err)
newBs, err = transition.ProcessSlots(ctx, newBs, params.BeaconConfig().SlotsPerEpoch)
require.NoError(t, err) require.NoError(t, err)
for _, att := range []*ethpbv1.IndexedAttestation{slashing.Attestation_1, slashing.Attestation_2} { for _, att := range []*ethpbv1.IndexedAttestation{slashing.Attestation_1, slashing.Attestation_2} {
@@ -659,8 +660,9 @@ func TestSubmitProposerSlashing_AcrossFork(t *testing.T) {
}, },
} }
newBs := bs.Copy() newBs, err := bs.Copy()
newBs, err := transition.ProcessSlots(ctx, newBs, params.BeaconConfig().SlotsPerEpoch) require.NoError(t, err)
newBs, err = transition.ProcessSlots(ctx, newBs, params.BeaconConfig().SlotsPerEpoch)
require.NoError(t, err) require.NoError(t, err)
for _, h := range []*ethpbv1.SignedBeaconBlockHeader{slashing.SignedHeader_1, slashing.SignedHeader_2} { for _, h := range []*ethpbv1.SignedBeaconBlockHeader{slashing.SignedHeader_1, slashing.SignedHeader_2} {
@@ -787,8 +789,9 @@ func TestSubmitVoluntaryExit_AcrossFork(t *testing.T) {
Signature: make([]byte, 96), Signature: make([]byte, 96),
} }
newBs := bs.Copy() newBs, err := bs.Copy()
newBs, err := transition.ProcessSlots(ctx, newBs, params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod)+1)) require.NoError(t, err)
newBs, err = transition.ProcessSlots(ctx, newBs, params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod)+1))
require.NoError(t, err) require.NoError(t, err)
sb, err := signing.ComputeDomainAndSign(newBs, exit.Message.Epoch, exit.Message, params.BeaconConfig().DomainVoluntaryExit, keys[0]) sb, err := signing.ComputeDomainAndSign(newBs, exit.Message.Epoch, exit.Message, params.BeaconConfig().DomainVoluntaryExit, keys[0])

View File

@@ -239,7 +239,10 @@ func (bs *Server) ListValidators(
return nil, err return nil, err
} }
if s > reqState.Slot() { if s > reqState.Slot() {
reqState = reqState.Copy() reqState, err = reqState.Copy()
if err != nil {
return nil, err
}
reqState, err = transition.ProcessSlots(ctx, reqState, s) reqState, err = transition.ProcessSlots(ctx, reqState, s)
if err != nil { if err != nil {
return nil, status.Errorf( return nil, status.Errorf(

View File

@@ -1907,7 +1907,8 @@ func TestGetValidatorPerformance_Indices(t *testing.T) {
SyncChecker: &mockSync.Sync{IsSyncing: false}, SyncChecker: &mockSync.Sync{IsSyncing: false},
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)}, GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
} }
c := headState.Copy() c, err := headState.Copy()
require.NoError(t, err)
vp, bp, err := precompute.New(ctx, c) vp, bp, err := precompute.New(ctx, c)
require.NoError(t, err) require.NoError(t, err)
vp, bp, err = precompute.ProcessAttestations(ctx, c, vp, bp) vp, bp, err = precompute.ProcessAttestations(ctx, c, vp, bp)
@@ -1977,7 +1978,8 @@ func TestGetValidatorPerformance_IndicesPubkeys(t *testing.T) {
SyncChecker: &mockSync.Sync{IsSyncing: false}, SyncChecker: &mockSync.Sync{IsSyncing: false},
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)}, GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
} }
c := headState.Copy() c, err := headState.Copy()
require.NoError(t, err)
vp, bp, err := precompute.New(ctx, c) vp, bp, err := precompute.New(ctx, c)
require.NoError(t, err) require.NoError(t, err)
vp, bp, err = precompute.ProcessAttestations(ctx, c, vp, bp) vp, bp, err = precompute.ProcessAttestations(ctx, c, vp, bp)

View File

@@ -20,7 +20,7 @@ type BeaconState interface {
ReadOnlyBeaconState ReadOnlyBeaconState
ReadOnlyWithdrawals ReadOnlyWithdrawals
WriteOnlyBeaconState WriteOnlyBeaconState
Copy() BeaconState Copy() (BeaconState, error)
HashTreeRoot(ctx context.Context) ([32]byte, error) HashTreeRoot(ctx context.Context) ([32]byte, error)
FutureForkStub FutureForkStub
StateProver StateProver
@@ -50,8 +50,8 @@ type ReadOnlyBeaconState interface {
ReadOnlyBalances ReadOnlyBalances
ReadOnlyCheckpoint ReadOnlyCheckpoint
ReadOnlyAttestations ReadOnlyAttestations
ToProtoUnsafe() interface{} ToProtoUnsafe() (interface{}, error)
ToProto() interface{} ToProto() (interface{}, error)
GenesisTime() uint64 GenesisTime() uint64
GenesisValidatorsRoot() []byte GenesisValidatorsRoot() []byte
Slot() types.Slot Slot() types.Slot
@@ -63,7 +63,7 @@ type ReadOnlyBeaconState interface {
MarshalSSZ() ([]byte, error) MarshalSSZ() ([]byte, error)
IsNil() bool IsNil() bool
Version() int Version() int
LatestExecutionPayloadHeader() (interfaces.ExecutionData, error) LatestExecutionPayloadHeader() (interfaces.ExecutionDataHeader, error)
} }
// WriteOnlyBeaconState defines a struct which only has write access to beacon state methods. // WriteOnlyBeaconState defines a struct which only has write access to beacon state methods.
@@ -85,7 +85,7 @@ type WriteOnlyBeaconState interface {
SetSlashings(val []uint64) error SetSlashings(val []uint64) error
UpdateSlashingsAtIndex(idx, val uint64) error UpdateSlashingsAtIndex(idx, val uint64) error
AppendHistoricalRoots(root [32]byte) error AppendHistoricalRoots(root [32]byte) error
SetLatestExecutionPayloadHeader(payload interfaces.ExecutionData) error SetLatestExecutionPayloadHeader(payload interfaces.ExecutionDataHeader) error
SetNextWithdrawalIndex(i uint64) error SetNextWithdrawalIndex(i uint64) error
SetNextWithdrawalValidatorIndex(i types.ValidatorIndex) error SetNextWithdrawalValidatorIndex(i types.ValidatorIndex) error
} }

View File

@@ -10,45 +10,44 @@ import (
customtypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/custom-types" customtypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/custom-types"
nativetypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/types" nativetypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces"
eth2types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" eth2types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
) )
// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining // BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining
// getters and setters for its respective values and helpful functions such as HashTreeRoot(). // getters and setters for its respective values and helpful functions such as HashTreeRoot().
type BeaconState struct { type BeaconState struct {
version int version int
genesisTime uint64 genesisTime uint64 `ssz-gen:"true"`
genesisValidatorsRoot [32]byte genesisValidatorsRoot [32]byte `ssz-gen:"true" ssz-size:"32"`
slot eth2types.Slot slot eth2types.Slot `ssz-gen:"true"`
fork *ethpb.Fork fork *ethpb.Fork `ssz-gen:"true"`
latestBlockHeader *ethpb.BeaconBlockHeader latestBlockHeader *ethpb.BeaconBlockHeader `ssz-gen:"true"`
blockRoots *customtypes.BlockRoots blockRoots *customtypes.BlockRoots `ssz-gen:"true" ssz-size:"8192,32"`
stateRoots *customtypes.StateRoots stateRoots *customtypes.StateRoots `ssz-gen:"true" ssz-size:"8192,32"`
historicalRoots customtypes.HistoricalRoots historicalRoots customtypes.HistoricalRoots `ssz-gen:"true" ssz-size:"?,32" ssz-max:"16777216"`
eth1Data *ethpb.Eth1Data eth1Data *ethpb.Eth1Data `ssz-gen:"true"`
eth1DataVotes []*ethpb.Eth1Data eth1DataVotes []*ethpb.Eth1Data `ssz-gen:"true" ssz-max:"2048"`
eth1DepositIndex uint64 eth1DepositIndex uint64 `ssz-gen:"true"`
validators []*ethpb.Validator validators []*ethpb.Validator `ssz-gen:"true" ssz-max:"1099511627776"`
balances []uint64 balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
randaoMixes *customtypes.RandaoMixes randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"65536,32"`
slashings []uint64 slashings []uint64 `ssz-gen:"true" ssz-size:"8192"`
previousEpochAttestations []*ethpb.PendingAttestation previousEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"4096"`
currentEpochAttestations []*ethpb.PendingAttestation currentEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"4096"`
previousEpochParticipation []byte previousEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
currentEpochParticipation []byte currentEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
justificationBits bitfield.Bitvector4 justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
previousJustifiedCheckpoint *ethpb.Checkpoint previousJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
currentJustifiedCheckpoint *ethpb.Checkpoint currentJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
finalizedCheckpoint *ethpb.Checkpoint finalizedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
inactivityScores []uint64 inactivityScores []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
currentSyncCommittee *ethpb.SyncCommittee currentSyncCommittee *ethpb.SyncCommittee `ssz-gen:"true"`
nextSyncCommittee *ethpb.SyncCommittee nextSyncCommittee *ethpb.SyncCommittee `ssz-gen:"true"`
latestExecutionPayloadHeader *enginev1.ExecutionPayloadHeader latestExecutionPayloadHeader interfaces.ExecutionDataHeader `ssz-gen:"true"`
latestExecutionPayloadHeaderCapella *enginev1.ExecutionPayloadHeaderCapella nextWithdrawalIndex uint64
nextWithdrawalIndex uint64 nextWithdrawalValidatorIndex eth2types.ValidatorIndex
nextWithdrawalValidatorIndex eth2types.ValidatorIndex
lock sync.RWMutex lock sync.RWMutex
dirtyFields map[nativetypes.FieldIndex]bool dirtyFields map[nativetypes.FieldIndex]bool

View File

@@ -10,45 +10,44 @@ import (
customtypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/custom-types" customtypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/custom-types"
nativetypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/types" nativetypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces"
eth2types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" eth2types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
) )
// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining // BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining
// getters and setters for its respective values and helpful functions such as HashTreeRoot(). // getters and setters for its respective values and helpful functions such as HashTreeRoot().
type BeaconState struct { type BeaconState struct {
version int version int
genesisTime uint64 genesisTime uint64
genesisValidatorsRoot [32]byte genesisValidatorsRoot [32]byte
slot eth2types.Slot slot eth2types.Slot
fork *ethpb.Fork fork *ethpb.Fork
latestBlockHeader *ethpb.BeaconBlockHeader latestBlockHeader *ethpb.BeaconBlockHeader
blockRoots *customtypes.BlockRoots blockRoots *customtypes.BlockRoots
stateRoots *customtypes.StateRoots stateRoots *customtypes.StateRoots
historicalRoots customtypes.HistoricalRoots historicalRoots customtypes.HistoricalRoots
eth1Data *ethpb.Eth1Data eth1Data *ethpb.Eth1Data
eth1DataVotes []*ethpb.Eth1Data eth1DataVotes []*ethpb.Eth1Data
eth1DepositIndex uint64 eth1DepositIndex uint64
validators []*ethpb.Validator validators []*ethpb.Validator
balances []uint64 balances []uint64
randaoMixes *customtypes.RandaoMixes randaoMixes *customtypes.RandaoMixes
slashings []uint64 slashings []uint64
previousEpochAttestations []*ethpb.PendingAttestation previousEpochAttestations []*ethpb.PendingAttestation
currentEpochAttestations []*ethpb.PendingAttestation currentEpochAttestations []*ethpb.PendingAttestation
previousEpochParticipation []byte previousEpochParticipation []byte
currentEpochParticipation []byte currentEpochParticipation []byte
justificationBits bitfield.Bitvector4 justificationBits bitfield.Bitvector4
previousJustifiedCheckpoint *ethpb.Checkpoint previousJustifiedCheckpoint *ethpb.Checkpoint
currentJustifiedCheckpoint *ethpb.Checkpoint currentJustifiedCheckpoint *ethpb.Checkpoint
finalizedCheckpoint *ethpb.Checkpoint finalizedCheckpoint *ethpb.Checkpoint
inactivityScores []uint64 inactivityScores []uint64
currentSyncCommittee *ethpb.SyncCommittee currentSyncCommittee *ethpb.SyncCommittee
nextSyncCommittee *ethpb.SyncCommittee nextSyncCommittee *ethpb.SyncCommittee
latestExecutionPayloadHeader *enginev1.ExecutionPayloadHeader latestExecutionPayloadHeader interfaces.ExecutionDataHeader
latestExecutionPayloadHeaderCapella *enginev1.ExecutionPayloadHeaderCapella nextWithdrawalIndex uint64
nextWithdrawalIndex uint64 nextWithdrawalValidatorIndex eth2types.ValidatorIndex
nextWithdrawalValidatorIndex eth2types.ValidatorIndex
lock sync.RWMutex lock sync.RWMutex
dirtyFields map[nativetypes.FieldIndex]bool dirtyFields map[nativetypes.FieldIndex]bool

View File

@@ -1,6 +1,8 @@
package state_native package state_native
import ( import (
"fmt"
"github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1" enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
@@ -9,28 +11,37 @@ import (
) )
// LatestExecutionPayloadHeader of the beacon state. // LatestExecutionPayloadHeader of the beacon state.
func (b *BeaconState) LatestExecutionPayloadHeader() (interfaces.ExecutionData, error) { func (b *BeaconState) LatestExecutionPayloadHeader() (interfaces.ExecutionDataHeader, error) {
if b.version < version.Bellatrix { if b.version < version.Bellatrix {
return nil, errNotSupported("LatestExecutionPayloadHeader", b.version) return nil, errNotSupported("LatestExecutionPayloadHeader", b.version)
} }
if b.latestExecutionPayloadHeader == nil || b.latestExecutionPayloadHeader.IsNil() {
return nil, nil
}
b.lock.RLock() b.lock.RLock()
defer b.lock.RUnlock() defer b.lock.RUnlock()
if b.version == version.Bellatrix { return b.latestExecutionPayloadHeaderVal()
return blocks.WrappedExecutionPayloadHeader(b.latestExecutionPayloadHeaderVal())
}
return blocks.WrappedExecutionPayloadHeaderCapella(b.latestExecutionPayloadHeaderCapellaVal())
} }
// latestExecutionPayloadHeaderVal of the beacon state. // latestExecutionPayloadHeaderVal of the beacon state.
// This assumes that a lock is already held on BeaconState. // This assumes that a lock is already held on BeaconState.
func (b *BeaconState) latestExecutionPayloadHeaderVal() *enginev1.ExecutionPayloadHeader { func (b *BeaconState) latestExecutionPayloadHeaderVal() (interfaces.ExecutionDataHeader, error) {
return ethpb.CopyExecutionPayloadHeader(b.latestExecutionPayloadHeader) if b.latestExecutionPayloadHeader == nil {
} return nil, nil
}
// latestExecutionPayloadHeaderCapellaVal of the beacon state. headerProto := b.latestExecutionPayloadHeader.Proto()
// This assumes that a lock is already held on BeaconState. switch h := headerProto.(type) {
func (b *BeaconState) latestExecutionPayloadHeaderCapellaVal() *enginev1.ExecutionPayloadHeaderCapella { case *enginev1.ExecutionPayloadHeader:
return ethpb.CopyExecutionPayloadHeaderCapella(b.latestExecutionPayloadHeaderCapella) headerCopy := ethpb.CopyExecutionPayloadHeader(h)
return blocks.WrappedExecutionPayloadHeader(headerCopy)
case *enginev1.ExecutionPayloadHeaderCapella:
headerCopy := ethpb.CopyExecutionPayloadHeaderCapella(h)
return blocks.WrappedExecutionPayloadHeaderCapella(headerCopy)
default:
return nil, fmt.Errorf("invalid payload header in beacon state: %T", headerProto)
}
} }

View File

@@ -4,15 +4,16 @@ import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/runtime/version" "github.com/prysmaticlabs/prysm/v3/runtime/version"
) )
// ToProtoUnsafe returns the pointer value of the underlying // ToProtoUnsafe returns the pointer value of the underlying
// beacon state proto object, bypassing immutability. Use with care. // beacon state proto object, bypassing immutability. Use with care.
func (b *BeaconState) ToProtoUnsafe() interface{} { func (b *BeaconState) ToProtoUnsafe() (interface{}, error) {
if b == nil { if b == nil {
return nil return nil, nil
} }
gvrCopy := b.genesisValidatorsRoot gvrCopy := b.genesisValidatorsRoot
@@ -41,7 +42,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint, PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint, CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
FinalizedCheckpoint: b.finalizedCheckpoint, FinalizedCheckpoint: b.finalizedCheckpoint,
} }, nil
case version.Altair: case version.Altair:
return &ethpb.BeaconStateAltair{ return &ethpb.BeaconStateAltair{
GenesisTime: b.genesisTime, GenesisTime: b.genesisTime,
@@ -68,8 +69,12 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
InactivityScores: b.inactivityScores, InactivityScores: b.inactivityScores,
CurrentSyncCommittee: b.currentSyncCommittee, CurrentSyncCommittee: b.currentSyncCommittee,
NextSyncCommittee: b.nextSyncCommittee, NextSyncCommittee: b.nextSyncCommittee,
} }, nil
case version.Bellatrix: case version.Bellatrix:
execHeader, ok := b.latestExecutionPayloadHeader.Proto().(*enginev1.ExecutionPayloadHeader)
if !ok {
return nil, errors.New("unexpected execution payload")
}
return &ethpb.BeaconStateBellatrix{ return &ethpb.BeaconStateBellatrix{
GenesisTime: b.genesisTime, GenesisTime: b.genesisTime,
GenesisValidatorsRoot: gvrCopy[:], GenesisValidatorsRoot: gvrCopy[:],
@@ -95,9 +100,13 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
InactivityScores: b.inactivityScores, InactivityScores: b.inactivityScores,
CurrentSyncCommittee: b.currentSyncCommittee, CurrentSyncCommittee: b.currentSyncCommittee,
NextSyncCommittee: b.nextSyncCommittee, NextSyncCommittee: b.nextSyncCommittee,
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader, LatestExecutionPayloadHeader: execHeader,
} }, nil
case version.Capella: case version.Capella:
execHeader, ok := b.latestExecutionPayloadHeader.Proto().(*enginev1.ExecutionPayloadHeaderCapella)
if !ok {
return nil, errors.New("unexpected execution payload")
}
return &ethpb.BeaconStateCapella{ return &ethpb.BeaconStateCapella{
GenesisTime: b.genesisTime, GenesisTime: b.genesisTime,
GenesisValidatorsRoot: gvrCopy[:], GenesisValidatorsRoot: gvrCopy[:],
@@ -123,19 +132,19 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
InactivityScores: b.inactivityScores, InactivityScores: b.inactivityScores,
CurrentSyncCommittee: b.currentSyncCommittee, CurrentSyncCommittee: b.currentSyncCommittee,
NextSyncCommittee: b.nextSyncCommittee, NextSyncCommittee: b.nextSyncCommittee,
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderCapella, LatestExecutionPayloadHeader: execHeader,
NextWithdrawalIndex: b.nextWithdrawalIndex, NextWithdrawalIndex: b.nextWithdrawalIndex,
NextWithdrawalValidatorIndex: b.nextWithdrawalValidatorIndex, NextWithdrawalValidatorIndex: b.nextWithdrawalValidatorIndex,
} }, nil
default: default:
return nil return nil, nil
} }
} }
// ToProto the beacon state into a protobuf for usage. // ToProto the beacon state into a protobuf for usage.
func (b *BeaconState) ToProto() interface{} { func (b *BeaconState) ToProto() (interface{}, error) {
if b == nil { if b == nil {
return nil return nil, nil
} }
b.lock.RLock() b.lock.RLock()
@@ -167,7 +176,7 @@ func (b *BeaconState) ToProto() interface{} {
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(), PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(), CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
FinalizedCheckpoint: b.finalizedCheckpointVal(), FinalizedCheckpoint: b.finalizedCheckpointVal(),
} }, nil
case version.Altair: case version.Altair:
return &ethpb.BeaconStateAltair{ return &ethpb.BeaconStateAltair{
GenesisTime: b.genesisTime, GenesisTime: b.genesisTime,
@@ -194,8 +203,16 @@ func (b *BeaconState) ToProto() interface{} {
InactivityScores: b.inactivityScoresVal(), InactivityScores: b.inactivityScoresVal(),
CurrentSyncCommittee: b.currentSyncCommitteeVal(), CurrentSyncCommittee: b.currentSyncCommitteeVal(),
NextSyncCommittee: b.nextSyncCommitteeVal(), NextSyncCommittee: b.nextSyncCommitteeVal(),
} }, nil
case version.Bellatrix: case version.Bellatrix:
execHeader, err := b.latestExecutionPayloadHeaderVal()
if err != nil {
return nil, err
}
headerProto, ok := execHeader.Proto().(*enginev1.ExecutionPayloadHeader)
if !ok {
return nil, errors.New("unexpected execution payload")
}
return &ethpb.BeaconStateBellatrix{ return &ethpb.BeaconStateBellatrix{
GenesisTime: b.genesisTime, GenesisTime: b.genesisTime,
GenesisValidatorsRoot: gvrCopy[:], GenesisValidatorsRoot: gvrCopy[:],
@@ -221,9 +238,17 @@ func (b *BeaconState) ToProto() interface{} {
InactivityScores: b.inactivityScoresVal(), InactivityScores: b.inactivityScoresVal(),
CurrentSyncCommittee: b.currentSyncCommitteeVal(), CurrentSyncCommittee: b.currentSyncCommitteeVal(),
NextSyncCommittee: b.nextSyncCommitteeVal(), NextSyncCommittee: b.nextSyncCommitteeVal(),
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderVal(), LatestExecutionPayloadHeader: headerProto,
} }, nil
case version.Capella: case version.Capella:
execHeader, err := b.latestExecutionPayloadHeaderVal()
if err != nil {
return nil, err
}
headerProto, ok := execHeader.Proto().(*enginev1.ExecutionPayloadHeaderCapella)
if !ok {
return nil, errors.New("unexpected execution payload")
}
return &ethpb.BeaconStateCapella{ return &ethpb.BeaconStateCapella{
GenesisTime: b.genesisTime, GenesisTime: b.genesisTime,
GenesisValidatorsRoot: gvrCopy[:], GenesisValidatorsRoot: gvrCopy[:],
@@ -249,12 +274,12 @@ func (b *BeaconState) ToProto() interface{} {
InactivityScores: b.inactivityScoresVal(), InactivityScores: b.inactivityScoresVal(),
CurrentSyncCommittee: b.currentSyncCommitteeVal(), CurrentSyncCommittee: b.currentSyncCommitteeVal(),
NextSyncCommittee: b.nextSyncCommitteeVal(), NextSyncCommittee: b.nextSyncCommitteeVal(),
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderCapellaVal(), LatestExecutionPayloadHeader: headerProto,
NextWithdrawalIndex: b.nextWithdrawalIndex, NextWithdrawalIndex: b.nextWithdrawalIndex,
NextWithdrawalValidatorIndex: b.nextWithdrawalValidatorIndex, NextWithdrawalValidatorIndex: b.nextWithdrawalValidatorIndex,
} }, nil
default: default:
return nil return nil, nil
} }
} }

View File

@@ -229,7 +229,7 @@ func ComputeFieldRootsWithHasher(ctx context.Context, state *BeaconState) ([][]b
fieldRoots[nativetypes.NextSyncCommittee.RealPosition()] = nextSyncCommitteeRoot[:] fieldRoots[nativetypes.NextSyncCommittee.RealPosition()] = nextSyncCommitteeRoot[:]
} }
if state.version == version.Bellatrix { if state.version >= version.Bellatrix {
// Execution payload root. // Execution payload root.
executionPayloadRoot, err := state.latestExecutionPayloadHeader.HashTreeRoot() executionPayloadRoot, err := state.latestExecutionPayloadHeader.HashTreeRoot()
if err != nil { if err != nil {
@@ -239,13 +239,6 @@ func ComputeFieldRootsWithHasher(ctx context.Context, state *BeaconState) ([][]b
} }
if state.version == version.Capella { if state.version == version.Capella {
// Execution payload root.
executionPayloadRoot, err := state.latestExecutionPayloadHeaderCapella.HashTreeRoot()
if err != nil {
return nil, err
}
fieldRoots[nativetypes.LatestExecutionPayloadHeaderCapella.RealPosition()] = executionPayloadRoot[:]
// Next withdrawal index root. // Next withdrawal index root.
nextWithdrawalIndexRoot := make([]byte, 32) nextWithdrawalIndexRoot := make([]byte, 32)
binary.LittleEndian.PutUint64(nextWithdrawalIndexRoot, state.nextWithdrawalIndex) binary.LittleEndian.PutUint64(nextWithdrawalIndexRoot, state.nextWithdrawalIndex)

View File

@@ -26,7 +26,8 @@ func TestStateReferenceSharing_Finalizer_Phase0(t *testing.T) {
func() { func() {
// Create object in a different scope for GC // Create object in a different scope for GC
b := a.Copy() b, err := a.Copy()
require.NoError(t, err)
assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes") assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes")
_ = b _ = b
}() }()
@@ -34,7 +35,8 @@ func TestStateReferenceSharing_Finalizer_Phase0(t *testing.T) {
runtime.GC() // Should run finalizer on object b runtime.GC() // Should run finalizer on object b
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!") assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!")
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes") assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
@@ -55,7 +57,8 @@ func TestStateReferenceSharing_Finalizer_Altair(t *testing.T) {
func() { func() {
// Create object in a different scope for GC // Create object in a different scope for GC
b := a.Copy() b, err := a.Copy()
require.NoError(t, err)
assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes") assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes")
_ = b _ = b
}() }()
@@ -63,7 +66,8 @@ func TestStateReferenceSharing_Finalizer_Altair(t *testing.T) {
runtime.GC() // Should run finalizer on object b runtime.GC() // Should run finalizer on object b
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!") assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!")
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes") assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
@@ -84,7 +88,8 @@ func TestStateReferenceSharing_Finalizer_Bellatrix(t *testing.T) {
func() { func() {
// Create object in a different scope for GC // Create object in a different scope for GC
b := a.Copy() b, err := a.Copy()
require.NoError(t, err)
assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes") assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes")
_ = b _ = b
}() }()
@@ -92,7 +97,8 @@ func TestStateReferenceSharing_Finalizer_Bellatrix(t *testing.T) {
runtime.GC() // Should run finalizer on object b runtime.GC() // Should run finalizer on object b
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!") assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!")
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes") assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
@@ -113,7 +119,8 @@ func TestStateReferenceSharing_Finalizer_Capella(t *testing.T) {
func() { func() {
// Create object in a different scope for GC // Create object in a different scope for GC
b := a.Copy() b, err := a.Copy()
require.NoError(t, err)
assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes") assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes")
_ = b _ = b
}() }()
@@ -121,7 +128,8 @@ func TestStateReferenceSharing_Finalizer_Capella(t *testing.T) {
runtime.GC() // Should run finalizer on object b runtime.GC() // Should run finalizer on object b
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!") assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!")
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes") assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
@@ -149,7 +157,8 @@ func TestStateReferenceCopy_NoUnexpectedRootsMutation_Phase0(t *testing.T) {
assertRefCount(t, a, nativetypes.StateRoots, 1) assertRefCount(t, a, nativetypes.StateRoots, 1)
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.BlockRoots, 2) assertRefCount(t, a, nativetypes.BlockRoots, 2)
@@ -208,7 +217,8 @@ func TestStateReferenceCopy_NoUnexpectedRootsMutation_Altair(t *testing.T) {
assertRefCount(t, a, nativetypes.StateRoots, 1) assertRefCount(t, a, nativetypes.StateRoots, 1)
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.BlockRoots, 2) assertRefCount(t, a, nativetypes.BlockRoots, 2)
@@ -267,7 +277,8 @@ func TestStateReferenceCopy_NoUnexpectedRootsMutation_Bellatrix(t *testing.T) {
assertRefCount(t, a, nativetypes.StateRoots, 1) assertRefCount(t, a, nativetypes.StateRoots, 1)
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.BlockRoots, 2) assertRefCount(t, a, nativetypes.BlockRoots, 2)
@@ -326,7 +337,8 @@ func TestStateReferenceCopy_NoUnexpectedRootsMutation_Capella(t *testing.T) {
assertRefCount(t, a, nativetypes.StateRoots, 1) assertRefCount(t, a, nativetypes.StateRoots, 1)
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.BlockRoots, 2) assertRefCount(t, a, nativetypes.BlockRoots, 2)
@@ -381,7 +393,8 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Phase0(t *testing.T) {
assertRefCount(t, a, nativetypes.RandaoMixes, 1) assertRefCount(t, a, nativetypes.RandaoMixes, 1)
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.RandaoMixes, 2) assertRefCount(t, a, nativetypes.RandaoMixes, 2)
@@ -425,7 +438,8 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Altair(t *testing.T) {
assertRefCount(t, a, nativetypes.RandaoMixes, 1) assertRefCount(t, a, nativetypes.RandaoMixes, 1)
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.RandaoMixes, 2) assertRefCount(t, a, nativetypes.RandaoMixes, 2)
@@ -469,7 +483,8 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Bellatrix(t *testing.T) {
assertRefCount(t, a, nativetypes.RandaoMixes, 1) assertRefCount(t, a, nativetypes.RandaoMixes, 1)
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.RandaoMixes, 2) assertRefCount(t, a, nativetypes.RandaoMixes, 2)
@@ -513,7 +528,8 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Capella(t *testing.T) {
assertRefCount(t, a, nativetypes.RandaoMixes, 1) assertRefCount(t, a, nativetypes.RandaoMixes, 1)
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.RandaoMixes, 2) assertRefCount(t, a, nativetypes.RandaoMixes, 2)
@@ -585,7 +601,8 @@ func TestStateReferenceCopy_NoUnexpectedAttestationsMutation(t *testing.T) {
assert.Equal(t, 1, len(preAtt), "Unexpected number of attestations") assert.Equal(t, 1, len(preAtt), "Unexpected number of attestations")
// Copy, increases reference count. // Copy, increases reference count.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
assertRefCount(t, a, nativetypes.PreviousEpochAttestations, 2) assertRefCount(t, a, nativetypes.PreviousEpochAttestations, 2)
@@ -723,7 +740,8 @@ func TestValidatorReferences_RemainsConsistent_Phase0(t *testing.T) {
require.Equal(t, true, ok) require.Equal(t, true, ok)
// Create a second state. // Create a second state.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
@@ -758,7 +776,8 @@ func TestValidatorReferences_RemainsConsistent_Altair(t *testing.T) {
require.Equal(t, true, ok) require.Equal(t, true, ok)
// Create a second state. // Create a second state.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
@@ -793,7 +812,8 @@ func TestValidatorReferences_RemainsConsistent_Capella(t *testing.T) {
require.Equal(t, true, ok) require.Equal(t, true, ok)
// Create a second state. // Create a second state.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)
@@ -828,7 +848,8 @@ func TestValidatorReferences_RemainsConsistent_Bellatrix(t *testing.T) {
require.Equal(t, true, ok) require.Equal(t, true, ok)
// Create a second state. // Create a second state.
copied := a.Copy() copied, err := a.Copy()
require.NoError(t, err)
b, ok := copied.(*BeaconState) b, ok := copied.(*BeaconState)
require.Equal(t, true, ok) require.Equal(t, true, ok)

View File

@@ -1,17 +1,20 @@
package state_native package state_native
import ( import (
"github.com/pkg/errors"
nativetypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/types" nativetypes "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native/types"
consensusblocks "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
_ "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" _ "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/runtime/version" "github.com/prysmaticlabs/prysm/v3/runtime/version"
) )
// SetLatestExecutionPayloadHeader for the beacon state. // SetLatestExecutionPayloadHeader for the beacon state.
func (b *BeaconState) SetLatestExecutionPayloadHeader(val interfaces.ExecutionData) error { func (b *BeaconState) SetLatestExecutionPayloadHeader(val interfaces.ExecutionDataHeader) error {
headerCopy, err := blocks.CopyExecutionDataHeader(val)
if err != nil {
return err
}
b.lock.Lock() b.lock.Lock()
defer b.lock.Unlock() defer b.lock.Unlock()
@@ -19,32 +22,7 @@ func (b *BeaconState) SetLatestExecutionPayloadHeader(val interfaces.ExecutionDa
return errNotSupported("SetLatestExecutionPayloadHeader", b.version) return errNotSupported("SetLatestExecutionPayloadHeader", b.version)
} }
switch header := val.Proto().(type) { b.latestExecutionPayloadHeader = headerCopy
case *enginev1.ExecutionPayload: b.markFieldAsDirty(nativetypes.LatestExecutionPayloadHeader)
latest, err := consensusblocks.PayloadToHeader(val) return nil
if err != nil {
return errors.Wrap(err, "could not convert payload to header")
}
b.latestExecutionPayloadHeader = latest
b.markFieldAsDirty(nativetypes.LatestExecutionPayloadHeader)
return nil
case *enginev1.ExecutionPayloadCapella:
latest, err := consensusblocks.PayloadToHeaderCapella(val)
if err != nil {
return errors.Wrap(err, "could not convert payload to header")
}
b.latestExecutionPayloadHeaderCapella = latest
b.markFieldAsDirty(nativetypes.LatestExecutionPayloadHeaderCapella)
return nil
case *enginev1.ExecutionPayloadHeader:
b.latestExecutionPayloadHeader = header
b.markFieldAsDirty(nativetypes.LatestExecutionPayloadHeader)
return nil
case *enginev1.ExecutionPayloadHeaderCapella:
b.latestExecutionPayloadHeaderCapella = header
b.markFieldAsDirty(nativetypes.LatestExecutionPayloadHeaderCapella)
return nil
default:
return errors.New("value must be an execution payload header")
}
} }

View File

@@ -8,7 +8,10 @@ import (
var errAssertionFailed = errors.New("failed to convert interface to proto state") var errAssertionFailed = errors.New("failed to convert interface to proto state")
func (b *BeaconState) MarshalSSZ() ([]byte, error) { func (b *BeaconState) MarshalSSZ() ([]byte, error) {
proto := b.ToProto() proto, err := b.ToProto()
if err != nil {
return nil, err
}
s, ok := proto.(ssz.Marshaler) s, ok := proto.(ssz.Marshaler)
if !ok { if !ok {

View File

@@ -14,6 +14,8 @@ import (
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state/types" "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/types"
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
"github.com/prysmaticlabs/prysm/v3/config/params" "github.com/prysmaticlabs/prysm/v3/config/params"
"github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v3/container/slice" "github.com/prysmaticlabs/prysm/v3/container/slice"
"github.com/prysmaticlabs/prysm/v3/crypto/hash" "github.com/prysmaticlabs/prysm/v3/crypto/hash"
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
@@ -78,8 +80,7 @@ var altairFields = []nativetypes.FieldIndex{
var bellatrixFields = append(altairFields, nativetypes.LatestExecutionPayloadHeader) var bellatrixFields = append(altairFields, nativetypes.LatestExecutionPayloadHeader)
var capellaFields = append( var capellaFields = append(
altairFields, bellatrixFields,
nativetypes.LatestExecutionPayloadHeaderCapella,
nativetypes.NextWithdrawalIndex, nativetypes.NextWithdrawalIndex,
nativetypes.NextWithdrawalValidatorIndex, nativetypes.NextWithdrawalValidatorIndex,
) )
@@ -310,6 +311,14 @@ func InitializeFromProtoUnsafeBellatrix(st *ethpb.BeaconStateBellatrix) (state.B
for i, m := range st.RandaoMixes { for i, m := range st.RandaoMixes {
mixes[i] = bytesutil.ToBytes32(m) mixes[i] = bytesutil.ToBytes32(m)
} }
var initialPayloadHeader interfaces.ExecutionDataHeader
if st.LatestExecutionPayloadHeader != nil {
var err error
initialPayloadHeader, err = blocks.WrappedExecutionPayloadHeader(st.LatestExecutionPayloadHeader)
if err != nil {
return nil, errors.Wrap(err, "failed to wrap latest execution payload header")
}
}
fieldCount := params.BeaconConfig().BeaconStateBellatrixFieldCount fieldCount := params.BeaconConfig().BeaconStateBellatrixFieldCount
b := &BeaconState{ b := &BeaconState{
@@ -338,7 +347,7 @@ func InitializeFromProtoUnsafeBellatrix(st *ethpb.BeaconStateBellatrix) (state.B
inactivityScores: st.InactivityScores, inactivityScores: st.InactivityScores,
currentSyncCommittee: st.CurrentSyncCommittee, currentSyncCommittee: st.CurrentSyncCommittee,
nextSyncCommittee: st.NextSyncCommittee, nextSyncCommittee: st.NextSyncCommittee,
latestExecutionPayloadHeader: st.LatestExecutionPayloadHeader, latestExecutionPayloadHeader: initialPayloadHeader,
dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount), dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount),
dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount), dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount),
@@ -402,37 +411,45 @@ func InitializeFromProtoUnsafeCapella(st *ethpb.BeaconStateCapella) (state.Beaco
for i, m := range st.RandaoMixes { for i, m := range st.RandaoMixes {
mixes[i] = bytesutil.ToBytes32(m) mixes[i] = bytesutil.ToBytes32(m)
} }
var initialPayloadHeader interfaces.ExecutionDataHeader
if st.LatestExecutionPayloadHeader != nil {
var err error
initialPayloadHeader, err = blocks.WrappedExecutionPayloadHeaderCapella(st.LatestExecutionPayloadHeader)
if err != nil {
return nil, errors.Wrap(err, "failed to wrap latest execution payload header")
}
}
fieldCount := params.BeaconConfig().BeaconStateCapellaFieldCount fieldCount := params.BeaconConfig().BeaconStateCapellaFieldCount
b := &BeaconState{ b := &BeaconState{
version: version.Capella, version: version.Capella,
genesisTime: st.GenesisTime, genesisTime: st.GenesisTime,
genesisValidatorsRoot: bytesutil.ToBytes32(st.GenesisValidatorsRoot), genesisValidatorsRoot: bytesutil.ToBytes32(st.GenesisValidatorsRoot),
slot: st.Slot, slot: st.Slot,
fork: st.Fork, fork: st.Fork,
latestBlockHeader: st.LatestBlockHeader, latestBlockHeader: st.LatestBlockHeader,
blockRoots: &bRoots, blockRoots: &bRoots,
stateRoots: &sRoots, stateRoots: &sRoots,
historicalRoots: hRoots, historicalRoots: hRoots,
eth1Data: st.Eth1Data, eth1Data: st.Eth1Data,
eth1DataVotes: st.Eth1DataVotes, eth1DataVotes: st.Eth1DataVotes,
eth1DepositIndex: st.Eth1DepositIndex, eth1DepositIndex: st.Eth1DepositIndex,
validators: st.Validators, validators: st.Validators,
balances: st.Balances, balances: st.Balances,
randaoMixes: &mixes, randaoMixes: &mixes,
slashings: st.Slashings, slashings: st.Slashings,
previousEpochParticipation: st.PreviousEpochParticipation, previousEpochParticipation: st.PreviousEpochParticipation,
currentEpochParticipation: st.CurrentEpochParticipation, currentEpochParticipation: st.CurrentEpochParticipation,
justificationBits: st.JustificationBits, justificationBits: st.JustificationBits,
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint, previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint, currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
finalizedCheckpoint: st.FinalizedCheckpoint, finalizedCheckpoint: st.FinalizedCheckpoint,
inactivityScores: st.InactivityScores, inactivityScores: st.InactivityScores,
currentSyncCommittee: st.CurrentSyncCommittee, currentSyncCommittee: st.CurrentSyncCommittee,
nextSyncCommittee: st.NextSyncCommittee, nextSyncCommittee: st.NextSyncCommittee,
latestExecutionPayloadHeaderCapella: st.LatestExecutionPayloadHeader, latestExecutionPayloadHeader: initialPayloadHeader,
nextWithdrawalIndex: st.NextWithdrawalIndex, nextWithdrawalIndex: st.NextWithdrawalIndex,
nextWithdrawalValidatorIndex: st.NextWithdrawalValidatorIndex, nextWithdrawalValidatorIndex: st.NextWithdrawalValidatorIndex,
dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount), dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount),
dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount), dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount),
@@ -465,7 +482,7 @@ func InitializeFromProtoUnsafeCapella(st *ethpb.BeaconStateCapella) (state.Beaco
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1) b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1) b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1) b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.LatestExecutionPayloadHeaderCapella] = stateutil.NewRef(1) // New in Capella. b.sharedFieldReferences[nativetypes.LatestExecutionPayloadHeader] = stateutil.NewRef(1)
state.StateCount.Inc() state.StateCount.Inc()
// Finalizer runs when dst is being destroyed in garbage collection. // Finalizer runs when dst is being destroyed in garbage collection.
@@ -474,7 +491,7 @@ func InitializeFromProtoUnsafeCapella(st *ethpb.BeaconStateCapella) (state.Beaco
} }
// Copy returns a deep copy of the beacon state. // Copy returns a deep copy of the beacon state.
func (b *BeaconState) Copy() state.BeaconState { func (b *BeaconState) Copy() (state.BeaconState, error) {
b.lock.RLock() b.lock.RLock()
defer b.lock.RUnlock() defer b.lock.RUnlock()
@@ -490,6 +507,11 @@ func (b *BeaconState) Copy() state.BeaconState {
fieldCount = params.BeaconConfig().BeaconStateCapellaFieldCount fieldCount = params.BeaconConfig().BeaconStateCapellaFieldCount
} }
// TODO: may panic!
header, err := b.latestExecutionPayloadHeaderVal()
if err != nil {
return nil, errors.Wrap(err, "failed to get latest execution payload header")
}
dst := &BeaconState{ dst := &BeaconState{
version: b.version, version: b.version,
@@ -518,18 +540,17 @@ func (b *BeaconState) Copy() state.BeaconState {
inactivityScores: b.inactivityScores, inactivityScores: b.inactivityScores,
// Everything else, too small to be concerned about, constant size. // Everything else, too small to be concerned about, constant size.
genesisValidatorsRoot: b.genesisValidatorsRoot, genesisValidatorsRoot: b.genesisValidatorsRoot,
justificationBits: b.justificationBitsVal(), justificationBits: b.justificationBitsVal(),
fork: b.forkVal(), fork: b.forkVal(),
latestBlockHeader: b.latestBlockHeaderVal(), latestBlockHeader: b.latestBlockHeaderVal(),
eth1Data: b.eth1DataVal(), eth1Data: b.eth1DataVal(),
previousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(), previousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
currentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(), currentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
finalizedCheckpoint: b.finalizedCheckpointVal(), finalizedCheckpoint: b.finalizedCheckpointVal(),
currentSyncCommittee: b.currentSyncCommitteeVal(), currentSyncCommittee: b.currentSyncCommitteeVal(),
nextSyncCommittee: b.nextSyncCommitteeVal(), nextSyncCommittee: b.nextSyncCommitteeVal(),
latestExecutionPayloadHeader: b.latestExecutionPayloadHeaderVal(), latestExecutionPayloadHeader: header,
latestExecutionPayloadHeaderCapella: b.latestExecutionPayloadHeaderCapellaVal(),
dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount), dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount),
dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount), dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount),
@@ -596,7 +617,7 @@ func (b *BeaconState) Copy() state.BeaconState {
state.StateCount.Inc() state.StateCount.Inc()
// Finalizer runs when dst is being destroyed in garbage collection. // Finalizer runs when dst is being destroyed in garbage collection.
runtime.SetFinalizer(dst, finalizerCleanup) runtime.SetFinalizer(dst, finalizerCleanup)
return dst return dst, nil
} }
// HashTreeRoot of the beacon state retrieves the Merkle root of the trie // HashTreeRoot of the beacon state retrieves the Merkle root of the trie
@@ -827,8 +848,6 @@ func (b *BeaconState) rootSelector(ctx context.Context, field nativetypes.FieldI
return stateutil.SyncCommitteeRoot(b.nextSyncCommittee) return stateutil.SyncCommitteeRoot(b.nextSyncCommittee)
case nativetypes.LatestExecutionPayloadHeader: case nativetypes.LatestExecutionPayloadHeader:
return b.latestExecutionPayloadHeader.HashTreeRoot() return b.latestExecutionPayloadHeader.HashTreeRoot()
case nativetypes.LatestExecutionPayloadHeaderCapella:
return b.latestExecutionPayloadHeaderCapella.HashTreeRoot()
case nativetypes.NextWithdrawalIndex: case nativetypes.NextWithdrawalIndex:
return ssz.Uint64Root(b.nextWithdrawalIndex), nil return ssz.Uint64Root(b.nextWithdrawalIndex), nil
case nativetypes.NextWithdrawalValidatorIndex: case nativetypes.NextWithdrawalValidatorIndex:

View File

@@ -65,8 +65,6 @@ func (f FieldIndex) String(_ int) string {
return "nextSyncCommittee" return "nextSyncCommittee"
case LatestExecutionPayloadHeader: case LatestExecutionPayloadHeader:
return "latestExecutionPayloadHeader" return "latestExecutionPayloadHeader"
case LatestExecutionPayloadHeaderCapella:
return "LatestExecutionPayloadHeaderCapella"
case NextWithdrawalIndex: case NextWithdrawalIndex:
return "NextWithdrawalIndex" return "NextWithdrawalIndex"
case NextWithdrawalValidatorIndex: case NextWithdrawalValidatorIndex:
@@ -128,7 +126,7 @@ func (f FieldIndex) RealPosition() int {
return 22 return 22
case NextSyncCommittee: case NextSyncCommittee:
return 23 return 23
case LatestExecutionPayloadHeader, LatestExecutionPayloadHeaderCapella: case LatestExecutionPayloadHeader:
return 24 return 24
case NextWithdrawalIndex: case NextWithdrawalIndex:
return 25 return 25
@@ -188,7 +186,6 @@ const (
CurrentSyncCommittee CurrentSyncCommittee
NextSyncCommittee NextSyncCommittee
LatestExecutionPayloadHeader LatestExecutionPayloadHeader
LatestExecutionPayloadHeaderCapella
NextWithdrawalIndex NextWithdrawalIndex
NextWithdrawalValidatorIndex NextWithdrawalValidatorIndex
) )

View File

@@ -26,7 +26,9 @@ func TestBeaconState_ProtoBeaconStateCompatibility(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
cloned, ok := proto.Clone(genesis).(*ethpb.BeaconState) cloned, ok := proto.Clone(genesis).(*ethpb.BeaconState)
assert.Equal(t, true, ok, "Object is not of type *ethpb.BeaconState") assert.Equal(t, true, ok, "Object is not of type *ethpb.BeaconState")
custom := customState.ToProto() customStateProto, err := customState.ToProto()
require.NoError(t, err)
custom := customStateProto
assert.DeepSSZEqual(t, cloned, custom) assert.DeepSSZEqual(t, cloned, custom)
r1, err := customState.HashTreeRoot(ctx) r1, err := customState.HashTreeRoot(ctx)
@@ -141,7 +143,8 @@ func BenchmarkStateClone_Manual(b *testing.B) {
require.NoError(b, err) require.NoError(b, err)
b.StartTimer() b.StartTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
_ = st.ToProto() _, err = st.ToProto()
require.NoError(b, err)
} }
} }

View File

@@ -99,9 +99,13 @@ func (e *epochBoundaryState) getByBlockRootLockFree(r [32]byte) (*rootStateInfo,
return nil, false, errNotRootStateInfo return nil, false, errNotRootStateInfo
} }
copiedState, err := s.state.Copy()
if err != nil {
return nil, false, err
}
return &rootStateInfo{ return &rootStateInfo{
root: r, root: r,
state: s.state.Copy(), state: copiedState,
}, true, nil }, true, nil
} }
@@ -138,9 +142,13 @@ func (e *epochBoundaryState) put(blockRoot [32]byte, s state.BeaconState) error
}); err != nil { }); err != nil {
return err return err
} }
copiedState, err := s.Copy()
if err != nil {
return err
}
if err := e.rootStateCache.AddIfNotPresent(&rootStateInfo{ if err := e.rootStateCache.AddIfNotPresent(&rootStateInfo{
root: blockRoot, root: blockRoot,
state: s.Copy(), state: copiedState,
}); err != nil { }); err != nil {
return err return err
} }

View File

@@ -35,7 +35,11 @@ func TestEpochBoundaryStateCache_CanSaveAndDelete(t *testing.T) {
got, exists, err = e.getByBlockRoot([32]byte{'a'}) got, exists, err = e.getByBlockRoot([32]byte{'a'})
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, true, exists, "Should exist") assert.Equal(t, true, exists, "Should exist")
assert.DeepSSZEqual(t, s.ToProtoUnsafe(), got.state.ToProtoUnsafe(), "Should have the same state") s1, err := s.ToProtoUnsafe()
require.NoError(t, err)
s2, err := got.state.ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, s2, s2, "Should have the same state")
got, exists, err = e.getBySlot(2) got, exists, err = e.getBySlot(2)
require.NoError(t, err) require.NoError(t, err)
@@ -45,7 +49,11 @@ func TestEpochBoundaryStateCache_CanSaveAndDelete(t *testing.T) {
got, exists, err = e.getBySlot(1) got, exists, err = e.getBySlot(1)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, true, exists, "Should exist") assert.Equal(t, true, exists, "Should exist")
assert.DeepSSZEqual(t, s.ToProtoUnsafe(), got.state.ToProtoUnsafe(), "Should have the same state") s1, err = s.ToProtoUnsafe()
require.NoError(t, err)
s2, err = got.state.ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, s1, s2, "Should have the same state")
require.NoError(t, e.delete(r)) require.NoError(t, e.delete(r))
got, exists, err = e.getByBlockRoot([32]byte{'b'}) got, exists, err = e.getByBlockRoot([32]byte{'b'})

View File

@@ -187,7 +187,10 @@ func (s *State) loadStateByRoot(ctx context.Context, blockRoot [32]byte) (state.
defer span.End() defer span.End()
// First, it checks if the state exists in hot state cache. // First, it checks if the state exists in hot state cache.
cachedState := s.hotStateCache.get(blockRoot) cachedState, err := s.hotStateCache.get(blockRoot)
if err != nil {
return nil, err
}
if cachedState != nil && !cachedState.IsNil() { if cachedState != nil && !cachedState.IsNil() {
return cachedState, nil return cachedState, nil
} }
@@ -248,8 +251,12 @@ func (s *State) latestAncestor(ctx context.Context, blockRoot [32]byte) (state.B
ctx, span := trace.StartSpan(ctx, "stateGen.latestAncestor") ctx, span := trace.StartSpan(ctx, "stateGen.latestAncestor")
defer span.End() defer span.End()
if s.isFinalizedRoot(blockRoot) && s.finalizedState() != nil { fState, err := s.finalizedState()
return s.finalizedState(), nil if err != nil {
return nil, err
}
if s.isFinalizedRoot(blockRoot) && fState != nil {
return fState, nil
} }
b, err := s.beaconDB.Block(ctx, blockRoot) b, err := s.beaconDB.Block(ctx, blockRoot)
@@ -279,12 +286,12 @@ func (s *State) latestAncestor(ctx context.Context, blockRoot [32]byte) (state.B
} }
// Does the state exist in the hot state cache. // Does the state exist in the hot state cache.
if s.hotStateCache.has(parentRoot) { if s.hotStateCache.has(parentRoot) {
return s.hotStateCache.get(parentRoot), nil return s.hotStateCache.get(parentRoot)
} }
// Does the state exist in finalized info cache. // Does the state exist in finalized info cache.
if s.isFinalizedRoot(parentRoot) { if s.isFinalizedRoot(parentRoot) {
return s.finalizedState(), nil return s.finalizedState()
} }
// Does the state exist in epoch boundary cache. // Does the state exist in epoch boundary cache.

View File

@@ -30,7 +30,11 @@ func TestStateByRoot_GenesisState(t *testing.T) {
require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, bRoot)) require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, bRoot))
loadedState, err := service.StateByRoot(ctx, params.BeaconConfig().ZeroHash) // Zero hash is genesis state root. loadedState, err := service.StateByRoot(ctx, params.BeaconConfig().ZeroHash) // Zero hash is genesis state root.
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, loadedState.ToProtoUnsafe(), beaconState.ToProtoUnsafe()) s1, err := loadedState.ToProtoUnsafe()
require.NoError(t, err)
s2, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2)
} }
func TestStateByRoot_ColdState(t *testing.T) { func TestStateByRoot_ColdState(t *testing.T) {
@@ -53,7 +57,11 @@ func TestStateByRoot_ColdState(t *testing.T) {
require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, bRoot)) require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, bRoot))
loadedState, err := service.StateByRoot(ctx, bRoot) loadedState, err := service.StateByRoot(ctx, bRoot)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, loadedState.ToProtoUnsafe(), beaconState.ToProtoUnsafe()) s1, err := loadedState.ToProtoUnsafe()
require.NoError(t, err)
s2, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2)
bal, err := service.BalancesByRoot(ctx, bRoot) bal, err := service.BalancesByRoot(ctx, bRoot)
require.NoError(t, err) require.NoError(t, err)
@@ -75,7 +83,11 @@ func TestStateByRootIfCachedNoCopy_HotState(t *testing.T) {
service.hotStateCache.put(r, beaconState) service.hotStateCache.put(r, beaconState)
loadedState := service.StateByRootIfCachedNoCopy(r) loadedState := service.StateByRootIfCachedNoCopy(r)
require.DeepSSZEqual(t, loadedState.ToProtoUnsafe(), beaconState.ToProtoUnsafe()) s1, err := loadedState.ToProtoUnsafe()
require.NoError(t, err)
s2, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2)
} }
func TestStateByRootIfCachedNoCopy_ColdState(t *testing.T) { func TestStateByRootIfCachedNoCopy_ColdState(t *testing.T) {
@@ -157,7 +169,11 @@ func TestStateByRoot_HotStateCached(t *testing.T) {
loadedState, err := service.StateByRoot(ctx, r) loadedState, err := service.StateByRoot(ctx, r)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, loadedState.ToProtoUnsafe(), beaconState.ToProtoUnsafe()) s1, err := loadedState.ToProtoUnsafe()
require.NoError(t, err)
s2, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s1, s2)
} }
func TestDeleteStateFromCaches(t *testing.T) { func TestDeleteStateFromCaches(t *testing.T) {
@@ -203,7 +219,11 @@ func TestStateByRoot_StateByRootInitialSync(t *testing.T) {
require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, bRoot)) require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, bRoot))
loadedState, err := service.StateByRootInitialSync(ctx, params.BeaconConfig().ZeroHash) // Zero hash is genesis state root. loadedState, err := service.StateByRootInitialSync(ctx, params.BeaconConfig().ZeroHash) // Zero hash is genesis state root.
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, loadedState.ToProtoUnsafe(), beaconState.ToProtoUnsafe()) s0, err := loadedState.ToProtoUnsafe()
require.NoError(t, err)
s1, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s0, s1)
} }
func TestStateByRootInitialSync_UseEpochStateCache(t *testing.T) { func TestStateByRootInitialSync_UseEpochStateCache(t *testing.T) {
@@ -237,7 +257,11 @@ func TestStateByRootInitialSync_UseCache(t *testing.T) {
loadedState, err := service.StateByRootInitialSync(ctx, r) loadedState, err := service.StateByRootInitialSync(ctx, r)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, loadedState.ToProtoUnsafe(), beaconState.ToProtoUnsafe()) s0, err := loadedState.ToProtoUnsafe()
require.NoError(t, err)
s1, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s0, s1)
if service.hotStateCache.has(r) { if service.hotStateCache.has(r) {
t.Error("Hot state cache was not invalidated") t.Error("Hot state cache was not invalidated")
} }
@@ -279,7 +303,11 @@ func TestLoadeStateByRoot_Cached(t *testing.T) {
// This tests where hot state was already cached. // This tests where hot state was already cached.
loadedState, err := service.loadStateByRoot(ctx, r) loadedState, err := service.loadStateByRoot(ctx, r)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, loadedState.ToProtoUnsafe(), beaconState.ToProtoUnsafe()) s0, err := loadedState.ToProtoUnsafe()
require.NoError(t, err)
s1, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s0, s1)
} }
func TestLoadeStateByRoot_FinalizedState(t *testing.T) { func TestLoadeStateByRoot_FinalizedState(t *testing.T) {
@@ -303,7 +331,11 @@ func TestLoadeStateByRoot_FinalizedState(t *testing.T) {
// This tests where hot state was already cached. // This tests where hot state was already cached.
loadedState, err := service.loadStateByRoot(ctx, gRoot) loadedState, err := service.loadStateByRoot(ctx, gRoot)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, loadedState.ToProtoUnsafe(), beaconState.ToProtoUnsafe()) s0, err := loadedState.ToProtoUnsafe()
require.NoError(t, err)
s1, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
require.DeepSSZEqual(t, s0, s1)
} }
func TestLoadeStateByRoot_EpochBoundaryStateCanProcess(t *testing.T) { func TestLoadeStateByRoot_EpochBoundaryStateCanProcess(t *testing.T) {

View File

@@ -39,21 +39,28 @@ func newHotStateCache() *hotStateCache {
// Get returns a cached response via input block root, if any. // Get returns a cached response via input block root, if any.
// The response is copied by default. // The response is copied by default.
func (c *hotStateCache) get(blockRoot [32]byte) state.BeaconState { func (c *hotStateCache) get(blockRoot [32]byte) (state.BeaconState, error) {
c.lock.RLock() c.lock.RLock()
defer c.lock.RUnlock() defer c.lock.RUnlock()
item, exists := c.cache.Get(blockRoot) item, exists := c.cache.Get(blockRoot)
copiedState, err := item.(state.BeaconState).Copy()
if err != nil {
return nil, err
}
if exists && item != nil { if exists && item != nil {
hotStateCacheHit.Inc() hotStateCacheHit.Inc()
return item.(state.BeaconState).Copy() return copiedState, nil
} }
hotStateCacheMiss.Inc() hotStateCacheMiss.Inc()
return nil return nil, nil
} }
func (c *hotStateCache) ByBlockRoot(r [32]byte) (state.BeaconState, error) { func (c *hotStateCache) ByBlockRoot(r [32]byte) (state.BeaconState, error) {
st := c.get(r) st, err := c.get(r)
if err != nil {
return nil, err
}
if st == nil { if st == nil {
return nil, ErrNotInCache return nil, ErrNotInCache
} }

View File

@@ -13,11 +13,12 @@ import (
func TestHotStateCache_RoundTrip(t *testing.T) { func TestHotStateCache_RoundTrip(t *testing.T) {
c := newHotStateCache() c := newHotStateCache()
root := [32]byte{'A'} root := [32]byte{'A'}
s := c.get(root) s, err := c.get(root)
require.NoError(t, err)
assert.Equal(t, state.BeaconState(nil), s) assert.Equal(t, state.BeaconState(nil), s)
assert.Equal(t, false, c.has(root), "Empty cache has an object") assert.Equal(t, false, c.has(root), "Empty cache has an object")
s, err := state_native.InitializeFromProtoPhase0(&ethpb.BeaconState{ s, err = state_native.InitializeFromProtoPhase0(&ethpb.BeaconState{
Slot: 10, Slot: 10,
}) })
require.NoError(t, err) require.NoError(t, err)
@@ -25,9 +26,14 @@ func TestHotStateCache_RoundTrip(t *testing.T) {
c.put(root, s) c.put(root, s)
assert.Equal(t, true, c.has(root), "Empty cache does not have an object") assert.Equal(t, true, c.has(root), "Empty cache does not have an object")
res := c.get(root) res, err := c.get(root)
require.NoError(t, err)
assert.NotNil(t, s) assert.NotNil(t, s)
assert.DeepEqual(t, res.ToProto(), s.ToProto(), "Expected equal protos to return from cache") resProto, err := res.ToProto()
require.NoError(t, err)
sProto, err := s.ToProto()
require.NoError(t, err)
assert.DeepEqual(t, resProto, sProto, "Expected equal protos to return from cache")
c.delete(root) c.delete(root)
assert.Equal(t, false, c.has(root), "Cache not supposed to have the object") assert.Equal(t, false, c.has(root), "Cache not supposed to have the object")

View File

@@ -115,7 +115,9 @@ func (s *State) MigrateToCold(ctx context.Context, fRoot [32]byte) error {
return err return err
} }
if ok { if ok {
s.SaveFinalizedState(fSlot, fRoot, fInfo.state) if err := s.SaveFinalizedState(fSlot, fRoot, fInfo.state); err != nil {
return err
}
} }
return nil return nil

View File

@@ -53,7 +53,11 @@ func TestMigrateToCold_HappyPath(t *testing.T) {
gotState, err := service.beaconDB.State(ctx, fRoot) gotState, err := service.beaconDB.State(ctx, fRoot)
require.NoError(t, err) require.NoError(t, err)
assert.DeepSSZEqual(t, beaconState.ToProtoUnsafe(), gotState.ToProtoUnsafe(), "Did not save state") s1, err := beaconState.ToProtoUnsafe()
require.NoError(t, err)
s2, err := gotState.ToProtoUnsafe()
require.NoError(t, err)
assert.DeepSSZEqual(t, s1, s2, "Did not save state")
gotRoot := service.beaconDB.ArchivedPointRoot(ctx, stateSlot/service.slotsPerArchivedPoint) gotRoot := service.beaconDB.ArchivedPointRoot(ctx, stateSlot/service.slotsPerArchivedPoint)
assert.Equal(t, fRoot, gotRoot, "Did not save archived root") assert.Equal(t, fRoot, gotRoot, "Did not save archived root")
lastIndex, err := service.beaconDB.LastArchivedSlot(ctx) lastIndex, err := service.beaconDB.LastArchivedSlot(ctx)
@@ -145,7 +149,8 @@ func TestMigrateToCold_ParallelCalls(t *testing.T) {
service := New(beaconDB, doublylinkedtree.New()) service := New(beaconDB, doublylinkedtree.New())
service.slotsPerArchivedPoint = 1 service.slotsPerArchivedPoint = 1
beaconState, pks := util.DeterministicGenesisState(t, 32) beaconState, pks := util.DeterministicGenesisState(t, 32)
genState := beaconState.Copy() genState, err := beaconState.Copy()
require.NoError(t, err)
genesisStateRoot, err := beaconState.HashTreeRoot(ctx) genesisStateRoot, err := beaconState.HashTreeRoot(ctx)
require.NoError(t, err) require.NoError(t, err)
genesis := blocks.NewGenesisBlock(genesisStateRoot[:]) genesis := blocks.NewGenesisBlock(genesisStateRoot[:])

View File

@@ -32,7 +32,7 @@ func (_ *MockStateManager) Resume(_ context.Context, _ state.BeaconState) (state
} }
// SaveFinalizedState -- // SaveFinalizedState --
func (_ *MockStateManager) SaveFinalizedState(_ types.Slot, _ [32]byte, _ state.BeaconState) { func (_ *MockStateManager) SaveFinalizedState(_ types.Slot, _ [32]byte, _ state.BeaconState) error {
panic("implement me") panic("implement me")
} }

View File

@@ -140,7 +140,7 @@ func (m *mockHistory) Block(_ context.Context, blockRoot [32]byte) (interfaces.S
func (m *mockHistory) StateOrError(_ context.Context, blockRoot [32]byte) (state.BeaconState, error) { func (m *mockHistory) StateOrError(_ context.Context, blockRoot [32]byte) (state.BeaconState, error) {
if s, ok := m.states[blockRoot]; ok { if s, ok := m.states[blockRoot]; ok {
return s.Copy(), nil return s.Copy()
} }
return nil, db.ErrNotFoundState return nil, db.ErrNotFoundState
} }
@@ -213,9 +213,12 @@ func newMockHistory(t *testing.T, hist []mockHistorySpec, current types.Slot) *m
// add genesis block as canonical // add genesis block as canonical
mh.addBlock(pr, gb, true) mh.addBlock(pr, gb, true)
// add genesis state, indexed by unapplied genesis block - genesis block is never really processed... // add genesis state, indexed by unapplied genesis block - genesis block is never really processed...
mh.addState(pr, gs.Copy()) s0, err := gs.Copy()
require.NoError(t, err)
mh.addState(pr, s0)
ps := gs.Copy() ps, err := gs.Copy()
require.NoError(t, err)
for _, spec := range hist { for _, spec := range hist {
// call process_slots and process_block separately, because process_slots updates values used in randao mix // call process_slots and process_block separately, because process_slots updates values used in randao mix
// which influences proposer_index. // which influences proposer_index.
@@ -259,7 +262,8 @@ func newMockHistory(t *testing.T, hist []mockHistorySpec, current types.Slot) *m
mh.hideState(pr, s) mh.hideState(pr, s)
} }
mh.addBlock(pr, b, spec.canonicalBlock) mh.addBlock(pr, b, spec.canonicalBlock)
ps = s.Copy() ps, err = s.Copy()
require.NoError(t, err)
} }
require.NoError(t, mh.validateRoots()) require.NoError(t, mh.validateRoots())

View File

@@ -449,7 +449,9 @@ func tree1(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][32]byte,
if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil { if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil {
return nil, nil, err return nil, nil, err
} }
if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { copied, err := st.Copy()
require.NoError(t, err)
if err := beaconDB.SaveState(context.Background(), copied, bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
return nil, nil, err return nil, nil, err
} }
returnedBlocks = append(returnedBlocks, beaconBlock) returnedBlocks = append(returnedBlocks, beaconBlock)
@@ -532,7 +534,9 @@ func tree2(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][32]byte,
if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil { if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil {
return nil, nil, err return nil, nil, err
} }
if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { copied, err := st.Copy()
require.NoError(t, err)
if err := beaconDB.SaveState(context.Background(), copied, bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
return nil, nil, err return nil, nil, err
} }
returnedBlocks = append(returnedBlocks, beaconBlock) returnedBlocks = append(returnedBlocks, beaconBlock)
@@ -608,7 +612,9 @@ func tree3(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][32]byte,
if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil { if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil {
return nil, nil, err return nil, nil, err
} }
if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { copied, err := st.Copy()
require.NoError(t, err)
if err := beaconDB.SaveState(context.Background(), copied, bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
return nil, nil, err return nil, nil, err
} }
returnedBlocks = append(returnedBlocks, beaconBlock) returnedBlocks = append(returnedBlocks, beaconBlock)
@@ -678,7 +684,9 @@ func tree4(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][32]byte,
if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil { if err := beaconDB.SaveBlock(context.Background(), wsb); err != nil {
return nil, nil, err return nil, nil, err
} }
if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil { copied, err := st.Copy()
require.NoError(t, err)
if err := beaconDB.SaveState(context.Background(), copied, bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
return nil, nil, err return nil, nil, err
} }
returnedBlocks = append(returnedBlocks, beaconBlock) returnedBlocks = append(returnedBlocks, beaconBlock)

View File

@@ -30,7 +30,7 @@ type StateManager interface {
DeleteStateFromCaches(ctx context.Context, blockRoot [32]byte) error DeleteStateFromCaches(ctx context.Context, blockRoot [32]byte) error
ForceCheckpoint(ctx context.Context, root []byte) error ForceCheckpoint(ctx context.Context, root []byte) error
SaveState(ctx context.Context, blockRoot [32]byte, st state.BeaconState) error SaveState(ctx context.Context, blockRoot [32]byte, st state.BeaconState) error
SaveFinalizedState(fSlot types.Slot, fRoot [32]byte, fState state.BeaconState) SaveFinalizedState(fSlot types.Slot, fRoot [32]byte, fState state.BeaconState) error
MigrateToCold(ctx context.Context, fRoot [32]byte) error MigrateToCold(ctx context.Context, fRoot [32]byte) error
StateByRoot(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error) StateByRoot(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
BalancesByRoot(context.Context, [32]byte) ([]uint64, error) BalancesByRoot(context.Context, [32]byte) ([]uint64, error)
@@ -126,7 +126,11 @@ func (s *State) Resume(ctx context.Context, fState state.BeaconState) (state.Bea
} }
}() }()
s.finalizedInfo = &finalizedInfo{slot: fState.Slot(), root: fRoot, state: fState.Copy()} copiedSt, err := fState.Copy()
if err != nil {
return nil, err
}
s.finalizedInfo = &finalizedInfo{slot: fState.Slot(), root: fRoot, state: copiedSt}
return fState, nil return fState, nil
} }
@@ -134,12 +138,17 @@ func (s *State) Resume(ctx context.Context, fState state.BeaconState) (state.Bea
// SaveFinalizedState saves the finalized slot, root and state into memory to be used by state gen service. // SaveFinalizedState saves the finalized slot, root and state into memory to be used by state gen service.
// This used for migration at the correct start slot and used for hot state play back to ensure // This used for migration at the correct start slot and used for hot state play back to ensure
// lower bound to start is always at the last finalized state. // lower bound to start is always at the last finalized state.
func (s *State) SaveFinalizedState(fSlot types.Slot, fRoot [32]byte, fState state.BeaconState) { func (s *State) SaveFinalizedState(fSlot types.Slot, fRoot [32]byte, fState state.BeaconState) error {
s.finalizedInfo.lock.Lock() s.finalizedInfo.lock.Lock()
defer s.finalizedInfo.lock.Unlock() defer s.finalizedInfo.lock.Unlock()
s.finalizedInfo.root = fRoot s.finalizedInfo.root = fRoot
s.finalizedInfo.state = fState.Copy() copiedState, err := fState.Copy()
if err != nil {
return err
}
s.finalizedInfo.state = copiedState
s.finalizedInfo.slot = fSlot s.finalizedInfo.slot = fSlot
return nil
} }
// Returns true if input root equals to cached finalized root. // Returns true if input root equals to cached finalized root.
@@ -150,7 +159,7 @@ func (s *State) isFinalizedRoot(r [32]byte) bool {
} }
// Returns the cached and copied finalized state. // Returns the cached and copied finalized state.
func (s *State) finalizedState() state.BeaconState { func (s *State) finalizedState() (state.BeaconState, error) {
s.finalizedInfo.lock.RLock() s.finalizedInfo.lock.RLock()
defer s.finalizedInfo.lock.RUnlock() defer s.finalizedInfo.lock.RUnlock()
return s.finalizedInfo.state.Copy() return s.finalizedInfo.state.Copy()

View File

@@ -141,7 +141,8 @@ func VerifyBeaconStateValidatorByPubkey(t *testing.T, factory getState) {
key1 := keyCreator([]byte{'C'}) key1 := keyCreator([]byte{'C'})
key2 := keyCreator([]byte{'D'}) key2 := keyCreator([]byte{'D'})
assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key[:]})) assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key[:]}))
_ = b.Copy() _, err := b.Copy()
require.NoError(t, err)
assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key1[:]})) assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key1[:]}))
assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key2[:]})) assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key2[:]}))
}, },
@@ -155,7 +156,8 @@ func VerifyBeaconStateValidatorByPubkey(t *testing.T, factory getState) {
key2 := keyCreator([]byte{'D'}) key2 := keyCreator([]byte{'D'})
assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key1[:]})) assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key1[:]}))
assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key2[:]})) assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key2[:]}))
n := b.Copy() n, err := b.Copy()
require.NoError(t, err)
// Append to another state // Append to another state
assert.NoError(t, n.AppendValidator(&ethpb.Validator{PublicKey: key[:]})) assert.NoError(t, n.AppendValidator(&ethpb.Validator{PublicKey: key[:]}))
@@ -168,7 +170,8 @@ func VerifyBeaconStateValidatorByPubkey(t *testing.T, factory getState) {
modifyFunc: func(b state.BeaconState, key [fieldparams.BLSPubkeyLength]byte) { modifyFunc: func(b state.BeaconState, key [fieldparams.BLSPubkeyLength]byte) {
key1 := keyCreator([]byte{'C'}) key1 := keyCreator([]byte{'C'})
assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key1[:]})) assert.NoError(t, b.AppendValidator(&ethpb.Validator{PublicKey: key1[:]}))
n := b.Copy() n, err := b.Copy()
require.NoError(t, err)
// Append to another state // Append to another state
assert.NoError(t, n.AppendValidator(&ethpb.Validator{PublicKey: key[:]})) assert.NoError(t, n.AppendValidator(&ethpb.Validator{PublicKey: key[:]}))

View File

@@ -724,7 +724,8 @@ func TestService_ProcessPendingBlockOnCorrectSlot(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -802,7 +803,8 @@ func TestService_ProcessBadPendingBlocks(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -648,7 +648,8 @@ func TestStatusRPCRequest_FinalizedBlockSkippedSlots(t *testing.T) {
expectedFinalizedEpoch := tt.expectedFinalizedEpoch expectedFinalizedEpoch := tt.expectedFinalizedEpoch
headSlot := tt.headSlot headSlot := tt.headSlot
nState := bState.Copy() nState, err := bState.Copy()
require.NoError(t, err)
// Set up a head state with data we expect. // Set up a head state with data we expect.
head := blocksTillHead[len(blocksTillHead)-1] head := blocksTillHead[len(blocksTillHead)-1]
headRoot, err := head.Block().HashTreeRoot() headRoot, err := head.Block().HashTreeRoot()

View File

@@ -41,7 +41,8 @@ func FuzzValidateBeaconBlockPubSub_Phase0(f *testing.F) {
require.NoError(f, err) require.NoError(f, err)
require.NoError(f, db.SaveState(ctx, beaconState, bRoot)) require.NoError(f, db.SaveState(ctx, beaconState, bRoot))
require.NoError(f, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(f, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(f, err)
require.NoError(f, copied.SetSlot(1)) require.NoError(f, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(f, err) require.NoError(f, err)
@@ -122,7 +123,8 @@ func FuzzValidateBeaconBlockPubSub_Altair(f *testing.F) {
require.NoError(f, err) require.NoError(f, err)
require.NoError(f, db.SaveState(ctx, beaconState, bRoot)) require.NoError(f, db.SaveState(ctx, beaconState, bRoot))
require.NoError(f, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(f, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(f, err)
require.NoError(f, copied.SetSlot(1)) require.NoError(f, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(f, err) require.NoError(f, err)
@@ -203,7 +205,8 @@ func FuzzValidateBeaconBlockPubSub_Bellatrix(f *testing.F) {
require.NoError(f, err) require.NoError(f, err)
require.NoError(f, db.SaveState(ctx, beaconState, bRoot)) require.NoError(f, db.SaveState(ctx, beaconState, bRoot))
require.NoError(f, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(f, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(f, err)
require.NoError(f, copied.SetSlot(1)) require.NoError(f, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(f, err) require.NoError(f, err)

View File

@@ -53,7 +53,8 @@ func TestValidateBeaconBlockPubSub_InvalidSignature(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -157,7 +158,8 @@ func TestValidateBeaconBlockPubSub_CanRecoverStateSummary(t *testing.T) {
bRoot, err := parentBlock.Block.HashTreeRoot() bRoot, err := parentBlock.Block.HashTreeRoot()
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -221,7 +223,8 @@ func TestValidateBeaconBlockPubSub_IsInCache(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(context.Background(), copied) proposerIdx, err := helpers.BeaconProposerIndex(context.Background(), copied)
require.NoError(t, err) require.NoError(t, err)
@@ -287,7 +290,8 @@ func TestValidateBeaconBlockPubSub_ValidProposerSignature(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -352,7 +356,8 @@ func TestValidateBeaconBlockPubSub_WithLookahead(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
// The next block is only 1 epoch ahead so as to not induce a new seed. // The next block is only 1 epoch ahead so as to not induce a new seed.
blkSlot := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(coreTime.NextEpoch(copied))) blkSlot := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(coreTime.NextEpoch(copied)))
copied, err = transition.ProcessSlots(context.Background(), copied, blkSlot) copied, err = transition.ProcessSlots(context.Background(), copied, blkSlot)
@@ -420,7 +425,8 @@ func TestValidateBeaconBlockPubSub_AdvanceEpochsForState(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
// The next block is at least 2 epochs ahead to induce shuffling and a new seed. // The next block is at least 2 epochs ahead to induce shuffling and a new seed.
blkSlot := params.BeaconConfig().SlotsPerEpoch * 2 blkSlot := params.BeaconConfig().SlotsPerEpoch * 2
copied, err = transition.ProcessSlots(context.Background(), copied, blkSlot) copied, err = transition.ProcessSlots(context.Background(), copied, blkSlot)
@@ -529,7 +535,8 @@ func TestValidateBeaconBlockPubSub_IgnoreAndQueueBlocksFromNearFuture(t *testing
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -819,7 +826,8 @@ func TestValidateBeaconBlockPubSub_ParentNotFinalizedDescendant(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -883,7 +891,8 @@ func TestValidateBeaconBlockPubSub_InvalidParentBlock(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -981,7 +990,8 @@ func TestValidateBeaconBlockPubSub_RejectBlocksFromBadParent(t *testing.T) {
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
// The next block is at least 2 epochs ahead to induce shuffling and a new seed. // The next block is at least 2 epochs ahead to induce shuffling and a new seed.
blkSlot := params.BeaconConfig().SlotsPerEpoch * 2 blkSlot := params.BeaconConfig().SlotsPerEpoch * 2
copied, err = transition.ProcessSlots(context.Background(), copied, blkSlot) copied, err = transition.ProcessSlots(context.Background(), copied, blkSlot)
@@ -1090,7 +1100,8 @@ func TestValidateBeaconBlockPubSub_ValidExecutionPayload(t *testing.T) {
require.NoError(t, beaconState.SetGenesisTime(uint64(presentTime))) require.NoError(t, beaconState.SetGenesisTime(uint64(presentTime)))
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -1161,7 +1172,8 @@ func TestValidateBeaconBlockPubSub_InvalidPayloadTimestamp(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -1265,7 +1277,8 @@ func Test_validateBellatrixBeaconBlockParentValidation(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)
@@ -1321,7 +1334,8 @@ func Test_validateBeaconBlockProcessingWhenParentIsOptimistic(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]})) require.NoError(t, db.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bRoot[:]}))
copied := beaconState.Copy() copied, err := beaconState.Copy()
require.NoError(t, err)
require.NoError(t, copied.SetSlot(1)) require.NoError(t, copied.SetSlot(1))
proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -1035,7 +1035,8 @@ func fillUpBlocksAndState(ctx context.Context, t *testing.T, beaconDB db.Databas
assert.NoError(t, gs.SetCurrentSyncCommittee(sCom)) assert.NoError(t, gs.SetCurrentSyncCommittee(sCom))
assert.NoError(t, beaconDB.SaveGenesisData(context.Background(), gs)) assert.NoError(t, beaconDB.SaveGenesisData(context.Background(), gs))
testState := gs.Copy() testState, err := gs.Copy()
assert.NoError(t, err)
hRoot := [32]byte{} hRoot := [32]byte{}
for i := types.Slot(1); i <= params.BeaconConfig().SlotsPerEpoch; i++ { for i := types.Slot(1); i <= params.BeaconConfig().SlotsPerEpoch; i++ {
blk, err := util.GenerateFullBlockAltair(testState, keys, util.DefaultBlockGenConfig(), i) blk, err := util.GenerateFullBlockAltair(testState, keys, util.DefaultBlockGenConfig(), i)

View File

@@ -41,7 +41,9 @@ go_test(
"//config/fieldparams:go_default_library", "//config/fieldparams:go_default_library",
"//consensus-types/interfaces:go_default_library", "//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library", "//consensus-types/primitives:go_default_library",
"//crypto/hash:go_default_library",
"//encoding/bytesutil:go_default_library", "//encoding/bytesutil:go_default_library",
"//encoding/ssz:go_default_library",
"//proto/engine/v1:go_default_library", "//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library", "//proto/prysm/v1alpha1/validator-client:go_default_library",

View File

@@ -142,7 +142,11 @@ func (e executionPayload) Transactions() ([][]byte, error) {
// TransactionsRoot -- // TransactionsRoot --
func (e executionPayload) TransactionsRoot() ([]byte, error) { func (e executionPayload) TransactionsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter txRoot, err := ssz.TransactionsRoot(e.p.Transactions)
if err != nil {
return nil, err
}
return txRoot[:], nil
} }
// Withdrawals -- // Withdrawals --
@@ -324,6 +328,104 @@ func PayloadToHeader(payload interfaces.ExecutionData) (*enginev1.ExecutionPaylo
}, nil }, nil
} }
// CopyExecutionDataHeader copies only the execution header fields into a payload header interface.
func CopyExecutionDataHeader(header interfaces.ExecutionDataHeader) (interfaces.ExecutionDataHeader, error) {
switch payload := header.Proto().(type) {
case *enginev1.ExecutionPayload:
txRoot, err := ssz.TransactionsRoot(payload.Transactions)
if err != nil {
return nil, err
}
h := &enginev1.ExecutionPayloadHeader{
ParentHash: bytesutil.SafeCopyBytes(payload.ParentHash),
FeeRecipient: bytesutil.SafeCopyBytes(payload.FeeRecipient),
StateRoot: bytesutil.SafeCopyBytes(payload.StateRoot),
ReceiptsRoot: bytesutil.SafeCopyBytes(payload.ReceiptsRoot),
LogsBloom: bytesutil.SafeCopyBytes(payload.LogsBloom),
PrevRandao: bytesutil.SafeCopyBytes(payload.PrevRandao),
BlockNumber: payload.BlockNumber,
GasLimit: payload.GasLimit,
GasUsed: payload.GasUsed,
Timestamp: payload.Timestamp,
ExtraData: bytesutil.SafeCopyBytes(payload.ExtraData),
BaseFeePerGas: bytesutil.SafeCopyBytes(payload.BaseFeePerGas),
BlockHash: bytesutil.SafeCopyBytes(payload.BlockHash),
TransactionsRoot: txRoot[:],
}
return WrappedExecutionPayloadHeader(h)
case *enginev1.ExecutionPayloadHeader:
h := &enginev1.ExecutionPayloadHeader{
ParentHash: bytesutil.SafeCopyBytes(payload.ParentHash),
FeeRecipient: bytesutil.SafeCopyBytes(payload.FeeRecipient),
StateRoot: bytesutil.SafeCopyBytes(payload.StateRoot),
ReceiptsRoot: bytesutil.SafeCopyBytes(payload.ReceiptsRoot),
LogsBloom: bytesutil.SafeCopyBytes(payload.LogsBloom),
PrevRandao: bytesutil.SafeCopyBytes(payload.PrevRandao),
BlockNumber: payload.BlockNumber,
GasLimit: payload.GasLimit,
GasUsed: payload.GasUsed,
Timestamp: payload.Timestamp,
ExtraData: bytesutil.SafeCopyBytes(payload.ExtraData),
BaseFeePerGas: bytesutil.SafeCopyBytes(payload.BaseFeePerGas),
BlockHash: bytesutil.SafeCopyBytes(payload.BlockHash),
TransactionsRoot: bytesutil.SafeCopyBytes(payload.TransactionsRoot),
}
return WrappedExecutionPayloadHeader(h)
case *enginev1.ExecutionPayloadCapella:
txRoot, err := ssz.TransactionsRoot(payload.Transactions)
if err != nil {
return nil, err
}
var withdrawalsRoot []byte
if len(payload.Withdrawals) != 0 {
root, err := ssz.WithdrawalSliceRoot(hash.CustomSHA256Hasher(), payload.Withdrawals, fieldparams.MaxWithdrawalsPerPayload)
if err != nil {
return nil, err
}
withdrawalsRoot = root[:]
}
h := &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: bytesutil.SafeCopyBytes(payload.ParentHash),
FeeRecipient: bytesutil.SafeCopyBytes(payload.FeeRecipient),
StateRoot: bytesutil.SafeCopyBytes(payload.StateRoot),
ReceiptsRoot: bytesutil.SafeCopyBytes(payload.ReceiptsRoot),
LogsBloom: bytesutil.SafeCopyBytes(payload.LogsBloom),
PrevRandao: bytesutil.SafeCopyBytes(payload.PrevRandao),
BlockNumber: payload.BlockNumber,
GasLimit: payload.GasLimit,
GasUsed: payload.GasUsed,
Timestamp: payload.Timestamp,
ExtraData: bytesutil.SafeCopyBytes(payload.ExtraData),
BaseFeePerGas: bytesutil.SafeCopyBytes(payload.BaseFeePerGas),
BlockHash: bytesutil.SafeCopyBytes(payload.BlockHash),
TransactionsRoot: txRoot[:],
WithdrawalsRoot: withdrawalsRoot,
}
return WrappedExecutionPayloadHeaderCapella(h)
case *enginev1.ExecutionPayloadHeaderCapella:
h := &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: bytesutil.SafeCopyBytes(payload.ParentHash),
FeeRecipient: bytesutil.SafeCopyBytes(payload.FeeRecipient),
StateRoot: bytesutil.SafeCopyBytes(payload.StateRoot),
ReceiptsRoot: bytesutil.SafeCopyBytes(payload.ReceiptsRoot),
LogsBloom: bytesutil.SafeCopyBytes(payload.LogsBloom),
PrevRandao: bytesutil.SafeCopyBytes(payload.PrevRandao),
BlockNumber: payload.BlockNumber,
GasLimit: payload.GasLimit,
GasUsed: payload.GasUsed,
Timestamp: payload.Timestamp,
ExtraData: bytesutil.SafeCopyBytes(payload.ExtraData),
BaseFeePerGas: bytesutil.SafeCopyBytes(payload.BaseFeePerGas),
BlockHash: bytesutil.SafeCopyBytes(payload.BlockHash),
TransactionsRoot: bytesutil.SafeCopyBytes(payload.TransactionsRoot),
WithdrawalsRoot: bytesutil.SafeCopyBytes(payload.WithdrawalsRoot),
}
return WrappedExecutionPayloadHeaderCapella(h)
default:
return nil, errUnsupportedExecutionPayload
}
}
// executionPayloadCapella is a convenience wrapper around a beacon block body's execution payload data structure // executionPayloadCapella is a convenience wrapper around a beacon block body's execution payload data structure
// This wrapper allows us to conform to a common interface so that beacon // This wrapper allows us to conform to a common interface so that beacon
// blocks for future forks can also be applied across Prysm without issues. // blocks for future forks can also be applied across Prysm without issues.
@@ -452,7 +554,11 @@ func (e executionPayloadCapella) Transactions() ([][]byte, error) {
// TransactionsRoot -- // TransactionsRoot --
func (e executionPayloadCapella) TransactionsRoot() ([]byte, error) { func (e executionPayloadCapella) TransactionsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter txRoot, err := ssz.TransactionsRoot(e.p.Transactions)
if err != nil {
return nil, err
}
return txRoot[:], nil
} }
// Withdrawals -- // Withdrawals --
@@ -647,6 +753,9 @@ func PayloadToHeaderCapella(payload interfaces.ExecutionData) (*enginev1.Executi
// IsEmptyExecutionData checks if an execution data is empty underneath. If a single field has // IsEmptyExecutionData checks if an execution data is empty underneath. If a single field has
// a non-zero value, this function will return false. // a non-zero value, this function will return false.
func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) { func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) {
if _, ok := data.Proto().(*enginev1.ExecutionPayloadCapella); ok {
return false, nil
}
if !bytes.Equal(data.ParentHash(), make([]byte, fieldparams.RootLength)) { if !bytes.Equal(data.ParentHash(), make([]byte, fieldparams.RootLength)) {
return false, nil return false, nil
} }
@@ -700,3 +809,60 @@ func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) {
} }
return true, nil return true, nil
} }
// IsEmptyExecutionDataHeader checks if an execution data header is empty underneath. If a single
// field has a non-zero value, this function will return false.
func IsEmptyExecutionDataHeader(data interfaces.ExecutionDataHeader) (bool, error) {
if _, ok := data.Proto().(*enginev1.ExecutionPayloadHeaderCapella); ok {
return false, nil
}
if !bytes.Equal(data.ParentHash(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.FeeRecipient(), make([]byte, fieldparams.FeeRecipientLength)) {
return false, nil
}
if !bytes.Equal(data.StateRoot(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.ReceiptsRoot(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.LogsBloom(), make([]byte, fieldparams.LogsBloomLength)) {
return false, nil
}
if !bytes.Equal(data.PrevRandao(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.BaseFeePerGas(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.BlockHash(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if len(data.ExtraData()) != 0 {
return false, nil
}
if data.BlockNumber() != 0 {
return false, nil
}
if data.GasLimit() != 0 {
return false, nil
}
if data.GasUsed() != 0 {
return false, nil
}
if data.Timestamp() != 0 {
return false, nil
}
txRoot, err := data.TransactionsRoot()
if err != nil {
return false, err
}
if !bytes.Equal(txRoot, make([]byte, fieldparams.RootLength)) {
return false, nil
}
return true, nil
}

View File

@@ -6,6 +6,8 @@ import (
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
"github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v3/crypto/hash"
"github.com/prysmaticlabs/prysm/v3/encoding/ssz"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1" enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
"github.com/prysmaticlabs/prysm/v3/testing/assert" "github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require" "github.com/prysmaticlabs/prysm/v3/testing/require"
@@ -281,3 +283,116 @@ func createWrappedPayloadHeaderCapella(t testing.TB) interfaces.ExecutionData {
require.NoError(t, err) require.NoError(t, err)
return payload return payload
} }
func TestCopyExecutionDataHeader(t *testing.T) {
data := &enginev1.ExecutionPayloadHeader{GasUsed: 54}
wsb, err := blocks.WrappedExecutionPayloadHeader(data)
require.NoError(t, err)
headerCopy, err := blocks.CopyExecutionDataHeader(wsb)
require.NoError(t, err)
assert.DeepEqual(t, data, headerCopy.Proto())
}
func TestCopyExecutionDataHeaderFromFullPayload(t *testing.T) {
data := &enginev1.ExecutionPayload{GasUsed: 54}
wsb, err := blocks.WrappedExecutionPayload(data)
require.NoError(t, err)
headerCopy, err := blocks.CopyExecutionDataHeader(wsb)
require.NoError(t, err)
txRoot, err := ssz.TransactionsRoot(nil)
require.NoError(t, err)
assert.DeepSSZEqual(t, &enginev1.ExecutionPayloadHeader{GasUsed: 54, TransactionsRoot: txRoot[:]}, headerCopy.Proto().(*enginev1.ExecutionPayloadHeader))
}
func TestCopyExecutionDataHeaderCapella(t *testing.T) {
data := &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: []byte("parenthash"),
FeeRecipient: []byte("feerecipient"),
StateRoot: []byte("stateroot"),
ReceiptsRoot: []byte("receiptsroot"),
LogsBloom: []byte("logsbloom"),
PrevRandao: []byte("prevrandao"),
BlockNumber: 11,
GasLimit: 22,
GasUsed: 33,
Timestamp: 44,
ExtraData: []byte("extradata"),
BaseFeePerGas: []byte("basefeepergas"),
BlockHash: []byte("blockhash"),
TransactionsRoot: []byte("transactionsroot"),
WithdrawalsRoot: []byte("withdrawalsroot"),
}
payload, err := blocks.WrappedExecutionPayloadHeaderCapella(data)
require.NoError(t, err)
headerCopy, err := blocks.CopyExecutionDataHeader(payload)
require.NoError(t, err)
assert.DeepEqual(t, data, headerCopy.Proto())
txRoot, err := headerCopy.TransactionsRoot()
require.NoError(t, err)
require.DeepEqual(t, txRoot, data.TransactionsRoot)
wrRoot, err := headerCopy.WithdrawalsRoot()
require.NoError(t, err)
require.DeepEqual(t, wrRoot, data.WithdrawalsRoot)
}
func TestCopyExecutionDataHeaderCapellaFromFullPayload(t *testing.T) {
data := &enginev1.ExecutionPayloadCapella{
ParentHash: []byte("parenthash"),
FeeRecipient: []byte("feerecipient"),
StateRoot: []byte("stateroot"),
ReceiptsRoot: []byte("receiptsroot"),
LogsBloom: []byte("logsbloom"),
PrevRandao: []byte("prevrandao"),
BlockNumber: 11,
GasLimit: 22,
GasUsed: 33,
Timestamp: 44,
ExtraData: []byte("extradata"),
BaseFeePerGas: []byte("basefeepergas"),
BlockHash: []byte("blockhash"),
Transactions: [][]byte{[]byte("transaction")},
Withdrawals: []*enginev1.Withdrawal{{
WithdrawalIndex: 55,
ValidatorIndex: 66,
ExecutionAddress: []byte("executionaddress"),
Amount: 77,
}},
}
payload, err := blocks.WrappedExecutionPayloadCapella(data)
require.NoError(t, err)
headerCopy, err := blocks.CopyExecutionDataHeader(payload)
require.NoError(t, err)
txRoot, err := ssz.TransactionsRoot(data.Transactions)
require.NoError(t, err)
wRoot, err := ssz.WithdrawalSliceRoot(hash.CustomSHA256Hasher(), data.Withdrawals, fieldparams.MaxWithdrawalsPerPayload)
require.NoError(t, err)
dataHeader := &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: data.ParentHash,
FeeRecipient: data.FeeRecipient,
StateRoot: data.StateRoot,
ReceiptsRoot: data.ReceiptsRoot,
LogsBloom: data.LogsBloom,
PrevRandao: data.PrevRandao,
BlockNumber: data.BlockNumber,
GasLimit: data.GasLimit,
GasUsed: data.GasUsed,
Timestamp: data.Timestamp,
ExtraData: data.ExtraData,
BaseFeePerGas: data.BaseFeePerGas,
BlockHash: data.BlockHash,
TransactionsRoot: txRoot[:],
WithdrawalsRoot: wRoot[:],
}
assert.DeepSSZEqual(t, dataHeader, headerCopy.Proto())
}

View File

@@ -33,11 +33,12 @@ var (
// ErrUnsupportedVersion for beacon block methods. // ErrUnsupportedVersion for beacon block methods.
ErrUnsupportedVersion = errors.New("unsupported beacon block version") ErrUnsupportedVersion = errors.New("unsupported beacon block version")
// ErrNilObjectWrapped is returned in a constructor when the underlying object is nil. // ErrNilObjectWrapped is returned in a constructor when the underlying object is nil.
ErrNilObjectWrapped = errors.New("attempted to wrap nil object") ErrNilObjectWrapped = errors.New("attempted to wrap nil object")
errNilBlock = errors.New("received nil beacon block") errNilBlock = errors.New("received nil beacon block")
errNilBlockBody = errors.New("received nil beacon block body") errNilBlockBody = errors.New("received nil beacon block body")
errIncorrectBlockVersion = errors.New(incorrectBlockVersion) errIncorrectBlockVersion = errors.New(incorrectBlockVersion)
errIncorrectBodyVersion = errors.New(incorrectBodyVersion) errIncorrectBodyVersion = errors.New(incorrectBodyVersion)
errUnsupportedExecutionPayload = errors.New("unsupported execution payload")
) )
// BeaconBlockBody is the main beacon block body structure. It can represent any block type. // BeaconBlockBody is the main beacon block body structure. It can represent any block type.

View File

@@ -74,6 +74,12 @@ type BeaconBlockBody interface {
// ExecutionData represents execution layer information that is contained // ExecutionData represents execution layer information that is contained
// within post-Bellatrix beacon block bodies. // within post-Bellatrix beacon block bodies.
type ExecutionData interface { type ExecutionData interface {
ExecutionDataHeader
Transactions() ([][]byte, error)
Withdrawals() ([]*enginev1.Withdrawal, error)
}
type ExecutionDataHeader interface {
ssz.Marshaler ssz.Marshaler
ssz.Unmarshaler ssz.Unmarshaler
ssz.HashRoot ssz.HashRoot
@@ -92,8 +98,6 @@ type ExecutionData interface {
ExtraData() []byte ExtraData() []byte
BaseFeePerGas() []byte BaseFeePerGas() []byte
BlockHash() []byte BlockHash() []byte
Transactions() ([][]byte, error)
TransactionsRoot() ([]byte, error) TransactionsRoot() ([]byte, error)
Withdrawals() ([]*enginev1.Withdrawal, error)
WithdrawalsRoot() ([]byte, error) WithdrawalsRoot() ([]byte, error)
} }

View File

@@ -68,7 +68,11 @@ func GenerateGenesisStateFromDepositData(
return nil, nil, errors.Wrap(err, "could not generate genesis state") return nil, nil, errors.Wrap(err, "could not generate genesis state")
} }
pbState, err := statenative.ProtobufBeaconStatePhase0(beaconState.ToProtoUnsafe()) p, err := beaconState.ToProtoUnsafe()
if err != nil {
return nil, nil, errors.Wrap(err, "could not convert state to proto")
}
pbState, err := statenative.ProtobufBeaconStatePhase0(p)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@@ -125,7 +125,9 @@ func RunForkTransitionTest(t *testing.T, config string) {
postBeaconState := &ethpb.BeaconStateAltair{} postBeaconState := &ethpb.BeaconStateAltair{}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal") require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal")
pbState, err := state_native.ProtobufBeaconStateAltair(beaconState.ToProto()) bStateProto, err := beaconState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateAltair(bStateProto)
require.NoError(t, err) require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) { if !proto.Equal(pbState, postBeaconState) {
t.Fatal("Post state does not match expected") t.Fatal("Post state does not match expected")

View File

@@ -66,10 +66,12 @@ func RunBlockHeaderTest(t *testing.T, config string) {
postBeaconState := &ethpb.BeaconStateAltair{} postBeaconState := &ethpb.BeaconStateAltair{}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal") require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal")
pbState, err := state_native.ProtobufBeaconStateAltair(beaconState.ToProto()) beaconStateProto, err := beaconState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateAltair(beaconStateProto)
require.NoError(t, err) require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) { if !proto.Equal(pbState, postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState.ToProto(), postBeaconState) diff, _ := messagediff.PrettyDiff(beaconStateProto, postBeaconState)
t.Log(diff) t.Log(diff)
t.Fatal("Post state does not match expected") t.Fatal("Post state does not match expected")
} }

View File

@@ -55,7 +55,9 @@ func RunSlotProcessingTests(t *testing.T, config string) {
postState, err := transition.ProcessSlots(context.Background(), beaconState, beaconState.Slot().Add(slotsCount)) postState, err := transition.ProcessSlots(context.Background(), beaconState, beaconState.Slot().Add(slotsCount))
require.NoError(t, err) require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateAltair(postState.ToProto()) postStateProto, err := postState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateAltair(postStateProto)
require.NoError(t, err) require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) { if !proto.Equal(pbState, postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState) diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState)

View File

@@ -120,7 +120,9 @@ func RunForkTransitionTest(t *testing.T, config string) {
postBeaconState := &ethpb.BeaconStateBellatrix{} postBeaconState := &ethpb.BeaconStateBellatrix{}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal") require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal")
pbState, err := state_native.ProtobufBeaconStateBellatrix(beaconState.ToProto()) beaconStateProto, err := beaconState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateBellatrix(beaconStateProto)
require.NoError(t, err) require.NoError(t, err)
require.DeepSSZEqual(t, pbState, postBeaconState) require.DeepSSZEqual(t, pbState, postBeaconState)
}) })

View File

@@ -66,10 +66,12 @@ func RunBlockHeaderTest(t *testing.T, config string) {
postBeaconState := &ethpb.BeaconStateBellatrix{} postBeaconState := &ethpb.BeaconStateBellatrix{}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal") require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal")
pbState, err := state_native.ProtobufBeaconStateBellatrix(beaconState.ToProto()) beaconStateProto, err := beaconState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateBellatrix(beaconStateProto)
require.NoError(t, err) require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) { if !proto.Equal(pbState, postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState.ToProto(), postBeaconState) diff, _ := messagediff.PrettyDiff(beaconStateProto, postBeaconState)
t.Log(diff) t.Log(diff)
t.Fatal("Post state does not match expected") t.Fatal("Post state does not match expected")
} }

View File

@@ -54,7 +54,9 @@ func RunSlotProcessingTests(t *testing.T, config string) {
postState, err := transition.ProcessSlots(context.Background(), beaconState, beaconState.Slot().Add(slotsCount)) postState, err := transition.ProcessSlots(context.Background(), beaconState, beaconState.Slot().Add(slotsCount))
require.NoError(t, err) require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateBellatrix(postState.ToProto()) postStateProto, err := postState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStateBellatrix(postStateProto)
require.NoError(t, err) require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) { if !proto.Equal(pbState, postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState) diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState)

View File

@@ -67,10 +67,12 @@ func RunBlockHeaderTest(t *testing.T, config string) {
postBeaconState := &ethpb.BeaconState{} postBeaconState := &ethpb.BeaconState{}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal") require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal")
pbState, err := state_native.ProtobufBeaconStatePhase0(beaconState.ToProto()) beaconStateProto, err := beaconState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStatePhase0(beaconStateProto)
require.NoError(t, err) require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) { if !proto.Equal(pbState, postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState.ToProto(), postBeaconState) diff, _ := messagediff.PrettyDiff(beaconStateProto, postBeaconState)
t.Log(diff) t.Log(diff)
t.Fatal("Post state does not match expected") t.Fatal("Post state does not match expected")
} }

View File

@@ -54,7 +54,9 @@ func RunSlotProcessingTests(t *testing.T, config string) {
postState, err := transition.ProcessSlots(context.Background(), beaconState, beaconState.Slot().Add(slotsCount)) postState, err := transition.ProcessSlots(context.Background(), beaconState, beaconState.Slot().Add(slotsCount))
require.NoError(t, err) require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStatePhase0(postState.ToProto()) postStateProto, err := postState.ToProto()
require.NoError(t, err)
pbState, err := state_native.ProtobufBeaconStatePhase0(postStateProto)
require.NoError(t, err) require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) { if !proto.Equal(pbState, postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState) diff, _ := messagediff.PrettyDiff(beaconState, postBeaconState)

View File

@@ -326,13 +326,16 @@ func GenerateFullBlockAltair(
if currentSlot > slot { if currentSlot > slot {
return nil, fmt.Errorf("current slot in state is larger than given slot. %d > %d", currentSlot, slot) return nil, fmt.Errorf("current slot in state is larger than given slot. %d > %d", currentSlot, slot)
} }
bState = bState.Copy() var err error
bState, err = bState.Copy()
if err != nil {
return nil, err
}
if conf == nil { if conf == nil {
conf = &BlockGenConfig{} conf = &BlockGenConfig{}
} }
var err error
var pSlashings []*ethpb.ProposerSlashing var pSlashings []*ethpb.ProposerSlashing
numToGen := conf.NumProposerSlashings numToGen := conf.NumProposerSlashings
if numToGen > 0 { if numToGen > 0 {
@@ -417,7 +420,10 @@ func GenerateFullBlockAltair(
slot = currentSlot + 1 slot = currentSlot + 1
} }
stCopy := bState.Copy() stCopy, err := bState.Copy()
if err != nil {
return nil, err
}
stCopy, err = transition.ProcessSlots(context.Background(), stCopy, slot) stCopy, err = transition.ProcessSlots(context.Background(), stCopy, slot)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -53,7 +53,11 @@ func GenerateAttestations(
) ([]*ethpb.Attestation, error) { ) ([]*ethpb.Attestation, error) {
var attestations []*ethpb.Attestation var attestations []*ethpb.Attestation
generateHeadState := false generateHeadState := false
bState = bState.Copy() var err error
bState, err = bState.Copy()
if err != nil {
return nil, err
}
if slot > bState.Slot() { if slot > bState.Slot() {
// Going back a slot here so there's no inclusion delay issues. // Going back a slot here so there's no inclusion delay issues.
slot-- slot--
@@ -63,13 +67,16 @@ func GenerateAttestations(
targetRoot := make([]byte, fieldparams.RootLength) targetRoot := make([]byte, fieldparams.RootLength)
var headRoot []byte var headRoot []byte
var err error
// Only calculate head state if its an attestation for the current slot or future slot. // Only calculate head state if its an attestation for the current slot or future slot.
if generateHeadState || slot == bState.Slot() { if generateHeadState || slot == bState.Slot() {
var headState state.BeaconState var headState state.BeaconState
switch bState.Version() { switch bState.Version() {
case version.Phase0: case version.Phase0:
pbState, err := state_native.ProtobufBeaconStatePhase0(bState.ToProto()) bStateProto, err := bState.ToProto()
if err != nil {
return nil, err
}
pbState, err := state_native.ProtobufBeaconStatePhase0(bStateProto)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -79,7 +86,11 @@ func GenerateAttestations(
} }
headState = genState headState = genState
case version.Altair: case version.Altair:
pbState, err := state_native.ProtobufBeaconStateAltair(bState.ToProto()) bStateProto, err := bState.ToProto()
if err != nil {
return nil, err
}
pbState, err := state_native.ProtobufBeaconStateAltair(bStateProto)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -89,7 +100,11 @@ func GenerateAttestations(
} }
headState = genState headState = genState
case version.Bellatrix: case version.Bellatrix:
pbState, err := state_native.ProtobufBeaconStateBellatrix(bState.ToProto()) bStateProto, err := bState.ToProto()
if err != nil {
return nil, err
}
pbState, err := state_native.ProtobufBeaconStateBellatrix(bStateProto)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -37,13 +37,16 @@ func GenerateFullBlockBellatrix(
if currentSlot > slot { if currentSlot > slot {
return nil, fmt.Errorf("current slot in state is larger than given slot. %d > %d", currentSlot, slot) return nil, fmt.Errorf("current slot in state is larger than given slot. %d > %d", currentSlot, slot)
} }
bState = bState.Copy() var err error
bState, err = bState.Copy()
if err != nil {
return nil, err
}
if conf == nil { if conf == nil {
conf = &BlockGenConfig{} conf = &BlockGenConfig{}
} }
var err error
var pSlashings []*ethpb.ProposerSlashing var pSlashings []*ethpb.ProposerSlashing
numToGen := conf.NumProposerSlashings numToGen := conf.NumProposerSlashings
if numToGen > 0 { if numToGen > 0 {
@@ -105,7 +108,10 @@ func GenerateFullBlockBellatrix(
return nil, errors.Wrap(err, "could not get current timestamp") return nil, errors.Wrap(err, "could not get current timestamp")
} }
stCopy := bState.Copy() stCopy, err := bState.Copy()
if err != nil {
return nil, errors.Wrap(err, "could not copy state")
}
stCopy, err = transition.ProcessSlots(context.Background(), stCopy, slot) stCopy, err = transition.ProcessSlots(context.Background(), stCopy, slot)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -88,13 +88,15 @@ func GenerateFullBlock(
if currentSlot > slot { if currentSlot > slot {
return nil, fmt.Errorf("current slot in state is larger than given slot. %d > %d", currentSlot, slot) return nil, fmt.Errorf("current slot in state is larger than given slot. %d > %d", currentSlot, slot)
} }
bState = bState.Copy() bState, err := bState.Copy()
if err != nil {
return nil, err
}
if conf == nil { if conf == nil {
conf = &BlockGenConfig{} conf = &BlockGenConfig{}
} }
var err error
var pSlashings []*ethpb.ProposerSlashing var pSlashings []*ethpb.ProposerSlashing
numToGen := conf.NumProposerSlashings numToGen := conf.NumProposerSlashings
if numToGen > 0 { if numToGen > 0 {

View File

@@ -42,9 +42,11 @@ func BlockSignature(
privKeys []bls.SecretKey, privKeys []bls.SecretKey,
) (bls.Signature, error) { ) (bls.Signature, error) {
var wsb interfaces.SignedBeaconBlock var wsb interfaces.SignedBeaconBlock
var err error
// copy the state since we need to process slots // copy the state since we need to process slots
bState = bState.Copy() bState, err := bState.Copy()
if err != nil {
return nil, err
}
switch b := block.(type) { switch b := block.(type) {
case *ethpb.BeaconBlock: case *ethpb.BeaconBlock:
wsb, err = blocks.NewSignedBeaconBlock(&ethpb.SignedBeaconBlock{Block: b}) wsb, err = blocks.NewSignedBeaconBlock(&ethpb.SignedBeaconBlock{Block: b})

View File

@@ -112,7 +112,7 @@ func NewBeaconState(options ...NewBeaconStateOption) (state.BeaconState, error)
return nil, err return nil, err
} }
return st.Copy(), nil return st.Copy()
} }
// NewBeaconStateAltair creates a beacon state with minimum marshalable fields. // NewBeaconStateAltair creates a beacon state with minimum marshalable fields.
@@ -167,7 +167,7 @@ func NewBeaconStateAltair(options ...func(state *ethpb.BeaconStateAltair) error)
return nil, err return nil, err
} }
return st.Copy(), nil return st.Copy()
} }
// NewBeaconStateBellatrix creates a beacon state with minimum marshalable fields. // NewBeaconStateBellatrix creates a beacon state with minimum marshalable fields.
@@ -234,7 +234,7 @@ func NewBeaconStateBellatrix(options ...func(state *ethpb.BeaconStateBellatrix)
return nil, err return nil, err
} }
return st.Copy(), nil return st.Copy()
} }
// NewBeaconStateCapella creates a beacon state with minimum marshalable fields. // NewBeaconStateCapella creates a beacon state with minimum marshalable fields.
@@ -302,7 +302,7 @@ func NewBeaconStateCapella(options ...func(state *ethpb.BeaconStateCapella) erro
return nil, err return nil, err
} }
return st.Copy(), nil return st.Copy()
} }
// SSZ will fill 2D byte slices with their respective values, so we must fill these in too for round // SSZ will fill 2D byte slices with their respective values, so we must fill these in too for round