mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
Deneb - web3signer (#12767)
* wip * adding deneb block * adding in support for blobs and fixing unit tests for deneb * fixing linting * gaz * adding support for new web3signer version * fixing tag name * addressing feedback * fixing tests * adding unit test for review * updating test name * updating unit tests and length logic * adding in lengthfor root * adjusting max blob length * fixing mock * fixing another mock * gaz * adding network configs * removing duplicate * changing based on nishant's feedback * Update validator/keymanager/remote-web3signer/v1/requests.go Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com> * Update validator/keymanager/remote-web3signer/metrics.go Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com> * sammy's suggestions * removing temp file --------- Co-authored-by: Nishant Das <nishdas93@gmail.com> Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com> Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -6,15 +6,22 @@ searching `Consensys' Web3Signer API specification`
|
||||
|
||||
issue: https://github.com/prysmaticlabs/prysm/issues/9994
|
||||
|
||||
## Support
|
||||
|
||||
WIP
|
||||
API interface: https://github.com/ethereum/remote-signing-api
|
||||
|
||||
## Features
|
||||
|
||||
### CLI
|
||||
|
||||
WIP
|
||||
detailed info found on https://docs.prylabs.network/docs/wallet/web3signer
|
||||
|
||||
Flags used on validator client
|
||||
- `--validators-external-signer-url=http://localhost:9000`
|
||||
|
||||
with hex keys
|
||||
- `--validators-external-signer-public-keys=0xa99a...e44c,0xb89b...4a0b`
|
||||
|
||||
with url
|
||||
- `--validators-external-signer-public-keys=https://web3signer.com/api/v1/eth2/publicKeys`
|
||||
|
||||
### API
|
||||
|
||||
|
||||
@@ -113,95 +113,27 @@ func getSignRequestJson(ctx context.Context, validator *validator.Validate, requ
|
||||
}
|
||||
switch request.Object.(type) {
|
||||
case *validatorpb.SignRequest_Block:
|
||||
bockSignRequest, err := web3signerv1.GetBlockSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, bockSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockSignRequestsTotal.Inc()
|
||||
return json.Marshal(bockSignRequest)
|
||||
return handleBlock(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_AttestationData:
|
||||
attestationSignRequest, err := web3signerv1.GetAttestationSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, attestationSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attestationSignRequestsTotal.Inc()
|
||||
return json.Marshal(attestationSignRequest)
|
||||
return handleAttestationData(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_AggregateAttestationAndProof:
|
||||
aggregateAndProofSignRequest, err := web3signerv1.GetAggregateAndProofSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, aggregateAndProofSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregateAndProofSignRequestsTotal.Inc()
|
||||
return json.Marshal(aggregateAndProofSignRequest)
|
||||
return handleAggregateAttestationAndProof(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_Slot:
|
||||
aggregationSlotSignRequest, err := web3signerv1.GetAggregationSlotSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, aggregationSlotSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregationSlotSignRequestsTotal.Inc()
|
||||
return json.Marshal(aggregationSlotSignRequest)
|
||||
return handleAggregationSlot(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_BlockAltair:
|
||||
blockv2AltairSignRequest, err := web3signerv1.GetBlockAltairSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blockv2AltairSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockAltairSignRequestsTotal.Inc()
|
||||
return json.Marshal(blockv2AltairSignRequest)
|
||||
return handleBlockAltair(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_BlockBellatrix:
|
||||
blockv2BellatrixSignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blockv2BellatrixSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockBellatrixSignRequestsTotal.Inc()
|
||||
return json.Marshal(blockv2BellatrixSignRequest)
|
||||
return handleBlockBellatrix(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_BlindedBlockBellatrix:
|
||||
blindedBlockv2SignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blindedBlockv2SignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blindedBlockBellatrixSignRequestsTotal.Inc()
|
||||
return json.Marshal(blindedBlockv2SignRequest)
|
||||
return handleBlindedBlockBellatrix(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_BlockCapella:
|
||||
blockv2CapellaSignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blockv2CapellaSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockCapellaSignRequestsTotal.Inc()
|
||||
return json.Marshal(blockv2CapellaSignRequest)
|
||||
return handleBlockCapella(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_BlindedBlockCapella:
|
||||
blindedBlockv2CapellaSignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blindedBlockv2CapellaSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blindedBlockCapellaSignRequestsTotal.Inc()
|
||||
return json.Marshal(blindedBlockv2CapellaSignRequest)
|
||||
return handleBlindedBlockCapella(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_BlockDeneb:
|
||||
return handleBlockDeneb(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_BlindedBlockDeneb:
|
||||
return handleBlindedBlockDeneb(ctx, validator, request, genesisValidatorsRoot)
|
||||
// We do not support "DEPOSIT" type.
|
||||
/*
|
||||
case *validatorpb.:
|
||||
@@ -209,70 +141,255 @@ func getSignRequestJson(ctx context.Context, validator *validator.Validate, requ
|
||||
*/
|
||||
|
||||
case *validatorpb.SignRequest_Epoch:
|
||||
randaoRevealSignRequest, err := web3signerv1.GetRandaoRevealSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, randaoRevealSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
randaoRevealSignRequestsTotal.Inc()
|
||||
return json.Marshal(randaoRevealSignRequest)
|
||||
// tech debt that prysm uses signing type epoch
|
||||
return handleRandaoReveal(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_Exit:
|
||||
voluntaryExitRequest, err := web3signerv1.GetVoluntaryExitSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, voluntaryExitRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
voluntaryExitSignRequestsTotal.Inc()
|
||||
return json.Marshal(voluntaryExitRequest)
|
||||
return handleVoluntaryExit(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_SyncMessageBlockRoot:
|
||||
syncCommitteeMessageRequest, err := web3signerv1.GetSyncCommitteeMessageSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, syncCommitteeMessageRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncCommitteeMessageSignRequestsTotal.Inc()
|
||||
return json.Marshal(syncCommitteeMessageRequest)
|
||||
return handleSyncMessageBlockRoot(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_SyncAggregatorSelectionData:
|
||||
syncCommitteeSelectionProofRequest, err := web3signerv1.GetSyncCommitteeSelectionProofSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, syncCommitteeSelectionProofRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncCommitteeSelectionProofSignRequestsTotal.Inc()
|
||||
return json.Marshal(syncCommitteeSelectionProofRequest)
|
||||
return handleSyncAggregatorSelectionData(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_ContributionAndProof:
|
||||
contributionAndProofRequest, err := web3signerv1.GetSyncCommitteeContributionAndProofSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, contributionAndProofRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncCommitteeContributionAndProofSignRequestsTotal.Inc()
|
||||
return json.Marshal(contributionAndProofRequest)
|
||||
return handleContributionAndProof(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_Registration:
|
||||
validatorRegistrationRequest, err := web3signerv1.GetValidatorRegistrationSignRequest(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, validatorRegistrationRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validatorRegistrationSignRequestsTotal.Inc()
|
||||
return json.Marshal(validatorRegistrationRequest)
|
||||
return handleRegistration(ctx, validator, request)
|
||||
case *validatorpb.SignRequest_Blob:
|
||||
return handleBlob(ctx, validator, request, genesisValidatorsRoot)
|
||||
case *validatorpb.SignRequest_BlindedBlob:
|
||||
return handleBlindedBlob(ctx, validator, request, genesisValidatorsRoot)
|
||||
default:
|
||||
return nil, fmt.Errorf("web3signer sign request type %T not supported", request.Object)
|
||||
}
|
||||
}
|
||||
|
||||
func handleBlock(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
bockSignRequest, err := web3signerv1.GetBlockSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, bockSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockSignRequestsTotal.Inc()
|
||||
return json.Marshal(bockSignRequest)
|
||||
}
|
||||
|
||||
func handleAttestationData(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
attestationSignRequest, err := web3signerv1.GetAttestationSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, attestationSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attestationSignRequestsTotal.Inc()
|
||||
return json.Marshal(attestationSignRequest)
|
||||
}
|
||||
|
||||
func handleAggregateAttestationAndProof(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
aggregateAndProofSignRequest, err := web3signerv1.GetAggregateAndProofSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, aggregateAndProofSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregateAndProofSignRequestsTotal.Inc()
|
||||
return json.Marshal(aggregateAndProofSignRequest)
|
||||
}
|
||||
|
||||
func handleAggregationSlot(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
aggregationSlotSignRequest, err := web3signerv1.GetAggregationSlotSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, aggregationSlotSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregationSlotSignRequestsTotal.Inc()
|
||||
return json.Marshal(aggregationSlotSignRequest)
|
||||
}
|
||||
|
||||
func handleBlockAltair(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blockv2AltairSignRequest, err := web3signerv1.GetBlockAltairSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blockv2AltairSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockAltairSignRequestsTotal.Inc()
|
||||
return json.Marshal(blockv2AltairSignRequest)
|
||||
}
|
||||
|
||||
func handleBlockBellatrix(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blockv2BellatrixSignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blockv2BellatrixSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockBellatrixSignRequestsTotal.Inc()
|
||||
return json.Marshal(blockv2BellatrixSignRequest)
|
||||
}
|
||||
|
||||
func handleBlindedBlockBellatrix(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blindedBlockv2SignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blindedBlockv2SignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blindedBlockBellatrixSignRequestsTotal.Inc()
|
||||
return json.Marshal(blindedBlockv2SignRequest)
|
||||
}
|
||||
|
||||
func handleBlockCapella(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blockv2CapellaSignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blockv2CapellaSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockCapellaSignRequestsTotal.Inc()
|
||||
return json.Marshal(blockv2CapellaSignRequest)
|
||||
}
|
||||
|
||||
func handleBlindedBlockCapella(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blindedBlockv2CapellaSignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blindedBlockv2CapellaSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blindedBlockCapellaSignRequestsTotal.Inc()
|
||||
return json.Marshal(blindedBlockv2CapellaSignRequest)
|
||||
}
|
||||
|
||||
func handleBlockDeneb(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blockv2DenebSignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blockv2DenebSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockDenebSignRequestsTotal.Inc()
|
||||
return json.Marshal(blockv2DenebSignRequest)
|
||||
}
|
||||
|
||||
func handleBlindedBlockDeneb(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blindedBlockv2DenebSignRequest, err := web3signerv1.GetBlockV2BlindedSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blindedBlockv2DenebSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blindedBlockDenebSignRequestsTotal.Inc()
|
||||
return json.Marshal(blindedBlockv2DenebSignRequest)
|
||||
}
|
||||
|
||||
func handleRandaoReveal(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
randaoRevealSignRequest, err := web3signerv1.GetRandaoRevealSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, randaoRevealSignRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
randaoRevealSignRequestsTotal.Inc()
|
||||
return json.Marshal(randaoRevealSignRequest)
|
||||
}
|
||||
|
||||
func handleVoluntaryExit(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
voluntaryExitRequest, err := web3signerv1.GetVoluntaryExitSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, voluntaryExitRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
voluntaryExitSignRequestsTotal.Inc()
|
||||
return json.Marshal(voluntaryExitRequest)
|
||||
}
|
||||
|
||||
func handleSyncMessageBlockRoot(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
syncCommitteeMessageRequest, err := web3signerv1.GetSyncCommitteeMessageSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, syncCommitteeMessageRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncCommitteeMessageSignRequestsTotal.Inc()
|
||||
return json.Marshal(syncCommitteeMessageRequest)
|
||||
}
|
||||
|
||||
func handleSyncAggregatorSelectionData(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
syncCommitteeSelectionProofRequest, err := web3signerv1.GetSyncCommitteeSelectionProofSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, syncCommitteeSelectionProofRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncCommitteeSelectionProofSignRequestsTotal.Inc()
|
||||
return json.Marshal(syncCommitteeSelectionProofRequest)
|
||||
}
|
||||
|
||||
func handleContributionAndProof(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
contributionAndProofRequest, err := web3signerv1.GetSyncCommitteeContributionAndProofSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, contributionAndProofRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncCommitteeContributionAndProofSignRequestsTotal.Inc()
|
||||
return json.Marshal(contributionAndProofRequest)
|
||||
}
|
||||
|
||||
func handleRegistration(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest) ([]byte, error) {
|
||||
validatorRegistrationRequest, err := web3signerv1.GetValidatorRegistrationSignRequest(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, validatorRegistrationRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validatorRegistrationSignRequestsTotal.Inc()
|
||||
return json.Marshal(validatorRegistrationRequest)
|
||||
}
|
||||
|
||||
func handleBlob(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blobRequest, err := web3signerv1.GetBlobSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blobRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blobSignRequestsTotal.Inc()
|
||||
return json.Marshal(blobRequest)
|
||||
}
|
||||
|
||||
func handleBlindedBlob(ctx context.Context, validator *validator.Validate, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) ([]byte, error) {
|
||||
blindedBlobRequest, err := web3signerv1.GetBlobSignRequest(request, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validator.StructCtx(ctx, blindedBlobRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blindedBlobSignRequestsTotal.Inc()
|
||||
return json.Marshal(blindedBlobRequest)
|
||||
}
|
||||
|
||||
// SubscribeAccountChanges returns the event subscription for changes to public keys.
|
||||
func (km *Keymanager) SubscribeAccountChanges(pubKeysChan chan [][fieldparams.BLSPubkeyLength]byte) event.Subscription {
|
||||
return km.accountsChangedFeed.Subscribe(pubKeysChan)
|
||||
|
||||
@@ -171,12 +171,20 @@ func TestKeymanager_Sign(t *testing.T) {
|
||||
want: desiredSig,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "BLOB_SIDECAR",
|
||||
args: args{
|
||||
request: mock.GetMockSignRequest("BLOB_SIDECAR"),
|
||||
},
|
||||
want: desiredSig,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := km.Sign(ctx, tt.args.request)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetVoluntaryExitSignRequest() error = %v, wantErr %v", err, tt.wantErr)
|
||||
t.Errorf("name:%s error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
require.DeepEqual(t, got, tt.want)
|
||||
|
||||
@@ -50,6 +50,14 @@ var (
|
||||
Name: "remote_web3signer_blinded_block_capella_sign_requests_total",
|
||||
Help: "Total number of block capella sign requests",
|
||||
})
|
||||
blockDenebSignRequestsTotal = promauto.NewCounter(prometheus.CounterOpts{
|
||||
Name: "remote_web3signer_block_deneb_sign_requests_total",
|
||||
Help: "Total number of block deneb sign requests",
|
||||
})
|
||||
blindedBlockDenebSignRequestsTotal = promauto.NewCounter(prometheus.CounterOpts{
|
||||
Name: "remote_web3signer_blinded_block_deneb_sign_requests_total",
|
||||
Help: "Total number of blinded block deneb sign requests",
|
||||
})
|
||||
randaoRevealSignRequestsTotal = promauto.NewCounter(prometheus.CounterOpts{
|
||||
Name: "remote_web3signer_randao_reveal_sign_requests_total",
|
||||
Help: "Total number of randao reveal sign requests",
|
||||
@@ -74,4 +82,12 @@ var (
|
||||
Name: "remote_web3signer_validator_registration_sign_requests_total",
|
||||
Help: "Total number of validator registration sign requests",
|
||||
})
|
||||
blobSignRequestsTotal = promauto.NewCounter(prometheus.CounterOpts{
|
||||
Name: "remote_web3signer_blob_sign_requests_total",
|
||||
Help: "Total number of blob sign requests",
|
||||
})
|
||||
blindedBlobSignRequestsTotal = promauto.NewCounter(prometheus.CounterOpts{
|
||||
Name: "remote_web3signer_blinded_blob_sign_requests_total",
|
||||
Help: "Total number of blinded blob sign requests",
|
||||
})
|
||||
)
|
||||
|
||||
@@ -10,9 +10,11 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/validator/keymanager/remote-web3signer/v1",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/ssz:go_default_library",
|
||||
"//network/forks:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
|
||||
@@ -8,11 +8,13 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//encoding/ssz:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//validator/keymanager/remote-web3signer/v1:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -6,10 +6,12 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/ssz"
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
||||
v1 "github.com/prysmaticlabs/prysm/v4/validator/keymanager/remote-web3signer/v1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -363,6 +365,24 @@ func GetMockSignRequest(t string) *validatorpb.SignRequest {
|
||||
BlindedBlockCapella: util.HydrateBlindedBeaconBlockCapella(ð.BlindedBeaconBlockCapella{}),
|
||||
},
|
||||
}
|
||||
case "BLOCK_V2_DENEB":
|
||||
return &validatorpb.SignRequest{
|
||||
PublicKey: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
SigningRoot: make([]byte, fieldparams.RootLength),
|
||||
SignatureDomain: make([]byte, 4),
|
||||
Object: &validatorpb.SignRequest_BlockDeneb{
|
||||
BlockDeneb: util.HydrateBeaconBlockDeneb(ð.BeaconBlockDeneb{}),
|
||||
},
|
||||
}
|
||||
case "BLOCK_V2_BLINDED_DENEB":
|
||||
return &validatorpb.SignRequest{
|
||||
PublicKey: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
SigningRoot: make([]byte, fieldparams.RootLength),
|
||||
SignatureDomain: make([]byte, 4),
|
||||
Object: &validatorpb.SignRequest_BlindedBlockDeneb{
|
||||
BlindedBlockDeneb: util.HydrateBlindedBeaconBlockDeneb(ð.BlindedBeaconBlockDeneb{}),
|
||||
},
|
||||
}
|
||||
case "RANDAO_REVEAL":
|
||||
return &validatorpb.SignRequest{
|
||||
PublicKey: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
@@ -444,6 +464,49 @@ func GetMockSignRequest(t string) *validatorpb.SignRequest {
|
||||
},
|
||||
SigningSlot: 0,
|
||||
}
|
||||
case "BLOB_SIDECAR":
|
||||
return &validatorpb.SignRequest{
|
||||
PublicKey: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
SigningRoot: make([]byte, fieldparams.RootLength),
|
||||
SignatureDomain: make([]byte, 4),
|
||||
Object: &validatorpb.SignRequest_Blob{
|
||||
Blob: ð.BlobSidecar{
|
||||
BlockRoot: make([]byte, fieldparams.RootLength),
|
||||
Index: uint64(0),
|
||||
Slot: 0,
|
||||
BlockParentRoot: make([]byte, fieldparams.RootLength),
|
||||
ProposerIndex: 0,
|
||||
Blob: make([]byte, fieldparams.BlobLength),
|
||||
KzgCommitment: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
KzgProof: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
},
|
||||
},
|
||||
SigningSlot: 0,
|
||||
}
|
||||
case "BLINDED_BLOB_SIDECAR":
|
||||
blobRoot, err := ssz.ByteSliceRoot(make([]byte, fieldparams.BlobLength), fieldparams.BlobLength)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return nil
|
||||
}
|
||||
return &validatorpb.SignRequest{
|
||||
PublicKey: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
SigningRoot: make([]byte, fieldparams.RootLength),
|
||||
SignatureDomain: make([]byte, 4),
|
||||
Object: &validatorpb.SignRequest_BlindedBlob{
|
||||
BlindedBlob: ð.BlindedBlobSidecar{
|
||||
BlockRoot: make([]byte, fieldparams.RootLength),
|
||||
Index: uint64(0),
|
||||
Slot: 0,
|
||||
BlockParentRoot: make([]byte, fieldparams.RootLength),
|
||||
ProposerIndex: 0,
|
||||
BlobRoot: blobRoot[:],
|
||||
KzgCommitment: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
KzgProof: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
},
|
||||
},
|
||||
SigningSlot: 0,
|
||||
}
|
||||
default:
|
||||
fmt.Printf("Web3signer sign request type: %v not found", t)
|
||||
return nil
|
||||
@@ -606,6 +669,30 @@ func MockValidatorRegistrationSignRequest() *v1.ValidatorRegistrationSignRequest
|
||||
}
|
||||
}
|
||||
|
||||
// MockBlobSidecarSignRequest is a mock implementation of the BlobSidecarSignRequest.
|
||||
func MockBlobSidecarSignRequest() *v1.BlobSidecarSignRequest {
|
||||
blobRoot, err := ssz.ByteSliceRoot(make([]byte, fieldparams.BlobLength), fieldparams.BlobLength)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return nil
|
||||
}
|
||||
return &v1.BlobSidecarSignRequest{
|
||||
Type: "BLOB_SIDECAR",
|
||||
ForkInfo: MockForkInfo(),
|
||||
SigningRoot: make([]byte, fieldparams.RootLength),
|
||||
BlobSidecar: &v1.BlobSidecar{
|
||||
BlockRoot: make([]byte, fieldparams.RootLength),
|
||||
Index: fmt.Sprint(0),
|
||||
Slot: fmt.Sprint(0),
|
||||
BlockParentRoot: make([]byte, fieldparams.RootLength),
|
||||
ProposerIndex: fmt.Sprint(0),
|
||||
BlobRoot: blobRoot[:],
|
||||
KzgCommitment: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
KzgProof: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -4,8 +4,10 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/ssz"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||
)
|
||||
|
||||
@@ -271,8 +273,8 @@ func GetSyncCommitteeContributionAndProofSignRequest(request *validatorpb.SignRe
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetBlockV2BlindedSignRequest maps the request for signing types
|
||||
// Supports Bellatrix and Capella
|
||||
// GetBlockV2BlindedSignRequest maps the request for signing types (GetBlockV2 id defined by the remote signer interface and not the beacon APIs)
|
||||
// Supports Bellatrix, Capella, Deneb
|
||||
func GetBlockV2BlindedSignRequest(request *validatorpb.SignRequest, genesisValidatorsRoot []byte) (*BlockV2BlindedSignRequest, error) {
|
||||
if request == nil {
|
||||
return nil, errors.New("nil sign request provided")
|
||||
@@ -337,6 +339,34 @@ func GetBlockV2BlindedSignRequest(request *validatorpb.SignRequest, genesisValid
|
||||
return nil, err
|
||||
}
|
||||
b = beaconBlock
|
||||
case *validatorpb.SignRequest_BlockDeneb:
|
||||
version = "DENEB"
|
||||
blockDeneb, ok := request.Object.(*validatorpb.SignRequest_BlockDeneb)
|
||||
if !ok {
|
||||
return nil, errors.New("failed to cast request object to deneb block")
|
||||
}
|
||||
if blockDeneb == nil {
|
||||
return nil, errors.New("invalid sign request: deneb block is nil")
|
||||
}
|
||||
beaconBlock, err := blocks.NewBeaconBlock(blockDeneb.BlockDeneb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = beaconBlock
|
||||
case *validatorpb.SignRequest_BlindedBlockDeneb:
|
||||
version = "DENEB"
|
||||
blindedBlockDeneb, ok := request.Object.(*validatorpb.SignRequest_BlindedBlockDeneb)
|
||||
if !ok {
|
||||
return nil, errors.New("failed to cast request object to blinded deneb block")
|
||||
}
|
||||
if blindedBlockDeneb == nil {
|
||||
return nil, errors.New("invalid sign request: blinded deneb block is nil")
|
||||
}
|
||||
beaconBlock, err := blocks.NewBeaconBlock(blindedBlockDeneb.BlindedBlockDeneb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = beaconBlock
|
||||
default:
|
||||
return nil, errors.New("invalid sign request - invalid object type")
|
||||
}
|
||||
@@ -386,3 +416,66 @@ func GetValidatorRegistrationSignRequest(request *validatorpb.SignRequest) (*Val
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetBlobSignRequest maps the request for signing type BLOB_SIDECAR
|
||||
func GetBlobSignRequest(request *validatorpb.SignRequest, genesisValidatorsRoot []byte) (*BlobSidecarSignRequest, error) {
|
||||
if request == nil {
|
||||
return nil, errors.New("nil sign request provided")
|
||||
}
|
||||
fork, err := MapForkInfo(request.SigningSlot, genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var blobSidecar *BlobSidecar
|
||||
switch request.Object.(type) {
|
||||
case *validatorpb.SignRequest_Blob:
|
||||
blob, ok := request.Object.(*validatorpb.SignRequest_Blob)
|
||||
if !ok {
|
||||
return nil, errors.New("failed to cast request object to blob sidecar")
|
||||
}
|
||||
if blob == nil || blob.Blob == nil {
|
||||
return nil, errors.New("invalid sign request: blob sidecar is nil")
|
||||
}
|
||||
blobRoot, err := ssz.ByteSliceRoot(blob.Blob.Blob, fieldparams.BlobLength)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to get blob root from ssz roots")
|
||||
}
|
||||
blobSidecar = &BlobSidecar{
|
||||
BlockRoot: blob.Blob.BlockRoot,
|
||||
Index: fmt.Sprint(blob.Blob.Index),
|
||||
Slot: fmt.Sprint(blob.Blob.Slot),
|
||||
BlockParentRoot: blob.Blob.BlockParentRoot,
|
||||
ProposerIndex: fmt.Sprint(blob.Blob.ProposerIndex),
|
||||
BlobRoot: blobRoot[:],
|
||||
KzgCommitment: blob.Blob.KzgCommitment,
|
||||
KzgProof: blob.Blob.KzgProof,
|
||||
}
|
||||
case *validatorpb.SignRequest_BlindedBlob:
|
||||
blindedBlob, ok := request.Object.(*validatorpb.SignRequest_BlindedBlob)
|
||||
if !ok {
|
||||
return nil, errors.New("failed to cast request object to blinded blob sidecar")
|
||||
}
|
||||
if blindedBlob == nil || blindedBlob.BlindedBlob == nil {
|
||||
return nil, errors.New("invalid sign request: blinded blob sidecar is nil")
|
||||
}
|
||||
blobSidecar = &BlobSidecar{
|
||||
BlockRoot: blindedBlob.BlindedBlob.BlockRoot,
|
||||
Index: fmt.Sprint(blindedBlob.BlindedBlob.Index),
|
||||
Slot: fmt.Sprint(blindedBlob.BlindedBlob.Slot),
|
||||
BlockParentRoot: blindedBlob.BlindedBlob.BlockParentRoot,
|
||||
ProposerIndex: fmt.Sprint(blindedBlob.BlindedBlob.ProposerIndex),
|
||||
BlobRoot: blindedBlob.BlindedBlob.BlobRoot,
|
||||
KzgCommitment: blindedBlob.BlindedBlob.KzgCommitment,
|
||||
KzgProof: blindedBlob.BlindedBlob.KzgProof,
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("invalid sign request: invalid object type")
|
||||
}
|
||||
|
||||
return &BlobSidecarSignRequest{
|
||||
Type: "BLOB_SIDECAR",
|
||||
ForkInfo: fork,
|
||||
SigningRoot: request.SigningRoot,
|
||||
BlobSidecar: blobSidecar,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -424,6 +424,32 @@ func TestGetBlockV2BlindedSignRequest(t *testing.T) {
|
||||
}(t), "CAPELLA"),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Happy Path Test non blinded Deneb",
|
||||
args: args{
|
||||
request: mock.GetMockSignRequest("BLOCK_V2_DENEB"),
|
||||
genesisValidatorsRoot: make([]byte, fieldparams.RootLength),
|
||||
},
|
||||
want: mock.MockBlockV2BlindedSignRequest(func(t *testing.T) []byte {
|
||||
bytevalue, err := hexutil.Decode("0xbce73ee2c617851846af2b3ea2287e3b686098e18ae508c7271aaa06ab1d06cd")
|
||||
require.NoError(t, err)
|
||||
return bytevalue
|
||||
}(t), "DENEB"),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Happy Path Test blinded Deneb",
|
||||
args: args{
|
||||
request: mock.GetMockSignRequest("BLOCK_V2_BLINDED_DENEB"),
|
||||
genesisValidatorsRoot: make([]byte, fieldparams.RootLength),
|
||||
},
|
||||
want: mock.MockBlockV2BlindedSignRequest(func(t *testing.T) []byte {
|
||||
bytevalue, err := hexutil.Decode("0xfeb1f7e4f704e72544f4f097b36cb3f3af83043765ad9ad3c3a6cd7fac605055")
|
||||
require.NoError(t, err)
|
||||
return bytevalue
|
||||
}(t), "DENEB"),
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -439,6 +465,47 @@ func TestGetBlockV2BlindedSignRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBlobSignRequest(t *testing.T) {
|
||||
type args struct {
|
||||
request *validatorpb.SignRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *v1.BlobSidecarSignRequest
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Happy Path Test",
|
||||
args: args{
|
||||
request: mock.GetMockSignRequest("BLOB_SIDECAR"),
|
||||
},
|
||||
want: mock.MockBlobSidecarSignRequest(),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Happy Path Test Blinded",
|
||||
args: args{
|
||||
request: mock.GetMockSignRequest("BLINDED_BLOB_SIDECAR"),
|
||||
},
|
||||
want: mock.MockBlobSidecarSignRequest(),
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := v1.GetBlobSignRequest(tt.args.request, make([]byte, fieldparams.RootLength))
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetBlobSignRequest() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("GetBlobSignRequest() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetValidatorRegistrationSignRequest(t *testing.T) {
|
||||
type args struct {
|
||||
request *validatorpb.SignRequest
|
||||
|
||||
@@ -105,6 +105,14 @@ type ValidatorRegistrationSignRequest struct {
|
||||
ValidatorRegistration *ValidatorRegistration `json:"validator_registration" validate:"required"`
|
||||
}
|
||||
|
||||
// BlobSidecarSignRequest a request object for web3signer sign api.
|
||||
type BlobSidecarSignRequest struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
ForkInfo *ForkInfo `json:"fork_info" validate:"required"`
|
||||
SigningRoot hexutil.Bytes `json:"signingRoot"`
|
||||
BlobSidecar *BlobSidecar `json:"blob_sidecar" validate:"required,dive"`
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// sub properties of Sign Requests /////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -337,6 +345,18 @@ type ValidatorRegistration struct {
|
||||
Pubkey hexutil.Bytes `json:"pubkey" validate:"required"` /* bls hexadecimal string */
|
||||
}
|
||||
|
||||
// BlobSidecar a sub property of BlobSidecarSignRequest
|
||||
type BlobSidecar struct {
|
||||
BlockRoot hexutil.Bytes `json:"block_root" validate:"required"` /* 32 hexadecimal string */
|
||||
Index string `json:"index" validate:"required"` /* uint64 */
|
||||
Slot string `json:"slot" validate:"required"` /* uint64 */
|
||||
BlockParentRoot hexutil.Bytes `json:"block_parent_root" validate:"required"` /* 32 hexadecimal string */
|
||||
ProposerIndex string `json:"proposer_index" validate:"required"` /* uint64 */
|
||||
BlobRoot hexutil.Bytes `json:"blob_root" validate:"required"` /* 32 hexadecimal string */
|
||||
KzgCommitment hexutil.Bytes `json:"kzg_commitment" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48"
|
||||
KzgProof hexutil.Bytes `json:"kzg_proof" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48"
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user