prysm-pulse/validator/client/wait_for_activation_test.go
Preston Van Loon 923e4d3a5e
Attempt to reconnect when waiting for activation (#8057)
* Attempt to reconnect when waiting for activation

* rm fuzz/attestation_fuzz.go

* math.Min, not math.Max

* Gofmt

* resolve RVV-B0003
2020-12-10 19:26:31 -06:00

186 lines
5.3 KiB
Go

package client
import (
"context"
"testing"
"github.com/golang/mock/gomock"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/mock"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func TestWaitActivation_ContextCanceled(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewMockBeaconNodeValidatorClient(ctrl)
privKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], privKey.PublicKey().Marshal())
km := &mockKeymanager{
keysMap: map[[48]byte]bls.SecretKey{
pubKey: privKey,
},
}
v := validator{
validatorClient: client,
keyManager: km,
}
clientStream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl)
client.EXPECT().WaitForActivation(
gomock.Any(),
&ethpb.ValidatorActivationRequest{
PublicKeys: [][]byte{pubKey[:]},
},
).Return(clientStream, nil)
clientStream.EXPECT().Recv().Return(
&ethpb.ValidatorActivationResponse{},
nil,
)
ctx, cancel := context.WithCancel(context.Background())
cancel()
assert.ErrorContains(t, cancelledCtx, v.WaitForActivation(ctx))
}
func TestWaitActivation_StreamSetupFails_AttemptsToReconnect(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewMockBeaconNodeValidatorClient(ctrl)
privKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], privKey.PublicKey().Marshal())
km := &mockKeymanager{
keysMap: map[[48]byte]bls.SecretKey{
pubKey: privKey,
},
}
v := validator{
validatorClient: client,
keyManager: km,
}
clientStream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl)
client.EXPECT().WaitForActivation(
gomock.Any(),
&ethpb.ValidatorActivationRequest{
PublicKeys: [][]byte{pubKey[:]},
},
).Return(clientStream, errors.New("failed stream")).Return(clientStream, nil)
resp := generateMockStatusResponse([][]byte{pubKey[:]})
resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_ACTIVE
clientStream.EXPECT().Recv().Return(resp, nil)
assert.NoError(t, v.WaitForActivation(context.Background()))
}
func TestWaitForActivation_ReceiveErrorFromStream_AttemptsReconnection(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewMockBeaconNodeValidatorClient(ctrl)
privKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], privKey.PublicKey().Marshal())
km := &mockKeymanager{
keysMap: map[[48]byte]bls.SecretKey{
pubKey: privKey,
},
}
v := validator{
validatorClient: client,
keyManager: km,
}
clientStream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl)
client.EXPECT().WaitForActivation(
gomock.Any(),
&ethpb.ValidatorActivationRequest{
PublicKeys: [][]byte{pubKey[:]},
},
).Return(clientStream, nil)
// A stream fails the first time, but succeeds the second time.
resp := generateMockStatusResponse([][]byte{pubKey[:]})
resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_ACTIVE
clientStream.EXPECT().Recv().Return(
nil,
errors.New("fails"),
).Return(resp, nil)
assert.NoError(t, v.WaitForActivation(context.Background()))
}
func TestWaitActivation_LogsActivationEpochOK(t *testing.T) {
hook := logTest.NewGlobal()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewMockBeaconNodeValidatorClient(ctrl)
privKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], privKey.PublicKey().Marshal())
km := &mockKeymanager{
keysMap: map[[48]byte]bls.SecretKey{
pubKey: privKey,
},
}
v := validator{
validatorClient: client,
keyManager: km,
genesisTime: 1,
}
resp := generateMockStatusResponse([][]byte{pubKey[:]})
resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_ACTIVE
clientStream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl)
client.EXPECT().WaitForActivation(
gomock.Any(),
&ethpb.ValidatorActivationRequest{
PublicKeys: [][]byte{pubKey[:]},
},
).Return(clientStream, nil)
clientStream.EXPECT().Recv().Return(
resp,
nil,
)
assert.NoError(t, v.WaitForActivation(context.Background()), "Could not wait for activation")
require.LogsContain(t, hook, "Validator activated")
}
func TestWaitForActivation_Exiting(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewMockBeaconNodeValidatorClient(ctrl)
privKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], privKey.PublicKey().Marshal())
km := &mockKeymanager{
keysMap: map[[48]byte]bls.SecretKey{
pubKey: privKey,
},
}
v := validator{
validatorClient: client,
keyManager: km,
genesisTime: 1,
}
resp := generateMockStatusResponse([][]byte{pubKey[:]})
resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_EXITING
clientStream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl)
client.EXPECT().WaitForActivation(
gomock.Any(),
&ethpb.ValidatorActivationRequest{
PublicKeys: [][]byte{pubKey[:]},
},
).Return(clientStream, nil)
clientStream.EXPECT().Recv().Return(
resp,
nil,
)
require.NoError(t, v.WaitForActivation(context.Background()))
}