mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 13:28:01 -05:00
Methods to precompute process_epoch records (#3788)
This commit is contained in:
@@ -1,8 +1,36 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["type.go"],
|
||||
srcs = [
|
||||
"attestation.go",
|
||||
"new.go",
|
||||
"type.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//shared/traceutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"attestation_test.go",
|
||||
"new_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
169
beacon-chain/core/epoch/precompute/attestation.go
Normal file
169
beacon-chain/core/epoch/precompute/attestation.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package precompute
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/traceutil"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// ProcessAttestations process the attestations in state and update individual validator's pre computes,
|
||||
// it also tracks and updates epoch attesting balances.
|
||||
func ProcessAttestations(
|
||||
ctx context.Context,
|
||||
state *pb.BeaconState,
|
||||
vp []*Validator,
|
||||
bp *Balance) ([]*Validator, *Balance, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "precomputeEpoch.ProcessAttestations")
|
||||
defer span.End()
|
||||
|
||||
v := &Validator{}
|
||||
var err error
|
||||
for _, a := range append(state.PreviousEpochAttestations, state.CurrentEpochAttestations...) {
|
||||
v.IsCurrentEpochAttester, v.IsCurrentEpochTargetAttester, err = attestedCurrentEpoch(state, a)
|
||||
if err != nil {
|
||||
traceutil.AnnotateError(span, err)
|
||||
return nil, nil, errors.Wrap(err, "could not check validator attested current epoch")
|
||||
}
|
||||
v.IsPrevEpochAttester, v.IsPrevEpochTargetAttester, v.IsPrevEpochHeadAttester, err = attestedPrevEpoch(state, a)
|
||||
if err != nil {
|
||||
traceutil.AnnotateError(span, err)
|
||||
return nil, nil, errors.Wrap(err, "could not check validator attested previous epoch")
|
||||
}
|
||||
|
||||
// Get attested indices and update the pre computed fields for each attested validators.
|
||||
indices, err := helpers.AttestingIndices(state, a.Data, a.AggregationBits)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
vp = updateValidator(vp, v, indices, a)
|
||||
}
|
||||
|
||||
bp = updateBalance(vp, bp)
|
||||
|
||||
return vp, bp, nil
|
||||
}
|
||||
|
||||
// Has attestation `a` attested once in current epoch and epoch boundary block.
|
||||
func attestedCurrentEpoch(s *pb.BeaconState, a *pb.PendingAttestation) (bool, bool, error) {
|
||||
currentEpoch := helpers.CurrentEpoch(s)
|
||||
var votedCurrentEpoch, votedTarget bool
|
||||
// Did validator vote current epoch.
|
||||
if a.Data.Target.Epoch == currentEpoch {
|
||||
votedCurrentEpoch = true
|
||||
same, err := sameTarget(s, a, currentEpoch)
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
if same {
|
||||
votedTarget = true
|
||||
}
|
||||
}
|
||||
return votedCurrentEpoch, votedTarget, nil
|
||||
}
|
||||
|
||||
// Has attestation `a` attested once in previous epoch and epoch boundary block and the same head.
|
||||
func attestedPrevEpoch(s *pb.BeaconState, a *pb.PendingAttestation) (bool, bool, bool, error) {
|
||||
prevEpoch := helpers.PrevEpoch(s)
|
||||
var votedPrevEpoch, votedTarget, votedHead bool
|
||||
// Did validator vote previous epoch.
|
||||
if a.Data.Target.Epoch == prevEpoch {
|
||||
votedPrevEpoch = true
|
||||
same, err := sameTarget(s, a, prevEpoch)
|
||||
if err != nil {
|
||||
return false, false, false, errors.Wrap(err, "could not check same target")
|
||||
}
|
||||
if same {
|
||||
votedTarget = true
|
||||
}
|
||||
|
||||
same, err = sameHead(s, a)
|
||||
if err != nil {
|
||||
return false, false, false, errors.Wrap(err, "could not check same head")
|
||||
}
|
||||
if same {
|
||||
votedHead = true
|
||||
}
|
||||
}
|
||||
return votedPrevEpoch, votedTarget, votedHead, nil
|
||||
}
|
||||
|
||||
// Has attestation `a` attested to the same target block in state.
|
||||
func sameTarget(state *pb.BeaconState, a *pb.PendingAttestation, e uint64) (bool, error) {
|
||||
r, err := helpers.BlockRoot(state, e)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if bytes.Equal(a.Data.Target.Root, r) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Has attestation `a` attested to the same block by attestation slot in state.
|
||||
func sameHead(state *pb.BeaconState, a *pb.PendingAttestation) (bool, error) {
|
||||
aSlot, err := helpers.AttestationDataSlot(state, a.Data)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
r, err := helpers.BlockRootAtSlot(state, aSlot)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if bytes.Equal(a.Data.BeaconBlockRoot, r) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// This updates pre computed validator store.
|
||||
func updateValidator(vp []*Validator, record *Validator, indices []uint64, a *pb.PendingAttestation) []*Validator {
|
||||
for _, i := range indices {
|
||||
if record.IsCurrentEpochAttester {
|
||||
vp[i].IsCurrentEpochAttester = true
|
||||
}
|
||||
if record.IsCurrentEpochTargetAttester {
|
||||
vp[i].IsCurrentEpochTargetAttester = true
|
||||
}
|
||||
if record.IsPrevEpochAttester {
|
||||
vp[i].IsPrevEpochAttester = true
|
||||
}
|
||||
if record.IsPrevEpochTargetAttester {
|
||||
vp[i].IsPrevEpochTargetAttester = true
|
||||
}
|
||||
if record.IsPrevEpochHeadAttester {
|
||||
vp[i].IsPrevEpochHeadAttester = true
|
||||
}
|
||||
vp[i].InclusionDistance = a.InclusionDelay
|
||||
vp[i].ProposerIndex = a.ProposerIndex
|
||||
}
|
||||
return vp
|
||||
}
|
||||
|
||||
// This updates pre computed balance store.
|
||||
func updateBalance(vp []*Validator, bp *Balance) *Balance {
|
||||
for _, v := range vp {
|
||||
if !v.IsSlashed {
|
||||
if v.IsCurrentEpochAttester {
|
||||
bp.CurrentEpochAttesters += v.CurrentEpochEffectiveBalance
|
||||
}
|
||||
if v.IsCurrentEpochTargetAttester {
|
||||
bp.CurrentEpochTargetAttesters += v.CurrentEpochEffectiveBalance
|
||||
}
|
||||
if v.IsPrevEpochAttester {
|
||||
bp.PrevEpochAttesters += v.CurrentEpochEffectiveBalance
|
||||
}
|
||||
if v.IsPrevEpochTargetAttester {
|
||||
bp.PrevEpochTargetAttesters += v.CurrentEpochEffectiveBalance
|
||||
}
|
||||
if v.IsPrevEpochHeadAttester {
|
||||
bp.PrevEpochHeadAttesters += v.CurrentEpochEffectiveBalance
|
||||
}
|
||||
}
|
||||
}
|
||||
return bp
|
||||
}
|
||||
242
beacon-chain/core/epoch/precompute/attestation_test.go
Normal file
242
beacon-chain/core/epoch/precompute/attestation_test.go
Normal file
@@ -0,0 +1,242 @@
|
||||
package precompute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
func TestUpdateValidator(t *testing.T) {
|
||||
vp := []*Validator{{}, {}, {}, {}, {}, {}}
|
||||
record := &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 = updateValidator(vp, record, []uint64{1, 3, 5}, a)
|
||||
|
||||
wanted := &Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true,
|
||||
IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, IsPrevEpochHeadAttester: true, ProposerIndex: 2, InclusionDistance: 1}
|
||||
wantedVp := []*Validator{{}, wanted, {}, wanted, {}, wanted}
|
||||
if !reflect.DeepEqual(vp, wantedVp) {
|
||||
t.Error("Incorrect attesting validator calculations")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateBalance(t *testing.T) {
|
||||
vp := []*Validator{
|
||||
{IsCurrentEpochAttester: true, CurrentEpochEffectiveBalance: 100},
|
||||
{IsCurrentEpochTargetAttester: true, IsCurrentEpochAttester: true, CurrentEpochEffectiveBalance: 100},
|
||||
{IsCurrentEpochTargetAttester: true, CurrentEpochEffectiveBalance: 100},
|
||||
{IsPrevEpochAttester: true, CurrentEpochEffectiveBalance: 100},
|
||||
{IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, CurrentEpochEffectiveBalance: 100},
|
||||
{IsPrevEpochHeadAttester: true, CurrentEpochEffectiveBalance: 100},
|
||||
{IsPrevEpochAttester: true, IsPrevEpochHeadAttester: true, CurrentEpochEffectiveBalance: 100},
|
||||
{IsSlashed: true, IsCurrentEpochAttester: true, CurrentEpochEffectiveBalance: 100},
|
||||
}
|
||||
wantedBp := &Balance{
|
||||
CurrentEpochAttesters: 200,
|
||||
CurrentEpochTargetAttesters: 200,
|
||||
PrevEpochAttesters: 300,
|
||||
PrevEpochTargetAttesters: 100,
|
||||
PrevEpochHeadAttesters: 200,
|
||||
}
|
||||
bp := updateBalance(vp, &Balance{})
|
||||
if !reflect.DeepEqual(bp, wantedBp) {
|
||||
t.Error("Incorrect balance calculations")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSameHead(t *testing.T) {
|
||||
deposits, _, _ := testutil.SetupInitialDeposits(t, 100)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beaconState.Slot = 1
|
||||
att := ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Crosslink: ðpb.Crosslink{Shard: 0}}}
|
||||
attSlot, err := helpers.AttestationDataSlot(beaconState, att.Data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := []byte{'A'}
|
||||
beaconState.BlockRoots[attSlot] = r
|
||||
att.Data.BeaconBlockRoot = r
|
||||
same, err := sameHead(beaconState, &pb.PendingAttestation{Data: att.Data})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !same {
|
||||
t.Error("head in state does not match head in attestation")
|
||||
}
|
||||
att.Data.BeaconBlockRoot = []byte{'B'}
|
||||
same, err = sameHead(beaconState, &pb.PendingAttestation{Data: att.Data})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if same {
|
||||
t.Error("head in state matches head in attestation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSameTarget(t *testing.T) {
|
||||
deposits, _, _ := testutil.SetupInitialDeposits(t, 100)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beaconState.Slot = 1
|
||||
att := ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Crosslink: ðpb.Crosslink{Shard: 0}}}
|
||||
attSlot, err := helpers.AttestationDataSlot(beaconState, att.Data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := []byte{'A'}
|
||||
beaconState.BlockRoots[attSlot] = r
|
||||
att.Data.Target.Root = r
|
||||
same, err := sameTarget(beaconState, &pb.PendingAttestation{Data: att.Data}, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !same {
|
||||
t.Error("head in state does not match head in attestation")
|
||||
}
|
||||
att.Data.Target.Root = []byte{'B'}
|
||||
same, err = sameTarget(beaconState, &pb.PendingAttestation{Data: att.Data}, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if same {
|
||||
t.Error("head in state matches head in attestation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttestedPrevEpoch(t *testing.T) {
|
||||
deposits, _, _ := testutil.SetupInitialDeposits(t, 100)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beaconState.Slot = params.BeaconConfig().SlotsPerEpoch
|
||||
att := ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Crosslink: ðpb.Crosslink{Shard: 960}}}
|
||||
attSlot, err := helpers.AttestationDataSlot(beaconState, att.Data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := []byte{'A'}
|
||||
beaconState.BlockRoots[attSlot] = r
|
||||
att.Data.Target.Root = r
|
||||
att.Data.BeaconBlockRoot = r
|
||||
votedEpoch, votedTarget, votedHead, err := attestedPrevEpoch(beaconState, &pb.PendingAttestation{Data: att.Data})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !votedEpoch {
|
||||
t.Error("did not vote epoch")
|
||||
}
|
||||
if !votedTarget {
|
||||
t.Error("did not vote target")
|
||||
}
|
||||
if !votedHead {
|
||||
t.Error("did not vote head")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttestedCurrentEpoch(t *testing.T) {
|
||||
deposits, _, _ := testutil.SetupInitialDeposits(t, 100)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beaconState.Slot = params.BeaconConfig().SlotsPerEpoch + 1
|
||||
att := ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
Crosslink: ðpb.Crosslink{}}}
|
||||
attSlot, err := helpers.AttestationDataSlot(beaconState, att.Data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := []byte{'A'}
|
||||
beaconState.BlockRoots[attSlot] = r
|
||||
att.Data.Target.Root = r
|
||||
att.Data.BeaconBlockRoot = r
|
||||
votedEpoch, votedTarget, err := attestedCurrentEpoch(beaconState, &pb.PendingAttestation{Data: att.Data})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !votedEpoch {
|
||||
t.Error("did not vote epoch")
|
||||
}
|
||||
if !votedTarget {
|
||||
t.Error("did not vote target")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessAttestations(t *testing.T) {
|
||||
helpers.ClearAllCaches()
|
||||
|
||||
params.UseMinimalConfig()
|
||||
defer params.UseMainnetConfig()
|
||||
|
||||
validators := uint64(64)
|
||||
deposits, _, _ := testutil.SetupInitialDeposits(t, validators)
|
||||
beaconState, err := state.GenesisBeaconState(deposits, uint64(0), ðpb.Eth1Data{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beaconState.Slot = params.BeaconConfig().SlotsPerEpoch
|
||||
|
||||
bf := []byte{0xff}
|
||||
att1 := ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Crosslink: ðpb.Crosslink{Shard: 960}}, AggregationBits: bf}
|
||||
att2 := ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Epoch: 0},
|
||||
Crosslink: ðpb.Crosslink{Shard: 961}}, AggregationBits: bf}
|
||||
beaconState.BlockRoots[0] = []byte{'A'}
|
||||
att1.Data.Target.Root = []byte{'A'}
|
||||
att1.Data.BeaconBlockRoot = []byte{'A'}
|
||||
beaconState.BlockRoots[0] = []byte{'B'}
|
||||
att2.Data.Target.Root = []byte{'A'}
|
||||
att2.Data.BeaconBlockRoot = []byte{'B'}
|
||||
beaconState.PreviousEpochAttestations = []*pb.PendingAttestation{{Data: att1.Data, AggregationBits: bf}}
|
||||
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{{Data: att2.Data, AggregationBits: bf}}
|
||||
|
||||
vp := make([]*Validator, validators)
|
||||
for i := 0; i < len(vp); i++ {
|
||||
vp[i] = &Validator{CurrentEpochEffectiveBalance: 100}
|
||||
}
|
||||
bp := &Balance{}
|
||||
vp, bp, err = ProcessAttestations(context.Background(), beaconState, vp, bp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
indices, _ := helpers.AttestingIndices(beaconState, att1.Data, att1.AggregationBits)
|
||||
for _, i := range indices {
|
||||
if !vp[i].IsPrevEpochAttester {
|
||||
t.Error("Not a prev epoch attester")
|
||||
}
|
||||
}
|
||||
indices, _ = helpers.AttestingIndices(beaconState, att2.Data, att2.AggregationBits)
|
||||
for _, i := range indices {
|
||||
if !vp[i].IsPrevEpochAttester {
|
||||
t.Error("Not a prev epoch attester")
|
||||
}
|
||||
if !vp[i].IsPrevEpochHeadAttester {
|
||||
t.Error("Not a prev epoch head attester")
|
||||
}
|
||||
}
|
||||
}
|
||||
45
beacon-chain/core/epoch/precompute/new.go
Normal file
45
beacon-chain/core/epoch/precompute/new.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package precompute
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// New gets called at the beginning of process epoch cycle to return
|
||||
// pre computed instances of validators attesting records and total
|
||||
// balances attested in an epoch.
|
||||
func New(ctx context.Context, state *pb.BeaconState) ([]*Validator, *Balance) {
|
||||
ctx, span := trace.StartSpan(ctx, "precomputeEpoch.New")
|
||||
defer span.End()
|
||||
|
||||
vp := make([]*Validator, len(state.Validators))
|
||||
bp := &Balance{}
|
||||
|
||||
currentEpoch := helpers.CurrentEpoch(state)
|
||||
prevEpoch := helpers.PrevEpoch(state)
|
||||
|
||||
for i, v := range state.Validators {
|
||||
// Was validator withdrawable or slashed
|
||||
withdrawable := currentEpoch >= v.WithdrawableEpoch
|
||||
p := &Validator{
|
||||
IsSlashed: v.Slashed,
|
||||
IsWithdrawableCurrentEpoch: withdrawable,
|
||||
CurrentEpochEffectiveBalance: v.EffectiveBalance,
|
||||
}
|
||||
// Was validator active current epoch
|
||||
if helpers.IsActiveValidator(v, currentEpoch) {
|
||||
p.IsActiveCurrentEpoch = true
|
||||
bp.CurrentEpoch += v.EffectiveBalance
|
||||
}
|
||||
// Was validator active previous epoch
|
||||
if helpers.IsActiveValidator(v, prevEpoch) {
|
||||
p.IsActivePrevEpoch = true
|
||||
bp.PrevEpoch += v.EffectiveBalance
|
||||
}
|
||||
vp[i] = p
|
||||
}
|
||||
return vp, bp
|
||||
}
|
||||
49
beacon-chain/core/epoch/precompute/new_test.go
Normal file
49
beacon-chain/core/epoch/precompute/new_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package precompute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
ffe := params.BeaconConfig().FarFutureEpoch
|
||||
s := &pb.BeaconState{
|
||||
Slot: params.BeaconConfig().SlotsPerEpoch,
|
||||
// Validator 0 is slashed
|
||||
// Validator 1 is withdrawable
|
||||
// Validator 2 is active prev epoch and current epoch
|
||||
// Validator 3 is active prev epoch
|
||||
Validators: []*ethpb.Validator{
|
||||
{Slashed: true, WithdrawableEpoch: ffe, EffectiveBalance: 100},
|
||||
{EffectiveBalance: 100},
|
||||
{WithdrawableEpoch: ffe, ExitEpoch: ffe, EffectiveBalance: 100},
|
||||
{WithdrawableEpoch: ffe, ExitEpoch: 1, EffectiveBalance: 100},
|
||||
},
|
||||
}
|
||||
v, b := New(context.Background(), s)
|
||||
if !reflect.DeepEqual(v[0], &Validator{IsSlashed: true, CurrentEpochEffectiveBalance: 100}) {
|
||||
t.Error("Incorrect validator 0 status")
|
||||
}
|
||||
if !reflect.DeepEqual(v[1], &Validator{IsWithdrawableCurrentEpoch: true, CurrentEpochEffectiveBalance: 100}) {
|
||||
t.Error("Incorrect validator 1 status")
|
||||
}
|
||||
if !reflect.DeepEqual(v[2], &Validator{IsActiveCurrentEpoch: true, IsActivePrevEpoch: true, CurrentEpochEffectiveBalance: 100}) {
|
||||
t.Error("Incorrect validator 2 status")
|
||||
}
|
||||
if !reflect.DeepEqual(v[3], &Validator{IsActivePrevEpoch: true, CurrentEpochEffectiveBalance: 100}) {
|
||||
t.Error("Incorrect validator 3 status")
|
||||
}
|
||||
|
||||
wantedBalances := &Balance{
|
||||
CurrentEpoch: 100,
|
||||
PrevEpoch: 200,
|
||||
}
|
||||
if !reflect.DeepEqual(b, wantedBalances) {
|
||||
t.Error("Incorrect wanted balance")
|
||||
}
|
||||
}
|
||||
@@ -323,6 +323,11 @@ func UseMinimalConfig() {
|
||||
beaconConfig = MinimalSpecConfig()
|
||||
}
|
||||
|
||||
// UseMainnetConfig for beacon chain services.
|
||||
func UseMainnetConfig() {
|
||||
beaconConfig = defaultBeaconConfig
|
||||
}
|
||||
|
||||
// OverrideBeaconConfig by replacing the config. The preferred pattern is to
|
||||
// call BeaconConfig(), change the specific parameters, and then call
|
||||
// OverrideBeaconConfig(c). Any subsequent calls to params.BeaconConfig() will
|
||||
|
||||
Reference in New Issue
Block a user