Compare commits

...

2 Commits

Author SHA1 Message Date
Sammy Rosso
0cf1ca8b3c Update produce block funcs to support Capella (#11959)
Co-authored-by: rkapka <rkapka@wp.pl>
2023-02-11 09:38:10 +08:00
terencechain
4dec2ebcf6 Add Capella fork epoch for Sepolia (#11979)
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2023-02-11 09:37:52 +08:00
8 changed files with 1273 additions and 23 deletions

View File

@@ -19,6 +19,7 @@ type MockBuilderService struct {
PayloadCapella *v1.ExecutionPayloadCapella
ErrSubmitBlindedBlock error
Bid *ethpb.SignedBuilderBid
BidCapella *ethpb.SignedBuilderBidCapella
ErrGetHeader error
ErrRegisterValidator error
}
@@ -46,9 +47,16 @@ func (s *MockBuilderService) SubmitBlindedBlock(_ context.Context, _ interfaces.
// GetHeader for mocking.
func (s *MockBuilderService) GetHeader(context.Context, primitives.Slot, [32]byte, [48]byte) (builder.SignedBid, error) {
w, err := builder.WrappedSignedBuilderBid(s.Bid)
if s.Bid != nil {
w, err := builder.WrappedSignedBuilderBid(s.Bid)
if err != nil {
return nil, errors.Wrap(err, "could not wrap bid")
}
return w, s.ErrGetHeader
}
w, err := builder.WrappedSignedBuilderBidCapella(s.BidCapella)
if err != nil {
return nil, errors.Wrap(err, "could not wrap bid")
return nil, errors.Wrap(err, "could not wrap capella bid")
}
return w, s.ErrGetHeader
}

View File

@@ -61,6 +61,7 @@ go_test(
"//beacon-chain/execution/testing:go_default_library",
"//beacon-chain/forkchoice/doubly-linked-tree:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/blstoexec:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",
"//beacon-chain/operations/synccommittee:go_default_library",
"//beacon-chain/operations/voluntaryexits:go_default_library",
@@ -69,6 +70,7 @@ go_test(
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
"//beacon-chain/rpc/testutil:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/sync/initial-sync/testing:go_default_library",
"//config/fieldparams:go_default_library",
@@ -76,7 +78,9 @@ go_test(
"//consensus-types/blocks:go_default_library",
"//consensus-types/primitives:go_default_library",
"//crypto/bls:go_default_library",
"//crypto/hash:go_default_library",
"//encoding/bytesutil:go_default_library",
"//encoding/ssz:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/eth/v1:go_default_library",
"//proto/eth/v2:go_default_library",

View File

@@ -355,6 +355,19 @@ func (vs *Server) ProduceBlockV2(ctx context.Context, req *ethpbv1.ProduceBlockR
},
}, nil
}
capellaBlock, ok := v1alpha1resp.Block.(*ethpbalpha.GenericBeaconBlock_Capella)
if ok {
block, err := migration.V1Alpha1BeaconBlockCapellaToV2(capellaBlock.Capella)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not prepare beacon block: %v", err)
}
return &ethpbv2.ProduceBlockResponseV2{
Version: ethpbv2.Version_CAPELLA,
Data: &ethpbv2.BeaconBlockContainerV2{
Block: &ethpbv2.BeaconBlockContainerV2_CapellaBlock{CapellaBlock: block},
},
}, nil
}
return nil, status.Error(codes.InvalidArgument, "Unsupported block type")
}
@@ -432,6 +445,21 @@ func (vs *Server) ProduceBlockV2SSZ(ctx context.Context, req *ethpbv1.ProduceBlo
Data: sszBlock,
}, nil
}
capellaBlock, ok := v1alpha1resp.Block.(*ethpbalpha.GenericBeaconBlock_Capella)
if ok {
block, err := migration.V1Alpha1BeaconBlockCapellaToV2(capellaBlock.Capella)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not prepare beacon block: %v", err)
}
sszBlock, err := block.MarshalSSZ()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not marshal block into SSZ format: %v", err)
}
return &ethpbv2.SSZContainer{
Version: ethpbv2.Version_CAPELLA,
Data: sszBlock,
}, nil
}
return nil, status.Error(codes.InvalidArgument, "Unsupported block type")
}
@@ -456,14 +484,14 @@ func (vs *Server) ProduceBlindedBlock(ctx context.Context, req *ethpbv1.ProduceB
RandaoReveal: req.RandaoReveal,
Graffiti: req.Graffiti,
}
v1alpha1resp, err := vs.V1Alpha1Server.GetBeaconBlock(ctx, v1alpha1req)
if err != nil {
// We simply return err because it's already of a gRPC error type.
return nil, err
}
// Before Bellatrix, return normal block.
if req.Slot < primitives.Slot(params.BeaconConfig().BellatrixForkEpoch)*params.BeaconConfig().SlotsPerEpoch {
v1alpha1resp, err := vs.V1Alpha1Server.GetBeaconBlock(ctx, v1alpha1req)
if err != nil {
// We simply return err because it's already of a gRPC error type.
return nil, err
}
phase0Block, ok := v1alpha1resp.Block.(*ethpbalpha.GenericBeaconBlock_Phase0)
if ok {
block, err := migration.V1Alpha1ToV1Block(phase0Block.Phase0)
@@ -491,8 +519,6 @@ func (vs *Server) ProduceBlindedBlock(ctx context.Context, req *ethpbv1.ProduceB
}, nil
}
}
// After Bellatrix, return blinded block.
optimistic, err := vs.OptimisticModeFetcher.IsOptimistic(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not determine if the node is a optimistic node: %v", err)
@@ -500,20 +526,33 @@ 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")
}
b, err := vs.V1Alpha1Server.GetBeaconBlock(ctx, v1alpha1req)
if err != nil {
return nil, status.Error(codes.Unavailable, "Could not get block from prysm API")
bellatrixBlock, ok := v1alpha1resp.Block.(*ethpbalpha.GenericBeaconBlock_BlindedBellatrix)
if ok {
blk, err := migration.V1Alpha1BeaconBlockBlindedBellatrixToV2Blinded(bellatrixBlock.BlindedBellatrix)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not prepare beacon block: %v", err)
}
return &ethpbv2.ProduceBlindedBlockResponse{
Version: ethpbv2.Version_BELLATRIX,
Data: &ethpbv2.BlindedBeaconBlockContainer{
Block: &ethpbv2.BlindedBeaconBlockContainer_BellatrixBlock{BellatrixBlock: blk},
},
}, nil
}
blk, err := migration.V1Alpha1BeaconBlockBlindedBellatrixToV2Blinded(b.GetBlindedBellatrix())
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not prepare beacon block: %v", err)
capellaBlock, ok := v1alpha1resp.Block.(*ethpbalpha.GenericBeaconBlock_BlindedCapella)
if ok {
blk, err := migration.V1Alpha1BeaconBlockBlindedCapellaToV2Blinded(capellaBlock.BlindedCapella)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not prepare beacon block: %v", err)
}
return &ethpbv2.ProduceBlindedBlockResponse{
Version: ethpbv2.Version_CAPELLA,
Data: &ethpbv2.BlindedBeaconBlockContainer{
Block: &ethpbv2.BlindedBeaconBlockContainer_CapellaBlock{CapellaBlock: blk},
},
}, nil
}
return &ethpbv2.ProduceBlindedBlockResponse{
Version: ethpbv2.Version_BELLATRIX,
Data: &ethpbv2.BlindedBeaconBlockContainer{
Block: &ethpbv2.BlindedBeaconBlockContainer_BellatrixBlock{BellatrixBlock: blk},
},
}, nil
return nil, status.Error(codes.InvalidArgument, "Unsupported block type")
}
// ProduceBlindedBlockSSZ requests the beacon node to produce a valid unsigned blinded beacon block,
@@ -586,6 +625,21 @@ func (vs *Server) ProduceBlindedBlockSSZ(ctx context.Context, req *ethpbv1.Produ
Data: sszBlock,
}, nil
}
capellaBlock, ok := v1alpha1resp.Block.(*ethpbalpha.GenericBeaconBlock_Capella)
if ok {
block, err := migration.V1Alpha1BeaconBlockCapellaToV2Blinded(capellaBlock.Capella)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not prepare beacon block: %v", err)
}
sszBlock, err := block.MarshalSSZ()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not marshal block into SSZ format: %v", err)
}
return &ethpbv2.SSZContainer{
Version: ethpbv2.Version_CAPELLA,
Data: sszBlock,
}, nil
}
return nil, status.Error(codes.InvalidArgument, "Unsupported block type")
}

