Skip to content

Commit

Permalink
setup: Add isSlashingProtectionMinimal argument.
Browse files Browse the repository at this point in the history
The added feature is located in the `validator/client/propose_test.go`
file.

The rest of this commit consists in tests wrapping.
  • Loading branch information
nalepae committed Dec 22, 2023
1 parent 410c891 commit c11c02b
Show file tree
Hide file tree
Showing 11 changed files with 2,125 additions and 1,853 deletions.
2 changes: 1 addition & 1 deletion validator/client/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ go_library(

go_test(
name = "go_default_test",
size = "small",
size = "medium",
srcs = [
"aggregate_test.go",
"attest_protect_test.go",
Expand Down
283 changes: 154 additions & 129 deletions validator/client/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package client
import (
"context"
"errors"
"fmt"
"testing"

"github.com/golang/mock/gomock"
Expand All @@ -21,151 +22,175 @@ import (
)

func TestSubmitAggregateAndProof_GetDutiesRequestFailure(t *testing.T) {
hook := logTest.NewGlobal()
validator, _, validatorKey, finish := setup(t)
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{}}
defer finish()

var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.SubmitAggregateAndProof(context.Background(), 0, pubKey)

require.LogsContain(t, hook, "Could not fetch validator assignment")
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
hook := logTest.NewGlobal()
validator, _, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
validator.duties = &ethpb.DutiesResponse{Duties: []*ethpb.DutiesResponse_Duty{}}
defer finish()

var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.SubmitAggregateAndProof(context.Background(), 0, pubKey)

require.LogsContain(t, hook, "Could not fetch validator assignment")
})
}
}

func TestSubmitAggregateAndProof_SignFails(t *testing.T) {
validator, m, validatorKey, finish := setup(t)
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.duties = &ethpb.DutiesResponse{
Duties: []*ethpb.DutiesResponse_Duty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
},
},
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.duties = &ethpb.DutiesResponse{
Duties: []*ethpb.DutiesResponse_Duty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
},
},
}

m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)

m.validatorClient.EXPECT().SubmitAggregateSelectionProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}),
).Return(&ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0,
Aggregate: util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: make([]byte, 1),
}),
SelectionProof: make([]byte, 96),
},
}, nil)

m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: nil}, errors.New("bad domain root"))

validator.SubmitAggregateAndProof(context.Background(), 0, pubKey)
})
}

m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)

m.validatorClient.EXPECT().SubmitAggregateSelectionProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}),
).Return(&ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0,
Aggregate: util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: make([]byte, 1),
}),
SelectionProof: make([]byte, 96),
},
}, nil)

m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: nil}, errors.New("bad domain root"))

validator.SubmitAggregateAndProof(context.Background(), 0, pubKey)
}

func TestSubmitAggregateAndProof_Ok(t *testing.T) {
validator, m, validatorKey, finish := setup(t)
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.duties = &ethpb.DutiesResponse{
Duties: []*ethpb.DutiesResponse_Duty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
},
},
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.duties = &ethpb.DutiesResponse{
Duties: []*ethpb.DutiesResponse_Duty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
},
},
}

m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)

m.validatorClient.EXPECT().SubmitAggregateSelectionProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}),
).Return(&ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0,
Aggregate: util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: make([]byte, 1),
}),
SelectionProof: make([]byte, 96),
},
}, nil)

m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)

m.validatorClient.EXPECT().SubmitSignedAggregateSelectionProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedAggregateSubmitRequest{}),
).Return(&ethpb.SignedAggregateSubmitResponse{AttestationDataRoot: make([]byte, 32)}, nil)

validator.SubmitAggregateAndProof(context.Background(), 0, pubKey)
})
}

m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)

m.validatorClient.EXPECT().SubmitAggregateSelectionProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}),
).Return(&ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0,
Aggregate: util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: make([]byte, 1),
}),
SelectionProof: make([]byte, 96),
},
}, nil)

m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)

m.validatorClient.EXPECT().SubmitSignedAggregateSelectionProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedAggregateSubmitRequest{}),
).Return(&ethpb.SignedAggregateSubmitResponse{AttestationDataRoot: make([]byte, 32)}, nil)

