mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-23 11:57:18 +00:00
Add REST implementation for Validator's ProposeExit
(#11785)
* Add REST implementation for Validator's GetBeaconBlock * Move endpoint into constant Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
parent
4eb4cd9756
commit
3ff5895548
@ -16,6 +16,7 @@ go_library(
|
||||
"json_rest_handler.go",
|
||||
"prepare_beacon_proposer.go",
|
||||
"propose_beacon_block.go",
|
||||
"propose_exit.go",
|
||||
"state_validators.go",
|
||||
"status.go",
|
||||
],
|
||||
@ -64,6 +65,7 @@ go_test(
|
||||
"propose_beacon_block_blinded_capella_test.go",
|
||||
"propose_beacon_block_phase0_test.go",
|
||||
"propose_beacon_block_test.go",
|
||||
"propose_exit_test.go",
|
||||
"state_validators_test.go",
|
||||
"status_test.go",
|
||||
"wait_for_chain_start_test.go",
|
||||
|
@ -137,13 +137,8 @@ func (c *beaconApiValidatorClient) ProposeBeaconBlock(_ context.Context, in *eth
|
||||
return c.proposeBeaconBlock(in)
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) ProposeExit(ctx context.Context, in *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error) {
|
||||
if c.fallbackClient != nil {
|
||||
return c.fallbackClient.ProposeExit(ctx, in)
|
||||
}
|
||||
|
||||
// TODO: Implement me
|
||||
panic("beaconApiValidatorClient.ProposeExit is not implemented. To use a fallback client, create this validator with NewBeaconApiValidatorClientWithFallback instead.")
|
||||
func (c *beaconApiValidatorClient) ProposeExit(_ context.Context, in *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error) {
|
||||
return c.proposeExit(in)
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) StreamBlocksAltair(ctx context.Context, in *ethpb.StreamBlocksRequest) (ethpb.BeaconNodeValidator_StreamBlocksAltairClient, error) {
|
||||
|
48
validator/client/beacon-api/propose_exit.go
Normal file
48
validator/client/beacon-api/propose_exit.go
Normal file
@ -0,0 +1,48 @@
|
||||
package beacon_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"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) proposeExit(signedVoluntaryExit *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error) {
|
||||
if signedVoluntaryExit == nil {
|
||||
return nil, errors.New("signed voluntary exit is nil")
|
||||
}
|
||||
|
||||
if signedVoluntaryExit.Exit == nil {
|
||||
return nil, errors.New("exit is nil")
|
||||
}
|
||||
|
||||
jsonSignedVoluntaryExit := apimiddleware.SignedVoluntaryExitJson{
|
||||
Exit: &apimiddleware.VoluntaryExitJson{
|
||||
Epoch: strconv.FormatUint(uint64(signedVoluntaryExit.Exit.Epoch), 10),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(signedVoluntaryExit.Exit.ValidatorIndex), 10),
|
||||
},
|
||||
Signature: hexutil.Encode(signedVoluntaryExit.Signature),
|
||||
}
|
||||
|
||||
marshalledSignedVoluntaryExit, err := json.Marshal(jsonSignedVoluntaryExit)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal signed voluntary exit")
|
||||
}
|
||||
|
||||
if _, err := c.jsonRestHandler.PostRestJson("/eth/v1/beacon/pool/voluntary_exits", nil, bytes.NewBuffer(marshalledSignedVoluntaryExit), nil); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to send POST data to REST endpoint")
|
||||
}
|
||||
|
||||
exitRoot, err := signedVoluntaryExit.Exit.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to compute exit root")
|
||||
}
|
||||
|
||||
return ðpb.ProposeExitResponse{
|
||||
ExitRoot: exitRoot[:],
|
||||
}, nil
|
||||
}
|
107
validator/client/beacon-api/propose_exit_test.go
Normal file
107
validator/client/beacon-api/propose_exit_test.go
Normal file
@ -0,0 +1,107 @@
|
||||
package beacon_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/apimiddleware"
|
||||
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"
|
||||
)
|
||||
|
||||
const proposeExitTestEndpoint = "/eth/v1/beacon/pool/voluntary_exits"
|
||||
|
||||
func TestProposeExit_Valid(t *testing.T) {
|
||||
const signature = "0xd0a030a1d6b4f8217062ccc98088fbd908797f107aaa825f2366f090445fa79a6417789aa1d232c4f9b1e56671165bde25eb5586f94fc5677df593b99369684e8f413b1bfbd3fa6f20615244f9381895c71d4f7136c528092a3d03294a98be2d"
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
jsonSignedVoluntaryExit := apimiddleware.SignedVoluntaryExitJson{
|
||||
Exit: &apimiddleware.VoluntaryExitJson{
|
||||
Epoch: "1",
|
||||
ValidatorIndex: "2",
|
||||
},
|
||||
Signature: signature,
|
||||
}
|
||||
|
||||
marshalledVoluntaryExit, err := json.Marshal(jsonSignedVoluntaryExit)
|
||||
require.NoError(t, err)
|
||||
|
||||
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().PostRestJson(
|
||||
proposeExitTestEndpoint,
|
||||
nil,
|
||||
bytes.NewBuffer(marshalledVoluntaryExit),
|
||||
nil,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
decodedSignature, err := hexutil.Decode(signature)
|
||||
require.NoError(t, err)
|
||||
|
||||
protoSignedVoluntaryExit := ðpb.SignedVoluntaryExit{
|
||||
Exit: ðpb.VoluntaryExit{
|
||||
Epoch: 1,
|
||||
ValidatorIndex: 2,
|
||||
},
|
||||
Signature: decodedSignature,
|
||||
}
|
||||
|
||||
expectedExitRoot, err := protoSignedVoluntaryExit.Exit.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
exitResponse, err := validatorClient.proposeExit(protoSignedVoluntaryExit)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedExitRoot[:], exitResponse.ExitRoot)
|
||||
}
|
||||
|
||||
func TestProposeExit_NilSignedVoluntaryExit(t *testing.T) {
|
||||
validatorClient := &beaconApiValidatorClient{}
|
||||
_, err := validatorClient.proposeExit(nil)
|
||||
assert.ErrorContains(t, "signed voluntary exit is nil", err)
|
||||
}
|
||||
|
||||
func TestProposeExit_NilExit(t *testing.T) {
|
||||
validatorClient := &beaconApiValidatorClient{}
|
||||
_, err := validatorClient.proposeExit(ðpb.SignedVoluntaryExit{})
|
||||
assert.ErrorContains(t, "exit is nil", err)
|
||||
}
|
||||
|
||||
func TestProposeExit_BadRequest(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().PostRestJson(
|
||||
proposeExitTestEndpoint,
|
||||
nil,
|
||||
gomock.Any(),
|
||||
nil,
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("foo error"),
|
||||
).Times(1)
|
||||
|
||||
protoSignedVoluntaryExit := ðpb.SignedVoluntaryExit{
|
||||
Exit: ðpb.VoluntaryExit{
|
||||
Epoch: 1,
|
||||
ValidatorIndex: 2,
|
||||
},
|
||||
Signature: []byte{3},
|
||||
}
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := validatorClient.proposeExit(protoSignedVoluntaryExit)
|
||||
assert.ErrorContains(t, "failed to send POST data to REST endpoint", err)
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
Loading…
Reference in New Issue
Block a user