mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Validator Attester Rewrite (#1487)
* initial validator attesthead rewrite based on proposer rewrite * proceed with fetching committees and tree hashing the canonical head at assigned attester slot * complete filling the properties of attestation data and all associated root hashes * add when to attest todo * finish entire attester client logic * tests with mocks checked in * tests passing in client * stubbed out server implementation * fixed build due to old property * regen mocks with new mockgen version * fixed broken tests * complete bazel build fix * address some review comments * deep proto test * tests passing after checking for empty committee and crosslink root * address nishant comments
This commit is contained in:
@@ -117,7 +117,7 @@ http_archive(
|
||||
|
||||
go_repository(
|
||||
name = "com_github_golang_mock",
|
||||
commit = "8a44ef6e8be577e050008c7886f24fc705d709fb",
|
||||
commit = "c20582278a829e4b3259747a3ce0eceb1763ee13",
|
||||
importpath = "github.com/golang/mock",
|
||||
)
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ func (a *Service) updateLatestAttestation(attestation *pb.Attestation) error {
|
||||
|
||||
// The participation bitfield from attestation is represented in bytes,
|
||||
// here we multiply by 8 to get an accurate validator count in bits.
|
||||
bitfield := attestation.ParticipationBitfield
|
||||
bitfield := attestation.AggregationBitfield
|
||||
totalBits := len(bitfield) * 8
|
||||
|
||||
// Check each bit of participation bitfield to find out which
|
||||
|
||||
@@ -27,7 +27,7 @@ func TestUpdateLatestAttestation_Ok(t *testing.T) {
|
||||
service := NewAttestationService(context.Background(), &Config{BeaconDB: beaconDB})
|
||||
|
||||
attestation := &pb.Attestation{
|
||||
ParticipationBitfield: []byte{0x80},
|
||||
AggregationBitfield: []byte{0x80},
|
||||
Data: &pb.AttestationData{
|
||||
Slot: 5,
|
||||
},
|
||||
@@ -66,8 +66,8 @@ func TestAttestationPool_Ok(t *testing.T) {
|
||||
|
||||
service := NewAttestationService(context.Background(), &Config{BeaconDB: beaconDB})
|
||||
attestation := &pb.Attestation{
|
||||
ParticipationBitfield: []byte{0x80},
|
||||
Data: &pb.AttestationData{},
|
||||
AggregationBitfield: []byte{0x80},
|
||||
Data: &pb.AttestationData{},
|
||||
}
|
||||
|
||||
exitRoutine := make(chan bool)
|
||||
|
||||
@@ -364,7 +364,7 @@ func TestRunningChainService(t *testing.T) {
|
||||
},
|
||||
Body: &pb.BeaconBlockBody{
|
||||
Attestations: []*pb.Attestation{{
|
||||
ParticipationBitfield: []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
AggregationBitfield: []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
Data: &pb.AttestationData{
|
||||
Slot: attestationSlot,
|
||||
@@ -563,7 +563,7 @@ func TestIsBlockReadyForProcessing(t *testing.T) {
|
||||
},
|
||||
Body: &pb.BeaconBlockBody{
|
||||
Attestations: []*pb.Attestation{{
|
||||
ParticipationBitfield: []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
AggregationBitfield: []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
Data: &pb.AttestationData{
|
||||
Slot: attestationSlot,
|
||||
|
||||
@@ -214,8 +214,8 @@ func TestInclusionDistRewards_Ok(t *testing.T) {
|
||||
|
||||
attestation := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{Slot: 0},
|
||||
ParticipationBitfield: participationBitfield,
|
||||
SlotIncluded: 5},
|
||||
AggregationBitfield: participationBitfield,
|
||||
SlotIncluded: 5},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -263,7 +263,7 @@ func TestInclusionDistRewards_NotOk(t *testing.T) {
|
||||
|
||||
attestation := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{Shard: 1, Slot: 0},
|
||||
ParticipationBitfield: []byte{0xff}},
|
||||
AggregationBitfield: []byte{0xff}},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -447,8 +447,8 @@ func TestInactivityInclusionPenalty_Ok(t *testing.T) {
|
||||
}
|
||||
attestation := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{Slot: 0},
|
||||
ParticipationBitfield: participationBitfield,
|
||||
SlotIncluded: 5},
|
||||
AggregationBitfield: participationBitfield,
|
||||
SlotIncluded: 5},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -495,7 +495,7 @@ func TestInactivityInclusionPenalty_NotOk(t *testing.T) {
|
||||
}
|
||||
attestation := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{Shard: 1, Slot: 0},
|
||||
ParticipationBitfield: []byte{0xff}},
|
||||
AggregationBitfield: []byte{0xff}},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -531,8 +531,8 @@ func TestAttestationInclusionRewards(t *testing.T) {
|
||||
}
|
||||
attestation := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{Slot: 0},
|
||||
ParticipationBitfield: participationBitfield,
|
||||
SlotIncluded: 0},
|
||||
AggregationBitfield: participationBitfield,
|
||||
SlotIncluded: 0},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -608,8 +608,8 @@ func TestAttestationInclusionRewards_NoProposerIndex(t *testing.T) {
|
||||
}
|
||||
attestation := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{Shard: 1, Slot: 0},
|
||||
ParticipationBitfield: []byte{0xff},
|
||||
SlotIncluded: 0},
|
||||
AggregationBitfield: []byte{0xff},
|
||||
SlotIncluded: 0},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -663,8 +663,8 @@ func TestCrosslinksRewardsPenalties(t *testing.T) {
|
||||
}
|
||||
attestation := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{Shard: 1, Slot: 0},
|
||||
ParticipationBitfield: tt.voted,
|
||||
SlotIncluded: 0},
|
||||
AggregationBitfield: tt.voted,
|
||||
SlotIncluded: 0},
|
||||
}
|
||||
state := &pb.BeaconState{
|
||||
ValidatorRegistry: validators,
|
||||
|
||||
@@ -441,10 +441,10 @@ func ProcessBlockAttestations(
|
||||
return nil, fmt.Errorf("could not verify attestation at index %d in block: %v", idx, err)
|
||||
}
|
||||
pendingAttestations = append(pendingAttestations, &pb.PendingAttestationRecord{
|
||||
Data: attestation.Data,
|
||||
ParticipationBitfield: attestation.ParticipationBitfield,
|
||||
CustodyBitfield: attestation.CustodyBitfield,
|
||||
SlotIncluded: beaconState.Slot,
|
||||
Data: attestation.Data,
|
||||
AggregationBitfield: attestation.AggregationBitfield,
|
||||
CustodyBitfield: attestation.CustodyBitfield,
|
||||
SlotIncluded: beaconState.Slot,
|
||||
})
|
||||
}
|
||||
beaconState.LatestAttestations = pendingAttestations
|
||||
|
||||
@@ -1088,8 +1088,8 @@ func TestProcessBlockAttestations_CreatePendingAttestations(t *testing.T) {
|
||||
LatestCrosslinkRootHash32: []byte{1},
|
||||
ShardBlockRootHash32: []byte{},
|
||||
},
|
||||
ParticipationBitfield: []byte{1},
|
||||
CustodyBitfield: []byte{1},
|
||||
AggregationBitfield: []byte{1},
|
||||
CustodyBitfield: []byte{1},
|
||||
}
|
||||
attestations := []*pb.Attestation{att1}
|
||||
block := &pb.BeaconBlock{
|
||||
|
||||
@@ -206,7 +206,7 @@ func TotalBalance(
|
||||
func InclusionSlot(state *pb.BeaconState, validatorIndex uint64) (uint64, error) {
|
||||
lowestSlotIncluded := uint64(math.MaxUint64)
|
||||
for _, attestation := range state.LatestAttestations {
|
||||
participatedValidators, err := helpers.AttestationParticipants(state, attestation.Data, attestation.ParticipationBitfield)
|
||||
participatedValidators, err := helpers.AttestationParticipants(state, attestation.Data, attestation.AggregationBitfield)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not get attestation participants: %v", err)
|
||||
}
|
||||
@@ -234,7 +234,7 @@ func InclusionSlot(state *pb.BeaconState, validatorIndex uint64) (uint64, error)
|
||||
func InclusionDistance(state *pb.BeaconState, validatorIndex uint64) (uint64, error) {
|
||||
|
||||
for _, attestation := range state.LatestAttestations {
|
||||
participatedValidators, err := helpers.AttestationParticipants(state, attestation.Data, attestation.ParticipationBitfield)
|
||||
participatedValidators, err := helpers.AttestationParticipants(state, attestation.Data, attestation.AggregationBitfield)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not get attestation participants: %v", err)
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ func TestWinningRootOk(t *testing.T) {
|
||||
Slot: 0,
|
||||
ShardBlockRootHash32: []byte{byte(i + 100)},
|
||||
},
|
||||
ParticipationBitfield: participationBitfield,
|
||||
AggregationBitfield: participationBitfield,
|
||||
}
|
||||
attestations = append(attestations, attestation)
|
||||
}
|
||||
@@ -343,7 +343,7 @@ func TestWinningRootCantGetParticipantBitfield(t *testing.T) {
|
||||
{Data: &pb.AttestationData{
|
||||
ShardBlockRootHash32: []byte{},
|
||||
},
|
||||
ParticipationBitfield: []byte{},
|
||||
AggregationBitfield: []byte{},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ func TestAttestingValidatorsOk(t *testing.T) {
|
||||
Data: &pb.AttestationData{
|
||||
ShardBlockRootHash32: []byte{byte(i + 100)},
|
||||
},
|
||||
ParticipationBitfield: []byte{0xFF},
|
||||
AggregationBitfield: []byte{0xFF},
|
||||
}
|
||||
attestations = append(attestations, attestation)
|
||||
}
|
||||
@@ -389,7 +389,7 @@ func TestAttestingValidatorsCantGetWinningRoot(t *testing.T) {
|
||||
Data: &pb.AttestationData{
|
||||
ShardBlockRootHash32: []byte{},
|
||||
},
|
||||
ParticipationBitfield: []byte{},
|
||||
AggregationBitfield: []byte{},
|
||||
}
|
||||
|
||||
want := fmt.Sprintf("wanted participants bitfield length %d, got: %d", 16, 0)
|
||||
@@ -410,7 +410,7 @@ func TestTotalAttestingBalanceOk(t *testing.T) {
|
||||
ShardBlockRootHash32: []byte{byte(i + 100)},
|
||||
},
|
||||
// All validators attested to the above roots.
|
||||
ParticipationBitfield: []byte{0xff},
|
||||
AggregationBitfield: []byte{0xff},
|
||||
}
|
||||
attestations = append(attestations, attestation)
|
||||
}
|
||||
@@ -436,7 +436,7 @@ func TestTotalAttestingBalanceCantGetWinningRoot(t *testing.T) {
|
||||
Data: &pb.AttestationData{
|
||||
ShardBlockRootHash32: []byte{},
|
||||
},
|
||||
ParticipationBitfield: []byte{},
|
||||
AggregationBitfield: []byte{},
|
||||
}
|
||||
|
||||
want := fmt.Sprintf("wanted participants bitfield length %d, got: %d", 16, 0)
|
||||
@@ -469,14 +469,14 @@ func TestInclusionSlotOk(t *testing.T) {
|
||||
|
||||
state.LatestAttestations = []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{},
|
||||
ParticipationBitfield: participationBitfield,
|
||||
SlotIncluded: 101},
|
||||
AggregationBitfield: participationBitfield,
|
||||
SlotIncluded: 101},
|
||||
{Data: &pb.AttestationData{},
|
||||
ParticipationBitfield: participationBitfield,
|
||||
SlotIncluded: 100},
|
||||
AggregationBitfield: participationBitfield,
|
||||
SlotIncluded: 100},
|
||||
{Data: &pb.AttestationData{},
|
||||
ParticipationBitfield: participationBitfield,
|
||||
SlotIncluded: 102},
|
||||
AggregationBitfield: participationBitfield,
|
||||
SlotIncluded: 102},
|
||||
}
|
||||
slot, err := InclusionSlot(state, 237)
|
||||
if err != nil {
|
||||
@@ -493,8 +493,8 @@ func TestInclusionSlotBadBitfield(t *testing.T) {
|
||||
|
||||
state.LatestAttestations = []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{},
|
||||
ParticipationBitfield: []byte{},
|
||||
SlotIncluded: 100},
|
||||
AggregationBitfield: []byte{},
|
||||
SlotIncluded: 100},
|
||||
}
|
||||
|
||||
want := fmt.Sprintf("wanted participants bitfield length %d, got: %d", 16, 0)
|
||||
@@ -522,8 +522,8 @@ func TestInclusionDistanceOk(t *testing.T) {
|
||||
|
||||
state.LatestAttestations = []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{},
|
||||
ParticipationBitfield: participationBitfield,
|
||||
SlotIncluded: 100},
|
||||
AggregationBitfield: participationBitfield,
|
||||
SlotIncluded: 100},
|
||||
}
|
||||
distance, err := InclusionDistance(state, 237)
|
||||
if err != nil {
|
||||
@@ -543,8 +543,8 @@ func TestInclusionDistanceBadBitfield(t *testing.T) {
|
||||
|
||||
state.LatestAttestations = []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{},
|
||||
ParticipationBitfield: []byte{},
|
||||
SlotIncluded: 100},
|
||||
AggregationBitfield: []byte{},
|
||||
SlotIncluded: 100},
|
||||
}
|
||||
|
||||
want := fmt.Sprintf("wanted participants bitfield length %d, got: %d", 16, 0)
|
||||
|
||||
@@ -312,7 +312,7 @@ func TestProcessCrosslinksOk(t *testing.T) {
|
||||
ShardBlockRootHash32: []byte{'A'},
|
||||
},
|
||||
// All validators attested to the above roots.
|
||||
ParticipationBitfield: participationBitfield,
|
||||
AggregationBitfield: participationBitfield,
|
||||
}
|
||||
attestations = append(attestations, attestation)
|
||||
}
|
||||
@@ -346,7 +346,7 @@ func TestProcessCrosslinksNoParticipantsBitField(t *testing.T) {
|
||||
attestations := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{},
|
||||
// Empty participation bitfield will trigger error.
|
||||
ParticipationBitfield: []byte{}}}
|
||||
AggregationBitfield: []byte{}}}
|
||||
|
||||
wanted := fmt.Sprintf(
|
||||
"wanted participants bitfield length %d, got: %d",
|
||||
|
||||
@@ -237,8 +237,8 @@ func TestProcessBlock_IncorrectProcessExits(t *testing.T) {
|
||||
LatestCrosslinkRootHash32: []byte{1},
|
||||
ShardBlockRootHash32: []byte{},
|
||||
},
|
||||
ParticipationBitfield: []byte{1},
|
||||
CustodyBitfield: []byte{1},
|
||||
AggregationBitfield: []byte{1},
|
||||
CustodyBitfield: []byte{1},
|
||||
}
|
||||
attestations := []*pb.Attestation{blockAtt}
|
||||
latestMixes := make([][]byte, config.LatestRandaoMixesLength)
|
||||
@@ -328,8 +328,8 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
||||
LatestCrosslinkRootHash32: []byte{1},
|
||||
ShardBlockRootHash32: []byte{},
|
||||
},
|
||||
ParticipationBitfield: []byte{1},
|
||||
CustodyBitfield: []byte{1},
|
||||
AggregationBitfield: []byte{1},
|
||||
CustodyBitfield: []byte{1},
|
||||
}
|
||||
attestations := []*pb.Attestation{blockAtt}
|
||||
latestMixes := make([][]byte, config.LatestRandaoMixesLength)
|
||||
@@ -443,8 +443,8 @@ func TestProcessEpoch_InactiveConditions(t *testing.T) {
|
||||
JustifiedSlot: 64,
|
||||
JustifiedBlockRootHash32: []byte{0},
|
||||
},
|
||||
ParticipationBitfield: []byte{},
|
||||
SlotIncluded: i + config.EpochLength + 1,
|
||||
AggregationBitfield: []byte{},
|
||||
SlotIncluded: i + config.EpochLength + 1,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -506,7 +506,7 @@ func TestProcessEpoch_CantGetCurrentValidatorIndices(t *testing.T) {
|
||||
Shard: 1,
|
||||
JustifiedBlockRootHash32: make([]byte, 32),
|
||||
},
|
||||
ParticipationBitfield: []byte{0xff},
|
||||
AggregationBitfield: []byte{0xff},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -564,7 +564,7 @@ func TestProcessEpoch_CantProcessEjections(t *testing.T) {
|
||||
LatestRandaoMixesHash32S: randaoHashes,
|
||||
LatestCrosslinks: []*pb.CrosslinkRecord{{}},
|
||||
LatestAttestations: []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{}, ParticipationBitfield: participationBitfield},
|
||||
{Data: &pb.AttestationData{}, AggregationBitfield: participationBitfield},
|
||||
}}
|
||||
|
||||
want := fmt.Sprintf("could not process inclusion distance: 0")
|
||||
|
||||
@@ -187,7 +187,7 @@ func ValidatorIndices(
|
||||
attesterIndices, err := helpers.AttestationParticipants(
|
||||
state,
|
||||
attestation.Data,
|
||||
attestation.ParticipationBitfield)
|
||||
attestation.AggregationBitfield)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -221,7 +221,7 @@ func AttestingValidatorIndices(
|
||||
if attestation.Data.Shard == shard &&
|
||||
bytes.Equal(attestation.Data.ShardBlockRootHash32, shardBlockRoot) {
|
||||
|
||||
validatorIndicesCommittee, err := helpers.AttestationParticipants(state, attestation.Data, attestation.ParticipationBitfield)
|
||||
validatorIndicesCommittee, err := helpers.AttestationParticipants(state, attestation.Data, attestation.AggregationBitfield)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get attester indices: %v", err)
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ import (
|
||||
func TestHasVoted(t *testing.T) {
|
||||
// Setting bit field to 11111111.
|
||||
pendingAttestation := &pb.Attestation{
|
||||
ParticipationBitfield: []byte{255},
|
||||
AggregationBitfield: []byte{255},
|
||||
}
|
||||
|
||||
for i := 0; i < len(pendingAttestation.ParticipationBitfield); i++ {
|
||||
voted, err := bitutil.CheckBit(pendingAttestation.ParticipationBitfield, i)
|
||||
for i := 0; i < len(pendingAttestation.AggregationBitfield); i++ {
|
||||
voted, err := bitutil.CheckBit(pendingAttestation.AggregationBitfield, i)
|
||||
if err != nil {
|
||||
t.Errorf("checking bit failed at index: %d with : %v", i, err)
|
||||
}
|
||||
@@ -32,11 +32,11 @@ func TestHasVoted(t *testing.T) {
|
||||
|
||||
// Setting bit field to 01010101.
|
||||
pendingAttestation = &pb.Attestation{
|
||||
ParticipationBitfield: []byte{85},
|
||||
AggregationBitfield: []byte{85},
|
||||
}
|
||||
|
||||
for i := 0; i < len(pendingAttestation.ParticipationBitfield); i++ {
|
||||
voted, err := bitutil.CheckBit(pendingAttestation.ParticipationBitfield, i)
|
||||
for i := 0; i < len(pendingAttestation.AggregationBitfield); i++ {
|
||||
voted, err := bitutil.CheckBit(pendingAttestation.AggregationBitfield, i)
|
||||
if err != nil {
|
||||
t.Errorf("checking bit failed at index: %d : %v", i, err)
|
||||
}
|
||||
@@ -189,8 +189,8 @@ func TestBoundaryAttesterIndices(t *testing.T) {
|
||||
}
|
||||
|
||||
boundaryAttestations := []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{}, ParticipationBitfield: []byte{0x10}}, // returns indices 242
|
||||
{Data: &pb.AttestationData{}, ParticipationBitfield: []byte{0xF0}}, // returns indices 237,224,2
|
||||
{Data: &pb.AttestationData{}, AggregationBitfield: []byte{0x10}}, // returns indices 242
|
||||
{Data: &pb.AttestationData{}, AggregationBitfield: []byte{0xF0}}, // returns indices 237,224,2
|
||||
}
|
||||
|
||||
attesterIndices, err := ValidatorIndices(state, boundaryAttestations)
|
||||
@@ -293,7 +293,7 @@ func TestAttestingValidatorIndices_Ok(t *testing.T) {
|
||||
Shard: 6,
|
||||
ShardBlockRootHash32: []byte{'B'},
|
||||
},
|
||||
ParticipationBitfield: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
|
||||
AggregationBitfield: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
|
||||
}
|
||||
|
||||
indices, err := AttestingValidatorIndices(
|
||||
@@ -331,7 +331,7 @@ func TestAttestingValidatorIndices_OutOfBound(t *testing.T) {
|
||||
Shard: 1,
|
||||
ShardBlockRootHash32: []byte{'B'},
|
||||
},
|
||||
ParticipationBitfield: []byte{'A'}, // 01000001 = 1,7
|
||||
AggregationBitfield: []byte{'A'}, // 01000001 = 1,7
|
||||
}
|
||||
|
||||
_, err := AttestingValidatorIndices(
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
@@ -13,7 +15,6 @@ import (
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
@@ -89,7 +89,7 @@ func TestIncomingAttestation_Ok(t *testing.T) {
|
||||
<-exitRoutine
|
||||
}()
|
||||
attestation := &pb.Attestation{
|
||||
ParticipationBitfield: []byte{'A'},
|
||||
AggregationBitfield: []byte{'A'},
|
||||
Data: &pb.AttestationData{
|
||||
Slot: 100,
|
||||
}}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
)
|
||||
@@ -16,12 +17,26 @@ type AttesterServer struct {
|
||||
|
||||
// AttestHead is a function called by an attester in a sharding validator to vote
|
||||
// on a block via an attestation object as defined in the Ethereum Serenity specification.
|
||||
func (as *AttesterServer) AttestHead(ctx context.Context, req *pb.AttestRequest) (*pb.AttestResponse, error) {
|
||||
h, err := hashutil.HashProto(req.Attestation)
|
||||
func (as *AttesterServer) AttestHead(ctx context.Context, att *pbp2p.Attestation) (*pb.AttestResponse, error) {
|
||||
h, err := hashutil.HashProto(att)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not hash attestation: %v", err)
|
||||
}
|
||||
// Relays the attestation to chain service.
|
||||
as.operationService.IncomingAttFeed().Send(req.Attestation)
|
||||
as.operationService.IncomingAttFeed().Send(att)
|
||||
return &pb.AttestResponse{AttestationHash: h[:]}, nil
|
||||
}
|
||||
|
||||
// AttestationInfoAtSlot --
|
||||
//
|
||||
// TODO(#1505): WIP.
|
||||
func (as *AttesterServer) AttestationInfoAtSlot(ctx context.Context, req *pb.AttestationInfoRequest) (*pb.AttestationInfoResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// CrosslinkCommitteesAtSlot --
|
||||
//
|
||||
// TODO(#1505): WIP.
|
||||
func (as *AttesterServer) CrosslinkCommitteesAtSlot(ctx context.Context, req *pb.CrosslinkCommitteeRequest) (*pb.CrosslinkCommitteeResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"testing"
|
||||
|
||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
)
|
||||
|
||||
func TestAttestHead(t *testing.T) {
|
||||
@@ -13,13 +12,11 @@ func TestAttestHead(t *testing.T) {
|
||||
attesterServer := &AttesterServer{
|
||||
operationService: mockOperationService,
|
||||
}
|
||||
req := &pb.AttestRequest{
|
||||
Attestation: &pbp2p.Attestation{
|
||||
Data: &pbp2p.AttestationData{
|
||||
Slot: 999,
|
||||
Shard: 1,
|
||||
ShardBlockRootHash32: []byte{'a'},
|
||||
},
|
||||
req := &pbp2p.Attestation{
|
||||
Data: &pbp2p.AttestationData{
|
||||
Slot: 999,
|
||||
Shard: 1,
|
||||
ShardBlockRootHash32: []byte{'a'},
|
||||
},
|
||||
}
|
||||
if _, err := attesterServer.AttestHead(context.Background(), req); err != nil {
|
||||
|
||||
@@ -405,7 +405,7 @@ func TestReceiveAttestation_Ok(t *testing.T) {
|
||||
}()
|
||||
|
||||
request1 := &pb.Attestation{
|
||||
ParticipationBitfield: []byte{99},
|
||||
AggregationBitfield: []byte{99},
|
||||
Data: &pb.AttestationData{
|
||||
Slot: 0,
|
||||
},
|
||||
|
||||
443
proto/beacon/p2p/v1/types.pb.go
generated
443
proto/beacon/p2p/v1/types.pb.go
generated
@@ -44,7 +44,7 @@ func (x ValidatorRecord_StatusFlags) String() string {
|
||||
return proto.EnumName(ValidatorRecord_StatusFlags_name, int32(x))
|
||||
}
|
||||
func (ValidatorRecord_StatusFlags) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{6, 0}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{6, 0}
|
||||
}
|
||||
|
||||
type ValidatorRegistryDeltaBlock_ValidatorRegistryDeltaFlags int32
|
||||
@@ -67,7 +67,7 @@ func (x ValidatorRegistryDeltaBlock_ValidatorRegistryDeltaFlags) String() string
|
||||
return proto.EnumName(ValidatorRegistryDeltaBlock_ValidatorRegistryDeltaFlags_name, int32(x))
|
||||
}
|
||||
func (ValidatorRegistryDeltaBlock_ValidatorRegistryDeltaFlags) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{19, 0}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{19, 0}
|
||||
}
|
||||
|
||||
type BeaconState struct {
|
||||
@@ -105,7 +105,7 @@ func (m *BeaconState) Reset() { *m = BeaconState{} }
|
||||
func (m *BeaconState) String() string { return proto.CompactTextString(m) }
|
||||
func (*BeaconState) ProtoMessage() {}
|
||||
func (*BeaconState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{0}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{0}
|
||||
}
|
||||
func (m *BeaconState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -322,7 +322,7 @@ func (m *Fork) Reset() { *m = Fork{} }
|
||||
func (m *Fork) String() string { return proto.CompactTextString(m) }
|
||||
func (*Fork) ProtoMessage() {}
|
||||
func (*Fork) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{1}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{1}
|
||||
}
|
||||
func (m *Fork) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -373,20 +373,20 @@ func (m *Fork) GetEpoch() uint64 {
|
||||
}
|
||||
|
||||
type PendingAttestationRecord struct {
|
||||
Data *AttestationData `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
|
||||
ParticipationBitfield []byte `protobuf:"bytes,2,opt,name=participation_bitfield,json=participationBitfield,proto3" json:"participation_bitfield,omitempty"`
|
||||
CustodyBitfield []byte `protobuf:"bytes,3,opt,name=custody_bitfield,json=custodyBitfield,proto3" json:"custody_bitfield,omitempty"`
|
||||
SlotIncluded uint64 `protobuf:"varint,4,opt,name=slot_included,json=slotIncluded,proto3" json:"slot_included,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Data *AttestationData `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
|
||||
AggregationBitfield []byte `protobuf:"bytes,2,opt,name=aggregation_bitfield,json=aggregationBitfield,proto3" json:"aggregation_bitfield,omitempty"`
|
||||
CustodyBitfield []byte `protobuf:"bytes,3,opt,name=custody_bitfield,json=custodyBitfield,proto3" json:"custody_bitfield,omitempty"`
|
||||
SlotIncluded uint64 `protobuf:"varint,4,opt,name=slot_included,json=slotIncluded,proto3" json:"slot_included,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *PendingAttestationRecord) Reset() { *m = PendingAttestationRecord{} }
|
||||
func (m *PendingAttestationRecord) String() string { return proto.CompactTextString(m) }
|
||||
func (*PendingAttestationRecord) ProtoMessage() {}
|
||||
func (*PendingAttestationRecord) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{2}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{2}
|
||||
}
|
||||
func (m *PendingAttestationRecord) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -422,9 +422,9 @@ func (m *PendingAttestationRecord) GetData() *AttestationData {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PendingAttestationRecord) GetParticipationBitfield() []byte {
|
||||
func (m *PendingAttestationRecord) GetAggregationBitfield() []byte {
|
||||
if m != nil {
|
||||
return m.ParticipationBitfield
|
||||
return m.AggregationBitfield
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -444,20 +444,20 @@ func (m *PendingAttestationRecord) GetSlotIncluded() uint64 {
|
||||
}
|
||||
|
||||
type Attestation struct {
|
||||
Data *AttestationData `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
|
||||
ParticipationBitfield []byte `protobuf:"bytes,2,opt,name=participation_bitfield,json=participationBitfield,proto3" json:"participation_bitfield,omitempty"`
|
||||
CustodyBitfield []byte `protobuf:"bytes,3,opt,name=custody_bitfield,json=custodyBitfield,proto3" json:"custody_bitfield,omitempty"`
|
||||
AggregateSignature []byte `protobuf:"bytes,4,opt,name=aggregate_signature,json=aggregateSignature,proto3" json:"aggregate_signature,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Data *AttestationData `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
|
||||
AggregationBitfield []byte `protobuf:"bytes,2,opt,name=aggregation_bitfield,json=aggregationBitfield,proto3" json:"aggregation_bitfield,omitempty"`
|
||||
CustodyBitfield []byte `protobuf:"bytes,3,opt,name=custody_bitfield,json=custodyBitfield,proto3" json:"custody_bitfield,omitempty"`
|
||||
AggregateSignature []byte `protobuf:"bytes,4,opt,name=aggregate_signature,json=aggregateSignature,proto3" json:"aggregate_signature,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Attestation) Reset() { *m = Attestation{} }
|
||||
func (m *Attestation) String() string { return proto.CompactTextString(m) }
|
||||
func (*Attestation) ProtoMessage() {}
|
||||
func (*Attestation) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{3}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{3}
|
||||
}
|
||||
func (m *Attestation) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -493,9 +493,9 @@ func (m *Attestation) GetData() *AttestationData {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Attestation) GetParticipationBitfield() []byte {
|
||||
func (m *Attestation) GetAggregationBitfield() []byte {
|
||||
if m != nil {
|
||||
return m.ParticipationBitfield
|
||||
return m.AggregationBitfield
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -521,8 +521,9 @@ type AttestationData struct {
|
||||
EpochBoundaryRootHash32 []byte `protobuf:"bytes,4,opt,name=epoch_boundary_root_hash32,json=epochBoundaryRootHash32,proto3" json:"epoch_boundary_root_hash32,omitempty"`
|
||||
ShardBlockRootHash32 []byte `protobuf:"bytes,5,opt,name=shard_block_root_hash32,json=shardBlockRootHash32,proto3" json:"shard_block_root_hash32,omitempty"`
|
||||
LatestCrosslinkRootHash32 []byte `protobuf:"bytes,6,opt,name=latest_crosslink_root_hash32,json=latestCrosslinkRootHash32,proto3" json:"latest_crosslink_root_hash32,omitempty"`
|
||||
JustifiedSlot uint64 `protobuf:"varint,7,opt,name=justified_slot,json=justifiedSlot,proto3" json:"justified_slot,omitempty"`
|
||||
JustifiedEpoch uint64 `protobuf:"varint,7,opt,name=justified_epoch,json=justifiedEpoch,proto3" json:"justified_epoch,omitempty"`
|
||||
JustifiedBlockRootHash32 []byte `protobuf:"bytes,8,opt,name=justified_block_root_hash32,json=justifiedBlockRootHash32,proto3" json:"justified_block_root_hash32,omitempty"`
|
||||
JustifiedSlot uint64 `protobuf:"varint,1000,opt,name=justified_slot,json=justifiedSlot,proto3" json:"justified_slot,omitempty"` // Deprecated: Do not use.
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@@ -532,7 +533,7 @@ func (m *AttestationData) Reset() { *m = AttestationData{} }
|
||||
func (m *AttestationData) String() string { return proto.CompactTextString(m) }
|
||||
func (*AttestationData) ProtoMessage() {}
|
||||
func (*AttestationData) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{4}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{4}
|
||||
}
|
||||
func (m *AttestationData) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -603,9 +604,9 @@ func (m *AttestationData) GetLatestCrosslinkRootHash32() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AttestationData) GetJustifiedSlot() uint64 {
|
||||
func (m *AttestationData) GetJustifiedEpoch() uint64 {
|
||||
if m != nil {
|
||||
return m.JustifiedSlot
|
||||
return m.JustifiedEpoch
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -617,6 +618,14 @@ func (m *AttestationData) GetJustifiedBlockRootHash32() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deprecated: Do not use.
|
||||
func (m *AttestationData) GetJustifiedSlot() uint64 {
|
||||
if m != nil {
|
||||
return m.JustifiedSlot
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type AttestationDataAndCustodyBit struct {
|
||||
Data *AttestationData `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
|
||||
CustodyBit bool `protobuf:"varint,2,opt,name=custody_bit,json=custodyBit,proto3" json:"custody_bit,omitempty"`
|
||||
@@ -629,7 +638,7 @@ func (m *AttestationDataAndCustodyBit) Reset() { *m = AttestationDataAnd
|
||||
func (m *AttestationDataAndCustodyBit) String() string { return proto.CompactTextString(m) }
|
||||
func (*AttestationDataAndCustodyBit) ProtoMessage() {}
|
||||
func (*AttestationDataAndCustodyBit) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{5}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{5}
|
||||
}
|
||||
func (m *AttestationDataAndCustodyBit) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -691,7 +700,7 @@ func (m *ValidatorRecord) Reset() { *m = ValidatorRecord{} }
|
||||
func (m *ValidatorRecord) String() string { return proto.CompactTextString(m) }
|
||||
func (*ValidatorRecord) ProtoMessage() {}
|
||||
func (*ValidatorRecord) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{6}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{6}
|
||||
}
|
||||
func (m *ValidatorRecord) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -796,7 +805,7 @@ func (m *ShardReassignmentRecord) Reset() { *m = ShardReassignmentRecord
|
||||
func (m *ShardReassignmentRecord) String() string { return proto.CompactTextString(m) }
|
||||
func (*ShardReassignmentRecord) ProtoMessage() {}
|
||||
func (*ShardReassignmentRecord) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{7}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{7}
|
||||
}
|
||||
func (m *ShardReassignmentRecord) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -858,7 +867,7 @@ func (m *CrosslinkRecord) Reset() { *m = CrosslinkRecord{} }
|
||||
func (m *CrosslinkRecord) String() string { return proto.CompactTextString(m) }
|
||||
func (*CrosslinkRecord) ProtoMessage() {}
|
||||
func (*CrosslinkRecord) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{8}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{8}
|
||||
}
|
||||
func (m *CrosslinkRecord) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -918,7 +927,7 @@ func (m *BeaconBlock) Reset() { *m = BeaconBlock{} }
|
||||
func (m *BeaconBlock) String() string { return proto.CompactTextString(m) }
|
||||
func (*BeaconBlock) ProtoMessage() {}
|
||||
func (*BeaconBlock) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{9}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{9}
|
||||
}
|
||||
func (m *BeaconBlock) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1011,7 +1020,7 @@ func (m *BeaconBlockBody) Reset() { *m = BeaconBlockBody{} }
|
||||
func (m *BeaconBlockBody) String() string { return proto.CompactTextString(m) }
|
||||
func (*BeaconBlockBody) ProtoMessage() {}
|
||||
func (*BeaconBlockBody) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{10}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{10}
|
||||
}
|
||||
func (m *BeaconBlockBody) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1090,7 +1099,7 @@ func (m *DepositInput) Reset() { *m = DepositInput{} }
|
||||
func (m *DepositInput) String() string { return proto.CompactTextString(m) }
|
||||
func (*DepositInput) ProtoMessage() {}
|
||||
func (*DepositInput) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{11}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{11}
|
||||
}
|
||||
func (m *DepositInput) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1167,7 +1176,7 @@ func (m *ProposalSignedData) Reset() { *m = ProposalSignedData{} }
|
||||
func (m *ProposalSignedData) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProposalSignedData) ProtoMessage() {}
|
||||
func (*ProposalSignedData) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{12}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{12}
|
||||
}
|
||||
func (m *ProposalSignedData) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1231,7 +1240,7 @@ func (m *SlashableVote) Reset() { *m = SlashableVote{} }
|
||||
func (m *SlashableVote) String() string { return proto.CompactTextString(m) }
|
||||
func (*SlashableVote) ProtoMessage() {}
|
||||
func (*SlashableVote) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{13}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{13}
|
||||
}
|
||||
func (m *SlashableVote) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1301,7 +1310,7 @@ func (m *DepositData) Reset() { *m = DepositData{} }
|
||||
func (m *DepositData) String() string { return proto.CompactTextString(m) }
|
||||
func (*DepositData) ProtoMessage() {}
|
||||
func (*DepositData) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{14}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{14}
|
||||
}
|
||||
func (m *DepositData) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1366,7 +1375,7 @@ func (m *ProposerSlashing) Reset() { *m = ProposerSlashing{} }
|
||||
func (m *ProposerSlashing) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProposerSlashing) ProtoMessage() {}
|
||||
func (*ProposerSlashing) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{15}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{15}
|
||||
}
|
||||
func (m *ProposerSlashing) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1442,7 +1451,7 @@ func (m *AttesterSlashing) Reset() { *m = AttesterSlashing{} }
|
||||
func (m *AttesterSlashing) String() string { return proto.CompactTextString(m) }
|
||||
func (*AttesterSlashing) ProtoMessage() {}
|
||||
func (*AttesterSlashing) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{16}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{16}
|
||||
}
|
||||
func (m *AttesterSlashing) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1498,7 +1507,7 @@ func (m *Deposit) Reset() { *m = Deposit{} }
|
||||
func (m *Deposit) String() string { return proto.CompactTextString(m) }
|
||||
func (*Deposit) ProtoMessage() {}
|
||||
func (*Deposit) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{17}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{17}
|
||||
}
|
||||
func (m *Deposit) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1561,7 +1570,7 @@ func (m *Exit) Reset() { *m = Exit{} }
|
||||
func (m *Exit) String() string { return proto.CompactTextString(m) }
|
||||
func (*Exit) ProtoMessage() {}
|
||||
func (*Exit) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{18}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{18}
|
||||
}
|
||||
func (m *Exit) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1626,7 +1635,7 @@ func (m *ValidatorRegistryDeltaBlock) Reset() { *m = ValidatorRegistryDe
|
||||
func (m *ValidatorRegistryDeltaBlock) String() string { return proto.CompactTextString(m) }
|
||||
func (*ValidatorRegistryDeltaBlock) ProtoMessage() {}
|
||||
func (*ValidatorRegistryDeltaBlock) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{19}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{19}
|
||||
}
|
||||
func (m *ValidatorRegistryDeltaBlock) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1702,7 +1711,7 @@ func (m *Eth1Data) Reset() { *m = Eth1Data{} }
|
||||
func (m *Eth1Data) String() string { return proto.CompactTextString(m) }
|
||||
func (*Eth1Data) ProtoMessage() {}
|
||||
func (*Eth1Data) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{20}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{20}
|
||||
}
|
||||
func (m *Eth1Data) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1757,7 +1766,7 @@ func (m *Eth1DataVote) Reset() { *m = Eth1DataVote{} }
|
||||
func (m *Eth1DataVote) String() string { return proto.CompactTextString(m) }
|
||||
func (*Eth1DataVote) ProtoMessage() {}
|
||||
func (*Eth1DataVote) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_types_69a4d8ebf9326a13, []int{21}
|
||||
return fileDescriptor_types_bdf1eadd736c0167, []int{21}
|
||||
}
|
||||
func (m *Eth1DataVote) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -2175,11 +2184,11 @@ func (m *PendingAttestationRecord) MarshalTo(dAtA []byte) (int, error) {
|
||||
}
|
||||
i += n7
|
||||
}
|
||||
if len(m.ParticipationBitfield) > 0 {
|
||||
if len(m.AggregationBitfield) > 0 {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.ParticipationBitfield)))
|
||||
i += copy(dAtA[i:], m.ParticipationBitfield)
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.AggregationBitfield)))
|
||||
i += copy(dAtA[i:], m.AggregationBitfield)
|
||||
}
|
||||
if len(m.CustodyBitfield) > 0 {
|
||||
dAtA[i] = 0x1a
|
||||
@@ -2223,11 +2232,11 @@ func (m *Attestation) MarshalTo(dAtA []byte) (int, error) {
|
||||
}
|
||||
i += n8
|
||||
}
|
||||
if len(m.ParticipationBitfield) > 0 {
|
||||
if len(m.AggregationBitfield) > 0 {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.ParticipationBitfield)))
|
||||
i += copy(dAtA[i:], m.ParticipationBitfield)
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.AggregationBitfield)))
|
||||
i += copy(dAtA[i:], m.AggregationBitfield)
|
||||
}
|
||||
if len(m.CustodyBitfield) > 0 {
|
||||
dAtA[i] = 0x1a
|
||||
@@ -2296,10 +2305,10 @@ func (m *AttestationData) MarshalTo(dAtA []byte) (int, error) {
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.LatestCrosslinkRootHash32)))
|
||||
i += copy(dAtA[i:], m.LatestCrosslinkRootHash32)
|
||||
}
|
||||
if m.JustifiedSlot != 0 {
|
||||
if m.JustifiedEpoch != 0 {
|
||||
dAtA[i] = 0x38
|
||||
i++
|
||||
i = encodeVarintTypes(dAtA, i, uint64(m.JustifiedSlot))
|
||||
i = encodeVarintTypes(dAtA, i, uint64(m.JustifiedEpoch))
|
||||
}
|
||||
if len(m.JustifiedBlockRootHash32) > 0 {
|
||||
dAtA[i] = 0x42
|
||||
@@ -2307,6 +2316,13 @@ func (m *AttestationData) MarshalTo(dAtA []byte) (int, error) {
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.JustifiedBlockRootHash32)))
|
||||
i += copy(dAtA[i:], m.JustifiedBlockRootHash32)
|
||||
}
|
||||
if m.JustifiedSlot != 0 {
|
||||
dAtA[i] = 0xc0
|
||||
i++
|
||||
dAtA[i] = 0x3e
|
||||
i++
|
||||
i = encodeVarintTypes(dAtA, i, uint64(m.JustifiedSlot))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
@@ -3289,7 +3305,7 @@ func (m *PendingAttestationRecord) Size() (n int) {
|
||||
l = m.Data.Size()
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
l = len(m.ParticipationBitfield)
|
||||
l = len(m.AggregationBitfield)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
@@ -3316,7 +3332,7 @@ func (m *Attestation) Size() (n int) {
|
||||
l = m.Data.Size()
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
l = len(m.ParticipationBitfield)
|
||||
l = len(m.AggregationBitfield)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
@@ -3362,13 +3378,16 @@ func (m *AttestationData) Size() (n int) {
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
if m.JustifiedSlot != 0 {
|
||||
n += 1 + sovTypes(uint64(m.JustifiedSlot))
|
||||
if m.JustifiedEpoch != 0 {
|
||||
n += 1 + sovTypes(uint64(m.JustifiedEpoch))
|
||||
}
|
||||
l = len(m.JustifiedBlockRootHash32)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
if m.JustifiedSlot != 0 {
|
||||
n += 2 + sovTypes(uint64(m.JustifiedSlot))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
@@ -4791,7 +4810,7 @@ func (m *PendingAttestationRecord) Unmarshal(dAtA []byte) error {
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ParticipationBitfield", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AggregationBitfield", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
@@ -4815,9 +4834,9 @@ func (m *PendingAttestationRecord) Unmarshal(dAtA []byte) error {
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ParticipationBitfield = append(m.ParticipationBitfield[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.ParticipationBitfield == nil {
|
||||
m.ParticipationBitfield = []byte{}
|
||||
m.AggregationBitfield = append(m.AggregationBitfield[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.AggregationBitfield == nil {
|
||||
m.AggregationBitfield = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
@@ -4956,7 +4975,7 @@ func (m *Attestation) Unmarshal(dAtA []byte) error {
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ParticipationBitfield", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AggregationBitfield", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
@@ -4980,9 +4999,9 @@ func (m *Attestation) Unmarshal(dAtA []byte) error {
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ParticipationBitfield = append(m.ParticipationBitfield[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.ParticipationBitfield == nil {
|
||||
m.ParticipationBitfield = []byte{}
|
||||
m.AggregationBitfield = append(m.AggregationBitfield[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.AggregationBitfield == nil {
|
||||
m.AggregationBitfield = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
@@ -5262,9 +5281,9 @@ func (m *AttestationData) Unmarshal(dAtA []byte) error {
|
||||
iNdEx = postIndex
|
||||
case 7:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field JustifiedSlot", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field JustifiedEpoch", wireType)
|
||||
}
|
||||
m.JustifiedSlot = 0
|
||||
m.JustifiedEpoch = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
@@ -5274,7 +5293,7 @@ func (m *AttestationData) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.JustifiedSlot |= (uint64(b) & 0x7F) << shift
|
||||
m.JustifiedEpoch |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
@@ -5310,6 +5329,25 @@ func (m *AttestationData) Unmarshal(dAtA []byte) error {
|
||||
m.JustifiedBlockRootHash32 = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 1000:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field JustifiedSlot", wireType)
|
||||
}
|
||||
m.JustifiedSlot = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.JustifiedSlot |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipTypes(dAtA[iNdEx:])
|
||||
@@ -8091,140 +8129,141 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("proto/beacon/p2p/v1/types.proto", fileDescriptor_types_69a4d8ebf9326a13)
|
||||
proto.RegisterFile("proto/beacon/p2p/v1/types.proto", fileDescriptor_types_bdf1eadd736c0167)
|
||||
}
|
||||
|
||||
var fileDescriptor_types_69a4d8ebf9326a13 = []byte{
|
||||
// 2091 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcb, 0x73, 0x1b, 0x49,
|
||||
0x19, 0xdf, 0x91, 0xe4, 0xc4, 0xf9, 0x24, 0x5b, 0x72, 0x3b, 0xb1, 0x66, 0x63, 0x27, 0x76, 0x26,
|
||||
0xbb, 0xd8, 0x09, 0x60, 0xaf, 0x94, 0x5a, 0x42, 0x11, 0x02, 0x58, 0xb6, 0x97, 0x08, 0xb2, 0x9b,
|
||||
0xd4, 0xd8, 0xeb, 0x70, 0x81, 0xa9, 0xd6, 0x4c, 0x5b, 0x9a, 0x78, 0x34, 0x33, 0x35, 0xdd, 0xf2,
|
||||
0xc6, 0x14, 0x27, 0x8a, 0x0b, 0x8f, 0x02, 0xfe, 0x05, 0xf8, 0x1b, 0xb8, 0x50, 0xbc, 0x4e, 0x14,
|
||||
0x1c, 0x79, 0x5e, 0xa8, 0x82, 0xa2, 0x72, 0xe6, 0x7d, 0xa7, 0x8a, 0xea, 0xc7, 0x3c, 0x25, 0x39,
|
||||
0xce, 0xe6, 0xc2, 0x49, 0xd5, 0xdf, 0xf7, 0xfb, 0x7d, 0xdd, 0xfd, 0xf5, 0xf7, 0xd2, 0xc0, 0x6a,
|
||||
0x18, 0x05, 0x2c, 0xd8, 0xea, 0x11, 0x6c, 0x07, 0xfe, 0x56, 0xd8, 0x0e, 0xb7, 0x4e, 0x5a, 0x5b,
|
||||
0xec, 0x34, 0x24, 0x74, 0x53, 0x68, 0xd0, 0x12, 0x61, 0x03, 0x12, 0x91, 0xd1, 0x70, 0x53, 0x62,
|
||||
0x36, 0xc3, 0x76, 0xb8, 0x79, 0xd2, 0xba, 0xba, 0x2c, 0x89, 0x76, 0x30, 0x1c, 0x06, 0xfe, 0xd6,
|
||||
0x90, 0x50, 0x8a, 0xfb, 0x31, 0xc9, 0xf8, 0x7a, 0x0d, 0xaa, 0x1d, 0x01, 0xdf, 0x67, 0x98, 0x11,
|
||||
0x74, 0x08, 0xe8, 0x04, 0x7b, 0xae, 0x83, 0x59, 0x10, 0x59, 0x11, 0xe9, 0xbb, 0x94, 0x45, 0xa7,
|
||||
0xba, 0xb6, 0x56, 0xde, 0xa8, 0xb6, 0xd7, 0x37, 0x27, 0xef, 0xb0, 0x79, 0x18, 0x33, 0x4c, 0x62,
|
||||
0x07, 0x91, 0x63, 0x2e, 0x9c, 0xa4, 0x02, 0x69, 0x01, 0xed, 0xc1, 0xea, 0xb8, 0x5d, 0x6b, 0x14,
|
||||
0x3a, 0x98, 0x11, 0x8b, 0x84, 0x81, 0x3d, 0xd0, 0x4b, 0x6b, 0xda, 0x46, 0xc5, 0x5c, 0x19, 0xe3,
|
||||
0xbe, 0x2f, 0x40, 0x7b, 0x1c, 0x83, 0x3e, 0x9e, 0x3d, 0x5e, 0x0f, 0x7b, 0xd8, 0xb7, 0x09, 0xd5,
|
||||
0xcb, 0x6b, 0xe5, 0x8d, 0x4a, 0x66, 0xd7, 0x8e, 0x52, 0xa0, 0xcf, 0xc0, 0xb2, 0x87, 0x19, 0xa1,
|
||||
0xcc, 0x8a, 0xb0, 0xef, 0xe0, 0xc0, 0x1a, 0xba, 0xcf, 0x08, 0xb5, 0x06, 0x98, 0x0e, 0xee, 0xb4,
|
||||
0xa9, 0xfe, 0xb7, 0x8b, 0x6b, 0xe5, 0x8d, 0x9a, 0xa9, 0x4b, 0x8c, 0x29, 0x20, 0xef, 0x72, 0xc4,
|
||||
0x03, 0x09, 0x40, 0x9f, 0x86, 0xab, 0x61, 0x44, 0x4e, 0xdc, 0x60, 0x44, 0xe5, 0x21, 0x2d, 0xca,
|
||||
0x70, 0xc4, 0x2c, 0x3a, 0xc0, 0x91, 0xa3, 0xff, 0xfd, 0xa2, 0x38, 0x71, 0x33, 0x86, 0x88, 0x23,
|
||||
0xee, 0x73, 0xc0, 0x3e, 0xd7, 0xa3, 0x4f, 0xc1, 0xeb, 0xf6, 0x28, 0x8a, 0x88, 0xcf, 0x26, 0x90,
|
||||
0xff, 0x21, 0xc9, 0x4b, 0x0a, 0x51, 0xe4, 0xde, 0xcf, 0xec, 0x6c, 0x63, 0xcf, 0x1e, 0x79, 0x98,
|
||||
0xb9, 0x81, 0xaf, 0x5c, 0xf5, 0x4f, 0x49, 0xd6, 0x63, 0xc8, 0x4e, 0x8a, 0x90, 0x7e, 0xba, 0x97,
|
||||
0x6e, 0x3d, 0xce, 0xfe, 0x97, 0x3a, 0xb7, 0x42, 0x8c, 0x91, 0x27, 0xdc, 0x9a, 0x10, 0x47, 0x79,
|
||||
0x4d, 0xff, 0x37, 0x67, 0xd7, 0x8a, 0xb7, 0x26, 0xc4, 0x91, 0x4e, 0x9b, 0x70, 0xeb, 0x0c, 0xf9,
|
||||
0x3f, 0x92, 0x9c, 0xbf, 0x75, 0xca, 0xbd, 0x0b, 0x89, 0x59, 0xeb, 0xe9, 0x88, 0x32, 0xf7, 0xc8,
|
||||
0x25, 0x8e, 0x45, 0xbd, 0x80, 0xe9, 0xbf, 0xad, 0x8b, 0x43, 0x5f, 0x89, 0xf5, 0x5f, 0x88, 0xd5,
|
||||
0xfb, 0x5e, 0xc0, 0xd0, 0x47, 0x60, 0xbe, 0x80, 0xff, 0x9d, 0xc4, 0xcf, 0x3d, 0xcd, 0xe1, 0x3e,
|
||||
0x01, 0x4b, 0x4a, 0x60, 0x4b, 0x8f, 0xf4, 0x5c, 0x76, 0xe4, 0x12, 0xcf, 0xd1, 0x7f, 0xaf, 0xec,
|
||||
0xe7, 0xd4, 0x1d, 0xa5, 0xe5, 0xf6, 0x8f, 0x5c, 0x1f, 0x7b, 0xee, 0x57, 0x63, 0xfb, 0x7f, 0x50,
|
||||
0xf6, 0x13, 0xb1, 0xb0, 0xff, 0x3e, 0x2c, 0xa8, 0x80, 0xb3, 0xa3, 0x80, 0x52, 0xcf, 0xf5, 0x8f,
|
||||
0xa9, 0xfe, 0xe3, 0xe6, 0xd9, 0xe9, 0xb3, 0x13, 0x43, 0x55, 0xfa, 0x34, 0xa4, 0x89, 0x44, 0x4c,
|
||||
0xb9, 0x4f, 0x95, 0xd9, 0x9e, 0x17, 0xd8, 0xc7, 0x56, 0x14, 0x04, 0x2c, 0x89, 0xe2, 0x9f, 0x34,
|
||||
0x45, 0x14, 0x2f, 0x49, 0x44, 0x87, 0x03, 0xcc, 0x20, 0x60, 0x99, 0x18, 0xee, 0x61, 0x66, 0x0f,
|
||||
0x88, 0x33, 0x89, 0xfc, 0x53, 0x49, 0x6e, 0x2a, 0xc8, 0x18, 0xfb, 0x5e, 0xb2, 0x73, 0x48, 0xe2,
|
||||
0xfb, 0x27, 0x79, 0xf7, 0xb3, 0xa6, 0x48, 0xbc, 0xa6, 0x44, 0x3c, 0x8e, 0x01, 0x49, 0xfa, 0xf5,
|
||||
0x60, 0x51, 0x91, 0x31, 0xe3, 0x3f, 0xc2, 0xa7, 0x54, 0xff, 0xb9, 0xf4, 0xc7, 0x5b, 0xd3, 0xfc,
|
||||
0xf1, 0x98, 0xf8, 0x8e, 0xeb, 0xf7, 0xb7, 0x53, 0x8e, 0x72, 0x0c, 0x92, 0xd6, 0x32, 0x8a, 0xac,
|
||||
0x6b, 0x5c, 0xdf, 0x21, 0xcf, 0xf2, 0xb7, 0xfb, 0x45, 0xce, 0x35, 0x5d, 0x0e, 0xc8, 0x5e, 0xee,
|
||||
0x8b, 0xa0, 0x5c, 0x6d, 0x11, 0x36, 0x68, 0x59, 0x0e, 0x66, 0x58, 0xff, 0xc1, 0xea, 0x9a, 0xb6,
|
||||
0x51, 0x6d, 0xaf, 0x4d, 0x3b, 0xdc, 0x1e, 0x1b, 0xb4, 0x76, 0x31, 0xc3, 0xe6, 0xbc, 0xa4, 0xc6,
|
||||
0x6b, 0xf4, 0x2e, 0xd4, 0x13, 0x2b, 0xd6, 0x49, 0xc0, 0x08, 0xd5, 0x7f, 0xb8, 0x2a, 0x2e, 0xfa,
|
||||
0xc6, 0x8b, 0x6c, 0x1d, 0x06, 0x8c, 0x98, 0x73, 0x24, 0xb3, 0xa2, 0xc8, 0x80, 0x5a, 0x9f, 0xf8,
|
||||
0x84, 0xba, 0xd4, 0x62, 0xee, 0x90, 0xe8, 0xdf, 0x5c, 0x17, 0xf1, 0x56, 0x55, 0xc2, 0x03, 0x77,
|
||||
0x48, 0x50, 0x0b, 0x2a, 0x47, 0x41, 0x74, 0xac, 0x7f, 0x6b, 0x5d, 0x9c, 0x79, 0x65, 0xda, 0x3e,
|
||||
0xef, 0x04, 0xd1, 0xb1, 0x29, 0xa0, 0x68, 0x11, 0x2a, 0x22, 0x7c, 0xbf, 0x2d, 0xcd, 0x89, 0x85,
|
||||
0x11, 0x42, 0x85, 0x43, 0xd0, 0x2d, 0x68, 0x24, 0xe9, 0x77, 0x42, 0x22, 0xea, 0x06, 0xbe, 0xae,
|
||||
0x09, 0x5c, 0x3d, 0x96, 0x1f, 0x4a, 0x31, 0x5a, 0x87, 0x7a, 0x9c, 0xe5, 0x31, 0x52, 0xd6, 0xef,
|
||||
0x79, 0x25, 0x8e, 0x81, 0x97, 0x61, 0x46, 0x56, 0x9d, 0xb2, 0x50, 0xcb, 0x85, 0xf1, 0x17, 0x0d,
|
||||
0xf4, 0x69, 0xcf, 0x8c, 0xee, 0x41, 0x45, 0x3c, 0x85, 0x26, 0x6e, 0x35, 0x35, 0x6d, 0x32, 0x44,
|
||||
0xf1, 0x20, 0x82, 0x84, 0xde, 0x86, 0xa5, 0x10, 0x47, 0xcc, 0xb5, 0xdd, 0xb0, 0x90, 0xe1, 0x25,
|
||||
0x51, 0x7a, 0xae, 0xe4, 0xb4, 0x49, 0x82, 0xdf, 0x82, 0x86, 0x3d, 0xa2, 0x2c, 0x70, 0x4e, 0x53,
|
||||
0x42, 0x59, 0x10, 0xea, 0x4a, 0x9e, 0x40, 0x6f, 0xc2, 0x1c, 0xf7, 0x9a, 0xe5, 0xfa, 0xb6, 0x37,
|
||||
0x72, 0x88, 0xa3, 0x57, 0xc4, 0xcd, 0x6a, 0x5c, 0xd8, 0x55, 0x32, 0xe3, 0xcf, 0x1a, 0x54, 0x33,
|
||||
0x07, 0xfc, 0x7f, 0xbf, 0xd3, 0x16, 0x2c, 0xe2, 0x7e, 0x3f, 0x22, 0x7d, 0xde, 0x8e, 0xa9, 0xdb,
|
||||
0xf7, 0x31, 0x1b, 0x45, 0x44, 0xdc, 0xac, 0x66, 0xa2, 0x44, 0xb5, 0x1f, 0x6b, 0x8c, 0xef, 0x95,
|
||||
0xa1, 0x5e, 0x38, 0x2c, 0x42, 0x2a, 0xb6, 0xb4, 0x34, 0xb4, 0xf8, 0xf3, 0xcb, 0x7e, 0x27, 0xa3,
|
||||
0x43, 0x2e, 0xd0, 0x5d, 0xd0, 0xe5, 0xbd, 0xc7, 0x4b, 0x92, 0x3a, 0xe1, 0x15, 0xa9, 0x2f, 0xd4,
|
||||
0x23, 0x74, 0x0f, 0xae, 0xca, 0xa6, 0xd2, 0x0b, 0x46, 0xbe, 0x83, 0xa3, 0xd3, 0x1c, 0x55, 0x1e,
|
||||
0xb7, 0x29, 0x10, 0x1d, 0x05, 0xc8, 0x90, 0xdf, 0x86, 0xa6, 0xd8, 0x7e, 0xc2, 0xa6, 0x33, 0x82,
|
||||
0x79, 0x59, 0xa8, 0x8b, 0x7b, 0x7e, 0x16, 0x56, 0x8a, 0x35, 0x3d, 0xc7, 0xbd, 0x20, 0xb8, 0xaf,
|
||||
0x17, 0x8a, 0x76, 0xc6, 0xc0, 0x9b, 0x63, 0xcd, 0xe9, 0xe2, 0xa4, 0xde, 0x74, 0x1f, 0x96, 0x53,
|
||||
0xd8, 0xf8, 0x11, 0x67, 0xc5, 0x36, 0x7a, 0x02, 0x29, 0x1c, 0xd3, 0xf8, 0x1a, 0xac, 0x14, 0x1e,
|
||||
0x64, 0xdb, 0x77, 0x76, 0x92, 0x77, 0x7e, 0xb5, 0x08, 0x5c, 0x85, 0x6a, 0x26, 0x94, 0xc4, 0x63,
|
||||
0xce, 0x9a, 0x90, 0x46, 0x91, 0xf1, 0x8d, 0x0a, 0xd4, 0x0b, 0x63, 0x20, 0x5a, 0x82, 0x0b, 0xe1,
|
||||
0xa8, 0x77, 0x4c, 0x4e, 0xc5, 0x9e, 0x35, 0x53, 0xad, 0x50, 0x07, 0xae, 0x7d, 0xe0, 0xb2, 0x81,
|
||||
0x13, 0xe1, 0x0f, 0xb0, 0x67, 0xd9, 0x11, 0x71, 0x88, 0xcf, 0x5c, 0xec, 0xc5, 0x83, 0x99, 0x8a,
|
||||
0xea, 0xe5, 0x14, 0xb4, 0x93, 0x62, 0x94, 0x4f, 0x3f, 0x09, 0xba, 0x1a, 0xe9, 0xf8, 0x5c, 0xeb,
|
||||
0xb2, 0x21, 0xaf, 0x44, 0xb9, 0x08, 0x5a, 0x92, 0xfa, 0x9d, 0x44, 0xad, 0x98, 0x37, 0x61, 0x4e,
|
||||
0x31, 0x3d, 0x7c, 0x4a, 0x22, 0x1a, 0xa7, 0xaf, 0x14, 0x3e, 0x14, 0x32, 0x9e, 0x3a, 0xd8, 0x66,
|
||||
0xee, 0x49, 0x76, 0x6c, 0x9a, 0x91, 0x95, 0x30, 0x95, 0xcb, 0x69, 0xe9, 0x1a, 0x00, 0x79, 0xe6,
|
||||
0xaa, 0x61, 0x47, 0x04, 0x43, 0xc5, 0xbc, 0xc4, 0x25, 0x52, 0x7d, 0x0b, 0x1a, 0x99, 0xcb, 0x4a,
|
||||
0x90, 0x7c, 0xfe, 0x7a, 0x2a, 0x97, 0xd0, 0x75, 0xa8, 0xa7, 0x4d, 0x56, 0x22, 0x67, 0x65, 0x4d,
|
||||
0x4d, 0xc4, 0x12, 0x78, 0x08, 0x35, 0xfe, 0x44, 0x23, 0x6a, 0x1d, 0x79, 0xb8, 0x4f, 0x75, 0x58,
|
||||
0xd3, 0x36, 0xe6, 0xdb, 0x77, 0xce, 0x39, 0x9e, 0x6f, 0xee, 0x0b, 0xee, 0x3b, 0x9c, 0x6a, 0x56,
|
||||
0x69, 0xba, 0x30, 0x3e, 0x07, 0xd5, 0x8c, 0x0e, 0x55, 0xe1, 0x62, 0xf7, 0xbd, 0xee, 0x41, 0x77,
|
||||
0xfb, 0x61, 0xe3, 0x35, 0x84, 0x60, 0x5e, 0x2e, 0x0e, 0xf6, 0x76, 0xad, 0xbd, 0x2f, 0x75, 0x0f,
|
||||
0x1a, 0x1a, 0x6a, 0x40, 0xed, 0x49, 0xf7, 0xe0, 0xc1, 0xae, 0xb9, 0xfd, 0x64, 0xbb, 0xf3, 0x70,
|
||||
0xaf, 0x51, 0x32, 0x3c, 0x68, 0x8a, 0xf9, 0xd5, 0x24, 0x98, 0xf2, 0x32, 0xc2, 0xfd, 0xae, 0xa2,
|
||||
0x61, 0x1d, 0xea, 0xe9, 0xe8, 0x2e, 0x7a, 0xb5, 0x2a, 0x14, 0xf3, 0x89, 0x58, 0x34, 0xe8, 0x29,
|
||||
0x25, 0x23, 0x2e, 0x2e, 0xe5, 0x4c, 0xdf, 0xfa, 0x0a, 0xd4, 0x0b, 0xb3, 0x53, 0xda, 0x6e, 0xb4,
|
||||
0x4c, 0xbb, 0x39, 0x2b, 0xf3, 0x4b, 0xd3, 0x33, 0xdf, 0xf8, 0x55, 0x29, 0xfe, 0x73, 0x24, 0x34,
|
||||
0x13, 0x0b, 0xdc, 0xc7, 0x00, 0x85, 0x58, 0xf4, 0xc1, 0x71, 0xab, 0x0d, 0xa9, 0xc9, 0x94, 0x82,
|
||||
0xdb, 0xb0, 0xc0, 0x1d, 0x4e, 0x26, 0x54, 0xbc, 0xba, 0x50, 0x64, 0xb0, 0x6f, 0xc1, 0x65, 0x15,
|
||||
0xa8, 0x11, 0x39, 0x21, 0xd8, 0xcb, 0x57, 0x39, 0x24, 0x75, 0xa6, 0x50, 0x29, 0xc6, 0x7d, 0xb8,
|
||||
0x94, 0x0e, 0x32, 0x33, 0xe7, 0x9c, 0x63, 0x66, 0xe3, 0xb9, 0x03, 0xad, 0xc0, 0xa5, 0xb4, 0xf4,
|
||||
0x5f, 0x10, 0x93, 0x53, 0x2a, 0xe0, 0xf5, 0xa3, 0x17, 0x38, 0xa7, 0x22, 0x78, 0xcf, 0xa8, 0x1f,
|
||||
0x19, 0x7f, 0x75, 0x02, 0xe7, 0xd4, 0x14, 0x24, 0xe3, 0xbf, 0x25, 0xa8, 0x17, 0x34, 0xe8, 0xf3,
|
||||
0x50, 0xcb, 0x8d, 0x85, 0xf2, 0x4f, 0xe6, 0xcd, 0x73, 0x14, 0x26, 0x33, 0x47, 0x44, 0x4f, 0x00,
|
||||
0x85, 0x51, 0x10, 0x06, 0x94, 0x44, 0x16, 0xf5, 0x30, 0x1d, 0xb8, 0x7e, 0x9f, 0xea, 0x25, 0x61,
|
||||
0x6e, 0x63, 0xea, 0x90, 0xa9, 0x18, 0xfb, 0x8a, 0x60, 0x2e, 0x84, 0x05, 0x89, 0x30, 0x2c, 0x37,
|
||||
0xca, 0x19, 0x2e, 0x9f, 0x6d, 0x78, 0x5b, 0x31, 0x52, 0xc3, 0xb8, 0x20, 0xe1, 0x53, 0xf5, 0xac,
|
||||
0x43, 0xc2, 0x80, 0xba, 0x8c, 0x97, 0x1f, 0x6e, 0x6e, 0x75, 0x9a, 0xb9, 0x5d, 0x89, 0x33, 0x13,
|
||||
0x02, 0x6a, 0xc3, 0x0c, 0x2f, 0x2f, 0x54, 0x9f, 0x11, 0xcc, 0xa9, 0x53, 0xdf, 0xde, 0x33, 0x97,
|
||||
0x99, 0x12, 0x6a, 0x7c, 0xbf, 0x04, 0x35, 0x65, 0xa9, 0xeb, 0x87, 0x23, 0x36, 0xb5, 0x36, 0x6f,
|
||||
0xc2, 0x62, 0x18, 0x05, 0xc1, 0x91, 0x15, 0x1c, 0x59, 0x61, 0x40, 0x29, 0xa1, 0xc9, 0x6c, 0x57,
|
||||
0x13, 0x2e, 0x0a, 0x8e, 0x1e, 0x1d, 0x3d, 0x4e, 0x14, 0x2f, 0xae, 0xe5, 0xe5, 0x57, 0xab, 0xe5,
|
||||
0x95, 0x33, 0x6b, 0xb9, 0xf8, 0xaf, 0x29, 0xdb, 0xd2, 0x38, 0x55, 0xf6, 0xf4, 0xa6, 0x02, 0x14,
|
||||
0xb9, 0xc6, 0x53, 0x40, 0x32, 0x06, 0xb0, 0xc7, 0xc7, 0x1a, 0xe2, 0xbc, 0xe4, 0x0c, 0x73, 0x1b,
|
||||
0x16, 0xa6, 0x0d, 0x2f, 0xf5, 0x5e, 0xa1, 0x90, 0xfc, 0x51, 0x83, 0x39, 0xf1, 0xfa, 0xb8, 0xe7,
|
||||
0x11, 0x3e, 0xdf, 0xa3, 0x8f, 0xc2, 0x42, 0xae, 0x1a, 0xba, 0xfc, 0xff, 0x94, 0x26, 0xfe, 0x4e,
|
||||
0x35, 0xb2, 0xf5, 0x90, 0xcb, 0x27, 0x0e, 0x72, 0xa5, 0xc9, 0x83, 0x5c, 0xdc, 0xe5, 0xcb, 0x1f,
|
||||
0xa6, 0xcb, 0xbf, 0xf4, 0x14, 0xf8, 0x5d, 0x0d, 0xaa, 0x2a, 0xac, 0x84, 0xf7, 0xba, 0x30, 0xa7,
|
||||
0xc2, 0xd4, 0x72, 0x79, 0x98, 0xa9, 0x61, 0xe3, 0x8d, 0x17, 0x04, 0xb7, 0x08, 0x49, 0xb3, 0xe6,
|
||||
0x14, 0x02, 0x14, 0x0f, 0x83, 0x91, 0xcf, 0x94, 0xd7, 0xd5, 0x8a, 0x17, 0x29, 0xfe, 0x7f, 0x88,
|
||||
0x32, 0x3c, 0x0c, 0x55, 0x33, 0x48, 0x05, 0xc6, 0x2f, 0x4b, 0xd0, 0x28, 0x66, 0x36, 0x9f, 0xbf,
|
||||
0x92, 0xfa, 0x90, 0x6d, 0x3c, 0x73, 0xb1, 0x54, 0xf6, 0x1d, 0x13, 0xea, 0xa1, 0x0a, 0x08, 0xf9,
|
||||
0x27, 0xae, 0x25, 0xb6, 0xae, 0xb6, 0x6f, 0x9f, 0x5d, 0x43, 0xb2, 0xf1, 0x13, 0xdb, 0xc4, 0x1e,
|
||||
0x5f, 0xb5, 0x78, 0x0d, 0x4f, 0x6c, 0x26, 0x0e, 0xb5, 0x5a, 0x2a, 0x4e, 0x50, 0x98, 0x31, 0x20,
|
||||
0x54, 0xad, 0xf1, 0x53, 0xc8, 0x1c, 0x78, 0x85, 0x53, 0xb4, 0xa7, 0x9c, 0x22, 0xce, 0x90, 0xf1,
|
||||
0x53, 0xb4, 0x8d, 0x1f, 0x69, 0xd0, 0x28, 0x16, 0x32, 0xf4, 0x08, 0x1a, 0x34, 0x0e, 0x62, 0xf1,
|
||||
0x0f, 0xd7, 0x6a, 0xa9, 0x07, 0x7e, 0x73, 0xda, 0xd9, 0x72, 0x41, 0x6f, 0xce, 0xd3, 0xec, 0xb2,
|
||||
0x35, 0xc1, 0x60, 0x5b, 0xb9, 0xfc, 0x43, 0x19, 0x6c, 0x1b, 0xdf, 0xd1, 0xe0, 0xa2, 0x8a, 0x29,
|
||||
0xd4, 0x86, 0x2b, 0x43, 0x12, 0x1d, 0x7b, 0xc4, 0xea, 0x45, 0xd8, 0xb7, 0x07, 0xc9, 0x47, 0x01,
|
||||
0x4d, 0x74, 0xb6, 0x45, 0xa9, 0xec, 0x08, 0x5d, 0xfc, 0x41, 0xe0, 0x36, 0x2c, 0x28, 0x0e, 0x8b,
|
||||
0x08, 0x51, 0xc1, 0x22, 0xe3, 0xaf, 0x2e, 0x15, 0x07, 0x11, 0x21, 0x32, 0x5c, 0x6e, 0x40, 0x1c,
|
||||
0xb0, 0x56, 0x92, 0x71, 0x35, 0xb3, 0xea, 0xa4, 0xe9, 0x60, 0x60, 0xa8, 0xf0, 0x22, 0x3c, 0xb1,
|
||||
0xa8, 0x4c, 0x18, 0x87, 0x4a, 0x13, 0xc7, 0xa1, 0x5c, 0x57, 0x96, 0x9b, 0xa4, 0x02, 0xe3, 0x4f,
|
||||
0x25, 0x58, 0x3e, 0x2c, 0x7e, 0x31, 0xdd, 0x25, 0x1e, 0xc3, 0x72, 0x64, 0x79, 0x00, 0x37, 0xe2,
|
||||
0x2f, 0xa0, 0xf1, 0x47, 0x57, 0x87, 0x6b, 0x73, 0x55, 0x4b, 0xb6, 0x80, 0x6b, 0xea, 0x33, 0x68,
|
||||
0xd6, 0x48, 0x66, 0x1c, 0x39, 0xf7, 0x81, 0xd3, 0xd6, 0x52, 0xce, 0xb5, 0x96, 0xd8, 0x0b, 0x95,
|
||||
0x8c, 0x17, 0x6c, 0xa8, 0xf0, 0x11, 0x56, 0x44, 0xe2, 0x7c, 0xfb, 0xd1, 0x39, 0x26, 0xd8, 0xe2,
|
||||
0x0d, 0xa7, 0xe8, 0xe4, 0x74, 0x2b, 0x8c, 0x1b, 0x77, 0xa7, 0xb9, 0x48, 0x8e, 0xb9, 0xf3, 0x00,
|
||||
0xdb, 0x3b, 0x07, 0xdd, 0xc3, 0xed, 0x83, 0xee, 0xa3, 0xf7, 0x1a, 0xaf, 0xa1, 0x59, 0xa8, 0xc8,
|
||||
0xf9, 0xd6, 0xf8, 0x32, 0xcc, 0x26, 0x9f, 0x77, 0x36, 0x61, 0x31, 0x7e, 0xee, 0x71, 0xd7, 0x2d,
|
||||
0x28, 0x55, 0xc6, 0x5d, 0x37, 0xa0, 0x26, 0xdb, 0x43, 0x6e, 0x22, 0xac, 0x0a, 0x99, 0xea, 0x0a,
|
||||
0x1e, 0xd4, 0xb2, 0x5f, 0x80, 0xf2, 0xe3, 0x9b, 0xf6, 0xd2, 0xe3, 0xdb, 0x35, 0x00, 0x91, 0x43,
|
||||
0x76, 0xa6, 0x6a, 0x5e, 0xe2, 0x92, 0x1d, 0x2e, 0xe8, 0xd4, 0x7e, 0xfd, 0xfc, 0xba, 0xf6, 0x9b,
|
||||
0xe7, 0xd7, 0xb5, 0xbf, 0x3e, 0xbf, 0xae, 0xf5, 0x2e, 0x88, 0xcf, 0xff, 0x77, 0xfe, 0x17, 0x00,
|
||||
0x00, 0xff, 0xff, 0x56, 0x79, 0x39, 0x1f, 0x56, 0x18, 0x00, 0x00,
|
||||
var fileDescriptor_types_bdf1eadd736c0167 = []byte{
|
||||
// 2103 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0xcb, 0x73, 0x1b, 0x49,
|
||||
0x19, 0xdf, 0x91, 0xe4, 0xc4, 0xf9, 0x24, 0x4b, 0x72, 0x3b, 0xb1, 0x66, 0xf3, 0xb2, 0x33, 0xd9,
|
||||
0xc5, 0x4e, 0x00, 0x7b, 0xa5, 0x14, 0x84, 0x22, 0x04, 0xb0, 0x6c, 0x2f, 0x11, 0x64, 0x37, 0xa9,
|
||||
0xb1, 0xd7, 0xe1, 0x02, 0x53, 0xad, 0x99, 0xb6, 0x34, 0xf1, 0x68, 0x66, 0x6a, 0xba, 0xe5, 0x8d,
|
||||
0x29, 0x4e, 0x14, 0x17, 0x1e, 0x45, 0xf1, 0x2f, 0xc0, 0xdf, 0xc0, 0x85, 0x82, 0x85, 0x13, 0x05,
|
||||
0x47, 0x9e, 0x07, 0xf6, 0x44, 0xe5, 0xc4, 0x81, 0xf7, 0x9d, 0x2a, 0xaa, 0x1f, 0xf3, 0x94, 0xe4,
|
||||
0x38, 0x9b, 0x0b, 0x27, 0x57, 0x7f, 0xdf, 0xef, 0xf7, 0x75, 0xf7, 0xd7, 0xdf, 0x6b, 0x64, 0x58,
|
||||
0x09, 0xa3, 0x80, 0x05, 0x9b, 0x7d, 0x82, 0xed, 0xc0, 0xdf, 0x0c, 0x3b, 0xe1, 0xe6, 0x71, 0x7b,
|
||||
0x93, 0x9d, 0x84, 0x84, 0x6e, 0x08, 0x0d, 0x5a, 0x26, 0x6c, 0x48, 0x22, 0x32, 0x1e, 0x6d, 0x48,
|
||||
0xcc, 0x46, 0xd8, 0x09, 0x37, 0x8e, 0xdb, 0x97, 0xaf, 0x48, 0xa2, 0x1d, 0x8c, 0x46, 0x81, 0xbf,
|
||||
0x39, 0x22, 0x94, 0xe2, 0x41, 0x4c, 0x32, 0xbe, 0x55, 0x83, 0x6a, 0x57, 0xc0, 0xf7, 0x18, 0x66,
|
||||
0x04, 0x1d, 0x00, 0x3a, 0xc6, 0x9e, 0xeb, 0x60, 0x16, 0x44, 0x56, 0x44, 0x06, 0x2e, 0x65, 0xd1,
|
||||
0x89, 0xae, 0xad, 0x96, 0xd7, 0xab, 0x9d, 0xb5, 0x8d, 0xe9, 0x3b, 0x6c, 0x1c, 0xc4, 0x0c, 0x93,
|
||||
0xd8, 0x41, 0xe4, 0x98, 0x8b, 0xc7, 0xa9, 0x40, 0x5a, 0x40, 0xbb, 0xb0, 0x32, 0x69, 0xd7, 0x1a,
|
||||
0x87, 0x0e, 0x66, 0xc4, 0x22, 0x61, 0x60, 0x0f, 0xf5, 0xd2, 0xaa, 0xb6, 0x5e, 0x31, 0xaf, 0x4e,
|
||||
0x70, 0xdf, 0x13, 0xa0, 0x5d, 0x8e, 0x41, 0x9f, 0xcc, 0x1e, 0xaf, 0x8f, 0x3d, 0xec, 0xdb, 0x84,
|
||||
0xea, 0xe5, 0xd5, 0xf2, 0x7a, 0x25, 0xb3, 0x6b, 0x57, 0x29, 0xd0, 0xe7, 0xe1, 0x8a, 0x87, 0x19,
|
||||
0xa1, 0xcc, 0x8a, 0xb0, 0xef, 0xe0, 0xc0, 0x1a, 0xb9, 0xcf, 0x08, 0xb5, 0x86, 0x98, 0x0e, 0xef,
|
||||
0x74, 0xa8, 0xfe, 0xb7, 0xf3, 0xab, 0xe5, 0xf5, 0x9a, 0xa9, 0x4b, 0x8c, 0x29, 0x20, 0xef, 0x70,
|
||||
0xc4, 0x03, 0x09, 0x40, 0x9f, 0x83, 0xcb, 0x61, 0x44, 0x8e, 0xdd, 0x60, 0x4c, 0xe5, 0x21, 0x2d,
|
||||
0xca, 0x70, 0xc4, 0x2c, 0x3a, 0xc4, 0x91, 0xa3, 0xff, 0xfd, 0xbc, 0x38, 0x71, 0x2b, 0x86, 0x88,
|
||||
0x23, 0xee, 0x71, 0xc0, 0x1e, 0xd7, 0xa3, 0xcf, 0xc2, 0xeb, 0xf6, 0x38, 0x8a, 0x88, 0xcf, 0xa6,
|
||||
0x90, 0xff, 0x21, 0xc9, 0xcb, 0x0a, 0x51, 0xe4, 0xde, 0xcf, 0xec, 0x6c, 0x63, 0xcf, 0x1e, 0x7b,
|
||||
0x98, 0xb9, 0x81, 0xaf, 0x5c, 0xf5, 0x4f, 0x49, 0xd6, 0x63, 0xc8, 0x76, 0x8a, 0x90, 0x7e, 0xba,
|
||||
0x97, 0x6e, 0x3d, 0xc9, 0xfe, 0x97, 0x3a, 0xb7, 0x42, 0x4c, 0x90, 0xa7, 0xdc, 0x9a, 0x10, 0x47,
|
||||
0x79, 0x4d, 0xff, 0x37, 0x67, 0xd7, 0x8a, 0xb7, 0x26, 0xc4, 0x91, 0x4e, 0x9b, 0x72, 0xeb, 0x0c,
|
||||
0xf9, 0x3f, 0x92, 0x9c, 0xbf, 0x75, 0xca, 0xbd, 0x0b, 0x89, 0x59, 0xeb, 0xe9, 0x98, 0x32, 0xf7,
|
||||
0xd0, 0x25, 0x8e, 0x45, 0xbd, 0x80, 0xe9, 0xbf, 0x6b, 0x88, 0x43, 0x5f, 0x8a, 0xf5, 0x5f, 0x8e,
|
||||
0xd5, 0x7b, 0x5e, 0xc0, 0xd0, 0xc7, 0xa0, 0x5e, 0xc0, 0xff, 0x5e, 0xe2, 0x17, 0x9e, 0xe6, 0x70,
|
||||
0x9f, 0x86, 0x65, 0x25, 0xb0, 0xa5, 0x47, 0xfa, 0x2e, 0x3b, 0x74, 0x89, 0xe7, 0xe8, 0x7f, 0x50,
|
||||
0xf6, 0x73, 0xea, 0xae, 0xd2, 0x72, 0xfb, 0x87, 0xae, 0x8f, 0x3d, 0xf7, 0x1b, 0xb1, 0xfd, 0x3f,
|
||||
0x2a, 0xfb, 0x89, 0x58, 0xd8, 0x7f, 0x0f, 0x16, 0x55, 0xc0, 0xd9, 0x51, 0x40, 0xa9, 0xe7, 0xfa,
|
||||
0x47, 0x54, 0xff, 0x69, 0xeb, 0xf4, 0xf4, 0xd9, 0x8e, 0xa1, 0x2a, 0x7d, 0x9a, 0xd2, 0x44, 0x22,
|
||||
0xa6, 0xdc, 0xa7, 0xca, 0x6c, 0xdf, 0x0b, 0xec, 0x23, 0x2b, 0x0a, 0x02, 0x96, 0x44, 0xf1, 0xcf,
|
||||
0x5a, 0x22, 0x8a, 0x97, 0x25, 0xa2, 0xcb, 0x01, 0x66, 0x10, 0xb0, 0x4c, 0x0c, 0xf7, 0x31, 0xb3,
|
||||
0x87, 0xc4, 0x99, 0x46, 0xfe, 0xb9, 0x24, 0xb7, 0x14, 0x64, 0x82, 0x7d, 0x2f, 0xd9, 0x39, 0x24,
|
||||
0xf1, 0xfd, 0x93, 0xbc, 0xfb, 0xa0, 0x25, 0x12, 0xaf, 0x25, 0x11, 0x8f, 0x63, 0x40, 0x92, 0x7e,
|
||||
0x7d, 0x58, 0x52, 0x64, 0xcc, 0xf8, 0x1f, 0xe1, 0x53, 0xaa, 0xff, 0x42, 0xfa, 0xe3, 0xad, 0x59,
|
||||
0xfe, 0x78, 0x4c, 0x7c, 0xc7, 0xf5, 0x07, 0x5b, 0x29, 0x47, 0x39, 0x06, 0x49, 0x6b, 0x19, 0x45,
|
||||
0xd6, 0x35, 0xae, 0xef, 0x90, 0x67, 0xf9, 0xdb, 0xfd, 0x32, 0xe7, 0x9a, 0x1e, 0x07, 0x64, 0x2f,
|
||||
0xf7, 0x15, 0x50, 0xae, 0xb6, 0x08, 0x1b, 0xb6, 0x2d, 0x07, 0x33, 0xac, 0xff, 0x68, 0x65, 0x55,
|
||||
0x5b, 0xaf, 0x76, 0x56, 0x67, 0x1d, 0x6e, 0x97, 0x0d, 0xdb, 0x3b, 0x98, 0x61, 0xb3, 0x2e, 0xa9,
|
||||
0xf1, 0x1a, 0xbd, 0x03, 0x8d, 0xc4, 0x8a, 0x75, 0x1c, 0x30, 0x42, 0xf5, 0x1f, 0xaf, 0x88, 0x8b,
|
||||
0xbe, 0xf1, 0x22, 0x5b, 0x07, 0x01, 0x23, 0xe6, 0x02, 0xc9, 0xac, 0x28, 0x32, 0xa0, 0x36, 0x20,
|
||||
0x3e, 0xa1, 0x2e, 0xb5, 0x98, 0x3b, 0x22, 0xfa, 0x77, 0xd6, 0x44, 0xbc, 0x55, 0x95, 0x70, 0xdf,
|
||||
0x1d, 0x11, 0xd4, 0x86, 0xca, 0x61, 0x10, 0x1d, 0xe9, 0xdf, 0x5d, 0x13, 0x67, 0xbe, 0x3a, 0x6b,
|
||||
0x9f, 0xb7, 0x83, 0xe8, 0xc8, 0x14, 0x50, 0xb4, 0x04, 0x15, 0x11, 0xbe, 0xdf, 0x93, 0xe6, 0xc4,
|
||||
0xc2, 0x08, 0xa1, 0xc2, 0x21, 0xe8, 0x16, 0x34, 0x93, 0xf4, 0x3b, 0x26, 0x11, 0x75, 0x03, 0x5f,
|
||||
0xd7, 0x04, 0xae, 0x11, 0xcb, 0x0f, 0xa4, 0x18, 0xad, 0x41, 0x23, 0xce, 0xf2, 0x18, 0x29, 0xeb,
|
||||
0x77, 0x5d, 0x89, 0x63, 0xe0, 0x45, 0x98, 0x93, 0x55, 0xa7, 0x2c, 0xd4, 0x72, 0x61, 0x7c, 0xa8,
|
||||
0x81, 0x3e, 0xeb, 0x99, 0xd1, 0x3d, 0xa8, 0x88, 0xa7, 0xd0, 0xc4, 0xad, 0x66, 0xa6, 0x4d, 0x86,
|
||||
0x28, 0x1e, 0x44, 0x90, 0x50, 0x1b, 0x2e, 0xe2, 0xc1, 0x20, 0x22, 0x83, 0x42, 0x7e, 0x97, 0x44,
|
||||
0xe1, 0x59, 0xca, 0xe8, 0x92, 0xe4, 0xbe, 0x05, 0x4d, 0x7b, 0x4c, 0x59, 0xe0, 0x9c, 0xa4, 0xf0,
|
||||
0xb2, 0x80, 0x37, 0x94, 0x3c, 0x81, 0xde, 0x84, 0x05, 0xee, 0x31, 0xcb, 0xf5, 0x6d, 0x6f, 0xec,
|
||||
0x10, 0x47, 0xaf, 0x88, 0x5b, 0xd5, 0xb8, 0xb0, 0xa7, 0x64, 0xc6, 0x9f, 0x35, 0xa8, 0x66, 0x0e,
|
||||
0xf7, 0xff, 0x7c, 0x9f, 0x4d, 0x48, 0x2c, 0x10, 0x8b, 0xba, 0x03, 0x1f, 0xb3, 0x71, 0x44, 0xc4,
|
||||
0xad, 0x6a, 0x26, 0x4a, 0x54, 0x7b, 0xb1, 0xc6, 0xf8, 0xa0, 0x0c, 0x8d, 0xc2, 0x41, 0x11, 0x52,
|
||||
0x31, 0xa5, 0xa5, 0x21, 0xc5, 0x9f, 0x5d, 0xf6, 0x39, 0x19, 0x15, 0x72, 0x81, 0xee, 0x82, 0x2e,
|
||||
0xef, 0x3c, 0x59, 0x8a, 0xd4, 0x09, 0x2f, 0x49, 0x7d, 0xa1, 0x0e, 0xa1, 0x7b, 0x70, 0x59, 0x36,
|
||||
0x93, 0x7e, 0x30, 0xf6, 0x1d, 0x1c, 0x9d, 0xe4, 0xa8, 0xf2, 0xb8, 0x2d, 0x81, 0xe8, 0x2a, 0x40,
|
||||
0x86, 0xfc, 0x29, 0x68, 0x89, 0xed, 0xa7, 0x6c, 0x3a, 0x27, 0x98, 0x17, 0x85, 0xba, 0xb8, 0xe7,
|
||||
0x17, 0xe0, 0x6a, 0xb1, 0x96, 0xe7, 0xb8, 0xe7, 0x04, 0xf7, 0xf5, 0x42, 0xb1, 0xce, 0x18, 0x58,
|
||||
0x83, 0x46, 0xda, 0x94, 0x64, 0x12, 0xc8, 0xce, 0x9b, 0xf6, 0x2a, 0xd9, 0x70, 0xef, 0xc3, 0x95,
|
||||
0x14, 0x38, 0x79, 0xc8, 0x79, 0xb1, 0x91, 0x9e, 0x40, 0x8a, 0x07, 0xbd, 0x3d, 0xd1, 0xfc, 0xfe,
|
||||
0x2a, 0xf6, 0xe9, 0x96, 0x74, 0xad, 0xd0, 0x00, 0x8d, 0x6f, 0xc2, 0xd5, 0xc2, 0xf3, 0x6d, 0xf9,
|
||||
0xce, 0x76, 0x12, 0x15, 0xaf, 0x16, 0xab, 0x2b, 0x50, 0xcd, 0x04, 0x9e, 0x78, 0xfa, 0x79, 0x13,
|
||||
0xd2, 0x98, 0x33, 0xbe, 0x5d, 0x81, 0x46, 0x61, 0x58, 0x44, 0xcb, 0x70, 0x2e, 0x1c, 0xf7, 0x8f,
|
||||
0xc8, 0x89, 0xd8, 0xb3, 0x66, 0xaa, 0x15, 0xea, 0xc2, 0xb5, 0xf7, 0x5d, 0x36, 0x74, 0x22, 0xfc,
|
||||
0x3e, 0xf6, 0x2c, 0x3b, 0x22, 0x0e, 0xf1, 0x99, 0x8b, 0xbd, 0x78, 0x7c, 0x53, 0x19, 0x70, 0x25,
|
||||
0x05, 0x6d, 0xa7, 0x18, 0xe5, 0x99, 0xcf, 0x80, 0xae, 0x06, 0x3f, 0x3e, 0xfd, 0xba, 0x6c, 0xc4,
|
||||
0xeb, 0x55, 0x2e, 0xde, 0x96, 0xa5, 0x7e, 0x3b, 0x51, 0x2b, 0xe6, 0x4d, 0x58, 0x50, 0x4c, 0x0f,
|
||||
0x9f, 0x90, 0x88, 0xc6, 0x89, 0x2e, 0x85, 0x0f, 0x85, 0x8c, 0x27, 0x1a, 0xb6, 0x99, 0x7b, 0x9c,
|
||||
0x1d, 0xae, 0xe6, 0x64, 0xbd, 0x4c, 0xe5, 0xf2, 0x89, 0xaf, 0x01, 0x90, 0x67, 0xae, 0x1a, 0x89,
|
||||
0x44, 0xe8, 0x54, 0xcc, 0x0b, 0x5c, 0x22, 0xd5, 0xb7, 0xa0, 0x99, 0xb9, 0x6c, 0x36, 0x56, 0x1a,
|
||||
0xa9, 0x5c, 0x42, 0xd7, 0xa0, 0x91, 0xb6, 0x62, 0x89, 0x9c, 0x97, 0x51, 0x95, 0x88, 0x25, 0xf0,
|
||||
0x00, 0x6a, 0xfc, 0x89, 0xc6, 0xd4, 0x3a, 0xf4, 0xf0, 0x80, 0xea, 0xb0, 0xaa, 0xad, 0xd7, 0x3b,
|
||||
0x77, 0xce, 0x38, 0xc4, 0x6f, 0xec, 0x09, 0xee, 0xdb, 0x9c, 0x6a, 0x56, 0x69, 0xba, 0x30, 0xbe,
|
||||
0x08, 0xd5, 0x8c, 0x0e, 0x55, 0xe1, 0x7c, 0xef, 0xdd, 0xde, 0x7e, 0x6f, 0xeb, 0x61, 0xf3, 0x35,
|
||||
0x84, 0xa0, 0x2e, 0x17, 0xfb, 0xbb, 0x3b, 0xd6, 0xee, 0x57, 0x7b, 0xfb, 0x4d, 0x0d, 0x35, 0xa1,
|
||||
0xf6, 0xa4, 0xb7, 0xff, 0x60, 0xc7, 0xdc, 0x7a, 0xb2, 0xd5, 0x7d, 0xb8, 0xdb, 0x2c, 0x19, 0x1e,
|
||||
0xb4, 0xc4, 0x94, 0x6b, 0x12, 0x4c, 0x79, 0xd1, 0xe1, 0x7e, 0x57, 0xd1, 0xb0, 0x06, 0x8d, 0x74,
|
||||
0xc0, 0x17, 0x1d, 0x5d, 0x95, 0x95, 0x7a, 0x22, 0x16, 0x6d, 0x7c, 0x46, 0x81, 0x89, 0x4b, 0x51,
|
||||
0x39, 0xd3, 0xdd, 0xbe, 0x0e, 0x8d, 0xc2, 0x84, 0x95, 0x36, 0x25, 0x2d, 0xd3, 0x94, 0x4e, 0xab,
|
||||
0x13, 0xa5, 0xd9, 0x75, 0xc2, 0xf8, 0x75, 0x29, 0xfe, 0x84, 0x12, 0x9a, 0xa9, 0xe5, 0xf0, 0x13,
|
||||
0x80, 0x42, 0x2c, 0xba, 0xe5, 0xa4, 0xd5, 0xa6, 0xd4, 0xe4, 0x12, 0x7a, 0x91, 0x3b, 0x9c, 0x4c,
|
||||
0xa9, 0x8f, 0x0d, 0xa1, 0xc8, 0x60, 0xdf, 0x82, 0x8b, 0x2a, 0x50, 0x23, 0x72, 0x4c, 0xb0, 0x97,
|
||||
0xaf, 0x89, 0x48, 0xea, 0x4c, 0xa1, 0x52, 0x8c, 0xfb, 0x70, 0x21, 0x1d, 0x77, 0xe6, 0xce, 0x38,
|
||||
0xed, 0xcc, 0xc7, 0xd3, 0x09, 0xba, 0x0a, 0x17, 0xd2, 0x46, 0x71, 0x4e, 0xcc, 0x57, 0xa9, 0x80,
|
||||
0xd7, 0x8f, 0x7e, 0xe0, 0x9c, 0x88, 0xe0, 0x3d, 0xa5, 0x7e, 0x64, 0xfc, 0xd5, 0x0d, 0x9c, 0x13,
|
||||
0x53, 0x90, 0x8c, 0xff, 0x96, 0xa0, 0x51, 0xd0, 0xa0, 0x2f, 0x41, 0x2d, 0x37, 0x3c, 0xca, 0x4f,
|
||||
0xd1, 0x9b, 0x67, 0x28, 0x4c, 0x66, 0x8e, 0x88, 0x9e, 0x00, 0x0a, 0xa3, 0x20, 0x0c, 0x28, 0x89,
|
||||
0x2c, 0xea, 0x61, 0x3a, 0x74, 0xfd, 0x01, 0xd5, 0x4b, 0xc2, 0xdc, 0xfa, 0xcc, 0x51, 0x54, 0x31,
|
||||
0xf6, 0x14, 0xc1, 0x5c, 0x0c, 0x0b, 0x12, 0x61, 0x58, 0x6e, 0x94, 0x33, 0x5c, 0x3e, 0xdd, 0xf0,
|
||||
0x96, 0x62, 0xa4, 0x86, 0x71, 0x41, 0xc2, 0x67, 0xef, 0x79, 0x87, 0x84, 0x01, 0x75, 0x19, 0x2f,
|
||||
0x3f, 0xdc, 0xdc, 0xca, 0x2c, 0x73, 0x3b, 0x12, 0x67, 0x26, 0x04, 0xd4, 0x81, 0x39, 0x5e, 0x5e,
|
||||
0xa8, 0x3e, 0x27, 0x98, 0x33, 0x67, 0xc3, 0xdd, 0x67, 0x2e, 0x33, 0x25, 0xd4, 0xf8, 0x61, 0x09,
|
||||
0x6a, 0xca, 0x52, 0xcf, 0x0f, 0xc7, 0x6c, 0x66, 0x6d, 0xde, 0x80, 0xa5, 0x30, 0x0a, 0x82, 0x43,
|
||||
0x2b, 0x38, 0xb4, 0xc2, 0x80, 0x52, 0x42, 0x93, 0x09, 0xb0, 0x26, 0x5c, 0x14, 0x1c, 0x3e, 0x3a,
|
||||
0x7c, 0x9c, 0x28, 0x5e, 0x5c, 0xcb, 0xcb, 0xaf, 0x56, 0xcb, 0x2b, 0xa7, 0xd6, 0x72, 0xf1, 0x45,
|
||||
0x2a, 0xdb, 0xd2, 0x24, 0x55, 0x4e, 0x00, 0x2d, 0x05, 0x28, 0x72, 0x8d, 0xa7, 0x80, 0x64, 0x0c,
|
||||
0x60, 0x8f, 0x0f, 0x41, 0xc4, 0x79, 0xc9, 0x89, 0xe7, 0x36, 0x2c, 0xce, 0x1a, 0x75, 0x1a, 0xfd,
|
||||
0x42, 0x21, 0xf9, 0x93, 0x06, 0x0b, 0xe2, 0xf5, 0x71, 0xdf, 0x23, 0xfc, 0x2b, 0x00, 0x7d, 0x1c,
|
||||
0x16, 0x73, 0xd5, 0xd0, 0xe5, 0x5f, 0x5d, 0x9a, 0xf8, 0xe8, 0x6a, 0x66, 0xeb, 0x21, 0x97, 0x4f,
|
||||
0x1d, 0xfb, 0x4a, 0xd3, 0xc7, 0xbe, 0xb8, 0xcb, 0x97, 0x3f, 0x4a, 0x97, 0x7f, 0xe9, 0x99, 0xf1,
|
||||
0x07, 0x1a, 0x54, 0x55, 0x58, 0x09, 0xef, 0xf5, 0x60, 0x41, 0x85, 0xa9, 0xe5, 0xf2, 0x30, 0x53,
|
||||
0xc3, 0xc6, 0x1b, 0x2f, 0x08, 0x6e, 0x11, 0x92, 0x66, 0xcd, 0x29, 0x04, 0x28, 0x1e, 0x05, 0x63,
|
||||
0x9f, 0x29, 0xaf, 0xab, 0x15, 0x2f, 0x52, 0xfc, 0xab, 0x89, 0x32, 0x3c, 0x0a, 0x55, 0x33, 0x48,
|
||||
0x05, 0xc6, 0xaf, 0x4a, 0xd0, 0x2c, 0x66, 0x36, 0x7a, 0x13, 0xea, 0x49, 0x7d, 0xc8, 0x36, 0x9e,
|
||||
0x85, 0x58, 0x2a, 0xfb, 0x8e, 0x09, 0x8d, 0x50, 0x05, 0x84, 0xfc, 0xd4, 0x6b, 0x8b, 0xad, 0xab,
|
||||
0x9d, 0xdb, 0xa7, 0xd7, 0x90, 0x6c, 0xfc, 0xc4, 0x36, 0xb1, 0xc7, 0x57, 0x6d, 0x5e, 0xc3, 0x13,
|
||||
0x9b, 0x89, 0x43, 0xad, 0xb6, 0x8a, 0x13, 0x14, 0x66, 0x0c, 0x08, 0x55, 0x7b, 0xf2, 0x14, 0x32,
|
||||
0x07, 0x5e, 0xe1, 0x14, 0x9d, 0x19, 0xa7, 0x88, 0x33, 0x64, 0xf2, 0x14, 0x1d, 0xe3, 0x27, 0x1a,
|
||||
0x34, 0x8b, 0x85, 0x0c, 0x3d, 0x82, 0x26, 0x8d, 0x83, 0x58, 0x7c, 0x07, 0x5b, 0x6d, 0xf5, 0xc0,
|
||||
0x6f, 0xce, 0x3a, 0x5b, 0x2e, 0xe8, 0xcd, 0x3a, 0xcd, 0x2e, 0xdb, 0x53, 0x0c, 0x76, 0x94, 0xcb,
|
||||
0x3f, 0x92, 0xc1, 0x8e, 0xf1, 0x7d, 0x0d, 0xce, 0xab, 0x98, 0x42, 0x1d, 0xb8, 0x34, 0x22, 0xd1,
|
||||
0x91, 0x47, 0xac, 0x7e, 0x84, 0x7d, 0x7b, 0x98, 0xfc, 0x74, 0xa0, 0x89, 0xce, 0xb6, 0x24, 0x95,
|
||||
0x5d, 0xa1, 0x8b, 0x7f, 0x36, 0xb8, 0x0d, 0x8b, 0x8a, 0xc3, 0x22, 0x42, 0x54, 0xb0, 0xc8, 0xf8,
|
||||
0x6b, 0x48, 0xc5, 0x7e, 0x44, 0x88, 0x0c, 0x97, 0x1b, 0x10, 0x07, 0xac, 0x95, 0x64, 0x5c, 0xcd,
|
||||
0xac, 0x3a, 0x69, 0x3a, 0x18, 0x18, 0x2a, 0xbc, 0x08, 0x4f, 0x2d, 0x2a, 0x53, 0xc6, 0xa1, 0xd2,
|
||||
0xd4, 0x71, 0x28, 0xd7, 0x95, 0xe5, 0x26, 0xa9, 0xc0, 0xf8, 0xb0, 0x04, 0x57, 0x0e, 0x8a, 0xbf,
|
||||
0xab, 0xee, 0x10, 0x8f, 0x61, 0x39, 0xb2, 0x3c, 0x80, 0x1b, 0xf1, 0xef, 0xa4, 0xf1, 0x4f, 0xb3,
|
||||
0x0e, 0xd7, 0xe6, 0xaa, 0x96, 0x6c, 0x01, 0xd7, 0xd4, 0x8f, 0xa5, 0x59, 0x23, 0xf9, 0x6f, 0x9e,
|
||||
0xb3, 0x1d, 0x38, 0x6d, 0x2d, 0xe5, 0x5c, 0x6b, 0x89, 0xbd, 0x50, 0xc9, 0x78, 0xc1, 0x86, 0x0a,
|
||||
0x1f, 0x61, 0x45, 0x24, 0xd6, 0x3b, 0x8f, 0xce, 0x30, 0xc1, 0x16, 0x6f, 0x38, 0x43, 0x27, 0xa7,
|
||||
0x5b, 0x61, 0xdc, 0xb8, 0x3b, 0xcb, 0x45, 0x72, 0xcc, 0xad, 0x03, 0x6c, 0x6d, 0xef, 0xf7, 0x0e,
|
||||
0xb6, 0xf6, 0x7b, 0x8f, 0xde, 0x6d, 0xbe, 0x86, 0xe6, 0xa1, 0x22, 0xe7, 0x5b, 0xe3, 0x6b, 0x30,
|
||||
0x9f, 0xfc, 0x08, 0xb4, 0x01, 0x4b, 0xf1, 0x73, 0x4f, 0xba, 0x6e, 0x51, 0xa9, 0x32, 0xee, 0xba,
|
||||
0x01, 0x35, 0xd9, 0x1e, 0x72, 0x13, 0x61, 0x55, 0xc8, 0x54, 0x57, 0xf0, 0xa0, 0x96, 0xfd, 0x9d,
|
||||
0x28, 0x3f, 0xbe, 0x69, 0x2f, 0x3d, 0xbe, 0x5d, 0x03, 0x10, 0x39, 0x64, 0x67, 0xaa, 0xe6, 0x05,
|
||||
0x2e, 0xd9, 0xe6, 0x82, 0x6e, 0xed, 0x37, 0xcf, 0xaf, 0x6b, 0xbf, 0x7d, 0x7e, 0x5d, 0xfb, 0xcb,
|
||||
0xf3, 0xeb, 0x5a, 0xff, 0x9c, 0xf8, 0x27, 0xc1, 0x9d, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x2b,
|
||||
0x62, 0x5a, 0xe4, 0x7c, 0x18, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@@ -51,14 +51,14 @@ message Fork {
|
||||
|
||||
message PendingAttestationRecord {
|
||||
AttestationData data = 1;
|
||||
bytes participation_bitfield = 2;
|
||||
bytes aggregation_bitfield = 2;
|
||||
bytes custody_bitfield = 3;
|
||||
uint64 slot_included = 4;
|
||||
}
|
||||
|
||||
message Attestation {
|
||||
AttestationData data = 1;
|
||||
bytes participation_bitfield = 2;
|
||||
bytes aggregation_bitfield = 2;
|
||||
bytes custody_bitfield = 3;
|
||||
bytes aggregate_signature = 4; // Type of [uint384] ?
|
||||
}
|
||||
@@ -70,8 +70,9 @@ message AttestationData {
|
||||
bytes epoch_boundary_root_hash32 = 4;
|
||||
bytes shard_block_root_hash32 = 5;
|
||||
bytes latest_crosslink_root_hash32 = 6;
|
||||
uint64 justified_slot = 7;
|
||||
uint64 justified_epoch = 7;
|
||||
bytes justified_block_root_hash32 = 8;
|
||||
uint64 justified_slot = 1000 [deprecated=true];
|
||||
}
|
||||
|
||||
message AttestationDataAndCustodyBit {
|
||||
|
||||
1430
proto/beacon/rpc/v1/services.pb.go
generated
1430
proto/beacon/rpc/v1/services.pb.go
generated
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,9 @@ service BeaconService {
|
||||
}
|
||||
|
||||
service AttesterService {
|
||||
rpc AttestHead(AttestRequest) returns (AttestResponse);
|
||||
rpc AttestHead(ethereum.beacon.p2p.v1.Attestation) returns (AttestResponse);
|
||||
rpc CrosslinkCommitteesAtSlot(CrosslinkCommitteeRequest) returns (CrosslinkCommitteeResponse);
|
||||
rpc AttestationInfoAtSlot(AttestationInfoRequest) returns (AttestationInfoResponse);
|
||||
}
|
||||
|
||||
service ProposerService {
|
||||
@@ -31,6 +33,28 @@ service ValidatorService {
|
||||
rpc ValidatorEpochAssignments(ValidatorEpochAssignmentsRequest) returns (ValidatorEpochAssignmentsResponse);
|
||||
}
|
||||
|
||||
message AttestationInfoRequest {
|
||||
uint64 slot = 1;
|
||||
uint64 shard = 2;
|
||||
}
|
||||
|
||||
message AttestationInfoResponse {
|
||||
bytes beacon_block_root_hash32 = 1;
|
||||
bytes epoch_boundary_root_hash32 = 2;
|
||||
uint64 justified_epoch = 3;
|
||||
bytes justified_block_root_hash32 = 4;
|
||||
bytes latest_crosslink_root_hash32 = 5;
|
||||
}
|
||||
|
||||
message CrosslinkCommitteeRequest {
|
||||
uint64 slot = 1;
|
||||
}
|
||||
|
||||
message CrosslinkCommitteeResponse {
|
||||
repeated uint64 committee = 1;
|
||||
uint64 shard = 2;
|
||||
}
|
||||
|
||||
message ChainStartResponse {
|
||||
bool started = 1;
|
||||
uint64 genesis_time = 2;
|
||||
@@ -61,10 +85,6 @@ message StateRootResponse {
|
||||
bytes state_root = 1;
|
||||
}
|
||||
|
||||
message AttestRequest {
|
||||
ethereum.beacon.p2p.v1.Attestation attestation = 1;
|
||||
}
|
||||
|
||||
message AttestResponse {
|
||||
bytes attestation_hash = 1;
|
||||
}
|
||||
@@ -92,18 +112,19 @@ message ValidatorIndexResponse {
|
||||
}
|
||||
|
||||
message ValidatorEpochAssignmentsRequest {
|
||||
uint64 epoch_start = 1;
|
||||
bytes public_key = 2;
|
||||
uint64 epoch_start = 1;
|
||||
bytes public_key = 2;
|
||||
}
|
||||
|
||||
message ValidatorEpochAssignmentsResponse {
|
||||
Assignment assignment = 2;
|
||||
Assignment assignment = 2;
|
||||
}
|
||||
|
||||
message PendingDepositsResponse {
|
||||
repeated ethereum.beacon.p2p.v1.Deposit pending_deposits = 1;
|
||||
repeated ethereum.beacon.p2p.v1.Deposit pending_deposits = 1;
|
||||
}
|
||||
|
||||
message Eth1DataResponse {
|
||||
ethereum.beacon.p2p.v1.Eth1Data eth1_data = 1;
|
||||
ethereum.beacon.p2p.v1.Eth1Data eth1_data = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ func TestMessageMetrics(t *testing.T) {
|
||||
t.Error("Expected metric adapter")
|
||||
}
|
||||
data := &pb.Attestation{
|
||||
ParticipationBitfield: []byte{99},
|
||||
AggregationBitfield: []byte{99},
|
||||
Data: &pb.AttestationData{
|
||||
Slot: 0,
|
||||
},
|
||||
|
||||
@@ -3,8 +3,8 @@ package p2p
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/libp2p/go-libp2p-host"
|
||||
"github.com/libp2p/go-libp2p-peerstore"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
peerstore "github.com/libp2p/go-libp2p-peerstore"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
iaddr "github.com/ipfs/go-ipfs-addr"
|
||||
"github.com/libp2p/go-libp2p-host"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
ps "github.com/libp2p/go-libp2p-peerstore"
|
||||
mdns "github.com/libp2p/go-libp2p/p2p/discovery"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-host"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
|
||||
@@ -13,10 +13,10 @@ import (
|
||||
|
||||
ggio "github.com/gogo/protobuf/io"
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p-host"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
dhtopts "github.com/libp2p/go-libp2p-kad-dht/opts"
|
||||
dhtpb "github.com/libp2p/go-libp2p-kad-dht/pb"
|
||||
"github.com/libp2p/go-libp2p-net"
|
||||
net "github.com/libp2p/go-libp2p-net"
|
||||
"github.com/prysmaticlabs/prysm/shared/p2p"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,35 +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/attester",
|
||||
visibility = ["//validator:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/beacon/rpc/v1:go_default_library",
|
||||
"//shared/bitutil:go_default_library",
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/hashutil:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["service_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library", #keep
|
||||
"//proto/beacon/rpc/v1:go_default_library",
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//validator/internal:go_default_library",
|
||||
"@com_github_golang_mock//gomock:go_default_library", #keep
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library", #keep
|
||||
"@org_golang_google_grpc//metadata:go_default_library", #keep
|
||||
],
|
||||
)
|
||||
@@ -1,151 +0,0 @@
|
||||
// Package attester defines all relevant functionality for a Attester actor
|
||||
// within Ethereum Serenity.
|
||||
package attester
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/bitutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var log = logrus.WithField("prefix", "attester")
|
||||
|
||||
type rpcClientService interface {
|
||||
AttesterServiceClient() pb.AttesterServiceClient
|
||||
ValidatorServiceClient() pb.ValidatorServiceClient
|
||||
}
|
||||
|
||||
type beaconClientService interface {
|
||||
AttesterAssignmentFeed() *event.Feed
|
||||
}
|
||||
|
||||
// Attester holds functionality required to run a block attester
|
||||
// in Ethereum Serenity.
|
||||
type Attester struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
beaconService beaconClientService
|
||||
rpcClientService rpcClientService
|
||||
assignmentChan chan *pbp2p.BeaconBlock
|
||||
shardID uint64
|
||||
publicKey []byte
|
||||
}
|
||||
|
||||
// Config options for an attester service.
|
||||
type Config struct {
|
||||
AssignmentBuf int
|
||||
ShardID uint64
|
||||
Assigner beaconClientService
|
||||
Client rpcClientService
|
||||
PublicKey []byte
|
||||
}
|
||||
|
||||
// NewAttester creates a new attester instance.
|
||||
func NewAttester(ctx context.Context, cfg *Config) *Attester {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
return &Attester{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
beaconService: cfg.Assigner,
|
||||
rpcClientService: cfg.Client,
|
||||
shardID: cfg.ShardID,
|
||||
publicKey: cfg.PublicKey,
|
||||
assignmentChan: make(chan *pbp2p.BeaconBlock, cfg.AssignmentBuf),
|
||||
}
|
||||
}
|
||||
|
||||
// Start the main routine for an attester.
|
||||
func (a *Attester) Start() {
|
||||
log.Info("Starting service")
|
||||
attester := a.rpcClientService.AttesterServiceClient()
|
||||
validator := a.rpcClientService.ValidatorServiceClient()
|
||||
go a.run(attester, validator)
|
||||
}
|
||||
|
||||
// Stop the main loop.
|
||||
func (a *Attester) Stop() error {
|
||||
defer a.cancel()
|
||||
log.Info("Stopping service")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status always returns nil.
|
||||
// This service will be rewritten in the future so this service check is a
|
||||
// no-op for now.
|
||||
func (a *Attester) Status() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// run the main event loop that listens for an attester assignment.
|
||||
func (a *Attester) run(attester pb.AttesterServiceClient, validator pb.ValidatorServiceClient) {
|
||||
sub := a.beaconService.AttesterAssignmentFeed().Subscribe(a.assignmentChan)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-a.ctx.Done():
|
||||
log.Debug("Attester context closed, exiting goroutine")
|
||||
return
|
||||
case latestBeaconBlock := <-a.assignmentChan:
|
||||
log.Info("Performing attester responsibility")
|
||||
|
||||
if latestBeaconBlock == nil {
|
||||
log.Errorf("could not marshal nil latest beacon block")
|
||||
continue
|
||||
}
|
||||
data, err := proto.Marshal(latestBeaconBlock)
|
||||
if err != nil {
|
||||
log.Errorf("could not marshal latest beacon block: %v", err)
|
||||
continue
|
||||
}
|
||||
latestBlockHash := hashutil.Hash(data)
|
||||
|
||||
req := &pb.ValidatorEpochAssignmentsRequest{
|
||||
EpochStart: 0,
|
||||
PublicKey: a.publicKey,
|
||||
}
|
||||
res, err := validator.ValidatorEpochAssignments(a.ctx, req)
|
||||
if err != nil {
|
||||
log.Errorf("could not get attester Shard ID: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
a.shardID = res.Assignment.Shard
|
||||
|
||||
indexReq := &pb.ValidatorIndexRequest{
|
||||
PublicKey: a.publicKey,
|
||||
}
|
||||
attesterIndex, err := validator.ValidatorIndex(a.ctx, indexReq)
|
||||
if err != nil {
|
||||
log.Errorf("could not get attester index: %v", err)
|
||||
continue
|
||||
}
|
||||
attesterBitfield := bitutil.SetBitfield(int(attesterIndex.Index))
|
||||
|
||||
attestReq := &pb.AttestRequest{
|
||||
Attestation: &pbp2p.Attestation{
|
||||
ParticipationBitfield: attesterBitfield,
|
||||
AggregateSignature: []byte{}, // TODO(258): Need Signature verification scheme/library
|
||||
Data: &pbp2p.AttestationData{
|
||||
Slot: latestBeaconBlock.Slot,
|
||||
Shard: a.shardID,
|
||||
ShardBlockRootHash32: latestBlockHash[:],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
attRes, err := attester.AttestHead(a.ctx, attestReq)
|
||||
if err != nil {
|
||||
log.Errorf("could not attest head: %v", err)
|
||||
continue
|
||||
}
|
||||
log.Infof("Attestation proposed successfully with hash %#x", attRes.AttestationHash)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
package attester
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/validator/internal"
|
||||
"github.com/sirupsen/logrus"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetOutput(ioutil.Discard)
|
||||
}
|
||||
|
||||
type mockClient struct {
|
||||
ctrl *gomock.Controller
|
||||
}
|
||||
|
||||
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 {
|
||||
return new(event.Feed)
|
||||
}
|
||||
|
||||
func (m *mockAssigner) PublicKey() []byte {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
func TestLifecycle(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)
|
||||
att.Start()
|
||||
att.Stop()
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Starting service")
|
||||
testutil.AssertLogsContain(t, hook, "Stopping service")
|
||||
}
|
||||
|
||||
func TestAttesterLoop(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().ValidatorEpochAssignments(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(&pb.ValidatorEpochAssignmentsResponse{
|
||||
Assignment: &pb.Assignment{
|
||||
Shard: 100,
|
||||
},
|
||||
}, nil)
|
||||
mockServiceValidator.EXPECT().ValidatorIndex(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(&pb.ValidatorIndexResponse{
|
||||
Index: 0,
|
||||
}, nil)
|
||||
|
||||
mockServiceAttester := internal.NewMockAttesterServiceClient(ctrl)
|
||||
mockServiceAttester.EXPECT().AttestHead(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(&pb.AttestResponse{
|
||||
AttestationHash: []byte{'A'},
|
||||
}, nil)
|
||||
|
||||
exitRoutine := make(chan bool)
|
||||
go func() {
|
||||
att.run(mockServiceAttester, mockServiceValidator)
|
||||
<-exitRoutine
|
||||
}()
|
||||
att.assignmentChan <- &pbp2p.BeaconBlock{Slot: 33}
|
||||
att.cancel()
|
||||
exitRoutine <- true
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Performing attester responsibility")
|
||||
testutil.AssertLogsContain(t, hook, "Attester context closed")
|
||||
}
|
||||
|
||||
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},
|
||||
}
|
||||
att := NewAttester(ctx, cfg)
|
||||
|
||||
mockServiceAttester := internal.NewMockAttesterServiceClient(ctrl)
|
||||
|
||||
mockServiceValidator := internal.NewMockValidatorServiceClient(ctrl)
|
||||
|
||||
exitRoutine := make(chan bool)
|
||||
go func() {
|
||||
att.run(mockServiceAttester, mockServiceValidator)
|
||||
<-exitRoutine
|
||||
}()
|
||||
|
||||
att.assignmentChan <- nil
|
||||
att.cancel()
|
||||
exitRoutine <- true
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "could not marshal nil latest beacon block")
|
||||
testutil.AssertLogsContain(t, hook, "Attester context closed")
|
||||
}
|
||||
|
||||
func TestAttesterErrorCantAttestHead(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().ValidatorEpochAssignments(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(&pb.ValidatorEpochAssignmentsResponse{
|
||||
Assignment: &pb.Assignment{
|
||||
Shard: 100,
|
||||
},
|
||||
}, nil)
|
||||
mockServiceValidator.EXPECT().ValidatorIndex(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(&pb.ValidatorIndexResponse{
|
||||
Index: 0,
|
||||
}, nil)
|
||||
|
||||
mockServiceAttester := internal.NewMockAttesterServiceClient(ctrl)
|
||||
// Expect call to throw an error.
|
||||
mockServiceAttester.EXPECT().AttestHead(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(nil, errors.New("could not attest head"))
|
||||
|
||||
exitRoutine := make(chan bool)
|
||||
go func() {
|
||||
att.run(mockServiceAttester, mockServiceValidator)
|
||||
<-exitRoutine
|
||||
}()
|
||||
|
||||
att.assignmentChan <- &pbp2p.BeaconBlock{Slot: 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().ValidatorEpochAssignments(
|
||||
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{Slot: 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().ValidatorEpochAssignments(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(&pb.ValidatorEpochAssignmentsResponse{
|
||||
Assignment: &pb.Assignment{
|
||||
Shard: 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{Slot: 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")
|
||||
}
|
||||
@@ -6,6 +6,7 @@ go_library(
|
||||
"runner.go",
|
||||
"service.go",
|
||||
"validator.go",
|
||||
"validator_attest.go",
|
||||
"validator_propose.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/validator/client",
|
||||
@@ -31,6 +32,7 @@ go_test(
|
||||
"fake_validator_test.go",
|
||||
"runner_test.go",
|
||||
"service_test.go",
|
||||
"validator_attest_test.go",
|
||||
"validator_propose_test.go",
|
||||
"validator_test.go",
|
||||
],
|
||||
@@ -42,6 +44,7 @@ go_test(
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//validator/internal:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto: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",
|
||||
|
||||
@@ -67,6 +67,7 @@ func (v *ValidatorService) Start() {
|
||||
v.validator = &validator{
|
||||
beaconClient: pb.NewBeaconServiceClient(v.conn),
|
||||
validatorClient: pb.NewValidatorServiceClient(v.conn),
|
||||
attesterClient: pb.NewAttesterServiceClient(v.conn),
|
||||
}
|
||||
go run(v.ctx, v.validator)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ type validator struct {
|
||||
proposerClient pb.ProposerServiceClient
|
||||
validatorClient pb.ValidatorServiceClient
|
||||
beaconClient pb.BeaconServiceClient
|
||||
attesterClient pb.AttesterServiceClient
|
||||
pubKey []byte
|
||||
attestationPool AttestationPool
|
||||
}
|
||||
@@ -137,11 +138,3 @@ func (v *validator) RoleAt(slot uint64) pb.ValidatorRole {
|
||||
}
|
||||
return pb.ValidatorRole_UNKNOWN
|
||||
}
|
||||
|
||||
// AttestToBlockHead
|
||||
//
|
||||
// WIP - not done.
|
||||
func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "validator.AttestToBlockHead")
|
||||
defer span.Finish()
|
||||
}
|
||||
|
||||
121
validator/client/validator_attest.go
Normal file
121
validator/client/validator_attest.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
|
||||
"github.com/opentracing/opentracing-go"
|
||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
)
|
||||
|
||||
// AttestToBlockHead completes the validator client's attester responsibility at a given slot.
|
||||
// It fetches the latest beacon block head along with the latest canonical beacon state
|
||||
// information in order to sign the block and include information about the validator's
|
||||
// participation in voting on the block.
|
||||
func (v *validator) AttestToBlockHead(ctx context.Context, slot uint64) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "validator.AttestToBlockHead")
|
||||
defer span.Finish()
|
||||
// First the validator should construct attestation_data, an AttestationData
|
||||
// object based upon the state at the assigned slot.
|
||||
attData := &pbp2p.AttestationData{
|
||||
Slot: slot,
|
||||
ShardBlockRootHash32: params.BeaconConfig().ZeroHash[:], // Stub for Phase 0.
|
||||
}
|
||||
req := &pb.CrosslinkCommitteeRequest{
|
||||
Slot: slot,
|
||||
}
|
||||
resp, err := v.attesterClient.CrosslinkCommitteesAtSlot(ctx, req)
|
||||
if err != nil {
|
||||
log.Errorf("Could not fetch crosslink committees at slot %d: %v", slot, err)
|
||||
return
|
||||
}
|
||||
if len(resp.Committee) == 0 {
|
||||
log.Error("Received an empty committee assignment")
|
||||
return
|
||||
}
|
||||
// Set the attestation data's shard as the shard associated with the validator's
|
||||
// committee as retrieved by CrosslinkCommitteesAtSlot.
|
||||
attData.Shard = resp.Shard
|
||||
|
||||
// Fetch other necessary information from the beacon node in order to attest
|
||||
// including the justified epoch, epoch boundary information, and more.
|
||||
infoReq := &pb.AttestationInfoRequest{
|
||||
Slot: slot,
|
||||
Shard: resp.Shard,
|
||||
}
|
||||
infoRes, err := v.attesterClient.AttestationInfoAtSlot(ctx, infoReq)
|
||||
if err != nil {
|
||||
log.Errorf("Could not fetch necessary info to produce attestation at slot %d: %v", slot, err)
|
||||
return
|
||||
}
|
||||
// Set the attestation data's beacon block root = hash_tree_root(head) where head
|
||||
// is the validator's view of the head block of the beacon chain during the slot.
|
||||
attData.BeaconBlockRootHash32 = infoRes.BeaconBlockRootHash32
|
||||
// Set the attestation data's epoch boundary root = hash_tree_root(epoch_boundary)
|
||||
// where epoch_boundary is the block at the most recent epoch boundary in the
|
||||
// chain defined by head -- i.e. the BeaconBlock where block.slot == get_epoch_start_slot(head.slot).
|
||||
// On the server side, this is fetched by calling get_block_root(state, get_epoch_start_slot(head.slot)).
|
||||
attData.EpochBoundaryRootHash32 = infoRes.EpochBoundaryRootHash32
|
||||
// Set the attestation data's latest crosslink root = state.latest_crosslinks[shard].shard_block_root
|
||||
// where state is the beacon state at head and shard is the validator's assigned shard.
|
||||
attData.LatestCrosslinkRootHash32 = infoRes.LatestCrosslinkRootHash32
|
||||
// Set the attestation data's justified epoch = state.justified_epoch where state
|
||||
// is the beacon state at the head.
|
||||
attData.JustifiedEpoch = infoRes.JustifiedEpoch
|
||||
// Set the attestation data's justified block root = hash_tree_root(justified_block) where
|
||||
// justified_block is the block at state.justified_epoch in the chain defined by head.
|
||||
// On the server side, this is fetched by calling get_block_root(state, justified_epoch).
|
||||
attData.JustifiedBlockRootHash32 = infoRes.JustifiedBlockRootHash32
|
||||
|
||||
// The validator now creates an Attestation object using the AttestationData as
|
||||
// set in the code above after all properties have been set.
|
||||
attestation := &pbp2p.Attestation{
|
||||
Data: attData,
|
||||
}
|
||||
|
||||
// We set the custody bitfield to an slice of zero values as a stub for phase 0
|
||||
// of length len(committee)+7 // 8.
|
||||
attestation.CustodyBitfield = make([]byte, (len(resp.Committee)+7)/8)
|
||||
|
||||
// We set the aggregation bitfield for the attestation.
|
||||
idxReq := &pb.ValidatorIndexRequest{
|
||||
PublicKey: v.pubKey,
|
||||
}
|
||||
// We fetch the validator index as it is necessary to generate the aggregation
|
||||
// bitfield of the attestation itself.
|
||||
validatorIndexRes, err := v.validatorClient.ValidatorIndex(ctx, idxReq)
|
||||
if err != nil {
|
||||
log.Errorf("Could not fetch validator index: %v", err)
|
||||
return
|
||||
}
|
||||
// We set the attestation's aggregation bitfield by determining the index in the committee
|
||||
// corresponding to the validator and modifying the bitfield itself.
|
||||
aggregationBitfield := make([]byte, (len(resp.Committee)+7)/8)
|
||||
var indexIntoCommittee uint
|
||||
for i, validator := range resp.Committee {
|
||||
if validator == validatorIndexRes.Index {
|
||||
indexIntoCommittee = uint(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
aggregationBitfield[indexIntoCommittee/8] |= 1 << (indexIntoCommittee % 8)
|
||||
// Note: calling get_attestation_participants(state, attestation.data, attestation.aggregation_bitfield)
|
||||
// should return a list of length equal to 1, containing validator_index.
|
||||
attestation.AggregationBitfield = aggregationBitfield
|
||||
|
||||
// TODO(#1366): Use BLS to generate an aggregate signature.
|
||||
attestation.AggregateSignature = []byte("signed")
|
||||
|
||||
attestRes, err := v.attesterClient.AttestHead(ctx, attestation)
|
||||
if err != nil {
|
||||
log.Errorf("Could not submit attestation to beacon node: %v", err)
|
||||
return
|
||||
}
|
||||
log.WithField(
|
||||
"hash", fmt.Sprintf("%#x", attestRes.AttestationHash),
|
||||
).Info("Submitted attestation successfully with hash %#x", attestRes.AttestationHash)
|
||||
}
|
||||
201
validator/client/validator_attest_test.go
Normal file
201
validator/client/validator_attest_test.go
Normal file
@@ -0,0 +1,201 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/golang/mock/gomock"
|
||||
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 TestAttestToBlockHead_CrosslinkCommitteeRequestFailure(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
validator, m, finish := setup(t)
|
||||
defer finish()
|
||||
m.attesterClient.EXPECT().CrosslinkCommitteesAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.CrosslinkCommitteeRequest{}),
|
||||
).Return(nil /*Crosslinks Response*/, errors.New("something bad happened"))
|
||||
|
||||
validator.AttestToBlockHead(context.Background(), 30)
|
||||
testutil.AssertLogsContain(t, hook, "Could not fetch crosslink committees at slot 30")
|
||||
}
|
||||
|
||||
func TestAttestToBlockHead_CrosslinkCommitteeRequestEmptyCommittee(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
validator, m, finish := setup(t)
|
||||
defer finish()
|
||||
m.attesterClient.EXPECT().CrosslinkCommitteesAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.CrosslinkCommitteeRequest{}),
|
||||
).Return(&pb.CrosslinkCommitteeResponse{
|
||||
Committee: []uint64{},
|
||||
}, nil)
|
||||
|
||||
validator.AttestToBlockHead(context.Background(), 30)
|
||||
testutil.AssertLogsContain(t, hook, "Received an empty committee assignment")
|
||||
}
|
||||
|
||||
func TestAttestToBlockHead_AttestationInfoAtSlotRequestFailure(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
validator, m, finish := setup(t)
|
||||
defer finish()
|
||||
m.attesterClient.EXPECT().CrosslinkCommitteesAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.Any(),
|
||||
).Return(&pb.CrosslinkCommitteeResponse{
|
||||
Shard: 5,
|
||||
Committee: []uint64{1, 2, 3, 4},
|
||||
}, nil)
|
||||
m.attesterClient.EXPECT().AttestationInfoAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.AttestationInfoRequest{}),
|
||||
).Return(nil /* Attestation Info Response*/, errors.New("something bad happened"))
|
||||
|
||||
validator.AttestToBlockHead(context.Background(), 30)
|
||||
testutil.AssertLogsContain(t, hook, "Could not fetch necessary info to produce attestation at slot 30")
|
||||
}
|
||||
|
||||
func TestAttestToBlockHead_ValidatorIndexRequestFailure(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
validator, m, finish := setup(t)
|
||||
defer finish()
|
||||
m.attesterClient.EXPECT().CrosslinkCommitteesAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.CrosslinkCommitteeRequest{}),
|
||||
).Return(&pb.CrosslinkCommitteeResponse{
|
||||
Shard: 5,
|
||||
Committee: []uint64{1, 2, 3, 4},
|
||||
}, nil)
|
||||
m.attesterClient.EXPECT().AttestationInfoAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.AttestationInfoRequest{}),
|
||||
).Return(&pb.AttestationInfoResponse{
|
||||
BeaconBlockRootHash32: []byte{},
|
||||
EpochBoundaryRootHash32: []byte{},
|
||||
JustifiedBlockRootHash32: []byte{},
|
||||
LatestCrosslinkRootHash32: []byte{},
|
||||
JustifiedEpoch: 0,
|
||||
}, nil)
|
||||
m.validatorClient.EXPECT().ValidatorIndex(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.ValidatorIndexRequest{}),
|
||||
).Return(nil /* Validator Index Response*/, errors.New("something bad happened"))
|
||||
|
||||
validator.AttestToBlockHead(context.Background(), 30)
|
||||
testutil.AssertLogsContain(t, hook, "Could not fetch validator index")
|
||||
}
|
||||
|
||||
func TestAttestToBlockHead_AttestHeadRequestFailure(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
validator, m, finish := setup(t)
|
||||
defer finish()
|
||||
m.attesterClient.EXPECT().CrosslinkCommitteesAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.CrosslinkCommitteeRequest{}),
|
||||
).Return(&pb.CrosslinkCommitteeResponse{
|
||||
Shard: 5,
|
||||
Committee: make([]uint64, 111),
|
||||
}, nil)
|
||||
m.attesterClient.EXPECT().AttestationInfoAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.AttestationInfoRequest{}),
|
||||
).Return(&pb.AttestationInfoResponse{
|
||||
BeaconBlockRootHash32: []byte{},
|
||||
EpochBoundaryRootHash32: []byte{},
|
||||
JustifiedBlockRootHash32: []byte{},
|
||||
LatestCrosslinkRootHash32: []byte{},
|
||||
JustifiedEpoch: 0,
|
||||
}, nil)
|
||||
m.validatorClient.EXPECT().ValidatorIndex(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.ValidatorIndexRequest{}),
|
||||
).Return(&pb.ValidatorIndexResponse{
|
||||
Index: 0,
|
||||
}, nil)
|
||||
m.attesterClient.EXPECT().AttestHead(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pbp2p.Attestation{}),
|
||||
).Return(nil, errors.New("something went wrong"))
|
||||
|
||||
validator.AttestToBlockHead(context.Background(), 30)
|
||||
testutil.AssertLogsContain(t, hook, "Could not submit attestation to beacon node")
|
||||
}
|
||||
|
||||
func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
validator, m, finish := setup(t)
|
||||
defer finish()
|
||||
validatorIndex := uint64(5)
|
||||
committee := []uint64{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
|
||||
m.attesterClient.EXPECT().CrosslinkCommitteesAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.CrosslinkCommitteeRequest{}),
|
||||
).Return(&pb.CrosslinkCommitteeResponse{
|
||||
Shard: 5,
|
||||
Committee: committee,
|
||||
}, nil)
|
||||
m.attesterClient.EXPECT().AttestationInfoAtSlot(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.AttestationInfoRequest{}),
|
||||
).Return(&pb.AttestationInfoResponse{
|
||||
BeaconBlockRootHash32: []byte("A"),
|
||||
EpochBoundaryRootHash32: []byte("B"),
|
||||
JustifiedBlockRootHash32: []byte("C"),
|
||||
LatestCrosslinkRootHash32: []byte("D"),
|
||||
JustifiedEpoch: 3,
|
||||
}, nil)
|
||||
m.validatorClient.EXPECT().ValidatorIndex(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pb.ValidatorIndexRequest{}),
|
||||
).Return(&pb.ValidatorIndexResponse{
|
||||
Index: uint64(validatorIndex),
|
||||
}, nil)
|
||||
|
||||
var generatedAttestation *pbp2p.Attestation
|
||||
m.attesterClient.EXPECT().AttestHead(
|
||||
gomock.Any(), // ctx
|
||||
gomock.AssignableToTypeOf(&pbp2p.Attestation{}),
|
||||
).Do(func(_ context.Context, att *pbp2p.Attestation) {
|
||||
generatedAttestation = att
|
||||
}).Return(&pb.AttestResponse{}, nil /* error */)
|
||||
|
||||
validator.AttestToBlockHead(context.Background(), 30)
|
||||
|
||||
aggregationBitfield := make([]byte, (len(committee)+7)/8)
|
||||
// Validator index is at index 4 in the mocked committee defined in this test.
|
||||
indexIntoCommittee := uint64(4)
|
||||
aggregationBitfield[indexIntoCommittee/8] |= 1 << (indexIntoCommittee % 8)
|
||||
expectedAttestation := &pbp2p.Attestation{
|
||||
Data: &pbp2p.AttestationData{
|
||||
Slot: 30,
|
||||
Shard: 5,
|
||||
BeaconBlockRootHash32: []byte("A"),
|
||||
EpochBoundaryRootHash32: []byte("B"),
|
||||
JustifiedBlockRootHash32: []byte("C"),
|
||||
LatestCrosslinkRootHash32: []byte("D"),
|
||||
ShardBlockRootHash32: params.BeaconConfig().ZeroHash[:],
|
||||
JustifiedEpoch: 3,
|
||||
},
|
||||
CustodyBitfield: make([]byte, (len(committee)+7)/8),
|
||||
AggregationBitfield: aggregationBitfield,
|
||||
AggregateSignature: []byte("signed"),
|
||||
}
|
||||
if !proto.Equal(generatedAttestation, expectedAttestation) {
|
||||
t.Errorf("Incorrectly attested head, wanted %v, received %v", expectedAttestation, generatedAttestation)
|
||||
}
|
||||
testutil.AssertLogsContain(t, hook, "Submitted attestation successfully")
|
||||
}
|
||||
@@ -16,21 +16,27 @@ import (
|
||||
)
|
||||
|
||||
type mocks struct {
|
||||
proposerClient *internal.MockProposerServiceClient
|
||||
beaconClient *internal.MockBeaconServiceClient
|
||||
proposerClient *internal.MockProposerServiceClient
|
||||
beaconClient *internal.MockBeaconServiceClient
|
||||
validatorClient *internal.MockValidatorServiceClient
|
||||
attesterClient *internal.MockAttesterServiceClient
|
||||
}
|
||||
|
||||
func setup(t *testing.T) (*validator, *mocks, func()) {
|
||||
ctrl := gomock.NewController(t)
|
||||
m := &mocks{
|
||||
proposerClient: internal.NewMockProposerServiceClient(ctrl),
|
||||
beaconClient: internal.NewMockBeaconServiceClient(ctrl),
|
||||
proposerClient: internal.NewMockProposerServiceClient(ctrl),
|
||||
beaconClient: internal.NewMockBeaconServiceClient(ctrl),
|
||||
validatorClient: internal.NewMockValidatorServiceClient(ctrl),
|
||||
attesterClient: internal.NewMockAttesterServiceClient(ctrl),
|
||||
}
|
||||
|
||||
validator := &validator{
|
||||
attestationPool: &fakeAttestationPool{},
|
||||
proposerClient: m.proposerClient,
|
||||
beaconClient: m.beaconClient,
|
||||
attesterClient: m.attesterClient,
|
||||
validatorClient: m.validatorClient,
|
||||
}
|
||||
|
||||
return validator, m, ctrl.Finish
|
||||
@@ -85,7 +91,7 @@ func TestProposeBlock_UsePendingDeposits(t *testing.T) {
|
||||
gomock.Eq(&ptypes.Empty{}),
|
||||
).Return(&pb.PendingDepositsResponse{
|
||||
PendingDeposits: []*pbp2p.Deposit{
|
||||
&pbp2p.Deposit{DepositData: []byte{'D', 'A', 'T', 'A'}},
|
||||
{DepositData: []byte{'D', 'A', 'T', 'A'}},
|
||||
},
|
||||
}, nil /*err*/)
|
||||
|
||||
|
||||
50
validator/internal/attester_service_mock.go
generated
50
validator/internal/attester_service_mock.go
generated
@@ -1,7 +1,6 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1 (interfaces: AttesterServiceClient)
|
||||
|
||||
// Package internal is a generated GoMock package.
|
||||
package internal
|
||||
|
||||
import (
|
||||
@@ -9,7 +8,8 @@ import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
v1 "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
v1 "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
v10 "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@@ -37,19 +37,61 @@ func (m *MockAttesterServiceClient) EXPECT() *MockAttesterServiceClientMockRecor
|
||||
}
|
||||
|
||||
// AttestHead mocks base method
|
||||
func (m *MockAttesterServiceClient) AttestHead(arg0 context.Context, arg1 *v1.AttestRequest, arg2 ...grpc.CallOption) (*v1.AttestResponse, error) {
|
||||
func (m *MockAttesterServiceClient) AttestHead(arg0 context.Context, arg1 *v1.Attestation, arg2 ...grpc.CallOption) (*v10.AttestResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "AttestHead", varargs...)
|
||||
ret0, _ := ret[0].(*v1.AttestResponse)
|
||||
ret0, _ := ret[0].(*v10.AttestResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AttestHead indicates an expected call of AttestHead
|
||||
func (mr *MockAttesterServiceClientMockRecorder) AttestHead(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]interface{}{arg0, arg1}, arg2...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AttestHead", reflect.TypeOf((*MockAttesterServiceClient)(nil).AttestHead), varargs...)
|
||||
}
|
||||
|
||||
// AttestationInfoAtSlot mocks base method
|
||||
func (m *MockAttesterServiceClient) AttestationInfoAtSlot(arg0 context.Context, arg1 *v10.AttestationInfoRequest, arg2 ...grpc.CallOption) (*v10.AttestationInfoResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "AttestationInfoAtSlot", varargs...)
|
||||
ret0, _ := ret[0].(*v10.AttestationInfoResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AttestationInfoAtSlot indicates an expected call of AttestationInfoAtSlot
|
||||
func (mr *MockAttesterServiceClientMockRecorder) AttestationInfoAtSlot(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]interface{}{arg0, arg1}, arg2...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AttestationInfoAtSlot", reflect.TypeOf((*MockAttesterServiceClient)(nil).AttestationInfoAtSlot), varargs...)
|
||||
}
|
||||
|
||||
// CrosslinkCommitteesAtSlot mocks base method
|
||||
func (m *MockAttesterServiceClient) CrosslinkCommitteesAtSlot(arg0 context.Context, arg1 *v10.CrosslinkCommitteeRequest, arg2 ...grpc.CallOption) (*v10.CrosslinkCommitteeResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "CrosslinkCommitteesAtSlot", varargs...)
|
||||
ret0, _ := ret[0].(*v10.CrosslinkCommitteeResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CrosslinkCommitteesAtSlot indicates an expected call of CrosslinkCommitteesAtSlot
|
||||
func (mr *MockAttesterServiceClientMockRecorder) CrosslinkCommitteesAtSlot(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]interface{}{arg0, arg1}, arg2...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrosslinkCommitteesAtSlot", reflect.TypeOf((*MockAttesterServiceClient)(nil).CrosslinkCommitteesAtSlot), varargs...)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/validator/types"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/x-cray/logrus-prefixed-formatter"
|
||||
prefixed "github.com/x-cray/logrus-prefixed-formatter"
|
||||
)
|
||||
|
||||
func startNode(ctx *cli.Context) error {
|
||||
|
||||
@@ -1,34 +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/proposer",
|
||||
visibility = ["//validator:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/beacon/rpc/v1:go_default_library",
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/hashutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = ["service_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/beacon/rpc/v1:go_default_library",
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//validator/internal: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",
|
||||
],
|
||||
)
|
||||
@@ -1,277 +0,0 @@
|
||||
// Package proposer defines all relevant functionality for a Proposer actor
|
||||
// within Ethereum Serenity.
|
||||
package proposer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
"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/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var log = logrus.WithField("prefix", "proposer")
|
||||
|
||||
type rpcClientService interface {
|
||||
ProposerServiceClient() pb.ProposerServiceClient
|
||||
}
|
||||
|
||||
type beaconClientService interface {
|
||||
ProposerAssignmentFeed() *event.Feed
|
||||
}
|
||||
|
||||
type rpcAttestationService interface {
|
||||
ProcessedAttestationFeed() *event.Feed
|
||||
}
|
||||
|
||||
// Proposer holds functionality required to run a block proposer
|
||||
// in Ethereum Serenity. Must satisfy the Service interface defined in
|
||||
// sharding/service.go.
|
||||
type Proposer struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
beaconService beaconClientService
|
||||
rpcClientService rpcClientService
|
||||
assignmentChan chan *pbp2p.BeaconBlock
|
||||
attestationService rpcAttestationService
|
||||
attestationChan chan *pbp2p.Attestation
|
||||
pendingAttestation []*pbp2p.Attestation
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Config options for proposer service.
|
||||
type Config struct {
|
||||
AssignmentBuf int
|
||||
AttestationBufferSize int
|
||||
Assigner beaconClientService
|
||||
AttesterFeed rpcAttestationService
|
||||
Client rpcClientService
|
||||
}
|
||||
|
||||
// NewProposer creates a new attester instance.
|
||||
func NewProposer(ctx context.Context, cfg *Config) *Proposer {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
return &Proposer{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
beaconService: cfg.Assigner,
|
||||
rpcClientService: cfg.Client,
|
||||
attestationService: cfg.AttesterFeed,
|
||||
assignmentChan: make(chan *pbp2p.BeaconBlock, cfg.AssignmentBuf),
|
||||
attestationChan: make(chan *pbp2p.Attestation, cfg.AttestationBufferSize),
|
||||
pendingAttestation: make([]*pbp2p.Attestation, 0),
|
||||
lock: sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// Start the main routine for a proposer.
|
||||
func (p *Proposer) Start() {
|
||||
log.Info("Starting service")
|
||||
client := p.rpcClientService.ProposerServiceClient()
|
||||
|
||||
go p.run(p.ctx.Done(), client)
|
||||
go p.processAttestation(p.ctx.Done())
|
||||
}
|
||||
|
||||
// Stop the main loop.
|
||||
func (p *Proposer) Stop() error {
|
||||
defer p.cancel()
|
||||
log.Info("Stopping service")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status always returns nil.
|
||||
// This service will be rewritten in the future so this service check is a
|
||||
// no-op for now.
|
||||
func (p *Proposer) Status() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DoesAttestationExist checks if an attester has already attested to a block.
|
||||
func (p *Proposer) DoesAttestationExist(attestation *pbp2p.Attestation) bool {
|
||||
exists := false
|
||||
for _, record := range p.pendingAttestation {
|
||||
if bytes.Equal(record.ParticipationBitfield, attestation.ParticipationBitfield) {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return exists
|
||||
}
|
||||
|
||||
// AddPendingAttestation adds a pending attestation to the memory so that it can be included
|
||||
// in the next proposed block.
|
||||
func (p *Proposer) AddPendingAttestation(attestation *pbp2p.Attestation) {
|
||||
p.pendingAttestation = append(p.pendingAttestation, attestation)
|
||||
}
|
||||
|
||||
// AggregateAllSignatures aggregates all the signatures of the attesters. This is currently a
|
||||
// stub for now till BLS/other signature schemes are implemented.
|
||||
func (p *Proposer) AggregateAllSignatures(attestations []*pbp2p.Attestation) []uint32 {
|
||||
// TODO(#258): Implement Signature Aggregation.
|
||||
return []uint32{}
|
||||
}
|
||||
|
||||
// GenerateBitmask creates the attestation bitmask from all the attester bitfields in the
|
||||
// attestation records.
|
||||
func (p *Proposer) GenerateBitmask(attestations []*pbp2p.Attestation) []byte {
|
||||
// TODO(#258): Implement bitmask where all attesters bitfields are aggregated.
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
// processAttestation processes incoming broadcasted attestations from the beacon node.
|
||||
func (p *Proposer) processAttestation(done <-chan struct{}) {
|
||||
attestationSub := p.attestationService.ProcessedAttestationFeed().Subscribe(p.attestationChan)
|
||||
defer attestationSub.Unsubscribe()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
log.Debug("Proposer context closed, exiting goroutine")
|
||||
return
|
||||
case attestationRecord := <-p.attestationChan:
|
||||
attestationExists := p.DoesAttestationExist(attestationRecord)
|
||||
if !attestationExists {
|
||||
p.AddPendingAttestation(attestationRecord)
|
||||
log.Info("Attestation stored in memory")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// run the main event loop that listens for a proposer assignment.
|
||||
func (p *Proposer) run(done <-chan struct{}, client pb.ProposerServiceClient) {
|
||||
sub := p.beaconService.ProposerAssignmentFeed().Subscribe(p.assignmentChan)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
log.Debug("Proposer context closed, exiting goroutine")
|
||||
return
|
||||
// When we receive an assignment on a slot, we leverage the fields
|
||||
// from the latest canonical beacon block to perform a proposal responsibility.
|
||||
case latestBeaconBlock := <-p.assignmentChan:
|
||||
p.receiveAssignment(latestBeaconBlock, client)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// receiveAssignment responds to the latest proposer assignment that the validator has received from the beacon
|
||||
// node. It handles all the core proposal logic for the validator client, from creating the block to be proposed,
|
||||
// to the signing of the proposal data and ultimately sending the block proposal to the beacon node.
|
||||
func (p *Proposer) receiveAssignment(latestBeaconBlock *pbp2p.BeaconBlock, client pb.ProposerServiceClient) {
|
||||
log.Info("Performing proposer responsibility")
|
||||
|
||||
block, err := p.computeBlockToBeProposed(latestBeaconBlock, client)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
proposalData, err := p.createProposalDataFromBlock(block)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
signature := p.signProposalData(proposalData)
|
||||
block.Signature[0] = signature[:]
|
||||
|
||||
hash, err := client.ProposeBlock(p.ctx, block)
|
||||
if err != nil {
|
||||
log.Errorf("Could not propose block %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("Successfully proposed block with hash %#x", hash.BlockHash)
|
||||
}
|
||||
|
||||
func (p *Proposer) computeBlockToBeProposed(latestBlock *pbp2p.BeaconBlock,
|
||||
client pb.ProposerServiceClient) (*pbp2p.BeaconBlock, error) {
|
||||
// Extract the hash of the latest beacon block to use as parent hash in
|
||||
// the proposal.
|
||||
if latestBlock == nil {
|
||||
return nil, fmt.Errorf("could not marshal nil latest beacon block")
|
||||
|
||||
}
|
||||
|
||||
latestBlockHash, err := hashutil.HashBeaconBlock(latestBlock)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not hash latest beacon block: %v", err)
|
||||
}
|
||||
|
||||
indexRes, err := client.ProposerIndex(p.ctx, &pb.ProposerIndexRequest{SlotNumber: latestBlock.Slot})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get proposer index: %v", err)
|
||||
}
|
||||
|
||||
proposerBitfield := uint64(math.Pow(2, 7-float64(indexRes.Index)))
|
||||
attestation := &pbp2p.Attestation{
|
||||
ParticipationBitfield: []byte{byte(proposerBitfield)},
|
||||
}
|
||||
|
||||
// To prevent any unaccounted attestations from being added.
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
signature := make([][]byte, 48)
|
||||
block := &pbp2p.BeaconBlock{
|
||||
Slot: latestBlock.Slot + 1,
|
||||
ParentRootHash32: latestBlockHash[:],
|
||||
RandaoRevealHash32: []byte{},
|
||||
Body: &pbp2p.BeaconBlockBody{
|
||||
Attestations: []*pbp2p.Attestation{attestation},
|
||||
},
|
||||
Signature: signature,
|
||||
}
|
||||
|
||||
block, err = p.addStateRootToBlock(block, client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Infof("Created block proposal for slot %d", block.Slot)
|
||||
p.pendingAttestation = nil
|
||||
|
||||
return block, nil
|
||||
}
|
||||
|
||||
func (p *Proposer) addStateRootToBlock(block *pbp2p.BeaconBlock, client pb.ProposerServiceClient) (*pbp2p.BeaconBlock, error) {
|
||||
res, err := client.ComputeStateRoot(p.ctx, block)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to compute state root for block: %v", err)
|
||||
}
|
||||
|
||||
block.StateRootHash32 = res.StateRoot
|
||||
|
||||
return block, nil
|
||||
}
|
||||
|
||||
func (p *Proposer) createProposalDataFromBlock(block *pbp2p.BeaconBlock) (*pbp2p.ProposalSignedData, error) {
|
||||
encodedBlock, err := proto.Marshal(block)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to marshal block %v", err)
|
||||
}
|
||||
|
||||
blockHash := hashutil.Hash(encodedBlock)
|
||||
|
||||
return &pbp2p.ProposalSignedData{
|
||||
Slot: block.Slot,
|
||||
Shard: params.BeaconConfig().BeaconChainShardNumber, // placeholder
|
||||
BlockRootHash32: blockHash[:],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Proposer) signProposalData(data *pbp2p.ProposalSignedData) [32]byte {
|
||||
return [32]byte{'S', 'I', 'G', 'N', 'A', 'T', 'U', 'R', 'E'}
|
||||
}
|
||||
@@ -1,368 +0,0 @@
|
||||
package proposer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/validator/internal"
|
||||
"github.com/sirupsen/logrus"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetOutput(ioutil.Discard)
|
||||
}
|
||||
|
||||
type mockClient struct {
|
||||
ctrl *gomock.Controller
|
||||
}
|
||||
|
||||
func (mc *mockClient) ProposerServiceClient() pb.ProposerServiceClient {
|
||||
return internal.NewMockProposerServiceClient(mc.ctrl)
|
||||
}
|
||||
|
||||
type mockAssigner struct{}
|
||||
|
||||
func (m *mockAssigner) ProposerAssignmentFeed() *event.Feed {
|
||||
return new(event.Feed)
|
||||
}
|
||||
|
||||
type mockAttesterFeed struct{}
|
||||
|
||||
func (m *mockAttesterFeed) ProcessedAttestationFeed() *event.Feed {
|
||||
return new(event.Feed)
|
||||
}
|
||||
|
||||
func TestDoesAttestationExist(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
cfg := &Config{
|
||||
AssignmentBuf: 0,
|
||||
Assigner: &mockAssigner{},
|
||||
Client: &mockClient{ctrl},
|
||||
}
|
||||
p := NewProposer(context.Background(), cfg)
|
||||
|
||||
p.pendingAttestation = []*pbp2p.Attestation{
|
||||
{
|
||||
ParticipationBitfield: []byte{'a'},
|
||||
},
|
||||
{
|
||||
ParticipationBitfield: []byte{'b'},
|
||||
},
|
||||
{
|
||||
ParticipationBitfield: []byte{'c'},
|
||||
},
|
||||
{
|
||||
ParticipationBitfield: []byte{'d'},
|
||||
}}
|
||||
|
||||
fakeAttestation := &pbp2p.Attestation{
|
||||
ParticipationBitfield: []byte{'e'},
|
||||
}
|
||||
|
||||
realAttestation := &pbp2p.Attestation{
|
||||
ParticipationBitfield: []byte{'a'},
|
||||
}
|
||||
|
||||
if p.DoesAttestationExist(fakeAttestation) {
|
||||
t.Fatal("invalid attestation exists")
|
||||
}
|
||||
|
||||
if !p.DoesAttestationExist(realAttestation) {
|
||||
t.Fatal("valid attestation does not exists")
|
||||
}
|
||||
|
||||
}
|
||||
func TestLifecycle(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
cfg := &Config{
|
||||
AssignmentBuf: 0,
|
||||
Assigner: &mockAssigner{},
|
||||
Client: &mockClient{ctrl},
|
||||
AttesterFeed: &mockAttesterFeed{},
|
||||
}
|
||||
p := NewProposer(context.Background(), cfg)
|
||||
p.Start()
|
||||
p.Stop()
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Starting service")
|
||||
testutil.AssertLogsContain(t, hook, "Stopping service")
|
||||
}
|
||||
|
||||
func TestProposerComputeBlock(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
cfg := &Config{
|
||||
AssignmentBuf: 0,
|
||||
Assigner: &mockAssigner{},
|
||||
Client: &mockClient{ctrl},
|
||||
AttesterFeed: &mockAttesterFeed{},
|
||||
}
|
||||
p := NewProposer(context.Background(), cfg)
|
||||
|
||||
mockServiceClient := internal.NewMockProposerServiceClient(ctrl)
|
||||
|
||||
mockServiceClient.EXPECT().ProposerIndex(
|
||||
gomock.Any(),
|
||||
gomock.Any()).Return(
|
||||
&pb.ProposerIndexResponse{
|
||||
Index: 2,
|
||||
}, nil)
|
||||
|
||||
mockServiceClient.EXPECT().ComputeStateRoot(
|
||||
gomock.Any(),
|
||||
gomock.Any()).Return(
|
||||
&pb.StateRootResponse{
|
||||
StateRoot: []byte("test"),
|
||||
}, nil)
|
||||
|
||||
mockServiceClient.EXPECT().ProposeBlock(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(&pb.ProposeResponse{
|
||||
BlockHash: []byte("hi"),
|
||||
}, nil)
|
||||
|
||||
doneChan := make(chan struct{})
|
||||
exitRoutine := make(chan bool)
|
||||
|
||||
go func() {
|
||||
p.run(doneChan, mockServiceClient)
|
||||
<-exitRoutine
|
||||
}()
|
||||
p.assignmentChan <- &pbp2p.BeaconBlock{Slot: 5}
|
||||
doneChan <- struct{}{}
|
||||
exitRoutine <- true
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Performing proposer responsibility")
|
||||
testutil.AssertLogsContain(t, hook, fmt.Sprintf("Created block proposal for slot %d", 6))
|
||||
testutil.AssertLogsContain(t, hook, "Proposer context closed")
|
||||
}
|
||||
|
||||
func TestProposerProcessAttestation(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
cfg := &Config{
|
||||
AssignmentBuf: 0,
|
||||
Assigner: &mockAssigner{},
|
||||
Client: &mockClient{ctrl},
|
||||
AttesterFeed: &mockAttesterFeed{},
|
||||
}
|
||||
p := NewProposer(context.Background(), cfg)
|
||||
|
||||
doneChan := make(chan struct{})
|
||||
exitRoutine := make(chan bool)
|
||||
|
||||
go func() {
|
||||
p.processAttestation(doneChan)
|
||||
<-exitRoutine
|
||||
}()
|
||||
p.pendingAttestation = []*pbp2p.Attestation{
|
||||
{
|
||||
ParticipationBitfield: []byte{'a'},
|
||||
},
|
||||
{
|
||||
ParticipationBitfield: []byte{'b'},
|
||||
}}
|
||||
|
||||
attestation := &pbp2p.Attestation{ParticipationBitfield: []byte{'c'}}
|
||||
p.attestationChan <- attestation
|
||||
|
||||
doneChan <- struct{}{}
|
||||
exitRoutine <- true
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Attestation stored in memory")
|
||||
testutil.AssertLogsContain(t, hook, "Proposer context closed")
|
||||
|
||||
if !bytes.Equal(p.pendingAttestation[2].ParticipationBitfield, []byte{'c'}) {
|
||||
t.Errorf("attestation was unable to be saved %v", p.pendingAttestation[2].ParticipationBitfield)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFullProposalOfBlock(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
cfg := &Config{
|
||||
AssignmentBuf: 0,
|
||||
Assigner: &mockAssigner{},
|
||||
Client: &mockClient{ctrl},
|
||||
AttesterFeed: &mockAttesterFeed{},
|
||||
}
|
||||
p := NewProposer(context.Background(), cfg)
|
||||
mockServiceClient := internal.NewMockProposerServiceClient(ctrl)
|
||||
mockServiceClient.EXPECT().ProposerIndex(
|
||||
gomock.Any(),
|
||||
gomock.Any()).Return(
|
||||
&pb.ProposerIndexResponse{
|
||||
Index: 2,
|
||||
}, nil)
|
||||
|
||||
mockServiceClient.EXPECT().ComputeStateRoot(
|
||||
gomock.Any(),
|
||||
gomock.Any()).Return(
|
||||
&pb.StateRootResponse{
|
||||
StateRoot: []byte("test"),
|
||||
}, nil)
|
||||
|
||||
mockServiceClient.EXPECT().ProposeBlock(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(&pb.ProposeResponse{
|
||||
BlockHash: []byte("hi"),
|
||||
}, nil)
|
||||
|
||||
doneChan := make(chan struct{})
|
||||
exitRoutine := make(chan bool)
|
||||
|
||||
go p.run(doneChan, mockServiceClient)
|
||||
|
||||
go func() {
|
||||
p.processAttestation(doneChan)
|
||||
<-exitRoutine
|
||||
}()
|
||||
|
||||
p.pendingAttestation = []*pbp2p.Attestation{
|
||||
{
|
||||
ParticipationBitfield: []byte{'a'},
|
||||
},
|
||||
{
|
||||
ParticipationBitfield: []byte{'b'},
|
||||
}}
|
||||
|
||||
attestation := &pbp2p.Attestation{ParticipationBitfield: []byte{'c'}}
|
||||
p.attestationChan <- attestation
|
||||
|
||||
p.assignmentChan <- &pbp2p.BeaconBlock{Slot: 5}
|
||||
|
||||
doneChan <- struct{}{}
|
||||
doneChan <- struct{}{}
|
||||
exitRoutine <- true
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Performing proposer responsibility")
|
||||
testutil.AssertLogsContain(t, hook, fmt.Sprintf("Created block proposal for slot %d", 6))
|
||||
testutil.AssertLogsContain(t, hook, fmt.Sprintf("Successfully proposed block with hash %#x", []byte("hi")))
|
||||
testutil.AssertLogsContain(t, hook, "Proposer context closed")
|
||||
testutil.AssertLogsContain(t, hook, "Attestation stored in memory")
|
||||
testutil.AssertLogsContain(t, hook, "Proposer context closed")
|
||||
|
||||
}
|
||||
|
||||
func TestProposerServiceErrors(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
cfg := &Config{
|
||||
AssignmentBuf: 0,
|
||||
Assigner: &mockAssigner{},
|
||||
Client: &mockClient{ctrl},
|
||||
AttesterFeed: &mockAttesterFeed{},
|
||||
}
|
||||
p := NewProposer(context.Background(), cfg)
|
||||
|
||||
mockServiceClient := internal.NewMockProposerServiceClient(ctrl)
|
||||
|
||||
mockServiceClient.EXPECT().ProposerIndex(
|
||||
gomock.Any(),
|
||||
gomock.Any()).Return(
|
||||
&pb.ProposerIndexResponse{
|
||||
Index: 2,
|
||||
}, nil)
|
||||
// Expect call to throw an error
|
||||
mockServiceClient.EXPECT().ComputeStateRoot(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(nil, errors.New("could not hash state"))
|
||||
|
||||
doneChan := make(chan struct{})
|
||||
exitRoutine := make(chan bool)
|
||||
|
||||
go p.run(doneChan, mockServiceClient)
|
||||
|
||||
go func() {
|
||||
p.processAttestation(doneChan)
|
||||
<-exitRoutine
|
||||
}()
|
||||
|
||||
p.attestationChan <- &pbp2p.Attestation{}
|
||||
p.assignmentChan <- nil
|
||||
p.assignmentChan <- &pbp2p.BeaconBlock{Slot: 9}
|
||||
|
||||
doneChan <- struct{}{}
|
||||
doneChan <- struct{}{}
|
||||
exitRoutine <- true
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Performing proposer responsibility")
|
||||
testutil.AssertLogsContain(t, hook, "could not marshal nil latest beacon block")
|
||||
testutil.AssertLogsContain(t, hook, "Proposer context closed")
|
||||
testutil.AssertLogsContain(t, hook, "unable to compute state root for block: could not hash state")
|
||||
}
|
||||
|
||||
func TestProposedBlockError(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
cfg := &Config{
|
||||
AssignmentBuf: 0,
|
||||
Assigner: &mockAssigner{},
|
||||
Client: &mockClient{ctrl},
|
||||
AttesterFeed: &mockAttesterFeed{},
|
||||
}
|
||||
p := NewProposer(context.Background(), cfg)
|
||||
|
||||
mockServiceClient := internal.NewMockProposerServiceClient(ctrl)
|
||||
mockServiceClient.EXPECT().ProposerIndex(
|
||||
gomock.Any(),
|
||||
gomock.Any()).Return(
|
||||
&pb.ProposerIndexResponse{
|
||||
Index: 2,
|
||||
}, nil)
|
||||
|
||||
mockServiceClient.EXPECT().ComputeStateRoot(
|
||||
gomock.Any(),
|
||||
gomock.Any()).Return(
|
||||
&pb.StateRootResponse{
|
||||
StateRoot: []byte("test"),
|
||||
}, nil)
|
||||
|
||||
// Expect call to throw an error.
|
||||
mockServiceClient.EXPECT().ProposeBlock(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(nil, errors.New("bad block proposed"))
|
||||
|
||||
doneChan := make(chan struct{})
|
||||
exitRoutine := make(chan bool)
|
||||
|
||||
go p.run(doneChan, mockServiceClient)
|
||||
|
||||
go func() {
|
||||
p.processAttestation(doneChan)
|
||||
<-exitRoutine
|
||||
}()
|
||||
|
||||
p.assignmentChan <- &pbp2p.BeaconBlock{Slot: 9}
|
||||
|
||||
doneChan <- struct{}{}
|
||||
doneChan <- struct{}{}
|
||||
exitRoutine <- true
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Performing proposer responsibility")
|
||||
testutil.AssertLogsContain(t, hook, "Proposer context closed")
|
||||
testutil.AssertLogsContain(t, hook, "Could not propose block bad block proposed")
|
||||
}
|
||||
Reference in New Issue
Block a user