From 810930d6a7a4849110a95a2475d622ad2d63a032 Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 20 Mar 2019 19:51:25 -0400 Subject: [PATCH] Fix sleep logic for attesting (#2048) * sleep before attesting * Test --- validator/client/validator_attest.go | 21 +++++++++++---- validator/client/validator_attest_test.go | 33 ++++------------------- 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/validator/client/validator_attest.go b/validator/client/validator_attest.go index 958565761..356e2f1bc 100644 --- a/validator/client/validator_attest.go +++ b/validator/client/validator_attest.go @@ -22,6 +22,9 @@ var delay = params.BeaconConfig().SecondsPerSlot / 2 func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) { ctx, span := trace.StartSpan(ctx, "validator.AttestToBlockHead") defer span.End() + + v.waitToSlotMidpoint(ctx, slot) + // First the validator should construct attestation_data, an AttestationData // object based upon the state at the assigned slot. attData := &pbp2p.AttestationData{ @@ -118,11 +121,6 @@ func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) { "slot": slot - params.BeaconConfig().GenesisSlot, }).Info("Attesting to beacon chain head...") - duration := time.Duration(slot*params.BeaconConfig().SecondsPerSlot+delay) * time.Second - timeToBroadcast := time.Unix(int64(v.genesisTime), 0).Add(duration) - _, sleepSpan := trace.StartSpan(ctx, "validator.AttestToBlockHead_sleepUntilTimeToBroadcast") - time.Sleep(time.Until(timeToBroadcast)) - sleepSpan.End() log.Debugf("Produced attestation: %v", attestation) attResp, err := v.attesterClient.AttestHead(ctx, attestation) if err != nil { @@ -135,3 +133,16 @@ func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) { "slot": slot - params.BeaconConfig().GenesisSlot, }).Info("Beacon node processed attestation successfully") } + +// waitToSlotMidpoint waits until halfway through the current slot period +// such that any blocks from this slot have time to reach the beacon node +// before creating the attestation. +func (v *validator) waitToSlotMidpoint(ctx context.Context, slot uint64) { + _, span := trace.StartSpan(ctx, "validator.waitToSlotMidpoint") + defer span.End() + + duration := time.Duration(slot*params.BeaconConfig().SecondsPerSlot+delay) * time.Second + timeToBroadcast := time.Unix(int64(v.genesisTime), 0).Add(duration) + + time.Sleep(time.Until(timeToBroadcast)) +} diff --git a/validator/client/validator_attest_test.go b/validator/client/validator_attest_test.go index 5c98b7a89..9e4e0fd88 100644 --- a/validator/client/validator_attest_test.go +++ b/validator/client/validator_attest_test.go @@ -178,52 +178,29 @@ func TestAttestToBlockHead_DoesNotAttestBeforeDelay(t *testing.T) { validator, m, finish := setup(t) defer finish() - var wg sync.WaitGroup - wg.Add(3) - defer wg.Wait() - validator.genesisTime = uint64(time.Now().Unix()) - validatorIndex := uint64(5) - committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10} m.validatorClient.EXPECT().CommitteeAssignment( gomock.Any(), // ctx gomock.AssignableToTypeOf(&pb.ValidatorEpochAssignmentsRequest{}), - gomock.Any(), // ctx - ).Return(&pb.CommitteeAssignmentResponse{ - Shard: 5, - Committee: committee, - }, nil).Do(func(arg0, arg1 interface{}) { - wg.Done() - }) + gomock.Any(), + ).Times(0) m.attesterClient.EXPECT().AttestationDataAtSlot( gomock.Any(), // ctx gomock.AssignableToTypeOf(&pb.AttestationDataRequest{}), - ).Return(&pb.AttestationDataResponse{ - BeaconBlockRootHash32: []byte("A"), - EpochBoundaryRootHash32: []byte("B"), - JustifiedBlockRootHash32: []byte("C"), - LatestCrosslink: &pbp2p.Crosslink{CrosslinkDataRootHash32: []byte{'D'}}, - JustifiedEpoch: 3, - }, nil).Do(func(arg0, arg1 interface{}) { - wg.Done() - }) + ).Times(0) m.validatorClient.EXPECT().ValidatorIndex( gomock.Any(), // ctx gomock.AssignableToTypeOf(&pb.ValidatorIndexRequest{}), - ).Return(&pb.ValidatorIndexResponse{ - Index: uint64(validatorIndex), - }, nil).Do(func(arg0, arg1 interface{}) { - wg.Done() - }) + ).Times(0) m.attesterClient.EXPECT().AttestHead( gomock.Any(), // ctx gomock.AssignableToTypeOf(&pbp2p.Attestation{}), ).Return(&pb.AttestResponse{}, nil /* error */).Times(0) - delay = 2 + delay = 5 go validator.AttestToBlockHead(context.Background(), 0) }