mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-24 20:37:17 +00:00
4ec396c025
* refetch validating keys every 30 seconds * deduplicate error/log messages * remove redundant break statement * comment about execution flow * move code to wait_for_activation.go Co-authored-by: Victor Farazdagi <simple.square@gmail.com> Co-authored-by: terence tsao <terence@prysmaticlabs.com> Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
231 lines
6.5 KiB
Go
231 lines
6.5 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"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(),
|
|
ðpb.ValidatorActivationRequest{
|
|
PublicKeys: [][]byte{pubKey[:]},
|
|
},
|
|
).Return(clientStream, nil)
|
|
clientStream.EXPECT().Recv().Return(
|
|
ðpb.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(),
|
|
ðpb.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(),
|
|
ðpb.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(),
|
|
ðpb.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(),
|
|
ðpb.ValidatorActivationRequest{
|
|
PublicKeys: [][]byte{pubKey[:]},
|
|
},
|
|
).Return(clientStream, nil)
|
|
clientStream.EXPECT().Recv().Return(
|
|
resp,
|
|
nil,
|
|
)
|
|
require.NoError(t, v.WaitForActivation(context.Background()))
|
|
}
|
|
|
|
func TestWaitForActivation_RefetchKeys(t *testing.T) {
|
|
originalPeriod := keyRefetchPeriod
|
|
defer func() {
|
|
keyRefetchPeriod = originalPeriod
|
|
}()
|
|
keyRefetchPeriod = 5 * time.Second
|
|
|
|
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,
|
|
},
|
|
fetchNoKeys: true,
|
|
}
|
|
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(),
|
|
ðpb.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")
|
|
assert.LogsContain(t, hook, msgNoKeysFetched)
|
|
assert.LogsContain(t, hook, "Validator activated")
|
|
}
|