File diff suppressed because it is too large Load Diff

View File

@@ -33,6 +33,7 @@ func SepoliaConfig() *BeaconChainConfig {
cfg.AltairForkVersion = []byte{0x90, 0x00, 0x00, 0x70}
cfg.BellatrixForkEpoch = 100
cfg.BellatrixForkVersion = []byte{0x90, 0x00, 0x00, 0x71}
cfg.CapellaForkEpoch = 56832
cfg.CapellaForkVersion = []byte{0x90, 0x00, 0x00, 0x72}
cfg.TerminalTotalDifficulty = "17000000000000000"
cfg.DepositContractAddress = "0x7f02C3E3c98b133055B8B348B2Ac625669Ed295D"

View File

@@ -11,7 +11,9 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/state:go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//crypto/hash:go_default_library",
"//encoding/bytesutil:go_default_library",
"//encoding/ssz:go_default_library",
"//proto/engine/v1:go_default_library",

View File

@@ -3,6 +3,8 @@ package migration
import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
"github.com/prysmaticlabs/prysm/v3/crypto/hash"
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v3/encoding/ssz"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
@@ -316,6 +318,201 @@ func V1Alpha1BeaconBlockBellatrixToV2Blinded(v1alpha1Block *ethpbalpha.BeaconBlo
return v2Block, nil
}
// V1Alpha1BeaconBlockCapellaToV2Blinded converts a v1alpha1 Capella beacon block to a v2
// blinded Capella block.
func V1Alpha1BeaconBlockCapellaToV2Blinded(v1alpha1Block *ethpbalpha.BeaconBlockCapella) (*ethpbv2.BlindedBeaconBlockCapella, error) {
sourceProposerSlashings := v1alpha1Block.Body.ProposerSlashings
resultProposerSlashings := make([]*ethpbv1.ProposerSlashing, len(sourceProposerSlashings))
for i, s := range sourceProposerSlashings {
resultProposerSlashings[i] = &ethpbv1.ProposerSlashing{
SignedHeader_1: &ethpbv1.SignedBeaconBlockHeader{
Message: &ethpbv1.BeaconBlockHeader{
Slot: s.Header_1.Header.Slot,
ProposerIndex: s.Header_1.Header.ProposerIndex,
ParentRoot: bytesutil.SafeCopyBytes(s.Header_1.Header.ParentRoot),
StateRoot: bytesutil.SafeCopyBytes(s.Header_1.Header.StateRoot),
BodyRoot: bytesutil.SafeCopyBytes(s.Header_1.Header.BodyRoot),
},
Signature: bytesutil.SafeCopyBytes(s.Header_1.Signature),
},
SignedHeader_2: &ethpbv1.SignedBeaconBlockHeader{
Message: &ethpbv1.BeaconBlockHeader{
Slot: s.Header_2.Header.Slot,
ProposerIndex: s.Header_2.Header.ProposerIndex,
ParentRoot: bytesutil.SafeCopyBytes(s.Header_2.Header.ParentRoot),
StateRoot: bytesutil.SafeCopyBytes(s.Header_2.Header.StateRoot),
BodyRoot: bytesutil.SafeCopyBytes(s.Header_2.Header.BodyRoot),
},
Signature: bytesutil.SafeCopyBytes(s.Header_2.Signature),
},
}
}
sourceAttesterSlashings := v1alpha1Block.Body.AttesterSlashings
resultAttesterSlashings := make([]*ethpbv1.AttesterSlashing, len(sourceAttesterSlashings))
for i, s := range sourceAttesterSlashings {
att1Indices := make([]uint64, len(s.Attestation_1.AttestingIndices))
copy(att1Indices, s.Attestation_1.AttestingIndices)
att2Indices := make([]uint64, len(s.Attestation_2.AttestingIndices))
copy(att2Indices, s.Attestation_2.AttestingIndices)
resultAttesterSlashings[i] = &ethpbv1.AttesterSlashing{
Attestation_1: &ethpbv1.IndexedAttestation{
AttestingIndices: att1Indices,
Data: &ethpbv1.AttestationData{
Slot: s.Attestation_1.Data.Slot,
Index: s.Attestation_1.Data.CommitteeIndex,
BeaconBlockRoot: bytesutil.SafeCopyBytes(s.Attestation_1.Data.BeaconBlockRoot),
Source: &ethpbv1.Checkpoint{
Epoch: s.Attestation_1.Data.Source.Epoch,
Root: bytesutil.SafeCopyBytes(s.Attestation_1.Data.Source.Root),
},
Target: &ethpbv1.Checkpoint{
Epoch: s.Attestation_1.Data.Target.Epoch,
Root: bytesutil.SafeCopyBytes(s.Attestation_1.Data.Target.Root),
},
},
Signature: bytesutil.SafeCopyBytes(s.Attestation_1.Signature),
},
Attestation_2: &ethpbv1.IndexedAttestation{
AttestingIndices: att2Indices,
Data: &ethpbv1.AttestationData{
Slot: s.Attestation_2.Data.Slot,
Index: s.Attestation_2.Data.CommitteeIndex,
BeaconBlockRoot: bytesutil.SafeCopyBytes(s.Attestation_2.Data.BeaconBlockRoot),
Source: &ethpbv1.Checkpoint{
Epoch: s.Attestation_2.Data.Source.Epoch,
Root: bytesutil.SafeCopyBytes(s.Attestation_2.Data.Source.Root),
},
Target: &ethpbv1.Checkpoint{
Epoch: s.Attestation_2.Data.Target.Epoch,
Root: bytesutil.SafeCopyBytes(s.Attestation_2.Data.Target.Root),
},
},
Signature: bytesutil.SafeCopyBytes(s.Attestation_2.Signature),
},
}
}
sourceAttestations := v1alpha1Block.Body.Attestations
resultAttestations := make([]*ethpbv1.Attestation, len(sourceAttestations))
for i, a := range sourceAttestations {
resultAttestations[i] = &ethpbv1.Attestation{
AggregationBits: bytesutil.SafeCopyBytes(a.AggregationBits),
Data: &ethpbv1.AttestationData{
Slot: a.Data.Slot,
Index: a.Data.CommitteeIndex,
BeaconBlockRoot: bytesutil.SafeCopyBytes(a.Data.BeaconBlockRoot),
Source: &ethpbv1.Checkpoint{
Epoch: a.Data.Source.Epoch,
Root: bytesutil.SafeCopyBytes(a.Data.Source.Root),
},
Target: &ethpbv1.Checkpoint{
Epoch: a.Data.Target.Epoch,
Root: bytesutil.SafeCopyBytes(a.Data.Target.Root),
},
},
Signature: bytesutil.SafeCopyBytes(a.Signature),
}
}
sourceDeposits := v1alpha1Block.Body.Deposits
resultDeposits := make([]*ethpbv1.Deposit, len(sourceDeposits))
for i, d := range sourceDeposits {
resultDeposits[i] = &ethpbv1.Deposit{
Proof: bytesutil.SafeCopy2dBytes(d.Proof),
Data: &ethpbv1.Deposit_Data{
Pubkey: bytesutil.SafeCopyBytes(d.Data.PublicKey),
WithdrawalCredentials: bytesutil.SafeCopyBytes(d.Data.WithdrawalCredentials),
Amount: d.Data.Amount,
Signature: bytesutil.SafeCopyBytes(d.Data.Signature),
},
}
}
sourceExits := v1alpha1Block.Body.VoluntaryExits
resultExits := make([]*ethpbv1.SignedVoluntaryExit, len(sourceExits))
for i, e := range sourceExits {
resultExits[i] = &ethpbv1.SignedVoluntaryExit{
Message: &ethpbv1.VoluntaryExit{
Epoch: e.Exit.Epoch,
ValidatorIndex: e.Exit.ValidatorIndex,
},
Signature: bytesutil.SafeCopyBytes(e.Signature),
}
}
transactionsRoot, err := ssz.TransactionsRoot(v1alpha1Block.Body.ExecutionPayload.Transactions)
if err != nil {
return nil, errors.Wrapf(err, "could not calculate transactions root")
}
withdrawalsRoot, err := ssz.WithdrawalSliceRoot(
hash.CustomSHA256Hasher(),
v1alpha1Block.Body.ExecutionPayload.Withdrawals,
fieldparams.MaxWithdrawalsPerPayload,
)
if err != nil {
return nil, errors.Wrapf(err, "could not calculate transactions root")
}
changes := make([]*ethpbv2.SignedBLSToExecutionChange, len(v1alpha1Block.Body.BlsToExecutionChanges))
for i, change := range v1alpha1Block.Body.BlsToExecutionChanges {
changes[i] = &ethpbv2.SignedBLSToExecutionChange{
Message: &ethpbv2.BLSToExecutionChange{
ValidatorIndex: change.Message.ValidatorIndex,
FromBlsPubkey: bytesutil.SafeCopyBytes(change.Message.FromBlsPubkey),
ToExecutionAddress: bytesutil.SafeCopyBytes(change.Message.ToExecutionAddress),
},
Signature: bytesutil.SafeCopyBytes(change.Signature),
}
}
resultBlockBody := &ethpbv2.BlindedBeaconBlockBodyCapella{
RandaoReveal: bytesutil.SafeCopyBytes(v1alpha1Block.Body.RandaoReveal),
Eth1Data: &ethpbv1.Eth1Data{
DepositRoot: bytesutil.SafeCopyBytes(v1alpha1Block.Body.Eth1Data.DepositRoot),
DepositCount: v1alpha1Block.Body.Eth1Data.DepositCount,
BlockHash: bytesutil.SafeCopyBytes(v1alpha1Block.Body.Eth1Data.BlockHash),
},
Graffiti: bytesutil.SafeCopyBytes(v1alpha1Block.Body.Graffiti),
ProposerSlashings: resultProposerSlashings,
AttesterSlashings: resultAttesterSlashings,
Attestations: resultAttestations,
Deposits: resultDeposits,
VoluntaryExits: resultExits,
SyncAggregate: &ethpbv1.SyncAggregate{
SyncCommitteeBits: bytesutil.SafeCopyBytes(v1alpha1Block.Body.SyncAggregate.SyncCommitteeBits),
SyncCommitteeSignature: bytesutil.SafeCopyBytes(v1alpha1Block.Body.SyncAggregate.SyncCommitteeSignature),
},
ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.ParentHash),
FeeRecipient: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.FeeRecipient),
StateRoot: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.StateRoot),
ReceiptsRoot: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.ReceiptsRoot),
LogsBloom: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.LogsBloom),
PrevRandao: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.PrevRandao),
BlockNumber: v1alpha1Block.Body.ExecutionPayload.BlockNumber,
GasLimit: v1alpha1Block.Body.ExecutionPayload.GasLimit,
GasUsed: v1alpha1Block.Body.ExecutionPayload.GasUsed,
Timestamp: v1alpha1Block.Body.ExecutionPayload.Timestamp,
ExtraData: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.ExtraData),
BaseFeePerGas: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.BaseFeePerGas),
BlockHash: bytesutil.SafeCopyBytes(v1alpha1Block.Body.ExecutionPayload.BlockHash),
TransactionsRoot: transactionsRoot[:],
WithdrawalsRoot: withdrawalsRoot[:],
},
BlsToExecutionChanges: changes,
}
v2Block := &ethpbv2.BlindedBeaconBlockCapella{
Slot: v1alpha1Block.Slot,
ProposerIndex: v1alpha1Block.ProposerIndex,
ParentRoot: bytesutil.SafeCopyBytes(v1alpha1Block.ParentRoot),
StateRoot: bytesutil.SafeCopyBytes(v1alpha1Block.StateRoot),
Body: resultBlockBody,
}
return v2Block, nil
}
// BeaconStateAltairToProto converts a state.BeaconState object to its protobuf equivalent.
func BeaconStateAltairToProto(altairState state.BeaconState) (*ethpbv2.BeaconState, error) {
sourceFork := altairState.Fork()

View File

@@ -250,6 +250,35 @@ func Test_V1Alpha1BeaconBlockBellatrixToV2Blinded(t *testing.T) {
assert.DeepEqual(t, alphaRoot, v2Root)
}
func Test_V1Alpha1BeaconBlockCapellaToV2Blinded(t *testing.T) {
alphaBlock := util.HydrateBeaconBlockCapella(&ethpbalpha.BeaconBlockCapella{})
alphaBlock.Slot = slot
alphaBlock.ProposerIndex = validatorIndex
alphaBlock.ParentRoot = parentRoot
alphaBlock.StateRoot = stateRoot
alphaBlock.Body.RandaoReveal = randaoReveal
alphaBlock.Body.Eth1Data = &ethpbalpha.Eth1Data{
DepositRoot: depositRoot,
DepositCount: depositCount,
BlockHash: blockHash,
}
syncCommitteeBits := bitfield.NewBitvector512()
syncCommitteeBits.SetBitAt(100, true)
alphaBlock.Body.SyncAggregate = &ethpbalpha.SyncAggregate{
SyncCommitteeBits: syncCommitteeBits,
SyncCommitteeSignature: signature,
}
alphaBlock.Body.ExecutionPayload.Transactions = [][]byte{[]byte("transaction1"), []byte("transaction2")}
v2Block, err := V1Alpha1BeaconBlockCapellaToV2Blinded(alphaBlock)
require.NoError(t, err)
alphaRoot, err := alphaBlock.HashTreeRoot()
require.NoError(t, err)
v2Root, err := v2Block.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, alphaRoot, v2Root)
}
func TestBeaconStateAltairToProto(t *testing.T) {
source, err := util.NewBeaconStateAltair(util.FillRootsNaturalOptAltair, func(state *ethpbalpha.BeaconStateAltair) error {
state.GenesisTime = 1