mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
Optimize committee helpers (#4328)
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
@@ -30,6 +31,8 @@ type HeadFetcher interface {
|
||||
HeadRoot() []byte
|
||||
HeadBlock() *ethpb.BeaconBlock
|
||||
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
|
||||
@@ -102,6 +105,16 @@ func (s *Service) HeadState(ctx context.Context) (*pb.BeaconState, error) {
|
||||
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.
|
||||
func (s *Service) CanonicalRoot(slot uint64) []byte {
|
||||
s.headLock.RLock()
|
||||
|
||||
@@ -171,7 +171,7 @@ func (s *Store) saveCheckpointState(ctx context.Context, baseState *pb.BeaconSta
|
||||
|
||||
// verifyAttestation validates input attestation is valid.
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ func (s *Store) updateBlockAttestationVote(ctx context.Context, att *ethpb.Attes
|
||||
if baseState == nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ func TestStore_UpdateBlockAttestationVote(t *testing.T) {
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ go_library(
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//beacon-chain/core/feed/state:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
|
||||
@@ -9,9 +9,11 @@ import (
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
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"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -131,6 +133,16 @@ func (ms *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attes
|
||||
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.
|
||||
func (ms *ChainService) GenesisTime() time.Time {
|
||||
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
|
||||
// the signature in that attestation.
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -923,7 +923,7 @@ func TestProcessAttestations_OK(t *testing.T) {
|
||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -982,7 +982,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
|
||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -1016,7 +1016,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -1065,7 +1065,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
|
||||
beaconState.CurrentJustifiedCheckpoint.Root = []byte("hello-world")
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -1098,7 +1098,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -1223,7 +1223,7 @@ func TestConvertToIndexed_OK(t *testing.T) {
|
||||
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 {
|
||||
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) {
|
||||
var setIndices []uint64
|
||||
seen := make(map[uint64]bool)
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ func ProcessAttestations(
|
||||
|
||||
v := &Validator{}
|
||||
var err error
|
||||
|
||||
for _, a := range append(state.PreviousEpochAttestations, state.CurrentEpochAttestations...) {
|
||||
v.IsCurrentEpochAttester, v.IsCurrentEpochTargetAttester, err = AttestedCurrentEpoch(state, a)
|
||||
if err != nil {
|
||||
@@ -35,8 +36,7 @@ func ProcessAttestations(
|
||||
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.BeaconCommittee(state, a.Data.Slot, a.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(state, a.Data.Slot, a.Data.CommitteeIndex)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -199,7 +199,8 @@ func TestProcessAttestations(t *testing.T) {
|
||||
if err != nil {
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -209,7 +210,7 @@ func TestProcessAttestations(t *testing.T) {
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -121,21 +121,19 @@ func SlotSignature(state *pb.BeaconState, slot uint64, privKey *bls.SecretKey) (
|
||||
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:
|
||||
// def is_aggregator(state: BeaconState, slot: Slot, index: CommitteeIndex, slot_signature: BLSSignature) -> bool:
|
||||
// committee = get_beacon_committee(state, slot, index)
|
||||
// modulo = max(1, len(committee) // TARGET_AGGREGATORS_PER_COMMITTEE)
|
||||
// return bytes_to_int(hash(slot_signature)[0:8]) % modulo == 0
|
||||
func IsAggregator(state *pb.BeaconState, slot uint64, index uint64, slotSig []byte) (bool, error) {
|
||||
committee, err := BeaconCommittee(state, slot, index)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
func IsAggregator(committeeCount uint64, slot uint64, index uint64, slotSig []byte) (bool, error) {
|
||||
modulo := uint64(1)
|
||||
if len(committee)/int(params.BeaconConfig().TargetAggregatorsPerCommittee) > 1 {
|
||||
modulo = uint64(len(committee)) / params.BeaconConfig().TargetAggregatorsPerCommittee
|
||||
if committeeCount/params.BeaconConfig().TargetAggregatorsPerCommittee > 1 {
|
||||
modulo = committeeCount / params.BeaconConfig().TargetAggregatorsPerCommittee
|
||||
}
|
||||
|
||||
b := hashutil.Hash(slotSig)
|
||||
|
||||
@@ -228,8 +228,13 @@ func TestSlotSignature_Verify(t *testing.T) {
|
||||
|
||||
func TestIsAggregator_True(t *testing.T) {
|
||||
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)
|
||||
agg, err := helpers.IsAggregator(beaconState, 0, 0, sig.Marshal())
|
||||
agg, err := helpers.IsAggregator(uint64(len(committee)), 0, 0, sig.Marshal())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -243,8 +248,12 @@ func TestIsAggregator_False(t *testing.T) {
|
||||
defer params.UseMainnetConfig()
|
||||
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)
|
||||
agg, err := helpers.IsAggregator(beaconState, 0, 0, sig.Marshal())
|
||||
agg, err := helpers.IsAggregator(uint64(len(committee)), 0, 0, sig.Marshal())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,12 @@ import (
|
||||
|
||||
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:
|
||||
// def get_committee_count_at_slot(state: BeaconState, slot: Slot) -> uint64:
|
||||
@@ -29,23 +34,22 @@ var committeeCache = cache.NewCommitteesCache()
|
||||
// MAX_COMMITTEES_PER_SLOT,
|
||||
// len(get_active_validator_indices(state, epoch)) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
|
||||
// ))
|
||||
func CommitteeCountAtSlot(state *pb.BeaconState, slot uint64) (uint64, error) {
|
||||
epoch := SlotToEpoch(slot)
|
||||
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
|
||||
func SlotCommitteeCount(activeValidatorCount uint64) uint64 {
|
||||
var committeePerSlot = activeValidatorCount / params.BeaconConfig().SlotsPerEpoch / params.BeaconConfig().TargetCommitteeSize
|
||||
|
||||
if committeePerSlot > params.BeaconConfig().MaxCommitteesPerSlot {
|
||||
return params.BeaconConfig().MaxCommitteesPerSlot, nil
|
||||
return params.BeaconConfig().MaxCommitteesPerSlot
|
||||
}
|
||||
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:
|
||||
// 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,
|
||||
// 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)
|
||||
if featureconfig.Get().EnableNewCache {
|
||||
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get seed")
|
||||
}
|
||||
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
|
||||
if err != nil {
|
||||
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 {
|
||||
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)
|
||||
if err != nil {
|
||||
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 err := UpdateCommitteeCache(state); err != nil {
|
||||
return nil, errors.Wrap(err, "could not update committee cache")
|
||||
indices, err := committeeCache.Committee(slot, seed, committeeIndex)
|
||||
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
|
||||
@@ -109,11 +117,11 @@ func BeaconCommittee(state *pb.BeaconState, slot uint64, index uint64) ([]uint64
|
||||
// TODO(3603): Delete this function when issue 3603 closes.
|
||||
func BeaconCommitteeWithoutCache(state *pb.BeaconState, slot uint64, index uint64) ([]uint64, error) {
|
||||
epoch := SlotToEpoch(slot)
|
||||
|
||||
committeesPerSlot, err := CommitteeCountAtSlot(state, slot)
|
||||
activeValidatorCount, err := ActiveValidatorCount(state, epoch)
|
||||
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
|
||||
count := committeesPerSlot * params.BeaconConfig().SlotsPerEpoch
|
||||
|
||||
@@ -121,7 +129,6 @@ func BeaconCommitteeWithoutCache(state *pb.BeaconState, slot uint64, index uint6
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get seed")
|
||||
}
|
||||
|
||||
indices, err := ActiveValidatorIndices(state, epoch)
|
||||
if err != nil {
|
||||
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) {
|
||||
return nil, nil, fmt.Errorf(
|
||||
"epoch %d can't be greater than next epoch %d",
|
||||
epoch,
|
||||
epoch,
|
||||
NextEpoch(state),
|
||||
)
|
||||
}
|
||||
@@ -229,13 +236,13 @@ func CommitteeAssignments(state *pb.BeaconState, epoch uint64) (map[uint64]*Comm
|
||||
proposerIndexToSlot[i] = slot
|
||||
}
|
||||
|
||||
// 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, err := CommitteeCountAtSlot(state, StartSlot(epoch))
|
||||
activeValidatorIndices, err := ActiveValidatorIndices(state, epoch)
|
||||
if err != nil {
|
||||
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)
|
||||
|
||||
// Compute all committees for all slots.
|
||||
@@ -243,7 +250,7 @@ func CommitteeAssignments(state *pb.BeaconState, epoch uint64) (map[uint64]*Comm
|
||||
// Compute committees.
|
||||
for j := uint64(0); j < numCommitteesPerSlot; j++ {
|
||||
slot := startSlot + i
|
||||
committee, err := BeaconCommittee(state, slot, j /*committee index*/)
|
||||
committee, err := BeaconCommitteeFromState(state, slot, j /*committee index*/)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -316,13 +323,14 @@ func CommitteeAssignment(
|
||||
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++ {
|
||||
countAtSlot, err := CommitteeCountAtSlot(state, slot)
|
||||
if err != nil {
|
||||
return nil, 0, 0, 0, errors.Wrapf(err, "could not get committee count at slot %d", slot)
|
||||
}
|
||||
countAtSlot := SlotCommitteeCount(uint64(len(activeValidatorIndices)))
|
||||
for i := uint64(0); i < countAtSlot; i++ {
|
||||
committee, err := BeaconCommittee(state, slot, i)
|
||||
committee, err := BeaconCommitteeFromState(state, slot, i)
|
||||
if err != nil {
|
||||
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
|
||||
// a valid length matching the size of the committee.
|
||||
func VerifyAttestationBitfieldLengths(bState *pb.BeaconState, att *ethpb.Attestation) error {
|
||||
committee, err := BeaconCommittee(bState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
func VerifyAttestationBitfieldLengths(state *pb.BeaconState, att *ethpb.Attestation) error {
|
||||
committee, err := BeaconCommitteeFromState(state, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve beacon committees")
|
||||
}
|
||||
@@ -406,10 +414,9 @@ func UpdateCommitteeCache(state *pb.BeaconState) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
count, err := CommitteeCountAtSlot(state, StartSlot(epoch))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count := SlotCommitteeCount(uint64(len(shuffledIndices)))
|
||||
|
||||
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -116,7 +116,8 @@ func TestAttestationParticipants_NoCommitteeCache(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
attestationData.Target = ðpb.Checkpoint{Epoch: 0}
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -210,7 +211,7 @@ func TestAttestationParticipants_EmptyBitfield(t *testing.T) {
|
||||
}
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -394,7 +395,7 @@ func TestCommitteeAssignments_CanRetrieve(t *testing.T) {
|
||||
|
||||
state := &pb.BeaconState{
|
||||
Validators: validators,
|
||||
Slot: 2*params.BeaconConfig().SlotsPerEpoch, // epoch 2
|
||||
Slot: 2 * params.BeaconConfig().SlotsPerEpoch, // epoch 2
|
||||
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) {
|
||||
ctx, span := trace.StartSpan(ctx, "beacon-chain.ChainService.state.ProcessEpoch")
|
||||
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, err := precompute.ProcessAttestations(ctx, state, vp, bp)
|
||||
|
||||
@@ -379,7 +379,7 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
||||
blockAtt := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Slot: beaconState.Slot - 1,
|
||||
Target: ðpb.Checkpoint{Epoch: helpers.SlotToEpoch(beaconState.Slot)},
|
||||
Target: ðpb.Checkpoint{Epoch: helpers.CurrentEpoch(beaconState)},
|
||||
Source: ðpb.Checkpoint{
|
||||
Epoch: 0,
|
||||
Root: []byte("hello-world"),
|
||||
@@ -387,7 +387,8 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
|
||||
AggregationBits: aggBits,
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -633,7 +634,7 @@ func BenchmarkProcessBlk_65536Validators_FullBlock(b *testing.B) {
|
||||
|
||||
// Precache the shuffled indices
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -676,7 +677,7 @@ func TestProcessBlk_AttsBasedOnValidatorCount(t *testing.T) {
|
||||
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 {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func TestHandleAttestation_Saves_NewAttestation(t *testing.T) {
|
||||
AggregationBits: bitfield.Bitlist{0xCF, 0xC0, 0xC0, 0xC0, 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 {
|
||||
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.
|
||||
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 {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
attDataRoot, err := ssz.HashTreeRoot(att.Data)
|
||||
if err != nil {
|
||||
@@ -213,9 +213,9 @@ func TestHandleAttestation_Skips_PreviouslyAggregatedAttestations(t *testing.T)
|
||||
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 {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
aggregationBits := bitfield.NewBitlist(uint64(len(committee)))
|
||||
aggregationBits.SetBitAt(0, true)
|
||||
@@ -353,9 +353,9 @@ func TestRetrieveAttestations_OK(t *testing.T) {
|
||||
AggregationBits: aggBits,
|
||||
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 {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
attestingIndices, err := helpers.AttestingIndices(att.AggregationBits, committee)
|
||||
if err != nil {
|
||||
|
||||
@@ -8,7 +8,6 @@ go_library(
|
||||
deps = [
|
||||
"//beacon-chain/blockchain: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/sync: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/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/sync"
|
||||
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")
|
||||
}
|
||||
|
||||
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))
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
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
|
||||
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 {
|
||||
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()
|
||||
|
||||
genesis := blk.NewGenesisBlock([]byte{})
|
||||
depChainStart := uint64(8192*2)
|
||||
depChainStart := uint64(8192 * 2)
|
||||
deposits, _, _ := testutil.DeterministicDepositsAndKeys(depChainStart)
|
||||
eth1Data, err := testutil.DeterministicEth1Data(len(deposits))
|
||||
if err != nil {
|
||||
|
||||
@@ -205,7 +205,7 @@ func generateAttesterSlashings(
|
||||
attesterSlashings := make([]*ethpb.AttesterSlashing, numSlashings)
|
||||
for i := uint64(0); i < numSlashings; i++ {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -330,10 +330,11 @@ func GenerateAttestations(
|
||||
}
|
||||
}
|
||||
|
||||
committeesPerSlot, err := helpers.CommitteeCountAtSlot(bState, slot)
|
||||
activeValidatorCount, err := helpers.ActiveValidatorCount(bState, currentEpoch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
committeesPerSlot := helpers.SlotCommitteeCount(activeValidatorCount)
|
||||
|
||||
if numToGen < committeesPerSlot {
|
||||
log.Printf(
|
||||
@@ -361,7 +362,7 @@ func GenerateAttestations(
|
||||
|
||||
domain := helpers.Domain(bState.Fork, currentEpoch, params.BeaconConfig().DomainBeaconAttester)
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func main() {
|
||||
}
|
||||
// Retrieve attestation indices
|
||||
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 {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user