Use lowest included slot for precompute (#3805)

* Fix attestations

* Fix new

* Testing state transition

* Fix

* Runtime works
This commit is contained in:
terence tsao 2019-10-18 21:47:54 -07:00 committed by GitHub
parent 23be8419fe
commit 1433fab0d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 17 deletions

View File

@ -40,7 +40,13 @@ func ProcessAttestations(
if err != nil {
return nil, nil, err
}
vp = UpdateValidator(vp, v, indices, a)
// Get attestation slot to find lowest inclusion delayed attestation for each attested validators.
aSlot, err := helpers.AttestationDataSlot(state, a.Data)
if err != nil {
return nil, nil, err
}
vp = UpdateValidator(vp, v, indices, a, aSlot)
}
bp = UpdateBalance(vp, bp)
@ -121,7 +127,9 @@ func SameHead(state *pb.BeaconState, a *pb.PendingAttestation) (bool, error) {
}
// UpdateValidator updates pre computed validator store.
func UpdateValidator(vp []*Validator, record *Validator, indices []uint64, a *pb.PendingAttestation) []*Validator {
func UpdateValidator(vp []*Validator, record *Validator, indices []uint64, a *pb.PendingAttestation, aSlot uint64) []*Validator {
inclusionSlot := aSlot + a.InclusionDelay
for _, i := range indices {
if record.IsCurrentEpochAttester {
vp[i].IsCurrentEpochAttester = true
@ -138,8 +146,13 @@ func UpdateValidator(vp []*Validator, record *Validator, indices []uint64, a *pb
if record.IsPrevEpochHeadAttester {
vp[i].IsPrevEpochHeadAttester = true
}
vp[i].InclusionDistance = a.InclusionDelay
vp[i].ProposerIndex = a.ProposerIndex
// Update attestation inclusion info if inclusion slot is lower than before
if inclusionSlot < vp[i].InclusionSlot {
vp[i].InclusionSlot = aSlot + a.InclusionDelay
vp[i].InclusionDistance = a.InclusionDelay
vp[i].ProposerIndex = a.ProposerIndex
}
}
return vp
}

View File

@ -15,16 +15,18 @@ import (
)
func TestUpdateValidator(t *testing.T) {
vp := []*precompute.Validator{{}, {}, {}, {}, {}, {}}
e := params.BeaconConfig().FarFutureEpoch
vp := []*precompute.Validator{{}, {InclusionSlot:e}, {}, {InclusionSlot:e}, {}, {InclusionSlot:e}}
record := &precompute.Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true,
IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, IsPrevEpochHeadAttester: true}
a := &pb.PendingAttestation{InclusionDelay: 1, ProposerIndex: 2}
// Indices 1 3 and 5 attested
vp = precompute.UpdateValidator(vp, record, []uint64{1, 3, 5}, a)
vp = precompute.UpdateValidator(vp, record, []uint64{1, 3, 5}, a, 100)
wanted := &precompute.Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true,
IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, IsPrevEpochHeadAttester: true, ProposerIndex: 2, InclusionDistance: 1}
IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, IsPrevEpochHeadAttester: true,
ProposerIndex: 2, InclusionDistance: 1, InclusionSlot: 101}
wantedVp := []*precompute.Validator{{}, wanted, {}, wanted, {}, wanted}
if !reflect.DeepEqual(vp, wantedVp) {
t.Error("Incorrect attesting validator calculations")

View File

@ -5,6 +5,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
@ -39,6 +40,11 @@ func New(ctx context.Context, state *pb.BeaconState) ([]*Validator, *Balance) {
p.IsActivePrevEpoch = true
bp.PrevEpoch += v.EffectiveBalance
}
// Set inclusion slot and inclusion distance to be max, they will be compared and replaced
// with the lower values
p.InclusionSlot = params.BeaconConfig().FarFutureEpoch
p.InclusionDistance = params.BeaconConfig().FarFutureEpoch
vp[i] = p
}
return vp, bp

View File

@ -26,17 +26,22 @@ func TestNew(t *testing.T) {
{WithdrawableEpoch: ffe, ExitEpoch: 1, EffectiveBalance: 100},
},
}
e := params.BeaconConfig().FarFutureEpoch
v, b := precompute.New(context.Background(), s)
if !reflect.DeepEqual(v[0], &precompute.Validator{IsSlashed: true, CurrentEpochEffectiveBalance: 100}) {
if !reflect.DeepEqual(v[0], &precompute.Validator{IsSlashed: true, CurrentEpochEffectiveBalance: 100,
InclusionDistance: e, InclusionSlot: e}) {
t.Error("Incorrect validator 0 status")
}
if !reflect.DeepEqual(v[1], &precompute.Validator{IsWithdrawableCurrentEpoch: true, CurrentEpochEffectiveBalance: 100}) {
if !reflect.DeepEqual(v[1], &precompute.Validator{IsWithdrawableCurrentEpoch: true, CurrentEpochEffectiveBalance: 100,
InclusionDistance: e, InclusionSlot: e}) {
t.Error("Incorrect validator 1 status")
}
if !reflect.DeepEqual(v[2], &precompute.Validator{IsActiveCurrentEpoch: true, IsActivePrevEpoch: true, CurrentEpochEffectiveBalance: 100}) {
if !reflect.DeepEqual(v[2], &precompute.Validator{IsActiveCurrentEpoch: true, IsActivePrevEpoch: true,
CurrentEpochEffectiveBalance: 100, InclusionDistance: e, InclusionSlot: e}) {
t.Error("Incorrect validator 2 status")
}
if !reflect.DeepEqual(v[3], &precompute.Validator{IsActivePrevEpoch: true, CurrentEpochEffectiveBalance: 100}) {
if !reflect.DeepEqual(v[3], &precompute.Validator{IsActivePrevEpoch: true, CurrentEpochEffectiveBalance: 100,
InclusionDistance: e, InclusionSlot: e}) {
t.Error("Incorrect validator 3 status")
}

View File

@ -108,12 +108,12 @@ func proposerDeltaPrecompute(state *pb.BeaconState, bp *Balance, vp []*Validator
totalBalance := bp.CurrentEpoch
for i, v := range vp {
for _, v := range vp {
if v.IsPrevEpochAttester {
vBalance := v.CurrentEpochEffectiveBalance
baseReward := vBalance * params.BeaconConfig().BaseRewardFactor / mathutil.IntegerSquareRoot(totalBalance) / params.BeaconConfig().BaseRewardsPerEpoch
proposerReward := baseReward / params.BeaconConfig().ProposerRewardQuotient
rewards[i] += proposerReward
rewards[v.ProposerIndex] += proposerReward
}
}
return rewards, nil

View File

@ -55,15 +55,15 @@ func TestProcessRewardsAndPenaltiesPrecompute(t *testing.T) {
t.Fatal(err)
}
// Indices that voted
wanted := uint64(32000001776)
// Indices that voted everything except for head, lost a bit money
wanted := uint64(31999995452)
if state.Balances[4] != wanted {
t.Errorf("wanted balance: %d, got: %d",
wanted, state.Balances[4])
}
// Indices that did not vote - lose money
wanted = uint64(31999797616)
// Indices that did not vote, lost more money
wanted = uint64(31999949392)
if state.Balances[0] != wanted {
t.Errorf("wanted balance: %d, got: %d",
wanted, state.Balances[0])

View File

@ -25,6 +25,8 @@ type Validator struct {
// CurrentEpochEffectiveBalance is how much effective balance this validator validator has current epoch.
CurrentEpochEffectiveBalance uint64
// InclusionSlot is the slot of when the attestation gets included in the chain.
InclusionSlot uint64
// InclusionDistance is the distance between the assigned slot and this validator's attestation was included in block.
InclusionDistance uint64
// ProposerIndex is the index of proposer at slot where this validator's attestation was included.