mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
Implement WaitForChainStart RPC Server and Client (#1421)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: BeaconServiceServer,BeaconService_LatestAttestationServer)
|
||||
// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: BeaconServiceServer,BeaconService_LatestAttestationServer,BeaconService_WaitForChainStartServer)
|
||||
|
||||
package internal
|
||||
|
||||
@@ -62,6 +62,18 @@ func (mr *MockBeaconServiceServerMockRecorder) LatestAttestation(arg0, arg1 inte
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatestAttestation", reflect.TypeOf((*MockBeaconServiceServer)(nil).LatestAttestation), arg0, arg1)
|
||||
}
|
||||
|
||||
// WaitForChainStart mocks base method
|
||||
func (m *MockBeaconServiceServer) WaitForChainStart(arg0 *types.Empty, arg1 v10.BeaconService_WaitForChainStartServer) error {
|
||||
ret := m.ctrl.Call(m, "WaitForChainStart", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// WaitForChainStart indicates an expected call of WaitForChainStart
|
||||
func (mr *MockBeaconServiceServerMockRecorder) WaitForChainStart(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForChainStart", reflect.TypeOf((*MockBeaconServiceServer)(nil).WaitForChainStart), arg0, arg1)
|
||||
}
|
||||
|
||||
// MockBeaconService_LatestAttestationServer is a mock of BeaconService_LatestAttestationServer interface
|
||||
type MockBeaconService_LatestAttestationServer struct {
|
||||
ctrl *gomock.Controller
|
||||
@@ -166,3 +178,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_WaitForChainStartServer is a mock of BeaconService_WaitForChainStartServer interface
|
||||
type MockBeaconService_WaitForChainStartServer struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockBeaconService_WaitForChainStartServerMockRecorder
|
||||
}
|
||||
|
||||
// MockBeaconService_WaitForChainStartServerMockRecorder is the mock recorder for MockBeaconService_WaitForChainStartServer
|
||||
type MockBeaconService_WaitForChainStartServerMockRecorder struct {
|
||||
mock *MockBeaconService_WaitForChainStartServer
|
||||
}
|
||||
|
||||
// NewMockBeaconService_WaitForChainStartServer creates a new mock instance
|
||||
func NewMockBeaconService_WaitForChainStartServer(ctrl *gomock.Controller) *MockBeaconService_WaitForChainStartServer {
|
||||
mock := &MockBeaconService_WaitForChainStartServer{ctrl: ctrl}
|
||||
mock.recorder = &MockBeaconService_WaitForChainStartServerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockBeaconService_WaitForChainStartServer) EXPECT() *MockBeaconService_WaitForChainStartServerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Context mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartServer) 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_WaitForChainStartServerMockRecorder) Context() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBeaconService_WaitForChainStartServer)(nil).Context))
|
||||
}
|
||||
|
||||
// RecvMsg mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartServer) 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_WaitForChainStartServerMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockBeaconService_WaitForChainStartServer)(nil).RecvMsg), arg0)
|
||||
}
|
||||
|
||||
// Send mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartServer) Send(arg0 *v10.ChainStartResponse) error {
|
||||
ret := m.ctrl.Call(m, "Send", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Send indicates an expected call of Send
|
||||
func (mr *MockBeaconService_WaitForChainStartServerMockRecorder) Send(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockBeaconService_WaitForChainStartServer)(nil).Send), arg0)
|
||||
}
|
||||
|
||||
// SendHeader mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartServer) 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_WaitForChainStartServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockBeaconService_WaitForChainStartServer)(nil).SendHeader), arg0)
|
||||
}
|
||||
|
||||
// SendMsg mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartServer) 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_WaitForChainStartServerMockRecorder) SendMsg(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockBeaconService_WaitForChainStartServer)(nil).SendMsg), arg0)
|
||||
}
|
||||
|
||||
// SetHeader mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartServer) 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_WaitForChainStartServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockBeaconService_WaitForChainStartServer)(nil).SetHeader), arg0)
|
||||
}
|
||||
|
||||
// SetTrailer mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartServer) SetTrailer(arg0 metadata.MD) {
|
||||
m.ctrl.Call(m, "SetTrailer", arg0)
|
||||
}
|
||||
|
||||
// SetTrailer indicates an expected call of SetTrailer
|
||||
func (mr *MockBeaconService_WaitForChainStartServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockBeaconService_WaitForChainStartServer)(nil).SetTrailer), arg0)
|
||||
}
|
||||
|
||||
@@ -186,7 +186,6 @@ func (b *BeaconNode) registerBlockchainService(ctx *cli.Context) error {
|
||||
Web3Service: web3Service,
|
||||
BeaconBlockBuf: 10,
|
||||
IncomingBlockBuf: 100, // Big buffer to accommodate other feed subscribers.
|
||||
EnablePOWChain: enablePOWChain,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not register blockchain service: %v", err)
|
||||
@@ -304,7 +303,6 @@ func (b *BeaconNode) registerRPCService(ctx *cli.Context) error {
|
||||
ChainService: chainService,
|
||||
AttestationService: attestationService,
|
||||
POWChainService: web3Service,
|
||||
EnablePOWChain: enablePOWChain,
|
||||
})
|
||||
|
||||
return b.services.RegisterService(rpcService)
|
||||
|
||||
@@ -56,7 +56,6 @@ func TestNodeClose(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String("web3provider", "ws//127.0.0.1:8546", "web3 provider ws or IPC endpoint")
|
||||
set.String("datadir", tmp, "node data directory")
|
||||
set.Bool("enable-powchain", false, "no powchain service")
|
||||
set.Bool("demo-config", true, "demo configuration")
|
||||
|
||||
context := cli.NewContext(app, set, nil)
|
||||
|
||||
@@ -143,18 +143,119 @@ func (w *Web3Service) Status() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// initDataFromVRC calls the vrc contract and finds the deposit count
|
||||
// and deposit root.
|
||||
func (w *Web3Service) initDataFromVRC() error {
|
||||
root, err := w.vrcCaller.GetDepositRoot(&bind.CallOpts{})
|
||||
// LatestBlockNumber in the ETH1.0 chain.
|
||||
func (w *Web3Service) LatestBlockNumber() *big.Int {
|
||||
return w.blockNumber
|
||||
}
|
||||
|
||||
// LatestBlockHash in the ETH1.0 chain.
|
||||
func (w *Web3Service) LatestBlockHash() common.Hash {
|
||||
return w.blockHash
|
||||
}
|
||||
|
||||
// Client for interacting with the ETH1.0 chain.
|
||||
func (w *Web3Service) Client() Client {
|
||||
return w.client
|
||||
}
|
||||
|
||||
// HasChainStartLogOccurred queries all logs in the deposit contract to verify
|
||||
// if ChainStart has occurred. If so, it returns true alongside the ChainStart timestamp.
|
||||
func (w *Web3Service) HasChainStartLogOccurred() (bool, time.Time, error) {
|
||||
query := ethereum.FilterQuery{
|
||||
Addresses: []common.Address{
|
||||
w.depositContractAddress,
|
||||
},
|
||||
}
|
||||
logs, err := w.logger.FilterLogs(w.ctx, query)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not retrieve deposit root %v", err)
|
||||
return false, time.Now(), fmt.Errorf("could not filter deposit contract logs: %v", err)
|
||||
}
|
||||
for _, log := range logs {
|
||||
if log.Topics[0] == hashutil.Hash(chainStartEventSignature) {
|
||||
_, timestampData, err := contracts.UnpackChainStartLogData(log.Data)
|
||||
if err != nil {
|
||||
return false, time.Now(), fmt.Errorf("unable to unpack ChainStart log data %v", err)
|
||||
}
|
||||
timestamp := binary.BigEndian.Uint64(timestampData)
|
||||
if uint64(time.Now().Unix()) < timestamp {
|
||||
return false, time.Now(), fmt.Errorf(
|
||||
"invalid timestamp from log expected %d > %d",
|
||||
time.Now().Unix(),
|
||||
timestamp,
|
||||
)
|
||||
}
|
||||
return true, time.Unix(int64(timestamp), 0), nil
|
||||
}
|
||||
}
|
||||
return false, time.Now(), nil
|
||||
}
|
||||
|
||||
// ProcessLog is the main method which handles the processing of all
|
||||
// logs from the deposit contract on the ETH1.0 chain.
|
||||
func (w *Web3Service) ProcessLog(VRClog gethTypes.Log) {
|
||||
// Process logs according to their event signature.
|
||||
if VRClog.Topics[0] == hashutil.Hash(depositEventSignature) {
|
||||
w.ProcessDepositLog(VRClog)
|
||||
return
|
||||
}
|
||||
|
||||
w.depositRoot = root[:]
|
||||
w.depositTrie = trie.NewDepositTrie()
|
||||
if VRClog.Topics[0] == hashutil.Hash(chainStartEventSignature) {
|
||||
w.ProcessChainStartLog(VRClog)
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
log.Debugf("Log is not of a valid event signature %#x", VRClog.Topics[0])
|
||||
}
|
||||
|
||||
// ProcessDepositLog processes the log which had been received from
|
||||
// the ETH1.0 chain by trying to ascertain which participant deposited
|
||||
// in the contract.
|
||||
func (w *Web3Service) ProcessDepositLog(VRClog gethTypes.Log) {
|
||||
merkleRoot, depositData, MerkleTreeIndex, err := contracts.UnpackDepositLogData(VRClog.Data)
|
||||
if err != nil {
|
||||
log.Errorf("Could not unpack log %v", err)
|
||||
return
|
||||
}
|
||||
if err := w.saveInTrie(depositData, merkleRoot); err != nil {
|
||||
log.Errorf("Could not save in trie %v", err)
|
||||
return
|
||||
}
|
||||
depositInput, err := blocks.DecodeDepositInput(depositData)
|
||||
if err != nil {
|
||||
log.Errorf("Could not decode deposit input %v", err)
|
||||
return
|
||||
}
|
||||
index := binary.BigEndian.Uint64(MerkleTreeIndex)
|
||||
log.WithFields(logrus.Fields{
|
||||
"publicKey": depositInput.Pubkey,
|
||||
"merkle tree index": index,
|
||||
}).Info("Validator registered in VRC with public key and index")
|
||||
}
|
||||
|
||||
// ProcessChainStartLog processes the log which had been received from
|
||||
// the ETH1.0 chain by trying to determine when to start the beacon chain.
|
||||
func (w *Web3Service) ProcessChainStartLog(VRClog gethTypes.Log) {
|
||||
receiptRoot, timestampData, err := contracts.UnpackChainStartLogData(VRClog.Data)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to unpack ChainStart log data %v", err)
|
||||
return
|
||||
}
|
||||
if w.depositTrie.Root() != receiptRoot {
|
||||
log.Errorf("Receipt root from log doesn't match the root saved in memory,"+
|
||||
" want %#x but got %#x", w.depositTrie.Root(), receiptRoot)
|
||||
return
|
||||
}
|
||||
|
||||
timestamp := binary.BigEndian.Uint64(timestampData)
|
||||
if uint64(time.Now().Unix()) < timestamp {
|
||||
log.Errorf("Invalid timestamp from log expected %d > %d", time.Now().Unix(), timestamp)
|
||||
}
|
||||
|
||||
chainStartTime := time.Unix(int64(timestamp), 0)
|
||||
log.WithFields(logrus.Fields{
|
||||
"ChainStartTime": chainStartTime,
|
||||
}).Info("Minimum Number of Validators Reached for beacon-chain to start")
|
||||
w.chainStartFeed.Send(chainStartTime)
|
||||
}
|
||||
|
||||
// run subscribes to all the services for the ETH1.0 chain.
|
||||
@@ -205,79 +306,25 @@ func (w *Web3Service) run(done <-chan struct{}) {
|
||||
"blockHash": w.blockHash.Hex(),
|
||||
}).Debug("Latest web3 chain event")
|
||||
case VRClog := <-w.logChan:
|
||||
log.Info("Received deposit contract log")
|
||||
w.ProcessLog(VRClog)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ProcessLog is the main method which handles the processing of all
|
||||
// logs from the deposit contract on the ETH1.0 chain.
|
||||
func (w *Web3Service) ProcessLog(VRClog gethTypes.Log) {
|
||||
// Process logs according to their event signature.
|
||||
if VRClog.Topics[0] == hashutil.Hash(depositEventSignature) {
|
||||
w.ProcessDepositLog(VRClog)
|
||||
return
|
||||
}
|
||||
|
||||
if VRClog.Topics[0] == hashutil.Hash(chainStartEventSignature) {
|
||||
w.ProcessChainStartLog(VRClog)
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("Log is not of a valid event signature %#x", VRClog.Topics[0])
|
||||
}
|
||||
|
||||
// ProcessDepositLog processes the log which had been received from
|
||||
// the ETH1.0 chain by trying to ascertain which participant deposited
|
||||
// in the contract.
|
||||
func (w *Web3Service) ProcessDepositLog(VRClog gethTypes.Log) {
|
||||
merkleRoot, depositData, MerkleTreeIndex, err := contracts.UnpackDepositLogData(VRClog.Data)
|
||||
// initDataFromVRC calls the vrc contract and finds the deposit count
|
||||
// and deposit root.
|
||||
func (w *Web3Service) initDataFromVRC() error {
|
||||
root, err := w.vrcCaller.GetDepositRoot(&bind.CallOpts{})
|
||||
if err != nil {
|
||||
log.Errorf("Could not unpack log %v", err)
|
||||
return
|
||||
}
|
||||
if err := w.saveInTrie(depositData, merkleRoot); err != nil {
|
||||
log.Errorf("Could not save in trie %v", err)
|
||||
return
|
||||
}
|
||||
depositInput, err := blocks.DecodeDepositInput(depositData)
|
||||
if err != nil {
|
||||
log.Errorf("Could not decode deposit input %v", err)
|
||||
return
|
||||
}
|
||||
index := binary.BigEndian.Uint64(MerkleTreeIndex)
|
||||
log.WithFields(logrus.Fields{
|
||||
"publicKey": depositInput.Pubkey,
|
||||
"merkle tree index": index,
|
||||
}).Info("Validator registered in VRC with public key and index")
|
||||
}
|
||||
|
||||
// ProcessChainStartLog processes the log which had been received from
|
||||
// the ETH1.0 chain by trying to determine when to start the beacon chain.
|
||||
func (w *Web3Service) ProcessChainStartLog(VRClog gethTypes.Log) {
|
||||
|
||||
receiptRoot, timestampData, err := contracts.UnpackChainStartLogData(VRClog.Data)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to unpack ChainStart log data %v", err)
|
||||
return
|
||||
}
|
||||
if w.depositTrie.Root() != receiptRoot {
|
||||
log.Errorf("Receipt root from log doesn't match the root saved in memory,"+
|
||||
" want %#x but got %#x", w.depositTrie.Root(), receiptRoot)
|
||||
return
|
||||
return fmt.Errorf("could not retrieve deposit root %v", err)
|
||||
}
|
||||
|
||||
timestamp := binary.BigEndian.Uint64(timestampData)
|
||||
if uint64(time.Now().Unix()) < timestamp {
|
||||
log.Errorf("Invalid timestamp from log expected %d > %d", time.Now().Unix(), timestamp)
|
||||
}
|
||||
w.depositRoot = root[:]
|
||||
w.depositTrie = trie.NewDepositTrie()
|
||||
|
||||
chainStartTime := time.Unix(int64(timestamp), 0)
|
||||
log.WithFields(logrus.Fields{
|
||||
"ChainStartTime": chainStartTime,
|
||||
}).Info("Minimum Number of Validators Reached for beacon-chain to start")
|
||||
w.chainStartFeed.Send(chainStartTime)
|
||||
return nil
|
||||
}
|
||||
|
||||
// saveInTrie saves in the in-memory deposit trie.
|
||||
@@ -303,18 +350,3 @@ func (w *Web3Service) processPastLogs(query ethereum.FilterQuery) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LatestBlockNumber in the ETH1.0 chain.
|
||||
func (w *Web3Service) LatestBlockNumber() *big.Int {
|
||||
return w.blockNumber
|
||||
}
|
||||
|
||||
// LatestBlockHash in the ETH1.0 chain.
|
||||
func (w *Web3Service) LatestBlockHash() common.Hash {
|
||||
return w.blockHash
|
||||
}
|
||||
|
||||
// Client for interacting with the ETH1.0 chain.
|
||||
func (w *Web3Service) Client() Client {
|
||||
return w.client
|
||||
}
|
||||
|
||||
@@ -730,3 +730,66 @@ func TestUnpackChainStartLogs(t *testing.T) {
|
||||
t.Errorf("Timestamp from log is higher than the current time %d > %d", timestamp, time.Now().Unix())
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasChainStartLogOccurred(t *testing.T) {
|
||||
endpoint := "ws://127.0.0.1"
|
||||
testAcc, err := setup()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to set up simulated backend %v", err)
|
||||
}
|
||||
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
|
||||
Endpoint: endpoint,
|
||||
DepositContract: testAcc.contractAddr,
|
||||
Reader: &goodReader{},
|
||||
Logger: testAcc.backend,
|
||||
ContractBackend: testAcc.backend,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unable to setup web3 ETH1.0 chain service: %v", err)
|
||||
}
|
||||
|
||||
testAcc.backend.Commit()
|
||||
|
||||
testAcc.backend.AdjustTime(time.Duration(int64(time.Now().Nanosecond())))
|
||||
|
||||
var stub [48]byte
|
||||
copy(stub[:], []byte("testing"))
|
||||
|
||||
data := &pb.DepositInput{
|
||||
Pubkey: stub[:],
|
||||
ProofOfPossession: stub[:],
|
||||
WithdrawalCredentialsHash32: []byte("withdraw"),
|
||||
RandaoCommitmentHash32: []byte("randao"),
|
||||
CustodyCommitmentHash32: []byte("custody"),
|
||||
}
|
||||
|
||||
serializedData := new(bytes.Buffer)
|
||||
if err := ssz.Encode(serializedData, data); err != nil {
|
||||
t.Fatalf("Could not serialize data %v", err)
|
||||
}
|
||||
ok, _, err := web3Service.HasChainStartLogOccurred()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not check if chain start log occurred: %v", err)
|
||||
}
|
||||
if ok {
|
||||
t.Error("Expected chain start log to not have occurred")
|
||||
}
|
||||
|
||||
// 8 Validators are used as size required for beacon-chain to start. This number
|
||||
// is defined in the VRC as the number required for the testnet.
|
||||
for i := 0; i < depositsReqForChainStart; i++ {
|
||||
testAcc.txOpts.Value = amount32Eth
|
||||
if _, err := testAcc.contract.Deposit(testAcc.txOpts, serializedData.Bytes()); err != nil {
|
||||
t.Fatalf("Could not deposit to VRC %v", err)
|
||||
}
|
||||
|
||||
testAcc.backend.Commit()
|
||||
}
|
||||
ok, _, err = web3Service.HasChainStartLogOccurred()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not check if chain start log occurred: %v", err)
|
||||
}
|
||||
if !ok {
|
||||
t.Error("Expected chain start log to have occurred")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ go_library(
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/hashutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_gogo_protobuf//types:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
@@ -50,7 +49,6 @@ go_test(
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_gogo_protobuf//types:go_default_library",
|
||||
"@com_github_golang_mock//gomock:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
|
||||
@@ -3,6 +3,7 @@ package rpc
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
@@ -16,9 +17,49 @@ import (
|
||||
type BeaconServer struct {
|
||||
beaconDB *db.BeaconDB
|
||||
ctx context.Context
|
||||
powChainService powChainService
|
||||
attestationService attestationService
|
||||
incomingAttestation chan *pbp2p.Attestation
|
||||
canonicalStateChan chan *pbp2p.BeaconState
|
||||
chainStartChan chan time.Time
|
||||
}
|
||||
|
||||
// WaitForChainStart queries the logs of the Deposit Contract in order to verify the beacon chain
|
||||
// has started its runtime and validators begin their responsibilities. If it has not, it then
|
||||
// subscribes to an event stream triggered by the powchain service whenever the ChainStart log does
|
||||
// occur in the Deposit Contract on ETH 1.0.
|
||||
func (bs *BeaconServer) WaitForChainStart(req *ptypes.Empty, stream pb.BeaconService_WaitForChainStartServer) error {
|
||||
ok, genesisTime, err := bs.powChainService.HasChainStartLogOccurred()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not verify ChainStart log occurred: %v", err)
|
||||
}
|
||||
if ok {
|
||||
res := &pb.ChainStartResponse{
|
||||
Started: true,
|
||||
GenesisTime: uint64(genesisTime.Unix()),
|
||||
}
|
||||
return stream.Send(res)
|
||||
}
|
||||
|
||||
sub := bs.powChainService.ChainStartFeed().Subscribe(bs.chainStartChan)
|
||||
defer sub.Unsubscribe()
|
||||
for {
|
||||
select {
|
||||
case chainStartTime := <-bs.chainStartChan:
|
||||
log.Info("Sending ChainStart log and genesis time to connected validator clients")
|
||||
res := &pb.ChainStartResponse{
|
||||
Started: true,
|
||||
GenesisTime: uint64(chainStartTime.Unix()),
|
||||
}
|
||||
return stream.Send(res)
|
||||
case <-sub.Err():
|
||||
log.Debug("Subscriber closed, exiting goroutine")
|
||||
return nil
|
||||
case <-bs.ctx.Done():
|
||||
log.Debug("RPC context closed, exiting goroutine")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CanonicalHead of the current beacon chain. This method is requested on-demand
|
||||
|
||||
@@ -4,16 +4,117 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/internal"
|
||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
func TestLatestAttestationContextClosed(t *testing.T) {
|
||||
type faultyPOWChainService struct {
|
||||
chainStartFeed *event.Feed
|
||||
}
|
||||
|
||||
func (f *faultyPOWChainService) HasChainStartLogOccurred() (bool, time.Time, error) {
|
||||
return false, time.Now(), nil
|
||||
}
|
||||
func (f *faultyPOWChainService) ChainStartFeed() *event.Feed {
|
||||
return f.chainStartFeed
|
||||
}
|
||||
|
||||
type mockPOWChainService struct {
|
||||
chainStartFeed *event.Feed
|
||||
}
|
||||
|
||||
func (m *mockPOWChainService) HasChainStartLogOccurred() (bool, time.Time, error) {
|
||||
return true, time.Unix(0, 0), nil
|
||||
}
|
||||
func (m *mockPOWChainService) ChainStartFeed() *event.Feed {
|
||||
return m.chainStartFeed
|
||||
}
|
||||
|
||||
func TestWaitForChainStart_ContextClosed(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
beaconServer := &BeaconServer{
|
||||
ctx: ctx,
|
||||
powChainService: &faultyPOWChainService{
|
||||
chainStartFeed: new(event.Feed),
|
||||
},
|
||||
}
|
||||
exitRoutine := make(chan bool)
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
mockStream := internal.NewMockBeaconService_WaitForChainStartServer(ctrl)
|
||||
go func(tt *testing.T) {
|
||||
if err := beaconServer.WaitForChainStart(&ptypes.Empty{}, mockStream); err != nil {
|
||||
tt.Errorf("Could not call RPC method: %v", err)
|
||||
}
|
||||
<-exitRoutine
|
||||
}(t)
|
||||
cancel()
|
||||
exitRoutine <- true
|
||||
testutil.AssertLogsContain(t, hook, "RPC context closed, exiting goroutine")
|
||||
}
|
||||
|
||||
func TestWaitForChainStart_AlreadyStarted(t *testing.T) {
|
||||
beaconServer := &BeaconServer{
|
||||
ctx: context.Background(),
|
||||
powChainService: &mockPOWChainService{
|
||||
chainStartFeed: new(event.Feed),
|
||||
},
|
||||
}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
mockStream := internal.NewMockBeaconService_WaitForChainStartServer(ctrl)
|
||||
mockStream.EXPECT().Send(
|
||||
&pb.ChainStartResponse{
|
||||
Started: true,
|
||||
GenesisTime: uint64(time.Unix(0, 0).Unix()),
|
||||
},
|
||||
).Return(nil)
|
||||
if err := beaconServer.WaitForChainStart(&ptypes.Empty{}, mockStream); err != nil {
|
||||
t.Errorf("Could not call RPC method: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitForChainStart_NotStartedThenLogFired(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
beaconServer := &BeaconServer{
|
||||
ctx: context.Background(),
|
||||
chainStartChan: make(chan time.Time, 1),
|
||||
powChainService: &faultyPOWChainService{
|
||||
chainStartFeed: new(event.Feed),
|
||||
},
|
||||
}
|
||||
exitRoutine := make(chan bool)
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
mockStream := internal.NewMockBeaconService_WaitForChainStartServer(ctrl)
|
||||
mockStream.EXPECT().Send(
|
||||
&pb.ChainStartResponse{
|
||||
Started: true,
|
||||
GenesisTime: uint64(time.Unix(0, 0).Unix()),
|
||||
},
|
||||
).Return(nil)
|
||||
go func(tt *testing.T) {
|
||||
if err := beaconServer.WaitForChainStart(&ptypes.Empty{}, mockStream); err != nil {
|
||||
tt.Errorf("Could not call RPC method: %v", err)
|
||||
}
|
||||
<-exitRoutine
|
||||
}(t)
|
||||
beaconServer.chainStartChan <- time.Unix(0, 0)
|
||||
exitRoutine <- true
|
||||
testutil.AssertLogsContain(t, hook, "Sending ChainStart log and genesis time to connected validator clients")
|
||||
}
|
||||
|
||||
func TestLatestAttestation_ContextClosed(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
mockAttestationService := &mockAttestationService{}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -36,7 +137,7 @@ func TestLatestAttestationContextClosed(t *testing.T) {
|
||||
testutil.AssertLogsContain(t, hook, "RPC context closed, exiting goroutine")
|
||||
}
|
||||
|
||||
func TestLatestAttestationFaulty(t *testing.T) {
|
||||
func TestLatestAttestation_FaultyServer(t *testing.T) {
|
||||
attestationService := &mockAttestationService{}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
beaconServer := &BeaconServer{
|
||||
@@ -65,7 +166,7 @@ func TestLatestAttestationFaulty(t *testing.T) {
|
||||
exitRoutine <- true
|
||||
}
|
||||
|
||||
func TestLatestAttestation(t *testing.T) {
|
||||
func TestLatestAttestation_SendsCorrectly(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
attestationService := &mockAttestationService{}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
@@ -22,7 +22,6 @@ type ProposerServer struct {
|
||||
chainService chainService
|
||||
powChainService powChainService
|
||||
canonicalStateChan chan *pbp2p.BeaconState
|
||||
enablePOWChain bool
|
||||
}
|
||||
|
||||
// ProposerIndex sends a response to the client which returns the proposer index for a given slot. Validators
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
@@ -35,7 +34,8 @@ type attestationService interface {
|
||||
}
|
||||
|
||||
type powChainService interface {
|
||||
LatestBlockHash() common.Hash
|
||||
HasChainStartLogOccurred() (bool, time.Time, error)
|
||||
ChainStartFeed() *event.Feed
|
||||
}
|
||||
|
||||
// Service defining an RPC server for a beacon node.
|
||||
@@ -54,7 +54,6 @@ type Service struct {
|
||||
canonicalBlockChan chan *pbp2p.BeaconBlock
|
||||
canonicalStateChan chan *pbp2p.BeaconState
|
||||
incomingAttestation chan *pbp2p.Attestation
|
||||
enablePOWChain bool
|
||||
slotAlignmentDuration time.Duration
|
||||
}
|
||||
|
||||
@@ -68,7 +67,6 @@ type Config struct {
|
||||
ChainService chainService
|
||||
POWChainService powChainService
|
||||
AttestationService attestationService
|
||||
EnablePOWChain bool
|
||||
}
|
||||
|
||||
// NewRPCService creates a new instance of a struct implementing the BeaconServiceServer
|
||||
@@ -89,7 +87,6 @@ func NewRPCService(ctx context.Context, cfg *Config) *Service {
|
||||
canonicalBlockChan: make(chan *pbp2p.BeaconBlock, cfg.SubscriptionBuf),
|
||||
canonicalStateChan: make(chan *pbp2p.BeaconState, cfg.SubscriptionBuf),
|
||||
incomingAttestation: make(chan *pbp2p.Attestation, cfg.SubscriptionBuf),
|
||||
enablePOWChain: cfg.EnablePOWChain,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,16 +118,17 @@ func (s *Service) Start() {
|
||||
beaconServer := &BeaconServer{
|
||||
beaconDB: s.beaconDB,
|
||||
ctx: s.ctx,
|
||||
powChainService: s.powChainService,
|
||||
attestationService: s.attestationService,
|
||||
incomingAttestation: s.incomingAttestation,
|
||||
canonicalStateChan: s.canonicalStateChan,
|
||||
chainStartChan: make(chan time.Time, 1),
|
||||
}
|
||||
proposerServer := &ProposerServer{
|
||||
beaconDB: s.beaconDB,
|
||||
chainService: s.chainService,
|
||||
powChainService: s.powChainService,
|
||||
canonicalStateChan: s.canonicalStateChan,
|
||||
enablePOWChain: s.enablePOWChain,
|
||||
}
|
||||
attesterServer := &AttesterServer{
|
||||
attestationService: s.attestationService,
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -18,12 +17,6 @@ func init() {
|
||||
logrus.SetOutput(ioutil.Discard)
|
||||
}
|
||||
|
||||
type mockPOWChainService struct{}
|
||||
|
||||
func (m *mockPOWChainService) LatestBlockHash() common.Hash {
|
||||
return common.BytesToHash([]byte{})
|
||||
}
|
||||
|
||||
type mockAttestationService struct{}
|
||||
|
||||
func (m *mockAttestationService) IncomingAttestationFeed() *event.Feed {
|
||||
|
||||
@@ -2,7 +2,6 @@ package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -71,7 +70,6 @@ func TestValidatorEpochAssignments(t *testing.T) {
|
||||
for i := 0; i < len(deposits); i++ {
|
||||
var pubKey [48]byte
|
||||
copy(pubKey[:], []byte(strconv.Itoa(i)))
|
||||
fmt.Println(len(pubKey))
|
||||
depositInput := &pbp2p.DepositInput{
|
||||
Pubkey: pubKey[:],
|
||||
RandaoCommitmentHash32: []byte{0},
|
||||
|
||||
@@ -48,7 +48,62 @@ func (x ValidatorRole) String() string {
|
||||
return proto.EnumName(ValidatorRole_name, int32(x))
|
||||
}
|
||||
func (ValidatorRole) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_e10adba4df963591, []int{0}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{0}
|
||||
}
|
||||
|
||||
type ChainStartResponse struct {
|
||||
Started bool `protobuf:"varint,1,opt,name=started,proto3" json:"started,omitempty"`
|
||||
GenesisTime uint64 `protobuf:"varint,2,opt,name=genesis_time,json=genesisTime,proto3" json:"genesis_time,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ChainStartResponse) Reset() { *m = ChainStartResponse{} }
|
||||
func (m *ChainStartResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ChainStartResponse) ProtoMessage() {}
|
||||
func (*ChainStartResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{0}
|
||||
}
|
||||
func (m *ChainStartResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *ChainStartResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_ChainStartResponse.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalTo(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (dst *ChainStartResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ChainStartResponse.Merge(dst, src)
|
||||
}
|
||||
func (m *ChainStartResponse) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *ChainStartResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ChainStartResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ChainStartResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ChainStartResponse) GetStarted() bool {
|
||||
if m != nil {
|
||||
return m.Started
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *ChainStartResponse) GetGenesisTime() uint64 {
|
||||
if m != nil {
|
||||
return m.GenesisTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ProposeRequest struct {
|
||||
@@ -67,7 +122,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_e10adba4df963591, []int{0}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{1}
|
||||
}
|
||||
func (m *ProposeRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -149,7 +204,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_e10adba4df963591, []int{1}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{2}
|
||||
}
|
||||
func (m *ProposeResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -196,7 +251,7 @@ func (m *ProposerIndexRequest) Reset() { *m = ProposerIndexRequest{} }
|
||||
func (m *ProposerIndexRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProposerIndexRequest) ProtoMessage() {}
|
||||
func (*ProposerIndexRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_e10adba4df963591, []int{2}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{3}
|
||||
}
|
||||
func (m *ProposerIndexRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -243,7 +298,7 @@ func (m *ProposerIndexResponse) Reset() { *m = ProposerIndexResponse{} }
|
||||
func (m *ProposerIndexResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProposerIndexResponse) ProtoMessage() {}
|
||||
func (*ProposerIndexResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_e10adba4df963591, []int{3}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{4}
|
||||
}
|
||||
func (m *ProposerIndexResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -290,7 +345,7 @@ func (m *StateRootResponse) Reset() { *m = StateRootResponse{} }
|
||||
func (m *StateRootResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*StateRootResponse) ProtoMessage() {}
|
||||
func (*StateRootResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_e10adba4df963591, []int{4}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{5}
|
||||
}
|
||||
func (m *StateRootResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -337,7 +392,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_e10adba4df963591, []int{5}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{6}
|
||||
}
|
||||
func (m *AttestRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -384,7 +439,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_e10adba4df963591, []int{6}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{7}
|
||||
}
|
||||
func (m *AttestResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -434,7 +489,7 @@ 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_e10adba4df963591, []int{7}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{8}
|
||||
}
|
||||
func (m *Assignment) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -502,7 +557,7 @@ func (m *ValidatorIndexRequest) Reset() { *m = ValidatorIndexRequest{} }
|
||||
func (m *ValidatorIndexRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ValidatorIndexRequest) ProtoMessage() {}
|
||||
func (*ValidatorIndexRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_e10adba4df963591, []int{8}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{9}
|
||||
}
|
||||
func (m *ValidatorIndexRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -549,7 +604,7 @@ func (m *ValidatorIndexResponse) Reset() { *m = ValidatorIndexResponse{}
|
||||
func (m *ValidatorIndexResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ValidatorIndexResponse) ProtoMessage() {}
|
||||
func (*ValidatorIndexResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_e10adba4df963591, []int{9}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{10}
|
||||
}
|
||||
func (m *ValidatorIndexResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -597,7 +652,7 @@ func (m *ValidatorEpochAssignmentsRequest) Reset() { *m = ValidatorEpoch
|
||||
func (m *ValidatorEpochAssignmentsRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ValidatorEpochAssignmentsRequest) ProtoMessage() {}
|
||||
func (*ValidatorEpochAssignmentsRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_e10adba4df963591, []int{10}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{11}
|
||||
}
|
||||
func (m *ValidatorEpochAssignmentsRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -651,7 +706,7 @@ func (m *ValidatorEpochAssignmentsResponse) Reset() { *m = ValidatorEpoc
|
||||
func (m *ValidatorEpochAssignmentsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ValidatorEpochAssignmentsResponse) ProtoMessage() {}
|
||||
func (*ValidatorEpochAssignmentsResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_services_e10adba4df963591, []int{11}
|
||||
return fileDescriptor_services_bf909c06e4b5edfe, []int{12}
|
||||
}
|
||||
func (m *ValidatorEpochAssignmentsResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -688,6 +743,7 @@ func (m *ValidatorEpochAssignmentsResponse) GetAssignment() *Assignment {
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ChainStartResponse)(nil), "ethereum.beacon.rpc.v1.ChainStartResponse")
|
||||
proto.RegisterType((*ProposeRequest)(nil), "ethereum.beacon.rpc.v1.ProposeRequest")
|
||||
proto.RegisterType((*ProposeResponse)(nil), "ethereum.beacon.rpc.v1.ProposeResponse")
|
||||
proto.RegisterType((*ProposerIndexRequest)(nil), "ethereum.beacon.rpc.v1.ProposerIndexRequest")
|
||||
@@ -714,6 +770,7 @@ const _ = grpc.SupportPackageIsVersion4
|
||||
// Client API for BeaconService service
|
||||
|
||||
type BeaconServiceClient interface {
|
||||
WaitForChainStart(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (BeaconService_WaitForChainStartClient, error)
|
||||
CanonicalHead(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (*v1.BeaconBlock, error)
|
||||
LatestAttestation(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (BeaconService_LatestAttestationClient, error)
|
||||
}
|
||||
@@ -726,6 +783,38 @@ func NewBeaconServiceClient(cc *grpc.ClientConn) BeaconServiceClient {
|
||||
return &beaconServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *beaconServiceClient) WaitForChainStart(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (BeaconService_WaitForChainStartClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_BeaconService_serviceDesc.Streams[0], "/ethereum.beacon.rpc.v1.BeaconService/WaitForChainStart", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &beaconServiceWaitForChainStartClient{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_WaitForChainStartClient interface {
|
||||
Recv() (*ChainStartResponse, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type beaconServiceWaitForChainStartClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *beaconServiceWaitForChainStartClient) Recv() (*ChainStartResponse, error) {
|
||||
m := new(ChainStartResponse)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *beaconServiceClient) CanonicalHead(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (*v1.BeaconBlock, error) {
|
||||
out := new(v1.BeaconBlock)
|
||||
err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.BeaconService/CanonicalHead", in, out, opts...)
|
||||
@@ -736,7 +825,7 @@ func (c *beaconServiceClient) CanonicalHead(ctx context.Context, in *types.Empty
|
||||
}
|
||||
|
||||
func (c *beaconServiceClient) LatestAttestation(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (BeaconService_LatestAttestationClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_BeaconService_serviceDesc.Streams[0], "/ethereum.beacon.rpc.v1.BeaconService/LatestAttestation", opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &_BeaconService_serviceDesc.Streams[1], "/ethereum.beacon.rpc.v1.BeaconService/LatestAttestation", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -770,6 +859,7 @@ func (x *beaconServiceLatestAttestationClient) Recv() (*v1.Attestation, error) {
|
||||
// Server API for BeaconService service
|
||||
|
||||
type BeaconServiceServer interface {
|
||||
WaitForChainStart(*types.Empty, BeaconService_WaitForChainStartServer) error
|
||||
CanonicalHead(context.Context, *types.Empty) (*v1.BeaconBlock, error)
|
||||
LatestAttestation(*types.Empty, BeaconService_LatestAttestationServer) error
|
||||
}
|
||||
@@ -778,6 +868,27 @@ func RegisterBeaconServiceServer(s *grpc.Server, srv BeaconServiceServer) {
|
||||
s.RegisterService(&_BeaconService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _BeaconService_WaitForChainStart_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(types.Empty)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(BeaconServiceServer).WaitForChainStart(m, &beaconServiceWaitForChainStartServer{stream})
|
||||
}
|
||||
|
||||
type BeaconService_WaitForChainStartServer interface {
|
||||
Send(*ChainStartResponse) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type beaconServiceWaitForChainStartServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *beaconServiceWaitForChainStartServer) Send(m *ChainStartResponse) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func _BeaconService_CanonicalHead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(types.Empty)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -827,6 +938,11 @@ var _BeaconService_serviceDesc = grpc.ServiceDesc{
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "WaitForChainStart",
|
||||
Handler: _BeaconService_WaitForChainStart_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "LatestAttestation",
|
||||
Handler: _BeaconService_LatestAttestation_Handler,
|
||||
@@ -1127,6 +1243,42 @@ var _ValidatorService_serviceDesc = grpc.ServiceDesc{
|
||||
Metadata: "proto/beacon/rpc/v1/services.proto",
|
||||
}
|
||||
|
||||
func (m *ChainStartResponse) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ChainStartResponse) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Started {
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
if m.Started {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i++
|
||||
}
|
||||
if m.GenesisTime != 0 {
|
||||
dAtA[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintServices(dAtA, i, uint64(m.GenesisTime))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *ProposeRequest) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
@@ -1529,6 +1681,21 @@ func encodeVarintServices(dAtA []byte, offset int, v uint64) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *ChainStartResponse) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
if m.Started {
|
||||
n += 2
|
||||
}
|
||||
if m.GenesisTime != 0 {
|
||||
n += 1 + sovServices(uint64(m.GenesisTime))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ProposeRequest) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
@@ -1729,6 +1896,96 @@ func sovServices(x uint64) (n int) {
|
||||
func sozServices(x uint64) (n int) {
|
||||
return sovServices(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *ChainStartResponse) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowServices
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ChainStartResponse: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ChainStartResponse: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Started", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowServices
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Started = bool(v != 0)
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GenesisTime", wireType)
|
||||
}
|
||||
m.GenesisTime = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowServices
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.GenesisTime |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipServices(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthServices
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ProposeRequest) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
@@ -3039,63 +3296,67 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("proto/beacon/rpc/v1/services.proto", fileDescriptor_services_e10adba4df963591)
|
||||
proto.RegisterFile("proto/beacon/rpc/v1/services.proto", fileDescriptor_services_bf909c06e4b5edfe)
|
||||
}
|
||||
|
||||
var fileDescriptor_services_e10adba4df963591 = []byte{
|
||||
// 856 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xd1, 0x6e, 0x23, 0x35,
|
||||
0x14, 0x65, 0xb2, 0xd9, 0x85, 0xbd, 0x49, 0xda, 0xac, 0xe9, 0x96, 0xec, 0x20, 0xda, 0x30, 0x2b,
|
||||
0xa0, 0x8b, 0xd8, 0x49, 0x3b, 0x2b, 0x41, 0x81, 0xa7, 0x64, 0x15, 0xa9, 0x68, 0x57, 0x6d, 0x35,
|
||||
0x29, 0xcb, 0x03, 0x48, 0x23, 0x4f, 0x62, 0x26, 0xa3, 0x4e, 0xc6, 0xc6, 0x76, 0x22, 0xfa, 0x0d,
|
||||
0xbc, 0xf0, 0xc4, 0x4f, 0xf0, 0xc4, 0x27, 0xf0, 0xc6, 0x23, 0x9f, 0x80, 0xfa, 0x25, 0xc8, 0xf6,
|
||||
0xcc, 0xd4, 0x4d, 0x9b, 0xb6, 0xf0, 0xe8, 0x73, 0xcf, 0xb9, 0xf7, 0xfa, 0xf8, 0xfa, 0x82, 0xc7,
|
||||
0x38, 0x95, 0xb4, 0x17, 0x13, 0x3c, 0xa6, 0x79, 0x8f, 0xb3, 0x71, 0x6f, 0xb1, 0xd7, 0x13, 0x84,
|
||||
0x2f, 0xd2, 0x31, 0x11, 0xbe, 0x0e, 0xa2, 0x4d, 0x22, 0xa7, 0x84, 0x93, 0xf9, 0xcc, 0x37, 0x34,
|
||||
0x9f, 0xb3, 0xb1, 0xbf, 0xd8, 0x73, 0xb7, 0x2f, 0x69, 0x59, 0xc0, 0x94, 0x56, 0x9e, 0xb1, 0x52,
|
||||
0xe8, 0xbe, 0x9f, 0x50, 0x9a, 0x64, 0xa4, 0xa7, 0x4f, 0xf1, 0xfc, 0xc7, 0x1e, 0x99, 0x31, 0x79,
|
||||
0x56, 0x04, 0xb7, 0x97, 0x83, 0x32, 0x9d, 0x11, 0x21, 0xf1, 0x8c, 0x19, 0x82, 0xf7, 0x7b, 0x0d,
|
||||
0xd6, 0x8e, 0x39, 0x65, 0x54, 0x90, 0x90, 0xfc, 0x34, 0x27, 0x42, 0xa2, 0x6d, 0x68, 0x30, 0xcc,
|
||||
0x49, 0x2e, 0xa3, 0x29, 0x16, 0xd3, 0x8e, 0xd3, 0x75, 0x76, 0x9a, 0x21, 0x18, 0xe8, 0x00, 0x8b,
|
||||
0xa9, 0x22, 0x88, 0x8c, 0xca, 0x28, 0x9f, 0xcf, 0x62, 0xc2, 0x3b, 0xb5, 0xae, 0xb3, 0x53, 0x0f,
|
||||
0x41, 0x41, 0x87, 0x1a, 0x41, 0xbb, 0xb0, 0xc1, 0x71, 0x3e, 0xc1, 0x34, 0xe2, 0x64, 0x41, 0x70,
|
||||
0xa6, 0x13, 0xbd, 0x08, 0x3a, 0xf7, 0x74, 0x2a, 0x64, 0x62, 0xa1, 0x0e, 0x1d, 0xe8, 0x08, 0xea,
|
||||
0xc1, 0xbb, 0x58, 0x4a, 0xd5, 0x99, 0x4c, 0x69, 0x1e, 0xc5, 0xa9, 0x9c, 0x61, 0x71, 0xda, 0xa9,
|
||||
0x1b, 0x81, 0x15, 0x1a, 0x98, 0x08, 0xfa, 0x0a, 0x9e, 0xd8, 0x02, 0x9c, 0x24, 0x9c, 0x24, 0x58,
|
||||
0x92, 0x48, 0xa4, 0x49, 0xe7, 0x7e, 0xf7, 0xde, 0x4e, 0x3d, 0x7c, 0xcf, 0x22, 0xf4, 0xcb, 0xf8,
|
||||
0x28, 0x4d, 0xd0, 0x3e, 0x3c, 0xac, 0x6c, 0xe8, 0x3c, 0xe8, 0x3a, 0x3b, 0x8d, 0xc0, 0xf5, 0x8d,
|
||||
0x51, 0x7e, 0x69, 0x94, 0x7f, 0x52, 0x32, 0xc2, 0x0b, 0xb2, 0xb7, 0x0b, 0xeb, 0x95, 0x59, 0x82,
|
||||
0xd1, 0x5c, 0x10, 0xf4, 0x01, 0x40, 0x9c, 0xd1, 0xf1, 0xa9, 0x6d, 0xd6, 0x43, 0x8d, 0xa8, 0xab,
|
||||
0x79, 0x5f, 0xc0, 0x46, 0xa1, 0xe0, 0xdf, 0xe4, 0x13, 0xf2, 0xb3, 0x65, 0xb2, 0xed, 0xa1, 0xb3,
|
||||
0xec, 0xa1, 0xf7, 0x1c, 0x1e, 0x2f, 0x09, 0x8b, 0x82, 0x1b, 0x70, 0x3f, 0x55, 0x40, 0xa1, 0x31,
|
||||
0x07, 0x2f, 0x80, 0x47, 0x23, 0x89, 0x25, 0x09, 0x29, 0x95, 0x76, 0x6f, 0xea, 0xfe, 0x24, 0xe2,
|
||||
0x94, 0xca, 0xb2, 0x37, 0x51, 0xd2, 0xbc, 0x37, 0xd0, 0xea, 0x6b, 0x8b, 0xca, 0xa6, 0x86, 0xd0,
|
||||
0xb0, 0x3c, 0xd3, 0x82, 0x46, 0xf0, 0xd4, 0x5f, 0x9e, 0x4c, 0x16, 0x30, 0x7f, 0xb1, 0xe7, 0xf7,
|
||||
0x2f, 0xa8, 0xa1, 0xad, 0xf3, 0xbe, 0x86, 0xb5, 0x32, 0x6f, 0xd1, 0xc8, 0x33, 0x68, 0xdb, 0xaf,
|
||||
0x65, 0x59, 0xb5, 0x6e, 0xe1, 0xda, 0xb0, 0x5f, 0x1c, 0x80, 0xbe, 0x10, 0x69, 0x92, 0xcf, 0x48,
|
||||
0x2e, 0xd5, 0x15, 0xd8, 0x3c, 0xce, 0xd2, 0x71, 0x74, 0x4a, 0xce, 0xca, 0x2b, 0x18, 0xe4, 0x15,
|
||||
0x39, 0x53, 0x66, 0x88, 0x29, 0xe6, 0x93, 0x62, 0x08, 0xcd, 0x01, 0x3d, 0x85, 0x96, 0x49, 0x4b,
|
||||
0x78, 0xa4, 0x2c, 0xd5, 0x83, 0x57, 0x0f, 0x9b, 0x25, 0x38, 0xca, 0xa8, 0x54, 0x24, 0x56, 0x18,
|
||||
0x6c, 0x48, 0x75, 0x43, 0x2a, 0x41, 0x45, 0xf2, 0x3e, 0x87, 0xc7, 0x6f, 0x70, 0x96, 0x4e, 0xb0,
|
||||
0xa4, 0x97, 0xdf, 0xef, 0xe6, 0xbe, 0x3c, 0x1f, 0x36, 0x97, 0x75, 0x37, 0x3e, 0x5f, 0x0c, 0xdd,
|
||||
0x8a, 0x3f, 0x64, 0x74, 0x3c, 0xbd, 0xb0, 0x40, 0x58, 0x23, 0x43, 0x54, 0x28, 0x12, 0x12, 0x73,
|
||||
0x59, 0x8e, 0x8c, 0x86, 0x46, 0x0a, 0x59, 0xea, 0xa9, 0xb6, 0xdc, 0x53, 0x02, 0x1f, 0xde, 0x50,
|
||||
0xa3, 0x68, 0x6f, 0x00, 0x80, 0x2b, 0x58, 0xe7, 0x68, 0x04, 0x9e, 0x7f, 0xfd, 0x6e, 0xf2, 0x2f,
|
||||
0x12, 0x84, 0x96, 0xea, 0xd3, 0x7d, 0x68, 0x55, 0x85, 0x42, 0x9a, 0x11, 0xd4, 0x80, 0xb7, 0xbf,
|
||||
0x3d, 0x7c, 0x75, 0x78, 0xf4, 0xdd, 0x61, 0xfb, 0x2d, 0xd4, 0x84, 0x77, 0xfa, 0x27, 0x27, 0xc3,
|
||||
0xd1, 0xc9, 0x30, 0x6c, 0x3b, 0xea, 0x74, 0x1c, 0x1e, 0x1d, 0x1f, 0x8d, 0x86, 0x61, 0xbb, 0x16,
|
||||
0xfc, 0xe1, 0x40, 0x6b, 0xa0, 0x4b, 0x8c, 0xcc, 0x76, 0x44, 0xaf, 0xa1, 0xf5, 0x12, 0xe7, 0x34,
|
||||
0x4f, 0xc7, 0x38, 0x3b, 0x20, 0x78, 0x82, 0x36, 0xaf, 0xfc, 0xd4, 0xa1, 0xda, 0x77, 0xee, 0xca,
|
||||
0x31, 0x35, 0xf9, 0x06, 0xea, 0x47, 0xa2, 0x10, 0x1e, 0xbd, 0xc6, 0x6a, 0x06, 0xac, 0xd9, 0xfd,
|
||||
0xef, 0x19, 0x2d, 0xf1, 0xae, 0x13, 0xe4, 0xb0, 0xde, 0x2f, 0xe7, 0xaa, 0x68, 0xfa, 0x7b, 0x00,
|
||||
0x03, 0xe9, 0x8e, 0x3f, 0x5a, 0x69, 0x9f, 0xfd, 0xf9, 0xdc, 0x8f, 0x6f, 0xa3, 0x99, 0x17, 0x0a,
|
||||
0xfe, 0xac, 0x55, 0x4b, 0xa8, 0x2a, 0x98, 0x41, 0xeb, 0xd2, 0xb2, 0x40, 0x9f, 0xad, 0x4a, 0x76,
|
||||
0xdd, 0x32, 0x72, 0x9f, 0xdf, 0x91, 0x5d, 0xcc, 0xc8, 0x0f, 0xd0, 0x2c, 0x02, 0xc6, 0xd5, 0xbb,
|
||||
0x58, 0xef, 0x7e, 0x72, 0x4b, 0x8d, 0x2a, 0x7b, 0x0c, 0xed, 0x97, 0x74, 0xc6, 0xe6, 0x92, 0x54,
|
||||
0x0b, 0xed, 0x6e, 0x15, 0x9e, 0xad, 0xaa, 0x70, 0x65, 0x31, 0x06, 0xbf, 0xd5, 0xa0, 0x5d, 0x8d,
|
||||
0x68, 0x69, 0x22, 0x85, 0xb5, 0xcb, 0x7f, 0x16, 0xad, 0xf4, 0xe5, 0xda, 0x9d, 0xe0, 0xfa, 0x77,
|
||||
0xa5, 0x17, 0x37, 0xfd, 0xd5, 0x81, 0x27, 0x2b, 0x7f, 0x24, 0xda, 0xbf, 0x35, 0xdb, 0x8a, 0x45,
|
||||
0xe1, 0x7e, 0xf9, 0x3f, 0x94, 0xa6, 0xa5, 0x41, 0xf3, 0xaf, 0xf3, 0x2d, 0xe7, 0xef, 0xf3, 0x2d,
|
||||
0xe7, 0x9f, 0xf3, 0x2d, 0x27, 0x7e, 0xa0, 0x7f, 0xc4, 0x8b, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff,
|
||||
0xbe, 0x05, 0x6e, 0x91, 0xc0, 0x08, 0x00, 0x00,
|
||||
var fileDescriptor_services_bf909c06e4b5edfe = []byte{
|
||||
// 920 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xdd, 0x6e, 0xe3, 0x44,
|
||||
0x14, 0xc6, 0xd9, 0xee, 0xdf, 0x49, 0xd2, 0xa6, 0x43, 0xb7, 0x64, 0x83, 0x68, 0xb3, 0x5e, 0x01,
|
||||
0xdd, 0x15, 0xeb, 0xb4, 0x5e, 0x09, 0x0a, 0x5c, 0x25, 0x55, 0x50, 0xd1, 0xae, 0xda, 0xe2, 0x84,
|
||||
0x5d, 0x21, 0x90, 0xac, 0x49, 0x72, 0x70, 0xac, 0xda, 0x1e, 0xe3, 0x99, 0x44, 0xf4, 0x19, 0xe0,
|
||||
0x82, 0x2b, 0x5e, 0x82, 0xa7, 0xe0, 0x8e, 0x4b, 0x1e, 0x01, 0xf5, 0x49, 0xd0, 0xcc, 0xd8, 0x8e,
|
||||
0x9b, 0xd6, 0x6d, 0xe1, 0x72, 0xce, 0xf9, 0xce, 0x37, 0x67, 0xbe, 0x39, 0xe7, 0x03, 0x33, 0x4e,
|
||||
0x98, 0x60, 0x9d, 0x11, 0xd2, 0x31, 0x8b, 0x3a, 0x49, 0x3c, 0xee, 0xcc, 0xf7, 0x3a, 0x1c, 0x93,
|
||||
0xb9, 0x3f, 0x46, 0x6e, 0xa9, 0x24, 0xd9, 0x44, 0x31, 0xc5, 0x04, 0x67, 0xa1, 0xa5, 0x61, 0x56,
|
||||
0x12, 0x8f, 0xad, 0xf9, 0x5e, 0x6b, 0xfb, 0x42, 0x6d, 0x6c, 0xc7, 0xb2, 0x56, 0x9c, 0xc5, 0x59,
|
||||
0x61, 0xeb, 0x7d, 0x8f, 0x31, 0x2f, 0xc0, 0x8e, 0x3a, 0x8d, 0x66, 0x3f, 0x76, 0x30, 0x8c, 0xc5,
|
||||
0x59, 0x9a, 0xdc, 0x5e, 0x4e, 0x0a, 0x3f, 0x44, 0x2e, 0x68, 0x18, 0x6b, 0x80, 0xf9, 0x0d, 0x90,
|
||||
0x83, 0x29, 0xf5, 0xa3, 0x81, 0xa0, 0x89, 0x70, 0x90, 0xc7, 0x2c, 0xe2, 0x48, 0x9a, 0x70, 0x9f,
|
||||
0xcb, 0x00, 0x4e, 0x9a, 0x46, 0xdb, 0xd8, 0x79, 0xe0, 0x64, 0x47, 0xf2, 0x04, 0x6a, 0x1e, 0x46,
|
||||
0xc8, 0x7d, 0xee, 0x4a, 0xaa, 0x66, 0xa5, 0x6d, 0xec, 0xac, 0x38, 0xd5, 0x34, 0x36, 0xf4, 0x43,
|
||||
0x34, 0xff, 0xa8, 0xc0, 0xea, 0x49, 0xc2, 0x62, 0xc6, 0xd1, 0xc1, 0x9f, 0x66, 0xc8, 0x05, 0xd9,
|
||||
0x86, 0x6a, 0x4c, 0x13, 0x8c, 0x84, 0x3b, 0xa5, 0x7c, 0xaa, 0x38, 0x6b, 0x0e, 0xe8, 0xd0, 0x21,
|
||||
0xe5, 0x53, 0x09, 0xe0, 0x01, 0x13, 0x6e, 0x34, 0x0b, 0x47, 0x98, 0xa4, 0xac, 0x20, 0x43, 0x47,
|
||||
0x2a, 0x42, 0x76, 0x61, 0x23, 0xa1, 0xd1, 0x84, 0x32, 0x37, 0xc1, 0x39, 0xd2, 0x40, 0x11, 0xbd,
|
||||
0xb4, 0x9b, 0x77, 0x14, 0x15, 0xd1, 0x39, 0x47, 0xa5, 0x0e, 0x55, 0x86, 0x74, 0xe0, 0x5d, 0x2a,
|
||||
0x84, 0x7c, 0xac, 0xf0, 0x59, 0xe4, 0x8e, 0x7c, 0x11, 0x52, 0x7e, 0xda, 0x5c, 0xd1, 0x05, 0x85,
|
||||
0x54, 0x4f, 0x67, 0xc8, 0x17, 0xf0, 0xb8, 0x58, 0x40, 0x3d, 0x2f, 0x41, 0x8f, 0x0a, 0x74, 0xb9,
|
||||
0xef, 0x35, 0xef, 0xb6, 0xef, 0xec, 0xac, 0x38, 0xef, 0x15, 0x00, 0xdd, 0x2c, 0x3f, 0xf0, 0x3d,
|
||||
0xb2, 0x0f, 0x0f, 0x73, 0x65, 0x9b, 0xf7, 0xda, 0xc6, 0x4e, 0xd5, 0x6e, 0x59, 0x5a, 0x7b, 0x2b,
|
||||
0xd3, 0xde, 0x1a, 0x66, 0x08, 0x67, 0x01, 0x36, 0x77, 0x61, 0x2d, 0x17, 0x2b, 0x55, 0xff, 0x03,
|
||||
0x80, 0x51, 0xc0, 0xc6, 0xa7, 0x45, 0xb1, 0x1e, 0xaa, 0x88, 0x7c, 0x9a, 0xf9, 0x19, 0x6c, 0xa4,
|
||||
0x15, 0xc9, 0xd7, 0xd1, 0x04, 0x7f, 0x2e, 0x88, 0x5c, 0xd4, 0xd0, 0x58, 0xd6, 0xd0, 0x7c, 0x01,
|
||||
0x8f, 0x96, 0x0a, 0xd3, 0x0b, 0x37, 0xe0, 0xae, 0x2f, 0x03, 0x69, 0x8d, 0x3e, 0x98, 0x36, 0xac,
|
||||
0x0f, 0x04, 0x15, 0xe8, 0x30, 0x26, 0x8a, 0xbd, 0xc9, 0xf7, 0xa3, 0x9b, 0x30, 0x26, 0xb2, 0xde,
|
||||
0x78, 0x06, 0x33, 0xdf, 0x40, 0xbd, 0xab, 0x24, 0xca, 0x9a, 0xea, 0x43, 0xb5, 0xa0, 0x99, 0x2a,
|
||||
0xa8, 0xda, 0x4f, 0xad, 0xe5, 0x61, 0x8f, 0xed, 0xd8, 0x9a, 0xef, 0x59, 0xdd, 0x05, 0xd4, 0x29,
|
||||
0xd6, 0x99, 0x5f, 0xc2, 0x6a, 0xc6, 0x9b, 0x36, 0xf2, 0x0c, 0x1a, 0xc5, 0xdf, 0x2a, 0x48, 0xb5,
|
||||
0x56, 0x88, 0x2b, 0xc1, 0x7e, 0x31, 0x00, 0xba, 0x9c, 0xfb, 0x5e, 0x14, 0x62, 0x24, 0xe4, 0x13,
|
||||
0xe2, 0xd9, 0x28, 0xf0, 0xc7, 0xee, 0x29, 0x9e, 0x65, 0x4f, 0xd0, 0x91, 0x57, 0x78, 0x26, 0xc5,
|
||||
0xe0, 0x53, 0x9a, 0x4c, 0xd2, 0x21, 0xd4, 0x07, 0xf2, 0x14, 0xea, 0x9a, 0x16, 0x13, 0x57, 0x4a,
|
||||
0xaa, 0x06, 0x6f, 0xc5, 0xa9, 0x65, 0xc1, 0x41, 0xc0, 0x84, 0x04, 0xc5, 0xa9, 0xc0, 0x1a, 0xb4,
|
||||
0xa2, 0x41, 0x59, 0x50, 0x82, 0xcc, 0x4f, 0xe1, 0xd1, 0x1b, 0x1a, 0xf8, 0x13, 0x2a, 0xd8, 0xc5,
|
||||
0xff, 0xbb, 0xbe, 0x2f, 0xd3, 0x82, 0xcd, 0xe5, 0xba, 0x6b, 0xbf, 0x6f, 0x04, 0xed, 0x1c, 0xdf,
|
||||
0x8f, 0xd9, 0x78, 0xba, 0x90, 0x80, 0x17, 0x46, 0x06, 0x65, 0xca, 0x55, 0xeb, 0x9d, 0x8d, 0x8c,
|
||||
0x0a, 0x29, 0x43, 0x58, 0xea, 0xa9, 0xb2, 0xdc, 0x93, 0x07, 0x4f, 0xae, 0xb9, 0x23, 0x6d, 0xaf,
|
||||
0x07, 0x40, 0xf3, 0xb0, 0xe2, 0xa8, 0xda, 0xa6, 0x75, 0xb5, 0xdd, 0x59, 0x0b, 0x02, 0xa7, 0x50,
|
||||
0xf5, 0x7c, 0x1f, 0xea, 0xf9, 0x45, 0x0e, 0x0b, 0x90, 0x54, 0xe1, 0xfe, 0xb7, 0x47, 0xaf, 0x8e,
|
||||
0x8e, 0xdf, 0x1e, 0x35, 0xde, 0x21, 0x35, 0x78, 0xd0, 0x1d, 0x0e, 0xfb, 0x83, 0x61, 0xdf, 0x69,
|
||||
0x18, 0xf2, 0x74, 0xe2, 0x1c, 0x9f, 0x1c, 0x0f, 0xfa, 0x4e, 0xa3, 0x62, 0xff, 0x5a, 0x81, 0x7a,
|
||||
0x4f, 0x5d, 0x31, 0xd0, 0x86, 0x4b, 0xbe, 0x83, 0xf5, 0xb7, 0xd4, 0x17, 0x5f, 0xb1, 0x64, 0xe1,
|
||||
0x7c, 0x64, 0xf3, 0xd2, 0xb6, 0xf6, 0xa5, 0x8d, 0xb6, 0x9e, 0x97, 0x35, 0x7a, 0xd9, 0x35, 0x77,
|
||||
0x0d, 0xf2, 0x1a, 0xea, 0x07, 0x34, 0x62, 0x91, 0x3f, 0xa6, 0xc1, 0x21, 0xd2, 0x49, 0x29, 0x6d,
|
||||
0xe9, 0x06, 0xe8, 0x56, 0x7b, 0x72, 0xd9, 0x89, 0x03, 0xeb, 0xaf, 0xa9, 0x1c, 0xaf, 0xc2, 0x5a,
|
||||
0xfc, 0x77, 0xc6, 0x42, 0xf1, 0xae, 0x61, 0x47, 0xb0, 0xd6, 0xcd, 0x46, 0x36, 0xd5, 0xe3, 0x7b,
|
||||
0x00, 0x1d, 0x52, 0x1d, 0x7f, 0x58, 0xfa, 0x33, 0xc5, 0xbd, 0x6e, 0x7d, 0x74, 0x13, 0x4c, 0x6b,
|
||||
0x62, 0xff, 0x59, 0xc9, 0xfd, 0x2d, 0xbf, 0x30, 0x80, 0xfa, 0x05, 0x1f, 0x22, 0x9f, 0x94, 0x91,
|
||||
0x5d, 0xe5, 0x73, 0xad, 0x17, 0xb7, 0x44, 0xa7, 0xe3, 0xf7, 0x03, 0xd4, 0xd2, 0x84, 0x56, 0xf5,
|
||||
0x36, 0xd2, 0xb7, 0x3e, 0xbe, 0xe1, 0x8e, 0x9c, 0x7d, 0x04, 0x8d, 0x03, 0x16, 0xc6, 0x33, 0x81,
|
||||
0xb9, 0x57, 0xde, 0xee, 0x86, 0x67, 0x65, 0x37, 0x5c, 0xf2, 0x5c, 0xfb, 0xf7, 0x0a, 0x34, 0xf2,
|
||||
0xe9, 0xcf, 0x44, 0x64, 0xb0, 0x7a, 0xd1, 0x0e, 0x48, 0xa9, 0x2e, 0x57, 0xda, 0x4d, 0xcb, 0xba,
|
||||
0x2d, 0x3c, 0x7d, 0xe9, 0x6f, 0x06, 0x3c, 0x2e, 0x5d, 0x76, 0xb2, 0x7f, 0x23, 0x5b, 0x89, 0x07,
|
||||
0xb5, 0x3e, 0xff, 0x1f, 0x95, 0xba, 0xa5, 0x5e, 0xed, 0xaf, 0xf3, 0x2d, 0xe3, 0xef, 0xf3, 0x2d,
|
||||
0xe3, 0x9f, 0xf3, 0x2d, 0x63, 0x74, 0x4f, 0x6d, 0xc4, 0xcb, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff,
|
||||
0xc6, 0x16, 0xb6, 0xab, 0x6e, 0x09, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@@ -7,11 +7,10 @@ import "google/protobuf/empty.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
service BeaconService {
|
||||
// CanonicalHead can be called on demand to fetch the current, head block of a
|
||||
// beacon node.
|
||||
rpc WaitForChainStart(google.protobuf.Empty) returns (stream ChainStartResponse);
|
||||
// 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);
|
||||
// LatestAttestation streams the latest aggregated attestation to connected
|
||||
// validator clients.
|
||||
// LatestAttestation streams the latest aggregated attestation to connected validator clients.
|
||||
rpc LatestAttestation(google.protobuf.Empty) returns (stream ethereum.beacon.p2p.v1.Attestation);
|
||||
}
|
||||
|
||||
@@ -30,6 +29,11 @@ service ValidatorService {
|
||||
rpc ValidatorEpochAssignments(ValidatorEpochAssignmentsRequest) returns (ValidatorEpochAssignmentsResponse);
|
||||
}
|
||||
|
||||
message ChainStartResponse {
|
||||
bool started = 1;
|
||||
uint64 genesis_time = 2;
|
||||
}
|
||||
|
||||
message ProposeRequest {
|
||||
bytes parent_hash = 1;
|
||||
uint64 slot_number = 2;
|
||||
|
||||
@@ -43,7 +43,6 @@ func (s *ServiceRegistry) StartAll() {
|
||||
log.Debugf("Starting service type %v", kind)
|
||||
s.services[kind].Start()
|
||||
}
|
||||
log.Info("All services started")
|
||||
}
|
||||
|
||||
// StopAll ends every service in reverse order of registration, logging a
|
||||
|
||||
@@ -29,8 +29,8 @@ func (s *SlotTicker) Done() {
|
||||
}
|
||||
|
||||
// GetSlotTicker is the constructor for SlotTicker.
|
||||
func GetSlotTicker(genesisTime time.Time, slotDuration uint64) SlotTicker {
|
||||
ticker := SlotTicker{
|
||||
func GetSlotTicker(genesisTime time.Time, slotDuration uint64) *SlotTicker {
|
||||
ticker := &SlotTicker{
|
||||
c: make(chan uint64),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func TestSlotTicker(t *testing.T) {
|
||||
ticker := SlotTicker{
|
||||
ticker := &SlotTicker{
|
||||
c: make(chan uint64),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
@@ -54,7 +54,7 @@ func TestSlotTicker(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSlotTickerGenesis(t *testing.T) {
|
||||
ticker := SlotTicker{
|
||||
ticker := &SlotTicker{
|
||||
c: make(chan uint64),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
||||
@@ -13,8 +13,11 @@ go_library(
|
||||
"//proto/beacon/rpc/v1:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/slotticker:go_default_library",
|
||||
"@com_github_gogo_protobuf//types:go_default_library",
|
||||
"@com_github_opentracing_opentracing_go//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_grpc//credentials:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -34,7 +37,9 @@ go_test(
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//validator/internal:go_default_library",
|
||||
"@com_github_gogo_protobuf//types:go_default_library",
|
||||
"@com_github_golang_mock//gomock:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -12,6 +12,7 @@ type fakeValidator struct {
|
||||
InitializeCalled bool
|
||||
DoneCalled bool
|
||||
WaitForActivationCalled bool
|
||||
WaitForChainStartCalled bool
|
||||
NextSlotRet <-chan uint64
|
||||
NextSlotCalled bool
|
||||
UpdateAssignmentsCalled bool
|
||||
@@ -34,6 +35,10 @@ func (fv *fakeValidator) Done() {
|
||||
fv.DoneCalled = true
|
||||
}
|
||||
|
||||
func (fv *fakeValidator) WaitForChainStart(_ context.Context) {
|
||||
fv.WaitForChainStartCalled = true
|
||||
}
|
||||
|
||||
func (fv *fakeValidator) WaitForActivation(_ context.Context) {
|
||||
fv.WaitForActivationCalled = true
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
type Validator interface {
|
||||
Initialize(ctx context.Context)
|
||||
Done()
|
||||
WaitForChainStart(ctx context.Context)
|
||||
WaitForActivation(ctx context.Context)
|
||||
NextSlot() <-chan uint64
|
||||
UpdateAssignments(ctx context.Context, slot uint64) error
|
||||
@@ -33,17 +34,16 @@ type Validator interface {
|
||||
func run(ctx context.Context, v Validator) {
|
||||
v.Initialize(ctx)
|
||||
defer v.Done()
|
||||
v.WaitForChainStart(ctx)
|
||||
v.WaitForActivation(ctx)
|
||||
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "processSlot")
|
||||
defer span.Finish()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Info("Context cancelled, stopping validator")
|
||||
return // Exit if context is cancelled.
|
||||
case slot := <-v.NextSlot():
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "processSlot")
|
||||
defer span.Finish()
|
||||
|
||||
if err := v.UpdateAssignments(ctx, slot); err != nil {
|
||||
log.WithField("error", err).Error("Failed to update assignments")
|
||||
continue
|
||||
|
||||
@@ -32,6 +32,14 @@ func TestRunCleansUpValidator(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunWaitsForChainStart(t *testing.T) {
|
||||
v := &fakeValidator{}
|
||||
run(cancelledContext(), v)
|
||||
if !v.WaitForChainStartCalled {
|
||||
t.Error("Expected WaitForChainStart() to be called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunWaitsForActivation(t *testing.T) {
|
||||
v := &fakeValidator{}
|
||||
run(cancelledContext(), v)
|
||||
|
||||
@@ -2,7 +2,12 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -14,27 +19,65 @@ type ValidatorService struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
validator Validator
|
||||
conn *grpc.ClientConn
|
||||
endpoint string
|
||||
withCert string
|
||||
}
|
||||
|
||||
// Config for the validator service.
|
||||
type Config struct {
|
||||
Endpoint string
|
||||
CertFlag string
|
||||
}
|
||||
|
||||
// NewValidatorService creates a new validator service for the service
|
||||
// registry.
|
||||
func NewValidatorService(ctx context.Context) *ValidatorService {
|
||||
func NewValidatorService(ctx context.Context, cfg *Config) *ValidatorService {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
return &ValidatorService{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
endpoint: cfg.Endpoint,
|
||||
withCert: cfg.CertFlag,
|
||||
}
|
||||
}
|
||||
|
||||
// Start the validator service. Launches the main go routine for the validator
|
||||
// client.
|
||||
func (v *ValidatorService) Start() {
|
||||
var dialOpt grpc.DialOption
|
||||
if v.withCert != "" {
|
||||
creds, err := credentials.NewClientTLSFromFile(v.withCert, "")
|
||||
if err != nil {
|
||||
log.Errorf("Could not get valid credentials: %v", err)
|
||||
return
|
||||
}
|
||||
dialOpt = grpc.WithTransportCredentials(creds)
|
||||
} else {
|
||||
dialOpt = grpc.WithInsecure()
|
||||
log.Warn("You are using an insecure gRPC connection! Please provide a certificate and key to use a secure connection.")
|
||||
}
|
||||
conn, err := grpc.DialContext(v.ctx, v.endpoint, dialOpt)
|
||||
if err != nil {
|
||||
log.Errorf("Could not dial endpoint: %s, %v", v.endpoint, err)
|
||||
return
|
||||
}
|
||||
log.Info("Successfully started gRPC connection")
|
||||
v.conn = conn
|
||||
v.validator = &validator{
|
||||
beaconClient: pb.NewBeaconServiceClient(v.conn),
|
||||
validatorClient: pb.NewValidatorServiceClient(v.conn),
|
||||
}
|
||||
go run(v.ctx, v.validator)
|
||||
}
|
||||
|
||||
// Stop the validator service.
|
||||
func (v *ValidatorService) Stop() error {
|
||||
v.cancel()
|
||||
log.Info("Stopping service")
|
||||
if v.conn != nil {
|
||||
return v.conn.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -42,5 +85,8 @@ func (v *ValidatorService) Stop() error {
|
||||
//
|
||||
// WIP - not done.
|
||||
func (v *ValidatorService) Status() error {
|
||||
if v.conn == nil {
|
||||
return errors.New("no connection to beacon RPC")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,10 +2,14 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
var _ = shared.Service(&ValidatorService{})
|
||||
@@ -27,3 +31,53 @@ func TestStop_cancelsContext(t *testing.T) {
|
||||
case <-vs.ctx.Done():
|
||||
}
|
||||
}
|
||||
|
||||
func TestLifecycle(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
// Use cancelled context so that the run function exits immediately..
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
validatorService := NewValidatorService(
|
||||
ctx,
|
||||
&Config{
|
||||
Endpoint: "merkle tries",
|
||||
CertFlag: "alice.crt",
|
||||
},
|
||||
)
|
||||
validatorService.Start()
|
||||
if err := validatorService.Stop(); err != nil {
|
||||
t.Fatalf("Could not stop service: %v", err)
|
||||
}
|
||||
testutil.AssertLogsContain(t, hook, "Stopping service")
|
||||
}
|
||||
|
||||
func TestLifecycle_WithInsecure(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
// Use cancelled context so that the run function exits immediately.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
validatorService := NewValidatorService(
|
||||
ctx,
|
||||
&Config{
|
||||
Endpoint: "merkle tries",
|
||||
},
|
||||
)
|
||||
validatorService.Start()
|
||||
testutil.AssertLogsContain(t, hook, "You are using an insecure gRPC connection")
|
||||
if err := validatorService.Stop(); err != nil {
|
||||
t.Fatalf("Could not stop service: %v", err)
|
||||
}
|
||||
testutil.AssertLogsContain(t, hook, "Stopping service")
|
||||
}
|
||||
|
||||
func TestStatus(t *testing.T) {
|
||||
validatorService := NewValidatorService(
|
||||
context.Background(),
|
||||
&Config{
|
||||
Endpoint: "merkle tries",
|
||||
},
|
||||
)
|
||||
if err := validatorService.Status(); !strings.Contains(err.Error(), "no connection") {
|
||||
t.Errorf("Expected status check to fail if no connection is found, received: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/opentracing/opentracing-go"
|
||||
|
||||
@@ -14,10 +18,11 @@ import (
|
||||
//
|
||||
// WIP - not done.
|
||||
type validator struct {
|
||||
ticker slotticker.SlotTicker
|
||||
assignment *pb.Assignment
|
||||
|
||||
genesisTime uint64
|
||||
ticker *slotticker.SlotTicker
|
||||
assignment *pb.Assignment
|
||||
validatorClient pb.ValidatorServiceClient
|
||||
beaconClient pb.BeaconServiceClient
|
||||
pubKey []byte
|
||||
}
|
||||
|
||||
@@ -27,9 +32,6 @@ type validator struct {
|
||||
func (v *validator) Initialize(ctx context.Context) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "validator.Initialize")
|
||||
defer span.Finish()
|
||||
|
||||
cfg := params.BeaconConfig()
|
||||
v.ticker = slotticker.GetSlotTicker(cfg.GenesisTime, cfg.SlotDuration)
|
||||
}
|
||||
|
||||
// Done cleans up the validator.
|
||||
@@ -37,14 +39,55 @@ func (v *validator) Done() {
|
||||
v.ticker.Done()
|
||||
}
|
||||
|
||||
// WaitForChainStart checks whether the beacon node has started its runtime. That is,
|
||||
// it calls to the beacon node which then verifies the ETH1.0 deposit contract logs to check
|
||||
// for the ChainStart log to have been emitted. If so, it starts a ticker based on the ChainStart
|
||||
// unix timestamp which will be used to keep track of time within the validator client.
|
||||
func (v *validator) WaitForChainStart(ctx context.Context) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "validator.WaitForChainStart")
|
||||
defer span.Finish()
|
||||
// First, check if the beacon chain has started.
|
||||
stream, err := v.beaconClient.WaitForChainStart(ctx, &ptypes.Empty{})
|
||||
if err != nil {
|
||||
log.Errorf("Could not setup beacon chain ChainStart streaming client: %v", err)
|
||||
return
|
||||
}
|
||||
for {
|
||||
log.Info("Waiting for beacon chain start log from the ETH 1.0 deposit contract...")
|
||||
chainStartRes, err := stream.Recv()
|
||||
// If the stream is closed, we stop the loop.
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
// If context is canceled we stop the loop.
|
||||
if ctx.Err() == context.Canceled {
|
||||
log.Debugf("Context has been canceled so shutting down the loop: %v", ctx.Err())
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf("Could not receive ChainStart from stream: %v", err)
|
||||
continue
|
||||
}
|
||||
v.genesisTime = chainStartRes.GenesisTime
|
||||
break
|
||||
}
|
||||
log.Infof("Beacon chain initialized at unix time: %v", time.Unix(int64(v.genesisTime), 0))
|
||||
// Once the ChainStart log is received, we update the genesis time of the validator client
|
||||
// and begin a slot ticker used to track the current slot the beacon node is in.
|
||||
v.ticker = slotticker.GetSlotTicker(time.Unix(int64(v.genesisTime), 0), params.BeaconConfig().SlotDuration)
|
||||
}
|
||||
|
||||
// WaitForActivation checks whether the validator pubkey is in the active
|
||||
// validator set. If not, this operation will block until an activation is
|
||||
// validator set. If not, this operation will block until an activation message is
|
||||
// received.
|
||||
//
|
||||
// WIP - not done.
|
||||
func (v *validator) WaitForActivation(ctx context.Context) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "validator.WaitForActivation")
|
||||
defer span.Finish()
|
||||
// First, check if the validator has deposited into the Deposit Contract.
|
||||
// If the validator has deposited, subscribe to a stream receiving the activation status.
|
||||
// of the validator until a final ACTIVATED check if received, then this function can return.
|
||||
}
|
||||
|
||||
// NextSlot emits the next slot number at the start time of that slot.
|
||||
@@ -99,7 +142,6 @@ func (v *validator) RoleAt(slot uint64) pb.ValidatorRole {
|
||||
func (v *validator) ProposeBlock(ctx context.Context, slot uint64) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "validator.ProposeBlock")
|
||||
defer span.Finish()
|
||||
|
||||
}
|
||||
|
||||
// AttestToBlockHead
|
||||
@@ -108,5 +150,4 @@ func (v *validator) ProposeBlock(ctx context.Context, slot uint64) {
|
||||
func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "validator.AttestToBlockHead")
|
||||
defer span.Finish()
|
||||
|
||||
}
|
||||
|
||||
@@ -3,19 +3,143 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/validator/internal"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetOutput(ioutil.Discard)
|
||||
}
|
||||
|
||||
var _ = Validator(&validator{})
|
||||
|
||||
var fakePubKey = []byte{1}
|
||||
|
||||
func TestUpdateAssignmentsDoesNothingWhenNotEpochStart(t *testing.T) {
|
||||
func TestWaitForChainStart_SetsChainStartGenesisTime(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := internal.NewMockBeaconServiceClient(ctrl)
|
||||
|
||||
v := validator{
|
||||
pubKey: fakePubKey,
|
||||
beaconClient: client,
|
||||
}
|
||||
genesis := uint64(time.Unix(0, 0).Unix())
|
||||
clientStream := internal.NewMockBeaconService_WaitForChainStartClient(ctrl)
|
||||
client.EXPECT().WaitForChainStart(
|
||||
gomock.Any(),
|
||||
&ptypes.Empty{},
|
||||
).Return(clientStream, nil)
|
||||
clientStream.EXPECT().Recv().Return(
|
||||
&pb.ChainStartResponse{
|
||||
Started: true,
|
||||
GenesisTime: genesis,
|
||||
},
|
||||
nil,
|
||||
)
|
||||
v.WaitForChainStart(context.Background())
|
||||
if v.genesisTime != genesis {
|
||||
t.Errorf("Expected chain start time to equal %d, received %d", genesis, v.genesisTime)
|
||||
}
|
||||
if v.ticker == nil {
|
||||
t.Error("Expected ticker to be set, received nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitForChainStart_ContextCanceled(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := internal.NewMockBeaconServiceClient(ctrl)
|
||||
|
||||
v := validator{
|
||||
pubKey: fakePubKey,
|
||||
beaconClient: client,
|
||||
}
|
||||
genesis := uint64(time.Unix(0, 0).Unix())
|
||||
clientStream := internal.NewMockBeaconService_WaitForChainStartClient(ctrl)
|
||||
client.EXPECT().WaitForChainStart(
|
||||
gomock.Any(),
|
||||
&ptypes.Empty{},
|
||||
).Return(clientStream, nil)
|
||||
clientStream.EXPECT().Recv().Return(
|
||||
&pb.ChainStartResponse{
|
||||
Started: true,
|
||||
GenesisTime: genesis,
|
||||
},
|
||||
nil,
|
||||
)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
v.WaitForChainStart(ctx)
|
||||
testutil.AssertLogsContain(t, hook, "Context has been canceled")
|
||||
}
|
||||
|
||||
func TestWaitForChainStart_StreamSetupFails(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := internal.NewMockBeaconServiceClient(ctrl)
|
||||
|
||||
v := validator{
|
||||
pubKey: fakePubKey,
|
||||
beaconClient: client,
|
||||
}
|
||||
clientStream := internal.NewMockBeaconService_WaitForChainStartClient(ctrl)
|
||||
client.EXPECT().WaitForChainStart(
|
||||
gomock.Any(),
|
||||
&ptypes.Empty{},
|
||||
).Return(clientStream, errors.New("failed stream"))
|
||||
v.WaitForChainStart(context.Background())
|
||||
testutil.AssertLogsContain(t, hook, "Could not setup beacon chain ChainStart streaming client")
|
||||
}
|
||||
|
||||
func TestWaitForChainStart_ReceiveErrorFromStream(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := internal.NewMockBeaconServiceClient(ctrl)
|
||||
|
||||
v := validator{
|
||||
pubKey: fakePubKey,
|
||||
beaconClient: client,
|
||||
}
|
||||
genesis := uint64(time.Unix(0, 0).Unix())
|
||||
clientStream := internal.NewMockBeaconService_WaitForChainStartClient(ctrl)
|
||||
client.EXPECT().WaitForChainStart(
|
||||
gomock.Any(),
|
||||
&ptypes.Empty{},
|
||||
).Return(clientStream, nil)
|
||||
clientStream.EXPECT().Recv().Return(
|
||||
nil,
|
||||
errors.New("fails"),
|
||||
)
|
||||
clientStream.EXPECT().Recv().Return(
|
||||
&pb.ChainStartResponse{
|
||||
Started: true,
|
||||
GenesisTime: genesis,
|
||||
},
|
||||
io.EOF,
|
||||
)
|
||||
v.WaitForChainStart(context.Background())
|
||||
testutil.AssertLogsContain(t, hook, "Could not receive ChainStart from stream")
|
||||
}
|
||||
|
||||
func TestUpdateAssignments_DoesNothingWhenNotEpochStart(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := internal.NewMockValidatorServiceClient(ctrl)
|
||||
@@ -30,10 +154,12 @@ func TestUpdateAssignmentsDoesNothingWhenNotEpochStart(t *testing.T) {
|
||||
gomock.Any(),
|
||||
).Times(0)
|
||||
|
||||
v.UpdateAssignments(context.Background(), slot)
|
||||
if err := v.UpdateAssignments(context.Background(), slot); err != nil {
|
||||
t.Errorf("Could not update assignments: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateAssignmentsReturnsError(t *testing.T) {
|
||||
func TestUpdateAssignments_ReturnsError(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := internal.NewMockValidatorServiceClient(ctrl)
|
||||
@@ -56,7 +182,7 @@ func TestUpdateAssignmentsReturnsError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateAssignmentsDoesUpdateAssignments(t *testing.T) {
|
||||
func TestUpdateAssignments_DoesUpdateAssignments(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := internal.NewMockValidatorServiceClient(ctrl)
|
||||
@@ -77,7 +203,9 @@ func TestUpdateAssignmentsDoesUpdateAssignments(t *testing.T) {
|
||||
gomock.Any(),
|
||||
).Return(resp, nil)
|
||||
|
||||
v.UpdateAssignments(context.Background(), slot)
|
||||
if err := v.UpdateAssignments(context.Background(), slot); err != nil {
|
||||
t.Fatalf("Could not update assignments: %v", err)
|
||||
}
|
||||
|
||||
if v.assignment.ProposerSlot != 67 {
|
||||
t.Errorf("Unexpected validator assignments. want=%v got=%v", 67, v.assignment.ProposerSlot)
|
||||
|
||||
@@ -17,5 +17,6 @@ go_library(
|
||||
"@com_github_gogo_protobuf//types:go_default_library",
|
||||
"@com_github_golang_mock//gomock:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_grpc//metadata:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: BeaconServiceClient)
|
||||
// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: BeaconServiceClient,BeaconService_LatestAttestationClient,BeaconService_WaitForChainStartClient)
|
||||
|
||||
package internal
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
v1 "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
v10 "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
grpc "google.golang.org/grpc"
|
||||
metadata "google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
// MockBeaconServiceClient is a mock of BeaconServiceClient interface
|
||||
@@ -72,3 +73,239 @@ func (mr *MockBeaconServiceClientMockRecorder) LatestAttestation(arg0, arg1 inte
|
||||
varargs := append([]interface{}{arg0, arg1}, arg2...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatestAttestation", reflect.TypeOf((*MockBeaconServiceClient)(nil).LatestAttestation), varargs...)
|
||||
}
|
||||
|
||||
// WaitForChainStart mocks base method
|
||||
func (m *MockBeaconServiceClient) WaitForChainStart(arg0 context.Context, arg1 *types.Empty, arg2 ...grpc.CallOption) (v10.BeaconService_WaitForChainStartClient, error) {
|
||||
varargs := []interface{}{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "WaitForChainStart", varargs...)
|
||||
ret0, _ := ret[0].(v10.BeaconService_WaitForChainStartClient)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// WaitForChainStart indicates an expected call of WaitForChainStart
|
||||
func (mr *MockBeaconServiceClientMockRecorder) WaitForChainStart(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
|
||||
varargs := append([]interface{}{arg0, arg1}, arg2...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForChainStart", reflect.TypeOf((*MockBeaconServiceClient)(nil).WaitForChainStart), varargs...)
|
||||
}
|
||||
|
||||
// MockBeaconService_LatestAttestationClient is a mock of BeaconService_LatestAttestationClient interface
|
||||
type MockBeaconService_LatestAttestationClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockBeaconService_LatestAttestationClientMockRecorder
|
||||
}
|
||||
|
||||
// MockBeaconService_LatestAttestationClientMockRecorder is the mock recorder for MockBeaconService_LatestAttestationClient
|
||||
type MockBeaconService_LatestAttestationClientMockRecorder struct {
|
||||
mock *MockBeaconService_LatestAttestationClient
|
||||
}
|
||||
|
||||
// NewMockBeaconService_LatestAttestationClient creates a new mock instance
|
||||
func NewMockBeaconService_LatestAttestationClient(ctrl *gomock.Controller) *MockBeaconService_LatestAttestationClient {
|
||||
mock := &MockBeaconService_LatestAttestationClient{ctrl: ctrl}
|
||||
mock.recorder = &MockBeaconService_LatestAttestationClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockBeaconService_LatestAttestationClient) EXPECT() *MockBeaconService_LatestAttestationClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// CloseSend mocks base method
|
||||
func (m *MockBeaconService_LatestAttestationClient) CloseSend() error {
|
||||
ret := m.ctrl.Call(m, "CloseSend")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CloseSend indicates an expected call of CloseSend
|
||||
func (mr *MockBeaconService_LatestAttestationClientMockRecorder) CloseSend() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockBeaconService_LatestAttestationClient)(nil).CloseSend))
|
||||
}
|
||||
|
||||
// Context mocks base method
|
||||
func (m *MockBeaconService_LatestAttestationClient) 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_LatestAttestationClientMockRecorder) Context() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBeaconService_LatestAttestationClient)(nil).Context))
|
||||
}
|
||||
|
||||
// Header mocks base method
|
||||
func (m *MockBeaconService_LatestAttestationClient) 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_LatestAttestationClientMockRecorder) Header() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockBeaconService_LatestAttestationClient)(nil).Header))
|
||||
}
|
||||
|
||||
// Recv mocks base method
|
||||
func (m *MockBeaconService_LatestAttestationClient) Recv() (*v1.Attestation, error) {
|
||||
ret := m.ctrl.Call(m, "Recv")
|
||||
ret0, _ := ret[0].(*v1.Attestation)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Recv indicates an expected call of Recv
|
||||
func (mr *MockBeaconService_LatestAttestationClientMockRecorder) Recv() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockBeaconService_LatestAttestationClient)(nil).Recv))
|
||||
}
|
||||
|
||||
// RecvMsg mocks base method
|
||||
func (m *MockBeaconService_LatestAttestationClient) 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_LatestAttestationClientMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockBeaconService_LatestAttestationClient)(nil).RecvMsg), arg0)
|
||||
}
|
||||
|
||||
// SendMsg mocks base method
|
||||
func (m *MockBeaconService_LatestAttestationClient) 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_LatestAttestationClientMockRecorder) SendMsg(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockBeaconService_LatestAttestationClient)(nil).SendMsg), arg0)
|
||||
}
|
||||
|
||||
// Trailer mocks base method
|
||||
func (m *MockBeaconService_LatestAttestationClient) 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_LatestAttestationClientMockRecorder) Trailer() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockBeaconService_LatestAttestationClient)(nil).Trailer))
|
||||
}
|
||||
|
||||
// MockBeaconService_WaitForChainStartClient is a mock of BeaconService_WaitForChainStartClient interface
|
||||
type MockBeaconService_WaitForChainStartClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockBeaconService_WaitForChainStartClientMockRecorder
|
||||
}
|
||||
|
||||
// MockBeaconService_WaitForChainStartClientMockRecorder is the mock recorder for MockBeaconService_WaitForChainStartClient
|
||||
type MockBeaconService_WaitForChainStartClientMockRecorder struct {
|
||||
mock *MockBeaconService_WaitForChainStartClient
|
||||
}
|
||||
|
||||
// NewMockBeaconService_WaitForChainStartClient creates a new mock instance
|
||||
func NewMockBeaconService_WaitForChainStartClient(ctrl *gomock.Controller) *MockBeaconService_WaitForChainStartClient {
|
||||
mock := &MockBeaconService_WaitForChainStartClient{ctrl: ctrl}
|
||||
mock.recorder = &MockBeaconService_WaitForChainStartClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockBeaconService_WaitForChainStartClient) EXPECT() *MockBeaconService_WaitForChainStartClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// CloseSend mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartClient) CloseSend() error {
|
||||
ret := m.ctrl.Call(m, "CloseSend")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CloseSend indicates an expected call of CloseSend
|
||||
func (mr *MockBeaconService_WaitForChainStartClientMockRecorder) CloseSend() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockBeaconService_WaitForChainStartClient)(nil).CloseSend))
|
||||
}
|
||||
|
||||
// Context mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartClient) 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_WaitForChainStartClientMockRecorder) Context() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBeaconService_WaitForChainStartClient)(nil).Context))
|
||||
}
|
||||
|
||||
// Header mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartClient) 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_WaitForChainStartClientMockRecorder) Header() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockBeaconService_WaitForChainStartClient)(nil).Header))
|
||||
}
|
||||
|
||||
// Recv mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartClient) Recv() (*v10.ChainStartResponse, error) {
|
||||
ret := m.ctrl.Call(m, "Recv")
|
||||
ret0, _ := ret[0].(*v10.ChainStartResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Recv indicates an expected call of Recv
|
||||
func (mr *MockBeaconService_WaitForChainStartClientMockRecorder) Recv() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockBeaconService_WaitForChainStartClient)(nil).Recv))
|
||||
}
|
||||
|
||||
// RecvMsg mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartClient) 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_WaitForChainStartClientMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockBeaconService_WaitForChainStartClient)(nil).RecvMsg), arg0)
|
||||
}
|
||||
|
||||
// SendMsg mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartClient) 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_WaitForChainStartClientMockRecorder) SendMsg(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockBeaconService_WaitForChainStartClient)(nil).SendMsg), arg0)
|
||||
}
|
||||
|
||||
// Trailer mocks base method
|
||||
func (m *MockBeaconService_WaitForChainStartClient) 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_WaitForChainStartClientMockRecorder) Trailer() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockBeaconService_WaitForChainStartClient)(nil).Trailer))
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ go_library(
|
||||
"//shared/prometheus:go_default_library",
|
||||
"//shared/version:go_default_library",
|
||||
"//validator/client:go_default_library",
|
||||
"//validator/types:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli//:go_default_library",
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/validator/types"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared"
|
||||
"github.com/prysmaticlabs/prysm/shared/cmd"
|
||||
"github.com/prysmaticlabs/prysm/shared/debug"
|
||||
@@ -49,7 +51,7 @@ func NewValidatorClient(ctx *cli.Context) (*ValidatorClient, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := ValidatorClient.registerClientService(); err != nil {
|
||||
if err := ValidatorClient.registerClientService(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -119,8 +121,10 @@ func (s *ValidatorClient) registerPrometheusService(ctx *cli.Context) error {
|
||||
return s.services.RegisterService(service)
|
||||
}
|
||||
|
||||
func (s *ValidatorClient) registerClientService() error {
|
||||
v := client.NewValidatorService(context.TODO())
|
||||
|
||||
func (s *ValidatorClient) registerClientService(ctx *cli.Context) error {
|
||||
endpoint := ctx.GlobalString(types.BeaconRPCProviderFlag.Name)
|
||||
v := client.NewValidatorService(context.TODO(), &client.Config{
|
||||
Endpoint: endpoint,
|
||||
})
|
||||
return s.services.RegisterService(v)
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["service.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/validator/rpcclient",
|
||||
visibility = ["//validator:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/beacon/rpc/v1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_grpc//credentials:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["service_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//proto/beacon/rpc/v1:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -1,118 +0,0 @@
|
||||
// Package rpcclient defines a gRPC connection to a beacon node.
|
||||
package rpcclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
var log = logrus.WithField("prefix", "rpc-client")
|
||||
|
||||
// Service for an RPCClient to a Beacon Node.
|
||||
type Service struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
conn *grpc.ClientConn
|
||||
endpoint string
|
||||
withCert string
|
||||
}
|
||||
|
||||
// Config for the RPCClient service.
|
||||
type Config struct {
|
||||
Endpoint string
|
||||
CertFlag string
|
||||
}
|
||||
|
||||
// NewRPCClient sets up a new beacon node RPC client connection.
|
||||
func NewRPCClient(ctx context.Context, cfg *Config) *Service {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
return &Service{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
endpoint: cfg.Endpoint,
|
||||
withCert: cfg.CertFlag,
|
||||
}
|
||||
}
|
||||
|
||||
// Start the grpc connection.
|
||||
func (s *Service) Start() {
|
||||
log.Info("Starting service")
|
||||
var server grpc.DialOption
|
||||
if s.withCert != "" {
|
||||
creds, err := credentials.NewClientTLSFromFile(s.withCert, "")
|
||||
if err != nil {
|
||||
log.Errorf("Could not get valid credentials: %v", err)
|
||||
return
|
||||
}
|
||||
server = grpc.WithTransportCredentials(creds)
|
||||
} else {
|
||||
server = grpc.WithInsecure()
|
||||
log.Warn("You are using an insecure gRPC connection! Please provide a certificate and key to use a secure connection.")
|
||||
}
|
||||
providerURL, err := url.Parse(s.endpoint)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to parse beacon RPC provider endpoint url: %v", err)
|
||||
}
|
||||
conn, err := grpc.Dial(fmt.Sprintf("[%s]:%s", providerURL.Hostname(), providerURL.Port()), server)
|
||||
if err != nil {
|
||||
log.Errorf("Could not dial endpoint: %s, %v", s.endpoint, err)
|
||||
return
|
||||
}
|
||||
s.conn = conn
|
||||
}
|
||||
|
||||
// Stop the dialed connection.
|
||||
func (s *Service) Stop() error {
|
||||
log.Info("Stopping service")
|
||||
if s.conn != nil {
|
||||
return s.conn.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status returns error if there is no connection to the beacon chain RPC.
|
||||
func (s *Service) Status() error {
|
||||
if s.conn == nil {
|
||||
return errors.New("no connection to beacon RPC")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BeaconServiceClient initializes a new beacon gRPC service using
|
||||
// an underlying connection object.
|
||||
// This wrapper is important because the underlying gRPC connection is
|
||||
// only defined after the service .Start() function is called.
|
||||
func (s *Service) BeaconServiceClient() pb.BeaconServiceClient {
|
||||
return pb.NewBeaconServiceClient(s.conn)
|
||||
}
|
||||
|
||||
// ProposerServiceClient initializes a new proposer gRPC service using
|
||||
// an underlying connection object.
|
||||
// This wrapper is important because the underlying gRPC connection is
|
||||
// only defined after the service .Start() function is called.
|
||||
func (s *Service) ProposerServiceClient() pb.ProposerServiceClient {
|
||||
return pb.NewProposerServiceClient(s.conn)
|
||||
}
|
||||
|
||||
// AttesterServiceClient initializes a new attester gRPC service using
|
||||
// an underlying connection object.
|
||||
// This wrapper is important because the underlying gRPC connection is
|
||||
// only defined after the service .Start() function is called.
|
||||
func (s *Service) AttesterServiceClient() pb.AttesterServiceClient {
|
||||
return pb.NewAttesterServiceClient(s.conn)
|
||||
}
|
||||
|
||||
// ValidatorServiceClient initializes a new validator gRPC service using
|
||||
// an underlying connection object.
|
||||
// This wrapper is important because the underlying gRPC connection is
|
||||
// only defined after the service .Start() function is called.
|
||||
func (s *Service) ValidatorServiceClient() pb.ValidatorServiceClient {
|
||||
return pb.NewValidatorServiceClient(s.conn)
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package rpcclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
func TestLifecycle(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
rpcClientService := NewRPCClient(
|
||||
context.Background(),
|
||||
&Config{
|
||||
Endpoint: "merkle tries",
|
||||
CertFlag: "alice.crt",
|
||||
},
|
||||
)
|
||||
rpcClientService.Start()
|
||||
testutil.AssertLogsContain(t, hook, "Starting service")
|
||||
rpcClientService.Stop()
|
||||
testutil.AssertLogsContain(t, hook, "Stopping service")
|
||||
}
|
||||
|
||||
func TestInsecure(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
rpcClientService := NewRPCClient(
|
||||
context.Background(),
|
||||
&Config{
|
||||
Endpoint: "merkle tries",
|
||||
},
|
||||
)
|
||||
rpcClientService.Start()
|
||||
testutil.AssertLogsContain(t, hook, "Starting service")
|
||||
testutil.AssertLogsContain(t, hook, "You are using an insecure gRPC connection")
|
||||
rpcClientService.Stop()
|
||||
testutil.AssertLogsContain(t, hook, "Stopping service")
|
||||
}
|
||||
|
||||
func TestBeaconServiceClient(t *testing.T) {
|
||||
rpcClientService := NewRPCClient(
|
||||
context.Background(),
|
||||
&Config{
|
||||
Endpoint: "merkle tries",
|
||||
},
|
||||
)
|
||||
rpcClientService.conn = nil
|
||||
client := rpcClientService.BeaconServiceClient()
|
||||
if _, ok := client.(pb.BeaconServiceClient); !ok {
|
||||
t.Error("Beacon service client function does not implement interface")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProposerServiceClient(t *testing.T) {
|
||||
rpcClientService := NewRPCClient(
|
||||
context.Background(),
|
||||
&Config{
|
||||
Endpoint: "merkle tries",
|
||||
},
|
||||
)
|
||||
rpcClientService.conn = nil
|
||||
client := rpcClientService.ProposerServiceClient()
|
||||
if _, ok := client.(pb.ProposerServiceClient); !ok {
|
||||
t.Error("Beacon service client function does not implement interface")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttesterServiceClient(t *testing.T) {
|
||||
rpcClientService := NewRPCClient(
|
||||
context.Background(),
|
||||
&Config{
|
||||
Endpoint: "merkle tries",
|
||||
},
|
||||
)
|
||||
rpcClientService.conn = nil
|
||||
client := rpcClientService.AttesterServiceClient()
|
||||
if _, ok := client.(pb.AttesterServiceClient); !ok {
|
||||
t.Error("Beacon service client function does not implement interface")
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ var (
|
||||
BeaconRPCProviderFlag = cli.StringFlag{
|
||||
Name: "beacon-rpc-provider",
|
||||
Usage: "Beacon node RPC provider endpoint",
|
||||
Value: "http://localhost:4000/",
|
||||
Value: "localhost:4000",
|
||||
}
|
||||
// PubKeyFlag defines a flag for validator's public key on the mainchain
|
||||
PubKeyFlag = cli.StringFlag{
|
||||
|
||||
Reference in New Issue
Block a user