mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
only viable head is invalid (#11117)
* failing onBlock syncing * passing merge check * failing signature verification * still failing block signature * mock full bellatrix blocks * working unit test * return error from FCU if head fails to update * move bellatrix block generator * remove bellatrix signature function * Add liveness unit tests * revert removal of sync_aggregate.go * gaz * Terence's suggestion Co-authored-by: terencechain <terence@prysmaticlabs.com> * go fmt * Nishant's suggestion Co-authored-by: Nishant Das <nishdas93@gmail.com> * Fix build Co-authored-by: terencechain <terence@prysmaticlabs.com> Co-authored-by: Nishant Das <nishdas93@gmail.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package blockchain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"time"
|
||||
|
||||
@@ -299,13 +300,14 @@ func (s *Service) ForkChoicer() forkchoice.ForkChoicer {
|
||||
|
||||
// IsOptimistic returns true if the current head is optimistic.
|
||||
func (s *Service) IsOptimistic(ctx context.Context) (bool, error) {
|
||||
s.headLock.RLock()
|
||||
defer s.headLock.RUnlock()
|
||||
if slots.ToEpoch(s.CurrentSlot()) < params.BeaconConfig().BellatrixForkEpoch {
|
||||
return false, nil
|
||||
}
|
||||
s.headLock.RLock()
|
||||
headRoot := s.head.root
|
||||
s.headLock.RUnlock()
|
||||
|
||||
return s.IsOptimisticForRoot(ctx, s.head.root)
|
||||
return s.IsOptimisticForRoot(ctx, headRoot)
|
||||
}
|
||||
|
||||
// IsFinalized returns true if the input root is finalized.
|
||||
@@ -332,7 +334,17 @@ func (s *Service) IsOptimisticForRoot(ctx context.Context, root [32]byte) (bool,
|
||||
return false, err
|
||||
}
|
||||
if ss == nil {
|
||||
return false, errInvalidNilSummary
|
||||
// if the requested root is the headroot we should treat the
|
||||
// node as optimistic. This can happen if we pruned INVALID
|
||||
// nodes and no viable head is available.
|
||||
headRoot, err := s.HeadRoot(ctx)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
if bytes.Equal(headRoot, root[:]) {
|
||||
return true, nil
|
||||
}
|
||||
return true, errInvalidNilSummary
|
||||
}
|
||||
|
||||
validatedCheckpoint, err := s.cfg.BeaconDB.LastValidatedCheckpoint(ctx)
|
||||
|
||||
@@ -106,8 +106,12 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkcho
|
||||
|
||||
r, err := s.cfg.ForkChoiceStore.Head(ctx, s.justifiedBalances.balances)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get head root")
|
||||
return nil, nil
|
||||
log.WithFields(logrus.Fields{
|
||||
"slot": headBlk.Slot(),
|
||||
"blockRoot": fmt.Sprintf("%#x", bytesutil.Trunc(headRoot[:])),
|
||||
"invalidCount": len(invalidRoots),
|
||||
}).Warn("Pruned invalid blocks, could not update head root")
|
||||
return nil, invalidBlock{error: ErrInvalidPayload, root: arg.headRoot, invalidAncestorRoots: invalidRoots}
|
||||
}
|
||||
b, err := s.getBlock(ctx, r)
|
||||
if err != nil {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@ package altair
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||
p2pType "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
|
||||
@@ -47,11 +47,11 @@ import (
|
||||
func ProcessSyncAggregate(ctx context.Context, s state.BeaconState, sync *ethpb.SyncAggregate) (state.BeaconState, error) {
|
||||
votedKeys, votedIndices, didntVoteIndices, err := FilterSyncCommitteeVotes(s, sync)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "could not filter sync committee votes")
|
||||
}
|
||||
|
||||
if err := VerifySyncCommitteeSig(s, votedKeys, sync.SyncCommitteeSignature); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "could not verify sync committee signature")
|
||||
}
|
||||
|
||||
return ApplySyncRewardsPenalties(ctx, s, votedIndices, didntVoteIndices)
|
||||
|
||||
@@ -99,7 +99,7 @@ func TestExecuteBellatrixStateTransitionNoVerify_FullProcess(t *testing.T) {
|
||||
block.Block.StateRoot = stateRoot[:]
|
||||
|
||||
c := beaconState.Copy()
|
||||
sig, err := util.BlockSignatureBellatrix(c, block.Block, privKeys)
|
||||
sig, err := util.BlockSignature(c, block.Block, privKeys)
|
||||
require.NoError(t, err)
|
||||
block.Signature = sig.Marshal()
|
||||
|
||||
@@ -187,7 +187,7 @@ func TestExecuteBellatrixStateTransitionNoVerifySignature_CouldNotVerifyStateRoo
|
||||
block.Block.StateRoot = stateRoot[:]
|
||||
|
||||
c := beaconState.Copy()
|
||||
sig, err := util.BlockSignatureBellatrix(c, block.Block, privKeys)
|
||||
sig, err := util.BlockSignature(c, block.Block, privKeys)
|
||||
require.NoError(t, err)
|
||||
block.Signature = sig.Marshal()
|
||||
|
||||
|
||||
@@ -194,6 +194,7 @@ func TestProcessBlock_AllEventsTrackedVals(t *testing.T) {
|
||||
|
||||
genConfig := util.DefaultBlockGenConfig()
|
||||
genConfig.NumProposerSlashings = 1
|
||||
genConfig.FullSyncAggregate = true
|
||||
b, err := util.GenerateFullBlockAltair(genesis, keys, genConfig, 1)
|
||||
require.NoError(t, err)
|
||||
s := setupService(t)
|
||||
|
||||
@@ -311,7 +311,7 @@ func BlockSignatureAltair(
|
||||
return privKeys[proposerIdx].Sign(blockRoot[:]), nil
|
||||
}
|
||||
|
||||
// GenerateFullBlockAltair generates a fully valid block with the requested parameters.
|
||||
// GenerateFullBlockAltair generates a fully valid Altair block with the requested parameters.
|
||||
// Use BlockGenConfig to declare the conditions you would like the block generated under.
|
||||
func GenerateFullBlockAltair(
|
||||
bState state.BeaconState,
|
||||
@@ -388,26 +388,44 @@ func GenerateFullBlockAltair(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var newSyncAggregate *ethpb.SyncAggregate
|
||||
if conf.FullSyncAggregate {
|
||||
newSyncAggregate, err = generateSyncAggregate(bState, privs, parentRoot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed generating syncAggregate")
|
||||
}
|
||||
} else {
|
||||
var syncCommitteeBits []byte
|
||||
currSize := new(ethpb.SyncAggregate).SyncCommitteeBits.Len()
|
||||
switch currSize {
|
||||
case 512:
|
||||
syncCommitteeBits = bitfield.NewBitvector512()
|
||||
case 32:
|
||||
syncCommitteeBits = bitfield.NewBitvector32()
|
||||
default:
|
||||
return nil, errors.New("invalid bit vector size")
|
||||
}
|
||||
newSyncAggregate = ðpb.SyncAggregate{
|
||||
SyncCommitteeBits: syncCommitteeBits,
|
||||
SyncCommitteeSignature: append([]byte{0xC0}, make([]byte, 95)...),
|
||||
}
|
||||
}
|
||||
|
||||
if slot == currentSlot {
|
||||
slot = currentSlot + 1
|
||||
}
|
||||
|
||||
syncAgg, err := generateSyncAggregate(bState, privs, parentRoot)
|
||||
stCopy := bState.Copy()
|
||||
stCopy, err = transition.ProcessSlots(context.Background(), stCopy, slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reveal, err := RandaoReveal(stCopy, time.CurrentEpoch(stCopy), privs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Temporarily incrementing the beacon state slot here since BeaconProposerIndex is a
|
||||
// function deterministic on beacon state slot.
|
||||
if err := bState.SetSlot(slot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reveal, err := RandaoReveal(bState, time.CurrentEpoch(bState), privs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idx, err := helpers.BeaconProposerIndex(ctx, bState)
|
||||
idx, err := helpers.BeaconProposerIndex(ctx, stCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -424,15 +442,12 @@ func GenerateFullBlockAltair(
|
||||
Attestations: atts,
|
||||
VoluntaryExits: exits,
|
||||
Deposits: newDeposits,
|
||||
Graffiti: make([]byte, 32),
|
||||
SyncAggregate: syncAgg,
|
||||
Graffiti: make([]byte, fieldparams.RootLength),
|
||||
SyncAggregate: newSyncAggregate,
|
||||
},
|
||||
}
|
||||
if err := bState.SetSlot(currentSlot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := BlockSignatureAltair(bState, block, privs)
|
||||
signature, err := BlockSignature(bState, block, privs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
@@ -89,6 +90,16 @@ func GenerateAttestations(
|
||||
return nil, err
|
||||
}
|
||||
headState = genState
|
||||
case version.Bellatrix:
|
||||
pbState, err := v3.ProtobufBeaconState(bState.CloneInnerState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
genState, err := v3.InitializeFromProtoUnsafe(pbState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headState = genState
|
||||
default:
|
||||
return nil, errors.New("state type isn't supported")
|
||||
}
|
||||
|
||||
@@ -2,54 +2,203 @@ package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
)
|
||||
|
||||
// BlockSignatureBellatrix calculates the post-state root of the block and returns the signature.
|
||||
func BlockSignatureBellatrix(
|
||||
// GenerateFullBlockBellatrix generates a fully valid Bellatrix block with the requested parameters.
|
||||
// Use BlockGenConfig to declare the conditions you would like the block generated under.
|
||||
// This function modifies the passed state as follows:
|
||||
|
||||
func GenerateFullBlockBellatrix(
|
||||
bState state.BeaconState,
|
||||
block *ethpb.BeaconBlockBellatrix,
|
||||
privKeys []bls.SecretKey,
|
||||
) (bls.Signature, error) {
|
||||
var err error
|
||||
wsb, err := wrapper.WrappedSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{Block: block})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s, err := transition.CalculateStateRoot(context.Background(), bState, wsb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
block.StateRoot = s[:]
|
||||
domain, err := signing.Domain(bState.Fork(), time.CurrentEpoch(bState), params.BeaconConfig().DomainBeaconProposer, bState.GenesisValidatorsRoot())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockRoot, err := signing.ComputeSigningRoot(block, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Temporarily increasing the beacon state slot here since BeaconProposerIndex is a
|
||||
// function deterministic on beacon state slot.
|
||||
privs []bls.SecretKey,
|
||||
conf *BlockGenConfig,
|
||||
slot types.Slot,
|
||||
) (*ethpb.SignedBeaconBlockBellatrix, error) {
|
||||
ctx := context.Background()
|
||||
currentSlot := bState.Slot()
|
||||
if err := bState.SetSlot(block.Slot); err != nil {
|
||||
return nil, err
|
||||
if currentSlot > slot {
|
||||
return nil, fmt.Errorf("current slot in state is larger than given slot. %d > %d", currentSlot, slot)
|
||||
}
|
||||
proposerIdx, err := helpers.BeaconProposerIndex(context.Background(), bState)
|
||||
bState = bState.Copy()
|
||||
|
||||
if conf == nil {
|
||||
conf = &BlockGenConfig{}
|
||||
}
|
||||
|
||||
var err error
|
||||
var pSlashings []*ethpb.ProposerSlashing
|
||||
numToGen := conf.NumProposerSlashings
|
||||
if numToGen > 0 {
|
||||
pSlashings, err = generateProposerSlashings(bState, privs, numToGen)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d proposer slashings:", numToGen)
|
||||
}
|
||||
}
|
||||
|
||||
numToGen = conf.NumAttesterSlashings
|
||||
var aSlashings []*ethpb.AttesterSlashing
|
||||
if numToGen > 0 {
|
||||
aSlashings, err = generateAttesterSlashings(bState, privs, numToGen)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d attester slashings:", numToGen)
|
||||
}
|
||||
}
|
||||
|
||||
numToGen = conf.NumAttestations
|
||||
var atts []*ethpb.Attestation
|
||||
if numToGen > 0 {
|
||||
atts, err = GenerateAttestations(bState, privs, numToGen, slot, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d attestations:", numToGen)
|
||||
}
|
||||
}
|
||||
|
||||
numToGen = conf.NumDeposits
|
||||
var newDeposits []*ethpb.Deposit
|
||||
eth1Data := bState.Eth1Data()
|
||||
if numToGen > 0 {
|
||||
newDeposits, eth1Data, err = generateDepositsAndEth1Data(bState, numToGen)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d deposits:", numToGen)
|
||||
}
|
||||
}
|
||||
|
||||
numToGen = conf.NumVoluntaryExits
|
||||
var exits []*ethpb.SignedVoluntaryExit
|
||||
if numToGen > 0 {
|
||||
exits, err = generateVoluntaryExits(bState, privs, numToGen)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d attester slashings:", numToGen)
|
||||
}
|
||||
}
|
||||
|
||||
numToGen = conf.NumTransactions
|
||||
newTransactions := make([][]byte, numToGen)
|
||||
for i := uint64(0); i < numToGen; i++ {
|
||||
newTransactions[i] = bytesutil.Uint64ToBytesLittleEndian(i)
|
||||
}
|
||||
random, err := helpers.RandaoMix(bState, time.CurrentEpoch(bState))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not process randao mix")
|
||||
}
|
||||
|
||||
timestamp, err := slots.ToTime(bState.GenesisTime(), slot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current timestamp")
|
||||
}
|
||||
|
||||
stCopy := bState.Copy()
|
||||
stCopy, err = transition.ProcessSlots(context.Background(), stCopy, slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := bState.SetSlot(currentSlot); err != nil {
|
||||
|
||||
parentExecution, err := stCopy.LatestExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return privKeys[proposerIdx].Sign(blockRoot[:]), nil
|
||||
blockHash := indexToHash(uint64(slot))
|
||||
newExecutionPayload := &enginev1.ExecutionPayload{
|
||||
ParentHash: parentExecution.BlockHash,
|
||||
FeeRecipient: make([]byte, 20),
|
||||
StateRoot: params.BeaconConfig().ZeroHash[:],
|
||||
ReceiptsRoot: params.BeaconConfig().ZeroHash[:],
|
||||
LogsBloom: make([]byte, 256),
|
||||
PrevRandao: random,
|
||||
BlockNumber: uint64(slot),
|
||||
ExtraData: params.BeaconConfig().ZeroHash[:],
|
||||
BaseFeePerGas: params.BeaconConfig().ZeroHash[:],
|
||||
BlockHash: blockHash[:],
|
||||
Timestamp: uint64(timestamp.Unix()),
|
||||
Transactions: newTransactions,
|
||||
}
|
||||
var syncCommitteeBits []byte
|
||||
currSize := new(ethpb.SyncAggregate).SyncCommitteeBits.Len()
|
||||
switch currSize {
|
||||
case 512:
|
||||
syncCommitteeBits = bitfield.NewBitvector512()
|
||||
case 32:
|
||||
syncCommitteeBits = bitfield.NewBitvector32()
|
||||
default:
|
||||
return nil, errors.New("invalid bit vector size")
|
||||
}
|
||||
newSyncAggregate := ðpb.SyncAggregate{
|
||||
SyncCommitteeBits: syncCommitteeBits,
|
||||
SyncCommitteeSignature: append([]byte{0xC0}, make([]byte, 95)...),
|
||||
}
|
||||
|
||||
newHeader := bState.LatestBlockHeader()
|
||||
prevStateRoot, err := bState.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not hash state")
|
||||
}
|
||||
newHeader.StateRoot = prevStateRoot[:]
|
||||
parentRoot, err := newHeader.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not hash the new header")
|
||||
}
|
||||
|
||||
if slot == currentSlot {
|
||||
slot = currentSlot + 1
|
||||
}
|
||||
|
||||
reveal, err := RandaoReveal(stCopy, time.CurrentEpoch(stCopy), privs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute randao reveal")
|
||||
}
|
||||
|
||||
idx, err := helpers.BeaconProposerIndex(ctx, stCopy)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute beacon proposer index")
|
||||
}
|
||||
|
||||
block := ðpb.BeaconBlockBellatrix{
|
||||
Slot: slot,
|
||||
ParentRoot: parentRoot[:],
|
||||
ProposerIndex: idx,
|
||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||
Eth1Data: eth1Data,
|
||||
RandaoReveal: reveal,
|
||||
ProposerSlashings: pSlashings,
|
||||
AttesterSlashings: aSlashings,
|
||||
Attestations: atts,
|
||||
VoluntaryExits: exits,
|
||||
Deposits: newDeposits,
|
||||
Graffiti: make([]byte, fieldparams.RootLength),
|
||||
SyncAggregate: newSyncAggregate,
|
||||
ExecutionPayload: newExecutionPayload,
|
||||
},
|
||||
}
|
||||
|
||||
// The fork can change after processing the state
|
||||
signature, err := BlockSignature(bState, block, privs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute block signature")
|
||||
}
|
||||
|
||||
return ðpb.SignedBeaconBlockBellatrix{Block: block, Signature: signature.Marshal()}, nil
|
||||
}
|
||||
|
||||
func indexToHash(i uint64) [32]byte {
|
||||
var b [8]byte
|
||||
binary.LittleEndian.PutUint64(b[:], i)
|
||||
return hash.Hash(b[:])
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ type BlockGenConfig struct {
|
||||
NumAttestations uint64
|
||||
NumDeposits uint64
|
||||
NumVoluntaryExits uint64
|
||||
NumTransactions uint64 // Only for post Bellatrix blocks
|
||||
FullSyncAggregate bool
|
||||
}
|
||||
|
||||
// DefaultBlockGenConfig returns the block config that utilizes the
|
||||
@@ -45,6 +47,7 @@ func DefaultBlockGenConfig() *BlockGenConfig {
|
||||
NumAttestations: 1,
|
||||
NumDeposits: 0,
|
||||
NumVoluntaryExits: 0,
|
||||
NumTransactions: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||
@@ -37,39 +38,80 @@ func RandaoReveal(beaconState state.ReadOnlyBeaconState, epoch types.Epoch, priv
|
||||
// BlockSignature calculates the post-state root of the block and returns the signature.
|
||||
func BlockSignature(
|
||||
bState state.BeaconState,
|
||||
block *ethpb.BeaconBlock,
|
||||
block interface{},
|
||||
privKeys []bls.SecretKey,
|
||||
) (bls.Signature, error) {
|
||||
wsb, err := wrapper.WrappedSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: block})
|
||||
var wsb interfaces.SignedBeaconBlock
|
||||
var err error
|
||||
// copy the state since we need to process slots
|
||||
bState = bState.Copy()
|
||||
switch b := block.(type) {
|
||||
case *ethpb.BeaconBlock:
|
||||
wsb, err = wrapper.WrappedSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: b})
|
||||
case *ethpb.BeaconBlockAltair:
|
||||
wsb, err = wrapper.WrappedSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{Block: b})
|
||||
case *ethpb.BeaconBlockBellatrix:
|
||||
wsb, err = wrapper.WrappedSignedBeaconBlock(ðpb.SignedBeaconBlockBellatrix{Block: b})
|
||||
default:
|
||||
return nil, errors.New("unsupported block type")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not wrap block")
|
||||
}
|
||||
s, err := transition.CalculateStateRoot(context.Background(), bState, wsb)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not calculate state root")
|
||||
}
|
||||
|
||||
switch b := block.(type) {
|
||||
case *ethpb.BeaconBlock:
|
||||
b.StateRoot = s[:]
|
||||
case *ethpb.BeaconBlockAltair:
|
||||
b.StateRoot = s[:]
|
||||
case *ethpb.BeaconBlockBellatrix:
|
||||
b.StateRoot = s[:]
|
||||
}
|
||||
|
||||
// Temporarily increasing the beacon state slot here since BeaconProposerIndex is a
|
||||
// function deterministic on beacon state slot.
|
||||
var blockSlot types.Slot
|
||||
switch b := block.(type) {
|
||||
case *ethpb.BeaconBlock:
|
||||
blockSlot = b.Slot
|
||||
case *ethpb.BeaconBlockAltair:
|
||||
blockSlot = b.Slot
|
||||
case *ethpb.BeaconBlockBellatrix:
|
||||
blockSlot = b.Slot
|
||||
}
|
||||
|
||||
// process slots to get the right fork
|
||||
bState, err = transition.ProcessSlots(context.Background(), bState, blockSlot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
block.StateRoot = s[:]
|
||||
|
||||
domain, err := signing.Domain(bState.Fork(), time.CurrentEpoch(bState), params.BeaconConfig().DomainBeaconProposer, bState.GenesisValidatorsRoot())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockRoot, err := signing.ComputeSigningRoot(block, domain)
|
||||
|
||||
var blockRoot [32]byte
|
||||
switch b := block.(type) {
|
||||
case *ethpb.BeaconBlock:
|
||||
blockRoot, err = signing.ComputeSigningRoot(b, domain)
|
||||
case *ethpb.BeaconBlockAltair:
|
||||
blockRoot, err = signing.ComputeSigningRoot(b, domain)
|
||||
case *ethpb.BeaconBlockBellatrix:
|
||||
blockRoot, err = signing.ComputeSigningRoot(b, domain)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Temporarily increasing the beacon state slot here since BeaconProposerIndex is a
|
||||
// function deterministic on beacon state slot.
|
||||
currentSlot := bState.Slot()
|
||||
if err := bState.SetSlot(block.Slot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
proposerIdx, err := helpers.BeaconProposerIndex(context.Background(), bState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := bState.SetSlot(currentSlot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return privKeys[proposerIdx].Sign(blockRoot[:]), nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user