Add REST implementation for Validator's GetBeaconBlock (#11772)

* WIP

* WIP

* WIP

* Remove unused parameter

* Address PR comments

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
Patrice Vignola
2022-12-15 14:34:05 -08:00
committed by GitHub
parent 1c5b0596c7
commit e843cafe7d
23 changed files with 4107 additions and 679 deletions

View File

@@ -422,31 +422,31 @@ func prepareValidatorAggregates(body []byte, responseContainer interface{}) (api
}
type phase0BlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *SignedBeaconBlockContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
}
type altairBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *SignedBeaconBlockAltairContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
}
type bellatrixBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *SignedBeaconBlockBellatrixContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
}
type bellatrixBlindedBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *SignedBlindedBeaconBlockBellatrixContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
}
type capellaBlindedBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *SignedBlindedBeaconBlockCapellaContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
}
@@ -553,22 +553,22 @@ func serializeBlindedBlock(response interface{}) (apimiddleware.RunDefault, []by
}
type phase0StateResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BeaconStateJson `json:"data"`
}
type altairStateResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BeaconStateAltairJson `json:"data"`
}
type bellatrixStateResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BeaconStateBellatrixJson `json:"data"`
}
type capellaStateResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BeaconStateCapellaJson `json:"data"`
}
@@ -612,22 +612,22 @@ func serializeV2State(response interface{}) (apimiddleware.RunDefault, []byte, a
}
type phase0ProduceBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BeaconBlockJson `json:"data"`
}
type altairProduceBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BeaconBlockAltairJson `json:"data"`
}
type bellatrixProduceBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BeaconBlockBellatrixJson `json:"data"`
}
type bellatrixProduceBlindedBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BlindedBeaconBlockBellatrixJson `json:"data"`
}

View File

@@ -239,12 +239,12 @@ type ProduceBlockResponseJson struct {
}
type ProduceBlockResponseV2Json struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BeaconBlockContainerV2Json `json:"data"`
}
type ProduceBlindedBlockResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Data *BlindedBeaconBlockContainerJson `json:"data"`
}
@@ -685,7 +685,7 @@ type PeerJson struct {
}
type VersionJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
}
type BeaconStateJson struct {
@@ -1000,7 +1000,7 @@ func (*SszResponseJson) SSZOptimistic() bool {
}
type VersionedSSZResponseJson struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Data string `json:"data"`
}

View File

@@ -454,3 +454,9 @@ func LittleEndianBytesToBigInt(bytes []byte) *big.Int {
// Integers are stored as little-endian, but big.Int expects big-endian. So we need to reverse the byte order before decoding.
return new(big.Int).SetBytes(ReverseByteOrder(bytes))
}
// BigIntToLittleEndianBytes takes a big integer and returns its bytes stored as little-endian
func BigIntToLittleEndianBytes(bigInt *big.Int) []byte {
// big.Int.Bytes() returns bytes in big-endian order, so we need to reverse the byte order
return ReverseByteOrder(bigInt.Bytes())
}

View File

@@ -662,3 +662,11 @@ func TestLittleEndianBytesToBigInt(t *testing.T) {
expected := new(big.Int).SetInt64(1234567890)
assert.DeepEqual(t, expected, converted)
}
func TestBigIntToLittleEndianBytes(t *testing.T) {
expected := make([]byte, 4)
binary.LittleEndian.PutUint32(expected, 1234567890)
bigInt := new(big.Int).SetUint64(1234567890)
converted := bytesutil.BigIntToLittleEndianBytes(bigInt)
assert.DeepEqual(t, expected, converted)
}

View File

