mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Optimize committee helpers (#4328)
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
"github.com/prysmaticlabs/prysm/shared/params"
|
"github.com/prysmaticlabs/prysm/shared/params"
|
||||||
)
|
)
|
||||||
@@ -30,6 +31,8 @@ type HeadFetcher interface {
|
|||||||
HeadRoot() []byte
|
HeadRoot() []byte
|
||||||
HeadBlock() *ethpb.BeaconBlock
|
HeadBlock() *ethpb.BeaconBlock
|
||||||
HeadState(ctx context.Context) (*pb.BeaconState, error)
|
HeadState(ctx context.Context) (*pb.BeaconState, error)
|
||||||
|
HeadValidatorsIndices(epoch uint64) ([]uint64, error)
|
||||||
|
HeadSeed(epoch uint64) ([32]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanonicalRootFetcher defines a common interface for methods in blockchain service which
|
// CanonicalRootFetcher defines a common interface for methods in blockchain service which
|
||||||
@@ -102,6 +105,16 @@ func (s *Service) HeadState(ctx context.Context) (*pb.BeaconState, error) {
|
|||||||
return proto.Clone(s.headState).(*pb.BeaconState), nil
|
return proto.Clone(s.headState).(*pb.BeaconState), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HeadValidatorsIndices returns a list of active validator indices from the head view of a given epoch.
|
||||||
|
func (s *Service) HeadValidatorsIndices(epoch uint64) ([]uint64, error) {
|
||||||
|
return helpers.ActiveValidatorIndices(s.headState, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeadSeed returns the seed from the head view of a given epoch.
|
||||||
|
func (s *Service) HeadSeed(epoch uint64) ([32]byte, error) {
|
||||||
|
return helpers.Seed(s.headState, epoch, params.BeaconConfig().DomainBeaconAttester)
|
||||||
|
}
|
||||||
|
|
||||||
// CanonicalRoot returns the canonical root of a given slot.
|
// CanonicalRoot returns the canonical root of a given slot.
|
||||||
func (s *Service) CanonicalRoot(slot uint64) []byte {
|
func (s *Service) CanonicalRoot(slot uint64) []byte {
|
||||||
s.headLock.RLock()
|
s.headLock.RLock()
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ func (s *Store) saveCheckpointState(ctx context.Context, baseState *pb.BeaconSta
|
|||||||
|
|
||||||
// verifyAttestation validates input attestation is valid.
|
// verifyAttestation validates input attestation is valid.
|
||||||
func (s *Store) verifyAttestation(ctx context.Context, baseState *pb.BeaconState, a *ethpb.Attestation) (*ethpb.IndexedAttestation, error) {
|
func (s *Store) verifyAttestation(ctx context.Context, baseState *pb.BeaconState, a *ethpb.Attestation) (*ethpb.IndexedAttestation, error) {
|
||||||
committee, err := helpers.BeaconCommittee(baseState, a.Data.Slot, a.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(baseState, a.Data.Slot, a.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ func (s *Store) updateBlockAttestationVote(ctx context.Context, att *ethpb.Attes
|
|||||||
if baseState == nil {
|
if baseState == nil {
|
||||||
return errors.New("no state found in db with attestation tgt root")
|
return errors.New("no state found in db with attestation tgt root")
|
||||||
}
|
}
|
||||||
committee, err := helpers.BeaconCommittee(baseState, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(baseState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ func TestStore_UpdateBlockAttestationVote(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ go_library(
|
|||||||
visibility = ["//beacon-chain:__subpackages__"],
|
visibility = ["//beacon-chain:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/core/feed/state:go_default_library",
|
"//beacon-chain/core/feed/state:go_default_library",
|
||||||
|
"//beacon-chain/core/helpers:go_default_library",
|
||||||
"//beacon-chain/db:go_default_library",
|
"//beacon-chain/db:go_default_library",
|
||||||
"//proto/beacon/p2p/v1:go_default_library",
|
"//proto/beacon/p2p/v1:go_default_library",
|
||||||
"//shared/event:go_default_library",
|
"//shared/event:go_default_library",
|
||||||
|
"//shared/params:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ import (
|
|||||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||||
"github.com/prysmaticlabs/go-ssz"
|
"github.com/prysmaticlabs/go-ssz"
|
||||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
"github.com/prysmaticlabs/prysm/shared/event"
|
"github.com/prysmaticlabs/prysm/shared/event"
|
||||||
|
"github.com/prysmaticlabs/prysm/shared/params"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -131,6 +133,16 @@ func (ms *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attes
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HeadValidatorsIndices mocks the same method in the chain service.
|
||||||
|
func (ms *ChainService) HeadValidatorsIndices(epoch uint64) ([]uint64, error) {
|
||||||
|
return helpers.ActiveValidatorIndices(ms.State, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeadSeed mocks the same method in the chain service.
|
||||||
|
func (ms *ChainService) HeadSeed(epoch uint64) ([32]byte, error) {
|
||||||
|
return helpers.Seed(ms.State, epoch, params.BeaconConfig().DomainBeaconAttester)
|
||||||
|
}
|
||||||
|
|
||||||
// GenesisTime mocks the same method in the chain service.
|
// GenesisTime mocks the same method in the chain service.
|
||||||
func (ms *ChainService) GenesisTime() time.Time {
|
func (ms *ChainService) GenesisTime() time.Time {
|
||||||
return ms.Genesis
|
return ms.Genesis
|
||||||
|
|||||||
@@ -828,7 +828,7 @@ func VerifyIndexedAttestation(ctx context.Context, beaconState *pb.BeaconState,
|
|||||||
// VerifyAttestation converts and attestation into an indexed attestation and verifies
|
// VerifyAttestation converts and attestation into an indexed attestation and verifies
|
||||||
// the signature in that attestation.
|
// the signature in that attestation.
|
||||||
func VerifyAttestation(ctx context.Context, beaconState *pb.BeaconState, att *ethpb.Attestation) error {
|
func VerifyAttestation(ctx context.Context, beaconState *pb.BeaconState, att *ethpb.Attestation) error {
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -923,7 +923,7 @@ func TestProcessAttestations_OK(t *testing.T) {
|
|||||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||||
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
||||||
|
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -982,7 +982,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
|
|||||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||||
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
||||||
|
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -1016,7 +1016,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
|
|||||||
CustodyBits: custodyBits2,
|
CustodyBits: custodyBits2,
|
||||||
}
|
}
|
||||||
|
|
||||||
committee, err = helpers.BeaconCommittee(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
|
committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -1065,7 +1065,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
|
|||||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||||
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
beaconState.CurrentEpochAttestations = []*pb.PendingAttestation{}
|
||||||
|
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -1098,7 +1098,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
|
|||||||
CustodyBits: custodyBits2,
|
CustodyBits: custodyBits2,
|
||||||
}
|
}
|
||||||
|
|
||||||
committee, err = helpers.BeaconCommittee(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
|
committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -1223,7 +1223,7 @@ func TestConvertToIndexed_OK(t *testing.T) {
|
|||||||
Signature: attestation.Signature,
|
Signature: attestation.Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
committee, err := helpers.BeaconCommittee(state, attestation.Data.Slot, attestation.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(state, attestation.Data.Slot, attestation.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,8 +339,9 @@ func ProcessFinalUpdates(state *pb.BeaconState) (*pb.BeaconState, error) {
|
|||||||
func unslashedAttestingIndices(state *pb.BeaconState, atts []*pb.PendingAttestation) ([]uint64, error) {
|
func unslashedAttestingIndices(state *pb.BeaconState, atts []*pb.PendingAttestation) ([]uint64, error) {
|
||||||
var setIndices []uint64
|
var setIndices []uint64
|
||||||
seen := make(map[uint64]bool)
|
seen := make(map[uint64]bool)
|
||||||
|
|
||||||
for _, att := range atts {
|
for _, att := range atts {
|
||||||
committee, err := helpers.BeaconCommittee(state, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(state, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ func ProcessAttestations(
|
|||||||
|
|
||||||
v := &Validator{}
|
v := &Validator{}
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
for _, a := range append(state.PreviousEpochAttestations, state.CurrentEpochAttestations...) {
|
for _, a := range append(state.PreviousEpochAttestations, state.CurrentEpochAttestations...) {
|
||||||
v.IsCurrentEpochAttester, v.IsCurrentEpochTargetAttester, err = AttestedCurrentEpoch(state, a)
|
v.IsCurrentEpochAttester, v.IsCurrentEpochTargetAttester, err = AttestedCurrentEpoch(state, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -35,8 +36,7 @@ func ProcessAttestations(
|
|||||||
return nil, nil, errors.Wrap(err, "could not check validator attested previous epoch")
|
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.
|
committee, err := helpers.BeaconCommitteeFromState(state, a.Data.Slot, a.Data.CommitteeIndex)
|
||||||
committee, err := helpers.BeaconCommittee(state, a.Data.Slot, a.Data.CommitteeIndex)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,7 +199,8 @@ func TestProcessAttestations(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
|
|
||||||
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -209,7 +210,7 @@ func TestProcessAttestations(t *testing.T) {
|
|||||||
t.Error("Not a prev epoch attester")
|
t.Error("Not a prev epoch attester")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
committee, err = helpers.BeaconCommittee(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
|
committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,21 +121,19 @@ func SlotSignature(state *pb.BeaconState, slot uint64, privKey *bls.SecretKey) (
|
|||||||
return privKey.Sign(s[:], d), nil
|
return privKey.Sign(s[:], d), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAggregator returns true if the signature is from the input validator.
|
// IsAggregator returns true if the signature is from the input validator. The committee
|
||||||
|
// count is provided as an argument rather than direct implementation from spec. Having
|
||||||
|
// committee count as an argument allows cheaper computation at run time.
|
||||||
//
|
//
|
||||||
// Spec pseudocode definition:
|
// Spec pseudocode definition:
|
||||||
// def is_aggregator(state: BeaconState, slot: Slot, index: CommitteeIndex, slot_signature: BLSSignature) -> bool:
|
// def is_aggregator(state: BeaconState, slot: Slot, index: CommitteeIndex, slot_signature: BLSSignature) -> bool:
|
||||||
// committee = get_beacon_committee(state, slot, index)
|
// committee = get_beacon_committee(state, slot, index)
|
||||||
// modulo = max(1, len(committee) // TARGET_AGGREGATORS_PER_COMMITTEE)
|
// modulo = max(1, len(committee) // TARGET_AGGREGATORS_PER_COMMITTEE)
|
||||||
// return bytes_to_int(hash(slot_signature)[0:8]) % modulo == 0
|
// return bytes_to_int(hash(slot_signature)[0:8]) % modulo == 0
|
||||||
func IsAggregator(state *pb.BeaconState, slot uint64, index uint64, slotSig []byte) (bool, error) {
|
func IsAggregator(committeeCount uint64, slot uint64, index uint64, slotSig []byte) (bool, error) {
|
||||||
committee, err := BeaconCommittee(state, slot, index)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
modulo := uint64(1)
|
modulo := uint64(1)
|
||||||
if len(committee)/int(params.BeaconConfig().TargetAggregatorsPerCommittee) > 1 {
|
if committeeCount/params.BeaconConfig().TargetAggregatorsPerCommittee > 1 {
|
||||||
modulo = uint64(len(committee)) / params.BeaconConfig().TargetAggregatorsPerCommittee
|
modulo = committeeCount / params.BeaconConfig().TargetAggregatorsPerCommittee
|
||||||
}
|
}
|
||||||
|
|
||||||
b := hashutil.Hash(slotSig)
|
b := hashutil.Hash(slotSig)
|
||||||
|
|||||||
@@ -228,8 +228,13 @@ func TestSlotSignature_Verify(t *testing.T) {
|
|||||||
|
|
||||||
func TestIsAggregator_True(t *testing.T) {
|
func TestIsAggregator_True(t *testing.T) {
|
||||||
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
|
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
|
||||||
|
|
||||||
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
sig := privKeys[0].Sign([]byte{}, 0)
|
sig := privKeys[0].Sign([]byte{}, 0)
|
||||||
agg, err := helpers.IsAggregator(beaconState, 0, 0, sig.Marshal())
|
agg, err := helpers.IsAggregator(uint64(len(committee)), 0, 0, sig.Marshal())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -243,8 +248,12 @@ func TestIsAggregator_False(t *testing.T) {
|
|||||||
defer params.UseMainnetConfig()
|
defer params.UseMainnetConfig()
|
||||||
beaconState, privKeys := testutil.DeterministicGenesisState(t, 2048)
|
beaconState, privKeys := testutil.DeterministicGenesisState(t, 2048)
|
||||||
|
|
||||||
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
sig := privKeys[0].Sign([]byte{}, 0)
|
sig := privKeys[0].Sign([]byte{}, 0)
|
||||||
agg, err := helpers.IsAggregator(beaconState, 0, 0, sig.Marshal())
|
agg, err := helpers.IsAggregator(uint64(len(committee)), 0, 0, sig.Marshal())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,12 @@ import (
|
|||||||
|
|
||||||
var committeeCache = cache.NewCommitteesCache()
|
var committeeCache = cache.NewCommitteesCache()
|
||||||
|
|
||||||
// CommitteeCountAtSlot returns the number of crosslink committees of a slot.
|
// SlotCommitteeCount returns the number of crosslink committees of a slot. The
|
||||||
|
// active validator count is provided as an argument rather than a direct implementation
|
||||||
|
// from the spec definition. Having the active validator count as an argument allows for
|
||||||
|
// cheaper computation, instead of retrieving head state, one can retrieve the validator
|
||||||
|
// count.
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// Spec pseudocode definition:
|
// Spec pseudocode definition:
|
||||||
// def get_committee_count_at_slot(state: BeaconState, slot: Slot) -> uint64:
|
// def get_committee_count_at_slot(state: BeaconState, slot: Slot) -> uint64:
|
||||||
@@ -29,23 +34,22 @@ var committeeCache = cache.NewCommitteesCache()
|
|||||||
// MAX_COMMITTEES_PER_SLOT,
|
// MAX_COMMITTEES_PER_SLOT,
|
||||||
// len(get_active_validator_indices(state, epoch)) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
|
// len(get_active_validator_indices(state, epoch)) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
|
||||||
// ))
|
// ))
|
||||||
func CommitteeCountAtSlot(state *pb.BeaconState, slot uint64) (uint64, error) {
|
func SlotCommitteeCount(activeValidatorCount uint64) uint64 {
|
||||||
epoch := SlotToEpoch(slot)
|
var committeePerSlot = activeValidatorCount / params.BeaconConfig().SlotsPerEpoch / params.BeaconConfig().TargetCommitteeSize
|
||||||
count, err := ActiveValidatorCount(state, epoch)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.Wrap(err, "could not get active count")
|
|
||||||
}
|
|
||||||
var committeePerSlot = count / params.BeaconConfig().SlotsPerEpoch / params.BeaconConfig().TargetCommitteeSize
|
|
||||||
if committeePerSlot > params.BeaconConfig().MaxCommitteesPerSlot {
|
if committeePerSlot > params.BeaconConfig().MaxCommitteesPerSlot {
|
||||||
return params.BeaconConfig().MaxCommitteesPerSlot, nil
|
return params.BeaconConfig().MaxCommitteesPerSlot
|
||||||
}
|
}
|
||||||
if committeePerSlot == 0 {
|
if committeePerSlot == 0 {
|
||||||
return 1, nil
|
return 1
|
||||||
}
|
}
|
||||||
return committeePerSlot, nil
|
|
||||||
|
return committeePerSlot
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeaconCommittee returns the crosslink committee of a given slot and committee index.
|
// BeaconCommitteeFromState returns the crosslink committee of a given slot and committee index. This
|
||||||
|
// is a spec implementation where state is used as an argument. In case of state retrieval
|
||||||
|
// becomes expensive, consider using BeaconCommittee below.
|
||||||
//
|
//
|
||||||
// Spec pseudocode definition:
|
// Spec pseudocode definition:
|
||||||
// def get_beacon_committee(state: BeaconState, slot: Slot, index: CommitteeIndex) -> Sequence[ValidatorIndex]:
|
// def get_beacon_committee(state: BeaconState, slot: Slot, index: CommitteeIndex) -> Sequence[ValidatorIndex]:
|
||||||
@@ -61,15 +65,15 @@ func CommitteeCountAtSlot(state *pb.BeaconState, slot uint64) (uint64, error) {
|
|||||||
// index=epoch_offset,
|
// index=epoch_offset,
|
||||||
// count=committees_per_slot * SLOTS_PER_EPOCH,
|
// count=committees_per_slot * SLOTS_PER_EPOCH,
|
||||||
// )
|
// )
|
||||||
func BeaconCommittee(state *pb.BeaconState, slot uint64, index uint64) ([]uint64, error) {
|
func BeaconCommitteeFromState(state *pb.BeaconState, slot uint64, committeeIndex uint64) ([]uint64, error) {
|
||||||
epoch := SlotToEpoch(slot)
|
epoch := SlotToEpoch(slot)
|
||||||
if featureconfig.Get().EnableNewCache {
|
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
|
||||||
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, errors.Wrap(err, "could not get seed")
|
||||||
return nil, errors.Wrap(err, "could not get seed")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
indices, err := committeeCache.Committee(slot, seed, index)
|
if featureconfig.Get().EnableNewCache {
|
||||||
|
indices, err := committeeCache.Committee(slot, seed, committeeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not interface with committee cache")
|
return nil, errors.Wrap(err, "could not interface with committee cache")
|
||||||
}
|
}
|
||||||
@@ -78,30 +82,34 @@ func BeaconCommittee(state *pb.BeaconState, slot uint64, index uint64) ([]uint64
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
committeesPerSlot, err := CommitteeCountAtSlot(state, slot)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not get committee count at slot")
|
|
||||||
}
|
|
||||||
epochOffset := index + (slot%params.BeaconConfig().SlotsPerEpoch)*committeesPerSlot
|
|
||||||
count := committeesPerSlot * params.BeaconConfig().SlotsPerEpoch
|
|
||||||
|
|
||||||
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not get seed")
|
|
||||||
}
|
|
||||||
|
|
||||||
indices, err := ActiveValidatorIndices(state, epoch)
|
indices, err := ActiveValidatorIndices(state, epoch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get active indices")
|
return nil, errors.Wrap(err, "could not get active indices")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return BeaconCommittee(indices, seed, slot, committeeIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeaconCommittee returns the crosslink committee of a given slot and committee index. The
|
||||||
|
// validator indices and seed are provided as an argument rather than a direct implementation
|
||||||
|
// from the spec definition. Having them as an argument allows for cheaper computation run time.
|
||||||
|
func BeaconCommittee(validatorIndices []uint64, seed [32]byte, slot uint64, committeeIndex uint64) ([]uint64, error) {
|
||||||
if featureconfig.Get().EnableNewCache {
|
if featureconfig.Get().EnableNewCache {
|
||||||
if err := UpdateCommitteeCache(state); err != nil {
|
indices, err := committeeCache.Committee(slot, seed, committeeIndex)
|
||||||
return nil, errors.Wrap(err, "could not update committee cache")
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not interface with committee cache")
|
||||||
|
}
|
||||||
|
if indices != nil {
|
||||||
|
return indices, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ComputeCommittee(indices, seed, epochOffset, count)
|
committeesPerSlot := SlotCommitteeCount(uint64(len(validatorIndices)))
|
||||||
|
|
||||||
|
epochOffset := committeeIndex + (slot%params.BeaconConfig().SlotsPerEpoch)*committeesPerSlot
|
||||||
|
count := committeesPerSlot * params.BeaconConfig().SlotsPerEpoch
|
||||||
|
|
||||||
|
return ComputeCommittee(validatorIndices, seed, epochOffset, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeaconCommitteeWithoutCache returns the crosslink committee of a given slot and committee index without the
|
// BeaconCommitteeWithoutCache returns the crosslink committee of a given slot and committee index without the
|
||||||
@@ -109,11 +117,11 @@ func BeaconCommittee(state *pb.BeaconState, slot uint64, index uint64) ([]uint64
|
|||||||
// TODO(3603): Delete this function when issue 3603 closes.
|
// TODO(3603): Delete this function when issue 3603 closes.
|
||||||
func BeaconCommitteeWithoutCache(state *pb.BeaconState, slot uint64, index uint64) ([]uint64, error) {
|
func BeaconCommitteeWithoutCache(state *pb.BeaconState, slot uint64, index uint64) ([]uint64, error) {
|
||||||
epoch := SlotToEpoch(slot)
|
epoch := SlotToEpoch(slot)
|
||||||
|
activeValidatorCount, err := ActiveValidatorCount(state, epoch)
|
||||||
committeesPerSlot, err := CommitteeCountAtSlot(state, slot)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get committee count at slot")
|
return nil, err
|
||||||
}
|
}
|
||||||
|
committeesPerSlot := SlotCommitteeCount(activeValidatorCount)
|
||||||
epochOffset := index + (slot%params.BeaconConfig().SlotsPerEpoch)*committeesPerSlot
|
epochOffset := index + (slot%params.BeaconConfig().SlotsPerEpoch)*committeesPerSlot
|
||||||
count := committeesPerSlot * params.BeaconConfig().SlotsPerEpoch
|
count := committeesPerSlot * params.BeaconConfig().SlotsPerEpoch
|
||||||
|
|
||||||
@@ -121,7 +129,6 @@ func BeaconCommitteeWithoutCache(state *pb.BeaconState, slot uint64, index uint6
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get seed")
|
return nil, errors.Wrap(err, "could not get seed")
|
||||||
}
|
}
|
||||||
|
|
||||||
indices, err := ActiveValidatorIndices(state, epoch)
|
indices, err := ActiveValidatorIndices(state, epoch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get active indices")
|
return nil, errors.Wrap(err, "could not get active indices")
|
||||||
@@ -212,7 +219,7 @@ func CommitteeAssignments(state *pb.BeaconState, epoch uint64) (map[uint64]*Comm
|
|||||||
if epoch > NextEpoch(state) {
|
if epoch > NextEpoch(state) {
|
||||||
return nil, nil, fmt.Errorf(
|
return nil, nil, fmt.Errorf(
|
||||||
"epoch %d can't be greater than next epoch %d",
|
"epoch %d can't be greater than next epoch %d",
|
||||||
epoch,
|
epoch,
|
||||||
NextEpoch(state),
|
NextEpoch(state),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -229,13 +236,13 @@ func CommitteeAssignments(state *pb.BeaconState, epoch uint64) (map[uint64]*Comm
|
|||||||
proposerIndexToSlot[i] = slot
|
proposerIndexToSlot[i] = slot
|
||||||
}
|
}
|
||||||
|
|
||||||
// Each slot in an epoch has a different set of committees. This value is derived from the
|
activeValidatorIndices, err := ActiveValidatorIndices(state, epoch)
|
||||||
// active validator set, which does not change.
|
|
||||||
numCommitteesPerSlot, err := CommitteeCountAtSlot(state, StartSlot(epoch))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
// Each slot in an epoch has a different set of committees. This value is derived from the
|
||||||
|
// active validator set, which does not change.
|
||||||
|
numCommitteesPerSlot := SlotCommitteeCount(uint64(len(activeValidatorIndices)))
|
||||||
validatorIndexToCommittee := make(map[uint64]*CommitteeAssignmentContainer)
|
validatorIndexToCommittee := make(map[uint64]*CommitteeAssignmentContainer)
|
||||||
|
|
||||||
// Compute all committees for all slots.
|
// Compute all committees for all slots.
|
||||||
@@ -243,7 +250,7 @@ func CommitteeAssignments(state *pb.BeaconState, epoch uint64) (map[uint64]*Comm
|
|||||||
// Compute committees.
|
// Compute committees.
|
||||||
for j := uint64(0); j < numCommitteesPerSlot; j++ {
|
for j := uint64(0); j < numCommitteesPerSlot; j++ {
|
||||||
slot := startSlot + i
|
slot := startSlot + i
|
||||||
committee, err := BeaconCommittee(state, slot, j /*committee index*/)
|
committee, err := BeaconCommitteeFromState(state, slot, j /*committee index*/)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -316,13 +323,14 @@ func CommitteeAssignment(
|
|||||||
proposerIndexToSlot[i] = slot
|
proposerIndexToSlot[i] = slot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeValidatorIndices, err := ActiveValidatorIndices(state, epoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, 0, 0, err
|
||||||
|
}
|
||||||
for slot := startSlot; slot < startSlot+params.BeaconConfig().SlotsPerEpoch; slot++ {
|
for slot := startSlot; slot < startSlot+params.BeaconConfig().SlotsPerEpoch; slot++ {
|
||||||
countAtSlot, err := CommitteeCountAtSlot(state, slot)
|
countAtSlot := SlotCommitteeCount(uint64(len(activeValidatorIndices)))
|
||||||
if err != nil {
|
|
||||||
return nil, 0, 0, 0, errors.Wrapf(err, "could not get committee count at slot %d", slot)
|
|
||||||
}
|
|
||||||
for i := uint64(0); i < countAtSlot; i++ {
|
for i := uint64(0); i < countAtSlot; i++ {
|
||||||
committee, err := BeaconCommittee(state, slot, i)
|
committee, err := BeaconCommitteeFromState(state, slot, i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, 0, 0, errors.Wrapf(err, "could not get crosslink committee at slot %d", slot)
|
return nil, 0, 0, 0, errors.Wrapf(err, "could not get crosslink committee at slot %d", slot)
|
||||||
}
|
}
|
||||||
@@ -350,8 +358,8 @@ func VerifyBitfieldLength(bf bitfield.Bitfield, committeeSize uint64) error {
|
|||||||
|
|
||||||
// VerifyAttestationBitfieldLengths verifies that an attestations aggregation and custody bitfields are
|
// VerifyAttestationBitfieldLengths verifies that an attestations aggregation and custody bitfields are
|
||||||
// a valid length matching the size of the committee.
|
// a valid length matching the size of the committee.
|
||||||
func VerifyAttestationBitfieldLengths(bState *pb.BeaconState, att *ethpb.Attestation) error {
|
func VerifyAttestationBitfieldLengths(state *pb.BeaconState, att *ethpb.Attestation) error {
|
||||||
committee, err := BeaconCommittee(bState, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := BeaconCommitteeFromState(state, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not retrieve beacon committees")
|
return errors.Wrap(err, "could not retrieve beacon committees")
|
||||||
}
|
}
|
||||||
@@ -406,10 +414,9 @@ func UpdateCommitteeCache(state *pb.BeaconState) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
count, err := CommitteeCountAtSlot(state, StartSlot(epoch))
|
|
||||||
if err != nil {
|
count := SlotCommitteeCount(uint64(len(shuffledIndices)))
|
||||||
return err
|
|
||||||
}
|
|
||||||
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
|
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -116,7 +116,8 @@ func TestAttestationParticipants_NoCommitteeCache(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
attestationData.Target = ðpb.Checkpoint{Epoch: 0}
|
attestationData.Target = ðpb.Checkpoint{Epoch: 0}
|
||||||
attestationData.Slot = tt.attestationSlot
|
attestationData.Slot = tt.attestationSlot
|
||||||
committee, err := BeaconCommittee(state, tt.attestationSlot, 0 /* committee index */)
|
|
||||||
|
committee, err := BeaconCommitteeFromState(state, tt.attestationSlot, 0 /* committee index */)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -210,7 +211,7 @@ func TestAttestationParticipants_EmptyBitfield(t *testing.T) {
|
|||||||
}
|
}
|
||||||
attestationData := ðpb.AttestationData{Target: ðpb.Checkpoint{}}
|
attestationData := ðpb.AttestationData{Target: ðpb.Checkpoint{}}
|
||||||
|
|
||||||
committee, err := BeaconCommittee(state, attestationData.Slot, attestationData.CommitteeIndex)
|
committee, err := BeaconCommitteeFromState(state, attestationData.Slot, attestationData.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -394,7 +395,7 @@ func TestCommitteeAssignments_CanRetrieve(t *testing.T) {
|
|||||||
|
|
||||||
state := &pb.BeaconState{
|
state := &pb.BeaconState{
|
||||||
Validators: validators,
|
Validators: validators,
|
||||||
Slot: 2*params.BeaconConfig().SlotsPerEpoch, // epoch 2
|
Slot: 2 * params.BeaconConfig().SlotsPerEpoch, // epoch 2
|
||||||
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
|
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -610,7 +610,7 @@ func CanProcessEpoch(state *pb.BeaconState) bool {
|
|||||||
func ProcessEpochPrecompute(ctx context.Context, state *pb.BeaconState) (*pb.BeaconState, error) {
|
func ProcessEpochPrecompute(ctx context.Context, state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "beacon-chain.ChainService.state.ProcessEpoch")
|
ctx, span := trace.StartSpan(ctx, "beacon-chain.ChainService.state.ProcessEpoch")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
span.AddAttributes(trace.Int64Attribute("epoch", int64(helpers.SlotToEpoch(state.Slot))))
|
span.AddAttributes(trace.Int64Attribute("epoch", int64(helpers.CurrentEpoch(state))))
|
||||||
|
|
||||||
vp, bp := precompute.New(ctx, state)
|
vp, bp := precompute.New(ctx, state)
|
||||||
vp, bp, err := precompute.ProcessAttestations(ctx, state, vp, bp)
|
vp, bp, err := precompute.ProcessAttestations(ctx, state, vp, bp)
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
|||||||
blockAtt := ðpb.Attestation{
|
blockAtt := ðpb.Attestation{
|
||||||
Data: ðpb.AttestationData{
|
Data: ðpb.AttestationData{
|
||||||
Slot: beaconState.Slot - 1,
|
Slot: beaconState.Slot - 1,
|
||||||
Target: ðpb.Checkpoint{Epoch: helpers.SlotToEpoch(beaconState.Slot)},
|
Target: ðpb.Checkpoint{Epoch: helpers.CurrentEpoch(beaconState)},
|
||||||
Source: ðpb.Checkpoint{
|
Source: ðpb.Checkpoint{
|
||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
Root: []byte("hello-world"),
|
Root: []byte("hello-world"),
|
||||||
@@ -387,7 +387,8 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
|||||||
AggregationBits: aggBits,
|
AggregationBits: aggBits,
|
||||||
CustodyBits: custodyBits,
|
CustodyBits: custodyBits,
|
||||||
}
|
}
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, blockAtt.Data.Slot, blockAtt.Data.CommitteeIndex)
|
|
||||||
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, blockAtt.Data.Slot, blockAtt.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -633,7 +634,7 @@ func BenchmarkProcessBlk_65536Validators_FullBlock(b *testing.B) {
|
|||||||
|
|
||||||
// Precache the shuffled indices
|
// Precache the shuffled indices
|
||||||
for i := uint64(0); i < committeeCount; i++ {
|
for i := uint64(0); i < committeeCount; i++ {
|
||||||
if _, err := helpers.BeaconCommittee(s, 0, i); err != nil {
|
if _, err := helpers.BeaconCommitteeFromState(s, 0, i); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -676,7 +677,7 @@ func TestProcessBlk_AttsBasedOnValidatorCount(t *testing.T) {
|
|||||||
CustodyBits: custodyBits,
|
CustodyBits: custodyBits,
|
||||||
}
|
}
|
||||||
|
|
||||||
committee, err := helpers.BeaconCommittee(s, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(s, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func TestHandleAttestation_Saves_NewAttestation(t *testing.T) {
|
|||||||
AggregationBits: bitfield.Bitlist{0xCF, 0xC0, 0xC0, 0xC0, 0x01},
|
AggregationBits: bitfield.Bitlist{0xCF, 0xC0, 0xC0, 0xC0, 0x01},
|
||||||
CustodyBits: bitfield.Bitlist{0x00, 0x00, 0x00, 0x00, 0x01},
|
CustodyBits: bitfield.Bitlist{0x00, 0x00, 0x00, 0x00, 0x01},
|
||||||
}
|
}
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -138,9 +138,9 @@ func TestHandleAttestation_Aggregates_LargeNumValidators(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Next up, we compute the committee for the attestation we're testing.
|
// Next up, we compute the committee for the attestation we're testing.
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
attDataRoot, err := ssz.HashTreeRoot(att.Data)
|
attDataRoot, err := ssz.HashTreeRoot(att.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -213,9 +213,9 @@ func TestHandleAttestation_Skips_PreviouslyAggregatedAttestations(t *testing.T)
|
|||||||
CustodyBits: bitfield.Bitlist{0x00, 0x00, 0x00, 0x00, 0x01},
|
CustodyBits: bitfield.Bitlist{0x00, 0x00, 0x00, 0x00, 0x01},
|
||||||
}
|
}
|
||||||
|
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
aggregationBits := bitfield.NewBitlist(uint64(len(committee)))
|
aggregationBits := bitfield.NewBitlist(uint64(len(committee)))
|
||||||
aggregationBits.SetBitAt(0, true)
|
aggregationBits.SetBitAt(0, true)
|
||||||
@@ -353,9 +353,9 @@ func TestRetrieveAttestations_OK(t *testing.T) {
|
|||||||
AggregationBits: aggBits,
|
AggregationBits: aggBits,
|
||||||
CustodyBits: custodyBits,
|
CustodyBits: custodyBits,
|
||||||
}
|
}
|
||||||
committee, err := helpers.BeaconCommittee(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
attestingIndices, err := helpers.AttestingIndices(att.AggregationBits, committee)
|
attestingIndices, err := helpers.AttestingIndices(att.AggregationBits, committee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/blockchain:go_default_library",
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/core/helpers:go_default_library",
|
"//beacon-chain/core/helpers:go_default_library",
|
||||||
"//beacon-chain/core/state:go_default_library",
|
|
||||||
"//beacon-chain/db:go_default_library",
|
"//beacon-chain/db:go_default_library",
|
||||||
"//beacon-chain/sync:go_default_library",
|
"//beacon-chain/sync:go_default_library",
|
||||||
"//proto/beacon/rpc/v1:go_default_library",
|
"//proto/beacon/rpc/v1:go_default_library",
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/sync"
|
"github.com/prysmaticlabs/prysm/beacon-chain/sync"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
@@ -40,21 +39,6 @@ func (as *Server) SubmitAggregateAndProof(ctx context.Context, req *pb.Aggregati
|
|||||||
return nil, status.Errorf(codes.Unavailable, "Syncing to latest head, not ready to respond")
|
return nil, status.Errorf(codes.Unavailable, "Syncing to latest head, not ready to respond")
|
||||||
}
|
}
|
||||||
|
|
||||||
headState, err := as.HeadFetcher.HeadState(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Errorf(codes.Internal, "Could not retrieve head state: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Advance slots if it is behind the epoch start of requested slot.
|
|
||||||
// Ex: head slot is 100, req slot is 150, epoch start of 150 is 128. Advance 100 to 128.
|
|
||||||
reqEpochStartSlot := helpers.StartSlot(helpers.SlotToEpoch(req.Slot))
|
|
||||||
if reqEpochStartSlot > headState.Slot {
|
|
||||||
headState, err = state.ProcessSlots(ctx, headState, reqEpochStartSlot)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", req.Slot, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
validatorIndex, exists, err := as.BeaconDB.ValidatorIndex(ctx, bytesutil.ToBytes48(req.PublicKey))
|
validatorIndex, exists, err := as.BeaconDB.ValidatorIndex(ctx, bytesutil.ToBytes48(req.PublicKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "Could not get validator index from DB: %v", err)
|
return nil, status.Errorf(codes.Internal, "Could not get validator index from DB: %v", err)
|
||||||
@@ -63,8 +47,22 @@ func (as *Server) SubmitAggregateAndProof(ctx context.Context, req *pb.Aggregati
|
|||||||
return nil, status.Error(codes.Internal, "Could not locate validator index in DB")
|
return nil, status.Error(codes.Internal, "Could not locate validator index in DB")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
epoch := helpers.SlotToEpoch(req.Slot)
|
||||||
|
activeValidatorIndices, err := as.HeadFetcher.HeadValidatorsIndices(epoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "Could not get validators: %v", err)
|
||||||
|
}
|
||||||
|
seed, err := as.HeadFetcher.HeadSeed(epoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "Could not get seed: %v", err)
|
||||||
|
}
|
||||||
|
committee, err := helpers.BeaconCommittee(activeValidatorIndices, seed, req.Slot, req.CommitteeIndex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the validator is an aggregator
|
// Check if the validator is an aggregator
|
||||||
isAggregator, err := helpers.IsAggregator(headState, req.Slot, req.CommitteeIndex, req.SlotSignature)
|
isAggregator, err := helpers.IsAggregator(uint64(len(committee)), req.Slot, req.CommitteeIndex, req.SlotSignature)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "Could not get aggregator status: %v", err)
|
return nil, status.Errorf(codes.Internal, "Could not get aggregator status: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ func BenchmarkCommitteeAssignment(b *testing.B) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
genesis := blk.NewGenesisBlock([]byte{})
|
genesis := blk.NewGenesisBlock([]byte{})
|
||||||
depChainStart := uint64(8192*2)
|
depChainStart := uint64(8192 * 2)
|
||||||
deposits, _, _ := testutil.DeterministicDepositsAndKeys(depChainStart)
|
deposits, _, _ := testutil.DeterministicDepositsAndKeys(depChainStart)
|
||||||
eth1Data, err := testutil.DeterministicEth1Data(len(deposits))
|
eth1Data, err := testutil.DeterministicEth1Data(len(deposits))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ func generateAttesterSlashings(
|
|||||||
attesterSlashings := make([]*ethpb.AttesterSlashing, numSlashings)
|
attesterSlashings := make([]*ethpb.AttesterSlashing, numSlashings)
|
||||||
for i := uint64(0); i < numSlashings; i++ {
|
for i := uint64(0); i < numSlashings; i++ {
|
||||||
committeeIndex := rand.Uint64() % params.BeaconConfig().MaxCommitteesPerSlot
|
committeeIndex := rand.Uint64() % params.BeaconConfig().MaxCommitteesPerSlot
|
||||||
committee, err := helpers.BeaconCommittee(bState, bState.Slot, committeeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(bState, bState.Slot, committeeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -330,10 +330,11 @@ func GenerateAttestations(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
committeesPerSlot, err := helpers.CommitteeCountAtSlot(bState, slot)
|
activeValidatorCount, err := helpers.ActiveValidatorCount(bState, currentEpoch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
committeesPerSlot := helpers.SlotCommitteeCount(activeValidatorCount)
|
||||||
|
|
||||||
if numToGen < committeesPerSlot {
|
if numToGen < committeesPerSlot {
|
||||||
log.Printf(
|
log.Printf(
|
||||||
@@ -361,7 +362,7 @@ func GenerateAttestations(
|
|||||||
|
|
||||||
domain := helpers.Domain(bState.Fork, currentEpoch, params.BeaconConfig().DomainBeaconAttester)
|
domain := helpers.Domain(bState.Fork, currentEpoch, params.BeaconConfig().DomainBeaconAttester)
|
||||||
for c := uint64(0); c < committeesPerSlot && c < numToGen; c++ {
|
for c := uint64(0); c < committeesPerSlot && c < numToGen; c++ {
|
||||||
committee, err := helpers.BeaconCommittee(bState, slot, c)
|
committee, err := helpers.BeaconCommitteeFromState(bState, slot, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
// Retrieve attestation indices
|
// Retrieve attestation indices
|
||||||
for _, att := range atts {
|
for _, att := range atts {
|
||||||
committee, err := helpers.BeaconCommittee(state, att.Data.Slot, att.Data.CommitteeIndex)
|
committee, err := helpers.BeaconCommitteeFromState(state, att.Data.Slot, att.Data.CommitteeIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user