Add REST implementation for SubmitSyncMessage (#11827)

* Add REST implementation for `SubmitSyncMessage`

* Use context

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
Manu NALEPA 2023-01-09 18:05:18 +01:00 committed by GitHub
parent bad7c6a94e
commit 375a76d6c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 128 additions and 6 deletions

View File

@ -20,6 +20,7 @@ go_library(
"registration.go",
"state_validators.go",
"status.go",
"sync_committee.go",
],
importpath = "github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api",
visibility = ["//validator:__subpackages__"],
@ -70,6 +71,7 @@ go_test(
"registration_test.go",
"state_validators_test.go",
"status_test.go",
"sync_committee_test.go",
"wait_for_chain_start_test.go",
],
embed = [":go_default_library"],

View File

@ -184,12 +184,7 @@ func (c *beaconApiValidatorClient) SubmitSignedContributionAndProof(ctx context.
}
func (c *beaconApiValidatorClient) SubmitSyncMessage(ctx context.Context, in *ethpb.SyncCommitteeMessage) (*empty.Empty, error) {
if c.fallbackClient != nil {
return c.fallbackClient.SubmitSyncMessage(ctx, in)
}
// TODO: Implement me
panic("beaconApiValidatorClient.SubmitSyncMessage is not implemented. To use a fallback client, create this validator with NewBeaconApiValidatorClientWithFallback instead.")
return new(empty.Empty), c.submitSyncMessage(ctx, in)
}
func (c *beaconApiValidatorClient) SubmitValidatorRegistrations(ctx context.Context, in *ethpb.SignedValidatorRegistrationsV1) (*empty.Empty, error) {

View File

@ -0,0 +1,35 @@
package beacon_api
import (
"bytes"
"context"
"encoding/json"
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
)
func (c *beaconApiValidatorClient) submitSyncMessage(ctx context.Context, syncMessage *ethpb.SyncCommitteeMessage) error {
const endpoint = "/eth/v1/beacon/pool/sync_committees"
jsonSyncCommitteeMessage := &apimiddleware.SyncCommitteeMessageJson{
Slot: strconv.FormatUint(uint64(syncMessage.Slot), 10),
BeaconBlockRoot: hexutil.Encode(syncMessage.BlockRoot),
ValidatorIndex: strconv.FormatUint(uint64(syncMessage.ValidatorIndex), 10),
Signature: hexutil.Encode(syncMessage.Signature),
}
marshalledJsonSyncCommitteeMessage, err := json.Marshal(jsonSyncCommitteeMessage)
if err != nil {
return errors.Wrap(err, "failed to marshal sync committee message")
}
if _, err := c.jsonRestHandler.PostRestJson(ctx, endpoint, nil, bytes.NewBuffer(marshalledJsonSyncCommitteeMessage), nil); err != nil {
return errors.Wrapf(err, "failed to send POST data to `%s` REST endpoint", endpoint)
}
return nil
}

View File

@ -0,0 +1,90 @@
package beacon_api
import (
"bytes"
"context"
"encoding/json"
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
"github.com/golang/protobuf/ptypes/empty"
"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"
"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 TestSubmitSyncMessage_Valid(t *testing.T) {
const beaconBlockRoot = "0x719d4f66a5f25c35d93718821aacb342194391034b11cf0a5822cc249178a274"
const signature = "0xb459ef852bd4e0cb96e6723d67cacc8215406dd9ba663f8874a083167ebf428b28b746431bdbc1820a25289377b2610881e52b3a05c3548c5e99c08c8a36342573be5962d7510c03dcba8ddfb8ae419e59d222ddcf31cc512e704ef2cc3cf8"
decodedBeaconBlockRoot, err := hexutil.Decode(beaconBlockRoot)
require.NoError(t, err)
decodedSignature, err := hexutil.Decode(signature)
require.NoError(t, err)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
jsonSyncCommitteeMessage := &apimiddleware.SyncCommitteeMessageJson{
Slot: "42",
BeaconBlockRoot: beaconBlockRoot,
ValidatorIndex: "12345",
Signature: signature,
}
marshalledJsonRegistrations, err := json.Marshal(jsonSyncCommitteeMessage)
require.NoError(t, err)
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().PostRestJson(
context.Background(),
"/eth/v1/beacon/pool/sync_committees",
nil,
bytes.NewBuffer(marshalledJsonRegistrations),
nil,
).Return(
nil,
nil,
).Times(1)
protoSyncCommiteeMessage := ethpb.SyncCommitteeMessage{
Slot: types.Slot(42),
BlockRoot: decodedBeaconBlockRoot,
ValidatorIndex: types.ValidatorIndex(12345),
Signature: decodedSignature,
}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
res, err := validatorClient.SubmitSyncMessage(context.Background(), &protoSyncCommiteeMessage)
assert.DeepEqual(t, new(empty.Empty), res)
require.NoError(t, err)
}
func TestSubmitSyncMessage_BadRequest(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().PostRestJson(
context.Background(),
"/eth/v1/beacon/pool/sync_committees",
nil,
gomock.Any(),
nil,
).Return(
nil,
errors.New("foo error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.SubmitSyncMessage(context.Background(), &ethpb.SyncCommitteeMessage{})
assert.ErrorContains(t, "failed to send POST data to `/eth/v1/beacon/pool/sync_committees` REST endpoint", err)
assert.ErrorContains(t, "foo error", err)
}