@@ -8,8 +8,10 @@ go_library(
"beacon_api_helpers.go",
"beacon_api_validator_client.go",
"beacon_block_json_helpers.go",
"beacon_block_proto_helpers.go",
"domain_data.go",
"genesis.go",
"get_beacon_block.go",
"index.go",
"json_rest_handler.go",
"propose_beacon_block.go",
@@ -26,6 +28,7 @@ go_library(
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//network/forks:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//validator/client/iface:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
@@ -44,8 +47,13 @@ go_test(
"beacon_api_helpers_test.go",
"beacon_api_validator_client_test.go",
"beacon_block_json_helpers_test.go",
"beacon_block_proto_helpers_test.go",
"domain_data_test.go",
"genesis_test.go",
"get_beacon_block_altair_test.go",
"get_beacon_block_bellatrix_test.go",
"get_beacon_block_phase0_test.go",
"get_beacon_block_test.go",
"index_test.go",
"json_rest_handler_test.go",
"propose_beacon_block_altair_test.go",

View File

@@ -71,13 +71,8 @@ func (c *beaconApiValidatorClient) GetAttestationData(_ context.Context, in *eth
return c.getAttestationData(in.Slot, in.CommitteeIndex)
}
func (c *beaconApiValidatorClient) GetBeaconBlock(ctx context.Context, in *ethpb.BlockRequest) (*ethpb.GenericBeaconBlock, error) {
if c.fallbackClient != nil {
return c.fallbackClient.GetBeaconBlock(ctx, in)
}
// TODO: Implement me
panic("beaconApiValidatorClient.GetBeaconBlock is not implemented. To use a fallback client, create this validator with NewBeaconApiValidatorClientWithFallback instead.")
func (c *beaconApiValidatorClient) GetBeaconBlock(_ context.Context, in *ethpb.BlockRequest) (*ethpb.GenericBeaconBlock, error) {
return c.getBeaconBlock(in.Slot, in.RandaoReveal, in.Graffiti)
}
func (c *beaconApiValidatorClient) GetFeeRecipientByPubKey(ctx context.Context, in *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error) {

View File

@@ -0,0 +1,352 @@
package beacon_api
import (
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
)
func convertProposerSlashingsToProto(jsonProposerSlashings []*apimiddleware.ProposerSlashingJson) ([]*ethpb.ProposerSlashing, error) {
proposerSlashings := make([]*ethpb.ProposerSlashing, len(jsonProposerSlashings))
for index, jsonProposerSlashing := range jsonProposerSlashings {
if jsonProposerSlashing == nil {
return nil, errors.Errorf("proposer slashing at index `%d` is nil", index)
}
header1, err := convertProposerSlashingSignedHeaderToProto(jsonProposerSlashing.Header_1)
if err != nil {
return nil, errors.Wrap(err, "failed to get proposer header 1")
}
header2, err := convertProposerSlashingSignedHeaderToProto(jsonProposerSlashing.Header_2)
if err != nil {
return nil, errors.Wrap(err, "failed to get proposer header 2")
}
proposerSlashings[index] = &ethpb.ProposerSlashing{
Header_1: header1,
Header_2: header2,
}
}
return proposerSlashings, nil
}
func convertProposerSlashingSignedHeaderToProto(signedHeader *apimiddleware.SignedBeaconBlockHeaderJson) (*ethpb.SignedBeaconBlockHeader, error) {
if signedHeader == nil {
return nil, errors.New("signed header is nil")
}
if signedHeader.Header == nil {
return nil, errors.New("header is nil")
}
slot, err := strconv.ParseUint(signedHeader.Header.Slot, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse header slot `%s`", signedHeader.Header.Slot)
}
proposerIndex, err := strconv.ParseUint(signedHeader.Header.ProposerIndex, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse header proposer index `%s`", signedHeader.Header.ProposerIndex)
}
parentRoot, err := hexutil.Decode(signedHeader.Header.ParentRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode header parent root `%s`", signedHeader.Header.ParentRoot)
}
stateRoot, err := hexutil.Decode(signedHeader.Header.StateRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode header state root `%s`", signedHeader.Header.StateRoot)
}
bodyRoot, err := hexutil.Decode(signedHeader.Header.BodyRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode header body root `%s`", signedHeader.Header.BodyRoot)
}
signature, err := hexutil.Decode(signedHeader.Signature)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode signature `%s`", signedHeader.Signature)
}
return &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: types.Slot(slot),
ProposerIndex: types.ValidatorIndex(proposerIndex),
ParentRoot: parentRoot,
StateRoot: stateRoot,
BodyRoot: bodyRoot,
},
Signature: signature,
}, nil
}
func convertAttesterSlashingsToProto(jsonAttesterSlashings []*apimiddleware.AttesterSlashingJson) ([]*ethpb.AttesterSlashing, error) {
attesterSlashings := make([]*ethpb.AttesterSlashing, len(jsonAttesterSlashings))
for index, jsonAttesterSlashing := range jsonAttesterSlashings {
if jsonAttesterSlashing == nil {
return nil, errors.Errorf("attester slashing at index `%d` is nil", index)
}
attestation1, err := convertAttestationToProto(jsonAttesterSlashing.Attestation_1)
if err != nil {
return nil, errors.Wrap(err, "failed to get attestation 1")
}
attestation2, err := convertAttestationToProto(jsonAttesterSlashing.Attestation_2)
if err != nil {
return nil, errors.Wrap(err, "failed to get attestation 2")
}
attesterSlashings[index] = &ethpb.AttesterSlashing{
Attestation_1: attestation1,
Attestation_2: attestation2,
}
}
return attesterSlashings, nil
}
func convertAttestationToProto(jsonAttestation *apimiddleware.IndexedAttestationJson) (*ethpb.IndexedAttestation, error) {
if jsonAttestation == nil {
return nil, errors.New("indexed attestation is nil")
}
attestingIndices := make([]uint64, len(jsonAttestation.AttestingIndices))
for index, jsonAttestingIndex := range jsonAttestation.AttestingIndices {
attestingIndex, err := strconv.ParseUint(jsonAttestingIndex, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse attesting index `%s`", jsonAttestingIndex)
}
attestingIndices[index] = attestingIndex
}
signature, err := hexutil.Decode(jsonAttestation.Signature)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode attestation signature `%s`", jsonAttestation.Signature)
}
attestationData, err := convertAttestationDataToProto(jsonAttestation.Data)
if err != nil {
return nil, errors.Wrap(err, "failed to get attestation data")
}
return &ethpb.IndexedAttestation{
AttestingIndices: attestingIndices,
Data: attestationData,
Signature: signature,
}, nil
}
func convertCheckpointToProto(jsonCheckpoint *apimiddleware.CheckpointJson) (*ethpb.Checkpoint, error) {
if jsonCheckpoint == nil {
return nil, errors.New("checkpoint is nil")
}
epoch, err := strconv.ParseUint(jsonCheckpoint.Epoch, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse checkpoint epoch `%s`", jsonCheckpoint.Epoch)
}
root, err := hexutil.Decode(jsonCheckpoint.Root)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode checkpoint root `%s`", jsonCheckpoint.Root)
}
return &ethpb.Checkpoint{
Epoch: types.Epoch(epoch),
Root: root,
}, nil
}
func convertAttestationsToProto(jsonAttestations []*apimiddleware.AttestationJson) ([]*ethpb.Attestation, error) {
attestations := make([]*ethpb.Attestation, len(jsonAttestations))
for index, jsonAttestation := range jsonAttestations {
if jsonAttestation == nil {
return nil, errors.Errorf("attestation at index `%d` is nil", index)
}
aggregationBits, err := hexutil.Decode(jsonAttestation.AggregationBits)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode aggregation bits `%s`", jsonAttestation.AggregationBits)
}
attestationData, err := convertAttestationDataToProto(jsonAttestation.Data)
if err != nil {
return nil, errors.Wrap(err, "failed to get attestation data")
}
signature, err := hexutil.Decode(jsonAttestation.Signature)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode attestation signature `%s`", jsonAttestation.Signature)
}
attestations[index] = &ethpb.Attestation{
AggregationBits: aggregationBits,
Data: attestationData,
Signature: signature,
}
}
return attestations, nil
}
func convertAttestationDataToProto(jsonAttestationData *apimiddleware.AttestationDataJson) (*ethpb.AttestationData, error) {
if jsonAttestationData == nil {
return nil, errors.New("attestation data is nil")
}
slot, err := strconv.ParseUint(jsonAttestationData.Slot, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse attestation slot `%s`", jsonAttestationData.Slot)
}
committeeIndex, err := strconv.ParseUint(jsonAttestationData.CommitteeIndex, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse attestation committee index `%s`", jsonAttestationData.CommitteeIndex)
}
beaconBlockRoot, err := hexutil.Decode(jsonAttestationData.BeaconBlockRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode attestation beacon block root `%s`", jsonAttestationData.BeaconBlockRoot)
}
sourceCheckpoint, err := convertCheckpointToProto(jsonAttestationData.Source)
if err != nil {
return nil, errors.Wrap(err, "failed to get attestation source checkpoint")
}
targetCheckpoint, err := convertCheckpointToProto(jsonAttestationData.Target)
if err != nil {
return nil, errors.Wrap(err, "failed to get attestation target checkpoint")
}
return &ethpb.AttestationData{
Slot: types.Slot(slot),
CommitteeIndex: types.CommitteeIndex(committeeIndex),
BeaconBlockRoot: beaconBlockRoot,
Source: sourceCheckpoint,
Target: targetCheckpoint,
}, nil
}
func convertDepositsToProto(jsonDeposits []*apimiddleware.DepositJson) ([]*ethpb.Deposit, error) {
deposits := make([]*ethpb.Deposit, len(jsonDeposits))
for depositIndex, jsonDeposit := range jsonDeposits {
if jsonDeposit == nil {
return nil, errors.Errorf("deposit at index `%d` is nil", depositIndex)
}
proofs := make([][]byte, len(jsonDeposit.Proof))
for proofIndex, jsonProof := range jsonDeposit.Proof {
proof, err := hexutil.Decode(jsonProof)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode deposit proof `%s`", jsonProof)
}
proofs[proofIndex] = proof
}
if jsonDeposit.Data == nil {
return nil, errors.Errorf("deposit data at index `%d` is nil", depositIndex)
}
pubkey, err := hexutil.Decode(jsonDeposit.Data.PublicKey)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode deposit public key `%s`", jsonDeposit.Data.PublicKey)
}
withdrawalCredentials, err := hexutil.Decode(jsonDeposit.Data.WithdrawalCredentials)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode deposit withdrawal credentials `%s`", jsonDeposit.Data.WithdrawalCredentials)
}
amount, err := strconv.ParseUint(jsonDeposit.Data.Amount, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse deposit amount `%s`", jsonDeposit.Data.Amount)
}
signature, err := hexutil.Decode(jsonDeposit.Data.Signature)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode signature `%s`", jsonDeposit.Data.Signature)
}
deposits[depositIndex] = &ethpb.Deposit{
Proof: proofs,
Data: &ethpb.Deposit_Data{
PublicKey: pubkey,
WithdrawalCredentials: withdrawalCredentials,
Amount: amount,
Signature: signature,
},
}
}
return deposits, nil
}
func convertVoluntaryExitsToProto(jsonVoluntaryExits []*apimiddleware.SignedVoluntaryExitJson) ([]*ethpb.SignedVoluntaryExit, error) {
attestingIndices := make([]*ethpb.SignedVoluntaryExit, len(jsonVoluntaryExits))
for index, jsonVoluntaryExit := range jsonVoluntaryExits {
if jsonVoluntaryExit == nil {
return nil, errors.Errorf("signed voluntary exit at index `%d` is nil", index)
}
if jsonVoluntaryExit.Exit == nil {
return nil, errors.Errorf("voluntary exit at index `%d` is nil", index)
}
epoch, err := strconv.ParseUint(jsonVoluntaryExit.Exit.Epoch, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse voluntary exit epoch `%s`", jsonVoluntaryExit.Exit.Epoch)
}
validatorIndex, err := strconv.ParseUint(jsonVoluntaryExit.Exit.ValidatorIndex, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse voluntary exit validator index `%s`", jsonVoluntaryExit.Exit.ValidatorIndex)
}
signature, err := hexutil.Decode(jsonVoluntaryExit.Signature)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode signature `%s`", jsonVoluntaryExit.Signature)
}
attestingIndices[index] = &ethpb.SignedVoluntaryExit{
Exit: &ethpb.VoluntaryExit{
Epoch: types.Epoch(epoch),
ValidatorIndex: types.ValidatorIndex(validatorIndex),
},
Signature: signature,
}
}
return attestingIndices, nil
}
func convertTransactionsToProto(jsonTransactions []string) ([][]byte, error) {
transactions := make([][]byte, len(jsonTransactions))
for index, jsonTransaction := range jsonTransactions {
transaction, err := hexutil.Decode(jsonTransaction)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode transaction `%s`", jsonTransaction)
}
transactions[index] = transaction
}
return transactions, nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,396 @@
package beacon_api
import (
"bytes"
"encoding/json"
"fmt"
"math/big"
neturl "net/url"
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
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"
)
type abstractProduceBlockResponseJson struct {
Version string `json:"version" enum:"true"`
Data json.RawMessage `json:"data"`
}
func (c beaconApiValidatorClient) getBeaconBlock(slot types.Slot, randaoReveal []byte, graffiti []byte) (*ethpb.GenericBeaconBlock, error) {
queryParams := neturl.Values{}
queryParams.Add("randao_reveal", hexutil.Encode(randaoReveal))
if len(graffiti) > 0 {
queryParams.Add("graffiti", hexutil.Encode(graffiti))
}
queryUrl := buildURL(fmt.Sprintf("/eth/v2/validator/blocks/%d", slot), queryParams)
// Since we don't know yet what the json looks like, we unmarshal into an abstract structure that has only a version
// and a blob of data
produceBlockResponseJson := abstractProduceBlockResponseJson{}
if _, err := c.jsonRestHandler.GetRestJsonResponse(queryUrl, &produceBlockResponseJson); err != nil {
return nil, errors.Wrap(err, "failed to query GET REST endpoint")
}
// Once we know what the consensus version is, we can go ahead and unmarshal into the specific structs unique to each version
decoder := json.NewDecoder(bytes.NewReader(produceBlockResponseJson.Data))
decoder.DisallowUnknownFields()
response := &ethpb.GenericBeaconBlock{}
switch produceBlockResponseJson.Version {
case "phase0":
jsonPhase0Block := apimiddleware.BeaconBlockJson{}
if err := decoder.Decode(&jsonPhase0Block); err != nil {
return nil, errors.Wrap(err, "failed to decode phase0 block response json")
}
phase0Block, err := convertRESTPhase0BlockToProto(&jsonPhase0Block)
if err != nil {
return nil, errors.Wrap(err, "failed to get phase0 block")
}
response.Block = phase0Block
case "altair":
jsonAltairBlock := apimiddleware.BeaconBlockAltairJson{}
if err := decoder.Decode(&jsonAltairBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode altair block response json")
}
altairBlock, err := convertRESTAltairBlockToProto(&jsonAltairBlock)
if err != nil {
return nil, errors.Wrap(err, "failed to get altair block")
}
response.Block = altairBlock
case "bellatrix":
jsonBellatrixBlock := apimiddleware.BeaconBlockBellatrixJson{}
if err := decoder.Decode(&jsonBellatrixBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode bellatrix block response json")
}
bellatrixBlock, err := convertRESTBellatrixBlockToProto(&jsonBellatrixBlock)
if err != nil {
return nil, errors.Wrap(err, "failed to get bellatrix block")
}
response.Block = bellatrixBlock
default:
return nil, errors.Errorf("unsupported consensus version `%s`", produceBlockResponseJson.Version)
}
return response, nil
}
func convertRESTPhase0BlockToProto(block *apimiddleware.BeaconBlockJson) (*ethpb.GenericBeaconBlock_Phase0, error) {
blockSlot, err := strconv.ParseUint(block.Slot, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse slot `%s`", block.Slot)
}
blockProposerIndex, err := strconv.ParseUint(block.ProposerIndex, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse proposer index `%s`", block.ProposerIndex)
}
parentRoot, err := hexutil.Decode(block.ParentRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode parent root `%s`", block.ParentRoot)
}
stateRoot, err := hexutil.Decode(block.StateRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode state root `%s`", block.StateRoot)
}
if block.Body == nil {
return nil, errors.New("block body is nil")
}
randaoReveal, err := hexutil.Decode(block.Body.RandaoReveal)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode randao reveal `%s`", block.Body.RandaoReveal)
}
if block.Body.Eth1Data == nil {
return nil, errors.New("eth1 data is nil")
}
depositRoot, err := hexutil.Decode(block.Body.Eth1Data.DepositRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode deposit root `%s`", block.Body.Eth1Data.DepositRoot)
}
depositCount, err := strconv.ParseUint(block.Body.Eth1Data.DepositCount, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse deposit count `%s`", block.Body.Eth1Data.DepositCount)
}
blockHash, err := hexutil.Decode(block.Body.Eth1Data.BlockHash)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode block hash `%s`", block.Body.Eth1Data.BlockHash)
}
graffiti, err := hexutil.Decode(block.Body.Graffiti)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode graffiti `%s`", block.Body.Graffiti)
}
proposerSlashings, err := convertProposerSlashingsToProto(block.Body.ProposerSlashings)
if err != nil {
return nil, errors.Wrap(err, "failed to get proposer slashings")
}
attesterSlashings, err := convertAttesterSlashingsToProto(block.Body.AttesterSlashings)
if err != nil {
return nil, errors.Wrap(err, "failed to get attester slashings")
}
attestations, err := convertAttestationsToProto(block.Body.Attestations)
if err != nil {
return nil, errors.Wrap(err, "failed to get attestations")
}
deposits, err := convertDepositsToProto(block.Body.Deposits)
if err != nil {
return nil, errors.Wrap(err, "failed to get deposits")
}
voluntaryExits, err := convertVoluntaryExitsToProto(block.Body.VoluntaryExits)
if err != nil {
return nil, errors.Wrap(err, "failed to get voluntary exits")
}
return &ethpb.GenericBeaconBlock_Phase0{
Phase0: &ethpb.BeaconBlock{
Slot: types.Slot(blockSlot),
ProposerIndex: types.ValidatorIndex(blockProposerIndex),
ParentRoot: parentRoot,
StateRoot: stateRoot,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: randaoReveal,
Eth1Data: &ethpb.Eth1Data{
DepositRoot: depositRoot,
DepositCount: depositCount,
BlockHash: blockHash,
},
Graffiti: graffiti,
ProposerSlashings: proposerSlashings,
AttesterSlashings: attesterSlashings,
Attestations: attestations,
Deposits: deposits,
VoluntaryExits: voluntaryExits,
},
},
}, nil
}
func convertRESTAltairBlockToProto(block *apimiddleware.BeaconBlockAltairJson) (*ethpb.GenericBeaconBlock_Altair, error) {
if block.Body == nil {
return nil, errors.New("block body is nil")
}
// Call convertRESTPhase0BlockToProto to set the phase0 fields because all the error handling and the heavy lifting
// has already been done
phase0Block, err := convertRESTPhase0BlockToProto(&apimiddleware.BeaconBlockJson{
Slot: block.Slot,
ProposerIndex: block.ProposerIndex,
ParentRoot: block.ParentRoot,
StateRoot: block.StateRoot,
Body: &apimiddleware.BeaconBlockBodyJson{
RandaoReveal: block.Body.RandaoReveal,
Eth1Data: block.Body.Eth1Data,
Graffiti: block.Body.Graffiti,
ProposerSlashings: block.Body.ProposerSlashings,
AttesterSlashings: block.Body.AttesterSlashings,
Attestations: block.Body.Attestations,
Deposits: block.Body.Deposits,
VoluntaryExits: block.Body.VoluntaryExits,
},
})
if err != nil {
return nil, errors.Wrap(err, "failed to get the phase0 fields of the altair block")
}
if block.Body.SyncAggregate == nil {
return nil, errors.New("sync aggregate is nil")
}
syncCommitteeBits, err := hexutil.Decode(block.Body.SyncAggregate.SyncCommitteeBits)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode sync committee bits `%s`", block.Body.SyncAggregate.SyncCommitteeBits)
}
syncCommitteeSignature, err := hexutil.Decode(block.Body.SyncAggregate.SyncCommitteeSignature)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode sync committee signature `%s`", block.Body.SyncAggregate.SyncCommitteeSignature)
}
return &ethpb.GenericBeaconBlock_Altair{
Altair: &ethpb.BeaconBlockAltair{
Slot: phase0Block.Phase0.Slot,
ProposerIndex: phase0Block.Phase0.ProposerIndex,
ParentRoot: phase0Block.Phase0.ParentRoot,
StateRoot: phase0Block.Phase0.StateRoot,
Body: &ethpb.BeaconBlockBodyAltair{
RandaoReveal: phase0Block.Phase0.Body.RandaoReveal,
Eth1Data: phase0Block.Phase0.Body.Eth1Data,
Graffiti: phase0Block.Phase0.Body.Graffiti,
ProposerSlashings: phase0Block.Phase0.Body.ProposerSlashings,
AttesterSlashings: phase0Block.Phase0.Body.AttesterSlashings,
Attestations: phase0Block.Phase0.Body.Attestations,
Deposits: phase0Block.Phase0.Body.Deposits,
VoluntaryExits: phase0Block.Phase0.Body.VoluntaryExits,
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: syncCommitteeBits,
SyncCommitteeSignature: syncCommitteeSignature,
},
},
},
}, nil
}
func convertRESTBellatrixBlockToProto(block *apimiddleware.BeaconBlockBellatrixJson) (*ethpb.GenericBeaconBlock_Bellatrix, error) {
if block.Body == nil {
return nil, errors.New("block body is nil")
}
// Call convertRESTAltairBlockToProto to set the altair fields because all the error handling and the heavy lifting
// has already been done
altairBlock, err := convertRESTAltairBlockToProto(&apimiddleware.BeaconBlockAltairJson{
Slot: block.Slot,
ProposerIndex: block.ProposerIndex,
ParentRoot: block.ParentRoot,
StateRoot: block.StateRoot,
Body: &apimiddleware.BeaconBlockBodyAltairJson{
RandaoReveal: block.Body.RandaoReveal,
Eth1Data: block.Body.Eth1Data,
Graffiti: block.Body.Graffiti,
ProposerSlashings: block.Body.ProposerSlashings,
AttesterSlashings: block.Body.AttesterSlashings,
Attestations: block.Body.Attestations,
Deposits: block.Body.Deposits,
VoluntaryExits: block.Body.VoluntaryExits,
SyncAggregate: block.Body.SyncAggregate,
},
})
if err != nil {
return nil, errors.Wrap(err, "failed to get the altair fields of the bellatrix block")
}
if block.Body.ExecutionPayload == nil {
return nil, errors.New("execution payload is nil")
}
parentHash, err := hexutil.Decode(block.Body.ExecutionPayload.ParentHash)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode execution payload parent hash `%s`", block.Body.ExecutionPayload.ParentHash)
}
feeRecipient, err := hexutil.Decode(block.Body.ExecutionPayload.FeeRecipient)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode execution payload fee recipient `%s`", block.Body.ExecutionPayload.FeeRecipient)
}
stateRoot, err := hexutil.Decode(block.Body.ExecutionPayload.StateRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode execution payload state root `%s`", block.Body.ExecutionPayload.StateRoot)
}
receiptsRoot, err := hexutil.Decode(block.Body.ExecutionPayload.ReceiptsRoot)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode execution payload receipts root `%s`", block.Body.ExecutionPayload.ReceiptsRoot)
}
logsBloom, err := hexutil.Decode(block.Body.ExecutionPayload.LogsBloom)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode execution payload logs bloom `%s`", block.Body.ExecutionPayload.LogsBloom)
}
prevRandao, err := hexutil.Decode(block.Body.ExecutionPayload.PrevRandao)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode execution payload prev randao `%s`", block.Body.ExecutionPayload.PrevRandao)
}
blockNumber, err := strconv.ParseUint(block.Body.ExecutionPayload.BlockNumber, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse execution payload block number `%s`", block.Body.ExecutionPayload.BlockNumber)
}
gasLimit, err := strconv.ParseUint(block.Body.ExecutionPayload.GasLimit, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse execution payload gas limit `%s`", block.Body.ExecutionPayload.GasLimit)
}
gasUsed, err := strconv.ParseUint(block.Body.ExecutionPayload.GasUsed, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse execution payload gas used `%s`", block.Body.ExecutionPayload.GasUsed)
}
timestamp, err := strconv.ParseUint(block.Body.ExecutionPayload.TimeStamp, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse execution payload timestamp `%s`", block.Body.ExecutionPayload.TimeStamp)
}
extraData, err := hexutil.Decode(block.Body.ExecutionPayload.ExtraData)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode execution payload extra data `%s`", block.Body.ExecutionPayload.ExtraData)
}
baseFeePerGas := new(big.Int)
if _, ok := baseFeePerGas.SetString(block.Body.ExecutionPayload.BaseFeePerGas, 10); !ok {
return nil, errors.Errorf("failed to parse execution payload base fee per gas `%s`", block.Body.ExecutionPayload.BaseFeePerGas)
}
blockHash, err := hexutil.Decode(block.Body.ExecutionPayload.BlockHash)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode execution payload block hash `%s`", block.Body.ExecutionPayload.BlockHash)
}
transactions, err := convertTransactionsToProto(block.Body.ExecutionPayload.Transactions)
if err != nil {
return nil, errors.Wrap(err, "failed to get execution payload transactions")
}
return &ethpb.GenericBeaconBlock_Bellatrix{
Bellatrix: &ethpb.BeaconBlockBellatrix{
Slot: altairBlock.Altair.Slot,
ProposerIndex: altairBlock.Altair.ProposerIndex,
ParentRoot: altairBlock.Altair.ParentRoot,
StateRoot: altairBlock.Altair.StateRoot,
Body: &ethpb.BeaconBlockBodyBellatrix{
RandaoReveal: altairBlock.Altair.Body.RandaoReveal,
Eth1Data: altairBlock.Altair.Body.Eth1Data,
Graffiti: altairBlock.Altair.Body.Graffiti,
ProposerSlashings: altairBlock.Altair.Body.ProposerSlashings,
AttesterSlashings: altairBlock.Altair.Body.AttesterSlashings,
Attestations: altairBlock.Altair.Body.Attestations,
Deposits: altairBlock.Altair.Body.Deposits,
VoluntaryExits: altairBlock.Altair.Body.VoluntaryExits,
SyncAggregate: altairBlock.Altair.Body.SyncAggregate,
ExecutionPayload: &enginev1.ExecutionPayload{
ParentHash: parentHash,
FeeRecipient: feeRecipient,
StateRoot: stateRoot,
ReceiptsRoot: receiptsRoot,
LogsBloom: logsBloom,
PrevRandao: prevRandao,
BlockNumber: blockNumber,
GasLimit: gasLimit,
GasUsed: gasUsed,
Timestamp: timestamp,
ExtraData: extraData,
BaseFeePerGas: bytesutil.PadTo(bytesutil.BigIntToLittleEndianBytes(baseFeePerGas), 32),
BlockHash: blockHash,
Transactions: transactions,
},
},
},
}, nil
}

