Wait Until Halfway Through Slot Duration to AttestHead (#1532)

* Write initial sleep function

* Add fake delay to testing

* Attempt to fix tests

* Fix tests

* Remove stray delay = 0

* Attempt at test

* Changes to tests, removed unneeded code

* Fix delay

* Get further in test

* Fix gomock being stupid

* Fix merge issues

* Fix tests

* Fix tests (!!!)

* Fix goimports

* Fix merge issues
This commit is contained in:
Ivan Martinez 2019-02-15 09:58:06 -07:00 committed by Raul Jordan
parent eab64062d7
commit 78c205758f
2 changed files with 118 additions and 4 deletions

View File

@ -2,17 +2,19 @@ package client
import (
"context"
"github.com/opentracing/opentracing-go"
"fmt"
"time"
"github.com/prysmaticlabs/prysm/shared/params"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
"github.com/opentracing/opentracing-go"
)
var delay = params.BeaconConfig().SlotDuration / 2
// AttestToBlockHead completes the validator client's attester responsibility at a given slot.
// It fetches the latest beacon block head along with the latest canonical beacon state
// information in order to sign the block and include information about the validator's
@ -107,6 +109,10 @@ func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) {
// TODO(#1366): Use BLS to generate an aggregate signature.
attestation.AggregateSignature = []byte("signed")
duration := time.Duration(slot*params.BeaconConfig().SlotDuration+delay) * time.Second
timeToBroadcast := time.Unix(int64(v.genesisTime), 0).Add(duration)
time.Sleep(time.Until(timeToBroadcast))
attestRes, err := v.attesterClient.AttestHead(ctx, attestation)
if err != nil {
log.Errorf("Could not submit attestation to beacon node: %v", err)
@ -114,5 +120,5 @@ func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) {
}
log.WithField(
"hash", fmt.Sprintf("%#x", attestRes.AttestationHash),
).Info("Submitted attestation successfully with hash %#x", attestRes.AttestationHash)
).Infof("Submitted attestation successfully with hash %#x", attestRes.AttestationHash)
}

View File

@ -3,7 +3,9 @@ package client
import (
"context"
"errors"
"sync"
"testing"
"time"
"github.com/prysmaticlabs/prysm/shared/params"
@ -173,3 +175,109 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) {
}
testutil.AssertLogsContain(t, hook, "Submitted attestation successfully")
}
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().ValidatorCommitteeAtSlot(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pb.CommitteeRequest{}),
gomock.Any(), // ctx
).Return(&pb.CommitteeResponse{
Shard: 5,
Committee: committee,
}, nil).Do(func(arg0, arg1 interface{}) {
wg.Done()
})
m.attesterClient.EXPECT().AttestationInfoAtSlot(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pb.AttestationInfoRequest{}),
).Return(&pb.AttestationInfoResponse{
BeaconBlockRootHash32: []byte("A"),
EpochBoundaryRootHash32: []byte("B"),
JustifiedBlockRootHash32: []byte("C"),
LatestCrosslink: &pbp2p.Crosslink{ShardBlockRootHash32: []byte{'D'}},
JustifiedEpoch: 3,
}, nil).Do(func(arg0, arg1 interface{}) {
wg.Done()
})
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()
})
m.attesterClient.EXPECT().AttestHead(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pbp2p.Attestation{}),
).Return(&pb.AttestResponse{}, nil /* error */).Times(0)
delay = 2
go validator.AttestToBlockHead(context.Background(), 0)
}
func TestAttestToBlockHead_DoesAttestAfterDelay(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().ValidatorCommitteeAtSlot(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pb.CommitteeRequest{}),
gomock.Any(), // ctx
).Return(&pb.CommitteeResponse{
Shard: 5,
Committee: committee,
}, nil).Do(func(arg0, arg1 interface{}) {
wg.Done()
})
m.attesterClient.EXPECT().AttestationInfoAtSlot(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pb.AttestationInfoRequest{}),
).Return(&pb.AttestationInfoResponse{
BeaconBlockRootHash32: []byte("A"),
EpochBoundaryRootHash32: []byte("B"),
JustifiedBlockRootHash32: []byte("C"),
LatestCrosslink: &pbp2p.Crosslink{ShardBlockRootHash32: []byte{'D'}},
JustifiedEpoch: 3,
}, nil).Do(func(arg0, arg1 interface{}) {
wg.Done()
})
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()
})
m.attesterClient.EXPECT().AttestHead(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&pbp2p.Attestation{}),
).Return(&pb.AttestResponse{}, nil).Times(1)
delay = 0
go validator.AttestToBlockHead(context.Background(), 0)
}