mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-25 21:07:18 +00:00
879e310332
* panic in SizeSSZ * moving slowly * adapt old code to new interfaces * return interfaces from factory functions * replace the rest of WrappedSignedBeaconBlock * WrappedBeaconBlock * WrappedBeaconBlockBody * miscellaneous * Test_BeaconBlockIsNil * replace usages of BeaconBlockIsNil * replace usages of mutator * fix all build errors * fix some more issues * mutator changes * relax assertions when initializing * revert changes in object_mapping.go * allow calling Proto on nil * Revert "allow calling Proto on nil" This reverts commit ecc84e455381b03d24aec2fa0fa17bddbec71705. * modify Copy and Proto methods * remove unused var * fix block batch tests * correct BUILD file * Error when initializing nil objects * one more error fix * add missing comma * rename alias to blocktest * add logging * error when SignedBeaconBlock is nil * fix last test * import fix * broken * working * test fixes * reduce complexity of processPendingBlocks * simplified
171 lines
5.8 KiB
Go
171 lines
5.8 KiB
Go
package validator
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition/interop"
|
|
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
|
"github.com/prysmaticlabs/prysm/config/params"
|
|
consensusblocks "github.com/prysmaticlabs/prysm/consensus-types/blocks"
|
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
"go.opencensus.io/trace"
|
|
)
|
|
|
|
// blockData required to create a beacon block.
|
|
type blockData struct {
|
|
ParentRoot []byte
|
|
Graffiti [32]byte
|
|
ProposerIdx types.ValidatorIndex
|
|
Eth1Data *ethpb.Eth1Data
|
|
Deposits []*ethpb.Deposit
|
|
Attestations []*ethpb.Attestation
|
|
ProposerSlashings []*ethpb.ProposerSlashing
|
|
AttesterSlashings []*ethpb.AttesterSlashing
|
|
VoluntaryExits []*ethpb.SignedVoluntaryExit
|
|
}
|
|
|
|
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: req.Slot,
|
|
ParentRoot: blkData.ParentRoot,
|
|
StateRoot: stateRoot,
|
|
ProposerIndex: blkData.ProposerIdx,
|
|
Body: ðpb.BeaconBlockBody{
|
|
Eth1Data: blkData.Eth1Data,
|
|
Deposits: blkData.Deposits,
|
|
Attestations: blkData.Attestations,
|
|
RandaoReveal: req.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)
|
|
}
|
|
|
|
return &blockData{
|
|
ParentRoot: parentRoot,
|
|
Graffiti: graffiti,
|
|
ProposerIdx: idx,
|
|
Eth1Data: eth1Data,
|
|
Deposits: deposits,
|
|
Attestations: atts,
|
|
ProposerSlashings: validProposerSlashings,
|
|
AttesterSlashings: validAttSlashings,
|
|
VoluntaryExits: validExits,
|
|
}, nil
|
|
}
|