View File

@@ -0,0 +1,144 @@
package beacon_api
import (
"encoding/json"
"fmt"
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
"github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/mock"
test_helpers "github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/test-helpers"
)
func TestGetBeaconBlock_AltairValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
altairProtoBeaconBlock := test_helpers.GenerateProtoAltairBeaconBlock()
altairBeaconBlockBytes, err := json.Marshal(test_helpers.GenerateJsonAltairBeaconBlock())
require.NoError(t, err)
const slot = types.Slot(1)
randaoReveal := []byte{2}
graffiti := []byte{3}
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
fmt.Sprintf("/eth/v2/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
).SetArg(
1,
abstractProduceBlockResponseJson{
Version: "altair",
Data: altairBeaconBlockBytes,
},
).Return(
nil,
nil,
).Times(1)
expectedBeaconBlock := generateProtoAltairBlock(altairProtoBeaconBlock)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(slot, randaoReveal, graffiti)
require.NoError(t, err)
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_AltairError(t *testing.T) {
testCases := []struct {
name string
expectedErrorMessage string
generateData func() *apimiddleware.BeaconBlockAltairJson
}{
{
name: "nil body",
expectedErrorMessage: "block body is nil",
generateData: func() *apimiddleware.BeaconBlockAltairJson {
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body = nil
return beaconBlock
},
},
{
name: "nil sync aggregate",
expectedErrorMessage: "sync aggregate is nil",
generateData: func() *apimiddleware.BeaconBlockAltairJson {
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body.SyncAggregate = nil
return beaconBlock
},
},
{
name: "bad phase0 fields",
expectedErrorMessage: "failed to get the phase0 fields of the altair block",
generateData: func() *apimiddleware.BeaconBlockAltairJson {
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body.Eth1Data = nil
return beaconBlock
},
},
{
name: "bad sync committee bits",
expectedErrorMessage: "failed to decode sync committee bits `foo`",
generateData: func() *apimiddleware.BeaconBlockAltairJson {
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body.SyncAggregate.SyncCommitteeBits = "foo"
return beaconBlock
},
},
{
name: "bad sync committee signature",
expectedErrorMessage: "failed to decode sync committee signature `bar`",
generateData: func() *apimiddleware.BeaconBlockAltairJson {
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body.SyncAggregate.SyncCommitteeSignature = "bar"
return beaconBlock
},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
dataBytes, err := json.Marshal(testCase.generateData())
require.NoError(t, err)
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
gomock.Any(),
&abstractProduceBlockResponseJson{},
).SetArg(
1,
abstractProduceBlockResponseJson{
Version: "altair",
Data: dataBytes,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err = validatorClient.getBeaconBlock(1, []byte{1}, []byte{2})
assert.ErrorContains(t, "failed to get altair block", err)
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
})
}
}
func generateProtoAltairBlock(altairProtoBeaconBlock *ethpb.BeaconBlockAltair) *ethpb.GenericBeaconBlock {
return &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Altair{
Altair: altairProtoBeaconBlock,
},
}
}

