From 279cee42f124fc91ec46712352b2227f4701a8e5 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Fri, 2 Dec 2022 16:13:01 -0800 Subject: [PATCH 1/7] Refactor block proposal path --- .../rpc/prysm/v1alpha1/validator/BUILD.bazel | 1 - .../rpc/prysm/v1alpha1/validator/proposer.go | 180 +++++++++++++- .../v1alpha1/validator/proposer_altair.go | 59 ----- .../v1alpha1/validator/proposer_bellatrix.go | 109 --------- .../v1alpha1/validator/proposer_phase0.go | 220 ------------------ consensus-types/blocks/getters.go | 137 +++++++++++ consensus-types/interfaces/beacon_block.go | 16 ++ 7 files changed, 322 insertions(+), 400 deletions(-) delete mode 100644 beacon-chain/rpc/prysm/v1alpha1/validator/proposer_phase0.go diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel b/beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel index ddf3d83b3ece..8c630ad62f3c 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel @@ -16,7 +16,6 @@ go_library( "proposer_deposits.go", "proposer_eth1data.go", "proposer_execution_payload.go", - "proposer_phase0.go", "proposer_sync_aggregate.go", "server.go", "status.go", diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go index f5e58502a7ef..d7e2e72bb2ff 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go @@ -12,9 +12,12 @@ import ( emptypb "github.com/golang/protobuf/ptypes/empty" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v3/beacon-chain/builder" + blocks2 "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/blocks" "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/feed" blockfeed "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/feed/block" + "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition" + v "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/validators" "github.com/prysmaticlabs/prysm/v3/beacon-chain/db/kv" "github.com/prysmaticlabs/prysm/v3/config/params" "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" @@ -41,25 +44,180 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( ctx, span := trace.StartSpan(ctx, "ProposerServer.GetBeaconBlock") defer span.End() span.AddAttributes(trace.Int64Attribute("slot", int64(req.Slot))) - if slots.ToEpoch(req.Slot) < params.BeaconConfig().AltairForkEpoch { - blk, err := vs.getPhase0BeaconBlock(ctx, req) + + // A syncing validator should not produce a block. + if vs.SyncChecker.Syncing() { + return nil, fmt.Errorf("syncing to latest head, not ready to respond") + } + + // An optimistic validator MUST NOT produce a block (i.e., sign across the DOMAIN_BEACON_PROPOSER domain). + if err := vs.optimisticStatus(ctx); err != nil { + return nil, err + } + + var blk interfaces.BeaconBlock + var signedblk interfaces.SignedBeaconBlock + var err error + switch { + case slots.ToEpoch(req.Slot) < params.BeaconConfig().AltairForkEpoch: + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlock{}) + signedblk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlock{}) + case slots.ToEpoch(req.Slot) < params.BeaconConfig().BellatrixForkEpoch: + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockAltair{}) + signedblk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{}) + case slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch: + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockBellatrix{}) + signedblk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{}) + default: + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockCapella{}) + signedblk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockCapella{}) + } + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + + parentRoot, err := vs.HeadFetcher.HeadRoot(ctx) + if err != nil { + return nil, fmt.Errorf("could not retrieve head root: %v", err) + } + head, err := vs.HeadFetcher.HeadState(ctx) + if err != nil { + return nil, fmt.Errorf("could not get head state %v", err) + } + head, err = transition.ProcessSlotsUsingNextSlotCache(ctx, head, parentRoot, req.Slot) + if err != nil { + return nil, fmt.Errorf("could not advance slots to calculate proposer index: %v", err) + } + + // Set slot, graffiti and parent root. + blk.SetSlot(req.Slot) + blk.Body().SetGraffiti(req.Graffiti) + blk.SetParentRoot(parentRoot) + + // Set eth1 data. + eth1Data, err := vs.eth1DataMajorityVote(ctx, head) + if err != nil { + return nil, fmt.Errorf("could not get ETH1 data: %v", err) + } + blk.Body().SetEth1Data(eth1Data) + + // Set deposit and attestation. + deposits, atts, err := vs.packDepositsAndAttestations(ctx, head, eth1Data) + if err != nil { + return nil, err + } + blk.Body().SetDeposits(deposits) + blk.Body().SetAttestations(atts) + + // Set proposer index + idx, err := helpers.BeaconProposerIndex(ctx, head) + if err != nil { + return nil, fmt.Errorf("could not calculate proposer index %v", err) + } + blk.SetProposerIndex(idx) + + // Set slashings + proposerSlashings := vs.SlashingsPool.PendingProposerSlashings(ctx, head, false /*noLimit*/) + validProposerSlashings := make([]*ethpb.ProposerSlashing, 0, len(proposerSlashings)) + for _, slashing := range proposerSlashings { + _, err := blocks2.ProcessProposerSlashing(ctx, head, slashing, v.SlashValidator) if err != nil { - return nil, status.Errorf(codes.Internal, "Could not fetch phase0 beacon block: %v", err) + log.WithError(err).Warn("Proposer: invalid proposer slashing") + continue } - return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Phase0{Phase0: blk}}, nil - } else if slots.ToEpoch(req.Slot) < params.BeaconConfig().BellatrixForkEpoch { - blk, err := vs.getAltairBeaconBlock(ctx, req) + validProposerSlashings = append(validProposerSlashings, slashing) + } + attSlashings := vs.SlashingsPool.PendingAttesterSlashings(ctx, head, false /*noLimit*/) + validAttSlashings := make([]*ethpb.AttesterSlashing, 0, len(attSlashings)) + for _, slashing := range attSlashings { + _, err := blocks2.ProcessAttesterSlashing(ctx, head, slashing, v.SlashValidator) if err != nil { - return nil, status.Errorf(codes.Internal, "Could not fetch Altair beacon block: %v", err) + log.WithError(err).Warn("Proposer: invalid attester slashing") + continue } - return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Altair{Altair: blk}}, nil + validAttSlashings = append(validAttSlashings, slashing) } + blk.Body().SetProposerSlashings(validProposerSlashings) + blk.Body().SetAttesterSlashings(validAttSlashings) - // An optimistic validator MUST NOT produce a block (i.e., sign across the DOMAIN_BEACON_PROPOSER domain). - if err := vs.optimisticStatus(ctx); err != nil { + // Set exits + exits := vs.ExitPool.PendingExits(head, req.Slot, false /*noLimit*/) + validExits := make([]*ethpb.SignedVoluntaryExit, 0, len(exits)) + for _, exit := range exits { + val, err := head.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex) + if err != nil { + log.WithError(err).Warn("Proposer: invalid exit") + continue + } + if err := blocks2.VerifyExitAndSignature(val, head.Slot(), head.Fork(), exit, head.GenesisValidatorsRoot()); err != nil { + log.WithError(err).Warn("Proposer: invalid exit") + continue + } + validExits = append(validExits, exit) + } + blk.Body().SetVoluntaryExits(validExits) + + // Set sync aggregate. New in Altair + if slots.ToEpoch(req.Slot) >= params.BeaconConfig().AltairForkEpoch { + syncAggregate, err := vs.getSyncAggregate(ctx, req.Slot-1, bytesutil.ToBytes32(parentRoot)) + if err != nil { + return nil, errors.Wrap(err, "could not compute the sync aggregate") + } + + err = blk.Body().SetSyncAggregate(syncAggregate) + if err != nil { + return nil, errors.Wrap(err, "could not set sync aggregate") + } + } + + // Set execution data. New in Bellatrix + if slots.ToEpoch(req.Slot) >= params.BeaconConfig().BellatrixForkEpoch { + executionData, err := vs.getExecutionPayload(ctx, req.Slot, idx, bytesutil.ToBytes32(parentRoot), head) + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload") + } + err = blk.Body().SetExecution(executionData) + if err != nil { + return nil, errors.Wrap(err, "could not set execution data") + } + } + + // Set bls to execution change. New in Capella + if slots.ToEpoch(req.Slot) >= params.BeaconConfig().CapellaForkEpoch { + changes, err := vs.BLSChangesPool.BLSToExecChangesForInclusion(head) + if err != nil { + return nil, errors.Wrap(err, "could not pack BLSToExecutionChanges") + } + err = blk.Body().SetBLSToExecutionChanges(changes) + if err != nil { + return nil, errors.Wrap(err, "could not set bls to execution changes") + } + } + + blk.SetStateRoot(params.BeaconConfig().ZeroHash[:]) + err = signedblk.SetBlock(blk) + if err != nil { + return nil, err + } + sr, err := vs.computeStateRoot(ctx, signedblk) + if err != nil { + return nil, fmt.Errorf("could not compute state root: %v", err) + } + blk.SetStateRoot(sr) + + pb, err := blk.Proto() + if err != nil { return nil, err } - return vs.getBellatrixBeaconBlock(ctx, req) + switch { + case slots.ToEpoch(req.Slot) < params.BeaconConfig().AltairForkEpoch: + return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Phase0{Phase0: pb.(*ethpb.BeaconBlock)}}, nil + case slots.ToEpoch(req.Slot) < params.BeaconConfig().BellatrixForkEpoch: + return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Altair{Altair: pb.(*ethpb.BeaconBlockAltair)}}, nil + case slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch: + return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Bellatrix{Bellatrix: pb.(*ethpb.BeaconBlockBellatrix)}}, nil + } + return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}}, nil } // ProposeBeaconBlock is called by a proposer during its assigned slot to create a block in an attempt diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_altair.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_altair.go index bb17e192c318..0c767101c5bb 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_altair.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_altair.go @@ -2,11 +2,8 @@ package validator import ( "context" - "fmt" - "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition/interop" "github.com/prysmaticlabs/prysm/v3/config/params" - "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v3/crypto/bls" "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" @@ -15,62 +12,6 @@ import ( "go.opencensus.io/trace" ) -func buildAltairBeaconBlockFromBlockData(blkData *blockData) *ethpb.BeaconBlockAltair { - // Use zero hash as stub for state root to compute later. - stateRoot := params.BeaconConfig().ZeroHash[:] - - return ðpb.BeaconBlockAltair{ - Slot: blkData.Slot, - ParentRoot: blkData.ParentRoot, - StateRoot: stateRoot, - ProposerIndex: blkData.ProposerIdx, - Body: ðpb.BeaconBlockBodyAltair{ - Eth1Data: blkData.Eth1Data, - Deposits: blkData.Deposits, - Attestations: blkData.Attestations, - RandaoReveal: blkData.RandaoReveal, - ProposerSlashings: blkData.ProposerSlashings, - AttesterSlashings: blkData.AttesterSlashings, - VoluntaryExits: blkData.VoluntaryExits, - Graffiti: blkData.Graffiti[:], - SyncAggregate: blkData.SyncAggregate, - }, - } -} - -func (vs *Server) BuildAltairBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlockAltair, error) { - ctx, span := trace.StartSpan(ctx, "ProposerServer.BuildAltairBeaconBlock") - defer span.End() - blkData, err := vs.buildPhase0BlockData(ctx, req) - if err != nil { - return nil, fmt.Errorf("could not build block data: %v", err) - } - return buildAltairBeaconBlockFromBlockData(blkData), nil -} - -func (vs *Server) getAltairBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlockAltair, error) { - ctx, span := trace.StartSpan(ctx, "ProposerServer.getAltairBeaconBlock") - defer span.End() - blk, err := vs.BuildAltairBeaconBlock(ctx, req) - if err != nil { - return nil, fmt.Errorf("could not build block data: %v", err) - } - // Compute state root with the newly constructed block. - wsb, err := blocks.NewSignedBeaconBlock( - ðpb.SignedBeaconBlockAltair{Block: blk, Signature: make([]byte, 96)}, - ) - if err != nil { - return nil, err - } - stateRoot, err := vs.computeStateRoot(ctx, wsb) - if err != nil { - interop.WriteBlockToDisk(wsb, true /*failed*/) - return nil, fmt.Errorf("could not compute state root: %v", err) - } - blk.StateRoot = stateRoot - return blk, nil -} - // getSyncAggregate retrieves the sync contributions from the pool to construct the sync aggregate object. // The contributions are filtered based on matching of the input root and slot then profitability. func (vs *Server) getSyncAggregate(ctx context.Context, slot types.Slot, root [32]byte) (*ethpb.SyncAggregate, error) { diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go index 4781ad205e65..09b770a53456 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go @@ -12,8 +12,6 @@ import ( "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/blocks" "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/signing" - "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition" - "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition/interop" "github.com/prysmaticlabs/prysm/v3/beacon-chain/db/kv" "github.com/prysmaticlabs/prysm/v3/config/params" consensusblocks "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" @@ -57,113 +55,6 @@ func (vs *Server) getBlockFromBuilder(ctx context.Context, altairBlk *ethpb.Beac return nil, errors.New("validator is not registered") } -func (vs *Server) getBellatrixBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.GenericBeaconBlock, error) { - blkData, err := vs.buildPhase0BlockData(ctx, req) - if err != nil { - return nil, err - } - - // If the validator was not registered then we computed already an execution payload - if !req.SkipMevBoost && blkData.ExecutionPayload == nil && blkData.ExecutionPayloadV2 == nil { - altairBlk := buildAltairBeaconBlockFromBlockData(blkData) - b, err := vs.getBlockFromBuilder(ctx, altairBlk) - if err == nil { - return b, nil - } - log.WithError(err).Error("falling back to local execution") - - head, err := vs.HeadFetcher.HeadState(ctx) - if err != nil { - return nil, fmt.Errorf("could not get head state %v", err) - } - - head, err = transition.ProcessSlotsUsingNextSlotCache(ctx, head, blkData.ParentRoot, req.Slot) - if err != nil { - return nil, fmt.Errorf("could not advance slots to calculate proposer index: %v", err) - } - - e, err := vs.getExecutionPayload(ctx, req.Slot, blkData.ProposerIdx, bytesutil.ToBytes32(blkData.ParentRoot), head) - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") - } - p, err := e.PbV1() - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") - } - blkData.ExecutionPayload = p - } - - var wsb interfaces.SignedBeaconBlock - if slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch { - blk := ðpb.BeaconBlockBellatrix{ - Slot: blkData.Slot, - ProposerIndex: blkData.ProposerIdx, - ParentRoot: blkData.ParentRoot, - StateRoot: params.BeaconConfig().ZeroHash[:], - Body: ðpb.BeaconBlockBodyBellatrix{ - RandaoReveal: blkData.RandaoReveal, - Eth1Data: blkData.Eth1Data, - Graffiti: blkData.Graffiti[:], - ProposerSlashings: blkData.ProposerSlashings, - AttesterSlashings: blkData.AttesterSlashings, - Attestations: blkData.Attestations, - Deposits: blkData.Deposits, - VoluntaryExits: blkData.VoluntaryExits, - SyncAggregate: blkData.SyncAggregate, - ExecutionPayload: blkData.ExecutionPayload, - }, - } - // Compute state root with the newly constructed block. - wsb, err = consensusblocks.NewSignedBeaconBlock( - ðpb.SignedBeaconBlockBellatrix{Block: blk, Signature: make([]byte, 96)}, - ) - if err != nil { - return nil, err - } - } else { - blk := ðpb.BeaconBlockCapella{ - Slot: blkData.Slot, - ProposerIndex: blkData.ProposerIdx, - ParentRoot: blkData.ParentRoot, - StateRoot: params.BeaconConfig().ZeroHash[:], - Body: ðpb.BeaconBlockBodyCapella{ - RandaoReveal: blkData.RandaoReveal, - Eth1Data: blkData.Eth1Data, - Graffiti: blkData.Graffiti[:], - ProposerSlashings: blkData.ProposerSlashings, - AttesterSlashings: blkData.AttesterSlashings, - Attestations: blkData.Attestations, - Deposits: blkData.Deposits, - VoluntaryExits: blkData.VoluntaryExits, - SyncAggregate: blkData.SyncAggregate, - ExecutionPayload: blkData.ExecutionPayloadV2, - BlsToExecutionChanges: blkData.BlsToExecutionChanges, - }, - } - // Compute state root with the newly constructed block. - wsb, err = consensusblocks.NewSignedBeaconBlock( - ðpb.SignedBeaconBlockCapella{Block: blk, Signature: make([]byte, 96)}, - ) - if err != nil { - return nil, err - } - } - stateRoot, err := vs.computeStateRoot(ctx, wsb) - if err != nil { - interop.WriteBlockToDisk(wsb, true /*failed*/) - return nil, fmt.Errorf("could not compute state root: %v", err) - } - wsb.Block().SetStateRoot(stateRoot) - pb, err := wsb.Block().Proto() - if err != nil { - return nil, errors.Wrap(err, "could not unmarshal block") - } - if slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch { - return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Bellatrix{Bellatrix: pb.(*ethpb.BeaconBlockBellatrix)}}, nil - } - return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}}, nil -} - // This function retrieves the payload header given the slot number and the validator index. // It's a no-op if the latest head block is not versioned bellatrix. func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot types.Slot, idx types.ValidatorIndex) (*enginev1.ExecutionPayloadHeader, error) { diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_phase0.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_phase0.go deleted file mode 100644 index 948b5f69f862..000000000000 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_phase0.go +++ /dev/null @@ -1,220 +0,0 @@ -package validator - -import ( - "context" - "fmt" - - "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/blocks" - "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/helpers" - "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition" - "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition/interop" - v "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/validators" - "github.com/prysmaticlabs/prysm/v3/config/params" - consensusblocks "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" - types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" - enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1" - ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" - "github.com/prysmaticlabs/prysm/v3/time/slots" - "go.opencensus.io/trace" -) - -// blockData required to create a beacon block. -type blockData struct { - Slot types.Slot - ParentRoot []byte - Graffiti [32]byte - ProposerIdx types.ValidatorIndex - Eth1Data *ethpb.Eth1Data - Deposits []*ethpb.Deposit - Attestations []*ethpb.Attestation - RandaoReveal []byte - ProposerSlashings []*ethpb.ProposerSlashing - AttesterSlashings []*ethpb.AttesterSlashing - VoluntaryExits []*ethpb.SignedVoluntaryExit - SyncAggregate *ethpb.SyncAggregate - ExecutionPayload *enginev1.ExecutionPayload - ExecutionPayloadV2 *enginev1.ExecutionPayloadCapella - BlsToExecutionChanges []*ethpb.SignedBLSToExecutionChange -} - -func (vs *Server) getPhase0BeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlock, error) { - ctx, span := trace.StartSpan(ctx, "ProposerServer.getPhase0BeaconBlock") - defer span.End() - blkData, err := vs.buildPhase0BlockData(ctx, req) - if err != nil { - return nil, fmt.Errorf("could not build block data: %v", err) - } - - // Use zero hash as stub for state root to compute later. - stateRoot := params.BeaconConfig().ZeroHash[:] - - blk := ðpb.BeaconBlock{ - Slot: blkData.Slot, - ParentRoot: blkData.ParentRoot, - StateRoot: stateRoot, - ProposerIndex: blkData.ProposerIdx, - Body: ðpb.BeaconBlockBody{ - Eth1Data: blkData.Eth1Data, - Deposits: blkData.Deposits, - Attestations: blkData.Attestations, - RandaoReveal: blkData.RandaoReveal, - ProposerSlashings: blkData.ProposerSlashings, - AttesterSlashings: blkData.AttesterSlashings, - VoluntaryExits: blkData.VoluntaryExits, - Graffiti: blkData.Graffiti[:], - }, - } - - // Compute state root with the newly constructed block. - wsb, err := consensusblocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: blk, Signature: make([]byte, 96)}) - if err != nil { - return nil, err - } - stateRoot, err = vs.computeStateRoot(ctx, wsb) - if err != nil { - interop.WriteBlockToDisk(wsb, true /*failed*/) - return nil, errors.Wrap(err, "could not compute state root") - } - blk.StateRoot = stateRoot - return blk, nil -} - -// Build data required for creating a new beacon block, so this method can be shared across forks. -func (vs *Server) buildPhase0BlockData(ctx context.Context, req *ethpb.BlockRequest) (*blockData, error) { - ctx, span := trace.StartSpan(ctx, "ProposerServer.buildPhase0BlockData") - defer span.End() - - if vs.SyncChecker.Syncing() { - return nil, fmt.Errorf("syncing to latest head, not ready to respond") - } - - if err := vs.HeadUpdater.UpdateHead(ctx); err != nil { - log.WithError(err).Error("Could not process attestations and update head") - } - - // Retrieve the parent block as the current head of the canonical chain. - parentRoot, err := vs.HeadFetcher.HeadRoot(ctx) - if err != nil { - return nil, fmt.Errorf("could not retrieve head root: %v", err) - } - - head, err := vs.HeadFetcher.HeadState(ctx) - if err != nil { - return nil, fmt.Errorf("could not get head state %v", err) - } - - head, err = transition.ProcessSlotsUsingNextSlotCache(ctx, head, parentRoot, req.Slot) - if err != nil { - return nil, fmt.Errorf("could not advance slots to calculate proposer index: %v", err) - } - - eth1Data, err := vs.eth1DataMajorityVote(ctx, head) - if err != nil { - return nil, fmt.Errorf("could not get ETH1 data: %v", err) - } - - deposits, atts, err := vs.packDepositsAndAttestations(ctx, head, eth1Data) - if err != nil { - return nil, err - } - - graffiti := bytesutil.ToBytes32(req.Graffiti) - - // Calculate new proposer index. - idx, err := helpers.BeaconProposerIndex(ctx, head) - if err != nil { - return nil, fmt.Errorf("could not calculate proposer index %v", err) - } - - proposerSlashings := vs.SlashingsPool.PendingProposerSlashings(ctx, head, false /*noLimit*/) - validProposerSlashings := make([]*ethpb.ProposerSlashing, 0, len(proposerSlashings)) - for _, slashing := range proposerSlashings { - _, err := blocks.ProcessProposerSlashing(ctx, head, slashing, v.SlashValidator) - if err != nil { - log.WithError(err).Warn("Proposer: invalid proposer slashing") - continue - } - validProposerSlashings = append(validProposerSlashings, slashing) - } - - attSlashings := vs.SlashingsPool.PendingAttesterSlashings(ctx, head, false /*noLimit*/) - validAttSlashings := make([]*ethpb.AttesterSlashing, 0, len(attSlashings)) - for _, slashing := range attSlashings { - _, err := blocks.ProcessAttesterSlashing(ctx, head, slashing, v.SlashValidator) - if err != nil { - log.WithError(err).Warn("Proposer: invalid attester slashing") - continue - } - validAttSlashings = append(validAttSlashings, slashing) - } - exits := vs.ExitPool.PendingExits(head, req.Slot, false /*noLimit*/) - validExits := make([]*ethpb.SignedVoluntaryExit, 0, len(exits)) - for _, exit := range exits { - val, err := head.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex) - if err != nil { - log.WithError(err).Warn("Proposer: invalid exit") - continue - } - if err := blocks.VerifyExitAndSignature(val, head.Slot(), head.Fork(), exit, head.GenesisValidatorsRoot()); err != nil { - log.WithError(err).Warn("Proposer: invalid exit") - continue - } - validExits = append(validExits, exit) - } - - blk := &blockData{ - Slot: req.Slot, - ParentRoot: parentRoot, - Graffiti: graffiti, - ProposerIdx: idx, - Eth1Data: eth1Data, - Deposits: deposits, - Attestations: atts, - RandaoReveal: req.RandaoReveal, - ProposerSlashings: validProposerSlashings, - AttesterSlashings: validAttSlashings, - VoluntaryExits: validExits, - } - - if slots.ToEpoch(req.Slot) >= params.BeaconConfig().AltairForkEpoch { - syncAggregate, err := vs.getSyncAggregate(ctx, req.Slot-1, bytesutil.ToBytes32(parentRoot)) - if err != nil { - return nil, errors.Wrap(err, "could not compute the sync aggregate") - } - - blk.SyncAggregate = syncAggregate - } - - if slots.ToEpoch(req.Slot) >= params.BeaconConfig().BellatrixForkEpoch { - // We request the execution payload only if the validator is not registered with a relayer - registered, err := vs.validatorRegistered(ctx, idx) - if !registered || err != nil { - executionData, err := vs.getExecutionPayload(ctx, req.Slot, idx, bytesutil.ToBytes32(parentRoot), head) - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") - } - if slots.ToEpoch(req.Slot) >= params.BeaconConfig().CapellaForkEpoch { - p, err := executionData.PbV2() - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload v2") - } - blk.ExecutionPayloadV2 = p - changes, err := vs.BLSChangesPool.BLSToExecChangesForInclusion(head) - if err != nil { - return nil, errors.Wrap(err, "could not pack BLSToExecutionChanges") - } - blk.BlsToExecutionChanges = changes - } else { - p, err := executionData.PbV1() - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload v2") - } - blk.ExecutionPayload = p - } - } - } - - return blk, nil -} diff --git a/consensus-types/blocks/getters.go b/consensus-types/blocks/getters.go index e5cc18aced84..fa013e2bd7d0 100644 --- a/consensus-types/blocks/getters.go +++ b/consensus-types/blocks/getters.go @@ -29,11 +29,59 @@ func (b *SignedBeaconBlock) Signature() [field_params.BLSSignatureLength]byte { return b.signature } +// SetSignature sets the signature of the signed beacon block. +func (b *SignedBeaconBlock) SetSignature(sig []byte) { + copy(b.signature[:], sig) +} + // Block returns the underlying beacon block object. func (b *SignedBeaconBlock) Block() interfaces.BeaconBlock { return b.block } +// SetBlock sets the underlying beacon block object. +func (b *SignedBeaconBlock) SetBlock(blk interfaces.BeaconBlock) error { + b.block.slot = blk.Slot() + b.block.parentRoot = blk.ParentRoot() + b.block.stateRoot = blk.StateRoot() + b.block.stateRoot = blk.StateRoot() + b.block.proposerIndex = blk.ProposerIndex() + b.block.body.randaoReveal = blk.Body().RandaoReveal() + b.block.body.eth1Data = blk.Body().Eth1Data() + b.block.body.graffiti = blk.Body().Graffiti() + b.block.body.proposerSlashings = blk.Body().ProposerSlashings() + b.block.body.attesterSlashings = blk.Body().AttesterSlashings() + b.block.body.attestations = blk.Body().Attestations() + b.block.body.deposits = blk.Body().Deposits() + b.block.body.voluntaryExits = blk.Body().VoluntaryExits() + if b.version >= version.Altair { + syncAggregate, err := blk.Body().SyncAggregate() + if err != nil { + return err + } + b.block.body.syncAggregate = syncAggregate + } + if b.version >= version.Bellatrix { + executionData, err := blk.Body().Execution() + if err != nil { + return err + } + if b.block.body.isBlinded { + b.block.body.executionPayloadHeader = executionData + } else { + b.block.body.executionPayload = executionData + } + } + if b.version >= version.Capella { + changes, err := blk.Body().BLSToExecutionChanges() + if err != nil { + return err + } + b.block.body.blsToExecutionChanges = changes + } + return nil +} + // IsNil checks if the underlying beacon block is nil. func (b *SignedBeaconBlock) IsNil() bool { return b == nil || b.block.IsNil() @@ -458,16 +506,34 @@ func (b *BeaconBlock) Slot() types.Slot { return b.slot } +// SetSlot sets the respective slot of the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlock) SetSlot(slot types.Slot) { + b.slot = slot +} + // ProposerIndex returns the proposer index of the beacon block. func (b *BeaconBlock) ProposerIndex() types.ValidatorIndex { return b.proposerIndex } +// SetProposerIndex sets the proposer index of the beacon block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlock) SetProposerIndex(proposerIndex types.ValidatorIndex) { + b.proposerIndex = proposerIndex +} + // ParentRoot returns the parent root of beacon block. func (b *BeaconBlock) ParentRoot() [field_params.RootLength]byte { return b.parentRoot } +// SetParentRoot sets the parent root of beacon block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlock) SetParentRoot(parentRoot []byte) { + copy(b.parentRoot[:], parentRoot) +} + // StateRoot returns the state root of the beacon block. func (b *BeaconBlock) StateRoot() [field_params.RootLength]byte { return b.stateRoot @@ -748,41 +814,81 @@ func (b *BeaconBlockBody) RandaoReveal() [field_params.BLSSignatureLength]byte { return b.randaoReveal } +// SetRandaoReveal sets the randao reveal in the block body. +func (b *BeaconBlockBody) SetRandaoReveal(r []byte) { + copy(b.randaoReveal[:], r) +} + // Eth1Data returns the eth1 data in the block. func (b *BeaconBlockBody) Eth1Data() *eth.Eth1Data { return b.eth1Data } +// SetEth1Data sets the eth1 data in the block. +func (b *BeaconBlockBody) SetEth1Data(e *eth.Eth1Data) { + b.eth1Data = eth.CopyETH1Data(e) +} + // Graffiti returns the graffiti in the block. func (b *BeaconBlockBody) Graffiti() [field_params.RootLength]byte { return b.graffiti } +// SetGraffiti sets the graffiti in the block. +func (b *BeaconBlockBody) SetGraffiti(g []byte) { + copy(b.graffiti[:], g) +} + // ProposerSlashings returns the proposer slashings in the block. func (b *BeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing { return b.proposerSlashings } +// SetProposerSlashings sets the proposer slashings in the block. +func (b *BeaconBlockBody) SetProposerSlashings(p []*eth.ProposerSlashing) { + b.proposerSlashings = eth.CopyProposerSlashings(p) +} + // AttesterSlashings returns the attester slashings in the block. func (b *BeaconBlockBody) AttesterSlashings() []*eth.AttesterSlashing { return b.attesterSlashings } +// SetAttesterSlashings sets the attester slashings in the block. +func (b *BeaconBlockBody) SetAttesterSlashings(a []*eth.AttesterSlashing) { + b.attesterSlashings = eth.CopyAttesterSlashings(a) +} + // Attestations returns the stored attestations in the block. func (b *BeaconBlockBody) Attestations() []*eth.Attestation { return b.attestations } +// SetAttestations sets the attestations in the block. +func (b *BeaconBlockBody) SetAttestations(a []*eth.Attestation) { + b.attestations = eth.CopyAttestations(a) +} + // Deposits returns the stored deposits in the block. func (b *BeaconBlockBody) Deposits() []*eth.Deposit { return b.deposits } +// SetDeposits sets the deposits in the block. +func (b *BeaconBlockBody) SetDeposits(d []*eth.Deposit) { + b.deposits = eth.CopyDeposits(d) +} + // VoluntaryExits returns the voluntary exits in the block. func (b *BeaconBlockBody) VoluntaryExits() []*eth.SignedVoluntaryExit { return b.voluntaryExits } +// SetVoluntaryExits sets the voluntary exits in the block. +func (b *BeaconBlockBody) SetVoluntaryExits(v []*eth.SignedVoluntaryExit) { + b.voluntaryExits = eth.CopySignedVoluntaryExits(v) +} + // SyncAggregate returns the sync aggregate in the block. func (b *BeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) { if b.version == version.Phase0 { @@ -791,6 +897,15 @@ func (b *BeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) { return b.syncAggregate, nil } +// SetSyncAggregate sets the sync aggregate in the block. +func (b *BeaconBlockBody) SetSyncAggregate(s *eth.SyncAggregate) error { + if b.version == version.Phase0 { + return ErrNotSupported("SyncAggregate", b.version) + } + b.syncAggregate = eth.CopySyncAggregate(s) + return nil +} + // Execution returns the execution payload of the block body. func (b *BeaconBlockBody) Execution() (interfaces.ExecutionData, error) { switch b.version { @@ -843,6 +958,19 @@ func (b *BeaconBlockBody) Execution() (interfaces.ExecutionData, error) { } } +// SetExecution sets the execution payload of the block body. +func (b *BeaconBlockBody) SetExecution(e interfaces.ExecutionData) error { + if b.version == version.Phase0 || b.version == version.Altair { + return ErrNotSupported("Execution", b.version) + } + if b.isBlinded { + b.executionPayloadHeader = e // TODO: Copy? + return nil + } + b.executionPayload = e + return nil +} + func (b *BeaconBlockBody) BLSToExecutionChanges() ([]*eth.SignedBLSToExecutionChange, error) { if b.version < version.Capella { return nil, ErrNotSupported("BLSToExecutionChanges", b.version) @@ -850,6 +978,15 @@ func (b *BeaconBlockBody) BLSToExecutionChanges() ([]*eth.SignedBLSToExecutionCh return b.blsToExecutionChanges, nil } +// SetBLSToExecutionChanges sets the BLS to execution changes in the block. +func (b *BeaconBlockBody) SetBLSToExecutionChanges(blsToExecutionChanges []*eth.SignedBLSToExecutionChange) error { + if b.version < version.Capella { + return ErrNotSupported("BLSToExecutionChanges", b.version) + } + b.blsToExecutionChanges = eth.CopyBLSToExecutionChanges(blsToExecutionChanges) + return nil +} + // HashTreeRoot returns the ssz root of the block body. func (b *BeaconBlockBody) HashTreeRoot() ([field_params.RootLength]byte, error) { pb, err := b.Proto() diff --git a/consensus-types/interfaces/beacon_block.go b/consensus-types/interfaces/beacon_block.go index 258a2c4b797b..07067cd4a551 100644 --- a/consensus-types/interfaces/beacon_block.go +++ b/consensus-types/interfaces/beacon_block.go @@ -14,7 +14,9 @@ import ( // a signed beacon block. type SignedBeaconBlock interface { Block() BeaconBlock + SetBlock(BeaconBlock) error Signature() [field_params.BLSSignatureLength]byte + SetSignature(sig []byte) IsNil() bool Copy() (SignedBeaconBlock, error) Proto() (proto.Message, error) @@ -37,8 +39,11 @@ type SignedBeaconBlock interface { // employed by an object that is a beacon block. type BeaconBlock interface { Slot() types.Slot + SetSlot(slot types.Slot) ProposerIndex() types.ValidatorIndex + SetProposerIndex(idx types.ValidatorIndex) ParentRoot() [field_params.RootLength]byte + SetParentRoot([]byte) StateRoot() [field_params.RootLength]byte SetStateRoot([]byte) Body() BeaconBlockBody @@ -57,19 +62,30 @@ type BeaconBlock interface { // that is a beacon block body. type BeaconBlockBody interface { RandaoReveal() [field_params.BLSSignatureLength]byte + SetRandaoReveal([]byte) Eth1Data() *ethpb.Eth1Data + SetEth1Data(*ethpb.Eth1Data) Graffiti() [field_params.RootLength]byte + SetGraffiti([]byte) ProposerSlashings() []*ethpb.ProposerSlashing + SetProposerSlashings([]*ethpb.ProposerSlashing) AttesterSlashings() []*ethpb.AttesterSlashing + SetAttesterSlashings([]*ethpb.AttesterSlashing) Attestations() []*ethpb.Attestation + SetAttestations([]*ethpb.Attestation) Deposits() []*ethpb.Deposit + SetDeposits([]*ethpb.Deposit) VoluntaryExits() []*ethpb.SignedVoluntaryExit + SetVoluntaryExits([]*ethpb.SignedVoluntaryExit) SyncAggregate() (*ethpb.SyncAggregate, error) + SetSyncAggregate(*ethpb.SyncAggregate) error IsNil() bool HashTreeRoot() ([field_params.RootLength]byte, error) Proto() (proto.Message, error) Execution() (ExecutionData, error) + SetExecution(ExecutionData) error BLSToExecutionChanges() ([]*ethpb.SignedBLSToExecutionChange, error) + SetBLSToExecutionChanges([]*ethpb.SignedBLSToExecutionChange) error } // ExecutionData represents execution layer information that is contained From d9646a9183038ade835b38f4061d008a3da05984 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sat, 3 Dec 2022 07:29:46 -0800 Subject: [PATCH 2/7] Add builder paths --- beacon-chain/rpc/eth/validator/validator.go | 11 +- .../rpc/prysm/v1alpha1/validator/proposer.go | 81 ++++++++--- .../v1alpha1/validator/proposer_bellatrix.go | 131 ++---------------- consensus-types/blocks/getters.go | 5 + consensus-types/interfaces/beacon_block.go | 1 + 5 files changed, 77 insertions(+), 152 deletions(-) diff --git a/beacon-chain/rpc/eth/validator/validator.go b/beacon-chain/rpc/eth/validator/validator.go index bd40911ac1e0..7902f601ec37 100644 --- a/beacon-chain/rpc/eth/validator/validator.go +++ b/beacon-chain/rpc/eth/validator/validator.go @@ -488,16 +488,9 @@ func (vs *Server) ProduceBlindedBlock(ctx context.Context, req *ethpbv1.ProduceB if optimistic { return nil, status.Errorf(codes.Unavailable, "The node is currently optimistic and cannot serve validators") } - altairBlk, err := vs.V1Alpha1Server.BuildAltairBeaconBlock(ctx, v1alpha1req) + b, err := vs.V1Alpha1Server.GetBeaconBlock(ctx, v1alpha1req) if err != nil { - return nil, status.Errorf(codes.Internal, "Could not prepare beacon block: %v", err) - } - ok, b, err := vs.V1Alpha1Server.GetAndBuildBlindBlock(ctx, altairBlk) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not prepare blind beacon block: %v", err) - } - if !ok { - return nil, status.Error(codes.Unavailable, "Builder is not available due to miss-config or circuit breaker") + return nil, err } blk, err := migration.V1Alpha1BeaconBlockBlindedBellatrixToV2Blinded(b.GetBlindedBellatrix()) if err != nil { diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go index d7e2e72bb2ff..81a1a638461e 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go @@ -56,24 +56,45 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( } var blk interfaces.BeaconBlock - var signedblk interfaces.SignedBeaconBlock + var sBlk interfaces.SignedBeaconBlock var err error switch { case slots.ToEpoch(req.Slot) < params.BeaconConfig().AltairForkEpoch: blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlock{}) - signedblk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlock{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlock{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } case slots.ToEpoch(req.Slot) < params.BeaconConfig().BellatrixForkEpoch: blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockAltair{}) - signedblk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } case slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch: blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockBellatrix{}) - signedblk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } default: blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockCapella{}) - signedblk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockCapella{}) - } - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockCapella{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } } parentRoot, err := vs.HeadFetcher.HeadRoot(ctx) @@ -163,22 +184,39 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( if err != nil { return nil, errors.Wrap(err, "could not compute the sync aggregate") } - - err = blk.Body().SetSyncAggregate(syncAggregate) - if err != nil { + if err := blk.Body().SetSyncAggregate(syncAggregate); err != nil { return nil, errors.Wrap(err, "could not set sync aggregate") } } // Set execution data. New in Bellatrix if slots.ToEpoch(req.Slot) >= params.BeaconConfig().BellatrixForkEpoch { - executionData, err := vs.getExecutionPayload(ctx, req.Slot, idx, bytesutil.ToBytes32(parentRoot), head) + fallBackToLocal := true + canUseBuilder, err := vs.canUseBuilder(ctx, req.Slot, idx) if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") + log.WithError(err).Warn("Proposer: failed to check if builder can be used") } - err = blk.Body().SetExecution(executionData) - if err != nil { - return nil, errors.Wrap(err, "could not set execution data") + if canUseBuilder && err != nil { + h, err := vs.getPayloadHeaderFromBuilder(ctx, req.Slot, idx) + if err != nil { + log.WithError(err).Warn("Proposer: failed to get payload header from builder") + } else { + blk.SetBlinded(true) + if err := blk.Body().SetExecution(h); err != nil { + log.WithError(err).Warn("Proposer: failed to set execution payload") + } else { + fallBackToLocal = true + } + } + } + if !fallBackToLocal { + executionData, err := vs.getExecutionPayload(ctx, req.Slot, idx, bytesutil.ToBytes32(parentRoot), head) + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload") + } + if err := blk.Body().SetExecution(executionData); err != nil { + return nil, errors.Wrap(err, "could not set execution payload") + } } } @@ -188,18 +226,15 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( if err != nil { return nil, errors.Wrap(err, "could not pack BLSToExecutionChanges") } - err = blk.Body().SetBLSToExecutionChanges(changes) - if err != nil { - return nil, errors.Wrap(err, "could not set bls to execution changes") + if err := blk.Body().SetBLSToExecutionChanges(changes); err != nil { + return nil, errors.Wrap(err, "could not set BLSToExecutionChanges") } } - blk.SetStateRoot(params.BeaconConfig().ZeroHash[:]) - err = signedblk.SetBlock(blk) - if err != nil { + if err := sBlk.SetBlock(blk); err != nil { return nil, err } - sr, err := vs.computeStateRoot(ctx, signedblk) + sr, err := vs.computeStateRoot(ctx, sBlk) if err != nil { return nil, fmt.Errorf("could not compute state root: %v", err) } diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go index 09b770a53456..83551e96c934 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go @@ -37,27 +37,20 @@ var builderGetPayloadMissCount = promauto.NewCounter(prometheus.CounterOpts{ // block request. This value is known as `BUILDER_PROPOSAL_DELAY_TOLERANCE` in builder spec. const blockBuilderTimeout = 1 * time.Second -func (vs *Server) getBlockFromBuilder(ctx context.Context, altairBlk *ethpb.BeaconBlockAltair) ( - *ethpb.GenericBeaconBlock, error) { - registered, err := vs.validatorRegistered(ctx, altairBlk.ProposerIndex) - if registered && err == nil { - builderReady, b, err := vs.GetAndBuildBlindBlock(ctx, altairBlk) - if err != nil { - // In the event of an error, the node should fall back to default execution engine for building block. - builderGetPayloadMissCount.Inc() - return nil, err - } else if builderReady { - return b, nil - } - } else if err != nil { - return nil, err +func (vs *Server) canUseBuilder(ctx context.Context, slot types.Slot, idx types.ValidatorIndex) (bool, error) { + registered, err := vs.validatorRegistered(ctx, idx) + if err != nil { + return false, err } - return nil, errors.New("validator is not registered") + if !registered { + return false, nil + } + return vs.circuitBreakBuilder(slot) } // This function retrieves the payload header given the slot number and the validator index. // It's a no-op if the latest head block is not versioned bellatrix. -func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot types.Slot, idx types.ValidatorIndex) (*enginev1.ExecutionPayloadHeader, error) { +func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot types.Slot, idx types.ValidatorIndex) (interfaces.ExecutionData, error) { b, err := vs.HeadFetcher.HeadBlock(ctx) if err != nil { return nil, err @@ -117,48 +110,8 @@ func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot types.Sl "builderPubKey": fmt.Sprintf("%#x", bid.Message.Pubkey), "blockHash": fmt.Sprintf("%#x", bid.Message.Header.BlockHash), }).Info("Received header with bid") - return bid.Message.Header, nil -} -// This function constructs the builder block given the input altair block and the header. It returns a generic beacon block for signing -func (vs *Server) buildBlindBlock(ctx context.Context, b *ethpb.BeaconBlockAltair, h *enginev1.ExecutionPayloadHeader) (*ethpb.GenericBeaconBlock, error) { - if b == nil || b.Body == nil { - return nil, errors.New("nil block") - } - if h == nil { - return nil, errors.New("nil header") - } - - blk := ðpb.BlindedBeaconBlockBellatrix{ - Slot: b.Slot, - ProposerIndex: b.ProposerIndex, - ParentRoot: b.ParentRoot, - StateRoot: params.BeaconConfig().ZeroHash[:], - Body: ðpb.BlindedBeaconBlockBodyBellatrix{ - RandaoReveal: b.Body.RandaoReveal, - Eth1Data: b.Body.Eth1Data, - Graffiti: b.Body.Graffiti, - ProposerSlashings: b.Body.ProposerSlashings, - AttesterSlashings: b.Body.AttesterSlashings, - Attestations: b.Body.Attestations, - Deposits: b.Body.Deposits, - VoluntaryExits: b.Body.VoluntaryExits, - SyncAggregate: b.Body.SyncAggregate, - ExecutionPayloadHeader: h, - }, - } - wsb, err := consensusblocks.NewSignedBeaconBlock( - ðpb.SignedBlindedBeaconBlockBellatrix{Block: blk, Signature: make([]byte, 96)}, - ) - if err != nil { - return nil, err - } - stateRoot, err := vs.computeStateRoot(ctx, wsb) - if err != nil { - return nil, errors.Wrap(err, "could not compute state root") - } - blk.StateRoot = stateRoot - return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: blk}}, nil + return coreBlock.WrappedExecutionPayloadHeader(bid.Message.Header) } // This function retrieves the full payload block using the input blind block. This input must be versioned as @@ -272,24 +225,6 @@ func (vs *Server) unblindBuilderBlock(ctx context.Context, b interfaces.SignedBe return wb, nil } -// readyForBuilder returns true if builder is allowed to be used. Builder is only allowed to be use after the -// first finalized checkpt has been execution-enabled. -func (vs *Server) readyForBuilder(ctx context.Context) (bool, error) { - cp := vs.FinalizationFetcher.FinalizedCheckpt() - // Checkpoint root is zero means we are still at genesis epoch. - if bytesutil.ToBytes32(cp.Root) == params.BeaconConfig().ZeroHash { - return false, nil - } - b, err := vs.BeaconDB.Block(ctx, bytesutil.ToBytes32(cp.Root)) - if err != nil { - return false, err - } - if err = coreBlock.BeaconBlockIsNil(b); err != nil { - return false, err - } - return blocks.IsExecutionBlock(b.Block().Body()) -} - // circuitBreakBuilder returns true if the builder is not allowed to be used due to circuit breaker conditions. func (vs *Server) circuitBreakBuilder(s types.Slot) (bool, error) { if vs.ForkFetcher == nil || vs.ForkFetcher.ForkChoicer() == nil { @@ -338,50 +273,6 @@ func (vs *Server) circuitBreakBuilder(s types.Slot) (bool, error) { return false, nil } -// GetAndBuildBlindBlock builds blind block from builder network. Returns a boolean status, built block and error. -// If the status is false that means builder the header block is disallowed. -// This routine is time limited by `blockBuilderTimeout`. -func (vs *Server) GetAndBuildBlindBlock(ctx context.Context, b *ethpb.BeaconBlockAltair) (bool, *ethpb.GenericBeaconBlock, error) { - // No op. Builder is not defined. User did not specify a user URL. We should use local EE. - if vs.BlockBuilder == nil || !vs.BlockBuilder.Configured() { - return false, nil, nil - } - ctx, cancel := context.WithTimeout(ctx, blockBuilderTimeout) - defer cancel() - // Does the protocol allow for builder at this current moment. Builder is only allowed post merge after finalization. - ready, err := vs.readyForBuilder(ctx) - if err != nil { - return false, nil, errors.Wrap(err, "could not determine if builder is ready") - } - if !ready { - return false, nil, nil - } - - circuitBreak, err := vs.circuitBreakBuilder(b.Slot) - if err != nil { - return false, nil, errors.Wrap(err, "could not determine if builder circuit breaker condition") - } - if circuitBreak { - return false, nil, nil - } - - h, err := vs.getPayloadHeaderFromBuilder(ctx, b.Slot, b.ProposerIndex) - if err != nil { - return false, nil, errors.Wrap(err, "could not get payload header") - } - log.WithFields(logrus.Fields{ - "blockHash": fmt.Sprintf("%#x", h.BlockHash), - "feeRecipient": fmt.Sprintf("%#x", h.FeeRecipient), - "gasUsed": h.GasUsed, - "slot": b.Slot, - }).Info("Retrieved header from builder") - gb, err := vs.buildBlindBlock(ctx, b, h) - if err != nil { - return false, nil, errors.Wrap(err, "could not combine altair block with payload header") - } - return true, gb, nil -} - // validatorRegistered returns true if validator with index `id` was previously registered in the database. func (vs *Server) validatorRegistered(ctx context.Context, id types.ValidatorIndex) (bool, error) { if vs.BeaconDB == nil { @@ -401,7 +292,7 @@ func (vs *Server) validatorRegistered(ctx context.Context, id types.ValidatorInd func (vs *Server) validateBuilderSignature(bid *ethpb.SignedBuilderBid) error { d, err := signing.ComputeDomain(params.BeaconConfig().DomainApplicationBuilder, nil, /* fork version */ - nil /* genesis val root */) + nil /* genesis val root */) if err != nil { return err } diff --git a/consensus-types/blocks/getters.go b/consensus-types/blocks/getters.go index fa013e2bd7d0..97b63fa2c00b 100644 --- a/consensus-types/blocks/getters.go +++ b/consensus-types/blocks/getters.go @@ -561,6 +561,11 @@ func (b *BeaconBlock) IsBlinded() bool { return b.body.isBlinded } +// SetBlinded sets the blinded flag of the beacon block. +func (b *BeaconBlock) SetBlinded(blinded bool) { + b.body.isBlinded = blinded +} + // Version of the underlying protobuf object. func (b *BeaconBlock) Version() int { return b.version diff --git a/consensus-types/interfaces/beacon_block.go b/consensus-types/interfaces/beacon_block.go index 07067cd4a551..9dfa04b03c95 100644 --- a/consensus-types/interfaces/beacon_block.go +++ b/consensus-types/interfaces/beacon_block.go @@ -56,6 +56,7 @@ type BeaconBlock interface { ssz.HashRoot Version() int AsSignRequestObject() (validatorpb.SignRequestObject, error) + SetBlinded(bool) } // BeaconBlockBody describes the method set employed by an object From 468cc238761abd59708c0a2884c3cfbf42bf5081 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sun, 4 Dec 2022 07:47:34 -0800 Subject: [PATCH 3/7] Fix interop --- .../execution/testing/mock_engine_client.go | 9 +++++-- .../rpc/prysm/v1alpha1/validator/proposer.go | 24 +++++++++---------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/beacon-chain/execution/testing/mock_engine_client.go b/beacon-chain/execution/testing/mock_engine_client.go index aed18d8ed04f..0e6380202668 100644 --- a/beacon-chain/execution/testing/mock_engine_client.go +++ b/beacon-chain/execution/testing/mock_engine_client.go @@ -12,6 +12,7 @@ import ( "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" payloadattribute "github.com/prysmaticlabs/prysm/v3/consensus-types/payload-attribute" + types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" pb "github.com/prysmaticlabs/prysm/v3/proto/engine/v1" ) @@ -53,8 +54,12 @@ func (e *EngineClient) ForkchoiceUpdated( } // GetPayload -- -func (e *EngineClient) GetPayload(_ context.Context, _ [8]byte) (*pb.ExecutionPayload, error) { - return e.ExecutionPayload, e.ErrGetPayload +func (e *EngineClient) GetPayload(_ context.Context, _ [8]byte, slot types.Slot) (interfaces.ExecutionData, error) { + p, err := blocks.WrappedExecutionPayload(e.ExecutionPayload) + if err != nil { + return nil, err + } + return p, e.ErrGetPayload } func (e *EngineClient) GetPayloadV2(_ context.Context, _ [8]byte) (*pb.ExecutionPayloadCapella, error) { diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go index 81a1a638461e..df930f37119b 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go @@ -60,38 +60,38 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( var err error switch { case slots.ToEpoch(req.Slot) < params.BeaconConfig().AltairForkEpoch: - blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlock{}) + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}) if err != nil { return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) } - sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlock{}) + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}}) if err != nil { return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) } case slots.ToEpoch(req.Slot) < params.BeaconConfig().BellatrixForkEpoch: - blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockAltair{}) + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockAltair{Body: ðpb.BeaconBlockBodyAltair{}}) if err != nil { return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) } - sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{}) + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{Block: ðpb.BeaconBlockAltair{Body: ðpb.BeaconBlockBodyAltair{}}}) if err != nil { return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) } case slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch: - blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockBellatrix{}) + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockBellatrix{Body: ðpb.BeaconBlockBodyBellatrix{}}) if err != nil { return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) } - sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{}) + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{Block: ðpb.BeaconBlockBellatrix{Body: ðpb.BeaconBlockBodyBellatrix{}}}) if err != nil { return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) } default: - blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockCapella{}) + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockCapella{Body: ðpb.BeaconBlockBodyCapella{}}) if err != nil { return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) } - sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockCapella{}) + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockCapella{Block: ðpb.BeaconBlockCapella{Body: ðpb.BeaconBlockBodyCapella{}}}) if err != nil { return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) } @@ -110,11 +110,11 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( return nil, fmt.Errorf("could not advance slots to calculate proposer index: %v", err) } - // Set slot, graffiti and parent root. + // Set slot, graffiti, randao reveal, and parent root. blk.SetSlot(req.Slot) blk.Body().SetGraffiti(req.Graffiti) + blk.Body().SetRandaoReveal(req.RandaoReveal) blk.SetParentRoot(parentRoot) - // Set eth1 data. eth1Data, err := vs.eth1DataMajorityVote(ctx, head) if err != nil { @@ -205,11 +205,11 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( if err := blk.Body().SetExecution(h); err != nil { log.WithError(err).Warn("Proposer: failed to set execution payload") } else { - fallBackToLocal = true + fallBackToLocal = false } } } - if !fallBackToLocal { + if fallBackToLocal { executionData, err := vs.getExecutionPayload(ctx, req.Slot, idx, bytesutil.ToBytes32(parentRoot), head) if err != nil { return nil, errors.Wrap(err, "could not get execution payload") From a0c9d4b2fc8c5304fbf6c1a747c403d29d5f812b Mon Sep 17 00:00:00 2001 From: terence tsao Date: Wed, 7 Dec 2022 07:47:42 -0800 Subject: [PATCH 4/7] Feedback --- beacon-chain/execution/testing/BUILD.bazel | 1 + .../rpc/prysm/v1alpha1/validator/proposer.go | 254 ++++++++++-------- 2 files changed, 142 insertions(+), 113 deletions(-) diff --git a/beacon-chain/execution/testing/BUILD.bazel b/beacon-chain/execution/testing/BUILD.bazel index ce490c70769f..bd5ec6a4e1d9 100644 --- a/beacon-chain/execution/testing/BUILD.bazel +++ b/beacon-chain/execution/testing/BUILD.bazel @@ -21,6 +21,7 @@ go_library( "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", "//consensus-types/payload-attribute:go_default_library", + "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go index df930f37119b..f237914b9a99 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go @@ -19,6 +19,8 @@ import ( "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition" v "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/validators" "github.com/prysmaticlabs/prysm/v3/beacon-chain/db/kv" + "github.com/prysmaticlabs/prysm/v3/beacon-chain/state" + fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" "github.com/prysmaticlabs/prysm/v3/config/params" "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" @@ -47,67 +49,30 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( // A syncing validator should not produce a block. if vs.SyncChecker.Syncing() { - return nil, fmt.Errorf("syncing to latest head, not ready to respond") + return nil, status.Error(codes.Unavailable, "Syncing to latest head, not ready to respond") } // An optimistic validator MUST NOT produce a block (i.e., sign across the DOMAIN_BEACON_PROPOSER domain). if err := vs.optimisticStatus(ctx); err != nil { - return nil, err + return nil, status.Errorf(codes.Unavailable, "Validator is not ready to propose: %v", err) } - var blk interfaces.BeaconBlock - var sBlk interfaces.SignedBeaconBlock - var err error - switch { - case slots.ToEpoch(req.Slot) < params.BeaconConfig().AltairForkEpoch: - blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) - } - sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}}) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) - } - case slots.ToEpoch(req.Slot) < params.BeaconConfig().BellatrixForkEpoch: - blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockAltair{Body: ðpb.BeaconBlockBodyAltair{}}) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) - } - sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{Block: ðpb.BeaconBlockAltair{Body: ðpb.BeaconBlockBodyAltair{}}}) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) - } - case slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch: - blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockBellatrix{Body: ðpb.BeaconBlockBodyBellatrix{}}) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) - } - sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{Block: ðpb.BeaconBlockBellatrix{Body: ðpb.BeaconBlockBodyBellatrix{}}}) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) - } - default: - blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockCapella{Body: ðpb.BeaconBlockBodyCapella{}}) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) - } - sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockCapella{Block: ðpb.BeaconBlockCapella{Body: ðpb.BeaconBlockBodyCapella{}}}) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) - } + blk, sBlk, err := emptyBlockToSign(req.Slot) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not prepare block: %v", err) } parentRoot, err := vs.HeadFetcher.HeadRoot(ctx) if err != nil { - return nil, fmt.Errorf("could not retrieve head root: %v", err) + return nil, status.Errorf(codes.Internal, "Could not get head root: %v", err) } head, err := vs.HeadFetcher.HeadState(ctx) if err != nil { - return nil, fmt.Errorf("could not get head state %v", err) + return nil, status.Errorf(codes.Internal, "Could not get head state: %v", err) } head, err = transition.ProcessSlotsUsingNextSlotCache(ctx, head, parentRoot, req.Slot) if err != nil { - return nil, fmt.Errorf("could not advance slots to calculate proposer index: %v", err) + return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", req.Slot, err) } // Set slot, graffiti, randao reveal, and parent root. @@ -115,20 +80,23 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( blk.Body().SetGraffiti(req.Graffiti) blk.Body().SetRandaoReveal(req.RandaoReveal) blk.SetParentRoot(parentRoot) + // Set eth1 data. eth1Data, err := vs.eth1DataMajorityVote(ctx, head) if err != nil { - return nil, fmt.Errorf("could not get ETH1 data: %v", err) - } - blk.Body().SetEth1Data(eth1Data) + log.WithError(err).Error("Could not get eth1data") + } else { + blk.Body().SetEth1Data(eth1Data) - // Set deposit and attestation. - deposits, atts, err := vs.packDepositsAndAttestations(ctx, head, eth1Data) - if err != nil { - return nil, err + // Set deposit and attestation. + deposits, atts, err := vs.packDepositsAndAttestations(ctx, head, eth1Data) // TODO: split attestations and deposits + if err != nil { + log.WithError(err).Error("Could not pack deposits and attestations") + } else { + blk.Body().SetDeposits(deposits) + blk.Body().SetAttestations(atts) + } } - blk.Body().SetDeposits(deposits) - blk.Body().SetAttestations(atts) // Set proposer index idx, err := helpers.BeaconProposerIndex(ctx, head) @@ -138,54 +106,28 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( blk.SetProposerIndex(idx) // Set slashings - proposerSlashings := vs.SlashingsPool.PendingProposerSlashings(ctx, head, false /*noLimit*/) - validProposerSlashings := make([]*ethpb.ProposerSlashing, 0, len(proposerSlashings)) - for _, slashing := range proposerSlashings { - _, err := blocks2.ProcessProposerSlashing(ctx, head, slashing, v.SlashValidator) - if err != nil { - log.WithError(err).Warn("Proposer: invalid proposer slashing") - continue - } - validProposerSlashings = append(validProposerSlashings, slashing) - } - attSlashings := vs.SlashingsPool.PendingAttesterSlashings(ctx, head, false /*noLimit*/) - validAttSlashings := make([]*ethpb.AttesterSlashing, 0, len(attSlashings)) - for _, slashing := range attSlashings { - _, err := blocks2.ProcessAttesterSlashing(ctx, head, slashing, v.SlashValidator) - if err != nil { - log.WithError(err).Warn("Proposer: invalid attester slashing") - continue - } - validAttSlashings = append(validAttSlashings, slashing) - } + validProposerSlashings, validAttSlashings := vs.getSlashings(ctx, head) blk.Body().SetProposerSlashings(validProposerSlashings) blk.Body().SetAttesterSlashings(validAttSlashings) // Set exits - exits := vs.ExitPool.PendingExits(head, req.Slot, false /*noLimit*/) - validExits := make([]*ethpb.SignedVoluntaryExit, 0, len(exits)) - for _, exit := range exits { - val, err := head.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex) - if err != nil { - log.WithError(err).Warn("Proposer: invalid exit") - continue - } - if err := blocks2.VerifyExitAndSignature(val, head.Slot(), head.Fork(), exit, head.GenesisValidatorsRoot()); err != nil { - log.WithError(err).Warn("Proposer: invalid exit") - continue - } - validExits = append(validExits, exit) - } - blk.Body().SetVoluntaryExits(validExits) + blk.Body().SetVoluntaryExits(vs.getExits(head, req)) - // Set sync aggregate. New in Altair - if slots.ToEpoch(req.Slot) >= params.BeaconConfig().AltairForkEpoch { + // Set sync aggregate. New in Altair. + if req.Slot > 0 && slots.ToEpoch(req.Slot) >= params.BeaconConfig().AltairForkEpoch { syncAggregate, err := vs.getSyncAggregate(ctx, req.Slot-1, bytesutil.ToBytes32(parentRoot)) if err != nil { - return nil, errors.Wrap(err, "could not compute the sync aggregate") - } - if err := blk.Body().SetSyncAggregate(syncAggregate); err != nil { - return nil, errors.Wrap(err, "could not set sync aggregate") + log.WithError(err).Error("Could not get sync aggregate") + } else { + if err := blk.Body().SetSyncAggregate(syncAggregate); err != nil { + log.WithError(err).Error("Could not set sync aggregate") + if err := blk.Body().SetSyncAggregate(ðpb.SyncAggregate{ + SyncCommitteeBits: make([]byte, params.BeaconConfig().SyncCommitteeSize), + SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength), + }); err != nil { + return nil, status.Errorf(codes.Internal, "Could not set sync aggregate: %v", err) + } + } } } @@ -195,8 +137,7 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( canUseBuilder, err := vs.canUseBuilder(ctx, req.Slot, idx) if err != nil { log.WithError(err).Warn("Proposer: failed to check if builder can be used") - } - if canUseBuilder && err != nil { + } else if canUseBuilder { h, err := vs.getPayloadHeaderFromBuilder(ctx, req.Slot, idx) if err != nil { log.WithError(err).Warn("Proposer: failed to get payload header from builder") @@ -212,10 +153,10 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( if fallBackToLocal { executionData, err := vs.getExecutionPayload(ctx, req.Slot, idx, bytesutil.ToBytes32(parentRoot), head) if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") + return nil, status.Errorf(codes.Internal, "Could not get execution payload: %v", err) } if err := blk.Body().SetExecution(executionData); err != nil { - return nil, errors.Wrap(err, "could not set execution payload") + return nil, status.Errorf(codes.Internal, "Could not set execution payload: %v", err) } } } @@ -224,35 +165,122 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( if slots.ToEpoch(req.Slot) >= params.BeaconConfig().CapellaForkEpoch { changes, err := vs.BLSChangesPool.BLSToExecChangesForInclusion(head) if err != nil { - return nil, errors.Wrap(err, "could not pack BLSToExecutionChanges") - } - if err := blk.Body().SetBLSToExecutionChanges(changes); err != nil { - return nil, errors.Wrap(err, "could not set BLSToExecutionChanges") + log.WithError(err).Error("Could not get bls to execution changes") + } else { + if err := blk.Body().SetBLSToExecutionChanges(changes); err != nil { + log.WithError(err).Error("Could not set bls to execution changes") + } } } if err := sBlk.SetBlock(blk); err != nil { - return nil, err + return nil, status.Errorf(codes.Internal, "Could not set block: %v", err) } sr, err := vs.computeStateRoot(ctx, sBlk) if err != nil { - return nil, fmt.Errorf("could not compute state root: %v", err) + return nil, status.Errorf(codes.Internal, "Could not compute state root: %v", err) } blk.SetStateRoot(sr) pb, err := blk.Proto() if err != nil { - return nil, err + return nil, status.Errorf(codes.Internal, "Could not convert block to proto: %v", err) } - switch { - case slots.ToEpoch(req.Slot) < params.BeaconConfig().AltairForkEpoch: - return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Phase0{Phase0: pb.(*ethpb.BeaconBlock)}}, nil - case slots.ToEpoch(req.Slot) < params.BeaconConfig().BellatrixForkEpoch: - return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Altair{Altair: pb.(*ethpb.BeaconBlockAltair)}}, nil - case slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch: + if slots.ToEpoch(req.Slot) >= params.BeaconConfig().CapellaForkEpoch { + return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}}, nil + } else if slots.ToEpoch(req.Slot) >= params.BeaconConfig().BellatrixForkEpoch { return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Bellatrix{Bellatrix: pb.(*ethpb.BeaconBlockBellatrix)}}, nil + } else if slots.ToEpoch(req.Slot) >= params.BeaconConfig().AltairForkEpoch { + return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Altair{Altair: pb.(*ethpb.BeaconBlockAltair)}}, nil + } + return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Phase0{Phase0: pb.(*ethpb.BeaconBlock)}}, nil +} + +func (vs *Server) getExits(head state.BeaconState, req *ethpb.BlockRequest) []*ethpb.SignedVoluntaryExit { + exits := vs.ExitPool.PendingExits(head, req.Slot, false /*noLimit*/) + validExits := make([]*ethpb.SignedVoluntaryExit, 0, len(exits)) + for _, exit := range exits { + val, err := head.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex) + if err != nil { + log.WithError(err).Warn("Proposer: invalid exit") + continue + } + if err := blocks2.VerifyExitAndSignature(val, head.Slot(), head.Fork(), exit, head.GenesisValidatorsRoot()); err != nil { + log.WithError(err).Warn("Proposer: invalid exit") + continue + } + validExits = append(validExits, exit) + } + return validExits +} + +func (vs *Server) getSlashings(ctx context.Context, head state.BeaconState) ([]*ethpb.ProposerSlashing, []*ethpb.AttesterSlashing) { + proposerSlashings := vs.SlashingsPool.PendingProposerSlashings(ctx, head, false /*noLimit*/) + validProposerSlashings := make([]*ethpb.ProposerSlashing, 0, len(proposerSlashings)) + for _, slashing := range proposerSlashings { + _, err := blocks2.ProcessProposerSlashing(ctx, head, slashing, v.SlashValidator) + if err != nil { + log.WithError(err).Warn("Proposer: invalid proposer slashing") + continue + } + validProposerSlashings = append(validProposerSlashings, slashing) + } + attSlashings := vs.SlashingsPool.PendingAttesterSlashings(ctx, head, false /*noLimit*/) + validAttSlashings := make([]*ethpb.AttesterSlashing, 0, len(attSlashings)) + for _, slashing := range attSlashings { + _, err := blocks2.ProcessAttesterSlashing(ctx, head, slashing, v.SlashValidator) + if err != nil { + log.WithError(err).Warn("Proposer: invalid attester slashing") + continue + } + validAttSlashings = append(validAttSlashings, slashing) + } + return validProposerSlashings, validAttSlashings +} + +func emptyBlockToSign(slot types.Slot) (interfaces.BeaconBlock, interfaces.SignedBeaconBlock, error) { + var blk interfaces.BeaconBlock + var sBlk interfaces.SignedBeaconBlock + var err error + switch { + case slots.ToEpoch(slot) < params.BeaconConfig().AltairForkEpoch: + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}) + if err != nil { + return nil, nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}}) + if err != nil { + return nil, nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + case slots.ToEpoch(slot) < params.BeaconConfig().BellatrixForkEpoch: + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockAltair{Body: ðpb.BeaconBlockBodyAltair{}}) + if err != nil { + return nil, nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{Block: ðpb.BeaconBlockAltair{Body: ðpb.BeaconBlockBodyAltair{}}}) + if err != nil { + return nil, nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + case slots.ToEpoch(slot) < params.BeaconConfig().CapellaForkEpoch: + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockBellatrix{Body: ðpb.BeaconBlockBodyBellatrix{}}) + if err != nil { + return nil, nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{Block: ðpb.BeaconBlockBellatrix{Body: ðpb.BeaconBlockBodyBellatrix{}}}) + if err != nil { + return nil, nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + default: + blk, err = blocks.NewBeaconBlock(ðpb.BeaconBlockCapella{Body: ðpb.BeaconBlockBodyCapella{}}) + if err != nil { + return nil, nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } + sBlk, err = blocks.NewSignedBeaconBlock(ðpb.SignedBeaconBlockCapella{Block: ðpb.BeaconBlockCapella{Body: ðpb.BeaconBlockBodyCapella{}}}) + if err != nil { + return nil, nil, status.Errorf(codes.Internal, "Could not initialize block for proposal: %v", err) + } } - return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}}, nil + return blk, sBlk, err } // ProposeBeaconBlock is called by a proposer during its assigned slot to create a block in an attempt From 321014be5050c0ed8ccb2703b855be400ee17266 Mon Sep 17 00:00:00 2001 From: terencechain Date: Wed, 7 Dec 2022 13:05:38 -0800 Subject: [PATCH 5/7] Update beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RadosÅ‚aw Kapka --- beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go index f237914b9a99..411a4336a7bf 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go @@ -125,7 +125,7 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( SyncCommitteeBits: make([]byte, params.BeaconConfig().SyncCommitteeSize), SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength), }); err != nil { - return nil, status.Errorf(codes.Internal, "Could not set sync aggregate: %v", err) + return nil, status.Errorf(codes.Internal, "Could not set default sync aggregate: %v", err) } } } From 4514c3a0231550e657be48d5a3bd794ab55c0bb4 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Wed, 7 Dec 2022 13:16:17 -0800 Subject: [PATCH 6/7] Radek's feedback --- consensus-types/blocks/getters.go | 71 +++++++++++++++++----- consensus-types/interfaces/beacon_block.go | 3 +- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/consensus-types/blocks/getters.go b/consensus-types/blocks/getters.go index 97b63fa2c00b..2bfc22024487 100644 --- a/consensus-types/blocks/getters.go +++ b/consensus-types/blocks/getters.go @@ -41,28 +41,32 @@ func (b *SignedBeaconBlock) Block() interfaces.BeaconBlock { // SetBlock sets the underlying beacon block object. func (b *SignedBeaconBlock) SetBlock(blk interfaces.BeaconBlock) error { - b.block.slot = blk.Slot() - b.block.parentRoot = blk.ParentRoot() - b.block.stateRoot = blk.StateRoot() - b.block.stateRoot = blk.StateRoot() - b.block.proposerIndex = blk.ProposerIndex() - b.block.body.randaoReveal = blk.Body().RandaoReveal() - b.block.body.eth1Data = blk.Body().Eth1Data() - b.block.body.graffiti = blk.Body().Graffiti() - b.block.body.proposerSlashings = blk.Body().ProposerSlashings() - b.block.body.attesterSlashings = blk.Body().AttesterSlashings() - b.block.body.attestations = blk.Body().Attestations() - b.block.body.deposits = blk.Body().Deposits() - b.block.body.voluntaryExits = blk.Body().VoluntaryExits() + copied, err := blk.Copy() + if err != nil { + return err + } + b.block.slot = copied.Slot() + b.block.parentRoot = copied.ParentRoot() + b.block.stateRoot = copied.StateRoot() + b.block.stateRoot = copied.StateRoot() + b.block.proposerIndex = copied.ProposerIndex() + b.block.body.randaoReveal = copied.Body().RandaoReveal() + b.block.body.eth1Data = copied.Body().Eth1Data() + b.block.body.graffiti = copied.Body().Graffiti() + b.block.body.proposerSlashings = copied.Body().ProposerSlashings() + b.block.body.attesterSlashings = copied.Body().AttesterSlashings() + b.block.body.attestations = copied.Body().Attestations() + b.block.body.deposits = copied.Body().Deposits() + b.block.body.voluntaryExits = copied.Body().VoluntaryExits() if b.version >= version.Altair { - syncAggregate, err := blk.Body().SyncAggregate() + syncAggregate, err := copied.Body().SyncAggregate() if err != nil { return err } b.block.body.syncAggregate = syncAggregate } if b.version >= version.Bellatrix { - executionData, err := blk.Body().Execution() + executionData, err := copied.Body().Execution() if err != nil { return err } @@ -73,7 +77,7 @@ func (b *SignedBeaconBlock) SetBlock(blk interfaces.BeaconBlock) error { } } if b.version >= version.Capella { - changes, err := blk.Body().BLSToExecutionChanges() + changes, err := copied.Body().BLSToExecutionChanges() if err != nil { return err } @@ -809,6 +813,41 @@ func (b *BeaconBlock) AsSignRequestObject() (validatorpb.SignRequestObject, erro } } +func (b *BeaconBlock) Copy() (interfaces.BeaconBlock, error) { + if b == nil { + return nil, nil + } + + pb, err := b.Proto() + if err != nil { + return nil, err + } + switch b.version { + case version.Phase0: + cp := eth.CopyBeaconBlock(pb.(*eth.BeaconBlock)) + return initBlockFromProtoPhase0(cp) + case version.Altair: + cp := eth.CopyBeaconBlockAltair(pb.(*eth.BeaconBlockAltair)) + return initBlockFromProtoAltair(cp) + case version.Bellatrix: + if b.IsBlinded() { + cp := eth.CopyBlindedBeaconBlockBellatrix(pb.(*eth.BlindedBeaconBlockBellatrix)) + return initBlindedBlockFromProtoBellatrix(cp) + } + cp := eth.CopyBeaconBlockBellatrix(pb.(*eth.BeaconBlockBellatrix)) + return initBlockFromProtoBellatrix(cp) + case version.Capella: + if b.IsBlinded() { + cp := eth.CopyBlindedBeaconBlockCapella(pb.(*eth.BlindedBeaconBlockCapella)) + return initBlindedBlockFromProtoCapella(cp) + } + cp := eth.CopyBeaconBlockCapella(pb.(*eth.BeaconBlockCapella)) + return initBlockFromProtoCapella(cp) + default: + return nil, errIncorrectBlockVersion + } +} + // IsNil checks if the block body is nil. func (b *BeaconBlockBody) IsNil() bool { return b == nil diff --git a/consensus-types/interfaces/beacon_block.go b/consensus-types/interfaces/beacon_block.go index 9dfa04b03c95..99c787dbb548 100644 --- a/consensus-types/interfaces/beacon_block.go +++ b/consensus-types/interfaces/beacon_block.go @@ -49,6 +49,7 @@ type BeaconBlock interface { Body() BeaconBlockBody IsNil() bool IsBlinded() bool + SetBlinded(bool) HashTreeRoot() ([field_params.RootLength]byte, error) Proto() (proto.Message, error) ssz.Marshaler @@ -56,7 +57,7 @@ type BeaconBlock interface { ssz.HashRoot Version() int AsSignRequestObject() (validatorpb.SignRequestObject, error) - SetBlinded(bool) + Copy() (BeaconBlock, error) } // BeaconBlockBody describes the method set employed by an object From 99abb10820b07077171efcf77700b30e8e64e7dc Mon Sep 17 00:00:00 2001 From: terence tsao Date: Thu, 8 Dec 2022 07:23:16 -0800 Subject: [PATCH 7/7] Fix lint --- consensus-types/mock/block.go | 76 +++++++++++++++++++ .../shared/common/forkchoice/service.go | 5 +- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/consensus-types/mock/block.go b/consensus-types/mock/block.go index 2761ac22372e..a54cc89b7f66 100644 --- a/consensus-types/mock/block.go +++ b/consensus-types/mock/block.go @@ -94,6 +94,14 @@ func (SignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) { panic("implement me") } +func (SignedBeaconBlock) SetBlock(_ interfaces.BeaconBlock) error { + panic("implement me") +} + +func (SignedBeaconBlock) SetSignature(_ []byte) { + panic("implement me") +} + type BeaconBlock struct { Htr [field_params.RootLength]byte HtrErr error @@ -165,6 +173,30 @@ func (BeaconBlock) Version() int { panic("implement me") } +func (BeaconBlock) ToBlinded() (interfaces.BeaconBlock, error) { + panic("implement me") +} + +func (BeaconBlock) SetSlot(_ types.Slot) { + panic("implement me") +} + +func (BeaconBlock) SetProposerIndex(_ types.ValidatorIndex) { + panic("implement me") +} + +func (BeaconBlock) SetParentRoot(_ []byte) { + panic("implement me") +} + +func (BeaconBlock) SetBlinded(_ bool) { + panic("implement me") +} + +func (BeaconBlock) Copy() (interfaces.BeaconBlock, error) { + panic("implement me") +} + type BeaconBlockBody struct{} func (BeaconBlockBody) RandaoReveal() [field_params.BLSSignatureLength]byte { @@ -227,6 +259,50 @@ func (b *BeaconBlock) SetStateRoot(root []byte) { panic("implement me") } +func (b *BeaconBlockBody) SetRandaoReveal([]byte) { + panic("implement me") +} + +func (b *BeaconBlockBody) SetEth1Data(*eth.Eth1Data) { + panic("implement me") +} + +func (b *BeaconBlockBody) SetGraffiti([]byte) { + panic("implement me") +} + +func (b *BeaconBlockBody) SetProposerSlashings([]*eth.ProposerSlashing) { + panic("implement me") +} + +func (b *BeaconBlockBody) SetAttesterSlashings([]*eth.AttesterSlashing) { + panic("implement me") +} + +func (b *BeaconBlockBody) SetAttestations([]*eth.Attestation) { + panic("implement me") +} + +func (b *BeaconBlockBody) SetDeposits([]*eth.Deposit) { + panic("implement me") +} + +func (b *BeaconBlockBody) SetVoluntaryExits([]*eth.SignedVoluntaryExit) { + panic("implement me") +} + +func (b *BeaconBlockBody) SetSyncAggregate(*eth.SyncAggregate) error { + panic("implement me") +} + +func (b *BeaconBlockBody) SetExecution(interfaces.ExecutionData) error { + panic("implement me") +} + +func (b *BeaconBlockBody) SetBLSToExecutionChanges([]*eth.SignedBLSToExecutionChange) error { + panic("implement me") +} + var _ interfaces.SignedBeaconBlock = &SignedBeaconBlock{} var _ interfaces.BeaconBlock = &BeaconBlock{} var _ interfaces.BeaconBlockBody = &BeaconBlockBody{} diff --git a/testing/spectest/shared/common/forkchoice/service.go b/testing/spectest/shared/common/forkchoice/service.go index 1e7a0467305d..980de9c7916f 100644 --- a/testing/spectest/shared/common/forkchoice/service.go +++ b/testing/spectest/shared/common/forkchoice/service.go @@ -20,6 +20,7 @@ import ( "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/stategen" "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" payloadattribute "github.com/prysmaticlabs/prysm/v3/consensus-types/payload-attribute" + types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" pb "github.com/prysmaticlabs/prysm/v3/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" @@ -78,13 +79,13 @@ type engineMock struct { payloadStatus error } -func (m *engineMock) GetPayload(context.Context, [8]byte) (*pb.ExecutionPayload, error) { +func (m *engineMock) GetPayload(context.Context, [8]byte, types.Slot) (interfaces.ExecutionData, error) { return nil, nil } func (m *engineMock) GetPayloadV2(context.Context, [8]byte) (*pb.ExecutionPayloadCapella, error) { return nil, nil } -func (m *engineMock) ForkchoiceUpdated(context.Context, *pb.ForkchoiceState, *pb.PayloadAttributes) (*pb.PayloadIDBytes, []byte, error) { +func (m *engineMock) ForkchoiceUpdated(context.Context, *pb.ForkchoiceState, payloadattribute.Attributer) (*pb.PayloadIDBytes, []byte, error) { return nil, m.latestValidHash, m.payloadStatus } func (m *engineMock) ForkchoiceUpdatedV2(context.Context, *pb.ForkchoiceState, *pb.PayloadAttributesV2) (*pb.PayloadIDBytes, []byte, error) {