diff --git a/CHANGELOG.md b/CHANGELOG.md index b7f7727e055f..aef6f6efadfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Updated the `beacon-chain/monitor` package to Electra. [PR](https://github.com/prysmaticlabs/prysm/pull/14562) - Added ListAttestationsV2 endpoint. - Add ability to rollback node's internal state during processing. +- Change how unsafe protobuf state is created to prevent unnecessary copies. +- Added benchmarks for process slots for Capella, Deneb, Electra ### Changed @@ -32,12 +34,17 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Use read only validator for core processing to avoid unnecessary copying. - Use ROBlock across block processing pipeline. - Added missing Eth-Consensus-Version headers to GetBlockAttestationsV2 and GetAttesterSlashingsV2 endpoints. +- When instantiating new validators, explicit set `Slashed` to false and move `EffectiveBalance` to match struct definition. - Updated pgo profile for beacon chain with holesky data. This improves the profile guided optimizations in the go compiler. - Use read only state when computing the active validator list. - Simplified `ExitedValidatorIndices`. - Simplified `EjectedValidatorIndices`. - `engine_newPayloadV4`,`engine_getPayloadV4` are changes due to new execution request serialization decisions, [PR](https://github.com/prysmaticlabs/prysm/pull/14580) +- Use ROBlock earlier in block syncing pipeline. +- Changed the signature of `ProcessPayload`. +- Only Build the Protobuf state once during serialization. +- Capella blocks are execution. - updated geth to 1.14 ~ - e2e tests start from capella @@ -177,6 +184,7 @@ Updating to this release is recommended at your convenience. - Light client support: fix light client attested header execution fields' wrong version bug. - Testing: added custom matcher for better push settings testing. - Registered `GetDepositSnapshot` Beacon API endpoint. +- Fix rolling back of a block due to a context deadline. ### Security diff --git a/beacon-chain/blockchain/process_block.go b/beacon-chain/blockchain/process_block.go index 7a55c3f83fba..e2889507b801 100644 --- a/beacon-chain/blockchain/process_block.go +++ b/beacon-chain/blockchain/process_block.go @@ -76,6 +76,8 @@ func (s *Service) postBlockProcess(cfg *postBlockProcessConfig) error { err := s.cfg.ForkChoiceStore.InsertNode(ctx, cfg.postState, cfg.roblock) if err != nil { + // Do not use parent context in the event it deadlined + ctx = trace.NewContext(context.Background(), span) s.rollbackBlock(ctx, cfg.roblock.Root()) return errors.Wrapf(err, "could not insert block %d to fork choice store", cfg.roblock.Block().Slot()) } diff --git a/beacon-chain/blockchain/process_block_test.go b/beacon-chain/blockchain/process_block_test.go index 7ed483861f1c..53fb11e8055f 100644 --- a/beacon-chain/blockchain/process_block_test.go +++ b/beacon-chain/blockchain/process_block_test.go @@ -1520,7 +1520,9 @@ func TestStore_NoViableHead_NewPayload(t *testing.T) { require.NoError(t, err) preStateVersion, preStateHeader, err := getStateVersionAndPayload(preState) require.NoError(t, err) - _, err = service.validateExecutionOnBlock(ctx, preStateVersion, preStateHeader, wsb, root) + rowsb, err := consensusblocks.NewROBlockWithRoot(wsb, root) + require.NoError(t, err) + _, err = service.validateExecutionOnBlock(ctx, preStateVersion, preStateHeader, rowsb) require.ErrorContains(t, "received an INVALID payload from execution engine", err) // Check that forkchoice's head and store's headroot are the previous head (since the invalid block did // not finish importing and it was never imported to forkchoice). Check @@ -1714,7 +1716,9 @@ func TestStore_NoViableHead_Liveness(t *testing.T) { require.NoError(t, err) preStateVersion, preStateHeader, err := getStateVersionAndPayload(preState) require.NoError(t, err) - _, err = service.validateExecutionOnBlock(ctx, preStateVersion, preStateHeader, wsb, root) + rowsb, err := consensusblocks.NewROBlockWithRoot(wsb, root) + require.NoError(t, err) + _, err = service.validateExecutionOnBlock(ctx, preStateVersion, preStateHeader, rowsb) require.ErrorContains(t, "received an INVALID payload from execution engine", err) // Check that forkchoice's head and store's headroot are the previous head (since the invalid block did @@ -1964,7 +1968,9 @@ func TestNoViableHead_Reboot(t *testing.T) { require.NoError(t, err) preStateVersion, preStateHeader, err := getStateVersionAndPayload(preState) require.NoError(t, err) - _, err = service.validateExecutionOnBlock(ctx, preStateVersion, preStateHeader, wsb, root) + rowsb, err := consensusblocks.NewROBlockWithRoot(wsb, root) + require.NoError(t, err) + _, err = service.validateExecutionOnBlock(ctx, preStateVersion, preStateHeader, rowsb) require.ErrorContains(t, "received an INVALID payload from execution engine", err) // Check that the headroot/state are not in DB and restart the node @@ -2346,6 +2352,85 @@ func TestRollbackBlock(t *testing.T) { require.Equal(t, false, hasState) } +func TestRollbackBlock_ContextDeadline(t *testing.T) { + service, tr := minimalTestService(t) + ctx := tr.ctx + + st, keys := util.DeterministicGenesisState(t, 64) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err, "Could not hash genesis state") + + require.NoError(t, service.saveGenesisData(ctx, st)) + + genesis := blocks.NewGenesisBlock(stateRoot[:]) + wsb, err := consensusblocks.NewSignedBeaconBlock(genesis) + require.NoError(t, err) + require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wsb), "Could not save genesis block") + parentRoot, err := genesis.Block.HashTreeRoot() + require.NoError(t, err, "Could not get signing root") + require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st, parentRoot), "Could not save genesis state") + require.NoError(t, service.cfg.BeaconDB.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state") + require.NoError(t, service.cfg.BeaconDB.SaveJustifiedCheckpoint(ctx, ðpb.Checkpoint{Root: parentRoot[:]})) + require.NoError(t, service.cfg.BeaconDB.SaveFinalizedCheckpoint(ctx, ðpb.Checkpoint{Root: parentRoot[:]})) + + st, err = service.HeadState(ctx) + require.NoError(t, err) + b, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 33) + require.NoError(t, err) + wsb, err = consensusblocks.NewSignedBeaconBlock(b) + require.NoError(t, err) + root, err := b.Block.HashTreeRoot() + require.NoError(t, err) + preState, err := service.getBlockPreState(ctx, wsb.Block()) + require.NoError(t, err) + postState, err := service.validateStateTransition(ctx, preState, wsb) + require.NoError(t, err) + require.NoError(t, service.savePostStateInfo(ctx, root, wsb, postState)) + roblock, err := consensusblocks.NewROBlockWithRoot(wsb, root) + require.NoError(t, err) + require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, roblock, [32]byte{}, postState, false})) + + b, err = util.GenerateFullBlock(postState, keys, util.DefaultBlockGenConfig(), 34) + require.NoError(t, err) + wsb, err = consensusblocks.NewSignedBeaconBlock(b) + require.NoError(t, err) + root, err = b.Block.HashTreeRoot() + require.NoError(t, err) + preState, err = service.getBlockPreState(ctx, wsb.Block()) + require.NoError(t, err) + postState, err = service.validateStateTransition(ctx, preState, wsb) + require.NoError(t, err) + require.NoError(t, service.savePostStateInfo(ctx, root, wsb, postState)) + + require.Equal(t, true, service.cfg.BeaconDB.HasBlock(ctx, root)) + hasState, err := service.cfg.StateGen.HasState(ctx, root) + require.NoError(t, err) + require.Equal(t, true, hasState) + + // Set deadlined context when processing the block + cancCtx, canc := context.WithCancel(context.Background()) + canc() + roblock, err = consensusblocks.NewROBlockWithRoot(wsb, root) + require.NoError(t, err) + + parentRoot = roblock.Block().ParentRoot() + + cj := ðpb.Checkpoint{} + cj.Epoch = 1 + cj.Root = parentRoot[:] + require.NoError(t, postState.SetCurrentJustifiedCheckpoint(cj)) + require.NoError(t, postState.SetFinalizedCheckpoint(cj)) + + // Rollback block insertion into db and caches. + require.ErrorContains(t, "context canceled", service.postBlockProcess(&postBlockProcessConfig{cancCtx, roblock, [32]byte{}, postState, false})) + + // The block should no longer exist. + require.Equal(t, false, service.cfg.BeaconDB.HasBlock(ctx, root)) + hasState, err = service.cfg.StateGen.HasState(ctx, root) + require.NoError(t, err) + require.Equal(t, false, hasState) +} + func fakeCommitments(n int) [][]byte { f := make([][]byte, n) for i := range f { diff --git a/beacon-chain/blockchain/receive_block.go b/beacon-chain/blockchain/receive_block.go index e6afed076852..ff8c4d9187e4 100644 --- a/beacon-chain/blockchain/receive_block.go +++ b/beacon-chain/blockchain/receive_block.go @@ -18,6 +18,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/config/features" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" consensus_blocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" + consensusblocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" @@ -84,7 +85,12 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.ReadOnlySig } currentCheckpoints := s.saveCurrentCheckpoints(preState) - postState, isValidPayload, err := s.validateExecutionAndConsensus(ctx, preState, blockCopy, blockRoot) + roblock, err := consensus_blocks.NewROBlockWithRoot(blockCopy, blockRoot) + if err != nil { + return err + } + + postState, isValidPayload, err := s.validateExecutionAndConsensus(ctx, preState, roblock) if err != nil { return err } @@ -101,10 +107,6 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.ReadOnlySig if err := s.savePostStateInfo(ctx, blockRoot, blockCopy, postState); err != nil { return errors.Wrap(err, "could not save post state info") } - roblock, err := consensus_blocks.NewROBlockWithRoot(blockCopy, blockRoot) - if err != nil { - return err - } args := &postBlockProcessConfig{ ctx: ctx, roblock: roblock, @@ -188,8 +190,7 @@ func (s *Service) updateCheckpoints( func (s *Service) validateExecutionAndConsensus( ctx context.Context, preState state.BeaconState, - block interfaces.SignedBeaconBlock, - blockRoot [32]byte, + block consensusblocks.ROBlock, ) (state.BeaconState, bool, error) { preStateVersion, preStateHeader, err := getStateVersionAndPayload(preState) if err != nil { @@ -208,7 +209,7 @@ func (s *Service) validateExecutionAndConsensus( var isValidPayload bool eg.Go(func() error { var err error - isValidPayload, err = s.validateExecutionOnBlock(ctx, preStateVersion, preStateHeader, block, blockRoot) + isValidPayload, err = s.validateExecutionOnBlock(ctx, preStateVersion, preStateHeader, block) if err != nil { return errors.Wrap(err, "could not notify the engine of the new payload") } @@ -559,16 +560,16 @@ func (s *Service) sendBlockAttestationsToSlasher(signed interfaces.ReadOnlySigne } // validateExecutionOnBlock notifies the engine of the incoming block execution payload and returns true if the payload is valid -func (s *Service) validateExecutionOnBlock(ctx context.Context, ver int, header interfaces.ExecutionData, signed interfaces.ReadOnlySignedBeaconBlock, blockRoot [32]byte) (bool, error) { - isValidPayload, err := s.notifyNewPayload(ctx, ver, header, signed) +func (s *Service) validateExecutionOnBlock(ctx context.Context, ver int, header interfaces.ExecutionData, block consensusblocks.ROBlock) (bool, error) { + isValidPayload, err := s.notifyNewPayload(ctx, ver, header, block) if err != nil { s.cfg.ForkChoiceStore.Lock() - err = s.handleInvalidExecutionError(ctx, err, blockRoot, signed.Block().ParentRoot()) + err = s.handleInvalidExecutionError(ctx, err, block.Root(), block.Block().ParentRoot()) s.cfg.ForkChoiceStore.Unlock() return false, err } - if signed.Version() < version.Capella && isValidPayload { - if err := s.validateMergeTransitionBlock(ctx, ver, header, signed); err != nil { + if block.Block().Version() < version.Capella && isValidPayload { + if err := s.validateMergeTransitionBlock(ctx, ver, header, block); err != nil { return isValidPayload, err } } diff --git a/beacon-chain/core/altair/deposit.go b/beacon-chain/core/altair/deposit.go index 084643324e40..5aeb23c100c6 100644 --- a/beacon-chain/core/altair/deposit.go +++ b/beacon-chain/core/altair/deposit.go @@ -187,11 +187,12 @@ func AddValidatorToRegistry(beaconState state.BeaconState, pubKey []byte, withdr // return Validator( // pubkey=pubkey, // withdrawal_credentials=withdrawal_credentials, +// effective_balance=effective_balance, +// slashed=False, // activation_eligibility_epoch=FAR_FUTURE_EPOCH, // activation_epoch=FAR_FUTURE_EPOCH, // exit_epoch=FAR_FUTURE_EPOCH, // withdrawable_epoch=FAR_FUTURE_EPOCH, -// effective_balance=effective_balance, // ) func GetValidatorFromDeposit(pubKey []byte, withdrawalCredentials []byte, amount uint64) *ethpb.Validator { effectiveBalance := amount - (amount % params.BeaconConfig().EffectiveBalanceIncrement) @@ -202,10 +203,11 @@ func GetValidatorFromDeposit(pubKey []byte, withdrawalCredentials []byte, amount return ðpb.Validator{ PublicKey: pubKey, WithdrawalCredentials: withdrawalCredentials, + EffectiveBalance: effectiveBalance, + Slashed: false, ActivationEligibilityEpoch: params.BeaconConfig().FarFutureEpoch, ActivationEpoch: params.BeaconConfig().FarFutureEpoch, ExitEpoch: params.BeaconConfig().FarFutureEpoch, WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch, - EffectiveBalance: effectiveBalance, } } diff --git a/beacon-chain/core/blocks/payload.go b/beacon-chain/core/blocks/payload.go index a7ffde06aa5f..6d52931b1418 100644 --- a/beacon-chain/core/blocks/payload.go +++ b/beacon-chain/core/blocks/payload.go @@ -61,6 +61,9 @@ func IsExecutionBlock(body interfaces.ReadOnlyBeaconBlockBody) (bool, error) { if body == nil { return false, errors.New("nil block body") } + if body.Version() >= version.Capella { + return true, nil + } payload, err := body.Execution() switch { case errors.Is(err, consensus_types.ErrUnsupportedField): @@ -202,24 +205,24 @@ func ValidatePayload(st state.BeaconState, payload interfaces.ExecutionData) err // block_hash=payload.block_hash, // transactions_root=hash_tree_root(payload.transactions), // ) -func ProcessPayload(st state.BeaconState, body interfaces.ReadOnlyBeaconBlockBody) (state.BeaconState, error) { +func ProcessPayload(st state.BeaconState, body interfaces.ReadOnlyBeaconBlockBody) error { payload, err := body.Execution() if err != nil { - return nil, err + return err } if err := verifyBlobCommitmentCount(body); err != nil { - return nil, err + return err } if err := ValidatePayloadWhenMergeCompletes(st, payload); err != nil { - return nil, err + return err } if err := ValidatePayload(st, payload); err != nil { - return nil, err + return err } if err := st.SetLatestExecutionPayloadHeader(payload); err != nil { - return nil, err + return err } - return st, nil + return nil } func verifyBlobCommitmentCount(body interfaces.ReadOnlyBeaconBlockBody) error { diff --git a/beacon-chain/core/blocks/payload_test.go b/beacon-chain/core/blocks/payload_test.go index 20992c949aa2..38ce31eaa2d1 100644 --- a/beacon-chain/core/blocks/payload_test.go +++ b/beacon-chain/core/blocks/payload_test.go @@ -253,7 +253,8 @@ func Test_IsExecutionBlockCapella(t *testing.T) { require.NoError(t, err) got, err := blocks.IsExecutionBlock(wrappedBlock.Body()) require.NoError(t, err) - require.Equal(t, false, got) + // #14614 + require.Equal(t, true, got) } func Test_IsExecutionEnabled(t *testing.T) { @@ -587,8 +588,7 @@ func Test_ProcessPayload(t *testing.T) { ExecutionPayload: tt.payload, }) require.NoError(t, err) - st, err := blocks.ProcessPayload(st, body) - if err != nil { + if err := blocks.ProcessPayload(st, body); err != nil { require.Equal(t, tt.err.Error(), err.Error()) } else { require.Equal(t, tt.err, err) @@ -619,8 +619,7 @@ func Test_ProcessPayloadCapella(t *testing.T) { ExecutionPayload: payload, }) require.NoError(t, err) - _, err = blocks.ProcessPayload(st, body) - require.NoError(t, err) + require.NoError(t, blocks.ProcessPayload(st, body)) } func Test_ProcessPayload_Blinded(t *testing.T) { @@ -677,8 +676,7 @@ func Test_ProcessPayload_Blinded(t *testing.T) { ExecutionPayloadHeader: p, }) require.NoError(t, err) - st, err := blocks.ProcessPayload(st, body) - if err != nil { + if err := blocks.ProcessPayload(st, body); err != nil { require.Equal(t, tt.err.Error(), err.Error()) } else { require.Equal(t, tt.err, err) diff --git a/beacon-chain/core/electra/deposits.go b/beacon-chain/core/electra/deposits.go index 31fec1191af7..098f2ceaf56f 100644 --- a/beacon-chain/core/electra/deposits.go +++ b/beacon-chain/core/electra/deposits.go @@ -508,11 +508,12 @@ func AddValidatorToRegistry(beaconState state.BeaconState, pubKey []byte, withdr // validator = Validator( // pubkey=pubkey, // withdrawal_credentials=withdrawal_credentials, +// effective_balance=Gwei(0), +// slashed=False, // activation_eligibility_epoch=FAR_FUTURE_EPOCH, // activation_epoch=FAR_FUTURE_EPOCH, // exit_epoch=FAR_FUTURE_EPOCH, // withdrawable_epoch=FAR_FUTURE_EPOCH, -// effective_balance=Gwei(0), // ) // // # [Modified in Electra:EIP7251] @@ -524,11 +525,12 @@ func GetValidatorFromDeposit(pubKey []byte, withdrawalCredentials []byte, amount validator := ðpb.Validator{ PublicKey: pubKey, WithdrawalCredentials: withdrawalCredentials, + EffectiveBalance: 0, + Slashed: false, ActivationEligibilityEpoch: params.BeaconConfig().FarFutureEpoch, ActivationEpoch: params.BeaconConfig().FarFutureEpoch, ExitEpoch: params.BeaconConfig().FarFutureEpoch, WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch, - EffectiveBalance: 0, } v, err := state_native.NewValidator(validator) if err != nil { diff --git a/beacon-chain/core/transition/transition_no_verify_sig.go b/beacon-chain/core/transition/transition_no_verify_sig.go index 402d607837b3..e633c844d35b 100644 --- a/beacon-chain/core/transition/transition_no_verify_sig.go +++ b/beacon-chain/core/transition/transition_no_verify_sig.go @@ -333,8 +333,7 @@ func ProcessBlockForStateRoot( return nil, errors.Wrap(err, "could not process withdrawals") } } - state, err = b.ProcessPayload(state, blk.Body()) - if err != nil { + if err = b.ProcessPayload(state, blk.Body()); err != nil { return nil, errors.Wrap(err, "could not process execution data") } } diff --git a/beacon-chain/core/transition/transition_test.go b/beacon-chain/core/transition/transition_test.go index 9000afeee603..c03bdbafdc5a 100644 --- a/beacon-chain/core/transition/transition_test.go +++ b/beacon-chain/core/transition/transition_test.go @@ -698,3 +698,45 @@ func TestProcessSlotsConditionally(t *testing.T) { assert.Equal(t, primitives.Slot(6), s.Slot()) }) } + +func BenchmarkProcessSlots_Capella(b *testing.B) { + st, _ := util.DeterministicGenesisStateCapella(b, params.BeaconConfig().MaxValidatorsPerCommittee) + + var err error + + b.ResetTimer() + for i := 0; i < b.N; i++ { + st, err = transition.ProcessSlots(context.Background(), st, st.Slot()+1) + if err != nil { + b.Fatalf("Failed to process slot %v", err) + } + } +} + +func BenchmarkProcessSlots_Deneb(b *testing.B) { + st, _ := util.DeterministicGenesisStateDeneb(b, params.BeaconConfig().MaxValidatorsPerCommittee) + + var err error + + b.ResetTimer() + for i := 0; i < b.N; i++ { + st, err = transition.ProcessSlots(context.Background(), st, st.Slot()+1) + if err != nil { + b.Fatalf("Failed to process slot %v", err) + } + } +} + +func BenchmarkProcessSlots_Electra(b *testing.B) { + st, _ := util.DeterministicGenesisStateElectra(b, params.BeaconConfig().MaxValidatorsPerCommittee) + + var err error + + b.ResetTimer() + for i := 0; i < b.N; i++ { + st, err = transition.ProcessSlots(context.Background(), st, st.Slot()+1) + if err != nil { + b.Fatalf("Failed to process slot %v", err) + } + } +} diff --git a/beacon-chain/db/kv/state.go b/beacon-chain/db/kv/state.go index b78e45ab25bd..8f840448d452 100644 --- a/beacon-chain/db/kv/state.go +++ b/beacon-chain/db/kv/state.go @@ -18,6 +18,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/monitoring/tracing" "github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/time" "github.com/prysmaticlabs/prysm/v5/time/slots" bolt "go.etcd.io/bbolt" @@ -603,14 +604,14 @@ func (s *Store) unmarshalState(_ context.Context, enc []byte, validatorEntries [ // marshal versioned state from struct type down to bytes. func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, error) { - switch st.ToProtoUnsafe().(type) { - case *ethpb.BeaconState: + switch st.Version() { + case version.Phase0: rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconState) if !ok { return nil, errors.New("non valid inner state") } return encode(ctx, rState) - case *ethpb.BeaconStateAltair: + case version.Altair: rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateAltair) if !ok { return nil, errors.New("non valid inner state") @@ -623,7 +624,7 @@ func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, er return nil, err } return snappy.Encode(nil, append(altairKey, rawObj...)), nil - case *ethpb.BeaconStateBellatrix: + case version.Bellatrix: rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateBellatrix) if !ok { return nil, errors.New("non valid inner state") @@ -636,7 +637,7 @@ func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, er return nil, err } return snappy.Encode(nil, append(bellatrixKey, rawObj...)), nil - case *ethpb.BeaconStateCapella: + case version.Capella: rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateCapella) if !ok { return nil, errors.New("non valid inner state") @@ -649,7 +650,7 @@ func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, er return nil, err } return snappy.Encode(nil, append(capellaKey, rawObj...)), nil - case *ethpb.BeaconStateDeneb: + case version.Deneb: rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateDeneb) if !ok { return nil, errors.New("non valid inner state") @@ -662,7 +663,7 @@ func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, er return nil, err } return snappy.Encode(nil, append(denebKey, rawObj...)), nil - case *ethpb.BeaconStateElectra: + case version.Electra: rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateElectra) if !ok { return nil, errors.New("non valid inner state") diff --git a/beacon-chain/state/state-native/getters_state.go b/beacon-chain/state/state-native/getters_state.go index 29519afc7cee..b4512a8a2744 100644 --- a/beacon-chain/state/state-native/getters_state.go +++ b/beacon-chain/state/state-native/getters_state.go @@ -22,12 +22,22 @@ func (b *BeaconState) ToProtoUnsafe() interface{} { rm := b.randaoMixesVal().Slice() var vals []*ethpb.Validator var bals []uint64 + var inactivityScores []uint64 + if features.Get().EnableExperimentalState { - vals = b.validatorsVal() - bals = b.balancesVal() + if b.balancesMultiValue != nil { + bals = b.balancesMultiValue.Value(b) + } + if b.inactivityScoresMultiValue != nil { + inactivityScores = b.inactivityScoresMultiValue.Value(b) + } + if b.validatorsMultiValue != nil { + vals = b.validatorsMultiValue.Value(b) + } } else { - vals = b.validators bals = b.balances + inactivityScores = b.inactivityScores + vals = b.validators } switch b.version { @@ -78,7 +88,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} { PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint, CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint, FinalizedCheckpoint: b.finalizedCheckpoint, - InactivityScores: b.inactivityScoresVal(), + InactivityScores: inactivityScores, CurrentSyncCommittee: b.currentSyncCommittee, NextSyncCommittee: b.nextSyncCommittee, } @@ -105,7 +115,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} { PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint, CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint, FinalizedCheckpoint: b.finalizedCheckpoint, - InactivityScores: b.inactivityScoresVal(), + InactivityScores: inactivityScores, CurrentSyncCommittee: b.currentSyncCommittee, NextSyncCommittee: b.nextSyncCommittee, LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader, @@ -133,7 +143,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} { PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint, CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint, FinalizedCheckpoint: b.finalizedCheckpoint, - InactivityScores: b.inactivityScoresVal(), + InactivityScores: inactivityScores, CurrentSyncCommittee: b.currentSyncCommittee, NextSyncCommittee: b.nextSyncCommittee, LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderCapella, @@ -164,7 +174,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} { PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint, CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint, FinalizedCheckpoint: b.finalizedCheckpoint, - InactivityScores: b.inactivityScoresVal(), + InactivityScores: inactivityScores, CurrentSyncCommittee: b.currentSyncCommittee, NextSyncCommittee: b.nextSyncCommittee, LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderDeneb, @@ -195,7 +205,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} { PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint, CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint, FinalizedCheckpoint: b.finalizedCheckpoint, - InactivityScores: b.inactivityScoresVal(), + InactivityScores: inactivityScores, CurrentSyncCommittee: b.currentSyncCommittee, NextSyncCommittee: b.nextSyncCommittee, LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderDeneb, diff --git a/testing/spectest/shared/common/operations/block_header.go b/testing/spectest/shared/common/operations/block_header.go index d38221535aff..c1f01e597ef1 100644 --- a/testing/spectest/shared/common/operations/block_header.go +++ b/testing/spectest/shared/common/operations/block_header.go @@ -56,10 +56,10 @@ func RunBlockHeaderTest(t *testing.T, config string, fork string, sszToBlock SSZ bodyRoot, err := block.Block().Body().HashTreeRoot() require.NoError(t, err) pr := block.Block().ParentRoot() - beaconState, err := blocks.ProcessBlockHeaderNoVerify(context.Background(), preBeaconState, block.Block().Slot(), block.Block().ProposerIndex(), pr[:], bodyRoot[:]) + _, err = blocks.ProcessBlockHeaderNoVerify(context.Background(), preBeaconState, block.Block().Slot(), block.Block().ProposerIndex(), pr[:], bodyRoot[:]) if postSSZExists { require.NoError(t, err) - comparePostState(t, postSSZFilepath, sszToState, preBeaconState, beaconState) + comparePostState(t, postSSZFilepath, sszToState, preBeaconState) } else { // Note: This doesn't test anything worthwhile. It essentially tests // that *any* error has occurred, not any specific error. diff --git a/testing/spectest/shared/common/operations/execution_payload.go b/testing/spectest/shared/common/operations/execution_payload.go index c305efae2cd0..652b500aa496 100644 --- a/testing/spectest/shared/common/operations/execution_payload.go +++ b/testing/spectest/shared/common/operations/execution_payload.go @@ -54,10 +54,10 @@ func RunExecutionPayloadTest(t *testing.T, config string, fork string, sszToBloc config := &ExecutionConfig{} require.NoError(t, utils.UnmarshalYaml(file, config), "Failed to Unmarshal") - gotState, err := blocks.ProcessPayload(preBeaconState, body) + err = blocks.ProcessPayload(preBeaconState, body) if postSSZExists { require.NoError(t, err) - comparePostState(t, postSSZFilepath, sszToState, preBeaconState, gotState) + comparePostState(t, postSSZFilepath, sszToState, preBeaconState) } else if config.Valid { // Note: This doesn't test anything worthwhile. It essentially tests // that *any* error has occurred, not any specific error. diff --git a/testing/spectest/shared/common/operations/test_runner.go b/testing/spectest/shared/common/operations/test_runner.go index e166c830f0dc..1fa5087841b7 100644 --- a/testing/spectest/shared/common/operations/test_runner.go +++ b/testing/spectest/shared/common/operations/test_runner.go @@ -50,10 +50,10 @@ func RunBlockOperationTest( } helpers.ClearCache() - beaconState, err := operationFn(context.Background(), preState, wsb) + _, err = operationFn(context.Background(), preState, wsb) if postSSZExists { require.NoError(t, err) - comparePostState(t, postSSZFilepath, sszToState, preState, beaconState) + comparePostState(t, postSSZFilepath, sszToState, preState) } else { // Note: This doesn't test anything worthwhile. It essentially tests // that *any* error has occurred, not any specific error. @@ -65,7 +65,7 @@ func RunBlockOperationTest( } } -func comparePostState(t *testing.T, postSSZFilepath string, sszToState SSZToState, want state.BeaconState, got state.BeaconState) { +func comparePostState(t *testing.T, postSSZFilepath string, sszToState SSZToState, want state.BeaconState) { postBeaconStateFile, err := os.ReadFile(postSSZFilepath) // #nosec G304 require.NoError(t, err) postBeaconStateSSZ, err := snappy.Decode(nil /* dst */, postBeaconStateFile)