View File

@@ -0,0 +1,252 @@
package beacon_api
import (
"encoding/json"
"fmt"
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
"github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/mock"
test_helpers "github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/test-helpers"
)
func TestGetBeaconBlock_BellatrixValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
bellatrixProtoBeaconBlock := test_helpers.GenerateProtoBellatrixBeaconBlock()
bellatrixBeaconBlockBytes, err := json.Marshal(test_helpers.GenerateJsonBellatrixBeaconBlock())
require.NoError(t, err)
const slot = types.Slot(1)
randaoReveal := []byte{2}
graffiti := []byte{3}
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
fmt.Sprintf("/eth/v2/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
).SetArg(
1,
abstractProduceBlockResponseJson{
Version: "bellatrix",
Data: bellatrixBeaconBlockBytes,
},
).Return(
nil,
nil,
).Times(1)
expectedBeaconBlock := generateProtoBellatrixBlock(bellatrixProtoBeaconBlock)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(slot, randaoReveal, graffiti)
require.NoError(t, err)
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_BellatrixError(t *testing.T) {
testCases := []struct {
name string
expectedErrorMessage string
generateData func() *apimiddleware.BeaconBlockBellatrixJson
}{
{
name: "nil body",
expectedErrorMessage: "block body is nil",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body = nil
return beaconBlock
},
},
{
name: "nil execution payload",
expectedErrorMessage: "execution payload is nil",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload = nil
return beaconBlock
},
},
{
name: "bad altair fields",
expectedErrorMessage: "failed to get the altair fields of the bellatrix block",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.Eth1Data = nil
return beaconBlock
},
},
{
name: "bad parent hash",
expectedErrorMessage: "failed to decode execution payload parent hash `foo`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.ParentHash = "foo"
return beaconBlock
},
},
{
name: "bad fee recipient",
expectedErrorMessage: "failed to decode execution payload fee recipient `bar`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.FeeRecipient = "bar"
return beaconBlock
},
},
{
name: "bad state root",
expectedErrorMessage: "failed to decode execution payload state root `foo`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.StateRoot = "foo"
return beaconBlock
},
},
{
name: "bad receipts root",
expectedErrorMessage: "failed to decode execution payload receipts root `bar`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.ReceiptsRoot = "bar"
return beaconBlock
},
},
{
name: "bad logs bloom",
expectedErrorMessage: "failed to decode execution payload logs bloom `foo`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.LogsBloom = "foo"
return beaconBlock
},
},
{
name: "bad prev randao",
expectedErrorMessage: "failed to decode execution payload prev randao `bar`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.PrevRandao = "bar"
return beaconBlock
},
},
{
name: "bad block number",
expectedErrorMessage: "failed to parse execution payload block number `foo`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.BlockNumber = "foo"
return beaconBlock
},
},
{
name: "bad gas limit",
expectedErrorMessage: "failed to parse execution payload gas limit `bar`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.GasLimit = "bar"
return beaconBlock
},
},
{
name: "bad gas used",
expectedErrorMessage: "failed to parse execution payload gas used `foo`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.GasUsed = "foo"
return beaconBlock
},
},
{
name: "bad timestamp",
expectedErrorMessage: "failed to parse execution payload timestamp `bar`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.TimeStamp = "bar"
return beaconBlock
},
},
{
name: "bad extra data",
expectedErrorMessage: "failed to decode execution payload extra data `foo`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.ExtraData = "foo"
return beaconBlock
},
},
{
name: "bad base fee per gas",
expectedErrorMessage: "failed to parse execution payload base fee per gas `bar`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.BaseFeePerGas = "bar"
return beaconBlock
},
},
{
name: "bad block hash",
expectedErrorMessage: "failed to decode execution payload block hash `foo`",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.BlockHash = "foo"
return beaconBlock
},
},
{
name: "bad transactions",
expectedErrorMessage: "failed to get execution payload transactions",
generateData: func() *apimiddleware.BeaconBlockBellatrixJson {
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.Transactions[0] = "bar"
return beaconBlock
},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
dataBytes, err := json.Marshal(testCase.generateData())
require.NoError(t, err)
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
gomock.Any(),
&abstractProduceBlockResponseJson{},
).SetArg(
1,
abstractProduceBlockResponseJson{
Version: "bellatrix",
Data: dataBytes,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err = validatorClient.getBeaconBlock(1, []byte{1}, []byte{2})
assert.ErrorContains(t, "failed to get bellatrix block", err)
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
})
}
}
func generateProtoBellatrixBlock(bellatrixProtoBeaconBlock *ethpb.BeaconBlockBellatrix) *ethpb.GenericBeaconBlock {
return &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Bellatrix{
Bellatrix: bellatrixProtoBeaconBlock,
},
}
}

View File

@@ -0,0 +1,243 @@
package beacon_api
import (
"encoding/json"
"fmt"
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
"github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/mock"
test_helpers "github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/test-helpers"
)
func TestGetBeaconBlock_Phase0Valid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
phase0ProtoBeaconBlock := test_helpers.GenerateProtoPhase0BeaconBlock()
phase0BeaconBlockBytes, err := json.Marshal(test_helpers.GenerateJsonPhase0BeaconBlock())
require.NoError(t, err)
const slot = types.Slot(1)
randaoReveal := []byte{2}
graffiti := []byte{3}
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
fmt.Sprintf("/eth/v2/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
).SetArg(
1,
abstractProduceBlockResponseJson{
Version: "phase0",
Data: phase0BeaconBlockBytes,
},
).Return(
nil,
nil,
).Times(1)
expectedBeaconBlock := generateProtoPhase0Block(phase0ProtoBeaconBlock)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(slot, randaoReveal, graffiti)
require.NoError(t, err)
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_Phase0Error(t *testing.T) {
testCases := []struct {
name string
expectedErrorMessage string
generateData func() *apimiddleware.BeaconBlockJson
}{
{
name: "nil body",
expectedErrorMessage: "block body is nil",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body = nil
return beaconBlock
},
},
{
name: "nil eth1 data",
expectedErrorMessage: "eth1 data is nil",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Eth1Data = nil
return beaconBlock
},
},
{
name: "bad slot",
expectedErrorMessage: "failed to parse slot `foo`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Slot = "foo"
return beaconBlock
},
},
{
name: "bad proposer index",
expectedErrorMessage: "failed to parse proposer index `bar`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.ProposerIndex = "bar"
return beaconBlock
},
},
{
name: "bad parent root",
expectedErrorMessage: "failed to decode parent root `foo`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.ParentRoot = "foo"
return beaconBlock
},
},
{
name: "bad state root",
expectedErrorMessage: "failed to decode state root `bar`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.StateRoot = "bar"
return beaconBlock
},
},
{
name: "bad randao reveal",
expectedErrorMessage: "failed to decode randao reveal `foo`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.RandaoReveal = "foo"
return beaconBlock
},
},
{
name: "bad deposit root",
expectedErrorMessage: "failed to decode deposit root `bar`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Eth1Data.DepositRoot = "bar"
return beaconBlock
},
},
{
name: "bad deposit count",
expectedErrorMessage: "failed to parse deposit count `foo`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Eth1Data.DepositCount = "foo"
return beaconBlock
},
},
{
name: "bad block hash",
expectedErrorMessage: "failed to decode block hash `bar`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Eth1Data.BlockHash = "bar"
return beaconBlock
},
},
{
name: "bad graffiti",
expectedErrorMessage: "failed to decode graffiti `foo`",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Graffiti = "foo"
return beaconBlock
},
},
{
name: "bad proposer slashings",
expectedErrorMessage: "failed to get proposer slashings",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.ProposerSlashings[0] = nil
return beaconBlock
},
},
{
name: "bad attester slashings",
expectedErrorMessage: "failed to get attester slashings",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.AttesterSlashings[0] = nil
return beaconBlock
},
},
{
name: "bad attestations",
expectedErrorMessage: "failed to get attestations",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Attestations[0] = nil
return beaconBlock
},
},
{
name: "bad deposits",
expectedErrorMessage: "failed to get deposits",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Deposits[0] = nil
return beaconBlock
},
},
{
name: "bad voluntary exits",
expectedErrorMessage: "failed to get voluntary exits",
generateData: func() *apimiddleware.BeaconBlockJson {
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.VoluntaryExits[0] = nil
return beaconBlock
},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
dataBytes, err := json.Marshal(testCase.generateData())
require.NoError(t, err)
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
gomock.Any(),
&abstractProduceBlockResponseJson{},
).SetArg(
1,
abstractProduceBlockResponseJson{
Version: "phase0",
Data: dataBytes,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err = validatorClient.getBeaconBlock(1, []byte{1}, []byte{2})
assert.ErrorContains(t, "failed to get phase0 block", err)
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
})
}
}
func generateProtoPhase0Block(phase0ProtoBeaconBlock *ethpb.BeaconBlock) *ethpb.GenericBeaconBlock {
return &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Phase0{
Phase0: phase0ProtoBeaconBlock,
},
}
}

