Skip to content

Commit

Permalink
ActiveValidatorCount to use cache (#6254)
Browse files Browse the repository at this point in the history
* Add helper to prevent zero hashes

* Test

* Add ActiveIndicesCount getter for committee cache

* ActiveIndicesCount test

* ActiveValidatorCount to use cache

* Update cache on miss

* Update tests
  • Loading branch information
terencechain committed Jun 14, 2020
1 parent f4e9e2f commit a9070ad
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 0 deletions.
2 changes: 2 additions & 0 deletions beacon-chain/blockchain/receive_attestation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"time"

ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
)

func TestVerifyCheckpointEpoch_Ok(t *testing.T) {
helpers.ClearCache()
db := testDB.SetupDB(t)

chainService := setupBeaconChain(t, db)
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/blockchain/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ func TestChainStartStop_Initialized(t *testing.T) {
}

func TestChainService_InitializeBeaconChain(t *testing.T) {
helpers.ClearCache()
db := testDB.SetupDB(t)
ctx := context.Background()

Expand Down
24 changes: 24 additions & 0 deletions beacon-chain/cache/committee.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,30 @@ func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]uint64, error) {
return item.SortedIndices, nil
}

// ActiveIndicesCount returns the active indices count of a given seed stored in cache.
func (c *CommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return 0, err
}

if exists {
CommitteeCacheHit.Inc()
} else {
CommitteeCacheMiss.Inc()
return 0, nil
}

item, ok := obj.(*Committees)
if !ok {
return 0, ErrNotCommittee
}

return len(item.SortedIndices), nil
}

// ProposerIndices returns the proposer indices of a given seed.
func (c *CommitteeCache) ProposerIndices(seed [32]byte) ([]uint64, error) {
c.lock.RLock()
Expand Down
25 changes: 25 additions & 0 deletions beacon-chain/cache/committee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,31 @@ func TestCommitteeCache_ActiveIndices(t *testing.T) {
}
}

func TestCommitteeCache_ActiveCount(t *testing.T) {
cache := NewCommitteesCache()

item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
count, err := cache.ActiveIndicesCount(item.Seed)
if err != nil {
t.Fatal(err)
}
if count != 0 {
t.Error("Expected active count not to exist in empty cache")
}

if err := cache.AddCommitteeShuffledList(item); err != nil {
t.Fatal(err)
}

count, err = cache.ActiveIndicesCount(item.Seed)
if err != nil {
t.Fatal(err)
}
if count != len(item.SortedIndices) {
t.Error("Did not receive correct active acount from cache")
}
}

func TestCommitteeCache_AddProposerIndicesList(t *testing.T) {
cache := NewCommitteesCache()

Expand Down
17 changes: 17 additions & 0 deletions beacon-chain/core/helpers/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ func ActiveValidatorIndices(state *stateTrie.BeaconState, epoch uint64) ([]uint6
// ActiveValidatorCount returns the number of active validators in the state
// at the given epoch.
func ActiveValidatorCount(state *stateTrie.BeaconState, epoch uint64) (uint64, error) {
seed, err := Seed(state, epoch, params.BeaconConfig().DomainBeaconAttester)
if err != nil {
return 0, errors.Wrap(err, "could not get seed")
}
activeCount, err := committeeCache.ActiveIndicesCount(seed)
if err != nil {
return 0, errors.Wrap(err, "could not interface with committee cache")
}
if activeCount != 0 {
return uint64(activeCount), nil
}

count := uint64(0)
if err := state.ReadFromEveryValidator(func(idx int, val *stateTrie.ReadOnlyValidator) error {
if IsActiveValidatorUsingTrie(val, epoch) {
Expand All @@ -111,6 +123,11 @@ func ActiveValidatorCount(state *stateTrie.BeaconState, epoch uint64) (uint64, e
}); err != nil {
return 0, err
}

if err := UpdateCommitteeCache(state, epoch); err != nil {
return 0, errors.Wrap(err, "could not update committee cache")
}

return count, nil
}

Expand Down
2 changes: 2 additions & 0 deletions beacon-chain/core/helpers/validators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ func TestChurnLimit_OK(t *testing.T) {
{validatorCount: 2000000, wantedChurn: 30 /* validatorCount/churnLimitQuotient */},
}
for _, test := range tests {
ClearCache()

validators := make([]*ethpb.Validator, test.validatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
Expand Down

0 comments on commit a9070ad

Please sign in to comment.