Optimize committee helpers (#4328)

This commit is contained in:
terence tsao
2019-12-19 15:40:51 -08:00
committed by GitHub
parent da637668a8
commit 2e4908e7c4
23 changed files with 161 additions and 118 deletions

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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",

View File

@@ -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

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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

View File

@@ -116,7 +116,8 @@ func TestAttestationParticipants_NoCommitteeCache(t *testing.T) {
for _, tt := range tests {
attestationData.Target = &ethpb.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 := &ethpb.AttestationData{Target: &ethpb.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),
}

View File

@@ -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)

View File

@@ -379,7 +379,7 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
blockAtt := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Slot: beaconState.Slot - 1,
Target: &ethpb.Checkpoint{Epoch: helpers.SlotToEpoch(beaconState.Slot)},
Target: &ethpb.Checkpoint{Epoch: helpers.CurrentEpoch(beaconState)},
Source: &ethpb.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)
}

View File

@@ -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 {

View File

@@ -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",

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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)
}