RPC methods for Validators to Get ShardID, Index and Slot (#526)

This commit is contained in:
terence tsao
2018-09-17 19:36:09 -07:00
committed by Raul Jordan
parent 5a6e5f44fd
commit ddfe1715c9
25 changed files with 991 additions and 126 deletions

View File

@@ -569,3 +569,9 @@ go_repository(
commit = "073f507db72de824e981aa0f15f158175a8d6be1",
importpath = "github.com/libp2p/go-libp2p-blankhost",
)
go_repository(
name = "com_github_steakknife_hamming",
commit = "c99c65617cd3d686aea8365fe563d6542f01d940",
importpath = "github.com/steakknife/hamming",
)

View File

@@ -13,6 +13,7 @@ go_library(
"//beacon-chain/params:go_default_library",
"//beacon-chain/utils:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
@@ -31,6 +32,7 @@ go_test(
"//beacon-chain/params:go_default_library",
"//beacon-chain/utils:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
],
)

View File

@@ -2,8 +2,8 @@ package casper
import (
"github.com/prysmaticlabs/prysm/beacon-chain/params"
"github.com/prysmaticlabs/prysm/beacon-chain/utils"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared"
"github.com/sirupsen/logrus"
)
@@ -20,7 +20,7 @@ func CalculateRewards(attestations []*pb.AggregatedAttestation, validators []*pb
if attesterFactor >= totalFactor {
log.Debug("Applying rewards and penalties for the validators from last cycle")
for i, attesterIndex := range activeValidators {
voted := utils.CheckBit(attestations[len(attestations)-1].AttesterBitfield, int(attesterIndex))
voted := shared.CheckBit(attestations[len(attestations)-1].AttesterBitfield, int(attesterIndex))
if voted {
validators[i].Balance += params.AttesterReward
} else {

View File

@@ -7,6 +7,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/params"
"github.com/prysmaticlabs/prysm/beacon-chain/utils"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared"
)
const bitsInByte = 8
@@ -95,7 +96,7 @@ func SampleAttestersAndProposers(seed common.Hash, validators []*pb.ValidatorRec
func GetAttestersTotalDeposit(attestations []*pb.AggregatedAttestation) uint64 {
var numOfBits int
for _, attestation := range attestations {
numOfBits += int(utils.BitSetCount(attestation.AttesterBitfield))
numOfBits += int(shared.BitSetCount(attestation.AttesterBitfield))
}
// Assume there's no slashing condition, the following logic will change later phase.
return uint64(numOfBits) * params.DefaultBalance
@@ -113,9 +114,9 @@ func GetShardAndCommitteesForSlot(shardCommittees []*pb.ShardAndCommitteeArray,
// defined in the Crystallized State.
func AreAttesterBitfieldsValid(attestation *pb.AggregatedAttestation, attesterIndices []uint32) bool {
// Validate attester bit field has the correct length.
if utils.BitLength(len(attesterIndices)) != len(attestation.AttesterBitfield) {
if shared.BitLength(len(attesterIndices)) != len(attestation.AttesterBitfield) {
log.Debugf("attestation has incorrect bitfield length. Found %v, expected %v",
len(attestation.AttesterBitfield), utils.BitLength(len(attesterIndices)))
len(attestation.AttesterBitfield), shared.BitLength(len(attesterIndices)))
return false
}
@@ -127,7 +128,7 @@ func AreAttesterBitfieldsValid(attestation *pb.AggregatedAttestation, attesterIn
}
for i := 0; i < bitsInByte-remainingBits; i++ {
if utils.CheckBit(attestation.AttesterBitfield, lastBit+i) {
if shared.CheckBit(attestation.AttesterBitfield, lastBit+i) {
log.Debugf("attestation has non-zero trailing bits")
return false
}
@@ -156,3 +157,56 @@ func GetProposerIndexAndShard(shardCommittees []*pb.ShardAndCommitteeArray, lcs
proposerIndex := slot % uint64(len(slotCommittees.ArrayShardAndCommittee[0].Committee))
return proposerShardID, proposerIndex, nil
}
// ValidatorIndex returns the index of the validator given an input public key.
func ValidatorIndex(pubKey uint64, dynasty uint64, validators []*pb.ValidatorRecord) (uint32, error) {
activeValidators := ActiveValidatorIndices(validators, dynasty)
for _, index := range activeValidators {
if validators[index].PublicKey == pubKey {
return index, nil
}
}
return 0, fmt.Errorf("can't find validator index for public key %d", pubKey)
}
// ValidatorShardID returns the shard ID of the validator currently participates in.
func ValidatorShardID(pubKey uint64, dynasty uint64, validators []*pb.ValidatorRecord, shardCommittees []*pb.ShardAndCommitteeArray) (uint64, error) {
index, err := ValidatorIndex(pubKey, dynasty, validators)
if err != nil {
return 0, err
}
for _, slotCommittee := range shardCommittees {
for _, committee := range slotCommittee.ArrayShardAndCommittee {
for _, validator := range committee.Committee {
if validator == index {
return committee.ShardId, nil
}
}
}
}
return 0, fmt.Errorf("can't find shard ID for validator with public key %d", pubKey)
}
// ValidatorSlot returns the slot number of when the validator gets to attest or proposer.
func ValidatorSlot(pubKey uint64, dynasty uint64, validators []*pb.ValidatorRecord, shardCommittees []*pb.ShardAndCommitteeArray) (uint64, error) {
index, err := ValidatorIndex(pubKey, dynasty, validators)
if err != nil {
return 0, err
}
for slot, slotCommittee := range shardCommittees {
for _, committee := range slotCommittee.ArrayShardAndCommittee {
for _, validator := range committee.Committee {
if validator == index {
return uint64(slot), nil
}
}
}
}
return 0, fmt.Errorf("can't find slot number for validator with public key %d", pubKey)
}

View File

@@ -6,8 +6,8 @@ import (
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/params"
"github.com/prysmaticlabs/prysm/beacon-chain/utils"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared"
)
func TestRotateValidatorSet(t *testing.T) {
@@ -72,7 +72,7 @@ func TestHasVoted(t *testing.T) {
}
for i := 0; i < len(pendingAttestation.AttesterBitfield); i++ {
voted := utils.CheckBit(pendingAttestation.AttesterBitfield, i)
voted := shared.CheckBit(pendingAttestation.AttesterBitfield, i)
if !voted {
t.Error("validator voted but received didn't vote")
}
@@ -84,7 +84,7 @@ func TestHasVoted(t *testing.T) {
}
for i := 0; i < len(pendingAttestation.AttesterBitfield); i++ {
voted := utils.CheckBit(pendingAttestation.AttesterBitfield, i)
voted := shared.CheckBit(pendingAttestation.AttesterBitfield, i)
if i%2 == 0 && voted {
t.Error("validator didn't vote but received voted")
}
@@ -212,3 +212,94 @@ func TestGetProposerIndexAndShard(t *testing.T) {
t.Errorf("Invalid proposer index. Wanted 0, got %d", index)
}
}
func TestValidatorIndex(t *testing.T) {
var validators []*pb.ValidatorRecord
for i := 0; i < 10; i++ {
validators = append(validators, &pb.ValidatorRecord{StartDynasty: 0, EndDynasty: 10, PublicKey: 0})
}
if _, err := ValidatorIndex(100, 0, validators); err == nil {
t.Fatalf("ValidatorIndex should have failed, there's no validator with pubkey 100")
}
validators[5].PublicKey = 100
index, err := ValidatorIndex(100, 0, validators)
if err != nil {
t.Fatalf("call ValidatorIndex failed: %v", err)
}
if index != 5 {
t.Errorf("Incorrect validator index. Wanted 5, Got %v", index)
}
}
func TestValidatorShardID(t *testing.T) {
var validators []*pb.ValidatorRecord
for i := 0; i < 21; i++ {
validators = append(validators, &pb.ValidatorRecord{StartDynasty: 0, EndDynasty: 10, PublicKey: 0})
}
shardCommittees := []*pb.ShardAndCommitteeArray{
{ArrayShardAndCommittee: []*pb.ShardAndCommittee{
{ShardId: 0, Committee: []uint32{0, 1, 2, 3, 4, 5, 6}},
{ShardId: 1, Committee: []uint32{7, 8, 9, 10, 11, 12, 13}},
{ShardId: 2, Committee: []uint32{14, 15, 16, 17, 18, 19}},
}},
}
validators[19].PublicKey = 100
shardID, err := ValidatorShardID(100, 0, validators, shardCommittees)
if err != nil {
t.Fatalf("call ValidatorShardID failed: %v", err)
}
if shardID != 2 {
t.Errorf("Incorrect validator shard ID. Wanted 2, Got %v", shardID)
}
validators[19].PublicKey = 0
if _, err := ValidatorShardID(100, 0, validators, shardCommittees); err == nil {
t.Fatalf("ValidatorShardID should have failed, there's no validator with pubkey 100")
}
validators[20].PublicKey = 100
if _, err := ValidatorShardID(100, 0, validators, shardCommittees); err == nil {
t.Fatalf("ValidatorShardID should have failed, validator indexed at 20 is not in the committee")
}
}
func TestValidatorSlot(t *testing.T) {
var validators []*pb.ValidatorRecord
for i := 0; i < 61; i++ {
validators = append(validators, &pb.ValidatorRecord{StartDynasty: 0, EndDynasty: 10, PublicKey: 0})
}
shardCommittees := []*pb.ShardAndCommitteeArray{
{ArrayShardAndCommittee: []*pb.ShardAndCommittee{
{ShardId: 0, Committee: []uint32{0, 1, 2, 3, 4, 5, 6}},
{ShardId: 1, Committee: []uint32{7, 8, 9, 10, 11, 12, 13}},
{ShardId: 2, Committee: []uint32{14, 15, 16, 17, 18, 19}},
}},
{ArrayShardAndCommittee: []*pb.ShardAndCommittee{
{ShardId: 3, Committee: []uint32{20, 21, 22, 23, 24, 25, 26}},
{ShardId: 4, Committee: []uint32{27, 28, 29, 30, 31, 32, 33}},
{ShardId: 5, Committee: []uint32{34, 35, 36, 37, 38, 39}},
}},
{ArrayShardAndCommittee: []*pb.ShardAndCommittee{
{ShardId: 6, Committee: []uint32{40, 41, 42, 43, 44, 45, 46}},
{ShardId: 7, Committee: []uint32{47, 48, 49, 50, 51, 52, 53}},
{ShardId: 8, Committee: []uint32{54, 55, 56, 57, 58, 59}},
}},
}
if _, err := ValidatorSlot(100, 0, validators, shardCommittees); err == nil {
t.Fatalf("ValidatorSlot should have failed, there's no validator with pubkey 100")
}
validators[59].PublicKey = 100
slot, err := ValidatorSlot(100, 0, validators, shardCommittees)
if err != nil {
t.Fatalf("call ValidatorSlot failed: %v", err)
}
if slot != 2 {
t.Errorf("Incorrect validator slot ID. Wanted 1, Got %v", slot)
}
validators[60].PublicKey = 101
if _, err := ValidatorSlot(101, 0, validators, shardCommittees); err == nil {
t.Fatalf("ValidatorSlot should have failed, validator indexed at 60 is not in the committee")
}
}

View File

@@ -6,6 +6,7 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/rpc",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/casper:go_default_library",
"//beacon-chain/types:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/beacon/rpc/v1:go_default_library",

View File

@@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/event"
"github.com/golang/protobuf/ptypes/empty"
"github.com/prysmaticlabs/prysm/beacon-chain/casper"
"github.com/prysmaticlabs/prysm/beacon-chain/types"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
@@ -21,6 +22,7 @@ var log = logrus.WithField("prefix", "rpc")
type chainService interface {
IncomingBlockFeed() *event.Feed
IncomingAttestationFeed() *event.Feed
CurrentCrystallizedState() *types.CrystallizedState
ProcessedAttestationFeed() *event.Feed
}
@@ -206,6 +208,56 @@ func (s *Service) LatestCrystallizedState(req *empty.Empty, stream pb.BeaconServ
}
}
// ValidatorShardID is called by a validator to get the shard ID of where it's suppose
// to proposer or attest.
func (s *Service) ValidatorShardID(ctx context.Context, req *pb.PublicKey) (*pb.ShardIDResponse, error) {
cState := s.chainService.CurrentCrystallizedState()
shardID, err := casper.ValidatorShardID(
req.PublicKey,
cState.CurrentDynasty(),
cState.Validators(),
cState.ShardAndCommitteesForSlots())
if err != nil {
return nil, fmt.Errorf("could not get validator shard ID: %v", err)
}
return &pb.ShardIDResponse{ShardId: shardID}, nil
}
// ValidatorSlot is called by a validator to get the slot number of when it's suppose
// to proposer or attest.
func (s *Service) ValidatorSlot(ctx context.Context, req *pb.PublicKey) (*pb.SlotResponse, error) {
cState := s.chainService.CurrentCrystallizedState()
slot, err := casper.ValidatorSlot(
req.PublicKey,
cState.CurrentDynasty(),
cState.Validators(),
cState.ShardAndCommitteesForSlots())
if err != nil {
return nil, fmt.Errorf("could not get validator slot for attester/propose: %v", err)
}
return &pb.SlotResponse{Slot: slot}, nil
}
// ValidatorIndex is called by a validator to get its index location that corresponds
// to the attestation bit fields.
func (s *Service) ValidatorIndex(ctx context.Context, req *pb.PublicKey) (*pb.IndexResponse, error) {
cState := s.chainService.CurrentCrystallizedState()
index, err := casper.ValidatorIndex(
req.PublicKey,
cState.CurrentDynasty(),
cState.Validators())
if err != nil {
return nil, fmt.Errorf("could not get validator index: %v", err)
}
return &pb.IndexResponse{Index: index}, nil
}
// LatestAttestation streams the latest processed attestations to the rpc clients.
func (s *Service) LatestAttestation(req *empty.Empty, stream pb.BeaconService_LatestAttestationServer) error {
sub := s.chainService.ProcessedAttestationFeed().Subscribe(s.proccessedAttestation)

View File

@@ -47,6 +47,14 @@ func (m *mockChainService) ProcessedAttestationFeed() *event.Feed {
return m.attestationFeed
}
func (m *mockChainService) CurrentCrystallizedState() *types.CrystallizedState {
cState, err := types.NewGenesisCrystallizedState()
if err != nil {
return nil
}
return cState
}
type mockAnnouncer struct {
blockFeed *event.Feed
stateFeed *event.Feed
@@ -329,3 +337,51 @@ func TestLatestAttestation(t *testing.T) {
rpcService.cancel()
exitRoutine <- true
}
func TestValidatorSlot(t *testing.T) {
announcer := newMockAnnouncer()
mockChain := &mockChainService{}
rpcService := NewRPCService(context.Background(), &Config{
Port: "6372",
Announcer: announcer,
ChainService: mockChain,
})
req := &pb.PublicKey{
PublicKey: 0,
}
if _, err := rpcService.ValidatorSlot(context.Background(), req); err != nil {
t.Errorf("Could not get validator slot: %v", err)
}
}
func TestValidatorIndex(t *testing.T) {
announcer := newMockAnnouncer()
mockChain := &mockChainService{}
rpcService := NewRPCService(context.Background(), &Config{
Port: "6372",
Announcer: announcer,
ChainService: mockChain,
})
req := &pb.PublicKey{
PublicKey: 0,
}
if _, err := rpcService.ValidatorIndex(context.Background(), req); err != nil {
t.Errorf("Could not get validator index: %v", err)
}
}
func TestValidatorShardID(t *testing.T) {
announcer := newMockAnnouncer()
mockChain := &mockChainService{}
rpcService := NewRPCService(context.Background(), &Config{
Port: "6372",
Announcer: announcer,
ChainService: mockChain,
})
req := &pb.PublicKey{
PublicKey: 0,
}
if _, err := rpcService.ValidatorShardID(context.Background(), req); err != nil {
t.Errorf("Could not get validator shard ID: %v", err)
}
}

View File

@@ -17,6 +17,7 @@ go_library(
"//beacon-chain/params:go_default_library",
"//beacon-chain/utils:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared:go_default_library",
"//shared/p2p:go_default_library",
"@com_github_ethereum_go_ethereum//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",

View File

@@ -7,8 +7,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/gogo/protobuf/proto"
"github.com/prysmaticlabs/prysm/beacon-chain/params"
"github.com/prysmaticlabs/prysm/beacon-chain/utils"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared"
"golang.org/x/crypto/blake2b"
)
@@ -153,7 +153,7 @@ func (a *ActiveState) calculateNewVoteCache(block *Block, cState *CrystallizedSt
// in the cache, then we add attester's index and balance to the block cache.
for i, attesterIndex := range attesterIndices {
var attesterExists bool
if !utils.CheckBit(attestation.AttesterBitfield, i) {
if !shared.CheckBit(attestation.AttesterBitfield, i) {
continue
}
for _, indexInCache := range update[h].VoterIndices {

View File

@@ -12,6 +12,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/params"
"github.com/prysmaticlabs/prysm/beacon-chain/utils"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/blake2b"
)
@@ -178,7 +179,7 @@ func (b *Block) IsValid(aState *ActiveState, cState *CrystallizedState, parentSl
log.Debugf("attestation invalid: %v", attestation)
return false
}
if utils.BitSetCount(attestation.AttesterBitfield) == 1 && utils.CheckBit(attestation.AttesterBitfield, int(proposerIndex)) {
if shared.BitSetCount(attestation.AttesterBitfield) == 1 && shared.CheckBit(attestation.AttesterBitfield, int(proposerIndex)) {
proposerAttested = true
}
}

View File

@@ -7,8 +7,8 @@ import (
"github.com/gogo/protobuf/proto"
"github.com/prysmaticlabs/prysm/beacon-chain/casper"
"github.com/prysmaticlabs/prysm/beacon-chain/params"
"github.com/prysmaticlabs/prysm/beacon-chain/utils"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared"
"golang.org/x/crypto/blake2b"
)
@@ -382,7 +382,7 @@ func (c *CrystallizedState) processCrosslinks(pendingAttestations []*pb.Aggregat
// find the balance of votes cast in shard attestation.
var voteBalance uint64
for i, attesterIndex := range indices {
if utils.CheckBit(attestation.AttesterBitfield, i) {
if shared.CheckBit(attestation.AttesterBitfield, i) {
voteBalance += validators[attesterIndex].Balance
}
}

View File

@@ -3,7 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"checkbit.go",
"clock.go",
"flags.go",
"shuffle.go",
@@ -21,7 +20,6 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"checkbit_test.go",
"clock_test.go",
"shuffle_test.go",
],

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: proto/beacon/rpc/v1/services.proto
package v1
package ethereum_beacon_rpc_v1
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
@@ -37,7 +37,7 @@ func (m *ShuffleRequest) Reset() { *m = ShuffleRequest{} }
func (m *ShuffleRequest) String() string { return proto.CompactTextString(m) }
func (*ShuffleRequest) ProtoMessage() {}
func (*ShuffleRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_services_304af3a26a99c205, []int{0}
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{0}
}
func (m *ShuffleRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ShuffleRequest.Unmarshal(m, b)
@@ -65,9 +65,9 @@ func (m *ShuffleRequest) GetCrystallizedStateHash() []byte {
}
type ShuffleResponse struct {
ShuffledValidatorIndices []uint64 `protobuf:"varint,1,rep,packed,name=shuffled_validator_indices,json=shuffledValidatorIndices" json:"shuffled_validator_indices,omitempty"`
CutoffIndices []uint64 `protobuf:"varint,2,rep,packed,name=cutoff_indices,json=cutoffIndices" json:"cutoff_indices,omitempty"`
AssignedAttestationSlots []uint64 `protobuf:"varint,3,rep,packed,name=assigned_attestation_slots,json=assignedAttestationSlots" json:"assigned_attestation_slots,omitempty"`
ShuffledValidatorIndices []uint64 `protobuf:"varint,1,rep,packed,name=shuffled_validator_indices,json=shuffledValidatorIndices,proto3" json:"shuffled_validator_indices,omitempty"`
CutoffIndices []uint64 `protobuf:"varint,2,rep,packed,name=cutoff_indices,json=cutoffIndices,proto3" json:"cutoff_indices,omitempty"`
AssignedAttestationSlots []uint64 `protobuf:"varint,3,rep,packed,name=assigned_attestation_slots,json=assignedAttestationSlots,proto3" json:"assigned_attestation_slots,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -77,7 +77,7 @@ func (m *ShuffleResponse) Reset() { *m = ShuffleResponse{} }
func (m *ShuffleResponse) String() string { return proto.CompactTextString(m) }
func (*ShuffleResponse) ProtoMessage() {}
func (*ShuffleResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_services_304af3a26a99c205, []int{1}
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{1}
}
func (m *ShuffleResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ShuffleResponse.Unmarshal(m, b)
@@ -120,11 +120,11 @@ func (m *ShuffleResponse) GetAssignedAttestationSlots() []uint64 {
type ProposeRequest struct {
ParentHash []byte `protobuf:"bytes,1,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"`
SlotNumber uint64 `protobuf:"varint,2,opt,name=slot_number,json=slotNumber" json:"slot_number,omitempty"`
SlotNumber uint64 `protobuf:"varint,2,opt,name=slot_number,json=slotNumber,proto3" json:"slot_number,omitempty"`
RandaoReveal []byte `protobuf:"bytes,3,opt,name=randao_reveal,json=randaoReveal,proto3" json:"randao_reveal,omitempty"`
AttestationBitmask []byte `protobuf:"bytes,4,opt,name=attestation_bitmask,json=attestationBitmask,proto3" json:"attestation_bitmask,omitempty"`
AttestationAggregateSig []uint32 `protobuf:"varint,5,rep,packed,name=attestation_aggregate_sig,json=attestationAggregateSig" json:"attestation_aggregate_sig,omitempty"`
Timestamp *timestamp.Timestamp `protobuf:"bytes,6,opt,name=timestamp" json:"timestamp,omitempty"`
AttestationAggregateSig []uint32 `protobuf:"varint,5,rep,packed,name=attestation_aggregate_sig,json=attestationAggregateSig,proto3" json:"attestation_aggregate_sig,omitempty"`
Timestamp *timestamp.Timestamp `protobuf:"bytes,6,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -134,7 +134,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_304af3a26a99c205, []int{2}
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{2}
}
func (m *ProposeRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ProposeRequest.Unmarshal(m, b)
@@ -207,7 +207,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_304af3a26a99c205, []int{3}
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{3}
}
func (m *ProposeResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ProposeResponse.Unmarshal(m, b)
@@ -235,7 +235,7 @@ func (m *ProposeResponse) GetBlockHash() []byte {
}
type AttestRequest struct {
Attestation *v1.AggregatedAttestation `protobuf:"bytes,1,opt,name=attestation" json:"attestation,omitempty"`
Attestation *v1.AggregatedAttestation `protobuf:"bytes,1,opt,name=attestation,proto3" json:"attestation,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -245,7 +245,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_304af3a26a99c205, []int{4}
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{4}
}
func (m *AttestRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AttestRequest.Unmarshal(m, b)
@@ -283,7 +283,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_304af3a26a99c205, []int{5}
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{5}
}
func (m *AttestResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AttestResponse.Unmarshal(m, b)
@@ -310,6 +310,158 @@ func (m *AttestResponse) GetAttestationHash() []byte {
return nil
}
type PublicKey struct {
PublicKey uint64 `protobuf:"varint,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PublicKey) Reset() { *m = PublicKey{} }
func (m *PublicKey) String() string { return proto.CompactTextString(m) }
func (*PublicKey) ProtoMessage() {}
func (*PublicKey) Descriptor() ([]byte, []int) {
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{6}
}
func (m *PublicKey) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PublicKey.Unmarshal(m, b)
}
func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic)
}
func (dst *PublicKey) XXX_Merge(src proto.Message) {
xxx_messageInfo_PublicKey.Merge(dst, src)
}
func (m *PublicKey) XXX_Size() int {
return xxx_messageInfo_PublicKey.Size(m)
}
func (m *PublicKey) XXX_DiscardUnknown() {
xxx_messageInfo_PublicKey.DiscardUnknown(m)
}
var xxx_messageInfo_PublicKey proto.InternalMessageInfo
func (m *PublicKey) GetPublicKey() uint64 {
if m != nil {
return m.PublicKey
}
return 0
}
type ShardIDResponse struct {
ShardId uint64 `protobuf:"varint,1,opt,name=shard_id,json=shardId,proto3" json:"shard_id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ShardIDResponse) Reset() { *m = ShardIDResponse{} }
func (m *ShardIDResponse) String() string { return proto.CompactTextString(m) }
func (*ShardIDResponse) ProtoMessage() {}
func (*ShardIDResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{7}
}
func (m *ShardIDResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ShardIDResponse.Unmarshal(m, b)
}
func (m *ShardIDResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ShardIDResponse.Marshal(b, m, deterministic)
}
func (dst *ShardIDResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ShardIDResponse.Merge(dst, src)
}
func (m *ShardIDResponse) XXX_Size() int {
return xxx_messageInfo_ShardIDResponse.Size(m)
}
func (m *ShardIDResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ShardIDResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ShardIDResponse proto.InternalMessageInfo
func (m *ShardIDResponse) GetShardId() uint64 {
if m != nil {
return m.ShardId
}
return 0
}
type IndexResponse struct {
Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *IndexResponse) Reset() { *m = IndexResponse{} }
func (m *IndexResponse) String() string { return proto.CompactTextString(m) }
func (*IndexResponse) ProtoMessage() {}
func (*IndexResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{8}
}
func (m *IndexResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_IndexResponse.Unmarshal(m, b)
}
func (m *IndexResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_IndexResponse.Marshal(b, m, deterministic)
}
func (dst *IndexResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_IndexResponse.Merge(dst, src)
}
func (m *IndexResponse) XXX_Size() int {
return xxx_messageInfo_IndexResponse.Size(m)
}
func (m *IndexResponse) XXX_DiscardUnknown() {
xxx_messageInfo_IndexResponse.DiscardUnknown(m)
}
var xxx_messageInfo_IndexResponse proto.InternalMessageInfo
func (m *IndexResponse) GetIndex() uint32 {
if m != nil {
return m.Index
}
return 0
}
type SlotResponse struct {
Slot uint64 `protobuf:"varint,1,opt,name=slot,proto3" json:"slot,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SlotResponse) Reset() { *m = SlotResponse{} }
func (m *SlotResponse) String() string { return proto.CompactTextString(m) }
func (*SlotResponse) ProtoMessage() {}
func (*SlotResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_services_f2b7e4f7fe6852c7, []int{9}
}
func (m *SlotResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SlotResponse.Unmarshal(m, b)
}
func (m *SlotResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SlotResponse.Marshal(b, m, deterministic)
}
func (dst *SlotResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_SlotResponse.Merge(dst, src)
}
func (m *SlotResponse) XXX_Size() int {
return xxx_messageInfo_SlotResponse.Size(m)
}
func (m *SlotResponse) XXX_DiscardUnknown() {
xxx_messageInfo_SlotResponse.DiscardUnknown(m)
}
var xxx_messageInfo_SlotResponse proto.InternalMessageInfo
func (m *SlotResponse) GetSlot() uint64 {
if m != nil {
return m.Slot
}
return 0
}
func init() {
proto.RegisterType((*ShuffleRequest)(nil), "ethereum.beacon.rpc.v1.ShuffleRequest")
proto.RegisterType((*ShuffleResponse)(nil), "ethereum.beacon.rpc.v1.ShuffleResponse")
@@ -317,6 +469,10 @@ func init() {
proto.RegisterType((*ProposeResponse)(nil), "ethereum.beacon.rpc.v1.ProposeResponse")
proto.RegisterType((*AttestRequest)(nil), "ethereum.beacon.rpc.v1.AttestRequest")
proto.RegisterType((*AttestResponse)(nil), "ethereum.beacon.rpc.v1.AttestResponse")
proto.RegisterType((*PublicKey)(nil), "ethereum.beacon.rpc.v1.PublicKey")
proto.RegisterType((*ShardIDResponse)(nil), "ethereum.beacon.rpc.v1.ShardIDResponse")
proto.RegisterType((*IndexResponse)(nil), "ethereum.beacon.rpc.v1.IndexResponse")
proto.RegisterType((*SlotResponse)(nil), "ethereum.beacon.rpc.v1.SlotResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -327,8 +483,9 @@ var _ grpc.ClientConn
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for BeaconService service
// BeaconServiceClient is the client API for BeaconService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type BeaconServiceClient interface {
LatestBeaconBlock(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestBeaconBlockClient, error)
LatestCrystallizedState(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestCrystallizedStateClient, error)
@@ -345,7 +502,7 @@ func NewBeaconServiceClient(cc *grpc.ClientConn) BeaconServiceClient {
}
func (c *beaconServiceClient) LatestBeaconBlock(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestBeaconBlockClient, error) {
stream, err := grpc.NewClientStream(ctx, &_BeaconService_serviceDesc.Streams[0], c.cc, "/ethereum.beacon.rpc.v1.BeaconService/LatestBeaconBlock", opts...)
stream, err := c.cc.NewStream(ctx, &_BeaconService_serviceDesc.Streams[0], "/ethereum.beacon.rpc.v1.BeaconService/LatestBeaconBlock", opts...)
if err != nil {
return nil, err
}
@@ -377,7 +534,7 @@ func (x *beaconServiceLatestBeaconBlockClient) Recv() (*v1.BeaconBlock, error) {
}
func (c *beaconServiceClient) LatestCrystallizedState(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestCrystallizedStateClient, error) {
stream, err := grpc.NewClientStream(ctx, &_BeaconService_serviceDesc.Streams[1], c.cc, "/ethereum.beacon.rpc.v1.BeaconService/LatestCrystallizedState", opts...)
stream, err := c.cc.NewStream(ctx, &_BeaconService_serviceDesc.Streams[1], "/ethereum.beacon.rpc.v1.BeaconService/LatestCrystallizedState", opts...)
if err != nil {
return nil, err
}
@@ -410,7 +567,7 @@ func (x *beaconServiceLatestCrystallizedStateClient) Recv() (*v1.CrystallizedSta
func (c *beaconServiceClient) FetchShuffledValidatorIndices(ctx context.Context, in *ShuffleRequest, opts ...grpc.CallOption) (*ShuffleResponse, error) {
out := new(ShuffleResponse)
err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.BeaconService/FetchShuffledValidatorIndices", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.BeaconService/FetchShuffledValidatorIndices", in, out, opts...)
if err != nil {
return nil, err
}
@@ -418,7 +575,7 @@ func (c *beaconServiceClient) FetchShuffledValidatorIndices(ctx context.Context,
}
func (c *beaconServiceClient) LatestAttestation(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (BeaconService_LatestAttestationClient, error) {
stream, err := grpc.NewClientStream(ctx, &_BeaconService_serviceDesc.Streams[2], c.cc, "/ethereum.beacon.rpc.v1.BeaconService/LatestAttestation", opts...)
stream, err := c.cc.NewStream(ctx, &_BeaconService_serviceDesc.Streams[2], "/ethereum.beacon.rpc.v1.BeaconService/LatestAttestation", opts...)
if err != nil {
return nil, err
}
@@ -449,8 +606,7 @@ func (x *beaconServiceLatestAttestationClient) Recv() (*v1.AggregatedAttestation
return m, nil
}
// Server API for BeaconService service
// BeaconServiceServer is the server API for BeaconService service.
type BeaconServiceServer interface {
LatestBeaconBlock(*empty.Empty, BeaconService_LatestBeaconBlockServer) error
LatestCrystallizedState(*empty.Empty, BeaconService_LatestCrystallizedStateServer) error
@@ -572,8 +728,9 @@ var _BeaconService_serviceDesc = grpc.ServiceDesc{
Metadata: "proto/beacon/rpc/v1/services.proto",
}
// Client API for AttesterService service
// AttesterServiceClient is the client API for AttesterService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type AttesterServiceClient interface {
AttestHead(ctx context.Context, in *AttestRequest, opts ...grpc.CallOption) (*AttestResponse, error)
}
@@ -588,15 +745,14 @@ func NewAttesterServiceClient(cc *grpc.ClientConn) AttesterServiceClient {
func (c *attesterServiceClient) AttestHead(ctx context.Context, in *AttestRequest, opts ...grpc.CallOption) (*AttestResponse, error) {
out := new(AttestResponse)
err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.AttesterService/AttestHead", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.AttesterService/AttestHead", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for AttesterService service
// AttesterServiceServer is the server API for AttesterService service.
type AttesterServiceServer interface {
AttestHead(context.Context, *AttestRequest) (*AttestResponse, error)
}
@@ -636,8 +792,9 @@ var _AttesterService_serviceDesc = grpc.ServiceDesc{
Metadata: "proto/beacon/rpc/v1/services.proto",
}
// Client API for ProposerService service
// ProposerServiceClient is the client API for ProposerService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type ProposerServiceClient interface {
ProposeBlock(ctx context.Context, in *ProposeRequest, opts ...grpc.CallOption) (*ProposeResponse, error)
}
@@ -652,15 +809,14 @@ func NewProposerServiceClient(cc *grpc.ClientConn) ProposerServiceClient {
func (c *proposerServiceClient) ProposeBlock(ctx context.Context, in *ProposeRequest, opts ...grpc.CallOption) (*ProposeResponse, error) {
out := new(ProposeResponse)
err := grpc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ProposerService/ProposeBlock", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ProposerService/ProposeBlock", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for ProposerService service
// ProposerServiceServer is the server API for ProposerService service.
type ProposerServiceServer interface {
ProposeBlock(context.Context, *ProposeRequest) (*ProposeResponse, error)
}
@@ -700,51 +856,190 @@ var _ProposerService_serviceDesc = grpc.ServiceDesc{
Metadata: "proto/beacon/rpc/v1/services.proto",
}
func init() {
proto.RegisterFile("proto/beacon/rpc/v1/services.proto", fileDescriptor_services_304af3a26a99c205)
// ValidatorServiceClient is the client API for ValidatorService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type ValidatorServiceClient interface {
ValidatorShardID(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*ShardIDResponse, error)
ValidatorIndex(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*IndexResponse, error)
ValidatorSlot(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*SlotResponse, error)
}
var fileDescriptor_services_304af3a26a99c205 = []byte{
// 651 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xd1, 0x6e, 0xd3, 0x4a,
0x10, 0x95, 0x9b, 0xde, 0x4a, 0x9d, 0x34, 0xc9, 0xbd, 0x7b, 0x45, 0x6b, 0x8c, 0xaa, 0x46, 0xa9,
0x5a, 0xd2, 0x07, 0xec, 0xd4, 0x48, 0x08, 0x41, 0x5f, 0x5a, 0x04, 0x2a, 0x12, 0x02, 0xe4, 0x20,
0x5e, 0x40, 0x98, 0x8d, 0xbd, 0x71, 0xac, 0xda, 0xde, 0x65, 0x77, 0x13, 0xa9, 0xfc, 0x06, 0xef,
0x7c, 0x05, 0x1f, 0x88, 0xd6, 0x1b, 0xbb, 0x9b, 0x14, 0xab, 0xe2, 0xd1, 0xe7, 0x9c, 0x99, 0x9d,
0x39, 0x33, 0x63, 0x18, 0x30, 0x4e, 0x25, 0xf5, 0x26, 0x04, 0x47, 0xb4, 0xf0, 0x38, 0x8b, 0xbc,
0xc5, 0xa9, 0x27, 0x08, 0x5f, 0xa4, 0x11, 0x11, 0x6e, 0x49, 0xa2, 0x5d, 0x22, 0x67, 0x84, 0x93,
0x79, 0xee, 0x6a, 0x99, 0xcb, 0x59, 0xe4, 0x2e, 0x4e, 0x9d, 0xd5, 0x58, 0xe6, 0x33, 0x15, 0x9b,
0x13, 0x21, 0x70, 0x52, 0xc5, 0x3a, 0x0f, 0x12, 0x4a, 0x93, 0x8c, 0x78, 0xe5, 0xd7, 0x64, 0x3e,
0xf5, 0x48, 0xce, 0xe4, 0xf5, 0x92, 0x3c, 0x58, 0x27, 0x65, 0x9a, 0x13, 0x21, 0x71, 0xce, 0xb4,
0x60, 0x70, 0x09, 0xdd, 0xf1, 0x6c, 0x3e, 0x9d, 0x66, 0x24, 0x20, 0xdf, 0xe6, 0x44, 0x48, 0xf4,
0x04, 0xf6, 0x22, 0x7e, 0x2d, 0x24, 0xce, 0xb2, 0xf4, 0x3b, 0x89, 0x43, 0x21, 0xb1, 0x24, 0xe1,
0x0c, 0x8b, 0x99, 0x6d, 0xf5, 0xad, 0xe1, 0x4e, 0x70, 0xcf, 0xa4, 0xc7, 0x8a, 0xbd, 0xc4, 0x62,
0x36, 0xf8, 0x65, 0x41, 0xaf, 0x4e, 0x25, 0x18, 0x2d, 0x04, 0x41, 0x67, 0xe0, 0x08, 0x0d, 0xc5,
0xe1, 0x02, 0x67, 0x69, 0x8c, 0x25, 0xe5, 0x61, 0x5a, 0xc4, 0xaa, 0x77, 0xdb, 0xea, 0xb7, 0x86,
0x9b, 0x81, 0x5d, 0x29, 0x3e, 0x56, 0x82, 0xd7, 0x9a, 0x47, 0x47, 0xd0, 0x8d, 0xe6, 0x92, 0x4e,
0xa7, 0x75, 0xc4, 0x46, 0x19, 0xd1, 0xd1, 0x68, 0x25, 0x3b, 0x03, 0x07, 0x0b, 0x91, 0x26, 0x05,
0x89, 0x43, 0x2c, 0xa5, 0x6a, 0x4f, 0xa6, 0xb4, 0x08, 0x45, 0x46, 0xa5, 0xb0, 0x5b, 0xfa, 0x91,
0x4a, 0x71, 0x7e, 0x23, 0x18, 0x2b, 0x7e, 0xf0, 0x73, 0x03, 0xba, 0xef, 0x39, 0x65, 0x54, 0xd4,
0x0e, 0x1c, 0x40, 0x9b, 0x61, 0x4e, 0x0a, 0x69, 0x76, 0x0d, 0x1a, 0x52, 0xad, 0x2a, 0x81, 0x4a,
0x1e, 0x16, 0xf3, 0x7c, 0x42, 0xb8, 0xbd, 0xd1, 0xb7, 0x86, 0x9b, 0x01, 0x28, 0xe8, 0x6d, 0x89,
0xa0, 0x43, 0xe8, 0x70, 0x5c, 0xc4, 0x98, 0x86, 0x9c, 0x2c, 0x08, 0xce, 0xec, 0x56, 0x99, 0x63,
0x47, 0x83, 0x41, 0x89, 0x21, 0x0f, 0xfe, 0x37, 0xcb, 0x9d, 0xa4, 0x32, 0xc7, 0xe2, 0xca, 0xde,
0x2c, 0xa5, 0xc8, 0xa0, 0x2e, 0x34, 0x83, 0x9e, 0xc1, 0x7d, 0x33, 0x00, 0x27, 0x09, 0x27, 0x89,
0x1a, 0x8e, 0x48, 0x13, 0xfb, 0x9f, 0x7e, 0x6b, 0xd8, 0x09, 0xf6, 0x0c, 0xc1, 0x79, 0xc5, 0x8f,
0xd3, 0x04, 0x3d, 0x85, 0xed, 0x7a, 0xf4, 0xf6, 0x56, 0xdf, 0x1a, 0xb6, 0x7d, 0xc7, 0xd5, 0xcb,
0xe1, 0x56, 0xcb, 0xe1, 0x7e, 0xa8, 0x14, 0xc1, 0x8d, 0x78, 0x30, 0x82, 0x5e, 0xed, 0xcf, 0x72,
0xac, 0xfb, 0x00, 0x93, 0x8c, 0x46, 0x57, 0xa6, 0x3f, 0xdb, 0x25, 0x52, 0x6e, 0xc2, 0x57, 0xe8,
0x68, 0x9b, 0x2b, 0x43, 0xdf, 0x41, 0xdb, 0xa8, 0xab, 0x0c, 0x68, 0xfb, 0x8f, 0xdc, 0xf5, 0xa5,
0x67, 0x3e, 0x73, 0x17, 0xa7, 0x6e, 0x5d, 0xb7, 0x39, 0xac, 0xc0, 0xcc, 0x30, 0x78, 0x0e, 0xdd,
0xea, 0x85, 0x65, 0x49, 0x27, 0xf0, 0xaf, 0xe9, 0x8d, 0x51, 0x58, 0xcf, 0xc0, 0x55, 0x79, 0xfe,
0x8f, 0x16, 0x74, 0x2e, 0xca, 0x17, 0xc7, 0xfa, 0x0a, 0x51, 0x00, 0xff, 0xbd, 0xc1, 0x4a, 0xa4,
0xe1, 0x0b, 0xd5, 0x09, 0xda, 0xbd, 0x65, 0xcf, 0x4b, 0x75, 0x58, 0xce, 0x61, 0x53, 0xdd, 0x46,
0xf0, 0xc8, 0x42, 0x5f, 0x60, 0x4f, 0xe7, 0x7c, 0xb1, 0x7e, 0x2d, 0x8d, 0x99, 0x4f, 0x9a, 0x32,
0xdf, 0x4a, 0x31, 0xb2, 0x10, 0x83, 0xfd, 0x57, 0x44, 0x46, 0xb3, 0x71, 0xd3, 0xf5, 0x1c, 0xbb,
0x7f, 0xfe, 0xa9, 0xb8, 0xab, 0xf7, 0xee, 0x3c, 0xbc, 0x53, 0xb7, 0xb4, 0xf8, 0x73, 0xe5, 0x92,
0x31, 0x96, 0xc6, 0x5e, 0xfe, 0x6e, 0xba, 0x23, 0xcb, 0x2f, 0xa0, 0xa7, 0x01, 0xc2, 0xab, 0xb1,
0x7c, 0x02, 0xd0, 0xd0, 0x25, 0xc1, 0x31, 0x3a, 0x6a, 0xaa, 0x73, 0x65, 0xd7, 0x9c, 0xe3, 0xbb,
0x64, 0xba, 0x1b, 0x9f, 0xd7, 0x6b, 0x5d, 0xbf, 0x17, 0xc2, 0xce, 0x12, 0xd2, 0x1b, 0xd0, 0x98,
0x6a, 0xf5, 0x7f, 0xd1, 0xec, 0xe0, 0xda, 0xdd, 0x4c, 0xb6, 0x4a, 0x93, 0x1e, 0xff, 0x0e, 0x00,
0x00, 0xff, 0xff, 0x94, 0xde, 0xf9, 0x1b, 0x13, 0x06, 0x00, 0x00,
type validatorServiceClient struct {
cc *grpc.ClientConn
}
func NewValidatorServiceClient(cc *grpc.ClientConn) ValidatorServiceClient {
return &validatorServiceClient{cc}
}
func (c *validatorServiceClient) ValidatorShardID(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*ShardIDResponse, error) {
out := new(ShardIDResponse)
err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorShardID", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *validatorServiceClient) ValidatorIndex(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*IndexResponse, error) {
out := new(IndexResponse)
err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorIndex", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *validatorServiceClient) ValidatorSlot(ctx context.Context, in *PublicKey, opts ...grpc.CallOption) (*SlotResponse, error) {
out := new(SlotResponse)
err := c.cc.Invoke(ctx, "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorSlot", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ValidatorServiceServer is the server API for ValidatorService service.
type ValidatorServiceServer interface {
ValidatorShardID(context.Context, *PublicKey) (*ShardIDResponse, error)
ValidatorIndex(context.Context, *PublicKey) (*IndexResponse, error)
ValidatorSlot(context.Context, *PublicKey) (*SlotResponse, error)
}
func RegisterValidatorServiceServer(s *grpc.Server, srv ValidatorServiceServer) {
s.RegisterService(&_ValidatorService_serviceDesc, srv)
}
func _ValidatorService_ValidatorShardID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PublicKey)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ValidatorServiceServer).ValidatorShardID(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorShardID",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ValidatorServiceServer).ValidatorShardID(ctx, req.(*PublicKey))
}
return interceptor(ctx, in, info, handler)
}
func _ValidatorService_ValidatorIndex_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PublicKey)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ValidatorServiceServer).ValidatorIndex(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorIndex",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ValidatorServiceServer).ValidatorIndex(ctx, req.(*PublicKey))
}
return interceptor(ctx, in, info, handler)
}
func _ValidatorService_ValidatorSlot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PublicKey)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ValidatorServiceServer).ValidatorSlot(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.beacon.rpc.v1.ValidatorService/ValidatorSlot",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ValidatorServiceServer).ValidatorSlot(ctx, req.(*PublicKey))
}
return interceptor(ctx, in, info, handler)
}
var _ValidatorService_serviceDesc = grpc.ServiceDesc{
ServiceName: "ethereum.beacon.rpc.v1.ValidatorService",
HandlerType: (*ValidatorServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "ValidatorShardID",
Handler: _ValidatorService_ValidatorShardID_Handler,
},
{
MethodName: "ValidatorIndex",
Handler: _ValidatorService_ValidatorIndex_Handler,
},
{
MethodName: "ValidatorSlot",
Handler: _ValidatorService_ValidatorSlot_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/beacon/rpc/v1/services.proto",
}
func init() {
proto.RegisterFile("proto/beacon/rpc/v1/services.proto", fileDescriptor_services_f2b7e4f7fe6852c7)
}
var fileDescriptor_services_f2b7e4f7fe6852c7 = []byte{
// 795 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6e, 0xeb, 0x44,
0x10, 0x96, 0x93, 0x9c, 0x03, 0x99, 0xfc, 0xf5, 0xec, 0x81, 0x53, 0xd7, 0xa8, 0x6a, 0x70, 0x69,
0x49, 0x11, 0x38, 0xa9, 0x91, 0x10, 0x82, 0xde, 0xb4, 0xfc, 0x35, 0x02, 0x41, 0xe5, 0x20, 0x6e,
0x0a, 0x98, 0x8d, 0xbd, 0x71, 0xac, 0x3a, 0xb6, 0xd9, 0xdd, 0x44, 0x84, 0xd7, 0xe0, 0x9e, 0x77,
0x40, 0xe2, 0x01, 0xd1, 0xee, 0xc6, 0xee, 0x26, 0xc5, 0xb4, 0xdc, 0xd9, 0xdf, 0x7c, 0xf3, 0xf7,
0xcd, 0xcc, 0x82, 0x9d, 0xd3, 0x8c, 0x67, 0xc3, 0x29, 0xc1, 0x41, 0x96, 0x0e, 0x69, 0x1e, 0x0c,
0x57, 0xe7, 0x43, 0x46, 0xe8, 0x2a, 0x0e, 0x08, 0x73, 0xa4, 0x11, 0xbd, 0x22, 0x7c, 0x4e, 0x28,
0x59, 0x2e, 0x1c, 0x45, 0x73, 0x68, 0x1e, 0x38, 0xab, 0x73, 0x6b, 0xdb, 0x37, 0x77, 0x73, 0xe1,
0xbb, 0x20, 0x8c, 0xe1, 0xa8, 0xf0, 0xb5, 0xde, 0x8a, 0xb2, 0x2c, 0x4a, 0xc8, 0x50, 0xfe, 0x4d,
0x97, 0xb3, 0x21, 0x59, 0xe4, 0x7c, 0xbd, 0x31, 0x1e, 0xed, 0x1a, 0x79, 0xbc, 0x20, 0x8c, 0xe3,
0x45, 0xae, 0x08, 0xf6, 0x35, 0x74, 0x27, 0xf3, 0xe5, 0x6c, 0x96, 0x10, 0x8f, 0xfc, 0xba, 0x24,
0x8c, 0xa3, 0x8f, 0x60, 0x3f, 0xa0, 0x6b, 0xc6, 0x71, 0x92, 0xc4, 0xbf, 0x93, 0xd0, 0x67, 0x1c,
0x73, 0xe2, 0xcf, 0x31, 0x9b, 0x9b, 0x46, 0xdf, 0x18, 0xb4, 0xbd, 0x37, 0x75, 0xf3, 0x44, 0x58,
0xaf, 0x31, 0x9b, 0xdb, 0x7f, 0x1b, 0xd0, 0x2b, 0x43, 0xb1, 0x3c, 0x4b, 0x19, 0x41, 0x17, 0x60,
0x31, 0x05, 0x85, 0xfe, 0x0a, 0x27, 0x71, 0x88, 0x79, 0x46, 0xfd, 0x38, 0x0d, 0x45, 0xef, 0xa6,
0xd1, 0xaf, 0x0f, 0x1a, 0x9e, 0x59, 0x30, 0x7e, 0x28, 0x08, 0x63, 0x65, 0x47, 0x27, 0xd0, 0x0d,
0x96, 0x3c, 0x9b, 0xcd, 0x4a, 0x8f, 0x9a, 0xf4, 0xe8, 0x28, 0xb4, 0xa0, 0x5d, 0x80, 0x85, 0x19,
0x8b, 0xa3, 0x94, 0x84, 0x3e, 0xe6, 0x5c, 0xb4, 0xc7, 0xe3, 0x2c, 0xf5, 0x59, 0x92, 0x71, 0x66,
0xd6, 0x55, 0x92, 0x82, 0x71, 0x79, 0x4f, 0x98, 0x08, 0xbb, 0xfd, 0x67, 0x0d, 0xba, 0x37, 0x34,
0xcb, 0x33, 0x56, 0x2a, 0x70, 0x04, 0xad, 0x1c, 0x53, 0x92, 0x72, 0xbd, 0x6b, 0x50, 0x90, 0x68,
0x55, 0x10, 0x44, 0x70, 0x3f, 0x5d, 0x2e, 0xa6, 0x84, 0x9a, 0xb5, 0xbe, 0x31, 0x68, 0x78, 0x20,
0xa0, 0x6f, 0x25, 0x82, 0x8e, 0xa1, 0x43, 0x71, 0x1a, 0xe2, 0xcc, 0xa7, 0x64, 0x45, 0x70, 0x62,
0xd6, 0x65, 0x8c, 0xb6, 0x02, 0x3d, 0x89, 0xa1, 0x21, 0xbc, 0xd4, 0xcb, 0x9d, 0xc6, 0x7c, 0x81,
0xd9, 0x9d, 0xd9, 0x90, 0x54, 0xa4, 0x99, 0xae, 0x94, 0x05, 0x7d, 0x02, 0x07, 0xba, 0x03, 0x8e,
0x22, 0x4a, 0x22, 0x31, 0x1c, 0x16, 0x47, 0xe6, 0xb3, 0x7e, 0x7d, 0xd0, 0xf1, 0xf6, 0x35, 0xc2,
0x65, 0x61, 0x9f, 0xc4, 0x11, 0xfa, 0x18, 0x9a, 0xe5, 0xe8, 0xcd, 0xe7, 0x7d, 0x63, 0xd0, 0x72,
0x2d, 0x47, 0x2d, 0x87, 0x53, 0x2c, 0x87, 0xf3, 0x7d, 0xc1, 0xf0, 0xee, 0xc9, 0xf6, 0x08, 0x7a,
0xa5, 0x3e, 0x9b, 0xb1, 0x1e, 0x02, 0x4c, 0x93, 0x2c, 0xb8, 0xd3, 0xf5, 0x69, 0x4a, 0x44, 0x6e,
0xc2, 0x2f, 0xd0, 0x51, 0x32, 0x17, 0x82, 0x7e, 0x07, 0x2d, 0xad, 0x2e, 0xe9, 0xd0, 0x72, 0x3f,
0x70, 0x76, 0x97, 0x3e, 0x77, 0x73, 0x67, 0x75, 0xee, 0x94, 0x75, 0xeb, 0xc3, 0xf2, 0xf4, 0x08,
0xf6, 0xa7, 0xd0, 0x2d, 0x32, 0x6c, 0x4a, 0x3a, 0x83, 0x3d, 0x5d, 0x1b, 0xad, 0xb0, 0x9e, 0x86,
0xcb, 0xf2, 0xde, 0x83, 0xe6, 0xcd, 0x72, 0x9a, 0xc4, 0xc1, 0xd7, 0x64, 0x2d, 0x5a, 0xc9, 0xe5,
0x8f, 0x7f, 0x47, 0xd6, 0xd2, 0xa3, 0xe1, 0x35, 0xf3, 0xc2, 0x6c, 0xbf, 0x2f, 0x76, 0x1a, 0xd3,
0x70, 0xfc, 0x79, 0x99, 0xe9, 0x00, 0x5e, 0x67, 0x02, 0xf2, 0xe3, 0x70, 0xc3, 0x7f, 0x4d, 0xfe,
0x8f, 0x43, 0xfb, 0x04, 0x3a, 0xe3, 0x34, 0x24, 0xbf, 0x95, 0xdc, 0x37, 0xe0, 0x59, 0x2c, 0x00,
0x49, 0xec, 0x78, 0xea, 0xc7, 0xb6, 0xa1, 0x2d, 0x76, 0xaf, 0x64, 0x21, 0x68, 0x88, 0xdd, 0xd9,
0x44, 0x93, 0xdf, 0xee, 0x1f, 0x75, 0xe8, 0x5c, 0x49, 0x59, 0x26, 0xea, 0xa9, 0x40, 0x1e, 0xbc,
0xf8, 0x06, 0x8b, 0x4e, 0x14, 0x7c, 0x25, 0xe4, 0x46, 0xaf, 0x1e, 0xcc, 0xf0, 0x0b, 0x71, 0xfd,
0xd6, 0x71, 0x95, 0xb8, 0x9a, 0xf3, 0xc8, 0x40, 0x3f, 0xc3, 0xbe, 0x8a, 0xf9, 0xd9, 0xee, 0x49,
0x57, 0x46, 0x3e, 0xab, 0x8a, 0xfc, 0x20, 0xc4, 0xc8, 0x40, 0x39, 0x1c, 0x7e, 0x49, 0x78, 0x30,
0x9f, 0x54, 0x9d, 0xf8, 0xa9, 0xf3, 0xef, 0x2f, 0x9f, 0xb3, 0xfd, 0x28, 0x59, 0xef, 0x3e, 0xca,
0xdb, 0x68, 0xf9, 0x63, 0xa1, 0x92, 0xb6, 0x3b, 0x95, 0xbd, 0xfc, 0xbf, 0x15, 0x1c, 0x19, 0x6e,
0x0a, 0x3d, 0x05, 0x10, 0x5a, 0x8c, 0xe5, 0x16, 0x40, 0x41, 0xd7, 0x04, 0x87, 0xe8, 0xa4, 0xaa,
0xce, 0xad, 0x83, 0xb0, 0x4e, 0x1f, 0xa3, 0xa9, 0x6e, 0x5c, 0x5a, 0xde, 0x5e, 0x99, 0xcf, 0x87,
0xf6, 0x06, 0x52, 0x1b, 0x50, 0x19, 0x6a, 0xfb, 0x51, 0xab, 0x56, 0x70, 0xe7, 0xb8, 0xdd, 0xbf,
0x6a, 0xb0, 0x57, 0xce, 0xa9, 0xc8, 0x8a, 0xe1, 0xe5, 0x57, 0x84, 0xdf, 0xc3, 0xea, 0x26, 0xd0,
0xdb, 0x95, 0x41, 0x8b, 0x0b, 0xfa, 0xaf, 0xc9, 0x6d, 0xdf, 0xd5, 0x4f, 0xf0, 0x42, 0x4f, 0x21,
0x0f, 0xe9, 0x29, 0x09, 0x2a, 0x25, 0xdf, 0x3e, 0xc5, 0x5b, 0xd8, 0xdb, 0xea, 0x20, 0xc9, 0xf8,
0x53, 0xa2, 0xbf, 0x53, 0x59, 0xbe, 0x76, 0xc1, 0xd3, 0xe7, 0x72, 0xb1, 0x3e, 0xfc, 0x27, 0x00,
0x00, 0xff, 0xff, 0x8e, 0x2a, 0x92, 0xe1, 0xec, 0x07, 0x00, 0x00,
}

View File

@@ -21,6 +21,12 @@ service ProposerService {
rpc ProposeBlock(ProposeRequest) returns (ProposeResponse);
}
service ValidatorService {
rpc ValidatorShardID(PublicKey) returns (ShardIDResponse);
rpc ValidatorIndex(PublicKey) returns (IndexResponse);
rpc ValidatorSlot(PublicKey) returns (SlotResponse);
}
message ShuffleRequest {
bytes crystallized_state_hash = 1;
}
@@ -51,3 +57,19 @@ message AttestRequest {
message AttestResponse {
bytes attestation_hash = 1;
}
message PublicKey {
uint64 public_key = 1;
}
message ShardIDResponse {
uint64 shard_id = 1;
}
message IndexResponse {
uint32 index = 1;
}
message SlotResponse {
uint64 slot = 1;
}

View File

@@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"bit.go",
"marshal.go",
"service_registry.go",
"types.go",
@@ -15,12 +16,14 @@ go_library(
"@com_github_ethereum_go_ethereum//rlp:go_default_library",
"@com_github_golang_protobuf//proto:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_steakknife_hamming//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"bit_test.go",
"marshal_test.go",
"service_registry_test.go",
],

50
shared/bit.go Normal file
View File

@@ -0,0 +1,50 @@
package shared
import (
"math"
"github.com/steakknife/hamming"
)
// CheckBit checks if a bit in a bit field is one.
func CheckBit(bitfield []byte, index int) bool {
chunkLocation := (index + 1) / 8
indexLocation := (index + 1) % 8
if indexLocation == 0 {
indexLocation = 8
} else {
chunkLocation++
}
field := bitfield[chunkLocation-1] >> (8 - uint(indexLocation))
return field%2 != 0
}
// BitSetCount counts the number of 1s in a byte using the following algo:
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
func BitSetCount(bytes []byte) int {
var total int
for _, b := range bytes {
total += hamming.CountBitsByte(b)
}
return total
}
// BitLength returns the length of the bitfield in bytes.
func BitLength(b int) int {
return (b + 7) / 8
}
// SetBitfield takes an index and returns bitfield with the index flipped.
func SetBitfield(index int) []byte {
chunkLocation := index / 8
indexLocation := math.Pow(2, 7-float64(index%8))
var bitfield []byte
for i := 0; i < chunkLocation; i++ {
bitfield = append(bitfield, byte(0))
}
bitfield = append(bitfield, byte(indexLocation))
return bitfield
}

View File

@@ -1,6 +1,7 @@
package utils
package shared
import (
"bytes"
"testing"
)
@@ -59,3 +60,21 @@ func TestByteLength(t *testing.T) {
}
}
}
func TestBitSet(t *testing.T) {
tests := []struct {
a int
b []byte
}{
{a: 0, b: []byte{128}}, //10000000
{a: 1, b: []byte{64}}, //01000000
{a: 5, b: []byte{4}}, //00000100
{a: 10, b: []byte{0, 32}}, //00000000 00100000
{a: 100, b: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}},
}
for _, tt := range tests {
if !bytes.Equal(SetBitfield(tt.a), tt.b) {
t.Errorf("SetBitfield(%v) = %d, want = %v", tt.a, SetBitfield(tt.a), tt.b)
}
}
}

View File

@@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["log.go"],
srcs = [
"checkbit.go",
"log.go",
],
importpath = "github.com/prysmaticlabs/prysm/shared/testutil",
visibility = ["//visibility:public"],
deps = ["@com_github_sirupsen_logrus//hooks/test:go_default_library"],

View File

@@ -1,4 +1,4 @@
package utils
package testutil
// CheckBit checks if a bit in a bit field is one.
func CheckBit(bitfield []byte, index int) bool {

View File

@@ -8,6 +8,7 @@ go_library(
deps = [
"//proto/beacon/p2p/v1:go_default_library",
"//proto/beacon/rpc/v1:go_default_library",
"//shared:go_default_library",
"@com_github_ethereum_go_ethereum//event:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",

View File

@@ -9,14 +9,16 @@ import (
"github.com/gogo/protobuf/proto"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
"github.com/prysmaticlabs/prysm/shared"
"github.com/sirupsen/logrus"
blake2b "golang.org/x/crypto/blake2b"
"golang.org/x/crypto/blake2b"
)
var log = logrus.WithField("prefix", "attester")
type rpcClientService interface {
AttesterServiceClient() pb.AttesterServiceClient
ValidatorServiceClient() pb.ValidatorServiceClient
}
type assignmentAnnouncer interface {
@@ -58,8 +60,9 @@ func NewAttester(ctx context.Context, cfg *Config) *Attester {
// Start the main routine for an attester.
func (a *Attester) Start() {
log.Info("Starting service")
client := a.rpcClientService.AttesterServiceClient()
go a.run(a.ctx.Done(), client)
attester := a.rpcClientService.AttesterServiceClient()
validator := a.rpcClientService.ValidatorServiceClient()
go a.run(attester, validator)
}
// Stop the main loop.
@@ -70,13 +73,13 @@ func (a *Attester) Stop() error {
}
// run the main event loop that listens for an attester assignment.
func (a *Attester) run(done <-chan struct{}, client pb.AttesterServiceClient) {
func (a *Attester) run(attester pb.AttesterServiceClient, validator pb.ValidatorServiceClient) {
sub := a.assigner.AttesterAssignmentFeed().Subscribe(a.assignmentChan)
defer sub.Unsubscribe()
for {
select {
case <-done:
case <-a.ctx.Done():
log.Debug("Attester context closed, exiting goroutine")
return
case latestBeaconBlock := <-a.assignmentChan:
@@ -84,22 +87,40 @@ func (a *Attester) run(done <-chan struct{}, client pb.AttesterServiceClient) {
data, err := proto.Marshal(latestBeaconBlock)
if err != nil {
log.Errorf("Could not marshal latest beacon block: %v", err)
log.Errorf("could not marshal latest beacon block: %v", err)
continue
}
latestBlockHash := blake2b.Sum512(data)
req := &pb.AttestRequest{
pubKeyReq := &pb.PublicKey{
PublicKey: 0,
}
shardID, err := validator.ValidatorShardID(a.ctx, pubKeyReq)
if err != nil {
log.Errorf("could not get attester Shard ID: %v", err)
continue
}
a.shardID = shardID.ShardId
attesterIndex, err := validator.ValidatorIndex(a.ctx, pubKeyReq)
if err != nil {
log.Errorf("could not get attester index: %v", err)
continue
}
attesterBitfield := shared.SetBitfield(int(attesterIndex.Index))
attestReq := &pb.AttestRequest{
Attestation: &pbp2p.AggregatedAttestation{
Slot: latestBeaconBlock.GetSlotNumber(),
ShardId: a.shardID,
AttesterBitfield: attesterBitfield,
ShardBlockHash: latestBlockHash[:], // Is a stub for actual shard blockhash.
AttesterBitfield: []byte{}, // TODO: Need to find which index this attester represents.
AggregateSig: []uint64{}, // TODO: Need Signature verification scheme/library
},
}
res, err := client.AttestHead(a.ctx, req)
res, err := attester.AttestHead(a.ctx, attestReq)
if err != nil {
log.Errorf("could not attest head: %v", err)
continue

View File

@@ -29,6 +29,10 @@ func (mc *mockClient) AttesterServiceClient() pb.AttesterServiceClient {
return internal.NewMockAttesterServiceClient(mc.ctrl)
}
func (mc *mockClient) ValidatorServiceClient() pb.ValidatorServiceClient {
return internal.NewMockValidatorServiceClient(mc.ctrl)
}
type mockAssigner struct{}
func (m *mockAssigner) AttesterAssignmentFeed() *event.Feed {
@@ -63,23 +67,35 @@ func TestAttesterLoop(t *testing.T) {
}
att := NewAttester(context.Background(), cfg)
mockServiceClient := internal.NewMockAttesterServiceClient(ctrl)
mockServiceClient.EXPECT().AttestHead(
mockServiceValidator := internal.NewMockValidatorServiceClient(ctrl)
mockServiceValidator.EXPECT().ValidatorShardID(
gomock.Any(),
gomock.Any(),
).Return(&pb.ShardIDResponse{
ShardId: 100,
}, nil)
mockServiceValidator.EXPECT().ValidatorIndex(
gomock.Any(),
gomock.Any(),
).Return(&pb.IndexResponse{
Index: 0,
}, nil)
mockServiceAttester := internal.NewMockAttesterServiceClient(ctrl)
mockServiceAttester.EXPECT().AttestHead(
gomock.Any(),
gomock.Any(),
).Return(&pb.AttestResponse{
AttestationHash: []byte{'A'},
}, nil)
doneChan := make(chan struct{})
exitRoutine := make(chan bool)
go func() {
att.run(doneChan, mockServiceClient)
att.run(mockServiceAttester, mockServiceValidator)
<-exitRoutine
}()
att.assignmentChan <- &pbp2p.BeaconBlock{SlotNumber: 33}
doneChan <- struct{}{}
att.cancel()
exitRoutine <- true
testutil.AssertLogsContain(t, hook, "Performing attester responsibility")
@@ -90,31 +106,33 @@ func TestAttesterMarshalError(t *testing.T) {
hook := logTest.NewGlobal()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
ctx := context.Background()
cfg := &Config{
AssignmentBuf: 0,
Assigner: &mockAssigner{},
Client: &mockClient{ctrl},
}
p := NewAttester(context.Background(), cfg)
att := NewAttester(ctx, cfg)
mockServiceClient := internal.NewMockAttesterServiceClient(ctrl)
mockServiceAttester := internal.NewMockAttesterServiceClient(ctrl)
mockServiceValidator := internal.NewMockValidatorServiceClient(ctrl)
doneChan := make(chan struct{})
exitRoutine := make(chan bool)
go func() {
p.run(doneChan, mockServiceClient)
att.run(mockServiceAttester, mockServiceValidator)
<-exitRoutine
}()
p.assignmentChan <- nil
doneChan <- struct{}{}
att.assignmentChan <- nil
att.cancel()
exitRoutine <- true
testutil.AssertLogsContain(t, hook, "Could not marshal latest beacon block")
testutil.AssertLogsContain(t, hook, "could not marshal latest beacon block")
testutil.AssertLogsContain(t, hook, "Attester context closed")
}
func TestAttesterErrorLoop(t *testing.T) {
func TestAttesterErrorCantAttestHead(t *testing.T) {
hook := logTest.NewGlobal()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
@@ -123,28 +141,114 @@ func TestAttesterErrorLoop(t *testing.T) {
Assigner: &mockAssigner{},
Client: &mockClient{ctrl},
}
p := NewAttester(context.Background(), cfg)
att := NewAttester(context.Background(), cfg)
mockServiceClient := internal.NewMockAttesterServiceClient(ctrl)
mockServiceValidator := internal.NewMockValidatorServiceClient(ctrl)
mockServiceValidator.EXPECT().ValidatorShardID(
gomock.Any(),
gomock.Any(),
).Return(&pb.ShardIDResponse{
ShardId: 100,
}, nil)
mockServiceValidator.EXPECT().ValidatorIndex(
gomock.Any(),
gomock.Any(),
).Return(&pb.IndexResponse{
Index: 0,
}, nil)
mockServiceAttester := internal.NewMockAttesterServiceClient(ctrl)
// Expect call to throw an error.
mockServiceClient.EXPECT().AttestHead(
mockServiceAttester.EXPECT().AttestHead(
gomock.Any(),
gomock.Any(),
).Return(nil, errors.New("could not attest head"))
doneChan := make(chan struct{})
exitRoutine := make(chan bool)
go func() {
p.run(doneChan, mockServiceClient)
att.run(mockServiceAttester, mockServiceValidator)
<-exitRoutine
}()
p.assignmentChan <- &pbp2p.BeaconBlock{SlotNumber: 999}
doneChan <- struct{}{}
att.assignmentChan <- &pbp2p.BeaconBlock{SlotNumber: 999}
att.cancel()
exitRoutine <- true
testutil.AssertLogsContain(t, hook, "Performing attester responsibility")
testutil.AssertLogsContain(t, hook, "could not attest head")
testutil.AssertLogsContain(t, hook, "Attester context closed")
}
func TestAttesterErrorCantGetShardID(t *testing.T) {
hook := logTest.NewGlobal()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cfg := &Config{
AssignmentBuf: 0,
Assigner: &mockAssigner{},
Client: &mockClient{ctrl},
}
att := NewAttester(context.Background(), cfg)
mockServiceValidator := internal.NewMockValidatorServiceClient(ctrl)
mockServiceValidator.EXPECT().ValidatorShardID(
gomock.Any(),
gomock.Any(),
).Return(nil, errors.New("could not get attester Shard ID"))
mockServiceAttester := internal.NewMockAttesterServiceClient(ctrl)
exitRoutine := make(chan bool)
go func() {
att.run(mockServiceAttester, mockServiceValidator)
<-exitRoutine
}()
att.assignmentChan <- &pbp2p.BeaconBlock{SlotNumber: 999}
att.cancel()
exitRoutine <- true
testutil.AssertLogsContain(t, hook, "Performing attester responsibility")
testutil.AssertLogsContain(t, hook, "could not get attester Shard ID")
testutil.AssertLogsContain(t, hook, "Attester context closed")
}
func TestAttesterErrorCantGetAttesterIndex(t *testing.T) {
hook := logTest.NewGlobal()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cfg := &Config{
AssignmentBuf: 0,
Assigner: &mockAssigner{},
Client: &mockClient{ctrl},
}
att := NewAttester(context.Background(), cfg)
mockServiceValidator := internal.NewMockValidatorServiceClient(ctrl)
mockServiceValidator.EXPECT().ValidatorShardID(
gomock.Any(),
gomock.Any(),
).Return(&pb.ShardIDResponse{
ShardId: 100,
}, nil)
mockServiceValidator.EXPECT().ValidatorIndex(
gomock.Any(),
gomock.Any(),
).Return(nil, errors.New("could not get attester index"))
mockServiceAttester := internal.NewMockAttesterServiceClient(ctrl)
exitRoutine := make(chan bool)
go func() {
att.run(mockServiceAttester, mockServiceValidator)
<-exitRoutine
}()
att.assignmentChan <- &pbp2p.BeaconBlock{SlotNumber: 999}
att.cancel()
exitRoutine <- true
testutil.AssertLogsContain(t, hook, "Performing attester responsibility")
testutil.AssertLogsContain(t, hook, "could not get attester index")
testutil.AssertLogsContain(t, hook, "Attester context closed")
}

View File

@@ -52,3 +52,80 @@ func (mr *MockAttesterServiceClientMockRecorder) AttestHead(arg0, arg1 interface
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AttestHead", reflect.TypeOf((*MockAttesterServiceClient)(nil).AttestHead), varargs...)
}
// MockValidatorServiceClient is a mock of ValidatorServiceClient interface
type MockValidatorServiceClient struct {
ctrl *gomock.Controller
recorder *MockValidatorServiceClientMockRecorder
}
// MockValidatorServiceClientMockRecorder is the mock recorder for MockValidatorServiceClient
type MockValidatorServiceClientMockRecorder struct {
mock *MockValidatorServiceClient
}
// NewMockValidatorServiceClient creates a new mock instance
func NewMockValidatorServiceClient(ctrl *gomock.Controller) *MockValidatorServiceClient {
mock := &MockValidatorServiceClient{ctrl: ctrl}
mock.recorder = &MockValidatorServiceClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockValidatorServiceClient) EXPECT() *MockValidatorServiceClientMockRecorder {
return m.recorder
}
// ValidatorIndex mocks base method
func (m *MockValidatorServiceClient) ValidatorIndex(arg0 context.Context, arg1 *v1.PublicKey, arg2 ...grpc.CallOption) (*v1.IndexResponse, error) {
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ValidatorIndex", varargs...)
ret0, _ := ret[0].(*v1.IndexResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ValidatorIndex indicates an expected call of ValidatorIndex
func (mr *MockValidatorServiceClientMockRecorder) ValidatorIndex(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorIndex", reflect.TypeOf((*MockValidatorServiceClient)(nil).ValidatorIndex), varargs...)
}
// ValidatorShardID mocks base method
func (m *MockValidatorServiceClient) ValidatorShardID(arg0 context.Context, arg1 *v1.PublicKey, arg2 ...grpc.CallOption) (*v1.ShardIDResponse, error) {
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ValidatorShardID", varargs...)
ret0, _ := ret[0].(*v1.ShardIDResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ValidatorShardID indicates an expected call of ValidatorShardID
func (mr *MockValidatorServiceClientMockRecorder) ValidatorShardID(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorShardID", reflect.TypeOf((*MockValidatorServiceClient)(nil).ValidatorShardID), varargs...)
}
// ValidatorSlot mocks base method
func (m *MockValidatorServiceClient) ValidatorSlot(arg0 context.Context, arg1 *v1.PublicKey, arg2 ...grpc.CallOption) (*v1.SlotResponse, error) {
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ValidatorSlot", varargs...)
ret0, _ := ret[0].(*v1.SlotResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ValidatorSlot indicates an expected call of ValidatorSlot
func (mr *MockValidatorServiceClientMockRecorder) ValidatorSlot(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorSlot", reflect.TypeOf((*MockValidatorServiceClient)(nil).ValidatorSlot), varargs...)
}

View File

@@ -99,3 +99,11 @@ func (s *Service) ProposerServiceClient() pb.ProposerServiceClient {
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)
}