validator.SubmitAggregateAndProof(context.Background(), 0, pubKey)
}

func TestWaitForSlotTwoThird_WaitCorrectly(t *testing.T) {
validator, _, _, finish := setup(t)
defer finish()
currentTime := time.Now()
numOfSlots := primitives.Slot(4)
validator.genesisTime = uint64(currentTime.Unix()) - uint64(numOfSlots.Mul(params.BeaconConfig().SecondsPerSlot))
oneThird := slots.DivideSlotBy(3 /* one third of slot duration */)
timeToSleep := oneThird + oneThird

twoThirdTime := currentTime.Add(timeToSleep)
validator.waitToSlotTwoThirds(context.Background(), numOfSlots)
currentTime = time.Now()
assert.Equal(t, twoThirdTime.Unix(), currentTime.Unix())
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, _, _, finish := setup(t, isSlashingProtectionMinimal)
defer finish()
currentTime := time.Now()
numOfSlots := primitives.Slot(4)
validator.genesisTime = uint64(currentTime.Unix()) - uint64(numOfSlots.Mul(params.BeaconConfig().SecondsPerSlot))
oneThird := slots.DivideSlotBy(3 /* one third of slot duration */)
timeToSleep := oneThird + oneThird

twoThirdTime := currentTime.Add(timeToSleep)
validator.waitToSlotTwoThirds(context.Background(), numOfSlots)
currentTime = time.Now()
assert.Equal(t, twoThirdTime.Unix(), currentTime.Unix())
})
}
}

func TestWaitForSlotTwoThird_DoneContext_ReturnsImmediately(t *testing.T) {
validator, _, _, finish := setup(t)
defer finish()
currentTime := time.Now()
numOfSlots := primitives.Slot(4)
validator.genesisTime = uint64(currentTime.Unix()) - uint64(numOfSlots.Mul(params.BeaconConfig().SecondsPerSlot))

expectedTime := time.Now()
ctx, cancel := context.WithCancel(context.Background())
cancel()
validator.waitToSlotTwoThirds(ctx, numOfSlots)
currentTime = time.Now()
assert.Equal(t, expectedTime.Unix(), currentTime.Unix())
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, _, _, finish := setup(t, isSlashingProtectionMinimal)
defer finish()
currentTime := time.Now()
numOfSlots := primitives.Slot(4)
validator.genesisTime = uint64(currentTime.Unix()) - uint64(numOfSlots.Mul(params.BeaconConfig().SecondsPerSlot))

expectedTime := time.Now()
ctx, cancel := context.WithCancel(context.Background())
cancel()
validator.waitToSlotTwoThirds(ctx, numOfSlots)
currentTime = time.Now()
assert.Equal(t, expectedTime.Unix(), currentTime.Unix())
})
}
}

func TestAggregateAndProofSignature_CanSignValidSignature(t *testing.T) {
validator, m, validatorKey, finish := setup(t)
defer finish()

var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
&ethpb.DomainRequest{Epoch: 0, Domain: params.BeaconConfig().DomainAggregateAndProof[:]},
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)

agg := &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0,
Aggregate: util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(1),
}),
SelectionProof: make([]byte, 96),
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
defer finish()

var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
&ethpb.DomainRequest{Epoch: 0, Domain: params.BeaconConfig().DomainAggregateAndProof[:]},
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)

agg := &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0,
Aggregate: util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(1),
}),
SelectionProof: make([]byte, 96),
}
sig, err := validator.aggregateAndProofSig(context.Background(), pubKey, agg, 0 /* slot */)
require.NoError(t, err)
_, err = bls.SignatureFromBytes(sig)
require.NoError(t, err)
})
}
sig, err := validator.aggregateAndProofSig(context.Background(), pubKey, agg, 0 /* slot */)
require.NoError(t, err)
_, err = bls.SignatureFromBytes(sig)
require.NoError(t, err)
}
Loading

0 comments on commit c11c02b

Please sign in to comment.