Fix sleep logic for attesting (#2048)

* sleep before attesting

* Test
This commit is contained in:
Preston Van Loon 2019-03-20 19:51:25 -04:00 committed by GitHub
parent 92640f9182
commit 810930d6a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 33 deletions

View File

@ -22,6 +22,9 @@ var delay = params.BeaconConfig().SecondsPerSlot / 2
func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) { func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) {
ctx, span := trace.StartSpan(ctx, "validator.AttestToBlockHead") ctx, span := trace.StartSpan(ctx, "validator.AttestToBlockHead")
defer span.End() defer span.End()
v.waitToSlotMidpoint(ctx, slot)
// First the validator should construct attestation_data, an AttestationData // First the validator should construct attestation_data, an AttestationData
// object based upon the state at the assigned slot. // object based upon the state at the assigned slot.
attData := &pbp2p.AttestationData{ attData := &pbp2p.AttestationData{
@ -118,11 +121,6 @@ func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) {
"slot": slot - params.BeaconConfig().GenesisSlot, "slot": slot - params.BeaconConfig().GenesisSlot,
}).Info("Attesting to beacon chain head...") }).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) log.Debugf("Produced attestation: %v", attestation)
attResp, err := v.attesterClient.AttestHead(ctx, attestation) attResp, err := v.attesterClient.AttestHead(ctx, attestation)
if err != nil { if err != nil {
@ -135,3 +133,16 @@ func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) {
"slot": slot - params.BeaconConfig().GenesisSlot, "slot": slot - params.BeaconConfig().GenesisSlot,
}).Info("Beacon node processed attestation successfully") }).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))
}

View File

@ -178,52 +178,29 @@ func TestAttestToBlockHead_DoesNotAttestBeforeDelay(t *testing.T) {
validator, m, finish := setup(t) validator, m, finish := setup(t)
defer finish() defer finish()
var wg sync.WaitGroup
wg.Add(3)
defer wg.Wait()
validator.genesisTime = uint64(time.Now().Unix()) validator.genesisTime = uint64(time.Now().Unix())
validatorIndex := uint64(5)
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
m.validatorClient.EXPECT().CommitteeAssignment( m.validatorClient.EXPECT().CommitteeAssignment(
gomock.Any(), // ctx gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pb.ValidatorEpochAssignmentsRequest{}), gomock.AssignableToTypeOf(&pb.ValidatorEpochAssignmentsRequest{}),
gomock.Any(), // ctx gomock.Any(),
).Return(&pb.CommitteeAssignmentResponse{ ).Times(0)
Shard: 5,
Committee: committee,
}, nil).Do(func(arg0, arg1 interface{}) {
wg.Done()
})
m.attesterClient.EXPECT().AttestationDataAtSlot( m.attesterClient.EXPECT().AttestationDataAtSlot(
gomock.Any(), // ctx gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pb.AttestationDataRequest{}), gomock.AssignableToTypeOf(&pb.AttestationDataRequest{}),
).Return(&pb.AttestationDataResponse{ ).Times(0)
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()
})
m.validatorClient.EXPECT().ValidatorIndex( m.validatorClient.EXPECT().ValidatorIndex(
gomock.Any(), // ctx gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pb.ValidatorIndexRequest{}), gomock.AssignableToTypeOf(&pb.ValidatorIndexRequest{}),
).Return(&pb.ValidatorIndexResponse{ ).Times(0)
Index: uint64(validatorIndex),
}, nil).Do(func(arg0, arg1 interface{}) {
wg.Done()
})
m.attesterClient.EXPECT().AttestHead( m.attesterClient.EXPECT().AttestHead(
gomock.Any(), // ctx gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pbp2p.Attestation{}), gomock.AssignableToTypeOf(&pbp2p.Attestation{}),
).Return(&pb.AttestResponse{}, nil /* error */).Times(0) ).Return(&pb.AttestResponse{}, nil /* error */).Times(0)
delay = 2 delay = 5
go validator.AttestToBlockHead(context.Background(), 0) go validator.AttestToBlockHead(context.Background(), 0)
} }