diff --git a/beacon-chain/blockchain/BUILD.bazel b/beacon-chain/blockchain/BUILD.bazel index 9ffe3b167d..dc858011d8 100644 --- a/beacon-chain/blockchain/BUILD.bazel +++ b/beacon-chain/blockchain/BUILD.bazel @@ -13,6 +13,7 @@ go_library( "//beacon-chain/params:go_default_library", "//beacon-chain/powchain:go_default_library", "//beacon-chain/types:go_default_library", + "//beacon-chain/utils:go_default_library", "//proto/beacon/p2p/v1:go_default_library", "@com_github_ethereum_go_ethereum//ethdb:go_default_library", "@com_github_ethereum_go_ethereum//event:go_default_library", diff --git a/beacon-chain/blockchain/service.go b/beacon-chain/blockchain/service.go index 16bf93010d..84c0915cb3 100644 --- a/beacon-chain/blockchain/service.go +++ b/beacon-chain/blockchain/service.go @@ -13,6 +13,7 @@ import ( "github.com/prysmaticlabs/prysm/beacon-chain/params" "github.com/prysmaticlabs/prysm/beacon-chain/powchain" "github.com/prysmaticlabs/prysm/beacon-chain/types" + "github.com/prysmaticlabs/prysm/beacon-chain/utils" "github.com/sirupsen/logrus" ) @@ -34,6 +35,7 @@ type ChainService struct { lock sync.Mutex devMode bool genesisTimestamp time.Time + slotAlignmentDuration uint64 } // Config options for the service. @@ -52,7 +54,7 @@ func NewChainService(ctx context.Context, cfg *Config) (*ChainService, error) { ctx, cancel := context.WithCancel(ctx) return &ChainService{ ctx: ctx, - genesisTimestamp: types.GenesisTime, + genesisTimestamp: params.GenesisTime, chain: cfg.Chain, cancel: cancel, beaconDB: cfg.BeaconDB, @@ -63,6 +65,7 @@ func NewChainService(ctx context.Context, cfg *Config) (*ChainService, error) { canonicalCrystallizedStateFeed: new(event.Feed), blocksPendingProcessing: [][32]byte{}, devMode: cfg.DevMode, + slotAlignmentDuration: params.SlotDuration, }, nil } @@ -70,7 +73,18 @@ func NewChainService(ctx context.Context, cfg *Config) (*ChainService, error) { func (c *ChainService) Start() { // TODO(#474): Fetch the slot: (block, state) DAGs from persistent storage // to truly continue across sessions. - log.Infof("Starting service") + log.Info("Starting service") + + // If the genesis time was at 12:00:00PM and the current time is 12:00:03PM, + // the next slot should tick at 12:00:08PM. We can accomplish this + // using utils.BlockingWait and passing in the desired + // slot duration. + // + // Instead of utilizing params.SlotDuration, we utilize a property of + // RPC service struct so this value can be set to 0 seconds + // as a parameter in tests. Otherwise, tests would sleep. + utils.BlockingWait(time.Duration(c.slotAlignmentDuration) * time.Second) + go c.updateHead(time.NewTicker(time.Second * time.Duration(params.SlotDuration)).C) go c.blockProcessing() } diff --git a/beacon-chain/blockchain/service_test.go b/beacon-chain/blockchain/service_test.go index c54ff2ed5e..4b0a444a72 100644 --- a/beacon-chain/blockchain/service_test.go +++ b/beacon-chain/blockchain/service_test.go @@ -99,6 +99,8 @@ func TestStartStop(t *testing.T) { t.Fatalf("unable to setup chain service: %v", err) } + chainService.slotAlignmentDuration = 0 + chainService.IncomingBlockFeed() chainService.CanonicalBlockBySlotNumber(0) chainService.CheckForCanonicalBlockBySlot(0) @@ -118,6 +120,9 @@ func TestStartStop(t *testing.T) { if err != nil { t.Fatalf("unable to setup chain service: %v", err) } + + chainService.slotAlignmentDuration = 0 + chainService.Start() if len(chainService.CurrentActiveState().RecentBlockHashes()) != 128 { @@ -223,6 +228,8 @@ func TestFaultyStop(t *testing.T) { t.Fatalf("unable to setup chain service: %v", err) } + chainService.slotAlignmentDuration = 0 + chainService.Start() chainService.chain.SetActiveState(types.NewActiveState(nil, make(map[[32]byte]*types.VoteCache))) @@ -380,7 +387,7 @@ func TestRunningChainService(t *testing.T) { t.Fatalf("unable to get hash of canonical head: %v", err) } - secondsSinceGenesis := time.Since(types.GenesisTime).Seconds() + secondsSinceGenesis := time.Since(params.GenesisTime).Seconds() currentSlot := uint64(math.Floor(secondsSinceGenesis / float64(params.SlotDuration))) slotsStart := crystallized.LastStateRecalc() - params.CycleLength @@ -705,7 +712,7 @@ func TestProcessBlocksWithCorrectAttestations(t *testing.T) { t.Fatalf("Failed to compute block's hash: %v", err) } - secondsSinceGenesis := time.Since(types.GenesisTime).Seconds() + secondsSinceGenesis := time.Since(params.GenesisTime).Seconds() currentSlot := uint64(math.Floor(secondsSinceGenesis / float64(params.SlotDuration))) block1 := types.NewBlock(&pb.BeaconBlock{ diff --git a/beacon-chain/internal/BUILD.bazel b/beacon-chain/internal/BUILD.bazel index 3112febc31..a80509565f 100644 --- a/beacon-chain/internal/BUILD.bazel +++ b/beacon-chain/internal/BUILD.bazel @@ -4,7 +4,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", - srcs = ["beacon_service_mock.go"], + srcs = [ + "beacon_service_mock.go", + "validator_service_mock.go", + ], importpath = "github.com/prysmaticlabs/prysm/beacon-chain/internal", visibility = ["//beacon-chain:__subpackages__"], deps = [ diff --git a/beacon-chain/internal/beacon_service_mock.go b/beacon-chain/internal/beacon_service_mock.go index 5c8ef60d5f..4c1f2713f6 100644 --- a/beacon-chain/internal/beacon_service_mock.go +++ b/beacon-chain/internal/beacon_service_mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: BeaconServiceServer,BeaconService_LatestCrystallizedStateServer,BeaconService_LatestAttestationServer) +// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: BeaconServiceServer,BeaconService_LatestAttestationServer,BeaconService_ValidatorAssignmentsServer) package internal @@ -50,17 +50,17 @@ func (mr *MockBeaconServiceServerMockRecorder) CanonicalHead(arg0, arg1 interfac return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanonicalHead", reflect.TypeOf((*MockBeaconServiceServer)(nil).CanonicalHead), arg0, arg1) } -// GenesisTimeAndCanonicalState mocks base method -func (m *MockBeaconServiceServer) GenesisTimeAndCanonicalState(arg0 context.Context, arg1 *empty.Empty) (*v10.GenesisTimeAndStateResponse, error) { - ret := m.ctrl.Call(m, "GenesisTimeAndCanonicalState", arg0, arg1) - ret0, _ := ret[0].(*v10.GenesisTimeAndStateResponse) +// CurrentAssignmentsAndGenesisTime mocks base method +func (m *MockBeaconServiceServer) CurrentAssignmentsAndGenesisTime(arg0 context.Context, arg1 *v10.ValidatorAssignmentRequest) (*v10.CurrentAssignmentsResponse, error) { + ret := m.ctrl.Call(m, "CurrentAssignmentsAndGenesisTime", arg0, arg1) + ret0, _ := ret[0].(*v10.CurrentAssignmentsResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// GenesisTimeAndCanonicalState indicates an expected call of GenesisTimeAndCanonicalState -func (mr *MockBeaconServiceServerMockRecorder) GenesisTimeAndCanonicalState(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenesisTimeAndCanonicalState", reflect.TypeOf((*MockBeaconServiceServer)(nil).GenesisTimeAndCanonicalState), arg0, arg1) +// CurrentAssignmentsAndGenesisTime indicates an expected call of CurrentAssignmentsAndGenesisTime +func (mr *MockBeaconServiceServerMockRecorder) CurrentAssignmentsAndGenesisTime(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentAssignmentsAndGenesisTime", reflect.TypeOf((*MockBeaconServiceServer)(nil).CurrentAssignmentsAndGenesisTime), arg0, arg1) } // LatestAttestation mocks base method @@ -75,121 +75,16 @@ func (mr *MockBeaconServiceServerMockRecorder) LatestAttestation(arg0, arg1 inte return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatestAttestation", reflect.TypeOf((*MockBeaconServiceServer)(nil).LatestAttestation), arg0, arg1) } -// LatestCrystallizedState mocks base method -func (m *MockBeaconServiceServer) LatestCrystallizedState(arg0 *empty.Empty, arg1 v10.BeaconService_LatestCrystallizedStateServer) error { - ret := m.ctrl.Call(m, "LatestCrystallizedState", arg0, arg1) +// ValidatorAssignments mocks base method +func (m *MockBeaconServiceServer) ValidatorAssignments(arg0 *v10.ValidatorAssignmentRequest, arg1 v10.BeaconService_ValidatorAssignmentsServer) error { + ret := m.ctrl.Call(m, "ValidatorAssignments", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// LatestCrystallizedState indicates an expected call of LatestCrystallizedState -func (mr *MockBeaconServiceServerMockRecorder) LatestCrystallizedState(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatestCrystallizedState", reflect.TypeOf((*MockBeaconServiceServer)(nil).LatestCrystallizedState), arg0, arg1) -} - -// MockBeaconService_LatestCrystallizedStateServer is a mock of BeaconService_LatestCrystallizedStateServer interface -type MockBeaconService_LatestCrystallizedStateServer struct { - ctrl *gomock.Controller - recorder *MockBeaconService_LatestCrystallizedStateServerMockRecorder -} - -// MockBeaconService_LatestCrystallizedStateServerMockRecorder is the mock recorder for MockBeaconService_LatestCrystallizedStateServer -type MockBeaconService_LatestCrystallizedStateServerMockRecorder struct { - mock *MockBeaconService_LatestCrystallizedStateServer -} - -// NewMockBeaconService_LatestCrystallizedStateServer creates a new mock instance -func NewMockBeaconService_LatestCrystallizedStateServer(ctrl *gomock.Controller) *MockBeaconService_LatestCrystallizedStateServer { - mock := &MockBeaconService_LatestCrystallizedStateServer{ctrl: ctrl} - mock.recorder = &MockBeaconService_LatestCrystallizedStateServerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockBeaconService_LatestCrystallizedStateServer) EXPECT() *MockBeaconService_LatestCrystallizedStateServerMockRecorder { - return m.recorder -} - -// Context mocks base method -func (m *MockBeaconService_LatestCrystallizedStateServer) Context() context.Context { - ret := m.ctrl.Call(m, "Context") - ret0, _ := ret[0].(context.Context) - return ret0 -} - -// Context indicates an expected call of Context -func (mr *MockBeaconService_LatestCrystallizedStateServerMockRecorder) Context() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateServer)(nil).Context)) -} - -// RecvMsg mocks base method -func (m *MockBeaconService_LatestCrystallizedStateServer) RecvMsg(arg0 interface{}) error { - ret := m.ctrl.Call(m, "RecvMsg", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// RecvMsg indicates an expected call of RecvMsg -func (mr *MockBeaconService_LatestCrystallizedStateServerMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateServer)(nil).RecvMsg), arg0) -} - -// Send mocks base method -func (m *MockBeaconService_LatestCrystallizedStateServer) Send(arg0 *v1.CrystallizedState) error { - ret := m.ctrl.Call(m, "Send", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Send indicates an expected call of Send -func (mr *MockBeaconService_LatestCrystallizedStateServerMockRecorder) Send(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateServer)(nil).Send), arg0) -} - -// SendHeader mocks base method -func (m *MockBeaconService_LatestCrystallizedStateServer) SendHeader(arg0 metadata.MD) error { - ret := m.ctrl.Call(m, "SendHeader", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SendHeader indicates an expected call of SendHeader -func (mr *MockBeaconService_LatestCrystallizedStateServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateServer)(nil).SendHeader), arg0) -} - -// SendMsg mocks base method -func (m *MockBeaconService_LatestCrystallizedStateServer) SendMsg(arg0 interface{}) error { - ret := m.ctrl.Call(m, "SendMsg", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SendMsg indicates an expected call of SendMsg -func (mr *MockBeaconService_LatestCrystallizedStateServerMockRecorder) SendMsg(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateServer)(nil).SendMsg), arg0) -} - -// SetHeader mocks base method -func (m *MockBeaconService_LatestCrystallizedStateServer) SetHeader(arg0 metadata.MD) error { - ret := m.ctrl.Call(m, "SetHeader", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetHeader indicates an expected call of SetHeader -func (mr *MockBeaconService_LatestCrystallizedStateServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateServer)(nil).SetHeader), arg0) -} - -// SetTrailer mocks base method -func (m *MockBeaconService_LatestCrystallizedStateServer) SetTrailer(arg0 metadata.MD) { - m.ctrl.Call(m, "SetTrailer", arg0) -} - -// SetTrailer indicates an expected call of SetTrailer -func (mr *MockBeaconService_LatestCrystallizedStateServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateServer)(nil).SetTrailer), arg0) +// ValidatorAssignments indicates an expected call of ValidatorAssignments +func (mr *MockBeaconServiceServerMockRecorder) ValidatorAssignments(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorAssignments", reflect.TypeOf((*MockBeaconServiceServer)(nil).ValidatorAssignments), arg0, arg1) } // MockBeaconService_LatestAttestationServer is a mock of BeaconService_LatestAttestationServer interface @@ -296,3 +191,108 @@ func (m *MockBeaconService_LatestAttestationServer) SetTrailer(arg0 metadata.MD) func (mr *MockBeaconService_LatestAttestationServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockBeaconService_LatestAttestationServer)(nil).SetTrailer), arg0) } + +// MockBeaconService_ValidatorAssignmentsServer is a mock of BeaconService_ValidatorAssignmentsServer interface +type MockBeaconService_ValidatorAssignmentsServer struct { + ctrl *gomock.Controller + recorder *MockBeaconService_ValidatorAssignmentsServerMockRecorder +} + +// MockBeaconService_ValidatorAssignmentsServerMockRecorder is the mock recorder for MockBeaconService_ValidatorAssignmentsServer +type MockBeaconService_ValidatorAssignmentsServerMockRecorder struct { + mock *MockBeaconService_ValidatorAssignmentsServer +} + +// NewMockBeaconService_ValidatorAssignmentsServer creates a new mock instance +func NewMockBeaconService_ValidatorAssignmentsServer(ctrl *gomock.Controller) *MockBeaconService_ValidatorAssignmentsServer { + mock := &MockBeaconService_ValidatorAssignmentsServer{ctrl: ctrl} + mock.recorder = &MockBeaconService_ValidatorAssignmentsServerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockBeaconService_ValidatorAssignmentsServer) EXPECT() *MockBeaconService_ValidatorAssignmentsServerMockRecorder { + return m.recorder +} + +// Context mocks base method +func (m *MockBeaconService_ValidatorAssignmentsServer) Context() context.Context { + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(context.Context) + return ret0 +} + +// Context indicates an expected call of Context +func (mr *MockBeaconService_ValidatorAssignmentsServerMockRecorder) Context() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsServer)(nil).Context)) +} + +// RecvMsg mocks base method +func (m *MockBeaconService_ValidatorAssignmentsServer) RecvMsg(arg0 interface{}) error { + ret := m.ctrl.Call(m, "RecvMsg", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// RecvMsg indicates an expected call of RecvMsg +func (mr *MockBeaconService_ValidatorAssignmentsServerMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsServer)(nil).RecvMsg), arg0) +} + +// Send mocks base method +func (m *MockBeaconService_ValidatorAssignmentsServer) Send(arg0 *v10.ValidatorAssignmentResponse) error { + ret := m.ctrl.Call(m, "Send", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Send indicates an expected call of Send +func (mr *MockBeaconService_ValidatorAssignmentsServerMockRecorder) Send(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsServer)(nil).Send), arg0) +} + +// SendHeader mocks base method +func (m *MockBeaconService_ValidatorAssignmentsServer) SendHeader(arg0 metadata.MD) error { + ret := m.ctrl.Call(m, "SendHeader", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendHeader indicates an expected call of SendHeader +func (mr *MockBeaconService_ValidatorAssignmentsServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsServer)(nil).SendHeader), arg0) +} + +// SendMsg mocks base method +func (m *MockBeaconService_ValidatorAssignmentsServer) SendMsg(arg0 interface{}) error { + ret := m.ctrl.Call(m, "SendMsg", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendMsg indicates an expected call of SendMsg +func (mr *MockBeaconService_ValidatorAssignmentsServerMockRecorder) SendMsg(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsServer)(nil).SendMsg), arg0) +} + +// SetHeader mocks base method +func (m *MockBeaconService_ValidatorAssignmentsServer) SetHeader(arg0 metadata.MD) error { + ret := m.ctrl.Call(m, "SetHeader", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetHeader indicates an expected call of SetHeader +func (mr *MockBeaconService_ValidatorAssignmentsServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsServer)(nil).SetHeader), arg0) +} + +// SetTrailer mocks base method +func (m *MockBeaconService_ValidatorAssignmentsServer) SetTrailer(arg0 metadata.MD) { + m.ctrl.Call(m, "SetTrailer", arg0) +} + +// SetTrailer indicates an expected call of SetTrailer +func (mr *MockBeaconService_ValidatorAssignmentsServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsServer)(nil).SetTrailer), arg0) +} diff --git a/beacon-chain/internal/validator_service_mock.go b/beacon-chain/internal/validator_service_mock.go new file mode 100644 index 0000000000..5ae1c5fea1 --- /dev/null +++ b/beacon-chain/internal/validator_service_mock.go @@ -0,0 +1,74 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: ValidatorServiceServer) + +package internal + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + v1 "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1" +) + +// MockValidatorServiceServer is a mock of ValidatorServiceServer interface +type MockValidatorServiceServer struct { + ctrl *gomock.Controller + recorder *MockValidatorServiceServerMockRecorder +} + +// MockValidatorServiceServerMockRecorder is the mock recorder for MockValidatorServiceServer +type MockValidatorServiceServerMockRecorder struct { + mock *MockValidatorServiceServer +} + +// NewMockValidatorServiceServer creates a new mock instance +func NewMockValidatorServiceServer(ctrl *gomock.Controller) *MockValidatorServiceServer { + mock := &MockValidatorServiceServer{ctrl: ctrl} + mock.recorder = &MockValidatorServiceServerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockValidatorServiceServer) EXPECT() *MockValidatorServiceServerMockRecorder { + return m.recorder +} + +// ValidatorIndex mocks base method +func (m *MockValidatorServiceServer) ValidatorIndex(arg0 context.Context, arg1 *v1.PublicKey) (*v1.IndexResponse, error) { + ret := m.ctrl.Call(m, "ValidatorIndex", arg0, arg1) + ret0, _ := ret[0].(*v1.IndexResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ValidatorIndex indicates an expected call of ValidatorIndex +func (mr *MockValidatorServiceServerMockRecorder) ValidatorIndex(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorIndex", reflect.TypeOf((*MockValidatorServiceServer)(nil).ValidatorIndex), arg0, arg1) +} + +// ValidatorShardID mocks base method +func (m *MockValidatorServiceServer) ValidatorShardID(arg0 context.Context, arg1 *v1.PublicKey) (*v1.ShardIDResponse, error) { + ret := m.ctrl.Call(m, "ValidatorShardID", arg0, arg1) + ret0, _ := ret[0].(*v1.ShardIDResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ValidatorShardID indicates an expected call of ValidatorShardID +func (mr *MockValidatorServiceServerMockRecorder) ValidatorShardID(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorShardID", reflect.TypeOf((*MockValidatorServiceServer)(nil).ValidatorShardID), arg0, arg1) +} + +// ValidatorSlotAndResponsibility mocks base method +func (m *MockValidatorServiceServer) ValidatorSlotAndResponsibility(arg0 context.Context, arg1 *v1.PublicKey) (*v1.SlotResponsibilityResponse, error) { + ret := m.ctrl.Call(m, "ValidatorSlotAndResponsibility", arg0, arg1) + ret0, _ := ret[0].(*v1.SlotResponsibilityResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ValidatorSlotAndResponsibility indicates an expected call of ValidatorSlotAndResponsibility +func (mr *MockValidatorServiceServerMockRecorder) ValidatorSlotAndResponsibility(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorSlotAndResponsibility", reflect.TypeOf((*MockValidatorServiceServer)(nil).ValidatorSlotAndResponsibility), arg0, arg1) +} diff --git a/beacon-chain/params/config.go b/beacon-chain/params/config.go index 10f4f47d52..6cf6eb21ff 100644 --- a/beacon-chain/params/config.go +++ b/beacon-chain/params/config.go @@ -3,9 +3,12 @@ package params import ( "math/big" + "time" ) var ( + // GenesisTime used by the protocol. + GenesisTime = time.Date(2018, 9, 0, 0, 0, 0, 0, time.UTC) // September 2018 // CycleLength is the beacon chain cycle length in slots. CycleLength = uint64(64) // ShardCount is a fixed number. diff --git a/beacon-chain/rpc/BUILD.bazel b/beacon-chain/rpc/BUILD.bazel index 99129898b2..506a2043f6 100644 --- a/beacon-chain/rpc/BUILD.bazel +++ b/beacon-chain/rpc/BUILD.bazel @@ -7,11 +7,13 @@ go_library( visibility = ["//beacon-chain:__subpackages__"], deps = [ "//beacon-chain/casper:go_default_library", + "//beacon-chain/params:go_default_library", "//beacon-chain/types:go_default_library", "//proto/beacon/p2p/v1:go_default_library", "//proto/beacon/rpc/v1:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//event:go_default_library", + "@com_github_golang_protobuf//ptypes:go_default_library_gen", "@com_github_sirupsen_logrus//:go_default_library", "@io_bazel_rules_go//proto/wkt:empty_go_proto", "@org_golang_google_grpc//:go_default_library", diff --git a/beacon-chain/rpc/service.go b/beacon-chain/rpc/service.go index 9b658f43b8..1517ba84a8 100644 --- a/beacon-chain/rpc/service.go +++ b/beacon-chain/rpc/service.go @@ -3,13 +3,17 @@ package rpc import ( "context" + "errors" "fmt" "net" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/event" + "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/empty" "github.com/prysmaticlabs/prysm/beacon-chain/casper" + "github.com/prysmaticlabs/prysm/beacon-chain/params" "github.com/prysmaticlabs/prysm/beacon-chain/types" pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1" @@ -53,21 +57,22 @@ type powChainService interface { // Service defining an RPC server for a beacon node. type Service struct { - ctx context.Context - cancel context.CancelFunc - fetcher canonicalFetcher - chainService chainService - powChainService powChainService - attestationService attestationService - port string - listener net.Listener - withCert string - withKey string - grpcServer *grpc.Server - canonicalBlockChan chan *types.Block - canonicalStateChan chan *types.CrystallizedState - incomingAttestation chan *types.Attestation - devMode bool + ctx context.Context + cancel context.CancelFunc + fetcher canonicalFetcher + chainService chainService + powChainService powChainService + attestationService attestationService + port string + listener net.Listener + withCert string + withKey string + grpcServer *grpc.Server + canonicalBlockChan chan *types.Block + canonicalStateChan chan *types.CrystallizedState + incomingAttestation chan *types.Attestation + devMode bool + slotAlignmentDuration time.Duration } // Config options for the beacon node RPC server. @@ -88,19 +93,20 @@ type Config struct { func NewRPCService(ctx context.Context, cfg *Config) *Service { ctx, cancel := context.WithCancel(ctx) return &Service{ - ctx: ctx, - cancel: cancel, - fetcher: cfg.CanonicalFetcher, - chainService: cfg.ChainService, - powChainService: cfg.POWChainService, - attestationService: cfg.AttestationService, - port: cfg.Port, - withCert: cfg.CertFlag, - withKey: cfg.KeyFlag, - canonicalBlockChan: make(chan *types.Block, cfg.SubscriptionBuf), - canonicalStateChan: make(chan *types.CrystallizedState, cfg.SubscriptionBuf), - incomingAttestation: make(chan *types.Attestation, cfg.SubscriptionBuf), - devMode: cfg.DevMode, + ctx: ctx, + cancel: cancel, + fetcher: cfg.CanonicalFetcher, + chainService: cfg.ChainService, + powChainService: cfg.POWChainService, + attestationService: cfg.AttestationService, + port: cfg.Port, + withCert: cfg.CertFlag, + withKey: cfg.KeyFlag, + slotAlignmentDuration: time.Duration(params.SlotDuration) * time.Second, + canonicalBlockChan: make(chan *types.Block, cfg.SubscriptionBuf), + canonicalStateChan: make(chan *types.CrystallizedState, cfg.SubscriptionBuf), + incomingAttestation: make(chan *types.Attestation, cfg.SubscriptionBuf), + devMode: cfg.DevMode, } } @@ -128,7 +134,9 @@ func (s *Service) Start() { } pb.RegisterBeaconServiceServer(s.grpcServer, s) + pb.RegisterValidatorServiceServer(s.grpcServer, s) pb.RegisterProposerServiceServer(s.grpcServer, s) + pb.RegisterAttesterServiceServer(s.grpcServer, s) go func() { err = s.grpcServer.Serve(lis) if err != nil { @@ -158,16 +166,41 @@ func (s *Service) CanonicalHead(ctx context.Context, req *empty.Empty) (*pbp2p.B return block.Proto(), nil } -// GenesisTimeAndCanonicalState returns the genesis timestamp and crystallized state -// determined as canonical. Validator clients send this request -// once upon establishing a connection to the beacon node in order to determine -// their role and assigned slot initially and setup an internal ticker. -func (s *Service) GenesisTimeAndCanonicalState(ctx context.Context, req *empty.Empty) (*pb.GenesisTimeAndStateResponse, error) { - genesis := types.NewGenesisBlock([32]byte{}, [32]byte{}) - crystallized := s.fetcher.CanonicalCrystallizedState() - return &pb.GenesisTimeAndStateResponse{ - GenesisTimestamp: genesis.Proto().GetTimestamp(), - LatestCrystallizedState: crystallized.Proto(), +// CurrentAssignmentsAndGenesisTime returns the current validator assignments +// based on the beacon node's current, canonical crystallized state. +// Validator clients send this request once upon establishing a connection +// to the beacon node in order to determine their role and assigned slot +// initially. This method also returns the genesis timestamp +// of the beacon node which will allow a validator client to setup a +// a ticker to keep track of the current beacon slot. +func (s *Service) CurrentAssignmentsAndGenesisTime(ctx context.Context, req *pb.ValidatorAssignmentRequest) (*pb.CurrentAssignmentsResponse, error) { + // This error is safe to ignore as we are initializing a proto timestamp + // from a constant value (genesis time is constant in the protocol + // and defined in the params package). + // #nosec G104 + protoGenesis, _ := ptypes.TimestampProto(params.GenesisTime) + cState := s.chainService.CurrentCrystallizedState() + + var keys []*pb.PublicKey + if req.AllValidators { + for _, val := range cState.Validators() { + keys = append(keys, &pb.PublicKey{PublicKey: val.GetPublicKey()}) + } + } else { + keys = req.GetPublicKeys() + if len(keys) == 0 { + return nil, errors.New("no public keys specified in request") + } + } + + assignments, err := assignmentsForPublicKeys(keys, cState) + if err != nil { + return nil, fmt.Errorf("could not get assignments for public keys: %v", err) + } + + return &pb.CurrentAssignmentsResponse{ + GenesisTimestamp: protoGenesis, + Assignments: assignments, }, nil } @@ -212,17 +245,16 @@ func (s *Service) AttestHead(ctx context.Context, req *pb.AttestRequest) (*pb.At return &pb.AttestResponse{AttestationHash: h[:]}, nil } -// LatestCrystallizedState streams the latest beacon crystallized state. -func (s *Service) LatestCrystallizedState(req *empty.Empty, stream pb.BeaconService_LatestCrystallizedStateServer) error { - // Right now, this streams every newly created crystallized state but should only - // stream canonical states. - sub := s.fetcher.CanonicalCrystallizedStateFeed().Subscribe(s.canonicalStateChan) +// LatestAttestation streams the latest processed attestations to the rpc clients. +func (s *Service) LatestAttestation(req *empty.Empty, stream pb.BeaconService_LatestAttestationServer) error { + sub := s.attestationService.IncomingAttestationFeed().Subscribe(s.incomingAttestation) defer sub.Unsubscribe() + for { select { - case state := <-s.canonicalStateChan: - log.Info("Sending crystallized state to RPC clients") - if err := stream.Send(state.Proto()); err != nil { + case attestation := <-s.incomingAttestation: + log.Info("Sending attestation to RPC clients") + if err := stream.Send(attestation.Proto()); err != nil { return err } case <-sub.Err(): @@ -235,12 +267,6 @@ func (s *Service) LatestCrystallizedState(req *empty.Empty, stream pb.BeaconServ } } -// ValidatorAssignment streams validator assignments every slot to clients that request -// to watch a subset of public keys in the CrystallizedState's active validator set. -func (s *Service) ValidatorAssignment(req *pb.ValidatorAssignmentRequest, stream pb.ValidatorService_ValidatorAssignmentServer) error { - return nil -} - // ValidatorShardID is called by a validator to get the shard ID of where it's suppose // to proposer or attest. func (s *Service) ValidatorShardID(ctx context.Context, req *pb.PublicKey) (*pb.ShardIDResponse, error) { @@ -271,7 +297,7 @@ func (s *Service) ValidatorSlotAndResponsibility(ctx context.Context, req *pb.Pu cState.ShardAndCommitteesForSlots(), ) if err != nil { - return nil, fmt.Errorf("could not get validator slot for attester/propose: %v", err) + return nil, fmt.Errorf("could not get assigned validator slot for attester/proposer: %v", err) } var role pb.ValidatorRole @@ -301,16 +327,44 @@ func (s *Service) ValidatorIndex(ctx context.Context, req *pb.PublicKey) (*pb.In return &pb.IndexResponse{Index: index}, nil } -// LatestAttestation streams the latest processed attestations to the rpc clients. -func (s *Service) LatestAttestation(req *empty.Empty, stream pb.BeaconService_LatestAttestationServer) error { - sub := s.attestationService.IncomingAttestationFeed().Subscribe(s.incomingAttestation) +// ValidatorAssignments streams validator assignments every cycle transition +// to clients that request to watch a subset of public keys in the +// CrystallizedState's active validator set. +func (s *Service) ValidatorAssignments( + req *pb.ValidatorAssignmentRequest, + stream pb.BeaconService_ValidatorAssignmentsServer) error { + sub := s.fetcher.CanonicalCrystallizedStateFeed().Subscribe(s.canonicalStateChan) defer sub.Unsubscribe() - for { select { - case attestation := <-s.incomingAttestation: - log.Info("Sending attestation to RPC clients") - if err := stream.Send(attestation.Proto()); err != nil { + case cState := <-s.canonicalStateChan: + + log.Info("Sending new cycle assignments to validator clients") + + var keys []*pb.PublicKey + if req.AllValidators { + for _, val := range cState.Validators() { + keys = append(keys, &pb.PublicKey{PublicKey: val.GetPublicKey()}) + } + } else { + keys = req.GetPublicKeys() + if len(keys) == 0 { + return errors.New("no public keys specified in request") + } + } + + assignments, err := assignmentsForPublicKeys(keys, cState) + if err != nil { + return fmt.Errorf("could not get assignments for public keys: %v", err) + } + + // We create a response consisting of all the assignments for each + // corresponding, valid public key in the request. We also include + // the beacon node's current beacon slot in the response. + res := &pb.ValidatorAssignmentResponse{ + Assignments: assignments, + } + if err := stream.Send(res); err != nil { return err } case <-sub.Err(): @@ -322,3 +376,52 @@ func (s *Service) LatestAttestation(req *empty.Empty, stream pb.BeaconService_La } } } + +// assignmentsForPublicKeys fetches the validator assignments for a subset of public keys +// given a crystallized state. +func assignmentsForPublicKeys(keys []*pb.PublicKey, cState *types.CrystallizedState) ([]*pb.Assignment, error) { + // Next, for each public key in the request, we build + // up an array of assignments. + assignments := []*pb.Assignment{} + for _, val := range keys { + // For the corresponding public key and current crystallized state, + // we determine the assigned slot for the validator and whether it + // should act as a proposer or attester. + assignedSlot, responsibility, err := casper.ValidatorSlotAndResponsibility( + val.GetPublicKey(), + cState.CurrentDynasty(), + cState.Validators(), + cState.ShardAndCommitteesForSlots(), + ) + if err != nil { + return nil, err + } + + var role pb.ValidatorRole + if responsibility == "proposer" { + role = pb.ValidatorRole_PROPOSER + } else { + role = pb.ValidatorRole_ATTESTER + } + + // We determine the assigned shard ID for the validator + // based on a public key and current crystallized state. + shardID, err := casper.ValidatorShardID( + val.GetPublicKey(), + cState.CurrentDynasty(), + cState.Validators(), + cState.ShardAndCommitteesForSlots(), + ) + if err != nil { + return nil, err + } + + assignments = append(assignments, &pb.Assignment{ + PublicKey: val, + ShardId: shardID, + Role: role, + AssignedSlot: assignedSlot, + }) + } + return assignments, nil +} diff --git a/beacon-chain/rpc/service_test.go b/beacon-chain/rpc/service_test.go index 83ca243fb4..73bd47031c 100644 --- a/beacon-chain/rpc/service_test.go +++ b/beacon-chain/rpc/service_test.go @@ -181,7 +181,7 @@ func TestCanonicalHead(t *testing.T) { } } -func TestGenesisTimeAndCanonicalState(t *testing.T) { +func TestCurrentAssignmentsAndGenesisTime(t *testing.T) { mockChain := &mockChainService{} rpcService := NewRPCService(context.Background(), &Config{ Port: "6372", @@ -189,9 +189,16 @@ func TestGenesisTimeAndCanonicalState(t *testing.T) { ChainService: mockChain, POWChainService: &mockPOWChainService{}, }) - res, err := rpcService.GenesisTimeAndCanonicalState(context.Background(), &empty.Empty{}) + + key := &pb.PublicKey{PublicKey: []byte{}} + publicKeys := []*pb.PublicKey{key} + req := &pb.ValidatorAssignmentRequest{ + PublicKeys: publicKeys, + } + + res, err := rpcService.CurrentAssignmentsAndGenesisTime(context.Background(), req) if err != nil { - t.Errorf("Could not call GenesisTimeAndCanonicalState correctly: %v", err) + t.Errorf("Could not call CurrentAssignments correctly: %v", err) } genesis := types.NewGenesisBlock([32]byte{}, [32]byte{}) if res.GenesisTimestamp.String() != genesis.Proto().GetTimestamp().String() { @@ -217,69 +224,6 @@ func TestProposeBlock(t *testing.T) { } } -func TestLatestCrystallizedStateContextClosed(t *testing.T) { - hook := logTest.NewGlobal() - cs := newMockChainService() - rpcService := NewRPCService(context.Background(), &Config{ - Port: "8777", - SubscriptionBuf: 0, - CanonicalFetcher: cs, - }) - exitRoutine := make(chan bool) - ctrl := gomock.NewController(t) - defer ctrl.Finish() - mockStream := internal.NewMockBeaconService_LatestCrystallizedStateServer(ctrl) - go func(tt *testing.T) { - if err := rpcService.LatestCrystallizedState(&empty.Empty{}, mockStream); err != nil { - tt.Errorf("Could not call RPC method: %v", err) - } - <-exitRoutine - }(t) - rpcService.cancel() - exitRoutine <- true - testutil.AssertLogsContain(t, hook, "RPC context closed, exiting goroutine") -} - -func TestLatestCrystallizedState(t *testing.T) { - hook := logTest.NewGlobal() - cs := newMockChainService() - rpcService := NewRPCService(context.Background(), &Config{ - Port: "8773", - SubscriptionBuf: 0, - CanonicalFetcher: cs, - }) - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - exitRoutine := make(chan bool) - - mockStream := internal.NewMockBeaconService_LatestCrystallizedStateServer(ctrl) - mockStream.EXPECT().Send(&pbp2p.CrystallizedState{}).Return(errors.New("something wrong")) - // Tests a faulty stream. - go func(tt *testing.T) { - if err := rpcService.LatestCrystallizedState(&empty.Empty{}, mockStream); err.Error() != "something wrong" { - tt.Errorf("Faulty stream should throw correct error, wanted 'something wrong', got %v", err) - } - <-exitRoutine - }(t) - rpcService.canonicalStateChan <- types.NewCrystallizedState(&pbp2p.CrystallizedState{}) - - mockStream = internal.NewMockBeaconService_LatestCrystallizedStateServer(ctrl) - mockStream.EXPECT().Send(&pbp2p.CrystallizedState{}).Return(nil) - - // Tests a good stream. - go func(tt *testing.T) { - if err := rpcService.LatestCrystallizedState(&empty.Empty{}, mockStream); err != nil { - tt.Errorf("Could not call RPC method: %v", err) - } - <-exitRoutine - }(t) - rpcService.canonicalStateChan <- types.NewCrystallizedState(&pbp2p.CrystallizedState{}) - testutil.AssertLogsContain(t, hook, "Sending crystallized state to RPC clients") - rpcService.cancel() - exitRoutine <- true -} - func TestAttestHead(t *testing.T) { mockChain := &mockChainService{} mockAttestationService := &mockAttestationService{} @@ -303,7 +247,11 @@ func TestAttestHead(t *testing.T) { func TestLatestAttestationContextClosed(t *testing.T) { hook := logTest.NewGlobal() mockAttestationService := &mockAttestationService{} - rpcService := NewRPCService(context.Background(), &Config{Port: "8777", SubscriptionBuf: 0, AttestationService: mockAttestationService}) + rpcService := NewRPCService(context.Background(), &Config{ + Port: "8777", + SubscriptionBuf: 0, + AttestationService: mockAttestationService, + }) exitRoutine := make(chan bool) ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -322,7 +270,11 @@ func TestLatestAttestationContextClosed(t *testing.T) { func TestLatestAttestation(t *testing.T) { hook := logTest.NewGlobal() attestationService := &mockAttestationService{} - rpcService := NewRPCService(context.Background(), &Config{Port: "8777", SubscriptionBuf: 0, AttestationService: attestationService}) + rpcService := NewRPCService(context.Background(), &Config{ + Port: "8777", + SubscriptionBuf: 0, + AttestationService: attestationService, + }) ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -398,3 +350,46 @@ func TestValidatorShardID(t *testing.T) { t.Errorf("Could not get validator shard ID: %v", err) } } + +func TestValidatorAssignments(t *testing.T) { + hook := logTest.NewGlobal() + + mockChain := newMockChainService() + rpcService := NewRPCService(context.Background(), &Config{ + Port: "6372", + ChainService: mockChain, + CanonicalFetcher: mockChain, + }) + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockStream := internal.NewMockBeaconService_ValidatorAssignmentsServer(ctrl) + mockStream.EXPECT().Send(gomock.Any()).Return(nil) + + key := &pb.PublicKey{PublicKey: []byte{}} + publicKeys := []*pb.PublicKey{key} + req := &pb.ValidatorAssignmentRequest{ + PublicKeys: publicKeys, + } + + exitRoutine := make(chan bool) + + // Tests a validator assignment stream. + go func(tt *testing.T) { + if err := rpcService.ValidatorAssignments(req, mockStream); err != nil { + tt.Errorf("Could not stream validators: %v", err) + } + <-exitRoutine + }(t) + + genesisState, err := types.NewGenesisCrystallizedState() + if err != nil { + t.Fatal(err) + } + + rpcService.canonicalStateChan <- genesisState + rpcService.cancel() + exitRoutine <- true + testutil.AssertLogsContain(t, hook, "Sending new cycle assignments to validator clients") +} diff --git a/beacon-chain/types/block.go b/beacon-chain/types/block.go index 1147cb03d5..3517843fa8 100644 --- a/beacon-chain/types/block.go +++ b/beacon-chain/types/block.go @@ -19,8 +19,6 @@ import ( var log = logrus.WithField("prefix", "types") -// GenesisTime used by the protocol. -var GenesisTime = time.Date(2018, 9, 0, 0, 0, 0, 0, time.UTC) // September 2018 var clock utils.Clock = &utils.RealClock{} // Block defines a beacon chain core primitive. @@ -55,7 +53,7 @@ func NewBlock(data *pb.BeaconBlock) *Block { func NewGenesisBlock(activeStateHash [32]byte, crystallizedStateHash [32]byte) *Block { // Genesis time here is static so error can be safely ignored. // #nosec G104 - protoGenesis, _ := ptypes.TimestampProto(GenesisTime) + protoGenesis, _ := ptypes.TimestampProto(params.GenesisTime) gb := NewBlock(nil) gb.data.Timestamp = protoGenesis @@ -142,7 +140,7 @@ func (b *Block) Timestamp() (time.Time, error) { // isSlotValid compares the slot to the system clock to determine if the block is valid. func (b *Block) isSlotValid() bool { slotDuration := time.Duration(b.SlotNumber()*params.SlotDuration) * time.Second - validTimeThreshold := GenesisTime.Add(slotDuration) + validTimeThreshold := params.GenesisTime.Add(slotDuration) return clock.Now().After(validTimeThreshold) } diff --git a/beacon-chain/types/block_test.go b/beacon-chain/types/block_test.go index 4bc279f629..b665aa58d2 100644 --- a/beacon-chain/types/block_test.go +++ b/beacon-chain/types/block_test.go @@ -28,7 +28,7 @@ func TestGenesisBlock(t *testing.T) { // We ensure that initializing a proto timestamp from // genesis time will lead to no error. - if _, err := ptypes.TimestampProto(GenesisTime); err != nil { + if _, err := ptypes.TimestampProto(params.GenesisTime); err != nil { t.Errorf("could not create proto timestamp, expected no error: %v", err) } diff --git a/beacon-chain/utils/clock.go b/beacon-chain/utils/clock.go index 1ed5633314..2d91334b34 100644 --- a/beacon-chain/utils/clock.go +++ b/beacon-chain/utils/clock.go @@ -1,7 +1,10 @@ package utils import ( + "math" "time" + + "github.com/prysmaticlabs/prysm/beacon-chain/params" ) // Clock represents a time providing interface that can be mocked for testing. @@ -16,3 +19,19 @@ type RealClock struct{} func (RealClock) Now() time.Time { return time.Now() } + +// CurrentBeaconSlot based on the seconds since genesis. +func CurrentBeaconSlot() uint64 { + secondsSinceGenesis := time.Since(params.GenesisTime).Seconds() + return uint64(math.Floor(secondsSinceGenesis / 8.0)) +} + +// BlockingWait sleeps until a specific time is reached after +// a certain duration. For example, if the genesis block +// was at 12:00:00PM and the current time is 12:00:03PM, +// we want the next slot to tick at 12:00:08PM so we can use +// this helper method to achieve that purpose. +func BlockingWait(duration time.Duration) { + d := time.Until(time.Now().Add(duration).Truncate(duration)) + time.Sleep(d) +} diff --git a/beacon-chain/utils/clock_test.go b/beacon-chain/utils/clock_test.go index a07c2a8b16..6e022d308a 100644 --- a/beacon-chain/utils/clock_test.go +++ b/beacon-chain/utils/clock_test.go @@ -13,4 +13,6 @@ func TestRealClockIsAccurate(t *testing.T) { if clockTime != actualTime { t.Errorf("The time from the Clock interface should equal the actual time. Got: %v, Expected: %v", clockTime, actualTime) } + BlockingWait(0) + CurrentBeaconSlot() } diff --git a/proto/beacon/rpc/v1/services.pb.go b/proto/beacon/rpc/v1/services.pb.go index e1bd9076b2..4d920c4f02 100755 --- a/proto/beacon/rpc/v1/services.pb.go +++ b/proto/beacon/rpc/v1/services.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: proto/beacon/rpc/v1/services.proto -package v1 +package ethereum_beacon_rpc_v1 import proto "github.com/golang/protobuf/proto" import fmt "fmt" @@ -49,62 +49,16 @@ func (x ValidatorRole) String() string { return proto.EnumName(ValidatorRole_name, int32(x)) } func (ValidatorRole) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{0} -} - -type GenesisTimeAndStateResponse struct { - GenesisTimestamp *timestamp.Timestamp `protobuf:"bytes,1,opt,name=genesis_timestamp,json=genesisTimestamp" json:"genesis_timestamp,omitempty"` - LatestCrystallizedState *v1.CrystallizedState `protobuf:"bytes,2,opt,name=latest_crystallized_state,json=latestCrystallizedState" json:"latest_crystallized_state,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GenesisTimeAndStateResponse) Reset() { *m = GenesisTimeAndStateResponse{} } -func (m *GenesisTimeAndStateResponse) String() string { return proto.CompactTextString(m) } -func (*GenesisTimeAndStateResponse) ProtoMessage() {} -func (*GenesisTimeAndStateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{0} -} -func (m *GenesisTimeAndStateResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GenesisTimeAndStateResponse.Unmarshal(m, b) -} -func (m *GenesisTimeAndStateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GenesisTimeAndStateResponse.Marshal(b, m, deterministic) -} -func (dst *GenesisTimeAndStateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenesisTimeAndStateResponse.Merge(dst, src) -} -func (m *GenesisTimeAndStateResponse) XXX_Size() int { - return xxx_messageInfo_GenesisTimeAndStateResponse.Size(m) -} -func (m *GenesisTimeAndStateResponse) XXX_DiscardUnknown() { - xxx_messageInfo_GenesisTimeAndStateResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_GenesisTimeAndStateResponse proto.InternalMessageInfo - -func (m *GenesisTimeAndStateResponse) GetGenesisTimestamp() *timestamp.Timestamp { - if m != nil { - return m.GenesisTimestamp - } - return nil -} - -func (m *GenesisTimeAndStateResponse) GetLatestCrystallizedState() *v1.CrystallizedState { - if m != nil { - return m.LatestCrystallizedState - } - return nil + return fileDescriptor_services_54e1be11fa7a94d4, []int{0} } type ProposeRequest struct { ParentHash []byte `protobuf:"bytes,1,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"` - SlotNumber uint64 `protobuf:"varint,2,opt,name=slot_number,json=slotNumber" json:"slot_number,omitempty"` + SlotNumber uint64 `protobuf:"varint,2,opt,name=slot_number,json=slotNumber,proto3" json:"slot_number,omitempty"` RandaoReveal []byte `protobuf:"bytes,3,opt,name=randao_reveal,json=randaoReveal,proto3" json:"randao_reveal,omitempty"` AttestationBitmask []byte `protobuf:"bytes,4,opt,name=attestation_bitmask,json=attestationBitmask,proto3" json:"attestation_bitmask,omitempty"` - AttestationAggregateSig []uint32 `protobuf:"varint,5,rep,packed,name=attestation_aggregate_sig,json=attestationAggregateSig" json:"attestation_aggregate_sig,omitempty"` - Timestamp *timestamp.Timestamp `protobuf:"bytes,6,opt,name=timestamp" json:"timestamp,omitempty"` + AttestationAggregateSig []uint32 `protobuf:"varint,5,rep,packed,name=attestation_aggregate_sig,json=attestationAggregateSig,proto3" json:"attestation_aggregate_sig,omitempty"` + Timestamp *timestamp.Timestamp `protobuf:"bytes,6,opt,name=timestamp,proto3" json:"timestamp,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -114,7 +68,7 @@ func (m *ProposeRequest) Reset() { *m = ProposeRequest{} } func (m *ProposeRequest) String() string { return proto.CompactTextString(m) } func (*ProposeRequest) ProtoMessage() {} func (*ProposeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{1} + return fileDescriptor_services_54e1be11fa7a94d4, []int{0} } func (m *ProposeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ProposeRequest.Unmarshal(m, b) @@ -187,7 +141,7 @@ func (m *ProposeResponse) Reset() { *m = ProposeResponse{} } func (m *ProposeResponse) String() string { return proto.CompactTextString(m) } func (*ProposeResponse) ProtoMessage() {} func (*ProposeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{2} + return fileDescriptor_services_54e1be11fa7a94d4, []int{1} } func (m *ProposeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ProposeResponse.Unmarshal(m, b) @@ -215,7 +169,7 @@ func (m *ProposeResponse) GetBlockHash() []byte { } type AttestRequest struct { - Attestation *v1.AggregatedAttestation `protobuf:"bytes,1,opt,name=attestation" json:"attestation,omitempty"` + Attestation *v1.AggregatedAttestation `protobuf:"bytes,1,opt,name=attestation,proto3" json:"attestation,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -225,7 +179,7 @@ func (m *AttestRequest) Reset() { *m = AttestRequest{} } func (m *AttestRequest) String() string { return proto.CompactTextString(m) } func (*AttestRequest) ProtoMessage() {} func (*AttestRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{3} + return fileDescriptor_services_54e1be11fa7a94d4, []int{2} } func (m *AttestRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AttestRequest.Unmarshal(m, b) @@ -263,7 +217,7 @@ func (m *AttestResponse) Reset() { *m = AttestResponse{} } func (m *AttestResponse) String() string { return proto.CompactTextString(m) } func (*AttestResponse) ProtoMessage() {} func (*AttestResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{4} + return fileDescriptor_services_54e1be11fa7a94d4, []int{3} } func (m *AttestResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AttestResponse.Unmarshal(m, b) @@ -290,9 +244,11 @@ func (m *AttestResponse) GetAttestationHash() []byte { return nil } +// Request assignment updates for either all validators or a subset of validators +// defined by their public keys. type ValidatorAssignmentRequest struct { - AllValidators bool `protobuf:"varint,1,opt,name=all_validators,json=allValidators" json:"all_validators,omitempty"` - PublicKeys []*PublicKey `protobuf:"bytes,2,rep,name=public_keys,json=publicKeys" json:"public_keys,omitempty"` + AllValidators bool `protobuf:"varint,1,opt,name=all_validators,json=allValidators,proto3" json:"all_validators,omitempty"` + PublicKeys []*PublicKey `protobuf:"bytes,2,rep,name=public_keys,json=publicKeys,proto3" json:"public_keys,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -302,7 +258,7 @@ func (m *ValidatorAssignmentRequest) Reset() { *m = ValidatorAssignmentR func (m *ValidatorAssignmentRequest) String() string { return proto.CompactTextString(m) } func (*ValidatorAssignmentRequest) ProtoMessage() {} func (*ValidatorAssignmentRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{5} + return fileDescriptor_services_54e1be11fa7a94d4, []int{4} } func (m *ValidatorAssignmentRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ValidatorAssignmentRequest.Unmarshal(m, b) @@ -337,18 +293,17 @@ func (m *ValidatorAssignmentRequest) GetPublicKeys() []*PublicKey { } type ValidatorAssignmentResponse struct { - Assignments []*ValidatorAssignmentResponse_Assignment `protobuf:"bytes,1,rep,name=assignments" json:"assignments,omitempty"` - Slot uint64 `protobuf:"varint,2,opt,name=slot" json:"slot,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Assignments []*Assignment `protobuf:"bytes,1,rep,name=assignments,proto3" json:"assignments,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ValidatorAssignmentResponse) Reset() { *m = ValidatorAssignmentResponse{} } func (m *ValidatorAssignmentResponse) String() string { return proto.CompactTextString(m) } func (*ValidatorAssignmentResponse) ProtoMessage() {} func (*ValidatorAssignmentResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{6} + return fileDescriptor_services_54e1be11fa7a94d4, []int{5} } func (m *ValidatorAssignmentResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ValidatorAssignmentResponse.Unmarshal(m, b) @@ -368,76 +323,76 @@ func (m *ValidatorAssignmentResponse) XXX_DiscardUnknown() { var xxx_messageInfo_ValidatorAssignmentResponse proto.InternalMessageInfo -func (m *ValidatorAssignmentResponse) GetAssignments() []*ValidatorAssignmentResponse_Assignment { +func (m *ValidatorAssignmentResponse) GetAssignments() []*Assignment { if m != nil { return m.Assignments } return nil } -func (m *ValidatorAssignmentResponse) GetSlot() uint64 { - if m != nil { - return m.Slot - } - return 0 -} - -type ValidatorAssignmentResponse_Assignment struct { - PublicKey *PublicKey `protobuf:"bytes,1,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` - ShardId uint64 `protobuf:"varint,2,opt,name=shard_id,json=shardId" json:"shard_id,omitempty"` - Role ValidatorRole `protobuf:"varint,3,opt,name=role,enum=ethereum.beacon.rpc.v1.ValidatorRole" json:"role,omitempty"` +// Assignment defines a validator's assignment responsibilities. +type Assignment struct { + PublicKey *PublicKey `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + ShardId uint64 `protobuf:"varint,2,opt,name=shard_id,json=shardId,proto3" json:"shard_id,omitempty"` + Role ValidatorRole `protobuf:"varint,3,opt,name=role,proto3,enum=ethereum.beacon.rpc.v1.ValidatorRole" json:"role,omitempty"` + AssignedSlot uint64 `protobuf:"varint,4,opt,name=assigned_slot,json=assignedSlot,proto3" json:"assigned_slot,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } -func (m *ValidatorAssignmentResponse_Assignment) Reset() { - *m = ValidatorAssignmentResponse_Assignment{} +func (m *Assignment) Reset() { *m = Assignment{} } +func (m *Assignment) String() string { return proto.CompactTextString(m) } +func (*Assignment) ProtoMessage() {} +func (*Assignment) Descriptor() ([]byte, []int) { + return fileDescriptor_services_54e1be11fa7a94d4, []int{6} } -func (m *ValidatorAssignmentResponse_Assignment) String() string { return proto.CompactTextString(m) } -func (*ValidatorAssignmentResponse_Assignment) ProtoMessage() {} -func (*ValidatorAssignmentResponse_Assignment) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{6, 0} +func (m *Assignment) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Assignment.Unmarshal(m, b) } -func (m *ValidatorAssignmentResponse_Assignment) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ValidatorAssignmentResponse_Assignment.Unmarshal(m, b) +func (m *Assignment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Assignment.Marshal(b, m, deterministic) } -func (m *ValidatorAssignmentResponse_Assignment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ValidatorAssignmentResponse_Assignment.Marshal(b, m, deterministic) +func (dst *Assignment) XXX_Merge(src proto.Message) { + xxx_messageInfo_Assignment.Merge(dst, src) } -func (dst *ValidatorAssignmentResponse_Assignment) XXX_Merge(src proto.Message) { - xxx_messageInfo_ValidatorAssignmentResponse_Assignment.Merge(dst, src) +func (m *Assignment) XXX_Size() int { + return xxx_messageInfo_Assignment.Size(m) } -func (m *ValidatorAssignmentResponse_Assignment) XXX_Size() int { - return xxx_messageInfo_ValidatorAssignmentResponse_Assignment.Size(m) -} -func (m *ValidatorAssignmentResponse_Assignment) XXX_DiscardUnknown() { - xxx_messageInfo_ValidatorAssignmentResponse_Assignment.DiscardUnknown(m) +func (m *Assignment) XXX_DiscardUnknown() { + xxx_messageInfo_Assignment.DiscardUnknown(m) } -var xxx_messageInfo_ValidatorAssignmentResponse_Assignment proto.InternalMessageInfo +var xxx_messageInfo_Assignment proto.InternalMessageInfo -func (m *ValidatorAssignmentResponse_Assignment) GetPublicKey() *PublicKey { +func (m *Assignment) GetPublicKey() *PublicKey { if m != nil { return m.PublicKey } return nil } -func (m *ValidatorAssignmentResponse_Assignment) GetShardId() uint64 { +func (m *Assignment) GetShardId() uint64 { if m != nil { return m.ShardId } return 0 } -func (m *ValidatorAssignmentResponse_Assignment) GetRole() ValidatorRole { +func (m *Assignment) GetRole() ValidatorRole { if m != nil { return m.Role } return ValidatorRole_UNKNOWN } +func (m *Assignment) GetAssignedSlot() uint64 { + if m != nil { + return m.AssignedSlot + } + return 0 +} + type PublicKey struct { PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -449,7 +404,7 @@ func (m *PublicKey) Reset() { *m = PublicKey{} } func (m *PublicKey) String() string { return proto.CompactTextString(m) } func (*PublicKey) ProtoMessage() {} func (*PublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{7} + return fileDescriptor_services_54e1be11fa7a94d4, []int{7} } func (m *PublicKey) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PublicKey.Unmarshal(m, b) @@ -477,8 +432,8 @@ func (m *PublicKey) GetPublicKey() []byte { } type SlotResponsibilityResponse struct { - Slot uint64 `protobuf:"varint,1,opt,name=slot" json:"slot,omitempty"` - Role ValidatorRole `protobuf:"varint,2,opt,name=role,enum=ethereum.beacon.rpc.v1.ValidatorRole" json:"role,omitempty"` + Slot uint64 `protobuf:"varint,1,opt,name=slot,proto3" json:"slot,omitempty"` + Role ValidatorRole `protobuf:"varint,2,opt,name=role,proto3,enum=ethereum.beacon.rpc.v1.ValidatorRole" json:"role,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -488,7 +443,7 @@ func (m *SlotResponsibilityResponse) Reset() { *m = SlotResponsibilityRe func (m *SlotResponsibilityResponse) String() string { return proto.CompactTextString(m) } func (*SlotResponsibilityResponse) ProtoMessage() {} func (*SlotResponsibilityResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{8} + return fileDescriptor_services_54e1be11fa7a94d4, []int{8} } func (m *SlotResponsibilityResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlotResponsibilityResponse.Unmarshal(m, b) @@ -523,7 +478,7 @@ func (m *SlotResponsibilityResponse) GetRole() ValidatorRole { } type IndexResponse struct { - Index uint32 `protobuf:"varint,1,opt,name=index" json:"index,omitempty"` + Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -533,7 +488,7 @@ func (m *IndexResponse) Reset() { *m = IndexResponse{} } func (m *IndexResponse) String() string { return proto.CompactTextString(m) } func (*IndexResponse) ProtoMessage() {} func (*IndexResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{9} + return fileDescriptor_services_54e1be11fa7a94d4, []int{9} } func (m *IndexResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IndexResponse.Unmarshal(m, b) @@ -561,7 +516,7 @@ func (m *IndexResponse) GetIndex() uint32 { } type ShardIDResponse struct { - ShardId uint64 `protobuf:"varint,1,opt,name=shard_id,json=shardId" json:"shard_id,omitempty"` + ShardId uint64 `protobuf:"varint,1,opt,name=shard_id,json=shardId,proto3" json:"shard_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -571,7 +526,7 @@ func (m *ShardIDResponse) Reset() { *m = ShardIDResponse{} } func (m *ShardIDResponse) String() string { return proto.CompactTextString(m) } func (*ShardIDResponse) ProtoMessage() {} func (*ShardIDResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_services_2816c48a21556662, []int{10} + return fileDescriptor_services_54e1be11fa7a94d4, []int{10} } func (m *ShardIDResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardIDResponse.Unmarshal(m, b) @@ -598,19 +553,65 @@ func (m *ShardIDResponse) GetShardId() uint64 { return 0 } +type CurrentAssignmentsResponse struct { + Assignments []*Assignment `protobuf:"bytes,1,rep,name=assignments,proto3" json:"assignments,omitempty"` + GenesisTimestamp *timestamp.Timestamp `protobuf:"bytes,2,opt,name=genesis_timestamp,json=genesisTimestamp,proto3" json:"genesis_timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CurrentAssignmentsResponse) Reset() { *m = CurrentAssignmentsResponse{} } +func (m *CurrentAssignmentsResponse) String() string { return proto.CompactTextString(m) } +func (*CurrentAssignmentsResponse) ProtoMessage() {} +func (*CurrentAssignmentsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_services_54e1be11fa7a94d4, []int{11} +} +func (m *CurrentAssignmentsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CurrentAssignmentsResponse.Unmarshal(m, b) +} +func (m *CurrentAssignmentsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CurrentAssignmentsResponse.Marshal(b, m, deterministic) +} +func (dst *CurrentAssignmentsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CurrentAssignmentsResponse.Merge(dst, src) +} +func (m *CurrentAssignmentsResponse) XXX_Size() int { + return xxx_messageInfo_CurrentAssignmentsResponse.Size(m) +} +func (m *CurrentAssignmentsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CurrentAssignmentsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CurrentAssignmentsResponse proto.InternalMessageInfo + +func (m *CurrentAssignmentsResponse) GetAssignments() []*Assignment { + if m != nil { + return m.Assignments + } + return nil +} + +func (m *CurrentAssignmentsResponse) GetGenesisTimestamp() *timestamp.Timestamp { + if m != nil { + return m.GenesisTimestamp + } + return nil +} + func init() { - proto.RegisterType((*GenesisTimeAndStateResponse)(nil), "ethereum.beacon.rpc.v1.GenesisTimeAndStateResponse") proto.RegisterType((*ProposeRequest)(nil), "ethereum.beacon.rpc.v1.ProposeRequest") proto.RegisterType((*ProposeResponse)(nil), "ethereum.beacon.rpc.v1.ProposeResponse") proto.RegisterType((*AttestRequest)(nil), "ethereum.beacon.rpc.v1.AttestRequest") proto.RegisterType((*AttestResponse)(nil), "ethereum.beacon.rpc.v1.AttestResponse") proto.RegisterType((*ValidatorAssignmentRequest)(nil), "ethereum.beacon.rpc.v1.ValidatorAssignmentRequest") proto.RegisterType((*ValidatorAssignmentResponse)(nil), "ethereum.beacon.rpc.v1.ValidatorAssignmentResponse") - proto.RegisterType((*ValidatorAssignmentResponse_Assignment)(nil), "ethereum.beacon.rpc.v1.ValidatorAssignmentResponse.Assignment") + proto.RegisterType((*Assignment)(nil), "ethereum.beacon.rpc.v1.Assignment") proto.RegisterType((*PublicKey)(nil), "ethereum.beacon.rpc.v1.PublicKey") proto.RegisterType((*SlotResponsibilityResponse)(nil), "ethereum.beacon.rpc.v1.SlotResponsibilityResponse") proto.RegisterType((*IndexResponse)(nil), "ethereum.beacon.rpc.v1.IndexResponse") proto.RegisterType((*ShardIDResponse)(nil), "ethereum.beacon.rpc.v1.ShardIDResponse") + proto.RegisterType((*CurrentAssignmentsResponse)(nil), "ethereum.beacon.rpc.v1.CurrentAssignmentsResponse") proto.RegisterEnum("ethereum.beacon.rpc.v1.ValidatorRole", ValidatorRole_name, ValidatorRole_value) } @@ -622,13 +623,23 @@ var _ grpc.ClientConn // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 -// Client API for BeaconService service - +// BeaconServiceClient is the client API for BeaconService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type BeaconServiceClient interface { - GenesisTimeAndCanonicalState(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*GenesisTimeAndStateResponse, error) + // CanonicalHead can be called on demand to fetch the current, head block of a + // beacon node. CanonicalHead(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*v1.BeaconBlock, error) - LatestCrystallizedState(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestCrystallizedStateClient, error) + // LatestAttestation streams the latest aggregated attestation to connected + // validator clients. LatestAttestation(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestAttestationClient, error) + // CurrentAssignmentsAndGenesisTime is called by a validator client upon first connecting + // to a beacon node in order to determine the current validator assignments + // and genesis timestamp of the protocol. + CurrentAssignmentsAndGenesisTime(ctx context.Context, in *ValidatorAssignmentRequest, opts ...grpc.CallOption) (*CurrentAssignmentsResponse, error) + // ValidatorAssignments streams validator assignments to clients + // for a subset of public keys in the active validator set. + ValidatorAssignments(ctx context.Context, in *ValidatorAssignmentRequest, opts ...grpc.CallOption) (BeaconService_ValidatorAssignmentsClient, error) } type beaconServiceClient struct { @@ -639,58 +650,17 @@ func NewBeaconServiceClient(cc *grpc.ClientConn) BeaconServiceClient { return &beaconServiceClient{cc} } -func (c *beaconServiceClient) GenesisTimeAndCanonicalState(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*GenesisTimeAndStateResponse, error) { - out := new(GenesisTimeAndStateResponse) - err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.BeaconService/GenesisTimeAndCanonicalState", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *beaconServiceClient) CanonicalHead(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*v1.BeaconBlock, error) { out := new(v1.BeaconBlock) - err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.BeaconService/CanonicalHead", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.BeaconService/CanonicalHead", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *beaconServiceClient) LatestCrystallizedState(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestCrystallizedStateClient, error) { - stream, err := grpc.NewClientStream(ctx, &_BeaconService_serviceDesc.Streams[0], c.cc, "/ethereum.beacon.rpc.v1.BeaconService/LatestCrystallizedState", opts...) - if err != nil { - return nil, err - } - x := &beaconServiceLatestCrystallizedStateClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type BeaconService_LatestCrystallizedStateClient interface { - Recv() (*v1.CrystallizedState, error) - grpc.ClientStream -} - -type beaconServiceLatestCrystallizedStateClient struct { - grpc.ClientStream -} - -func (x *beaconServiceLatestCrystallizedStateClient) Recv() (*v1.CrystallizedState, error) { - m := new(v1.CrystallizedState) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - func (c *beaconServiceClient) LatestAttestation(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestAttestationClient, error) { - stream, err := grpc.NewClientStream(ctx, &_BeaconService_serviceDesc.Streams[1], c.cc, "/ethereum.beacon.rpc.v1.BeaconService/LatestAttestation", opts...) + stream, err := c.cc.NewStream(ctx, &_BeaconService_serviceDesc.Streams[0], "/ethereum.beacon.rpc.v1.BeaconService/LatestAttestation", opts...) if err != nil { return nil, err } @@ -721,37 +691,68 @@ func (x *beaconServiceLatestAttestationClient) Recv() (*v1.AggregatedAttestation return m, nil } -// Server API for BeaconService service +func (c *beaconServiceClient) CurrentAssignmentsAndGenesisTime(ctx context.Context, in *ValidatorAssignmentRequest, opts ...grpc.CallOption) (*CurrentAssignmentsResponse, error) { + out := new(CurrentAssignmentsResponse) + err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.BeaconService/CurrentAssignmentsAndGenesisTime", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} +func (c *beaconServiceClient) ValidatorAssignments(ctx context.Context, in *ValidatorAssignmentRequest, opts ...grpc.CallOption) (BeaconService_ValidatorAssignmentsClient, error) { + stream, err := c.cc.NewStream(ctx, &_BeaconService_serviceDesc.Streams[1], "/ethereum.beacon.rpc.v1.BeaconService/ValidatorAssignments", opts...) + if err != nil { + return nil, err + } + x := &beaconServiceValidatorAssignmentsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type BeaconService_ValidatorAssignmentsClient interface { + Recv() (*ValidatorAssignmentResponse, error) + grpc.ClientStream +} + +type beaconServiceValidatorAssignmentsClient struct { + grpc.ClientStream +} + +func (x *beaconServiceValidatorAssignmentsClient) Recv() (*ValidatorAssignmentResponse, error) { + m := new(ValidatorAssignmentResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// BeaconServiceServer is the server API for BeaconService service. type BeaconServiceServer interface { - GenesisTimeAndCanonicalState(context.Context, *empty.Empty) (*GenesisTimeAndStateResponse, error) + // CanonicalHead can be called on demand to fetch the current, head block of a + // beacon node. CanonicalHead(context.Context, *empty.Empty) (*v1.BeaconBlock, error) - LatestCrystallizedState(*empty.Empty, BeaconService_LatestCrystallizedStateServer) error + // LatestAttestation streams the latest aggregated attestation to connected + // validator clients. LatestAttestation(*empty.Empty, BeaconService_LatestAttestationServer) error + // CurrentAssignmentsAndGenesisTime is called by a validator client upon first connecting + // to a beacon node in order to determine the current validator assignments + // and genesis timestamp of the protocol. + CurrentAssignmentsAndGenesisTime(context.Context, *ValidatorAssignmentRequest) (*CurrentAssignmentsResponse, error) + // ValidatorAssignments streams validator assignments to clients + // for a subset of public keys in the active validator set. + ValidatorAssignments(*ValidatorAssignmentRequest, BeaconService_ValidatorAssignmentsServer) error } func RegisterBeaconServiceServer(s *grpc.Server, srv BeaconServiceServer) { s.RegisterService(&_BeaconService_serviceDesc, srv) } -func _BeaconService_GenesisTimeAndCanonicalState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(empty.Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(BeaconServiceServer).GenesisTimeAndCanonicalState(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ethereum.beacon.rpc.v1.BeaconService/GenesisTimeAndCanonicalState", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BeaconServiceServer).GenesisTimeAndCanonicalState(ctx, req.(*empty.Empty)) - } - return interceptor(ctx, in, info, handler) -} - func _BeaconService_CanonicalHead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(empty.Empty) if err := dec(in); err != nil { @@ -770,27 +771,6 @@ func _BeaconService_CanonicalHead_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } -func _BeaconService_LatestCrystallizedState_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(empty.Empty) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(BeaconServiceServer).LatestCrystallizedState(m, &beaconServiceLatestCrystallizedStateServer{stream}) -} - -type BeaconService_LatestCrystallizedStateServer interface { - Send(*v1.CrystallizedState) error - grpc.ServerStream -} - -type beaconServiceLatestCrystallizedStateServer struct { - grpc.ServerStream -} - -func (x *beaconServiceLatestCrystallizedStateServer) Send(m *v1.CrystallizedState) error { - return x.ServerStream.SendMsg(m) -} - func _BeaconService_LatestAttestation_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(empty.Empty) if err := stream.RecvMsg(m); err != nil { @@ -812,36 +792,76 @@ func (x *beaconServiceLatestAttestationServer) Send(m *v1.AggregatedAttestation) return x.ServerStream.SendMsg(m) } +func _BeaconService_CurrentAssignmentsAndGenesisTime_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ValidatorAssignmentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BeaconServiceServer).CurrentAssignmentsAndGenesisTime(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ethereum.beacon.rpc.v1.BeaconService/CurrentAssignmentsAndGenesisTime", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BeaconServiceServer).CurrentAssignmentsAndGenesisTime(ctx, req.(*ValidatorAssignmentRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _BeaconService_ValidatorAssignments_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(ValidatorAssignmentRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(BeaconServiceServer).ValidatorAssignments(m, &beaconServiceValidatorAssignmentsServer{stream}) +} + +type BeaconService_ValidatorAssignmentsServer interface { + Send(*ValidatorAssignmentResponse) error + grpc.ServerStream +} + +type beaconServiceValidatorAssignmentsServer struct { + grpc.ServerStream +} + +func (x *beaconServiceValidatorAssignmentsServer) Send(m *ValidatorAssignmentResponse) error { + return x.ServerStream.SendMsg(m) +} + var _BeaconService_serviceDesc = grpc.ServiceDesc{ ServiceName: "ethereum.beacon.rpc.v1.BeaconService", HandlerType: (*BeaconServiceServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "GenesisTimeAndCanonicalState", - Handler: _BeaconService_GenesisTimeAndCanonicalState_Handler, - }, { MethodName: "CanonicalHead", Handler: _BeaconService_CanonicalHead_Handler, }, + { + MethodName: "CurrentAssignmentsAndGenesisTime", + Handler: _BeaconService_CurrentAssignmentsAndGenesisTime_Handler, + }, }, Streams: []grpc.StreamDesc{ { - StreamName: "LatestCrystallizedState", - Handler: _BeaconService_LatestCrystallizedState_Handler, + StreamName: "LatestAttestation", + Handler: _BeaconService_LatestAttestation_Handler, ServerStreams: true, }, { - StreamName: "LatestAttestation", - Handler: _BeaconService_LatestAttestation_Handler, + StreamName: "ValidatorAssignments", + Handler: _BeaconService_ValidatorAssignments_Handler, ServerStreams: true, }, }, Metadata: "proto/beacon/rpc/v1/services.proto", } -// Client API for AttesterService service - +// AttesterServiceClient is the client API for AttesterService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type AttesterServiceClient interface { AttestHead(ctx context.Context, in *AttestRequest, opts ...grpc.CallOption) (*AttestResponse, error) } @@ -856,15 +876,14 @@ func NewAttesterServiceClient(cc *grpc.ClientConn) AttesterServiceClient { func (c *attesterServiceClient) AttestHead(ctx context.Context, in *AttestRequest, opts ...grpc.CallOption) (*AttestResponse, error) { out := new(AttestResponse) - err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.AttesterService/AttestHead", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.AttesterService/AttestHead", in, out, opts...) if err != nil { return nil, err } return out, nil } -// Server API for AttesterService service - +// AttesterServiceServer is the server API for AttesterService service. type AttesterServiceServer interface { AttestHead(context.Context, *AttestRequest) (*AttestResponse, error) } @@ -904,8 +923,9 @@ var _AttesterService_serviceDesc = grpc.ServiceDesc{ Metadata: "proto/beacon/rpc/v1/services.proto", } -// Client API for ProposerService service - +// ProposerServiceClient is the client API for ProposerService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ProposerServiceClient interface { ProposeBlock(ctx context.Context, in *ProposeRequest, opts ...grpc.CallOption) (*ProposeResponse, error) } @@ -920,15 +940,14 @@ func NewProposerServiceClient(cc *grpc.ClientConn) ProposerServiceClient { func (c *proposerServiceClient) ProposeBlock(ctx context.Context, in *ProposeRequest, opts ...grpc.CallOption) (*ProposeResponse, error) { out := new(ProposeResponse) - err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ProposerService/ProposeBlock", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ProposerService/ProposeBlock", in, out, opts...) if err != nil { return nil, err } return out, nil } -// Server API for ProposerService service - +// ProposerServiceServer is the server API for ProposerService service. type ProposerServiceServer interface { ProposeBlock(context.Context, *ProposeRequest) (*ProposeResponse, error) } @@ -968,13 +987,15 @@ var _ProposerService_serviceDesc = grpc.ServiceDesc{ Metadata: "proto/beacon/rpc/v1/services.proto", } -// Client API for ValidatorService service - +// ValidatorServiceClient is the client API for ValidatorService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ValidatorServiceClient interface { + // These endpoints can be called on demand in the future + // by some web3 API for users to conveniently know their assignment. ValidatorShardID(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*ShardIDResponse, error) ValidatorIndex(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*IndexResponse, error) ValidatorSlotAndResponsibility(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*SlotResponsibilityResponse, error) - ValidatorAssignment(ctx context.Context, in *ValidatorAssignmentRequest, opts ...grpc.CallOption) (ValidatorService_ValidatorAssignmentClient, error) } type validatorServiceClient struct { @@ -987,7 +1008,7 @@ func NewValidatorServiceClient(cc *grpc.ClientConn) ValidatorServiceClient { func (c *validatorServiceClient) ValidatorShardID(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*ShardIDResponse, error) { out := new(ShardIDResponse) - err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorShardID", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorShardID", in, out, opts...) if err != nil { return nil, err } @@ -996,7 +1017,7 @@ func (c *validatorServiceClient) ValidatorShardID(ctx context.Context, in *Publi func (c *validatorServiceClient) ValidatorIndex(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*IndexResponse, error) { out := new(IndexResponse) - err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorIndex", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorIndex", in, out, opts...) if err != nil { return nil, err } @@ -1005,52 +1026,20 @@ func (c *validatorServiceClient) ValidatorIndex(ctx context.Context, in *PublicK func (c *validatorServiceClient) ValidatorSlotAndResponsibility(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*SlotResponsibilityResponse, error) { out := new(SlotResponsibilityResponse) - err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorSlotAndResponsibility", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorSlotAndResponsibility", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *validatorServiceClient) ValidatorAssignment(ctx context.Context, in *ValidatorAssignmentRequest, opts ...grpc.CallOption) (ValidatorService_ValidatorAssignmentClient, error) { - stream, err := grpc.NewClientStream(ctx, &_ValidatorService_serviceDesc.Streams[0], c.cc, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorAssignment", opts...) - if err != nil { - return nil, err - } - x := &validatorServiceValidatorAssignmentClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type ValidatorService_ValidatorAssignmentClient interface { - Recv() (*ValidatorAssignmentResponse, error) - grpc.ClientStream -} - -type validatorServiceValidatorAssignmentClient struct { - grpc.ClientStream -} - -func (x *validatorServiceValidatorAssignmentClient) Recv() (*ValidatorAssignmentResponse, error) { - m := new(ValidatorAssignmentResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// Server API for ValidatorService service - +// ValidatorServiceServer is the server API for ValidatorService service. type ValidatorServiceServer interface { + // These endpoints can be called on demand in the future + // by some web3 API for users to conveniently know their assignment. ValidatorShardID(context.Context, *PublicKey) (*ShardIDResponse, error) ValidatorIndex(context.Context, *PublicKey) (*IndexResponse, error) ValidatorSlotAndResponsibility(context.Context, *PublicKey) (*SlotResponsibilityResponse, error) - ValidatorAssignment(*ValidatorAssignmentRequest, ValidatorService_ValidatorAssignmentServer) error } func RegisterValidatorServiceServer(s *grpc.Server, srv ValidatorServiceServer) { @@ -1111,27 +1100,6 @@ func _ValidatorService_ValidatorSlotAndResponsibility_Handler(srv interface{}, c return interceptor(ctx, in, info, handler) } -func _ValidatorService_ValidatorAssignment_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(ValidatorAssignmentRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(ValidatorServiceServer).ValidatorAssignment(m, &validatorServiceValidatorAssignmentServer{stream}) -} - -type ValidatorService_ValidatorAssignmentServer interface { - Send(*ValidatorAssignmentResponse) error - grpc.ServerStream -} - -type validatorServiceValidatorAssignmentServer struct { - grpc.ServerStream -} - -func (x *validatorServiceValidatorAssignmentServer) Send(m *ValidatorAssignmentResponse) error { - return x.ServerStream.SendMsg(m) -} - var _ValidatorService_serviceDesc = grpc.ServiceDesc{ ServiceName: "ethereum.beacon.rpc.v1.ValidatorService", HandlerType: (*ValidatorServiceServer)(nil), @@ -1149,81 +1117,73 @@ var _ValidatorService_serviceDesc = grpc.ServiceDesc{ Handler: _ValidatorService_ValidatorSlotAndResponsibility_Handler, }, }, - Streams: []grpc.StreamDesc{ - { - StreamName: "ValidatorAssignment", - Handler: _ValidatorService_ValidatorAssignment_Handler, - ServerStreams: true, - }, - }, + Streams: []grpc.StreamDesc{}, Metadata: "proto/beacon/rpc/v1/services.proto", } func init() { - proto.RegisterFile("proto/beacon/rpc/v1/services.proto", fileDescriptor_services_2816c48a21556662) + proto.RegisterFile("proto/beacon/rpc/v1/services.proto", fileDescriptor_services_54e1be11fa7a94d4) } -var fileDescriptor_services_2816c48a21556662 = []byte{ - // 963 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x72, 0xdb, 0x44, - 0x14, 0x46, 0x76, 0xda, 0x26, 0xc7, 0x3f, 0x71, 0xb7, 0x4c, 0xe3, 0x38, 0x40, 0x83, 0x3a, 0x81, - 0xb4, 0x03, 0x72, 0xa2, 0xdc, 0x14, 0x98, 0x61, 0x70, 0x4a, 0xa6, 0xed, 0xb4, 0x93, 0x64, 0x64, - 0x03, 0x33, 0xc0, 0x54, 0x5d, 0x5b, 0x07, 0x59, 0xe3, 0xd5, 0x0f, 0xda, 0xb5, 0xc1, 0x5c, 0x71, - 0x07, 0x4f, 0xc1, 0x15, 0x4f, 0xc1, 0x23, 0x30, 0xc3, 0x3b, 0x31, 0xda, 0x95, 0x64, 0x39, 0x8d, - 0xea, 0xa4, 0x77, 0xd2, 0xb7, 0xe7, 0x7c, 0xe7, 0xdb, 0x6f, 0xcf, 0x9e, 0x05, 0x3d, 0x8a, 0x43, - 0x11, 0x76, 0x87, 0x48, 0x47, 0x61, 0xd0, 0x8d, 0xa3, 0x51, 0x77, 0x76, 0xd8, 0xe5, 0x18, 0xcf, - 0xbc, 0x11, 0x72, 0x43, 0x2e, 0x92, 0xbb, 0x28, 0xc6, 0x18, 0xe3, 0xd4, 0x37, 0x54, 0x98, 0x11, - 0x47, 0x23, 0x63, 0x76, 0xd8, 0x59, 0xce, 0x8d, 0xcc, 0x28, 0xc9, 0xf5, 0x91, 0x73, 0xea, 0x66, - 0xb9, 0x9d, 0x1d, 0x37, 0x0c, 0x5d, 0x86, 0x5d, 0xf9, 0x37, 0x9c, 0xfe, 0xd4, 0x45, 0x3f, 0x12, - 0xf3, 0x74, 0xf1, 0xde, 0xc5, 0x45, 0xe1, 0xf9, 0xc8, 0x05, 0xf5, 0x23, 0x15, 0xa0, 0xff, 0xa7, - 0xc1, 0xce, 0x13, 0x0c, 0x90, 0x7b, 0x7c, 0xe0, 0xf9, 0xd8, 0x0b, 0x9c, 0xbe, 0xa0, 0x02, 0x2d, - 0xe4, 0x51, 0x18, 0x70, 0x24, 0x4f, 0xe0, 0xb6, 0xab, 0x96, 0xed, 0x3c, 0xb5, 0xad, 0xed, 0x6a, - 0xfb, 0x35, 0xb3, 0x63, 0x28, 0x72, 0x23, 0x23, 0x37, 0x06, 0x59, 0x84, 0xd5, 0x72, 0x17, 0x9c, - 0x12, 0x21, 0x08, 0xdb, 0x8c, 0x0a, 0xe4, 0xc2, 0x1e, 0xc5, 0x73, 0x2e, 0x28, 0x63, 0xde, 0x6f, - 0xe8, 0xd8, 0x3c, 0xa9, 0xd6, 0xae, 0x48, 0xc2, 0x07, 0xc6, 0x45, 0x1b, 0x22, 0x33, 0x32, 0x66, - 0x87, 0xc6, 0xe3, 0x42, 0x86, 0x92, 0xb7, 0xa5, 0xb8, 0x5e, 0x5b, 0xd0, 0xff, 0xaa, 0x40, 0xf3, - 0x3c, 0x0e, 0xa3, 0x90, 0xa3, 0x85, 0x3f, 0x4f, 0x91, 0x0b, 0x72, 0x0f, 0x6a, 0x11, 0x8d, 0x31, - 0x10, 0xf6, 0x98, 0xf2, 0xb1, 0x14, 0x5f, 0xb7, 0x40, 0x41, 0x4f, 0x29, 0x1f, 0x27, 0x01, 0x9c, - 0x85, 0xc2, 0x0e, 0xa6, 0xfe, 0x10, 0x63, 0x29, 0x66, 0xcd, 0x82, 0x04, 0x3a, 0x95, 0x08, 0xb9, - 0x0f, 0x8d, 0x98, 0x06, 0x0e, 0x0d, 0xed, 0x18, 0x67, 0x48, 0x59, 0xbb, 0x2a, 0x39, 0xea, 0x0a, - 0xb4, 0x24, 0x46, 0xba, 0x70, 0x87, 0x8a, 0x44, 0x14, 0x15, 0x5e, 0x18, 0xd8, 0x43, 0x4f, 0xf8, - 0x94, 0x4f, 0xda, 0x6b, 0x32, 0x94, 0x14, 0x96, 0x8e, 0xd5, 0x0a, 0xf9, 0x1c, 0xb6, 0x8b, 0x09, - 0xd4, 0x75, 0x63, 0x74, 0xa9, 0x40, 0x9b, 0x7b, 0x6e, 0xfb, 0xc6, 0x6e, 0x75, 0xbf, 0x61, 0x6d, - 0x15, 0x02, 0x7a, 0xd9, 0x7a, 0xdf, 0x73, 0xc9, 0x23, 0xd8, 0x58, 0x1c, 0xc7, 0xcd, 0x95, 0xc7, - 0xb1, 0x08, 0xd6, 0x0f, 0x60, 0x33, 0xf7, 0x27, 0x3d, 0xe3, 0xf7, 0x01, 0x86, 0x2c, 0x1c, 0x4d, - 0x8a, 0xfe, 0x6c, 0x48, 0x24, 0xb1, 0x47, 0x7f, 0x05, 0x8d, 0x9e, 0x94, 0x91, 0x19, 0x7a, 0x06, - 0xb5, 0x82, 0xae, 0xb4, 0x1b, 0x3e, 0x2d, 0x3b, 0xbc, 0x5c, 0xb7, 0xd3, 0x5b, 0x24, 0x59, 0x45, - 0x06, 0xfd, 0x0b, 0x68, 0x66, 0x15, 0x52, 0x49, 0x0f, 0xa0, 0x55, 0xf4, 0xa6, 0x20, 0x6c, 0xb3, - 0x80, 0x4b, 0x79, 0x7f, 0x68, 0xd0, 0xf9, 0x96, 0x32, 0xcf, 0xa1, 0x22, 0x8c, 0x7b, 0x9c, 0x7b, - 0x6e, 0xe0, 0x63, 0x90, 0x8b, 0xdd, 0x83, 0x26, 0x65, 0xcc, 0x9e, 0x65, 0x11, 0x5c, 0xf2, 0xac, - 0x5b, 0x0d, 0xca, 0x58, 0x9e, 0xc6, 0xc9, 0x31, 0xd4, 0xa2, 0xe9, 0x90, 0x79, 0x23, 0x7b, 0x82, - 0x73, 0xde, 0xae, 0xec, 0x56, 0xf7, 0x6b, 0xe6, 0x87, 0xc6, 0xe5, 0xf7, 0xd2, 0x38, 0x97, 0xa1, - 0xcf, 0x71, 0x6e, 0x41, 0x94, 0x7d, 0x72, 0xfd, 0x9f, 0x0a, 0xec, 0x5c, 0xaa, 0x24, 0xdd, 0xd4, - 0x2b, 0xa8, 0xd1, 0x1c, 0x4d, 0x74, 0x24, 0x35, 0xbe, 0x2c, 0xab, 0xf1, 0x06, 0x26, 0xa3, 0x00, - 0x15, 0x29, 0x09, 0x81, 0xb5, 0xa4, 0x6d, 0xd3, 0x16, 0x96, 0xdf, 0x9d, 0xbf, 0x35, 0x80, 0x45, - 0x3c, 0xf9, 0x0a, 0x60, 0xb1, 0xd1, 0xf4, 0xec, 0xae, 0xb0, 0xcf, 0x8d, 0x7c, 0x9f, 0x64, 0x1b, - 0xd6, 0xf9, 0x98, 0xc6, 0x8e, 0xed, 0x39, 0x69, 0xa1, 0x5b, 0xf2, 0xff, 0x99, 0x43, 0x3e, 0x83, - 0xb5, 0x38, 0x64, 0x28, 0xef, 0x47, 0xd3, 0xdc, 0x5b, 0xb9, 0x35, 0x2b, 0x64, 0x68, 0xc9, 0x14, - 0xfd, 0x21, 0x6c, 0xe4, 0xd5, 0x92, 0x8e, 0xbc, 0x20, 0xb2, 0x5e, 0x50, 0xa0, 0x4f, 0xa0, 0xd3, - 0x67, 0x61, 0x66, 0x87, 0x37, 0xf4, 0x98, 0x27, 0xe6, 0xb9, 0xcd, 0x99, 0x09, 0xda, 0xc2, 0x84, - 0x5c, 0x58, 0xe5, 0xfa, 0xc2, 0xf6, 0xa0, 0xf1, 0x2c, 0x70, 0xf0, 0xd7, 0x9c, 0xff, 0x5d, 0xb8, - 0xe1, 0x25, 0x80, 0x2c, 0xd0, 0xb0, 0xd4, 0x8f, 0xfe, 0x09, 0x6c, 0xf6, 0xa5, 0x0b, 0x5f, 0xe7, - 0x81, 0x45, 0xa3, 0xb4, 0x25, 0xa3, 0x1e, 0x3e, 0x82, 0xc6, 0x52, 0x2d, 0x52, 0x83, 0x5b, 0xdf, - 0x9c, 0x3e, 0x3f, 0x3d, 0xfb, 0xee, 0xb4, 0xf5, 0x0e, 0xa9, 0xc3, 0x7a, 0x6f, 0x30, 0x38, 0xe9, - 0x0f, 0x4e, 0xac, 0x96, 0x96, 0xfc, 0x9d, 0x5b, 0x67, 0xe7, 0x67, 0xfd, 0x13, 0xab, 0x55, 0x31, - 0xff, 0xac, 0x42, 0xe3, 0x58, 0x8a, 0xee, 0xab, 0x37, 0x84, 0x4c, 0xe0, 0xbd, 0xe5, 0x09, 0xfe, - 0x98, 0x06, 0x61, 0xe0, 0x8d, 0x28, 0x93, 0x23, 0x91, 0xdc, 0x7d, 0x6d, 0x30, 0x9c, 0x24, 0x2f, - 0x44, 0xe7, 0xa8, 0xcc, 0x85, 0x37, 0xbd, 0x07, 0x2f, 0xa0, 0x91, 0xd3, 0x3f, 0x45, 0xea, 0x94, - 0xb2, 0xdf, 0x2f, 0x9b, 0x07, 0x4a, 0xfc, 0x71, 0x32, 0x5e, 0xc8, 0x4b, 0xd8, 0x7a, 0x71, 0xf9, - 0x20, 0x2f, 0xe5, 0xbd, 0xfa, 0x23, 0x71, 0xa0, 0x91, 0x1f, 0xe1, 0xb6, 0xe2, 0x2f, 0x8c, 0x9e, - 0x52, 0xe6, 0xeb, 0x4d, 0xb0, 0x03, 0xcd, 0x0c, 0x60, 0x53, 0x01, 0x18, 0x67, 0x67, 0xf1, 0x03, - 0x80, 0x82, 0xa4, 0x37, 0xa5, 0x7d, 0xb6, 0x34, 0x4f, 0x3b, 0x1f, 0xad, 0x0a, 0x53, 0xde, 0x9b, - 0x71, 0x3e, 0xba, 0xf3, 0x7a, 0x36, 0xd4, 0x53, 0x48, 0x19, 0x5a, 0x4a, 0xb5, 0xfc, 0x26, 0x76, - 0x3e, 0x5e, 0x19, 0x97, 0xd6, 0xfc, 0xb7, 0x0a, 0xad, 0xbc, 0x53, 0xb3, 0xaa, 0x2f, 0x8b, 0x98, - 0x6a, 0x7a, 0xb2, 0x7a, 0x86, 0x94, 0x17, 0xbd, 0x78, 0x71, 0xbe, 0x87, 0x66, 0xce, 0x2f, 0xef, - 0xde, 0x55, 0xd8, 0x4b, 0xcd, 0x5e, 0xbe, 0xbd, 0xbf, 0xc0, 0x07, 0x0b, 0xed, 0x2c, 0x14, 0xbd, - 0xc0, 0x59, 0x9e, 0x23, 0x57, 0xa9, 0x65, 0x96, 0xee, 0xa4, 0x7c, 0x2c, 0xfd, 0xae, 0xc1, 0x9d, - 0x4b, 0x66, 0x3a, 0x31, 0xaf, 0xf5, 0x00, 0xa8, 0xe3, 0x3b, 0x7a, 0x8b, 0x47, 0xe3, 0x40, 0x1b, - 0xde, 0x94, 0x1d, 0x7f, 0xf4, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0x21, 0x7e, 0x87, 0x93, - 0x0a, 0x00, 0x00, +var fileDescriptor_services_54e1be11fa7a94d4 = []byte{ + // 929 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x6f, 0x6f, 0xdb, 0x44, + 0x1c, 0xc6, 0x69, 0xb6, 0xb5, 0xbf, 0xc4, 0x69, 0x76, 0x4c, 0x23, 0xf3, 0x04, 0x0b, 0x9e, 0x0a, + 0x61, 0x02, 0xa7, 0xf5, 0xde, 0x0c, 0x78, 0x43, 0xba, 0x55, 0xdb, 0xb4, 0xa9, 0xad, 0x9c, 0x02, + 0x12, 0x20, 0xcc, 0x25, 0x3e, 0x1c, 0xab, 0x8e, 0xcf, 0xdc, 0x5d, 0x02, 0x7d, 0xc9, 0x2b, 0x24, + 0x3e, 0x04, 0x5f, 0x80, 0x0f, 0x82, 0x90, 0xf8, 0x50, 0xe8, 0xce, 0xf6, 0xd9, 0x69, 0x6b, 0xd2, + 0xa2, 0xbd, 0xb3, 0x9f, 0xfb, 0xfd, 0x79, 0xee, 0xb9, 0xdf, 0x3d, 0x07, 0x76, 0xca, 0xa8, 0xa0, + 0xc3, 0x09, 0xc1, 0x53, 0x9a, 0x0c, 0x59, 0x3a, 0x1d, 0x2e, 0xf7, 0x86, 0x9c, 0xb0, 0x65, 0x34, + 0x25, 0xdc, 0x51, 0x8b, 0xe8, 0x2e, 0x11, 0x33, 0xc2, 0xc8, 0x62, 0xee, 0x64, 0x61, 0x0e, 0x4b, + 0xa7, 0xce, 0x72, 0xcf, 0x5a, 0xcd, 0x4d, 0xdd, 0x54, 0xe6, 0xce, 0x09, 0xe7, 0x38, 0x2c, 0x72, + 0xad, 0xfb, 0x21, 0xa5, 0x61, 0x4c, 0x86, 0xea, 0x6f, 0xb2, 0xf8, 0x71, 0x48, 0xe6, 0xa9, 0x38, + 0xcb, 0x17, 0x1f, 0x9c, 0x5f, 0x14, 0xd1, 0x9c, 0x70, 0x81, 0xe7, 0x69, 0x16, 0x60, 0xff, 0xd1, + 0x80, 0xce, 0x31, 0xa3, 0x29, 0xe5, 0xc4, 0x23, 0x3f, 0x2d, 0x08, 0x17, 0xe8, 0x01, 0xb4, 0x52, + 0xcc, 0x48, 0x22, 0xfc, 0x19, 0xe6, 0xb3, 0x9e, 0xd1, 0x37, 0x06, 0x6d, 0x0f, 0x32, 0xe8, 0x05, + 0xe6, 0x33, 0x19, 0xc0, 0x63, 0x2a, 0xfc, 0x64, 0x31, 0x9f, 0x10, 0xd6, 0x6b, 0xf4, 0x8d, 0x41, + 0xd3, 0x03, 0x09, 0x1d, 0x2a, 0x04, 0x3d, 0x04, 0x93, 0xe1, 0x24, 0xc0, 0xd4, 0x67, 0x64, 0x49, + 0x70, 0xdc, 0xdb, 0x50, 0x35, 0xda, 0x19, 0xe8, 0x29, 0x0c, 0x0d, 0xe1, 0x6d, 0x2c, 0x84, 0x24, + 0x23, 0x22, 0x9a, 0xf8, 0x93, 0x48, 0xcc, 0x31, 0x3f, 0xed, 0x35, 0x55, 0x28, 0xaa, 0x2c, 0xed, + 0x67, 0x2b, 0xe8, 0x33, 0xb8, 0x57, 0x4d, 0xc0, 0x61, 0xc8, 0x48, 0x88, 0x05, 0xf1, 0x79, 0x14, + 0xf6, 0x6e, 0xf4, 0x37, 0x06, 0xa6, 0xf7, 0x4e, 0x25, 0x60, 0x54, 0xac, 0x8f, 0xa3, 0x10, 0x3d, + 0x81, 0x2d, 0xbd, 0xf3, 0xde, 0xcd, 0xbe, 0x31, 0x68, 0xb9, 0x96, 0x93, 0x69, 0xe3, 0x14, 0xda, + 0x38, 0x27, 0x45, 0x84, 0x57, 0x06, 0xdb, 0xbb, 0xb0, 0xad, 0xf5, 0xe1, 0x29, 0x4d, 0x38, 0x41, + 0xef, 0x02, 0x4c, 0x62, 0x3a, 0x3d, 0xad, 0xea, 0xb3, 0xa5, 0x10, 0x29, 0x8f, 0xfd, 0x03, 0x98, + 0x23, 0x45, 0xa3, 0x10, 0xf4, 0x08, 0x5a, 0x15, 0x5e, 0x2a, 0xa1, 0xe5, 0x7e, 0xe2, 0x9c, 0x3f, + 0xf3, 0xd4, 0x4d, 0x9d, 0xe5, 0x9e, 0xa3, 0x79, 0x07, 0xa3, 0x32, 0xc9, 0xab, 0x56, 0xb0, 0x3f, + 0x87, 0x4e, 0xd1, 0x21, 0xa7, 0xf4, 0x11, 0x74, 0xab, 0xda, 0x54, 0x88, 0x6d, 0x57, 0x70, 0x45, + 0xef, 0x37, 0x03, 0xac, 0xaf, 0x70, 0x1c, 0x05, 0x58, 0x50, 0x36, 0xe2, 0x3c, 0x0a, 0x93, 0x39, + 0x49, 0x34, 0xd9, 0x1d, 0xe8, 0xe0, 0x38, 0xf6, 0x97, 0x45, 0x04, 0x57, 0x75, 0x36, 0x3d, 0x13, + 0xc7, 0xb1, 0x4e, 0xe3, 0x68, 0x1f, 0x5a, 0xe9, 0x62, 0x12, 0x47, 0x53, 0xff, 0x94, 0x9c, 0xf1, + 0x5e, 0xa3, 0xbf, 0x31, 0x68, 0xb9, 0xef, 0x3b, 0x97, 0xcf, 0xb1, 0x73, 0xac, 0x42, 0x5f, 0x91, + 0x33, 0x0f, 0xd2, 0xe2, 0x93, 0xdb, 0x53, 0xb8, 0x7f, 0x29, 0x91, 0x7c, 0x4f, 0xcf, 0xa0, 0x85, + 0x35, 0x2a, 0x69, 0xc8, 0x16, 0x76, 0x5d, 0x8b, 0x4a, 0x81, 0x6a, 0x9a, 0xfd, 0xb7, 0x01, 0x50, + 0xae, 0xa1, 0x2f, 0x00, 0x4a, 0xde, 0xf9, 0x51, 0x5c, 0x81, 0xf6, 0x96, 0xa6, 0x8d, 0xee, 0xc1, + 0x26, 0x9f, 0x61, 0x16, 0xf8, 0x51, 0x90, 0x8f, 0xfe, 0x2d, 0xf5, 0xff, 0x32, 0x40, 0x9f, 0x42, + 0x93, 0xd1, 0x98, 0xa8, 0x71, 0xef, 0xb8, 0x3b, 0x75, 0x65, 0xf5, 0xa6, 0x3d, 0x1a, 0x13, 0x4f, + 0xa5, 0xc8, 0x2b, 0x93, 0xb1, 0x26, 0x81, 0x2f, 0x6f, 0x92, 0xba, 0x07, 0x4d, 0xaf, 0x5d, 0x80, + 0xe3, 0x98, 0x0a, 0xfb, 0x11, 0x6c, 0x69, 0x4a, 0x72, 0x0a, 0xcf, 0xed, 0xa4, 0x5d, 0xa1, 0x69, + 0x9f, 0x82, 0x25, 0x73, 0x72, 0x35, 0xa3, 0x49, 0x14, 0x47, 0xe2, 0x4c, 0x6b, 0x8b, 0xa0, 0xa9, + 0xba, 0x18, 0xaa, 0x8b, 0xfa, 0xd6, 0xec, 0x1b, 0xd7, 0x66, 0x6f, 0xef, 0x80, 0xf9, 0x32, 0x09, + 0xc8, 0x2f, 0xba, 0xfe, 0x1d, 0xb8, 0x11, 0x49, 0x40, 0x35, 0x30, 0xbd, 0xec, 0xc7, 0xfe, 0x18, + 0xb6, 0xc7, 0x4a, 0xaa, 0x67, 0x3a, 0xb0, 0xaa, 0xa6, 0xb1, 0xa2, 0xa6, 0xfd, 0xa7, 0x01, 0xd6, + 0xd3, 0x05, 0x93, 0xb6, 0x53, 0x1e, 0x20, 0x7f, 0xb3, 0xe3, 0x81, 0x9e, 0xc3, 0xed, 0x90, 0x24, + 0x84, 0x47, 0xdc, 0x2f, 0x0d, 0xa2, 0xb1, 0xd6, 0x20, 0xba, 0x79, 0x92, 0x46, 0x1e, 0x3d, 0x01, + 0x73, 0x45, 0x19, 0xd4, 0x82, 0x5b, 0x5f, 0x1e, 0xbe, 0x3a, 0x3c, 0xfa, 0xfa, 0xb0, 0xfb, 0x16, + 0x6a, 0xc3, 0xe6, 0xe8, 0xe4, 0xe4, 0x60, 0x7c, 0x72, 0xe0, 0x75, 0x0d, 0xf9, 0x77, 0xec, 0x1d, + 0x1d, 0x1f, 0x8d, 0x0f, 0xbc, 0x6e, 0xc3, 0xfd, 0x67, 0x03, 0xcc, 0x7d, 0x45, 0x76, 0x9c, 0xbd, + 0x0a, 0xe8, 0x35, 0x98, 0x4f, 0x71, 0x42, 0x93, 0x68, 0x8a, 0xe3, 0x17, 0x04, 0x07, 0xe8, 0xee, + 0x05, 0x2a, 0x07, 0xd2, 0xe4, 0xad, 0x87, 0x75, 0x26, 0x92, 0xd5, 0xdb, 0x97, 0x9e, 0x84, 0xbe, + 0x83, 0xdb, 0xaf, 0xb1, 0xf4, 0x80, 0x8a, 0x9f, 0xd4, 0x56, 0xbc, 0x9e, 0x2d, 0xed, 0x1a, 0xe8, + 0x77, 0x03, 0xfa, 0x17, 0x4f, 0x69, 0x94, 0x04, 0xcf, 0x4b, 0x85, 0x90, 0xbb, 0x76, 0x98, 0x2e, + 0x18, 0x91, 0x55, 0x9b, 0xf3, 0x1f, 0x33, 0xf1, 0xab, 0x01, 0x77, 0x2e, 0x29, 0xc9, 0xff, 0x17, + 0x81, 0xc7, 0xd7, 0xca, 0xc9, 0x18, 0xec, 0x1a, 0x6e, 0x02, 0xdb, 0x99, 0x42, 0x84, 0x15, 0xe7, + 0xf9, 0x2d, 0x40, 0x06, 0xa9, 0xc3, 0xac, 0xbd, 0x59, 0x2b, 0xaf, 0x86, 0xf5, 0xc1, 0xba, 0xb0, + 0xac, 0xa3, 0xcb, 0xf4, 0x03, 0xa5, 0xfb, 0xf9, 0xd0, 0xce, 0xa1, 0x6c, 0x02, 0x6a, 0x4b, 0xad, + 0xbe, 0xfc, 0xd6, 0x87, 0x6b, 0xe3, 0xf2, 0x9e, 0x7f, 0x35, 0xa0, 0xab, 0x55, 0x28, 0xba, 0x7e, + 0x5f, 0xc5, 0xb2, 0x6b, 0x8e, 0xd6, 0x5b, 0x6b, 0x7d, 0xd3, 0xf3, 0x56, 0xf1, 0x0d, 0x74, 0x74, + 0x7d, 0xe5, 0x36, 0x57, 0xa9, 0x5e, 0x2b, 0xf6, 0xaa, 0x5f, 0xfd, 0x0c, 0xef, 0x95, 0xdc, 0x63, + 0x2a, 0x46, 0x49, 0xb0, 0xea, 0x9c, 0x57, 0xe9, 0x55, 0x3b, 0x64, 0xf5, 0x46, 0x3c, 0xb9, 0xa9, + 0xee, 0xdf, 0xe3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xd7, 0xae, 0x60, 0x87, 0x26, 0x0a, 0x00, + 0x00, } diff --git a/proto/beacon/rpc/v1/services.proto b/proto/beacon/rpc/v1/services.proto index cad51993e8..2eddd70459 100644 --- a/proto/beacon/rpc/v1/services.proto +++ b/proto/beacon/rpc/v1/services.proto @@ -7,10 +7,19 @@ import "google/protobuf/empty.proto"; import "google/protobuf/timestamp.proto"; service BeaconService { - rpc GenesisTimeAndCanonicalState(google.protobuf.Empty) returns (GenesisTimeAndStateResponse); + // CanonicalHead can be called on demand to fetch the current, head block of a + // beacon node. rpc CanonicalHead(google.protobuf.Empty) returns (ethereum.beacon.p2p.v1.BeaconBlock); - rpc LatestCrystallizedState(google.protobuf.Empty) returns (stream ethereum.beacon.p2p.v1.CrystallizedState); + // LatestAttestation streams the latest aggregated attestation to connected + // validator clients. rpc LatestAttestation(google.protobuf.Empty) returns (stream ethereum.beacon.p2p.v1.AggregatedAttestation); + // CurrentAssignmentsAndGenesisTime is called by a validator client upon first connecting + // to a beacon node in order to determine the current validator assignments + // and genesis timestamp of the protocol. + rpc CurrentAssignmentsAndGenesisTime(ValidatorAssignmentRequest) returns (CurrentAssignmentsResponse); + // ValidatorAssignments streams validator assignments to clients + // for a subset of public keys in the active validator set. + rpc ValidatorAssignments(ValidatorAssignmentRequest) returns(stream ValidatorAssignmentResponse); } service AttesterService { @@ -27,14 +36,6 @@ service ValidatorService { rpc ValidatorShardID(PublicKey) returns (ShardIDResponse); rpc ValidatorIndex(PublicKey) returns (IndexResponse); rpc ValidatorSlotAndResponsibility(PublicKey) returns (SlotResponsibilityResponse); - // This endpoint is called by all validator clients to watch for assignments - // for a subset of public keys in the active validator set. - rpc ValidatorAssignment(ValidatorAssignmentRequest) returns(stream ValidatorAssignmentResponse); -} - -message GenesisTimeAndStateResponse { - google.protobuf.Timestamp genesis_timestamp = 1; - ethereum.beacon.p2p.v1.CrystallizedState latest_crystallized_state = 2; } message ProposeRequest { @@ -67,19 +68,20 @@ message ValidatorAssignmentRequest { message ValidatorAssignmentResponse { repeated Assignment assignments = 1; - uint64 slot = 2; - - message Assignment { - PublicKey public_key = 1; - uint64 shard_id = 2; - ValidatorRole role = 3; - } } enum ValidatorRole { - UNKNOWN = 0; - ATTESTER = 1; - PROPOSER = 2; + UNKNOWN = 0; + ATTESTER = 1; + PROPOSER = 2; +} + +// Assignment defines a validator's assignment responsibilities. +message Assignment { + PublicKey public_key = 1; + uint64 shard_id = 2; + ValidatorRole role = 3; + uint64 assigned_slot = 4; } message PublicKey { @@ -98,3 +100,8 @@ message IndexResponse { message ShardIDResponse { uint64 shard_id = 1; } + +message CurrentAssignmentsResponse { + repeated Assignment assignments = 1; + google.protobuf.Timestamp genesis_timestamp = 2; +} diff --git a/validator/beacon/BUILD.bazel b/validator/beacon/BUILD.bazel index 63dd8742b5..3b5365b90f 100644 --- a/validator/beacon/BUILD.bazel +++ b/validator/beacon/BUILD.bazel @@ -6,9 +6,9 @@ go_library( importpath = "github.com/prysmaticlabs/prysm/validator/beacon", visibility = ["//validator:__subpackages__"], deps = [ - "//proto/beacon/p2p/v1:go_default_library", "//proto/beacon/rpc/v1:go_default_library", "//validator/params:go_default_library", + "//validator/utils:go_default_library", "@com_github_ethereum_go_ethereum//event:go_default_library", "@com_github_golang_protobuf//ptypes:go_default_library_gen", "@com_github_sirupsen_logrus//:go_default_library", diff --git a/validator/beacon/service.go b/validator/beacon/service.go index 9e31cf622b..071e40a927 100644 --- a/validator/beacon/service.go +++ b/validator/beacon/service.go @@ -10,9 +10,9 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/empty" - pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1" "github.com/prysmaticlabs/prysm/validator/params" + "github.com/prysmaticlabs/prysm/validator/utils" "github.com/sirupsen/logrus" ) @@ -27,13 +27,14 @@ type Service struct { ctx context.Context cancel context.CancelFunc rpcClient rpcClientService - validatorIndex int assignedSlot uint64 - responsibility string + shardID uint64 + role pb.ValidatorRole attesterAssignmentFeed *event.Feed proposerAssignmentFeed *event.Feed processedAttestationFeed *event.Feed genesisTimestamp time.Time + slotAlignmentDuration time.Duration } // NewBeaconValidator instantiates a service that interacts with a beacon node @@ -47,17 +48,18 @@ func NewBeaconValidator(ctx context.Context, rpcClient rpcClientService) *Servic attesterAssignmentFeed: new(event.Feed), proposerAssignmentFeed: new(event.Feed), processedAttestationFeed: new(event.Feed), + slotAlignmentDuration: time.Duration(params.DefaultConfig().SlotDuration) * time.Second, } } // Start the main routine for a beacon client service. func (s *Service) Start() { log.Info("Starting service") - client := s.rpcClient.BeaconServiceClient() + beaconServiceClient := s.rpcClient.BeaconServiceClient() - // First thing the validator does is request the genesis block timestamp - // and the latest, canonical crystallized state from a beacon node. From here, - // a validator can determine its assigned slot by keeping an internal + // First thing the validator does is request the current validator assignments + // for the current beacon node cycle as well as the genesis timestamp + // from the beacon node. From here, a validator can keep an internal // ticker that starts at the current slot the beacon node is in. This current slot // value is determined by taking the time differential between the genesis block // time and the current system time. @@ -65,19 +67,24 @@ func (s *Service) Start() { // Note: this does not validate the current system time against a global // NTP server, which will be important to do in production. // currently in a cycle we are supposed to participate in. - s.fetchGenesisAndCanonicalState(client) + s.fetchCurrentAssignmentsAndGenesisTime(beaconServiceClient) - // Then, we kick off a routine that uses the begins a ticker set in fetchGenesisAndCanonicalState - // to wait until the validator's assigned slot to perform proposals or attestations. - slotTicker := time.NewTicker(time.Second * time.Duration(params.DefaultConfig().SlotDuration)) - go s.waitForAssignment(slotTicker.C, client) + // Then, we kick off a routine that uses the begins a ticker based on the beacon node's + // genesis timestamp and the validator will use this slot ticker to + // determine when it is assigned to perform proposals or attestations. + // + // We block until the current time is a multiple of params.SlotDuration + // so the validator and beacon node's internal tickers are aligned. + utils.BlockingWait(s.slotAlignmentDuration) + + slotTicker := time.NewTicker(s.slotAlignmentDuration) + go s.waitForAssignment(slotTicker.C, beaconServiceClient) // We then kick off a routine that listens for streams of cycle transitions // coming from the beacon node. This will allow the validator client to recalculate - // when it has to perform its responsibilities appropriately using timestamps - // and the IndicesForSlots field inside the received crystallized state. - go s.listenForCrystallizedStates(client) - go s.listenForProcessedAttestations(client) + // when it has to perform its responsibilities. + go s.listenForCycleTransitions(beaconServiceClient) + go s.listenForProcessedAttestations(beaconServiceClient) } // Stop the main loop.. @@ -87,17 +94,11 @@ func (s *Service) Stop() error { return nil } -// CurrentBeaconSlot based on the seconds since genesis. -func (s *Service) CurrentBeaconSlot() uint64 { - secondsSinceGenesis := time.Since(s.genesisTimestamp).Seconds() - return uint64(math.Floor(secondsSinceGenesis / 8.0)) -} - -// fetchGenesisAndCanonicalState fetches both the genesis timestamp as well -// as the latest canonical crystallized state from a beacon node. This allows +// fetchCurrentAssignmentsAndGenesisTime fetches both the genesis timestamp as well +// as the current assignments for the current cycle in the beacon node. This allows // the validator to do the following: // -// (1) determine if it should act as an attester/proposer and at what slot +// (1) determine if it should act as an attester/proposer, at what slot, // and what shard // // (2) determine the seconds since genesis by using the latest crystallized @@ -106,8 +107,13 @@ func (s *Service) CurrentBeaconSlot() uint64 { // // From this, the validator client can deduce what slot interval the beacon // node is in and determine when exactly it is time to propose or attest. -func (s *Service) fetchGenesisAndCanonicalState(client pb.BeaconServiceClient) { - res, err := client.GenesisTimeAndCanonicalState(s.ctx, &empty.Empty{}) +func (s *Service) fetchCurrentAssignmentsAndGenesisTime(client pb.BeaconServiceClient) { + + // Currently fetches assignments for all validators. + req := &pb.ValidatorAssignmentRequest{ + AllValidators: true, + } + res, err := client.CurrentAssignmentsAndGenesisTime(s.ctx, req) if err != nil { // If this RPC request fails, the entire system should fatal as it is critical for // the validator to begin this way. @@ -123,9 +129,25 @@ func (s *Service) fetchGenesisAndCanonicalState(client pb.BeaconServiceClient) { s.genesisTimestamp = genesisTimestamp - crystallized := res.GetLatestCrystallizedState() - if err := s.processCrystallizedState(crystallized); err != nil { - log.Fatalf("unable to process received crystallized state: %v", err) + // Loops through the received assignments to determine which one + // corresponds to this validator client based on a matching public key. + for _, assignment := range res.GetAssignments() { + // TODO(#566): Determine assignment based on public key flag. + pubKeyProto := assignment.GetPublicKey() + if isZeroAddress(pubKeyProto.GetPublicKey()) { + s.assignedSlot = s.CurrentCycleStartSlot() + assignment.GetAssignedSlot() + s.shardID = assignment.GetShardId() + s.role = assignment.GetRole() + break + } + } + if s.role == pb.ValidatorRole_PROPOSER { + log.Infof("Assigned as PROPOSER to slot %v, shardID: %v", s.assignedSlot, s.shardID) + } else { + log.Infof("Assigned as ATTESTER to slot %v, shardID: %v", s.assignedSlot, s.shardID) + } + if s.CurrentBeaconSlot() > s.assignedSlot { + log.Info("You joined a bit too late -the current slot is greater than assigned slot in the cycle, wait until next cycle to be re-assigned") } } @@ -139,10 +161,9 @@ func (s *Service) waitForAssignment(ticker <-chan time.Time, client pb.BeaconSer case <-s.ctx.Done(): return case <-ticker: - log.WithField("slotNumber", s.CurrentBeaconSlot()).Info("New beacon node slot interval") - if s.responsibility == "proposer" && s.assignedSlot == s.CurrentBeaconSlot() { + log.WithField("slotNumber", s.CurrentBeaconSlot()).Info("New beacon node slot") + if s.role == pb.ValidatorRole_PROPOSER && s.assignedSlot == s.CurrentBeaconSlot() { log.WithField("slotNumber", s.CurrentBeaconSlot()).Info("Assigned proposal slot number reached") - s.responsibility = "" block, err := client.CanonicalHead(s.ctx, &empty.Empty{}) if err != nil { log.Errorf("Could not fetch canonical head via gRPC from beacon node: %v", err) @@ -150,9 +171,8 @@ func (s *Service) waitForAssignment(ticker <-chan time.Time, client pb.BeaconSer } // We forward the latest canonical block to the proposer service via a feed. s.proposerAssignmentFeed.Send(block) - } else if s.responsibility == "attester" && s.assignedSlot == s.CurrentBeaconSlot() { + } else if s.role == pb.ValidatorRole_ATTESTER && s.assignedSlot == s.CurrentBeaconSlot() { log.Info("Assigned attestation slot number reached") - s.responsibility = "" block, err := client.CanonicalHead(s.ctx, &empty.Empty{}) if err != nil { log.Errorf("Could not fetch canonical head via gRPC from beacon node: %v", err) @@ -165,19 +185,21 @@ func (s *Service) waitForAssignment(ticker <-chan time.Time, client pb.BeaconSer } } -// listenForCrystallizedStates receives the latest canonical crystallized state -// from the beacon node's RPC server via gRPC streams. -// TODO(#545): Rename to listen for assignment instead, which is streamed from a beacon node -// upon every new cycle transition and will include the validator's index in the -// assignment bitfield as well as the assigned shard ID. -func (s *Service) listenForCrystallizedStates(client pb.BeaconServiceClient) { - stream, err := client.LatestCrystallizedState(s.ctx, &empty.Empty{}) +// listenForCycleTransitions receives validator assignments from the +// the beacon node's RPC server when a new cycle transition occurs. +func (s *Service) listenForCycleTransitions(client pb.BeaconServiceClient) { + // Currently fetches assignments for all validators. + req := &pb.ValidatorAssignmentRequest{ + AllValidators: true, + } + stream, err := client.ValidatorAssignments(s.ctx, req) if err != nil { - log.Errorf("Could not setup crystallized beacon state streaming client: %v", err) + log.Errorf("Could not setup validator assignments streaming client: %v", err) return } for { - crystallizedState, err := stream.Recv() + res, err := stream.Recv() + // If the stream is closed, we stop the loop. if err == io.EOF { break @@ -187,56 +209,34 @@ func (s *Service) listenForCrystallizedStates(client pb.BeaconServiceClient) { log.Debugf("Context has been canceled so shutting down the loop: %v", s.ctx.Err()) break } + if err != nil { - log.Errorf("Could not receive latest crystallized beacon state from stream: %v", err) + log.Errorf("Could not receive validator assignments from stream: %v", err) continue } - if err := s.processCrystallizedState(crystallizedState); err != nil { - log.Error(err) + + log.WithField("slotNumber", s.CurrentBeaconSlot()).Info("New cycle transition") + + // Loops through the received assignments to determine which one + // corresponds to this validator client based on a matching public key. + for _, assignment := range res.GetAssignments() { + // TODO(#566): Determine assignment based on public key flag. + pubKeyProto := assignment.GetPublicKey() + if isZeroAddress(pubKeyProto.GetPublicKey()) { + s.assignedSlot = s.CurrentCycleStartSlot() + assignment.GetAssignedSlot() + s.shardID = assignment.GetShardId() + s.role = assignment.GetRole() + break + } + } + if s.role == pb.ValidatorRole_PROPOSER { + log.Infof("Assigned as PROPOSER to slot %v, shardID: %v", s.assignedSlot, s.shardID) + } else { + log.Infof("Assigned as ATTESTER to slot %v, shardID: %v", s.assignedSlot, s.shardID) } } } -// processCrystallizedState uses a received crystallized state to determine -// whether a validator is a proposer/attester and the validator's assigned slot. -func (s *Service) processCrystallizedState(crystallizedState *pbp2p.CrystallizedState) error { - var activeValidatorIndices []int - dynasty := crystallizedState.GetCurrentDynasty() - - for i, validator := range crystallizedState.GetValidators() { - if validator.StartDynasty <= dynasty && dynasty < validator.EndDynasty { - activeValidatorIndices = append(activeValidatorIndices, i) - } - } - isValidatorIndexSet := false - - // We then iteratate over the activeValidatorIndices to determine what index - // this running validator client corresponds to. - for _, val := range activeValidatorIndices { - // TODO(#258): Check the public key instead of withdrawal address. This will use BLS. - if isZeroAddress(crystallizedState.Validators[val].WithdrawalAddress) { - s.validatorIndex = val - isValidatorIndexSet = true - break - } - } - - // If validator was not found in the validator set was not set, keep listening for - // crystallized states. - if !isValidatorIndexSet { - log.Debug("Validator index not found in latest crystallized state's active validator list") - return nil - } - - // The validator needs to propose the next block. - // TODO(#545): Determine this from a gRPC stream from the beacon node - // instead. - s.responsibility = "proposer" - s.assignedSlot = s.CurrentBeaconSlot() + 2 - log.WithField("assignedSlot", s.assignedSlot).Info("Validator selected as proposer") - return nil -} - // listenForProcessedAttestations receives processed attestations from the // the beacon node's RPC server via gRPC streams. func (s *Service) listenForProcessedAttestations(client pb.BeaconServiceClient) { @@ -284,6 +284,19 @@ func (s *Service) ProcessedAttestationFeed() *event.Feed { return s.processedAttestationFeed } +// CurrentBeaconSlot based on the genesis timestamp of the protocol. +func (s *Service) CurrentBeaconSlot() uint64 { + secondsSinceGenesis := time.Since(s.genesisTimestamp).Seconds() + return uint64(math.Floor(secondsSinceGenesis / params.DefaultConfig().SlotDuration)) +} + +// CurrentCycleStartSlot returns the slot at which the current cycle started. +func (s *Service) CurrentCycleStartSlot() uint64 { + currentSlot := s.CurrentBeaconSlot() + cycleNum := math.Floor(float64(currentSlot) / float64(params.DefaultConfig().CycleLength)) + return uint64(cycleNum) * params.DefaultConfig().CycleLength +} + // isZeroAddress compares a withdrawal address to an empty byte array. func isZeroAddress(withdrawalAddress []byte) bool { return bytes.Equal(withdrawalAddress, []byte{}) diff --git a/validator/beacon/service_test.go b/validator/beacon/service_test.go index 8b706606ff..0a0e64adf2 100644 --- a/validator/beacon/service_test.go +++ b/validator/beacon/service_test.go @@ -31,8 +31,6 @@ type mockClient struct { func (fc *mockClient) BeaconServiceClient() pb.BeaconServiceClient { mockServiceClient := internal.NewMockBeaconServiceClient(fc.ctrl) - stateStream := internal.NewMockBeaconService_LatestCrystallizedStateClient(fc.ctrl) - stateStream.EXPECT().Recv().Return(&pbp2p.CrystallizedState{}, io.EOF) attesterStream := internal.NewMockBeaconService_LatestAttestationClient(fc.ctrl) attesterStream.EXPECT().Recv().Return(&pbp2p.AggregatedAttestation{}, io.EOF) @@ -41,10 +39,6 @@ func (fc *mockClient) BeaconServiceClient() pb.BeaconServiceClient { &empty.Empty{}, ).Return(attesterStream, nil) - mockServiceClient.EXPECT().LatestCrystallizedState( - gomock.Any(), - &empty.Empty{}, - ).Return(stateStream, nil) return mockServiceClient } @@ -55,28 +49,11 @@ type mockLifecycleClient struct { func (fc *mockLifecycleClient) BeaconServiceClient() pb.BeaconServiceClient { mockServiceClient := internal.NewMockBeaconServiceClient(fc.ctrl) - stateStream := internal.NewMockBeaconService_LatestCrystallizedStateClient(fc.ctrl) - stateStream.EXPECT().Recv().Return(&pbp2p.CrystallizedState{}, io.EOF) - - mockServiceClient.EXPECT().LatestCrystallizedState( - gomock.Any(), - &empty.Empty{}, - ).Return(stateStream, nil) - - validator1 := &pbp2p.ValidatorRecord{WithdrawalAddress: []byte("0x0"), StartDynasty: 1, EndDynasty: 10} - validator2 := &pbp2p.ValidatorRecord{WithdrawalAddress: []byte("0x1"), StartDynasty: 1, EndDynasty: 10} - validator3 := &pbp2p.ValidatorRecord{WithdrawalAddress: []byte{}, StartDynasty: 1, EndDynasty: 10} - crystallized := &pbp2p.CrystallizedState{ - Validators: []*pbp2p.ValidatorRecord{validator1, validator2, validator3}, - CurrentDynasty: 5, - } - - mockServiceClient.EXPECT().GenesisTimeAndCanonicalState( + mockServiceClient.EXPECT().CurrentAssignmentsAndGenesisTime( gomock.Any(), gomock.Any(), - ).Return(&pb.GenesisTimeAndStateResponse{ - LatestCrystallizedState: crystallized, - GenesisTimestamp: ptypes.TimestampNow(), + ).Return(&pb.CurrentAssignmentsResponse{ + GenesisTimestamp: ptypes.TimestampNow(), }, nil) attesterStream := internal.NewMockBeaconService_LatestAttestationClient(fc.ctrl) @@ -85,6 +62,14 @@ func (fc *mockLifecycleClient) BeaconServiceClient() pb.BeaconServiceClient { &empty.Empty{}, ).Return(attesterStream, nil) attesterStream.EXPECT().Recv().Return(&pbp2p.AggregatedAttestation{}, io.EOF) + + cycleStream := internal.NewMockBeaconService_ValidatorAssignmentsClient(fc.ctrl) + mockServiceClient.EXPECT().ValidatorAssignments( + gomock.Any(), + gomock.Any(), + ).Return(cycleStream, nil) + cycleStream.EXPECT().Recv().Return(&pb.ValidatorAssignmentResponse{}, io.EOF) + return mockServiceClient } @@ -103,6 +88,7 @@ func TestLifecycle(t *testing.T) { if b.ProcessedAttestationFeed() == nil { t.Error("ProcessedAttestationFeed empty") } + b.slotAlignmentDuration = time.Millisecond * 10 b.Start() time.Sleep(time.Millisecond * 10) testutil.AssertLogsContain(t, hook, "Starting service") @@ -139,14 +125,14 @@ func TestWaitForAssignmentProposer(t *testing.T) { <-exitRoutine }() - b.responsibility = "proposer" + b.role = pb.ValidatorRole_PROPOSER b.genesisTimestamp = time.Now() b.assignedSlot = 0 timeChan <- time.Now() b.cancel() exitRoutine <- true - testutil.AssertLogsContain(t, hook, "New beacon node slot interval") + testutil.AssertLogsContain(t, hook, "New beacon node slot") } func TestWaitForAssignmentProposerError(t *testing.T) { @@ -168,7 +154,7 @@ func TestWaitForAssignmentProposerError(t *testing.T) { <-exitRoutine }() - b.responsibility = "proposer" + b.role = pb.ValidatorRole_PROPOSER b.genesisTimestamp = time.Now() b.assignedSlot = 0 timeChan <- time.Now() @@ -197,14 +183,14 @@ func TestWaitForAssignmentAttester(t *testing.T) { <-exitRoutine }() - b.responsibility = "attester" + b.role = pb.ValidatorRole_ATTESTER b.genesisTimestamp = time.Now() b.assignedSlot = 0 timeChan <- time.Now() b.cancel() exitRoutine <- true - testutil.AssertLogsContain(t, hook, "New beacon node slot interval") + testutil.AssertLogsContain(t, hook, "New beacon node slot") } func TestWaitForAssignmentAttesterError(t *testing.T) { @@ -226,7 +212,7 @@ func TestWaitForAssignmentAttesterError(t *testing.T) { <-exitRoutine }() - b.responsibility = "attester" + b.role = pb.ValidatorRole_ATTESTER b.genesisTimestamp = time.Now() b.assignedSlot = 0 timeChan <- time.Now() @@ -236,91 +222,6 @@ func TestWaitForAssignmentAttesterError(t *testing.T) { testutil.AssertLogsContain(t, hook, "failed") } -func TestListenForCrystallizedStates(t *testing.T) { - hook := logTest.NewGlobal() - ctrl := gomock.NewController(t) - defer ctrl.Finish() - b := NewBeaconValidator(context.Background(), &mockClient{ctrl}) - - // Creating a faulty stream will trigger error. - stream := internal.NewMockBeaconService_LatestCrystallizedStateClient(ctrl) - mockServiceClient := internal.NewMockBeaconServiceClient(ctrl) - mockServiceClient.EXPECT().LatestCrystallizedState( - gomock.Any(), - gomock.Any(), - ).Return(stream, errors.New("stream creation failed")) - - b.listenForCrystallizedStates(mockServiceClient) - - testutil.AssertLogsContain(t, hook, "stream creation failed") - - // Stream recv error should trigger error log. - stream = internal.NewMockBeaconService_LatestCrystallizedStateClient(ctrl) - stream.EXPECT().Recv().Return(nil, errors.New("recv error")) - stream.EXPECT().Recv().Return(&pbp2p.CrystallizedState{}, io.EOF) - - mockServiceClient = internal.NewMockBeaconServiceClient(ctrl) - mockServiceClient.EXPECT().LatestCrystallizedState( - gomock.Any(), - gomock.Any(), - ).Return(stream, nil) - - b.listenForCrystallizedStates(mockServiceClient) - - testutil.AssertLogsContain(t, hook, "recv error") - - // If the current validator is not found within the active validators list, log a debug message. - validator := &pbp2p.ValidatorRecord{WithdrawalAddress: []byte("0x01"), StartDynasty: 1, EndDynasty: 10} - stream = internal.NewMockBeaconService_LatestCrystallizedStateClient(ctrl) - stream.EXPECT().Recv().Return(&pbp2p.CrystallizedState{Validators: []*pbp2p.ValidatorRecord{validator}, CurrentDynasty: 5}, nil) - stream.EXPECT().Recv().Return(&pbp2p.CrystallizedState{}, io.EOF) - - mockServiceClient = internal.NewMockBeaconServiceClient(ctrl) - mockServiceClient.EXPECT().LatestCrystallizedState( - gomock.Any(), - gomock.Any(), - ).Return(stream, nil) - - b.listenForCrystallizedStates(mockServiceClient) - - testutil.AssertLogsContain(t, hook, "Validator index not found in latest crystallized state's active validator list") - - // If the validator is the last index in the shuffled validator indices, it should be assigned - // to be a proposer. - validator1 := &pbp2p.ValidatorRecord{WithdrawalAddress: []byte("0x0"), StartDynasty: 1, EndDynasty: 10} - validator2 := &pbp2p.ValidatorRecord{WithdrawalAddress: []byte("0x1"), StartDynasty: 1, EndDynasty: 10} - validator3 := &pbp2p.ValidatorRecord{WithdrawalAddress: []byte{}, StartDynasty: 1, EndDynasty: 10} - stream = internal.NewMockBeaconService_LatestCrystallizedStateClient(ctrl) - stream.EXPECT().Recv().Return(&pbp2p.CrystallizedState{Validators: []*pbp2p.ValidatorRecord{validator1, validator2, validator3}, CurrentDynasty: 5}, nil) - stream.EXPECT().Recv().Return(&pbp2p.CrystallizedState{}, io.EOF) - - mockServiceClient = internal.NewMockBeaconServiceClient(ctrl) - mockServiceClient.EXPECT().LatestCrystallizedState( - gomock.Any(), - gomock.Any(), - ).Return(stream, nil) - - b.listenForCrystallizedStates(mockServiceClient) - - testutil.AssertLogsContain(t, hook, "Validator selected as proposer") - - // Test that the routine exits when context is closed - stream = internal.NewMockBeaconService_LatestCrystallizedStateClient(ctrl) - - stream.EXPECT().Recv().Return(&pbp2p.CrystallizedState{}, nil) - - mockServiceClient = internal.NewMockBeaconServiceClient(ctrl) - mockServiceClient.EXPECT().LatestCrystallizedState( - gomock.Any(), - gomock.Any(), - ).Return(stream, nil) - b.cancel() - - b.listenForCrystallizedStates(mockServiceClient) - testutil.AssertLogsContain(t, hook, "Context has been canceled so shutting down the loop") - -} - func TestListenForProcessedAttestations(t *testing.T) { hook := logTest.NewGlobal() ctrl := gomock.NewController(t) diff --git a/validator/internal/beacon_service_mock.go b/validator/internal/beacon_service_mock.go index ee38668567..c30efcebc6 100644 --- a/validator/internal/beacon_service_mock.go +++ b/validator/internal/beacon_service_mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: BeaconServiceClient,BeaconService_LatestCrystallizedStateClient,BeaconService_LatestAttestationClient) +// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: BeaconServiceClient,BeaconService_LatestAttestationClient,BeaconService_ValidatorAssignmentsClient) package internal @@ -56,22 +56,22 @@ func (mr *MockBeaconServiceClientMockRecorder) CanonicalHead(arg0, arg1 interfac return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanonicalHead", reflect.TypeOf((*MockBeaconServiceClient)(nil).CanonicalHead), varargs...) } -// GenesisTimeAndCanonicalState mocks base method -func (m *MockBeaconServiceClient) GenesisTimeAndCanonicalState(arg0 context.Context, arg1 *empty.Empty, arg2 ...grpc.CallOption) (*v10.GenesisTimeAndStateResponse, error) { +// CurrentAssignmentsAndGenesisTime mocks base method +func (m *MockBeaconServiceClient) CurrentAssignmentsAndGenesisTime(arg0 context.Context, arg1 *v10.ValidatorAssignmentRequest, arg2 ...grpc.CallOption) (*v10.CurrentAssignmentsResponse, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GenesisTimeAndCanonicalState", varargs...) - ret0, _ := ret[0].(*v10.GenesisTimeAndStateResponse) + ret := m.ctrl.Call(m, "CurrentAssignmentsAndGenesisTime", varargs...) + ret0, _ := ret[0].(*v10.CurrentAssignmentsResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// GenesisTimeAndCanonicalState indicates an expected call of GenesisTimeAndCanonicalState -func (mr *MockBeaconServiceClientMockRecorder) GenesisTimeAndCanonicalState(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// CurrentAssignmentsAndGenesisTime indicates an expected call of CurrentAssignmentsAndGenesisTime +func (mr *MockBeaconServiceClientMockRecorder) CurrentAssignmentsAndGenesisTime(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenesisTimeAndCanonicalState", reflect.TypeOf((*MockBeaconServiceClient)(nil).GenesisTimeAndCanonicalState), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentAssignmentsAndGenesisTime", reflect.TypeOf((*MockBeaconServiceClient)(nil).CurrentAssignmentsAndGenesisTime), varargs...) } // LatestAttestation mocks base method @@ -92,131 +92,22 @@ func (mr *MockBeaconServiceClientMockRecorder) LatestAttestation(arg0, arg1 inte return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatestAttestation", reflect.TypeOf((*MockBeaconServiceClient)(nil).LatestAttestation), varargs...) } -// LatestCrystallizedState mocks base method -func (m *MockBeaconServiceClient) LatestCrystallizedState(arg0 context.Context, arg1 *empty.Empty, arg2 ...grpc.CallOption) (v10.BeaconService_LatestCrystallizedStateClient, error) { +// ValidatorAssignments mocks base method +func (m *MockBeaconServiceClient) ValidatorAssignments(arg0 context.Context, arg1 *v10.ValidatorAssignmentRequest, arg2 ...grpc.CallOption) (v10.BeaconService_ValidatorAssignmentsClient, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "LatestCrystallizedState", varargs...) - ret0, _ := ret[0].(v10.BeaconService_LatestCrystallizedStateClient) + ret := m.ctrl.Call(m, "ValidatorAssignments", varargs...) + ret0, _ := ret[0].(v10.BeaconService_ValidatorAssignmentsClient) ret1, _ := ret[1].(error) return ret0, ret1 } -// LatestCrystallizedState indicates an expected call of LatestCrystallizedState -func (mr *MockBeaconServiceClientMockRecorder) LatestCrystallizedState(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// ValidatorAssignments indicates an expected call of ValidatorAssignments +func (mr *MockBeaconServiceClientMockRecorder) ValidatorAssignments(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatestCrystallizedState", reflect.TypeOf((*MockBeaconServiceClient)(nil).LatestCrystallizedState), varargs...) -} - -// MockBeaconService_LatestCrystallizedStateClient is a mock of BeaconService_LatestCrystallizedStateClient interface -type MockBeaconService_LatestCrystallizedStateClient struct { - ctrl *gomock.Controller - recorder *MockBeaconService_LatestCrystallizedStateClientMockRecorder -} - -// MockBeaconService_LatestCrystallizedStateClientMockRecorder is the mock recorder for MockBeaconService_LatestCrystallizedStateClient -type MockBeaconService_LatestCrystallizedStateClientMockRecorder struct { - mock *MockBeaconService_LatestCrystallizedStateClient -} - -// NewMockBeaconService_LatestCrystallizedStateClient creates a new mock instance -func NewMockBeaconService_LatestCrystallizedStateClient(ctrl *gomock.Controller) *MockBeaconService_LatestCrystallizedStateClient { - mock := &MockBeaconService_LatestCrystallizedStateClient{ctrl: ctrl} - mock.recorder = &MockBeaconService_LatestCrystallizedStateClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockBeaconService_LatestCrystallizedStateClient) EXPECT() *MockBeaconService_LatestCrystallizedStateClientMockRecorder { - return m.recorder -} - -// CloseSend mocks base method -func (m *MockBeaconService_LatestCrystallizedStateClient) CloseSend() error { - ret := m.ctrl.Call(m, "CloseSend") - ret0, _ := ret[0].(error) - return ret0 -} - -// CloseSend indicates an expected call of CloseSend -func (mr *MockBeaconService_LatestCrystallizedStateClientMockRecorder) CloseSend() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateClient)(nil).CloseSend)) -} - -// Context mocks base method -func (m *MockBeaconService_LatestCrystallizedStateClient) Context() context.Context { - ret := m.ctrl.Call(m, "Context") - ret0, _ := ret[0].(context.Context) - return ret0 -} - -// Context indicates an expected call of Context -func (mr *MockBeaconService_LatestCrystallizedStateClientMockRecorder) Context() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateClient)(nil).Context)) -} - -// Header mocks base method -func (m *MockBeaconService_LatestCrystallizedStateClient) Header() (metadata.MD, error) { - ret := m.ctrl.Call(m, "Header") - ret0, _ := ret[0].(metadata.MD) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Header indicates an expected call of Header -func (mr *MockBeaconService_LatestCrystallizedStateClientMockRecorder) Header() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateClient)(nil).Header)) -} - -// Recv mocks base method -func (m *MockBeaconService_LatestCrystallizedStateClient) Recv() (*v1.CrystallizedState, error) { - ret := m.ctrl.Call(m, "Recv") - ret0, _ := ret[0].(*v1.CrystallizedState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Recv indicates an expected call of Recv -func (mr *MockBeaconService_LatestCrystallizedStateClientMockRecorder) Recv() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateClient)(nil).Recv)) -} - -// RecvMsg mocks base method -func (m *MockBeaconService_LatestCrystallizedStateClient) RecvMsg(arg0 interface{}) error { - ret := m.ctrl.Call(m, "RecvMsg", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// RecvMsg indicates an expected call of RecvMsg -func (mr *MockBeaconService_LatestCrystallizedStateClientMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateClient)(nil).RecvMsg), arg0) -} - -// SendMsg mocks base method -func (m *MockBeaconService_LatestCrystallizedStateClient) SendMsg(arg0 interface{}) error { - ret := m.ctrl.Call(m, "SendMsg", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SendMsg indicates an expected call of SendMsg -func (mr *MockBeaconService_LatestCrystallizedStateClientMockRecorder) SendMsg(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateClient)(nil).SendMsg), arg0) -} - -// Trailer mocks base method -func (m *MockBeaconService_LatestCrystallizedStateClient) Trailer() metadata.MD { - ret := m.ctrl.Call(m, "Trailer") - ret0, _ := ret[0].(metadata.MD) - return ret0 -} - -// Trailer indicates an expected call of Trailer -func (mr *MockBeaconService_LatestCrystallizedStateClientMockRecorder) Trailer() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockBeaconService_LatestCrystallizedStateClient)(nil).Trailer)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorAssignments", reflect.TypeOf((*MockBeaconServiceClient)(nil).ValidatorAssignments), varargs...) } // MockBeaconService_LatestAttestationClient is a mock of BeaconService_LatestAttestationClient interface @@ -327,3 +218,112 @@ func (m *MockBeaconService_LatestAttestationClient) Trailer() metadata.MD { func (mr *MockBeaconService_LatestAttestationClientMockRecorder) Trailer() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockBeaconService_LatestAttestationClient)(nil).Trailer)) } + +// MockBeaconService_ValidatorAssignmentsClient is a mock of BeaconService_ValidatorAssignmentsClient interface +type MockBeaconService_ValidatorAssignmentsClient struct { + ctrl *gomock.Controller + recorder *MockBeaconService_ValidatorAssignmentsClientMockRecorder +} + +// MockBeaconService_ValidatorAssignmentsClientMockRecorder is the mock recorder for MockBeaconService_ValidatorAssignmentsClient +type MockBeaconService_ValidatorAssignmentsClientMockRecorder struct { + mock *MockBeaconService_ValidatorAssignmentsClient +} + +// NewMockBeaconService_ValidatorAssignmentsClient creates a new mock instance +func NewMockBeaconService_ValidatorAssignmentsClient(ctrl *gomock.Controller) *MockBeaconService_ValidatorAssignmentsClient { + mock := &MockBeaconService_ValidatorAssignmentsClient{ctrl: ctrl} + mock.recorder = &MockBeaconService_ValidatorAssignmentsClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockBeaconService_ValidatorAssignmentsClient) EXPECT() *MockBeaconService_ValidatorAssignmentsClientMockRecorder { + return m.recorder +} + +// CloseSend mocks base method +func (m *MockBeaconService_ValidatorAssignmentsClient) CloseSend() error { + ret := m.ctrl.Call(m, "CloseSend") + ret0, _ := ret[0].(error) + return ret0 +} + +// CloseSend indicates an expected call of CloseSend +func (mr *MockBeaconService_ValidatorAssignmentsClientMockRecorder) CloseSend() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsClient)(nil).CloseSend)) +} + +// Context mocks base method +func (m *MockBeaconService_ValidatorAssignmentsClient) Context() context.Context { + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(context.Context) + return ret0 +} + +// Context indicates an expected call of Context +func (mr *MockBeaconService_ValidatorAssignmentsClientMockRecorder) Context() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsClient)(nil).Context)) +} + +// Header mocks base method +func (m *MockBeaconService_ValidatorAssignmentsClient) Header() (metadata.MD, error) { + ret := m.ctrl.Call(m, "Header") + ret0, _ := ret[0].(metadata.MD) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Header indicates an expected call of Header +func (mr *MockBeaconService_ValidatorAssignmentsClientMockRecorder) Header() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsClient)(nil).Header)) +} + +// Recv mocks base method +func (m *MockBeaconService_ValidatorAssignmentsClient) Recv() (*v10.ValidatorAssignmentResponse, error) { + ret := m.ctrl.Call(m, "Recv") + ret0, _ := ret[0].(*v10.ValidatorAssignmentResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Recv indicates an expected call of Recv +func (mr *MockBeaconService_ValidatorAssignmentsClientMockRecorder) Recv() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsClient)(nil).Recv)) +} + +// RecvMsg mocks base method +func (m *MockBeaconService_ValidatorAssignmentsClient) RecvMsg(arg0 interface{}) error { + ret := m.ctrl.Call(m, "RecvMsg", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// RecvMsg indicates an expected call of RecvMsg +func (mr *MockBeaconService_ValidatorAssignmentsClientMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsClient)(nil).RecvMsg), arg0) +} + +// SendMsg mocks base method +func (m *MockBeaconService_ValidatorAssignmentsClient) SendMsg(arg0 interface{}) error { + ret := m.ctrl.Call(m, "SendMsg", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendMsg indicates an expected call of SendMsg +func (mr *MockBeaconService_ValidatorAssignmentsClientMockRecorder) SendMsg(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsClient)(nil).SendMsg), arg0) +} + +// Trailer mocks base method +func (m *MockBeaconService_ValidatorAssignmentsClient) Trailer() metadata.MD { + ret := m.ctrl.Call(m, "Trailer") + ret0, _ := ret[0].(metadata.MD) + return ret0 +} + +// Trailer indicates an expected call of Trailer +func (mr *MockBeaconService_ValidatorAssignmentsClientMockRecorder) Trailer() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockBeaconService_ValidatorAssignmentsClient)(nil).Trailer)) +} diff --git a/validator/internal/validator_service_mock.go b/validator/internal/validator_service_mock.go index 5c17e45998..b65685b0e0 100644 --- a/validator/internal/validator_service_mock.go +++ b/validator/internal/validator_service_mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: ValidatorServiceClient,ValidatorService_ValidatorAssignmentClient) +// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: ValidatorServiceClient) package internal @@ -10,7 +10,6 @@ import ( gomock "github.com/golang/mock/gomock" v1 "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1" grpc "google.golang.org/grpc" - metadata "google.golang.org/grpc/metadata" ) // MockValidatorServiceClient is a mock of ValidatorServiceClient interface @@ -36,24 +35,6 @@ func (m *MockValidatorServiceClient) EXPECT() *MockValidatorServiceClientMockRec return m.recorder } -// ValidatorAssignment mocks base method -func (m *MockValidatorServiceClient) ValidatorAssignment(arg0 context.Context, arg1 *v1.ValidatorAssignmentRequest, arg2 ...grpc.CallOption) (v1.ValidatorService_ValidatorAssignmentClient, error) { - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "ValidatorAssignment", varargs...) - ret0, _ := ret[0].(v1.ValidatorService_ValidatorAssignmentClient) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ValidatorAssignment indicates an expected call of ValidatorAssignment -func (mr *MockValidatorServiceClientMockRecorder) ValidatorAssignment(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorAssignment", reflect.TypeOf((*MockValidatorServiceClient)(nil).ValidatorAssignment), varargs...) -} - // ValidatorIndex mocks base method func (m *MockValidatorServiceClient) ValidatorIndex(arg0 context.Context, arg1 *v1.PublicKey, arg2 ...grpc.CallOption) (*v1.IndexResponse, error) { varargs := []interface{}{arg0, arg1} @@ -107,112 +88,3 @@ func (mr *MockValidatorServiceClientMockRecorder) ValidatorSlotAndResponsibility varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorSlotAndResponsibility", reflect.TypeOf((*MockValidatorServiceClient)(nil).ValidatorSlotAndResponsibility), varargs...) } - -// MockValidatorService_ValidatorAssignmentClient is a mock of ValidatorService_ValidatorAssignmentClient interface -type MockValidatorService_ValidatorAssignmentClient struct { - ctrl *gomock.Controller - recorder *MockValidatorService_ValidatorAssignmentClientMockRecorder -} - -// MockValidatorService_ValidatorAssignmentClientMockRecorder is the mock recorder for MockValidatorService_ValidatorAssignmentClient -type MockValidatorService_ValidatorAssignmentClientMockRecorder struct { - mock *MockValidatorService_ValidatorAssignmentClient -} - -// NewMockValidatorService_ValidatorAssignmentClient creates a new mock instance -func NewMockValidatorService_ValidatorAssignmentClient(ctrl *gomock.Controller) *MockValidatorService_ValidatorAssignmentClient { - mock := &MockValidatorService_ValidatorAssignmentClient{ctrl: ctrl} - mock.recorder = &MockValidatorService_ValidatorAssignmentClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockValidatorService_ValidatorAssignmentClient) EXPECT() *MockValidatorService_ValidatorAssignmentClientMockRecorder { - return m.recorder -} - -// CloseSend mocks base method -func (m *MockValidatorService_ValidatorAssignmentClient) CloseSend() error { - ret := m.ctrl.Call(m, "CloseSend") - ret0, _ := ret[0].(error) - return ret0 -} - -// CloseSend indicates an expected call of CloseSend -func (mr *MockValidatorService_ValidatorAssignmentClientMockRecorder) CloseSend() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockValidatorService_ValidatorAssignmentClient)(nil).CloseSend)) -} - -// Context mocks base method -func (m *MockValidatorService_ValidatorAssignmentClient) Context() context.Context { - ret := m.ctrl.Call(m, "Context") - ret0, _ := ret[0].(context.Context) - return ret0 -} - -// Context indicates an expected call of Context -func (mr *MockValidatorService_ValidatorAssignmentClientMockRecorder) Context() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockValidatorService_ValidatorAssignmentClient)(nil).Context)) -} - -// Header mocks base method -func (m *MockValidatorService_ValidatorAssignmentClient) Header() (metadata.MD, error) { - ret := m.ctrl.Call(m, "Header") - ret0, _ := ret[0].(metadata.MD) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Header indicates an expected call of Header -func (mr *MockValidatorService_ValidatorAssignmentClientMockRecorder) Header() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockValidatorService_ValidatorAssignmentClient)(nil).Header)) -} - -// Recv mocks base method -func (m *MockValidatorService_ValidatorAssignmentClient) Recv() (*v1.ValidatorAssignmentResponse, error) { - ret := m.ctrl.Call(m, "Recv") - ret0, _ := ret[0].(*v1.ValidatorAssignmentResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Recv indicates an expected call of Recv -func (mr *MockValidatorService_ValidatorAssignmentClientMockRecorder) Recv() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockValidatorService_ValidatorAssignmentClient)(nil).Recv)) -} - -// RecvMsg mocks base method -func (m *MockValidatorService_ValidatorAssignmentClient) RecvMsg(arg0 interface{}) error { - ret := m.ctrl.Call(m, "RecvMsg", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// RecvMsg indicates an expected call of RecvMsg -func (mr *MockValidatorService_ValidatorAssignmentClientMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockValidatorService_ValidatorAssignmentClient)(nil).RecvMsg), arg0) -} - -// SendMsg mocks base method -func (m *MockValidatorService_ValidatorAssignmentClient) SendMsg(arg0 interface{}) error { - ret := m.ctrl.Call(m, "SendMsg", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SendMsg indicates an expected call of SendMsg -func (mr *MockValidatorService_ValidatorAssignmentClientMockRecorder) SendMsg(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockValidatorService_ValidatorAssignmentClient)(nil).SendMsg), arg0) -} - -// Trailer mocks base method -func (m *MockValidatorService_ValidatorAssignmentClient) Trailer() metadata.MD { - ret := m.ctrl.Call(m, "Trailer") - ret0, _ := ret[0].(metadata.MD) - return ret0 -} - -// Trailer indicates an expected call of Trailer -func (mr *MockValidatorService_ValidatorAssignmentClientMockRecorder) Trailer() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockValidatorService_ValidatorAssignmentClient)(nil).Trailer)) -} diff --git a/validator/params/config.go b/validator/params/config.go index e8e97ec3ad..3846ec5cfa 100644 --- a/validator/params/config.go +++ b/validator/params/config.go @@ -11,7 +11,8 @@ import ( func DefaultConfig() *Config { return &Config{ CollationSizeLimit: DefaultCollationSizeLimit(), - SlotDuration: 8, + SlotDuration: 8.0, + CycleLength: 64, } } @@ -23,6 +24,7 @@ func DefaultCollationSizeLimit() int64 { // Config contains configs for node to participate in the sharded universe. type Config struct { - CollationSizeLimit int64 // CollationSizeLimit is the maximum size the serialized blobs in a collation can take. - SlotDuration int // SlotDuration in seconds. + CollationSizeLimit int64 // CollationSizeLimit is the maximum size the serialized blobs in a collation can take. + SlotDuration float64 // SlotDuration in seconds. + CycleLength uint64 } diff --git a/validator/utils/BUILD.bazel b/validator/utils/BUILD.bazel new file mode 100644 index 0000000000..465af8841a --- /dev/null +++ b/validator/utils/BUILD.bazel @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["clock.go"], + importpath = "github.com/prysmaticlabs/prysm/validator/utils", + visibility = ["//validator:__subpackages__"], +) + +go_test( + name = "go_default_test", + srcs = ["clock_test.go"], + embed = [":go_default_library"], +) diff --git a/validator/utils/clock.go b/validator/utils/clock.go new file mode 100644 index 0000000000..68878d095b --- /dev/null +++ b/validator/utils/clock.go @@ -0,0 +1,13 @@ +package utils + +import "time" + +// BlockingWait sleeps until a specific time is reached after +// a certain duration. For example, if the genesis block +// was at 12:00:00PM and the current time is 12:00:03PM, +// we want the next slot to tick at 12:00:08PM so we can use +// this helper method to achieve that purpose. +func BlockingWait(duration time.Duration) { + d := time.Until(time.Now().Add(duration).Truncate(duration)) + time.Sleep(d) +} diff --git a/validator/utils/clock_test.go b/validator/utils/clock_test.go new file mode 100644 index 0000000000..09b5c72419 --- /dev/null +++ b/validator/utils/clock_test.go @@ -0,0 +1,7 @@ +package utils + +import "testing" + +func TestBlockingWait(t *testing.T) { + BlockingWait(0) +}