github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/prysm/v1alpha1/beacon/committees_test.go (about)

     1  package beacon
     2  
     3  import (
     4  	"context"
     5  	"encoding/binary"
     6  	"testing"
     7  	"time"
     8  
     9  	mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
    10  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    11  	dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
    12  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    13  	"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
    14  	pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    15  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    16  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    17  	"github.com/prysmaticlabs/prysm/shared/params"
    18  	"github.com/prysmaticlabs/prysm/shared/testutil"
    19  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    20  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    21  	"github.com/prysmaticlabs/prysm/shared/timeutils"
    22  	"google.golang.org/protobuf/proto"
    23  	"gopkg.in/d4l3k/messagediff.v1"
    24  )
    25  
    26  func TestServer_ListBeaconCommittees_CurrentEpoch(t *testing.T) {
    27  	db := dbTest.SetupDB(t)
    28  	helpers.ClearCache()
    29  
    30  	numValidators := 128
    31  	ctx := context.Background()
    32  	headState := setupActiveValidators(t, numValidators)
    33  
    34  	offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
    35  	m := &mock.ChainService{
    36  		Genesis: timeutils.Now().Add(time.Duration(-1*offset) * time.Second),
    37  	}
    38  	bs := &Server{
    39  		HeadFetcher:        m,
    40  		GenesisTimeFetcher: m,
    41  		StateGen:           stategen.New(db),
    42  	}
    43  	b := testutil.NewBeaconBlock()
    44  	require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
    45  	gRoot, err := b.Block.HashTreeRoot()
    46  	require.NoError(t, err)
    47  	require.NoError(t, db.SaveGenesisBlockRoot(ctx, gRoot))
    48  	require.NoError(t, db.SaveState(ctx, headState, gRoot))
    49  
    50  	activeIndices, err := helpers.ActiveValidatorIndices(headState, 0)
    51  	require.NoError(t, err)
    52  	attesterSeed, err := helpers.Seed(headState, 0, params.BeaconConfig().DomainBeaconAttester)
    53  	require.NoError(t, err)
    54  	committees, err := computeCommittees(0, activeIndices, attesterSeed)
    55  	require.NoError(t, err)
    56  
    57  	wanted := &ethpb.BeaconCommittees{
    58  		Epoch:                0,
    59  		Committees:           committees.SlotToUint64(),
    60  		ActiveValidatorCount: uint64(numValidators),
    61  	}
    62  	res, err := bs.ListBeaconCommittees(context.Background(), &ethpb.ListCommitteesRequest{
    63  		QueryFilter: &ethpb.ListCommitteesRequest_Genesis{Genesis: true},
    64  	})
    65  	require.NoError(t, err)
    66  	if !proto.Equal(res, wanted) {
    67  		t.Errorf("Expected %v, received %v", wanted, res)
    68  	}
    69  }
    70  
    71  func TestServer_ListBeaconCommittees_PreviousEpoch(t *testing.T) {
    72  	params.UseMainnetConfig()
    73  	ctx := context.Background()
    74  
    75  	db := dbTest.SetupDB(t)
    76  	helpers.ClearCache()
    77  
    78  	numValidators := 128
    79  	headState := setupActiveValidators(t, numValidators)
    80  
    81  	mixes := make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector)
    82  	for i := 0; i < len(mixes); i++ {
    83  		mixes[i] = make([]byte, 32)
    84  	}
    85  	require.NoError(t, headState.SetRandaoMixes(mixes))
    86  	require.NoError(t, headState.SetSlot(params.BeaconConfig().SlotsPerEpoch))
    87  
    88  	b := testutil.NewBeaconBlock()
    89  	require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
    90  	gRoot, err := b.Block.HashTreeRoot()
    91  	require.NoError(t, err)
    92  	require.NoError(t, db.SaveState(ctx, headState, gRoot))
    93  	require.NoError(t, db.SaveGenesisBlockRoot(ctx, gRoot))
    94  
    95  	offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
    96  	m := &mock.ChainService{
    97  		State:   headState,
    98  		Genesis: timeutils.Now().Add(time.Duration(-1*offset) * time.Second),
    99  	}
   100  	bs := &Server{
   101  		HeadFetcher:        m,
   102  		GenesisTimeFetcher: m,
   103  		StateGen:           stategen.New(db),
   104  	}
   105  
   106  	activeIndices, err := helpers.ActiveValidatorIndices(headState, 1)
   107  	require.NoError(t, err)
   108  	attesterSeed, err := helpers.Seed(headState, 1, params.BeaconConfig().DomainBeaconAttester)
   109  	require.NoError(t, err)
   110  	startSlot, err := helpers.StartSlot(1)
   111  	require.NoError(t, err)
   112  	wanted, err := computeCommittees(startSlot, activeIndices, attesterSeed)
   113  	require.NoError(t, err)
   114  
   115  	tests := []struct {
   116  		req *ethpb.ListCommitteesRequest
   117  		res *ethpb.BeaconCommittees
   118  	}{
   119  		{
   120  			req: &ethpb.ListCommitteesRequest{
   121  				QueryFilter: &ethpb.ListCommitteesRequest_Epoch{Epoch: 1},
   122  			},
   123  			res: &ethpb.BeaconCommittees{
   124  				Epoch:                1,
   125  				Committees:           wanted.SlotToUint64(),
   126  				ActiveValidatorCount: uint64(numValidators),
   127  			},
   128  		},
   129  	}
   130  	helpers.ClearCache()
   131  	for i, test := range tests {
   132  		res, err := bs.ListBeaconCommittees(context.Background(), test.req)
   133  		require.NoError(t, err)
   134  		if !proto.Equal(res, test.res) {
   135  			diff, _ := messagediff.PrettyDiff(res, test.res)
   136  			t.Errorf("%d/ Diff between responses %s", i, diff)
   137  		}
   138  	}
   139  }
   140  
   141  func TestRetrieveCommitteesForRoot(t *testing.T) {
   142  
   143  	db := dbTest.SetupDB(t)
   144  	helpers.ClearCache()
   145  	ctx := context.Background()
   146  
   147  	numValidators := 128
   148  	headState := setupActiveValidators(t, numValidators)
   149  
   150  	offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
   151  	m := &mock.ChainService{
   152  		Genesis: timeutils.Now().Add(time.Duration(-1*offset) * time.Second),
   153  	}
   154  	bs := &Server{
   155  		HeadFetcher:        m,
   156  		GenesisTimeFetcher: m,
   157  		StateGen:           stategen.New(db),
   158  	}
   159  	b := testutil.NewBeaconBlock()
   160  	require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
   161  	gRoot, err := b.Block.HashTreeRoot()
   162  	require.NoError(t, err)
   163  	require.NoError(t, db.SaveGenesisBlockRoot(ctx, gRoot))
   164  	require.NoError(t, db.SaveState(ctx, headState, gRoot))
   165  	stateSummary := &pbp2p.StateSummary{
   166  		Slot: 0,
   167  		Root: gRoot[:],
   168  	}
   169  	require.NoError(t, db.SaveStateSummary(ctx, stateSummary))
   170  
   171  	// Store the genesis seed.
   172  	seed, err := helpers.Seed(headState, 0, params.BeaconConfig().DomainBeaconAttester)
   173  	require.NoError(t, err)
   174  	require.NoError(t, headState.SetSlot(params.BeaconConfig().SlotsPerEpoch*10))
   175  
   176  	activeIndices, err := helpers.ActiveValidatorIndices(headState, 0)
   177  	require.NoError(t, err)
   178  
   179  	wanted, err := computeCommittees(0, activeIndices, seed)
   180  	require.NoError(t, err)
   181  	committees, activeIndices, err := bs.retrieveCommitteesForRoot(context.Background(), gRoot[:])
   182  	require.NoError(t, err)
   183  
   184  	wantedRes := &ethpb.BeaconCommittees{
   185  		Epoch:                0,
   186  		Committees:           wanted.SlotToUint64(),
   187  		ActiveValidatorCount: uint64(numValidators),
   188  	}
   189  	receivedRes := &ethpb.BeaconCommittees{
   190  		Epoch:                0,
   191  		Committees:           committees.SlotToUint64(),
   192  		ActiveValidatorCount: uint64(len(activeIndices)),
   193  	}
   194  	assert.DeepEqual(t, wantedRes, receivedRes)
   195  }
   196  
   197  func setupActiveValidators(t *testing.T, count int) iface.BeaconState {
   198  	balances := make([]uint64, count)
   199  	validators := make([]*ethpb.Validator, 0, count)
   200  	for i := 0; i < count; i++ {
   201  		pubKey := make([]byte, params.BeaconConfig().BLSPubkeyLength)
   202  		binary.LittleEndian.PutUint64(pubKey, uint64(i))
   203  		balances[i] = uint64(i)
   204  		validators = append(validators, &ethpb.Validator{
   205  			PublicKey:             pubKey,
   206  			ActivationEpoch:       0,
   207  			ExitEpoch:             params.BeaconConfig().FarFutureEpoch,
   208  			WithdrawalCredentials: make([]byte, 32),
   209  		})
   210  	}
   211  	s, err := testutil.NewBeaconState()
   212  	require.NoError(t, err)
   213  	if err := s.SetValidators(validators); err != nil {
   214  		t.Error(err)
   215  		return nil
   216  	}
   217  	if err := s.SetBalances(balances); err != nil {
   218  		t.Error(err)
   219  		return nil
   220  	}
   221  	return s
   222  }