View File

@@ -0,0 +1,118 @@
package beacon_api
import (
"encoding/json"
"errors"
"testing"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
"github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/mock"
)
func TestGetBeaconBlock_RequestFailed(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
gomock.Any(),
gomock.Any(),
).Return(
nil,
errors.New("foo error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.getBeaconBlock(1, []byte{1}, []byte{2})
assert.ErrorContains(t, "failed to query GET REST endpoint", err)
assert.ErrorContains(t, "foo error", err)
}
func TestGetBeaconBlock_Error(t *testing.T) {
phase0BeaconBlockBytes, err := json.Marshal(apimiddleware.BeaconBlockJson{})
require.NoError(t, err)
altairBeaconBlockBytes, err := json.Marshal(apimiddleware.BeaconBlockAltairJson{})
require.NoError(t, err)
bellatrixBeaconBlockBytes, err := json.Marshal(apimiddleware.BeaconBlockBellatrixJson{})
require.NoError(t, err)
testCases := []struct {
name string
beaconBlock interface{}
expectedErrorMessage string
consensusVersion string
data json.RawMessage
}{
{
name: "phase0 block decoding failed",
expectedErrorMessage: "failed to decode phase0 block response json",
consensusVersion: "phase0",
data: []byte{},
},
{
name: "phase0 block conversion failed",
expectedErrorMessage: "failed to get phase0 block",
consensusVersion: "phase0",
data: phase0BeaconBlockBytes,
},
{
name: "altair block decoding failed",
expectedErrorMessage: "failed to decode altair block response json",
consensusVersion: "altair",
data: []byte{},
},
{
name: "altair block conversion failed",
expectedErrorMessage: "failed to get altair block",
consensusVersion: "altair",
data: altairBeaconBlockBytes,
},
{
name: "bellatrix block decoding failed",
expectedErrorMessage: "failed to decode bellatrix block response json",
beaconBlock: "foo",
consensusVersion: "bellatrix",
data: []byte{},
},
{
name: "bellatrix block conversion failed",
expectedErrorMessage: "failed to get bellatrix block",
consensusVersion: "bellatrix",
data: bellatrixBeaconBlockBytes,
},
{
name: "unsupported consensus version",
expectedErrorMessage: "unsupported consensus version `foo`",
consensusVersion: "foo",
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
gomock.Any(),
&abstractProduceBlockResponseJson{},
).SetArg(
1,
abstractProduceBlockResponseJson{
Version: testCase.consensusVersion,
Data: testCase.data,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.getBeaconBlock(1, []byte{1}, []byte{2})
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
})
}
}

View File

@@ -69,9 +69,12 @@ func (c beaconApiJsonRestHandler) PostRestJson(apiEndpoint string, headers map[s
}
func decodeJsonResp(resp *http.Response, responseJson interface{}) (*apimiddleware.DefaultErrorJson, error) {
decoder := json.NewDecoder(resp.Body)
decoder.DisallowUnknownFields()
if resp.StatusCode != http.StatusOK {
errorJson := &apimiddleware.DefaultErrorJson{}
if err := json.NewDecoder(resp.Body).Decode(errorJson); err != nil {
if err := decoder.Decode(errorJson); err != nil {
return nil, errors.Wrapf(err, "failed to decode error json for %s", resp.Request.URL)
}
@@ -79,7 +82,7 @@ func decodeJsonResp(resp *http.Response, responseJson interface{}) (*apimiddlewa
}
if responseJson != nil {
if err := json.NewDecoder(resp.Body).Decode(responseJson); err != nil {
if err := decoder.Decode(responseJson); err != nil {
return nil, errors.Wrapf(err, "failed to decode response json for %s", resp.Request.URL)
}
}

View File

@@ -76,217 +76,7 @@ func TestProposeBeaconBlock_Altair(t *testing.T) {
func generateSignedAltairBlock() *ethpb.GenericSignedBeaconBlock_Altair {
return &ethpb.GenericSignedBeaconBlock_Altair{
Altair: &ethpb.SignedBeaconBlockAltair{
Block: &ethpb.BeaconBlockAltair{
Slot: 1,
ProposerIndex: 2,
ParentRoot: test_helpers.FillByteSlice(32, 3),
StateRoot: test_helpers.FillByteSlice(32, 4),
Body: &ethpb.BeaconBlockBodyAltair{
RandaoReveal: test_helpers.FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: test_helpers.FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: test_helpers.FillByteSlice(32, 8),
},
Graffiti: test_helpers.FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: test_helpers.FillByteSlice(32, 12),
StateRoot: test_helpers.FillByteSlice(32, 13),
BodyRoot: test_helpers.FillByteSlice(32, 14),
},
Signature: test_helpers.FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: test_helpers.FillByteSlice(32, 18),
StateRoot: test_helpers.FillByteSlice(32, 19),
BodyRoot: test_helpers.FillByteSlice(32, 20),
},
Signature: test_helpers.FillByteSlice(96, 21),
},
},
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: test_helpers.FillByteSlice(32, 24),
StateRoot: test_helpers.FillByteSlice(32, 25),
BodyRoot: test_helpers.FillByteSlice(32, 26),
},
Signature: test_helpers.FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: test_helpers.FillByteSlice(32, 30),
StateRoot: test_helpers.FillByteSlice(32, 31),
BodyRoot: test_helpers.FillByteSlice(32, 32),
},
Signature: test_helpers.FillByteSlice(96, 33),
},
},
},
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{34, 35},
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: test_helpers.FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: test_helpers.FillByteSlice(32, 42),
},
},
Signature: test_helpers.FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: test_helpers.FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: test_helpers.FillByteSlice(32, 52),
},
},
Signature: test_helpers.FillByteSlice(96, 53),
},
},
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{54, 55},
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: test_helpers.FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: test_helpers.FillByteSlice(32, 62),
},
},
Signature: test_helpers.FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: test_helpers.FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: test_helpers.FillByteSlice(32, 72),
},
},
Signature: test_helpers.FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: test_helpers.FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: test_helpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: test_helpers.FillByteSlice(32, 81),
},
},
Signature: test_helpers.FillByteSlice(96, 82),
},
{
AggregationBits: test_helpers.FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: test_helpers.FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: test_helpers.FillByteSlice(32, 90),
},
},
Signature: test_helpers.FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: test_helpers.FillByteSlice(48, 94),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 95),
Amount: 96,
Signature: test_helpers.FillByteSlice(96, 97),
},
},
{
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: test_helpers.FillByteSlice(48, 100),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 101),
Amount: 102,
Signature: test_helpers.FillByteSlice(96, 103),
},
},
},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 104,
ValidatorIndex: 105,
},
Signature: test_helpers.FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: test_helpers.FillByteSlice(96, 109),
},
},
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: test_helpers.FillByteSlice(64, 110),
SyncCommitteeSignature: test_helpers.FillByteSlice(96, 111),
},
},
},
Block: test_helpers.GenerateProtoAltairBeaconBlock(),
Signature: test_helpers.FillByteSlice(96, 112),
},
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
"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/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
@@ -94,236 +93,7 @@ func TestProposeBeaconBlock_Bellatrix(t *testing.T) {
func generateSignedBellatrixBlock() *ethpb.GenericSignedBeaconBlock_Bellatrix {
return &ethpb.GenericSignedBeaconBlock_Bellatrix{
Bellatrix: &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Slot: 1,
ProposerIndex: 2,
ParentRoot: test_helpers.FillByteSlice(32, 3),
StateRoot: test_helpers.FillByteSlice(32, 4),
Body: &ethpb.BeaconBlockBodyBellatrix{
RandaoReveal: test_helpers.FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: test_helpers.FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: test_helpers.FillByteSlice(32, 8),
},
Graffiti: test_helpers.FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: test_helpers.FillByteSlice(32, 12),
StateRoot: test_helpers.FillByteSlice(32, 13),
BodyRoot: test_helpers.FillByteSlice(32, 14),
},
Signature: test_helpers.FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: test_helpers.FillByteSlice(32, 18),
StateRoot: test_helpers.FillByteSlice(32, 19),
BodyRoot: test_helpers.FillByteSlice(32, 20),
},
Signature: test_helpers.FillByteSlice(96, 21),
},
},
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: test_helpers.FillByteSlice(32, 24),
StateRoot: test_helpers.FillByteSlice(32, 25),
BodyRoot: test_helpers.FillByteSlice(32, 26),
},
Signature: test_helpers.FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: test_helpers.FillByteSlice(32, 30),
StateRoot: test_helpers.FillByteSlice(32, 31),
BodyRoot: test_helpers.FillByteSlice(32, 32),
},
Signature: test_helpers.FillByteSlice(96, 33),
},
},
},
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{34, 35},
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: test_helpers.FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: test_helpers.FillByteSlice(32, 42),
},
},
Signature: test_helpers.FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: test_helpers.FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: test_helpers.FillByteSlice(32, 52),
},
},
Signature: test_helpers.FillByteSlice(96, 53),
},
},
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{54, 55},
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: test_helpers.FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: test_helpers.FillByteSlice(32, 62),
},
},
Signature: test_helpers.FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: test_helpers.FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: test_helpers.FillByteSlice(32, 72),
},
},
Signature: test_helpers.FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: test_helpers.FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: test_helpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: test_helpers.FillByteSlice(32, 81),
},
},
Signature: test_helpers.FillByteSlice(96, 82),
},
{
AggregationBits: test_helpers.FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: test_helpers.FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: test_helpers.FillByteSlice(32, 90),
},
},
Signature: test_helpers.FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: test_helpers.FillByteSlice(48, 94),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 95),
Amount: 96,
Signature: test_helpers.FillByteSlice(96, 97),
},
},
{
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: test_helpers.FillByteSlice(48, 100),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 101),
Amount: 102,
Signature: test_helpers.FillByteSlice(96, 103),
},
},
},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 104,
ValidatorIndex: 105,
},
Signature: test_helpers.FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: test_helpers.FillByteSlice(96, 109),
},
},
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: test_helpers.FillByteSlice(64, 110),
SyncCommitteeSignature: test_helpers.FillByteSlice(96, 111),
},
ExecutionPayload: &enginev1.ExecutionPayload{
ParentHash: test_helpers.FillByteSlice(32, 112),
FeeRecipient: test_helpers.FillByteSlice(20, 113),
StateRoot: test_helpers.FillByteSlice(32, 114),
ReceiptsRoot: test_helpers.FillByteSlice(32, 115),
LogsBloom: test_helpers.FillByteSlice(256, 116),
PrevRandao: test_helpers.FillByteSlice(32, 117),
BlockNumber: 118,
GasLimit: 119,
GasUsed: 120,
Timestamp: 121,
ExtraData: test_helpers.FillByteSlice(32, 122),
BaseFeePerGas: test_helpers.FillByteSlice(32, 123),
BlockHash: test_helpers.FillByteSlice(32, 124),
Transactions: [][]byte{
{125},
{126},
},
},
},
},
Block: test_helpers.GenerateProtoBellatrixBeaconBlock(),
Signature: test_helpers.FillByteSlice(96, 127),
},
}

