Use Map for Inclusion Distance in EpochProcessing (#2346)

This commit is contained in:
Raul Jordan 2019-04-22 19:08:20 -05:00 committed by terence tsao
parent cda3f178cb
commit cfd3e548cd
4 changed files with 36 additions and 84 deletions

View File

@ -139,9 +139,9 @@ func InclusionDistance(
baseRewardQuotient := helpers.BaseRewardQuotient(totalBalance)
for _, index := range attesterIndices {
inclusionDistance, err := epoch.InclusionDistance(state, index)
inclusionDistance, err := blocks.AttsInclusionDistance(index)
if err != nil {
return nil, fmt.Errorf("could not get inclusion distance: %v", err)
return nil, err
}
if inclusionDistance == 0 {
return nil, errors.New("could not process inclusion distance: 0")
@ -266,9 +266,9 @@ func InactivityInclusionDistance(
baseRewardQuotient := helpers.BaseRewardQuotient(totalBalance)
for _, index := range attesterIndices {
inclusionDistance, err := epoch.InclusionDistance(state, index)
inclusionDistance, err := blocks.AttsInclusionDistance(index)
if err != nil {
return nil, fmt.Errorf("could not get inclusion distance: %v", err)
return nil, err
}
baseReward := helpers.BaseReward(state, index, baseRewardQuotient)
state.ValidatorBalances[index] -= baseReward -

View File

@ -140,10 +140,16 @@ func TestInclusionDistRewards_AccurateRewards(t *testing.T) {
participationBitfield = append(participationBitfield, byte(0xff))
}
attestation := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: params.BeaconConfig().GenesisSlot},
attestations := []*pb.PendingAttestation{
{Data: &pb.AttestationData{
Slot: params.BeaconConfig().GenesisSlot,
JustifiedBlockRootHash32: []byte{},
Shard: 0,
CrosslinkDataRootHash32: params.BeaconConfig().ZeroHash[:],
},
AggregationBitfield: participationBitfield,
InclusionSlot: params.BeaconConfig().GenesisSlot + 5},
InclusionSlot: params.BeaconConfig().GenesisSlot + 5,
},
}
tests := []struct {
@ -158,10 +164,29 @@ func TestInclusionDistRewards_AccurateRewards(t *testing.T) {
validatorBalances[i] = params.BeaconConfig().MaxDepositAmount
}
state := &pb.BeaconState{
Slot: params.BeaconConfig().GenesisSlot,
ValidatorRegistry: validators,
ValidatorBalances: validatorBalances,
LatestAttestations: attestation,
Slot: params.BeaconConfig().GenesisSlot + 5,
ValidatorRegistry: validators,
ValidatorBalances: validatorBalances,
LatestAttestations: attestations,
PreviousJustifiedRoot: []byte{},
LatestCrosslinks: []*pb.Crosslink{
{
CrosslinkDataRootHash32: params.BeaconConfig().ZeroHash[:],
Epoch: params.BeaconConfig().GenesisEpoch,
},
},
}
block := &pb.BeaconBlock{
Body: &pb.BeaconBlockBody{
Attestations: []*pb.Attestation{
{
Data: attestations[0].Data,
},
},
},
}
if _, err := blocks.ProcessBlockAttestations(state, block, false /* verify sig */); err != nil {
t.Fatal(err)
}
state, err := InclusionDistance(
state,

View File

@ -65,29 +65,6 @@ func InclusionSlot(state *pb.BeaconState, validatorIndex uint64) (uint64, error)
return lowestSlotIncluded, nil
}
// InclusionDistance returns the difference in slot number of when attestation
// gets submitted and when it gets included.
//
// Spec pseudocode definition:
// Let inclusion_distance(state, index) =
// a.slot_included - a.data.slot where a is the above attestation same as
// inclusion_slot.
func InclusionDistance(state *pb.BeaconState, validatorIndex uint64) (uint64, error) {
for _, attestation := range state.LatestAttestations {
participatedValidators, err := helpers.AttestationParticipants(state, attestation.Data, attestation.AggregationBitfield)
if err != nil {
return 0, fmt.Errorf("could not get attestation participants: %v", err)
}
for _, index := range participatedValidators {
if index == validatorIndex {
return attestation.InclusionSlot - attestation.Data.Slot, nil
}
}
}
return 0, fmt.Errorf("could not find inclusion distance for validator index %d", validatorIndex)
}
// AttestingValidators returns the validators of the winning root.
//
// Spec pseudocode definition:

View File

@ -254,53 +254,3 @@ func TestInclusionSlot_SlotNotFound(t *testing.T) {
t.Errorf("Expected %s, received %v", want, err)
}
}
func TestInclusionDistance_CorrectDistance(t *testing.T) {
state := buildState(params.BeaconConfig().GenesisSlot, params.BeaconConfig().DepositsForChainStart)
var participationBitfield []byte
for i := 0; i < 16; i++ {
participationBitfield = append(participationBitfield, byte(0xff))
}
state.LatestAttestations = []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: params.BeaconConfig().GenesisSlot},
AggregationBitfield: participationBitfield,
InclusionSlot: params.BeaconConfig().GenesisSlot + 100},
}
distance, err := InclusionDistance(state, 251)
if err != nil {
t.Fatalf("Could not execute InclusionDistance: %v", err)
}
// Inclusion distance is 100 because input validator index is 45,
// validator 45's attested slot 0 and got included slot 100.
if distance != 100 {
t.Errorf("Incorrect distance. Wanted: %d, got: %d",
100, distance)
}
}
func TestInclusionDistance_InvalidBitfield(t *testing.T) {
state := buildState(params.BeaconConfig().GenesisSlot, params.BeaconConfig().DepositsForChainStart)
state.LatestAttestations = []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: params.BeaconConfig().GenesisSlot},
AggregationBitfield: []byte{},
InclusionSlot: 100},
}
want := fmt.Sprintf("wanted participants bitfield length %d, got: %d", 16, 0)
if _, err := InclusionDistance(state, 0); !strings.Contains(err.Error(), want) {
t.Errorf("Expected %s, received %v", want, err)
}
}
func TestInclusionDistance_NotFound(t *testing.T) {
state := buildState(0, params.BeaconConfig().SlotsPerEpoch)
badIndex := uint64(10000)
want := fmt.Sprintf("could not find inclusion distance for validator index %d", badIndex)
if _, err := InclusionDistance(state, badIndex); !strings.Contains(err.Error(), want) {
t.Errorf("Expected %s, received %v", want, err)
}
}