mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Proposer builds block in parallel. (Consensus vs Execution) (#12297)
* Proposer builds block in parallel. Cosensus vs Execution * Update beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> * Use feature flag --------- Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@@ -18,6 +19,8 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/kv"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
||||
@@ -82,25 +85,6 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (
|
||||
sBlk.SetRandaoReveal(req.RandaoReveal)
|
||||
sBlk.SetParentRoot(parentRoot[:])
|
||||
|
||||
// Set eth1 data.
|
||||
eth1Data, err := vs.eth1DataMajorityVote(ctx, head)
|
||||
if err != nil {
|
||||
eth1Data = ðpb.Eth1Data{DepositRoot: params.BeaconConfig().ZeroHash[:], BlockHash: params.BeaconConfig().ZeroHash[:]}
|
||||
log.WithError(err).Error("Could not get eth1data")
|
||||
}
|
||||
sBlk.SetEth1Data(eth1Data)
|
||||
|
||||
// Set deposit and attestation.
|
||||
deposits, atts, err := vs.packDepositsAndAttestations(ctx, head, eth1Data) // TODO: split attestations and deposits
|
||||
if err != nil {
|
||||
sBlk.SetDeposits([]*ethpb.Deposit{})
|
||||
sBlk.SetAttestations([]*ethpb.Attestation{})
|
||||
log.WithError(err).Error("Could not pack deposits and attestations")
|
||||
} else {
|
||||
sBlk.SetDeposits(deposits)
|
||||
sBlk.SetAttestations(atts)
|
||||
}
|
||||
|
||||
// Set proposer index.
|
||||
idx, err := helpers.BeaconProposerIndex(ctx, head)
|
||||
if err != nil {
|
||||
@@ -108,25 +92,50 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (
|
||||
}
|
||||
sBlk.SetProposerIndex(idx)
|
||||
|
||||
// Set slashings.
|
||||
validProposerSlashings, validAttSlashings := vs.getSlashings(ctx, head)
|
||||
sBlk.SetProposerSlashings(validProposerSlashings)
|
||||
sBlk.SetAttesterSlashings(validAttSlashings)
|
||||
if features.Get().BuildBlockParallel {
|
||||
if err := vs.BuildBlockParallel(ctx, sBlk, head); err != nil {
|
||||
return nil, errors.Wrap(err, "could not build block in parallel")
|
||||
}
|
||||
} else {
|
||||
// Set eth1 data.
|
||||
eth1Data, err := vs.eth1DataMajorityVote(ctx, head)
|
||||
if err != nil {
|
||||
eth1Data = ðpb.Eth1Data{DepositRoot: params.BeaconConfig().ZeroHash[:], BlockHash: params.BeaconConfig().ZeroHash[:]}
|
||||
log.WithError(err).Error("Could not get eth1data")
|
||||
}
|
||||
sBlk.SetEth1Data(eth1Data)
|
||||
|
||||
// Set exits.
|
||||
sBlk.SetVoluntaryExits(vs.getExits(head, req.Slot))
|
||||
// Set deposit and attestation.
|
||||
deposits, atts, err := vs.packDepositsAndAttestations(ctx, head, eth1Data) // TODO: split attestations and deposits
|
||||
if err != nil {
|
||||
sBlk.SetDeposits([]*ethpb.Deposit{})
|
||||
sBlk.SetAttestations([]*ethpb.Attestation{})
|
||||
log.WithError(err).Error("Could not pack deposits and attestations")
|
||||
} else {
|
||||
sBlk.SetDeposits(deposits)
|
||||
sBlk.SetAttestations(atts)
|
||||
}
|
||||
|
||||
// Set sync aggregate. New in Altair.
|
||||
vs.setSyncAggregate(ctx, sBlk)
|
||||
// Set slashings.
|
||||
validProposerSlashings, validAttSlashings := vs.getSlashings(ctx, head)
|
||||
sBlk.SetProposerSlashings(validProposerSlashings)
|
||||
sBlk.SetAttesterSlashings(validAttSlashings)
|
||||
|
||||
// Set execution data. New in Bellatrix.
|
||||
if err := vs.setExecutionData(ctx, sBlk, head); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not set execution data: %v", err)
|
||||
// Set exits.
|
||||
sBlk.SetVoluntaryExits(vs.getExits(head, req.Slot))
|
||||
|
||||
// Set sync aggregate. New in Altair.
|
||||
vs.setSyncAggregate(ctx, sBlk)
|
||||
|
||||
// Set execution data. New in Bellatrix.
|
||||
if err := vs.setExecutionData(ctx, sBlk, head); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not set execution data: %v", err)
|
||||
}
|
||||
|
||||
// Set bls to execution change. New in Capella.
|
||||
vs.setBlsToExecData(sBlk, head)
|
||||
}
|
||||
|
||||
// Set bls to execution change. New in Capella.
|
||||
vs.setBlsToExecData(sBlk, head)
|
||||
|
||||
sr, err := vs.computeStateRoot(ctx, sBlk)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not compute state root: %v", err)
|
||||
@@ -155,6 +164,56 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Phase0{Phase0: pb.(*ethpb.BeaconBlock)}}, nil
|
||||
}
|
||||
|
||||
func (vs *Server) BuildBlockParallel(ctx context.Context, sBlk interfaces.SignedBeaconBlock, head state.BeaconState) error {
|
||||
// Build consensus fields in background
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
// Set eth1 data.
|
||||
eth1Data, err := vs.eth1DataMajorityVote(ctx, head)
|
||||
if err != nil {
|
||||
eth1Data = ðpb.Eth1Data{DepositRoot: params.BeaconConfig().ZeroHash[:], BlockHash: params.BeaconConfig().ZeroHash[:]}
|
||||
log.WithError(err).Error("Could not get eth1data")
|
||||
}
|
||||
sBlk.SetEth1Data(eth1Data)
|
||||
|
||||
// Set deposit and attestation.
|
||||
deposits, atts, err := vs.packDepositsAndAttestations(ctx, head, eth1Data) // TODO: split attestations and deposits
|
||||
if err != nil {
|
||||
sBlk.SetDeposits([]*ethpb.Deposit{})
|
||||
sBlk.SetAttestations([]*ethpb.Attestation{})
|
||||
log.WithError(err).Error("Could not pack deposits and attestations")
|
||||
} else {
|
||||
sBlk.SetDeposits(deposits)
|
||||
sBlk.SetAttestations(atts)
|
||||
}
|
||||
|
||||
// Set slashings.
|
||||
validProposerSlashings, validAttSlashings := vs.getSlashings(ctx, head)
|
||||
sBlk.SetProposerSlashings(validProposerSlashings)
|
||||
sBlk.SetAttesterSlashings(validAttSlashings)
|
||||
|
||||
// Set exits.
|
||||
sBlk.SetVoluntaryExits(vs.getExits(head, sBlk.Block().Slot()))
|
||||
|
||||
// Set sync aggregate. New in Altair.
|
||||
vs.setSyncAggregate(ctx, sBlk)
|
||||
|
||||
// Set bls to execution change. New in Capella.
|
||||
vs.setBlsToExecData(sBlk, head)
|
||||
}()
|
||||
|
||||
if err := vs.setExecutionData(ctx, sBlk, head); err != nil {
|
||||
return status.Errorf(codes.Internal, "Could not set execution data: %v", err)
|
||||
}
|
||||
|
||||
wg.Wait() // Wait until block is built via consensus and execution fields.
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProposeBeaconBlock is called by a proposer during its assigned slot to create a block in an attempt
|
||||
// to get it processed by the beacon node as the canonical head.
|
||||
func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSignedBeaconBlock) (*ethpb.ProposeResponse, error) {
|
||||
|
||||
@@ -67,6 +67,8 @@ type Flags struct {
|
||||
|
||||
PrepareAllPayloads bool // PrepareAllPayloads informs the engine to prepare a block on every slot.
|
||||
|
||||
BuildBlockParallel bool // BuildBlockParallel builds beacon block for proposer in parallel.
|
||||
|
||||
// KeystoreImportDebounceInterval specifies the time duration the validator waits to reload new keys if they have
|
||||
// changed on disk. This feature is for advanced use cases only.
|
||||
KeystoreImportDebounceInterval time.Duration
|
||||
@@ -212,6 +214,10 @@ func ConfigureBeaconChain(ctx *cli.Context) error {
|
||||
logEnabled(prepareAllPayloads)
|
||||
cfg.PrepareAllPayloads = true
|
||||
}
|
||||
if ctx.IsSet(buildBlockParallel.Name) {
|
||||
logEnabled(buildBlockParallel)
|
||||
cfg.BuildBlockParallel = true
|
||||
}
|
||||
Init(cfg)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -118,6 +118,10 @@ var (
|
||||
Name: "prepare-all-payloads",
|
||||
Usage: "Informs the engine to prepare all local payloads. Useful for relayers and builders",
|
||||
}
|
||||
buildBlockParallel = &cli.BoolFlag{
|
||||
Name: "build-block-parallel",
|
||||
Usage: "Builds a beacon block in parallel for consensus and execution. It results in faster block construction time",
|
||||
}
|
||||
)
|
||||
|
||||
// devModeFlags holds list of flags that are set when development mode is on.
|
||||
@@ -164,6 +168,7 @@ var BeaconChainFlags = append(deprecatedBeaconFlags, append(deprecatedFlags, []c
|
||||
enableVerboseSigVerification,
|
||||
enableOptionalEngineMethods,
|
||||
prepareAllPayloads,
|
||||
buildBlockParallel,
|
||||
}...)...)
|
||||
|
||||
// E2EBeaconChainFlags contains a list of the beacon chain feature flags to be tested in E2E.
|
||||
|
||||
Reference in New Issue
Block a user