View File

@@ -72,213 +72,7 @@ func TestProposeBeaconBlock_Phase0(t *testing.T) {
func generateSignedPhase0Block() *ethpb.GenericSignedBeaconBlock_Phase0 {
return &ethpb.GenericSignedBeaconBlock_Phase0{
Phase0: &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: 1,
ProposerIndex: 2,
ParentRoot: test_helpers.FillByteSlice(32, 3),
StateRoot: test_helpers.FillByteSlice(32, 4),
Body: &ethpb.BeaconBlockBody{
RandaoReveal: test_helpers.FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: test_helpers.FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: test_helpers.FillByteSlice(32, 8),
},
Graffiti: test_helpers.FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: test_helpers.FillByteSlice(32, 12),
StateRoot: test_helpers.FillByteSlice(32, 13),
BodyRoot: test_helpers.FillByteSlice(32, 14),
},
Signature: test_helpers.FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: test_helpers.FillByteSlice(32, 18),
StateRoot: test_helpers.FillByteSlice(32, 19),
BodyRoot: test_helpers.FillByteSlice(32, 20),
},
Signature: test_helpers.FillByteSlice(96, 21),
},
},
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: test_helpers.FillByteSlice(32, 24),
StateRoot: test_helpers.FillByteSlice(32, 25),
BodyRoot: test_helpers.FillByteSlice(32, 26),
},
Signature: test_helpers.FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: test_helpers.FillByteSlice(32, 30),
StateRoot: test_helpers.FillByteSlice(32, 31),
BodyRoot: test_helpers.FillByteSlice(32, 32),
},
Signature: test_helpers.FillByteSlice(96, 33),
},
},
},
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{34, 35},
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: test_helpers.FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: test_helpers.FillByteSlice(32, 42),
},
},
Signature: test_helpers.FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 48),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: test_helpers.FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: test_helpers.FillByteSlice(32, 52),
},
},
Signature: test_helpers.FillByteSlice(96, 53),
},
},
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{54, 55},
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 58),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: test_helpers.FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: test_helpers.FillByteSlice(32, 62),
},
},
Signature: test_helpers.FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 68),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: test_helpers.FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: test_helpers.FillByteSlice(32, 72),
},
},
Signature: test_helpers.FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: test_helpers.FillByteSlice(32, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 77),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: test_helpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: test_helpers.FillByteSlice(32, 81),
},
},
Signature: test_helpers.FillByteSlice(96, 82),
},
{
AggregationBits: test_helpers.FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: test_helpers.FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: test_helpers.FillByteSlice(32, 90),
},
},
Signature: test_helpers.FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: test_helpers.FillByteSlice(48, 94),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 95),
Amount: 96,
Signature: test_helpers.FillByteSlice(96, 97),
},
},
{
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: test_helpers.FillByteSlice(48, 100),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 101),
Amount: 102,
Signature: test_helpers.FillByteSlice(96, 103),
},
},
},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 104,
ValidatorIndex: 105,
},
Signature: test_helpers.FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: test_helpers.FillByteSlice(96, 109),
},
},
},
},
Block: test_helpers.GenerateProtoPhase0BeaconBlock(),
Signature: test_helpers.FillByteSlice(96, 110),
},
}

View File

@@ -3,7 +3,19 @@ load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
testonly = True,
srcs = ["test_helpers.go"],
srcs = [
"altair_beacon_block_test_helpers.go",
"bellatrix_beacon_block_test_helpers.go",
"phase0_beacon_block_test_helpers.go",
"test_helpers.go",
],
importpath = "github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/test-helpers",
visibility = ["//validator:__subpackages__"],
deps = [
"//beacon-chain/rpc/apimiddleware:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
],
)

View File

@@ -0,0 +1,434 @@
package test_helpers
import (
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
)
func GenerateProtoAltairBeaconBlock() *ethpb.BeaconBlockAltair {
return &ethpb.BeaconBlockAltair{
Slot: 1,
ProposerIndex: 2,
ParentRoot: FillByteSlice(32, 3),
StateRoot: FillByteSlice(32, 4),
Body: &ethpb.BeaconBlockBodyAltair{
RandaoReveal: FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: FillByteSlice(32, 8),
},
Graffiti: FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: FillByteSlice(32, 12),
StateRoot: FillByteSlice(32, 13),
BodyRoot: FillByteSlice(32, 14),
},
Signature: FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: FillByteSlice(32, 18),
StateRoot: FillByteSlice(32, 19),
BodyRoot: FillByteSlice(32, 20),
},
Signature: FillByteSlice(96, 21),
},
},
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: FillByteSlice(32, 24),
StateRoot: FillByteSlice(32, 25),
BodyRoot: FillByteSlice(32, 26),
},
Signature: FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: FillByteSlice(32, 30),
StateRoot: FillByteSlice(32, 31),
BodyRoot: FillByteSlice(32, 32),
},
Signature: FillByteSlice(96, 33),
},
},
},
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{34, 35},
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: FillByteSlice(32, 42),
},
},
Signature: FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: FillByteSlice(32, 52),
},
},
Signature: FillByteSlice(96, 53),
},
},
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{54, 55},
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: FillByteSlice(32, 62),
},
},
Signature: FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: FillByteSlice(32, 72),
},
},
Signature: FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: FillByteSlice(32, 81),
},
},
Signature: FillByteSlice(96, 82),
},
{
AggregationBits: FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: FillByteSlice(32, 90),
},
},
Signature: FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 94),
WithdrawalCredentials: FillByteSlice(32, 95),
Amount: 96,
Signature: FillByteSlice(96, 97),
},
},
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 100),
WithdrawalCredentials: FillByteSlice(32, 101),
Amount: 102,
Signature: FillByteSlice(96, 103),
},
},
},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 104,
ValidatorIndex: 105,
},
Signature: FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: FillByteSlice(96, 109),
},
},
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: FillByteSlice(64, 110),
SyncCommitteeSignature: FillByteSlice(96, 111),
},
},
}
}
func GenerateJsonAltairBeaconBlock() *apimiddleware.BeaconBlockAltairJson {
return &apimiddleware.BeaconBlockAltairJson{
Slot: "1",
ProposerIndex: "2",
ParentRoot: FillEncodedByteSlice(32, 3),
StateRoot: FillEncodedByteSlice(32, 4),
Body: &apimiddleware.BeaconBlockBodyAltairJson{
RandaoReveal: FillEncodedByteSlice(96, 5),
Eth1Data: &apimiddleware.Eth1DataJson{
DepositRoot: FillEncodedByteSlice(32, 6),
DepositCount: "7",
BlockHash: FillEncodedByteSlice(32, 8),
},
Graffiti: FillEncodedByteSlice(32, 9),
ProposerSlashings: []*apimiddleware.ProposerSlashingJson{
{
Header_1: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "10",
ProposerIndex: "11",
ParentRoot: FillEncodedByteSlice(32, 12),
StateRoot: FillEncodedByteSlice(32, 13),
BodyRoot: FillEncodedByteSlice(32, 14),
},
Signature: FillEncodedByteSlice(96, 15),
},
Header_2: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "16",
ProposerIndex: "17",
ParentRoot: FillEncodedByteSlice(32, 18),
StateRoot: FillEncodedByteSlice(32, 19),
BodyRoot: FillEncodedByteSlice(32, 20),
},
Signature: FillEncodedByteSlice(96, 21),
},
},
{
Header_1: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "22",
ProposerIndex: "23",
ParentRoot: FillEncodedByteSlice(32, 24),
StateRoot: FillEncodedByteSlice(32, 25),
BodyRoot: FillEncodedByteSlice(32, 26),
},
Signature: FillEncodedByteSlice(96, 27),
},
Header_2: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "28",
ProposerIndex: "29",
ParentRoot: FillEncodedByteSlice(32, 30),
StateRoot: FillEncodedByteSlice(32, 31),
BodyRoot: FillEncodedByteSlice(32, 32),
},
Signature: FillEncodedByteSlice(96, 33),
},
},
},
AttesterSlashings: []*apimiddleware.AttesterSlashingJson{
{
Attestation_1: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"34", "35"},
Data: &apimiddleware.AttestationDataJson{
Slot: "36",
CommitteeIndex: "37",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "39",
Root: FillEncodedByteSlice(32, 40),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "41",
Root: FillEncodedByteSlice(32, 42),
},
},
Signature: FillEncodedByteSlice(96, 43),
},
Attestation_2: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"44", "45"},
Data: &apimiddleware.AttestationDataJson{
Slot: "46",
CommitteeIndex: "47",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "49",
Root: FillEncodedByteSlice(32, 50),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "51",
Root: FillEncodedByteSlice(32, 52),
},
},
Signature: FillEncodedByteSlice(96, 53),
},
},
{
Attestation_1: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"54", "55"},
Data: &apimiddleware.AttestationDataJson{
Slot: "56",
CommitteeIndex: "57",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "59",
Root: FillEncodedByteSlice(32, 60),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "61",
Root: FillEncodedByteSlice(32, 62),
},
},
Signature: FillEncodedByteSlice(96, 63),
},
Attestation_2: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"64", "65"},
Data: &apimiddleware.AttestationDataJson{
Slot: "66",
CommitteeIndex: "67",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "69",
Root: FillEncodedByteSlice(32, 70),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "71",
Root: FillEncodedByteSlice(32, 72),
},
},
Signature: FillEncodedByteSlice(96, 73),
},
},
},
Attestations: []*apimiddleware.AttestationJson{
{
AggregationBits: FillEncodedByteSlice(4, 74),
Data: &apimiddleware.AttestationDataJson{
Slot: "75",
CommitteeIndex: "76",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "78",
Root: FillEncodedByteSlice(32, 79),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "80",
Root: FillEncodedByteSlice(32, 81),
},
},
Signature: FillEncodedByteSlice(96, 82),
},
{
AggregationBits: FillEncodedByteSlice(4, 83),
Data: &apimiddleware.AttestationDataJson{
Slot: "84",
CommitteeIndex: "85",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "87",
Root: FillEncodedByteSlice(32, 88),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "89",
Root: FillEncodedByteSlice(32, 90),
},
},
Signature: FillEncodedByteSlice(96, 91),
},
},
Deposits: []*apimiddleware.DepositJson{
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 92)),
Data: &apimiddleware.Deposit_DataJson{
PublicKey: FillEncodedByteSlice(48, 94),
WithdrawalCredentials: FillEncodedByteSlice(32, 95),
Amount: "96",
Signature: FillEncodedByteSlice(96, 97),
},
},
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 98)),
Data: &apimiddleware.Deposit_DataJson{
PublicKey: FillEncodedByteSlice(48, 100),
WithdrawalCredentials: FillEncodedByteSlice(32, 101),
Amount: "102",
Signature: FillEncodedByteSlice(96, 103),
},
},
},
VoluntaryExits: []*apimiddleware.SignedVoluntaryExitJson{
{
Exit: &apimiddleware.VoluntaryExitJson{
Epoch: "104",
ValidatorIndex: "105",
},
Signature: FillEncodedByteSlice(96, 106),
},
{
Exit: &apimiddleware.VoluntaryExitJson{
Epoch: "107",
ValidatorIndex: "108",
},
Signature: FillEncodedByteSlice(96, 109),
},
},
SyncAggregate: &apimiddleware.SyncAggregateJson{
SyncCommitteeBits: FillEncodedByteSlice(64, 110),
SyncCommitteeSignature: FillEncodedByteSlice(96, 111),
},
},
}
}

View File

@@ -0,0 +1,474 @@
package test_helpers
import (
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
"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"
)
func GenerateProtoBellatrixBeaconBlock() *ethpb.BeaconBlockBellatrix {
return &ethpb.BeaconBlockBellatrix{
Slot: 1,
ProposerIndex: 2,
ParentRoot: FillByteSlice(32, 3),
StateRoot: FillByteSlice(32, 4),
Body: &ethpb.BeaconBlockBodyBellatrix{
RandaoReveal: FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: FillByteSlice(32, 8),
},
Graffiti: FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: FillByteSlice(32, 12),
StateRoot: FillByteSlice(32, 13),
BodyRoot: FillByteSlice(32, 14),
},
Signature: FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: FillByteSlice(32, 18),
StateRoot: FillByteSlice(32, 19),
BodyRoot: FillByteSlice(32, 20),
},
Signature: FillByteSlice(96, 21),
},
},
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: FillByteSlice(32, 24),
StateRoot: FillByteSlice(32, 25),
BodyRoot: FillByteSlice(32, 26),
},
Signature: FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: FillByteSlice(32, 30),
StateRoot: FillByteSlice(32, 31),
BodyRoot: FillByteSlice(32, 32),
},
Signature: FillByteSlice(96, 33),
},
},
},
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{34, 35},
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: FillByteSlice(32, 42),
},
},
Signature: FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: FillByteSlice(32, 52),
},
},
Signature: FillByteSlice(96, 53),
},
},
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{54, 55},
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: FillByteSlice(32, 62),
},
},
Signature: FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: FillByteSlice(32, 72),
},
},
Signature: FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: FillByteSlice(32, 81),
},
},
Signature: FillByteSlice(96, 82),
},
{
AggregationBits: FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: FillByteSlice(32, 90),
},
},
Signature: FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 94),
WithdrawalCredentials: FillByteSlice(32, 95),
Amount: 96,
Signature: FillByteSlice(96, 97),
},
},
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 100),
WithdrawalCredentials: FillByteSlice(32, 101),
Amount: 102,
Signature: FillByteSlice(96, 103),
},
},
},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 104,
ValidatorIndex: 105,
},
Signature: FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: FillByteSlice(96, 109),
},
},
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: FillByteSlice(64, 110),
SyncCommitteeSignature: FillByteSlice(96, 111),
},
ExecutionPayload: &enginev1.ExecutionPayload{
ParentHash: FillByteSlice(32, 112),
FeeRecipient: FillByteSlice(20, 113),
StateRoot: FillByteSlice(32, 114),
ReceiptsRoot: FillByteSlice(32, 115),
LogsBloom: FillByteSlice(256, 116),
PrevRandao: FillByteSlice(32, 117),
BlockNumber: 118,
GasLimit: 119,
GasUsed: 120,
Timestamp: 121,
ExtraData: FillByteSlice(32, 122),
BaseFeePerGas: FillByteSlice(32, 123),
BlockHash: FillByteSlice(32, 124),
Transactions: [][]byte{
FillByteSlice(32, 125),
FillByteSlice(32, 126),
},
},
},
}
}
func GenerateJsonBellatrixBeaconBlock() *apimiddleware.BeaconBlockBellatrixJson {
return &apimiddleware.BeaconBlockBellatrixJson{
Slot: "1",
ProposerIndex: "2",
ParentRoot: FillEncodedByteSlice(32, 3),
StateRoot: FillEncodedByteSlice(32, 4),
Body: &apimiddleware.BeaconBlockBodyBellatrixJson{
RandaoReveal: FillEncodedByteSlice(96, 5),
Eth1Data: &apimiddleware.Eth1DataJson{
DepositRoot: FillEncodedByteSlice(32, 6),
DepositCount: "7",
BlockHash: FillEncodedByteSlice(32, 8),
},
Graffiti: FillEncodedByteSlice(32, 9),
ProposerSlashings: []*apimiddleware.ProposerSlashingJson{
{
Header_1: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "10",
ProposerIndex: "11",
ParentRoot: FillEncodedByteSlice(32, 12),
StateRoot: FillEncodedByteSlice(32, 13),
BodyRoot: FillEncodedByteSlice(32, 14),
},
Signature: FillEncodedByteSlice(96, 15),
},
Header_2: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "16",
ProposerIndex: "17",
ParentRoot: FillEncodedByteSlice(32, 18),
StateRoot: FillEncodedByteSlice(32, 19),
BodyRoot: FillEncodedByteSlice(32, 20),
},
Signature: FillEncodedByteSlice(96, 21),
},
},
{
Header_1: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "22",
ProposerIndex: "23",
ParentRoot: FillEncodedByteSlice(32, 24),
StateRoot: FillEncodedByteSlice(32, 25),
BodyRoot: FillEncodedByteSlice(32, 26),
},
Signature: FillEncodedByteSlice(96, 27),
},
Header_2: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "28",
ProposerIndex: "29",
ParentRoot: FillEncodedByteSlice(32, 30),
StateRoot: FillEncodedByteSlice(32, 31),
BodyRoot: FillEncodedByteSlice(32, 32),
},
Signature: FillEncodedByteSlice(96, 33),
},
},
},
AttesterSlashings: []*apimiddleware.AttesterSlashingJson{
{
Attestation_1: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"34", "35"},
Data: &apimiddleware.AttestationDataJson{
Slot: "36",
CommitteeIndex: "37",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "39",
Root: FillEncodedByteSlice(32, 40),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "41",
Root: FillEncodedByteSlice(32, 42),
},
},
Signature: FillEncodedByteSlice(96, 43),
},
Attestation_2: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"44", "45"},
Data: &apimiddleware.AttestationDataJson{
Slot: "46",
CommitteeIndex: "47",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "49",
Root: FillEncodedByteSlice(32, 50),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "51",
Root: FillEncodedByteSlice(32, 52),
},
},
Signature: FillEncodedByteSlice(96, 53),
},
},
{
Attestation_1: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"54", "55"},
Data: &apimiddleware.AttestationDataJson{
Slot: "56",
CommitteeIndex: "57",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "59",
Root: FillEncodedByteSlice(32, 60),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "61",
Root: FillEncodedByteSlice(32, 62),
},
},
Signature: FillEncodedByteSlice(96, 63),
},
Attestation_2: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"64", "65"},
Data: &apimiddleware.AttestationDataJson{
Slot: "66",
CommitteeIndex: "67",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "69",
Root: FillEncodedByteSlice(32, 70),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "71",
Root: FillEncodedByteSlice(32, 72),
},
},
Signature: FillEncodedByteSlice(96, 73),
},
},
},
Attestations: []*apimiddleware.AttestationJson{
{
AggregationBits: FillEncodedByteSlice(4, 74),
Data: &apimiddleware.AttestationDataJson{
Slot: "75",
CommitteeIndex: "76",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "78",
Root: FillEncodedByteSlice(32, 79),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "80",
Root: FillEncodedByteSlice(32, 81),
},
},
Signature: FillEncodedByteSlice(96, 82),
},
{
AggregationBits: FillEncodedByteSlice(4, 83),
Data: &apimiddleware.AttestationDataJson{
Slot: "84",
CommitteeIndex: "85",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "87",
Root: FillEncodedByteSlice(32, 88),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "89",
Root: FillEncodedByteSlice(32, 90),
},
},
Signature: FillEncodedByteSlice(96, 91),
},
},
Deposits: []*apimiddleware.DepositJson{
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 92)),
Data: &apimiddleware.Deposit_DataJson{
PublicKey: FillEncodedByteSlice(48, 94),
WithdrawalCredentials: FillEncodedByteSlice(32, 95),
Amount: "96",
Signature: FillEncodedByteSlice(96, 97),
},
},
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 98)),
Data: &apimiddleware.Deposit_DataJson{
PublicKey: FillEncodedByteSlice(48, 100),
WithdrawalCredentials: FillEncodedByteSlice(32, 101),
Amount: "102",
Signature: FillEncodedByteSlice(96, 103),
},
},
},
VoluntaryExits: []*apimiddleware.SignedVoluntaryExitJson{
{
Exit: &apimiddleware.VoluntaryExitJson{
Epoch: "104",
ValidatorIndex: "105",
},
Signature: FillEncodedByteSlice(96, 106),
},
{
Exit: &apimiddleware.VoluntaryExitJson{
Epoch: "107",
ValidatorIndex: "108",
},
Signature: FillEncodedByteSlice(96, 109),
},
},
SyncAggregate: &apimiddleware.SyncAggregateJson{
SyncCommitteeBits: FillEncodedByteSlice(64, 110),
SyncCommitteeSignature: FillEncodedByteSlice(96, 111),
},
ExecutionPayload: &apimiddleware.ExecutionPayloadJson{
ParentHash: FillEncodedByteSlice(32, 112),
FeeRecipient: FillEncodedByteSlice(20, 113),
StateRoot: FillEncodedByteSlice(32, 114),
ReceiptsRoot: FillEncodedByteSlice(32, 115),
LogsBloom: FillEncodedByteSlice(256, 116),
PrevRandao: FillEncodedByteSlice(32, 117),
BlockNumber: "118",
GasLimit: "119",
GasUsed: "120",
TimeStamp: "121",
ExtraData: FillEncodedByteSlice(32, 122),
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(FillByteSlice(32, 123)).String(),
BlockHash: FillEncodedByteSlice(32, 124),
Transactions: []string{
FillEncodedByteSlice(32, 125),
FillEncodedByteSlice(32, 126),
},
},
},
}
}

View File

@@ -0,0 +1,426 @@
package test_helpers
import (
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
)
func GenerateProtoPhase0BeaconBlock() *ethpb.BeaconBlock {
return &ethpb.BeaconBlock{
Slot: 1,
ProposerIndex: 2,
ParentRoot: FillByteSlice(32, 3),
StateRoot: FillByteSlice(32, 4),
Body: &ethpb.BeaconBlockBody{
RandaoReveal: FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: FillByteSlice(32, 8),
},
Graffiti: FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: FillByteSlice(32, 12),
StateRoot: FillByteSlice(32, 13),
BodyRoot: FillByteSlice(32, 14),
},
Signature: FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: FillByteSlice(32, 18),
StateRoot: FillByteSlice(32, 19),
BodyRoot: FillByteSlice(32, 20),
},
Signature: FillByteSlice(96, 21),
},
},
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: FillByteSlice(32, 24),
StateRoot: FillByteSlice(32, 25),
BodyRoot: FillByteSlice(32, 26),
},
Signature: FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: FillByteSlice(32, 30),
StateRoot: FillByteSlice(32, 31),
BodyRoot: FillByteSlice(32, 32),
},
Signature: FillByteSlice(96, 33),
},
},
},
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{34, 35},
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: FillByteSlice(32, 42),
},
},
Signature: FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: FillByteSlice(32, 48),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: FillByteSlice(32, 52),
},
},
Signature: FillByteSlice(96, 53),
},
},
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{54, 55},
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: FillByteSlice(32, 58),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: FillByteSlice(32, 62),
},
},
Signature: FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: FillByteSlice(32, 68),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: FillByteSlice(32, 72),
},
},
Signature: FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: FillByteSlice(32, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: FillByteSlice(32, 77),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: FillByteSlice(32, 81),
},
},
Signature: FillByteSlice(96, 82),
},
{
AggregationBits: FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: FillByteSlice(32, 90),
},
},
Signature: FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 94),
WithdrawalCredentials: FillByteSlice(32, 95),
Amount: 96,
Signature: FillByteSlice(96, 97),
},
},
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 100),
WithdrawalCredentials: FillByteSlice(32, 101),
Amount: 102,
Signature: FillByteSlice(96, 103),
},
},
},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 104,
ValidatorIndex: 105,
},
Signature: FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: FillByteSlice(96, 109),
},
},
},
}
}
func GenerateJsonPhase0BeaconBlock() *apimiddleware.BeaconBlockJson {
return &apimiddleware.BeaconBlockJson{
Slot: "1",
ProposerIndex: "2",
ParentRoot: FillEncodedByteSlice(32, 3),
StateRoot: FillEncodedByteSlice(32, 4),
Body: &apimiddleware.BeaconBlockBodyJson{
RandaoReveal: FillEncodedByteSlice(96, 5),
Eth1Data: &apimiddleware.Eth1DataJson{
DepositRoot: FillEncodedByteSlice(32, 6),
DepositCount: "7",
BlockHash: FillEncodedByteSlice(32, 8),
},
Graffiti: FillEncodedByteSlice(32, 9),
ProposerSlashings: []*apimiddleware.ProposerSlashingJson{
{
Header_1: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "10",
ProposerIndex: "11",
ParentRoot: FillEncodedByteSlice(32, 12),
StateRoot: FillEncodedByteSlice(32, 13),
BodyRoot: FillEncodedByteSlice(32, 14),
},
Signature: FillEncodedByteSlice(96, 15),
},
Header_2: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "16",
ProposerIndex: "17",
ParentRoot: FillEncodedByteSlice(32, 18),
StateRoot: FillEncodedByteSlice(32, 19),
BodyRoot: FillEncodedByteSlice(32, 20),
},
Signature: FillEncodedByteSlice(96, 21),
},
},
{
Header_1: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "22",
ProposerIndex: "23",
ParentRoot: FillEncodedByteSlice(32, 24),
StateRoot: FillEncodedByteSlice(32, 25),
BodyRoot: FillEncodedByteSlice(32, 26),
},
Signature: FillEncodedByteSlice(96, 27),
},
Header_2: &apimiddleware.SignedBeaconBlockHeaderJson{
Header: &apimiddleware.BeaconBlockHeaderJson{
Slot: "28",
ProposerIndex: "29",
ParentRoot: FillEncodedByteSlice(32, 30),
StateRoot: FillEncodedByteSlice(32, 31),
BodyRoot: FillEncodedByteSlice(32, 32),
},
Signature: FillEncodedByteSlice(96, 33),
},
},
},
AttesterSlashings: []*apimiddleware.AttesterSlashingJson{
{
Attestation_1: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"34", "35"},
Data: &apimiddleware.AttestationDataJson{
Slot: "36",
CommitteeIndex: "37",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "39",
Root: FillEncodedByteSlice(32, 40),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "41",
Root: FillEncodedByteSlice(32, 42),
},
},
Signature: FillEncodedByteSlice(96, 43),
},
Attestation_2: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"44", "45"},
Data: &apimiddleware.AttestationDataJson{
Slot: "46",
CommitteeIndex: "47",
BeaconBlockRoot: FillEncodedByteSlice(32, 48),
Source: &apimiddleware.CheckpointJson{
Epoch: "49",
Root: FillEncodedByteSlice(32, 50),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "51",
Root: FillEncodedByteSlice(32, 52),
},
},
Signature: FillEncodedByteSlice(96, 53),
},
},
{
Attestation_1: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"54", "55"},
Data: &apimiddleware.AttestationDataJson{
Slot: "56",
CommitteeIndex: "57",
BeaconBlockRoot: FillEncodedByteSlice(32, 58),
Source: &apimiddleware.CheckpointJson{
Epoch: "59",
Root: FillEncodedByteSlice(32, 60),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "61",
Root: FillEncodedByteSlice(32, 62),
},
},
Signature: FillEncodedByteSlice(96, 63),
},
Attestation_2: &apimiddleware.IndexedAttestationJson{
AttestingIndices: []string{"64", "65"},
Data: &apimiddleware.AttestationDataJson{
Slot: "66",
CommitteeIndex: "67",
BeaconBlockRoot: FillEncodedByteSlice(32, 68),
Source: &apimiddleware.CheckpointJson{
Epoch: "69",
Root: FillEncodedByteSlice(32, 70),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "71",
Root: FillEncodedByteSlice(32, 72),
},
},
Signature: FillEncodedByteSlice(96, 73),
},
},
},
Attestations: []*apimiddleware.AttestationJson{
{
AggregationBits: FillEncodedByteSlice(32, 74),
Data: &apimiddleware.AttestationDataJson{
Slot: "75",
CommitteeIndex: "76",
BeaconBlockRoot: FillEncodedByteSlice(32, 77),
Source: &apimiddleware.CheckpointJson{
Epoch: "78",
Root: FillEncodedByteSlice(32, 79),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "80",
Root: FillEncodedByteSlice(32, 81),
},
},
Signature: FillEncodedByteSlice(96, 82),
},
{
AggregationBits: FillEncodedByteSlice(4, 83),
Data: &apimiddleware.AttestationDataJson{
Slot: "84",
CommitteeIndex: "85",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &apimiddleware.CheckpointJson{
Epoch: "87",
Root: FillEncodedByteSlice(32, 88),
},
Target: &apimiddleware.CheckpointJson{
Epoch: "89",
Root: FillEncodedByteSlice(32, 90),
},
},
Signature: FillEncodedByteSlice(96, 91),
},
},
Deposits: []*apimiddleware.DepositJson{
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 92)),
Data: &apimiddleware.Deposit_DataJson{
PublicKey: FillEncodedByteSlice(48, 94),
WithdrawalCredentials: FillEncodedByteSlice(32, 95),
Amount: "96",
Signature: FillEncodedByteSlice(96, 97),
},
},
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 98)),
Data: &apimiddleware.Deposit_DataJson{
PublicKey: FillEncodedByteSlice(48, 100),
WithdrawalCredentials: FillEncodedByteSlice(32, 101),
Amount: "102",
Signature: FillEncodedByteSlice(96, 103),
},
},
},
VoluntaryExits: []*apimiddleware.SignedVoluntaryExitJson{
{
Exit: &apimiddleware.VoluntaryExitJson{
Epoch: "104",
ValidatorIndex: "105",
},
Signature: FillEncodedByteSlice(96, 106),
},
{
Exit: &apimiddleware.VoluntaryExitJson{
Epoch: "107",
ValidatorIndex: "108",
},
Signature: FillEncodedByteSlice(96, 109),
},
},
},
}
}

View File

@@ -1,5 +1,9 @@
package test_helpers
import (
"github.com/ethereum/go-ethereum/common/hexutil"
)
func FillByteSlice(sliceLength int, value byte) []byte {
bytes := make([]byte, sliceLength)
@@ -19,3 +23,15 @@ func FillByteArraySlice(sliceLength int, value []byte) [][]byte {
return bytes
}
func FillEncodedByteSlice(sliceLength int, value byte) string {
return hexutil.Encode(FillByteSlice(sliceLength, value))
}
func FillEncodedByteArraySlice(sliceLength int, value string) []string {
encodedBytes := make([]string, sliceLength)
for index := range encodedBytes {
encodedBytes[index] = value
}
return encodedBytes
}

View File

@@ -249,7 +249,7 @@ type VoluntaryExit struct {
// BeaconBlockAltairBlockV2 a sub property of BlockAltairSignRequest.
type BeaconBlockAltairBlockV2 struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Block *BeaconBlockAltair `json:"block"`
}
@@ -277,7 +277,7 @@ type BeaconBlockBodyAltair struct {
// BeaconBlockBellatrixBlockV2 a field of BlockBellatrixSignRequest.
type BeaconBlockBellatrixBlockV2 struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
BlockHeader *BeaconBlockHeader `json:"block_header"`
}
@@ -289,7 +289,7 @@ type SyncAggregate struct {
// BeaconBlockBlockV2 a sub property of BlockV2SignRequest.
type BeaconBlockBlockV2 struct {
Version string `json:"version"`
Version string `json:"version" enum:"true"`
Block *BeaconBlock `json:"beacon_block"`
}