From 64d0826469fb8286a03ef33c04630268136fb51f Mon Sep 17 00:00:00 2001 From: terence tsao Date: Mon, 26 Aug 2019 13:06:16 -0700 Subject: [PATCH] Update RPC service to use chain info (#3309) --- beacon-chain/blockchain/testing/BUILD.bazel | 13 ++ beacon-chain/blockchain/testing/mock.go | 67 +++++++ beacon-chain/rpc/BUILD.bazel | 1 + beacon-chain/rpc/attester_server.go | 32 ++-- beacon-chain/rpc/attester_server_test.go | 59 +----- beacon-chain/rpc/beacon_server.go | 7 +- beacon-chain/rpc/proposer_server.go | 30 ++- beacon-chain/rpc/proposer_server_test.go | 180 +++--------------- beacon-chain/rpc/service.go | 1 + beacon-chain/rpc/validator_server.go | 83 +++++--- beacon-chain/rpc/validator_server_test.go | 171 +++++------------ beacon-chain/sync/BUILD.bazel | 2 +- beacon-chain/sync/rpc_hello_test.go | 9 +- beacon-chain/sync/service_test.go | 54 ------ .../sync/validate_attester_slashing_test.go | 3 +- .../sync/validate_proposer_slashing_test.go | 3 +- .../sync/validate_voluntary_exit_test.go | 7 +- 17 files changed, 279 insertions(+), 443 deletions(-) create mode 100644 beacon-chain/blockchain/testing/BUILD.bazel create mode 100644 beacon-chain/blockchain/testing/mock.go delete mode 100644 beacon-chain/sync/service_test.go diff --git a/beacon-chain/blockchain/testing/BUILD.bazel b/beacon-chain/blockchain/testing/BUILD.bazel new file mode 100644 index 0000000000..4fd2b7c8cc --- /dev/null +++ b/beacon-chain/blockchain/testing/BUILD.bazel @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + testonly = True, + srcs = ["mock.go"], + importpath = "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing", + visibility = ["//beacon-chain:__subpackages__"], + deps = [ + "//proto/beacon/p2p/v1:go_default_library", + "//proto/eth/v1alpha1:go_default_library", + ], +) diff --git a/beacon-chain/blockchain/testing/mock.go b/beacon-chain/blockchain/testing/mock.go new file mode 100644 index 0000000000..b40d0054cc --- /dev/null +++ b/beacon-chain/blockchain/testing/mock.go @@ -0,0 +1,67 @@ +package testing + +import ( + "context" + + pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" + ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" +) + +// ChainService defines the mock interface for testing +type ChainService struct { + State *pb.BeaconState + Root []byte + FinalizedCheckPoint *ethpb.Checkpoint +} + +// ReceiveBlock mocks ReceiveBlock method in chain service. +func (ms *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.BeaconBlock) error { + return nil +} + +// ReceiveBlockNoPubsub mocks ReceiveBlockNoPubsub method in chain service. +func (ms *ChainService) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.BeaconBlock) error { + return nil +} + +// ReceiveBlockNoPubsubForkchoice mocks ReceiveBlockNoPubsubForkchoice method in chain service. +func (ms *ChainService) ReceiveBlockNoPubsubForkchoice(ctx context.Context, block *ethpb.BeaconBlock) error { + return nil +} + +// HeadSlot mocks HeadSlot method in chain service. +func (ms *ChainService) HeadSlot() uint64 { + return ms.State.Slot + +} + +// HeadRoot mocks HeadRoot method in chain service. +func (ms *ChainService) HeadRoot() []byte { + return ms.Root + +} + +// HeadBlock mocks HeadBlock method in chain service. +func (ms *ChainService) HeadBlock() *ethpb.BeaconBlock { + return nil +} + +// HeadState mocks HeadState method in chain service. +func (ms *ChainService) HeadState() *pb.BeaconState { + return ms.State +} + +// FinalizedCheckpt mocks FinalizedCheckpt method in chain service. +func (ms *ChainService) FinalizedCheckpt() *ethpb.Checkpoint { + return ms.FinalizedCheckPoint +} + +// ReceiveAttestation mocks ReceiveAttestation method in chain service. +func (ms *ChainService) ReceiveAttestation(context.Context, *ethpb.Attestation) error { + return nil +} + +// ReceiveAttestationNoPubsub mocks ReceiveAttestationNoPubsub method in chain service. +func (ms *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attestation) error { + return nil +} diff --git a/beacon-chain/rpc/BUILD.bazel b/beacon-chain/rpc/BUILD.bazel index 991da4b6b7..3f2d0f3985 100644 --- a/beacon-chain/rpc/BUILD.bazel +++ b/beacon-chain/rpc/BUILD.bazel @@ -71,6 +71,7 @@ go_test( ], embed = [":go_default_library"], deps = [ + "//beacon-chain/blockchain/testing:go_default_library", "//beacon-chain/cache:go_default_library", "//beacon-chain/cache/depositcache:go_default_library", "//beacon-chain/core/blocks:go_default_library", diff --git a/beacon-chain/rpc/attester_server.go b/beacon-chain/rpc/attester_server.go index 5f491f2826..78cfc398e6 100644 --- a/beacon-chain/rpc/attester_server.go +++ b/beacon-chain/rpc/attester_server.go @@ -6,11 +6,11 @@ import ( "github.com/pkg/errors" "github.com/prysmaticlabs/go-ssz" + "github.com/prysmaticlabs/prysm/beacon-chain/blockchain" "github.com/prysmaticlabs/prysm/beacon-chain/cache" "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/kv" "github.com/prysmaticlabs/prysm/beacon-chain/p2p" pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1" @@ -130,27 +130,25 @@ func (as *AttesterServer) RequestAttestation(ctx context.Context, req *pb.Attest // Set the attestation data's beacon block root = hash_tree_root(head) where head // is the validator's view of the head block of the beacon chain during the slot. - var headBlock *ethpb.BeaconBlock + var headRoot []byte + var headState *pbp2p.BeaconState if d, isLegacyDB := as.beaconDB.(*db.BeaconDB); isLegacyDB { - headBlock, err = d.ChainHead() + headBlock, err := d.ChainHead() if err != nil { return nil, errors.Wrap(err, "failed to retrieve chain head") } + headState, err = as.beaconDB.HeadState(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not fetch head state") + } + r, err := ssz.SigningRoot(headBlock) + if err != nil { + return nil, errors.Wrap(err, "could not tree hash beacon block") + } + headRoot = r[:] } else { - headBlock, err = as.beaconDB.(*kv.Store).HeadBlock(ctx) - if err != nil { - return nil, errors.Wrap(err, "failed to retrieve chain head") - } - } - headRoot, err := ssz.SigningRoot(headBlock) - if err != nil { - return nil, errors.Wrap(err, "could not tree hash beacon block") - } - - // Let head state be the state of head block processed through empty slots up to assigned slot. - headState, err := as.beaconDB.HeadState(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not fetch head state") + headState = as.chainService.(blockchain.HeadRetriever).HeadState() + headRoot = as.chainService.(blockchain.HeadRetriever).HeadRoot() } headState, err = state.ProcessSlots(ctx, headState, req.Slot) diff --git a/beacon-chain/rpc/attester_server_test.go b/beacon-chain/rpc/attester_server_test.go index 028f2d62c6..aa5df7ea44 100644 --- a/beacon-chain/rpc/attester_server_test.go +++ b/beacon-chain/rpc/attester_server_test.go @@ -15,6 +15,7 @@ import ( ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/params" + mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" ) type mockBroadcaster struct{} @@ -86,10 +87,6 @@ func TestSubmitAttestation_OK(t *testing.T) { } func TestRequestAttestation_OK(t *testing.T) { - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) - ctx := context.Background() - block := ðpb.BeaconBlock{ Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, } @@ -134,30 +131,11 @@ func TestRequestAttestation_OK(t *testing.T) { beaconState.BlockRoots[1*params.BeaconConfig().SlotsPerEpoch] = targetRoot[:] beaconState.BlockRoots[2*params.BeaconConfig().SlotsPerEpoch] = justifiedRoot[:] attesterServer := &AttesterServer{ - beaconDB: db, - p2p: &mockBroadcaster{}, - cache: cache.NewAttestationCache(), - } - if err := db.SaveBlock(ctx, targetBlock); err != nil { - t.Fatalf("Could not save block in test db: %v", err) + p2p: &mockBroadcaster{}, + cache: cache.NewAttestationCache(), + chainService: &mock.ChainService{State: beaconState, Root: blockRoot[:]}, } - if err := db.SaveBlock(ctx, justifiedBlock); err != nil { - t.Fatalf("Could not save block in test db: %v", err) - } - if err := db.SaveBlock(ctx, block); err != nil { - t.Fatalf("Could not save block in test db: %v", err) - } - headRoot, err := ssz.SigningRoot(block) - if err != nil { - t.Fatal(err) - } - if err := db.SaveHeadBlockRoot(ctx, headRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, headRoot); err != nil { - t.Fatal(err) - } req := &pb.AttestationRequest{ Shard: 0, Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1, @@ -201,12 +179,9 @@ func TestAttestationDataAtSlot_handlesFarAwayJustifiedEpoch(t *testing.T) { // HistoricalRootsLimit = 8192 // // More background: https://github.com/prysmaticlabs/prysm/issues/2153 - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) // This test breaks if it doesnt use mainnet config params.OverrideBeaconConfig(params.MainnetConfig()) defer params.OverrideBeaconConfig(params.MinimalSpecConfig()) - ctx := context.Background() // Ensure HistoricalRootsLimit matches scenario cfg := params.BeaconConfig() @@ -256,29 +231,11 @@ func TestAttestationDataAtSlot_handlesFarAwayJustifiedEpoch(t *testing.T) { beaconState.BlockRoots[1*params.BeaconConfig().SlotsPerEpoch] = epochBoundaryRoot[:] beaconState.BlockRoots[2*params.BeaconConfig().SlotsPerEpoch] = justifiedBlockRoot[:] attesterServer := &AttesterServer{ - beaconDB: db, - p2p: &mockBroadcaster{}, - cache: cache.NewAttestationCache(), - } - if err := db.SaveBlock(ctx, epochBoundaryBlock); err != nil { - t.Fatalf("Could not save block in test db: %v", err) - } - if err := db.SaveBlock(ctx, justifiedBlock); err != nil { - t.Fatalf("Could not save block in test db: %v", err) - } - if err := db.SaveBlock(ctx, block); err != nil { - t.Fatalf("Could not save block in test db: %v", err) - } - headRoot, err := ssz.SigningRoot(block) - if err != nil { - t.Fatal(err) - } - if err := db.SaveHeadBlockRoot(ctx, headRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, headRoot); err != nil { - t.Fatal(err) + p2p: &mockBroadcaster{}, + cache: cache.NewAttestationCache(), + chainService: &mock.ChainService{State: beaconState, Root: blockRoot[:]}, } + req := &pb.AttestationRequest{ Shard: 0, Slot: 10000, diff --git a/beacon-chain/rpc/beacon_server.go b/beacon-chain/rpc/beacon_server.go index b4283a6481..480ceb36fc 100644 --- a/beacon-chain/rpc/beacon_server.go +++ b/beacon-chain/rpc/beacon_server.go @@ -7,8 +7,8 @@ import ( ptypes "github.com/gogo/protobuf/types" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/beacon-chain/blockchain" "github.com/prysmaticlabs/prysm/beacon-chain/db" - "github.com/prysmaticlabs/prysm/beacon-chain/db/kv" pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1" ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" @@ -83,10 +83,7 @@ func (bs *BeaconServer) CanonicalHead(ctx context.Context, req *ptypes.Empty) (* return nil, errors.Wrap(err, "could not get canonical head block") } } else { - headBlock, err = bs.beaconDB.(*kv.Store).HeadBlock(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get canonical head block") - } + headBlock = bs.chainService.(blockchain.HeadRetriever).HeadBlock() } return headBlock, nil } diff --git a/beacon-chain/rpc/proposer_server.go b/beacon-chain/rpc/proposer_server.go index db3b622cea..bbe0460244 100644 --- a/beacon-chain/rpc/proposer_server.go +++ b/beacon-chain/rpc/proposer_server.go @@ -52,6 +52,7 @@ func (ps *ProposerServer) RequestBlock(ctx context.Context, req *pb.BlockRequest if err != nil { return nil, errors.Wrap(err, "could not get canonical head block") } + parent = ps.chainService.(newBlockchain.HeadRetriever).HeadBlock() } parentRoot, err := ssz.SigningRoot(parent) @@ -147,10 +148,17 @@ func (ps *ProposerServer) ProposeBlock(ctx context.Context, blk *ethpb.BeaconBlo // attestations which are ready for inclusion. That is, attestations that satisfy: // attestation.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot. func (ps *ProposerServer) attestations(ctx context.Context, expectedSlot uint64) ([]*ethpb.Attestation, error) { - beaconState, err := ps.beaconDB.HeadState(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not retrieve beacon state") + var beaconState *pbp2p.BeaconState + var err error + if _, isLegacyDB := ps.beaconDB.(*db.BeaconDB); isLegacyDB { + beaconState, err = ps.beaconDB.HeadState(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not retrieve beacon state") + } + } else { + beaconState = ps.chainService.(newBlockchain.HeadRetriever).HeadState() } + atts, err := ps.operationService.AttestationPool(ctx, expectedSlot) if err != nil { return nil, errors.Wrap(err, "could not retrieve pending attestations from operations service") @@ -240,8 +248,9 @@ func (ps *ProposerServer) eth1Data(ctx context.Context, slot uint64) (*ethpb.Eth func (ps *ProposerServer) computeStateRoot(ctx context.Context, block *ethpb.BeaconBlock) ([]byte, error) { beaconState, err := ps.beaconDB.HeadState(ctx) if err != nil { - return nil, errors.Wrap(err, "could not get beacon state") + return nil, errors.Wrap(err, "could not retrieve beacon state") } + s, err := state.ExecuteStateTransitionNoVerify( ctx, beaconState, @@ -267,10 +276,17 @@ func (ps *ProposerServer) computeStateRoot(ctx context.Context, block *ethpb.Bea func (ps *ProposerServer) deposits(ctx context.Context, currentVote *ethpb.Eth1Data) ([]*ethpb.Deposit, error) { // Need to fetch if the deposits up to the state's latest eth 1 data matches // the number of all deposits in this RPC call. If not, then we return nil. - beaconState, err := ps.beaconDB.HeadState(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not fetch beacon state") + var beaconState *pbp2p.BeaconState + var err error + if _, isLegacyDB := ps.beaconDB.(*db.BeaconDB); isLegacyDB { + beaconState, err = ps.beaconDB.HeadState(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not retrieve beacon state") + } + } else { + beaconState = ps.chainService.(newBlockchain.HeadRetriever).HeadState() } + canonicalEth1Data, latestEth1DataHeight, err := ps.canonicalEth1Data(ctx, beaconState, currentVote) if err != nil { return nil, err diff --git a/beacon-chain/rpc/proposer_server_test.go b/beacon-chain/rpc/proposer_server_test.go index 99181991be..377fd021b2 100644 --- a/beacon-chain/rpc/proposer_server_test.go +++ b/beacon-chain/rpc/proposer_server_test.go @@ -21,6 +21,7 @@ import ( "github.com/prysmaticlabs/prysm/shared/bls" "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/testutil" + mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" "github.com/prysmaticlabs/prysm/shared/trieutil" ) @@ -154,12 +155,9 @@ func TestComputeStateRoot_OK(t *testing.T) { func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) { helpers.ClearAllCaches() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) // This test breaks if it doesnt use mainnet config params.OverrideBeaconConfig(params.MainnetConfig()) defer params.OverrideBeaconConfig(params.MinimalSpecConfig()) - ctx := context.Background() validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount/8) for i := 0; i < len(validators); i++ { validators[i] = ðpb.Validator{ @@ -236,12 +234,6 @@ func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) { } att.Signature = bls.AggregateSignatures(sigs).Marshal()[:] - proposerServer := &ProposerServer{ - operationService: &mockOperationService{ - pendingAttestations: []*ethpb.Attestation{att}, - }, - beaconDB: db, - } blk := ðpb.BeaconBlock{ Slot: beaconState.Slot, } @@ -250,14 +242,11 @@ func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) + proposerServer := &ProposerServer{ + operationService: &mockOperationService{ + pendingAttestations: []*ethpb.Attestation{att}, + }, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, } atts, err := proposerServer.attestations(context.Background(), stateSlot) @@ -272,10 +261,10 @@ func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) { func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) { db := dbutil.SetupDB(t) defer dbutil.TeardownDB(t, db) + // This test breaks if it doesnt use mainnet config params.OverrideBeaconConfig(params.MainnetConfig()) defer params.OverrideBeaconConfig(params.MinimalSpecConfig()) - ctx := context.Background() // Edge case: current slot is at the end of an epoch. The pending attestation // for the next slot should come from currentSlot + 1. @@ -398,12 +387,6 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) { att3, }, } - expectedNumberOfAttestations := 3 - proposerServer := &ProposerServer{ - operationService: opService, - beaconDB: db, - } - blk := ðpb.BeaconBlock{ Slot: beaconState.Slot, } @@ -412,14 +395,11 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) + expectedNumberOfAttestations := 3 + proposerServer := &ProposerServer{ + beaconDB: db, + operationService: opService, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, } atts, err := proposerServer.attestations(context.Background(), currentSlot+params.BeaconConfig().MinAttestationInclusionDelay+1) @@ -470,8 +450,6 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) { func TestPendingDeposits_Eth1DataVoteOK(t *testing.T) { ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)) newHeight := big.NewInt(height.Int64() + 11000) @@ -502,11 +480,6 @@ func TestPendingDeposits_Eth1DataVoteOK(t *testing.T) { Eth1DataVotes: votes, } - bs := &ProposerServer{ - beaconDB: db, - powChainService: p, - } - blk := ðpb.BeaconBlock{ Body: ðpb.BeaconBlockBody{Eth1Data: ðpb.Eth1Data{}}, } @@ -516,14 +489,9 @@ func TestPendingDeposits_Eth1DataVoteOK(t *testing.T) { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) + bs := &ProposerServer{ + powChainService: p, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, } // It should also return the recent deposits after their follow window. @@ -572,8 +540,6 @@ func TestPendingDeposits_Eth1DataVoteOK(t *testing.T) { func TestPendingDeposits_OutsideEth1FollowWindow(t *testing.T) { ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)) p := &mockPOWChainService{ @@ -669,20 +635,10 @@ func TestPendingDeposits_OutsideEth1FollowWindow(t *testing.T) { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) - } - bs := &ProposerServer{ - beaconDB: db, powChainService: p, depositCache: depositCache, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, } deposits, err := bs.deposits(ctx, ðpb.Eth1Data{}) @@ -711,8 +667,6 @@ func TestPendingDeposits_OutsideEth1FollowWindow(t *testing.T) { func TestPendingDeposits_FollowsCorrectEth1Block(t *testing.T) { ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)) newHeight := big.NewInt(height.Int64() + 11000) @@ -751,16 +705,6 @@ func TestPendingDeposits_FollowsCorrectEth1Block(t *testing.T) { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) - } - var mockSig [96]byte var mockCreds [32]byte @@ -832,9 +776,9 @@ func TestPendingDeposits_FollowsCorrectEth1Block(t *testing.T) { } bs := &ProposerServer{ - beaconDB: db, powChainService: p, depositCache: depositCache, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, } deposits, err := bs.deposits(ctx, ðpb.Eth1Data{}) @@ -864,8 +808,6 @@ func TestPendingDeposits_FollowsCorrectEth1Block(t *testing.T) { func TestPendingDeposits_CantReturnBelowStateEth1DepositIndex(t *testing.T) { ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)) p := &mockPOWChainService{ latestBlockNumber: height, @@ -888,15 +830,6 @@ func TestPendingDeposits_CantReturnBelowStateEth1DepositIndex(t *testing.T) { if err != nil { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) - } var mockSig [96]byte var mockCreds [32]byte @@ -956,9 +889,9 @@ func TestPendingDeposits_CantReturnBelowStateEth1DepositIndex(t *testing.T) { } bs := &ProposerServer{ - beaconDB: db, powChainService: p, depositCache: depositCache, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, } // It should also return the recent deposits after their follow window. @@ -980,8 +913,6 @@ func TestPendingDeposits_CantReturnBelowStateEth1DepositIndex(t *testing.T) { func TestPendingDeposits_CantReturnMoreThanMax(t *testing.T) { ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)) p := &mockPOWChainService{ @@ -1005,15 +936,6 @@ func TestPendingDeposits_CantReturnMoreThanMax(t *testing.T) { if err != nil { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) - } var mockSig [96]byte var mockCreds [32]byte @@ -1072,9 +994,9 @@ func TestPendingDeposits_CantReturnMoreThanMax(t *testing.T) { } bs := &ProposerServer{ - beaconDB: db, powChainService: p, depositCache: depositCache, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, } // It should also return the recent deposits after their follow window. @@ -1094,8 +1016,6 @@ func TestPendingDeposits_CantReturnMoreThanMax(t *testing.T) { func TestPendingDeposits_CantReturnMoreDepositCount(t *testing.T) { ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)) p := &mockPOWChainService{ @@ -1119,15 +1039,6 @@ func TestPendingDeposits_CantReturnMoreDepositCount(t *testing.T) { if err != nil { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) - } var mockSig [96]byte var mockCreds [32]byte @@ -1186,7 +1097,7 @@ func TestPendingDeposits_CantReturnMoreDepositCount(t *testing.T) { } bs := &ProposerServer{ - beaconDB: db, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, powChainService: p, depositCache: depositCache, } @@ -1207,24 +1118,17 @@ func TestPendingDeposits_CantReturnMoreDepositCount(t *testing.T) { } func TestEth1Data_EmptyVotesFetchBlockHashFailure(t *testing.T) { - ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) - - proposerServer := &ProposerServer{ - beaconDB: db, - powChainService: &faultyPOWChainService{ - hashesByHeight: make(map[int][]byte), - }, - } beaconState := &pbp2p.BeaconState{ Eth1Data: ðpb.Eth1Data{ BlockHash: []byte{'a'}, }, Eth1DataVotes: []*ethpb.Eth1Data{}, } - if err := proposerServer.beaconDB.SaveState(ctx, beaconState, [32]byte{}); err != nil { - t.Fatal(err) + proposerServer := &ProposerServer{ + powChainService: &faultyPOWChainService{ + hashesByHeight: make(map[int][]byte), + }, + chainService: &mock.ChainService{State: beaconState}, } want := "could not fetch ETH1_FOLLOW_DISTANCE ancestor" if _, err := proposerServer.eth1Data(context.Background(), beaconState.Slot+1); !strings.Contains(err.Error(), want) { @@ -1234,8 +1138,6 @@ func TestEth1Data_EmptyVotesFetchBlockHashFailure(t *testing.T) { func TestDefaultEth1Data_NoBlockExists(t *testing.T) { ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)) deps := []*depositcache.DepositContainer{ @@ -1277,7 +1179,6 @@ func TestDefaultEth1Data_NoBlockExists(t *testing.T) { }, } proposerServer := &ProposerServer{ - beaconDB: db, powChainService: powChainService, depositCache: depositCache, } @@ -1302,8 +1203,6 @@ func TestDefaultEth1Data_NoBlockExists(t *testing.T) { // TODO(2312): Add more tests for edge cases and better coverage. func TestEth1Data(t *testing.T) { - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) slot := uint64(10000) @@ -1319,7 +1218,6 @@ func TestEth1Data(t *testing.T) { DepositCount: 55, }, }, - beaconDB: db, depositCache: depositcache.NewDepositCache(), } @@ -1336,8 +1234,6 @@ func TestEth1Data(t *testing.T) { func Benchmark_Eth1Data(b *testing.B) { ctx := context.Background() - db := dbutil.SetupDB(b) - defer dbutil.TeardownDB(b, db) hashesByHeight := make(map[int][]byte) @@ -1395,18 +1291,10 @@ func Benchmark_Eth1Data(b *testing.B) { if err != nil { b.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - b.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - b.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - b.Fatal(err) - } + currentHeight := params.BeaconConfig().Eth1FollowDistance + 5 proposerServer := &ProposerServer{ - beaconDB: db, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, powChainService: &mockPOWChainService{ latestBlockNumber: big.NewInt(int64(currentHeight)), hashesByHeight: hashesByHeight, @@ -1424,8 +1312,6 @@ func Benchmark_Eth1Data(b *testing.B) { func TestDeposits_ReturnsEmptyList_IfLatestEth1DataEqGenesisEth1Block(t *testing.T) { ctx := context.Background() - db := dbutil.SetupDB(t) - defer dbutil.TeardownDB(t, db) height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)) p := &mockPOWChainService{ @@ -1449,15 +1335,7 @@ func TestDeposits_ReturnsEmptyList_IfLatestEth1DataEqGenesisEth1Block(t *testing if err != nil { t.Fatal(err) } - if err := db.SaveBlock(ctx, blk); err != nil { - t.Fatalf("failed to save block %v", err) - } - if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil { - t.Fatal(err) - } - if err := db.SaveState(ctx, beaconState, blkRoot); err != nil { - t.Fatal(err) - } + var mockSig [96]byte var mockCreds [32]byte @@ -1516,7 +1394,7 @@ func TestDeposits_ReturnsEmptyList_IfLatestEth1DataEqGenesisEth1Block(t *testing } bs := &ProposerServer{ - beaconDB: db, + chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]}, powChainService: p, depositCache: depositCache, } diff --git a/beacon-chain/rpc/service.go b/beacon-chain/rpc/service.go index 799ed7a293..5bb75dcec3 100644 --- a/beacon-chain/rpc/service.go +++ b/beacon-chain/rpc/service.go @@ -180,6 +180,7 @@ func (s *Service) Start() { validatorServer := &ValidatorServer{ ctx: s.ctx, beaconDB: s.beaconDB, + chainService: s.chainService, canonicalStateChan: s.canonicalStateChan, powChainService: s.powChainService, depositCache: s.depositCache, diff --git a/beacon-chain/rpc/validator_server.go b/beacon-chain/rpc/validator_server.go index d514830569..e319e2178a 100644 --- a/beacon-chain/rpc/validator_server.go +++ b/beacon-chain/rpc/validator_server.go @@ -8,6 +8,7 @@ import ( "time" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/beacon-chain/blockchain" "github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/beacon-chain/core/state" @@ -29,6 +30,7 @@ import ( type ValidatorServer struct { ctx context.Context beaconDB db.Database + chainService interface{} canonicalStateChan chan *pbp2p.BeaconState powChainService powChainService depositCache *depositcache.DepositCache @@ -104,6 +106,7 @@ func (vs *ValidatorServer) ValidatorIndex(ctx context.Context, req *pb.Validator func (vs *ValidatorServer) ValidatorPerformance( ctx context.Context, req *pb.ValidatorPerformanceRequest, ) (*pb.ValidatorPerformanceResponse, error) { + var headState *pbp2p.BeaconState var index uint64 var ok bool var err error @@ -112,6 +115,10 @@ func (vs *ValidatorServer) ValidatorPerformance( if err != nil { return nil, status.Errorf(codes.Internal, "could not retrieve validator index: %v", err) } + headState, err = vs.beaconDB.HeadState(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not get head") + } } else { index, ok, err = vs.beaconDB.ValidatorIndex(ctx, bytesutil.ToBytes48(req.PublicKey)) if err != nil { @@ -120,27 +127,26 @@ func (vs *ValidatorServer) ValidatorPerformance( if !ok { return nil, status.Errorf(codes.Internal, "could validator index for public key %#x not found", req.PublicKey) } + headState = vs.chainService.(blockchain.HeadRetriever).HeadState() + } - head, err := vs.beaconDB.HeadState(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get head") - } - activeCount, err := helpers.ActiveValidatorCount(head, helpers.SlotToEpoch(req.Slot)) + + activeCount, err := helpers.ActiveValidatorCount(headState, helpers.SlotToEpoch(req.Slot)) if err != nil { return nil, errors.Wrap(err, "could not retrieve active validator count") } - totalActiveBalance, err := helpers.TotalActiveBalance(head) + totalActiveBalance, err := helpers.TotalActiveBalance(headState) if err != nil { return nil, errors.Wrap(err, "could not retrieve active balance") } avgBalance := float32(totalActiveBalance / activeCount) - balance := head.Balances[index] + balance := headState.Balances[index] return &pb.ValidatorPerformanceResponse{ Balance: balance, AverageActiveValidatorBalance: avgBalance, - TotalValidators: uint64(len(head.Validators)), + TotalValidators: uint64(len(headState.Validators)), TotalActiveValidators: uint64(activeCount), }, nil } @@ -152,9 +158,15 @@ func (vs *ValidatorServer) ValidatorPerformance( // 3.) The slot at which the committee is assigned. // 4.) The bool signaling if the validator is expected to propose a block at the assigned slot. func (vs *ValidatorServer) CommitteeAssignment(ctx context.Context, req *pb.AssignmentRequest) (*pb.AssignmentResponse, error) { - s, err := vs.beaconDB.HeadState(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not fetch beacon state") + var s *pbp2p.BeaconState + var err error + if _, isLegacyDB := vs.beaconDB.(*db.BeaconDB); isLegacyDB { + s, err = vs.beaconDB.HeadState(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not retrieve beacon state") + } + } else { + s = vs.chainService.(blockchain.HeadRetriever).HeadState() } // Advance state with empty transitions up to the requested epoch start slot. @@ -257,14 +269,21 @@ func (vs *ValidatorServer) assignment( func (vs *ValidatorServer) ValidatorStatus( ctx context.Context, req *pb.ValidatorIndexRequest) (*pb.ValidatorStatusResponse, error) { - beaconState, err := vs.beaconDB.HeadState(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not fetch beacon state") + var headState *pbp2p.BeaconState + var err error + if _, isLegacyDB := vs.beaconDB.(*db.BeaconDB); isLegacyDB { + headState, err = vs.beaconDB.HeadState(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not retrieve beacon state") + } + } else { + headState = vs.chainService.(blockchain.HeadRetriever).HeadState() } + chainStarted := vs.powChainService.HasChainStarted() chainStartKeys := vs.chainStartPubkeys() - validatorIndexMap := stateutils.ValidatorIndexMap(beaconState) - return vs.validatorStatus(ctx, req.PublicKey, chainStarted, chainStartKeys, validatorIndexMap, beaconState), nil + validatorIndexMap := stateutils.ValidatorIndexMap(headState) + return vs.validatorStatus(ctx, req.PublicKey, chainStarted, chainStartKeys, validatorIndexMap, headState), nil } // MultipleValidatorStatus returns the validator status response for the set of validators @@ -274,19 +293,26 @@ func (vs *ValidatorServer) MultipleValidatorStatus( pubkeys [][]byte) (bool, []*pb.ValidatorActivationResponse_Status, error) { activeValidatorExists := false statusResponses := make([]*pb.ValidatorActivationResponse_Status, len(pubkeys)) - beaconState, err := vs.beaconDB.HeadState(ctx) - if err != nil { - return false, nil, err + var headState *pbp2p.BeaconState + var err error + if _, isLegacyDB := vs.beaconDB.(*db.BeaconDB); isLegacyDB { + headState, err = vs.beaconDB.HeadState(ctx) + if err != nil { + return false, nil, errors.Wrap(err, "could not retrieve beacon state") + } + } else { + headState = vs.chainService.(blockchain.HeadRetriever).HeadState() } + chainStarted := vs.powChainService.HasChainStarted() chainStartKeys := vs.chainStartPubkeys() - validatorIndexMap := stateutils.ValidatorIndexMap(beaconState) + validatorIndexMap := stateutils.ValidatorIndexMap(headState) for i, key := range pubkeys { if ctx.Err() != nil { return false, nil, ctx.Err() } - status := vs.validatorStatus(ctx, key, chainStarted, chainStartKeys, validatorIndexMap, beaconState) + status := vs.validatorStatus(ctx, key, chainStarted, chainStartKeys, validatorIndexMap, headState) if status == nil { continue } @@ -491,11 +517,18 @@ func (vs *ValidatorServer) chainStartPubkeys() map[[96]byte]bool { // DomainData fetches the current domain version information from the beacon state. func (vs *ValidatorServer) DomainData(ctx context.Context, request *pb.DomainRequest) (*pb.DomainResponse, error) { - state, err := vs.beaconDB.HeadState(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not retrieve beacon state") + var headState *pbp2p.BeaconState + var err error + if _, isLegacyDB := vs.beaconDB.(*db.BeaconDB); isLegacyDB { + headState, err = vs.beaconDB.HeadState(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not retrieve beacon state") + } + } else { + headState = vs.chainService.(blockchain.HeadRetriever).HeadState() } - dv := helpers.Domain(state, request.Epoch, request.Domain) + + dv := helpers.Domain(headState, request.Epoch, request.Domain) return &pb.DomainResponse{ SignatureDomain: dv, }, nil diff --git a/beacon-chain/rpc/validator_server_test.go b/beacon-chain/rpc/validator_server_test.go index 955144129e..2f95c605fa 100644 --- a/beacon-chain/rpc/validator_server_test.go +++ b/beacon-chain/rpc/validator_server_test.go @@ -27,6 +27,7 @@ import ( "github.com/prysmaticlabs/prysm/shared/bytesutil" "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/testutil" + mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" "github.com/prysmaticlabs/prysm/shared/trieutil" ) @@ -75,15 +76,9 @@ func TestNextEpochCommitteeAssignment_WrongPubkeyLength(t *testing.T) { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - - if err := db.SaveState(ctx, beaconState, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } validatorServer := &ValidatorServer{ - beaconDB: db, + beaconDB: db, + chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]}, } req := &pb.AssignmentRequest{ PublicKeys: [][]byte{{1}}, @@ -110,15 +105,8 @@ func TestNextEpochCommitteeAssignment_CantFindValidatorIdx(t *testing.T) { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - - if err := db.SaveState(ctx, beaconState, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } vs := &ValidatorServer{ - beaconDB: db, + chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]}, } pubKey := make([]byte, 96) @@ -151,14 +139,6 @@ func TestCommitteeAssignment_OK(t *testing.T) { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - - if err := db.SaveState(ctx, state, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - var wg sync.WaitGroup numOfValidators := int(depChainStart) errs := make(chan error, numOfValidators) @@ -178,7 +158,8 @@ func TestCommitteeAssignment_OK(t *testing.T) { } vs := &ValidatorServer{ - beaconDB: db, + beaconDB: db, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } // Test the first validator in registry. @@ -240,14 +221,6 @@ func TestCommitteeAssignment_CurrentEpoch_ShouldNotFail(t *testing.T) { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - - if err := db.SaveState(ctx, state, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - var wg sync.WaitGroup numOfValidators := int(depChainStart) errs := make(chan error, numOfValidators) @@ -267,7 +240,8 @@ func TestCommitteeAssignment_CurrentEpoch_ShouldNotFail(t *testing.T) { } vs := &ValidatorServer{ - beaconDB: db, + beaconDB: db, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } // Test the first validator in registry. @@ -301,14 +275,6 @@ func TestCommitteeAssignment_MultipleKeys_OK(t *testing.T) { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - - if err := db.SaveState(ctx, state, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - var wg sync.WaitGroup numOfValidators := int(depChainStart) errs := make(chan error, numOfValidators) @@ -328,7 +294,8 @@ func TestCommitteeAssignment_MultipleKeys_OK(t *testing.T) { } vs := &ValidatorServer{ - beaconDB: db, + beaconDB: db, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } pubkey0 := deposits[0].Data.PublicKey @@ -370,19 +337,16 @@ func TestValidatorStatus_PendingActive(t *testing.T) { t.Fatalf("Could not save genesis state: %v", err) } // Pending active because activation epoch is still defaulted at far future slot. - if err := db.SaveState( - ctx, - &pbp2p.BeaconState{ - Validators: []*ethpb.Validator{ - { - ActivationEpoch: params.BeaconConfig().FarFutureEpoch, - PublicKey: pubKey, - }, + state := &pbp2p.BeaconState{ + Validators: []*ethpb.Validator{ + { + ActivationEpoch: params.BeaconConfig().FarFutureEpoch, + PublicKey: pubKey, }, - Slot: 5000, }, - genesisRoot, - ); err != nil { + Slot: 5000, + } + if err := db.SaveState(ctx, state, genesisRoot); err != nil { t.Fatalf("could not save state: %v", err) } depData := ðpb.Deposit_Data{ @@ -410,6 +374,7 @@ func TestValidatorStatus_PendingActive(t *testing.T) { }, }, depositCache: depositCache, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } req := &pb.ValidatorIndexRequest{ PublicKey: pubKey, @@ -463,19 +428,15 @@ func TestValidatorStatus_Active(t *testing.T) { if err != nil { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, &pbp2p.BeaconState{ + + state := &pbp2p.BeaconState{ GenesisTime: uint64(time.Unix(0, 0).Unix()), Slot: 10000, Validators: []*ethpb.Validator{{ ActivationEpoch: activeEpoch, ExitEpoch: params.BeaconConfig().FarFutureEpoch, PublicKey: pubKey}, - }}, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } + }} timestamp := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix() vs := &ValidatorServer{ @@ -486,6 +447,7 @@ func TestValidatorStatus_Active(t *testing.T) { }, }, depositCache: depositCache, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } req := &pb.ValidatorIndexRequest{ PublicKey: pubKey, @@ -528,19 +490,16 @@ func TestValidatorStatus_InitiatedExit(t *testing.T) { if err != nil { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, &pbp2p.BeaconState{ + + state := &pbp2p.BeaconState{ Slot: slot, Validators: []*ethpb.Validator{{ PublicKey: pubKey, ActivationEpoch: 0, ExitEpoch: exitEpoch, WithdrawableEpoch: withdrawableEpoch}, - }}, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } + }} + depData := ðpb.Deposit_Data{ PublicKey: pubKey, Signature: []byte("hi"), @@ -565,6 +524,7 @@ func TestValidatorStatus_InitiatedExit(t *testing.T) { }, }, depositCache: depositCache, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } req := &pb.ValidatorIndexRequest{ PublicKey: pubKey, @@ -599,18 +559,14 @@ func TestValidatorStatus_Withdrawable(t *testing.T) { if err != nil { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, &pbp2p.BeaconState{ + + state := &pbp2p.BeaconState{ Slot: 10000, Validators: []*ethpb.Validator{{ WithdrawableEpoch: epoch - 1, ExitEpoch: epoch - 2, PublicKey: pubKey}, - }}, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } + }} depData := ðpb.Deposit_Data{ PublicKey: pubKey, Signature: []byte("hi"), @@ -635,6 +591,7 @@ func TestValidatorStatus_Withdrawable(t *testing.T) { }, }, depositCache: depositCache, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } req := &pb.ValidatorIndexRequest{ PublicKey: pubKey, @@ -669,18 +626,14 @@ func TestValidatorStatus_ExitedSlashed(t *testing.T) { if err != nil { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, &pbp2p.BeaconState{ + + state := &pbp2p.BeaconState{ Slot: slot, Validators: []*ethpb.Validator{{ Slashed: true, PublicKey: pubKey, WithdrawableEpoch: epoch + 1}, - }}, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } + }} depData := ðpb.Deposit_Data{ PublicKey: pubKey, Signature: []byte("hi"), @@ -705,6 +658,7 @@ func TestValidatorStatus_ExitedSlashed(t *testing.T) { }, }, depositCache: depositCache, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } req := &pb.ValidatorIndexRequest{ PublicKey: pubKey, @@ -742,14 +696,12 @@ func TestValidatorStatus_Exited(t *testing.T) { if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { t.Fatalf("Could not save genesis state: %v", err) } - if err := db.SaveState(ctx, &pbp2p.BeaconState{ + state := &pbp2p.BeaconState{ Slot: slot, Validators: []*ethpb.Validator{{ PublicKey: pubKey, WithdrawableEpoch: epoch + 1}, - }}, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } + }} depData := ðpb.Deposit_Data{ PublicKey: pubKey, Signature: []byte("hi"), @@ -774,6 +726,7 @@ func TestValidatorStatus_Exited(t *testing.T) { }, }, depositCache: depositCache, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } req := &pb.ValidatorIndexRequest{ PublicKey: pubKey, @@ -805,18 +758,13 @@ func TestValidatorStatus_UnknownStatus(t *testing.T) { if err != nil { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, &pbp2p.BeaconState{ + state := &pbp2p.BeaconState{ Slot: 0, Validators: []*ethpb.Validator{{ ActivationEpoch: 0, ExitEpoch: params.BeaconConfig().FarFutureEpoch, PublicKey: pubKey}, - }}, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } + }} depData := ðpb.Deposit_Data{ PublicKey: pubKey, Signature: []byte("hi"), @@ -841,6 +789,7 @@ func TestValidatorStatus_UnknownStatus(t *testing.T) { }, }, depositCache: depositCache, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } req := &pb.ValidatorIndexRequest{ PublicKey: pubKey, @@ -871,12 +820,6 @@ func TestWaitForActivation_ContextClosed(t *testing.T) { if err != nil { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, beaconState, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } ctx, cancel := context.WithCancel(context.Background()) vs := &ValidatorServer{ @@ -885,6 +828,7 @@ func TestWaitForActivation_ContextClosed(t *testing.T) { powChainService: &mockPOWChainService{}, canonicalStateChan: make(chan *pbp2p.BeaconState, 1), depositCache: depositcache.NewDepositCache(), + chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]}, } req := &pb.ValidatorActivationRequest{ PublicKeys: [][]byte{[]byte("A")}, @@ -950,19 +894,10 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) { }, } block := blk.NewGenesisBlock([]byte{}) - if err := db.SaveBlock(ctx, block); err != nil { - t.Fatalf("Could not save genesis block: %v", err) - } genesisRoot, err := ssz.SigningRoot(block) if err != nil { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, beaconState, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } depData := ðpb.Deposit_Data{ PublicKey: pubKey1, WithdrawalCredentials: []byte("hey"), @@ -995,6 +930,7 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) { canonicalStateChan: make(chan *pbp2p.BeaconState, 1), powChainService: &mockPOWChainService{}, depositCache: depositCache, + chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]}, } req := &pb.ValidatorActivationRequest{ PublicKeys: [][]byte{pubKey1, pubKey2}, @@ -1059,19 +995,10 @@ func TestMultipleValidatorStatus_OK(t *testing.T) { }, } block := blk.NewGenesisBlock([]byte{}) - if err := db.SaveBlock(ctx, block); err != nil { - t.Fatalf("Could not save genesis block: %v", err) - } genesisRoot, err := ssz.SigningRoot(block) if err != nil { t.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - t.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, beaconState, genesisRoot); err != nil { - t.Fatalf("could not save state: %v", err) - } depData := ðpb.Deposit_Data{ PublicKey: []byte{'A'}, Signature: []byte("hi"), @@ -1116,6 +1043,7 @@ func TestMultipleValidatorStatus_OK(t *testing.T) { canonicalStateChan: make(chan *pbp2p.BeaconState, 1), powChainService: &mockPOWChainService{}, depositCache: depositCache, + chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]}, } activeExists, response, err := vs.MultipleValidatorStatus(context.Background(), pubKeys) if err != nil { @@ -1159,12 +1087,6 @@ func BenchmarkAssignment(b *testing.B) { if err != nil { b.Fatalf("Could not get signing root %v", err) } - if err := db.SaveHeadBlockRoot(ctx, genesisRoot); err != nil { - b.Fatalf("Could not save genesis state: %v", err) - } - if err := db.SaveState(ctx, state, genesisRoot); err != nil { - b.Fatalf("could not save state: %v", err) - } var wg sync.WaitGroup errs := make(chan error, validatorCount) for i := 0; i < int(validatorCount); i++ { @@ -1185,7 +1107,8 @@ func BenchmarkAssignment(b *testing.B) { } vs := &ValidatorServer{ - beaconDB: db, + beaconDB: db, + chainService: &mock.ChainService{State: state, Root: genesisRoot[:]}, } // Set up request for 100 public keys at a time diff --git a/beacon-chain/sync/BUILD.bazel b/beacon-chain/sync/BUILD.bazel index 205323df49..23e31dcf16 100644 --- a/beacon-chain/sync/BUILD.bazel +++ b/beacon-chain/sync/BUILD.bazel @@ -63,7 +63,6 @@ go_test( "rpc_hello_test.go", "rpc_recent_beacon_blocks_test.go", "rpc_test.go", - "service_test.go", "subscriber_test.go", "validate_attester_slashing_test.go", "validate_beacon_attestation_test.go", @@ -74,6 +73,7 @@ go_test( embed = [":go_default_library"], flaky = True, # libp2p hosts are flaky upstream. deps = [ + "//beacon-chain/blockchain/testing:go_default_library", "//beacon-chain/core/helpers:go_default_library", "//beacon-chain/core/state:go_default_library", "//beacon-chain/db/testing:go_default_library", diff --git a/beacon-chain/sync/rpc_hello_test.go b/beacon-chain/sync/rpc_hello_test.go index 8392504a03..f2d94e9e28 100644 --- a/beacon-chain/sync/rpc_hello_test.go +++ b/beacon-chain/sync/rpc_hello_test.go @@ -16,6 +16,7 @@ import ( ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/testutil" + mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" ) func TestHelloRPCHandler_Disconnects_OnForkVersionMismatch(t *testing.T) { @@ -94,10 +95,10 @@ func TestHelloRPCHandler_ReturnsHelloMessage(t *testing.T) { r := &RegularSync{ p2p: p1, - chain: &mockChainService{ - headState: genesisState, - finalizedCheckpt: finalizedCheckpt, - headRoot: headRoot[:], + chain: &mock.ChainService{ + State: genesisState, + FinalizedCheckPoint: finalizedCheckpt, + Root: headRoot[:], }, } diff --git a/beacon-chain/sync/service_test.go b/beacon-chain/sync/service_test.go deleted file mode 100644 index 1c550cc3bd..0000000000 --- a/beacon-chain/sync/service_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package sync - -import ( - "context" - - pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" - ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" -) - -type mockChainService struct { - headState *pb.BeaconState - headRoot []byte - finalizedCheckpt *ethpb.Checkpoint -} - -func (ms *mockChainService) ReceiveBlock(ctx context.Context, block *ethpb.BeaconBlock) error { - return nil -} - -func (ms *mockChainService) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.BeaconBlock) error { - return nil -} - -func (ms *mockChainService) ReceiveBlockNoPubsubForkchoice(ctx context.Context, block *ethpb.BeaconBlock) error { - return nil -} - -func (ms *mockChainService) HeadSlot() uint64 { - return ms.headState.Slot - -} -func (ms *mockChainService) HeadRoot() []byte { - return ms.headRoot - -} -func (ms *mockChainService) HeadBlock() *ethpb.BeaconBlock { - return nil -} - -func (ms *mockChainService) HeadState() *pb.BeaconState { - return ms.headState -} - -func (ms *mockChainService) FinalizedCheckpt() *ethpb.Checkpoint { - return ms.finalizedCheckpt -} - -func (ms *mockChainService) ReceiveAttestation(context.Context, *ethpb.Attestation) error { - return nil -} - -func (ms *mockChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attestation) error { - return nil -} diff --git a/beacon-chain/sync/validate_attester_slashing_test.go b/beacon-chain/sync/validate_attester_slashing_test.go index 0f3f412cd7..ec797530c9 100644 --- a/beacon-chain/sync/validate_attester_slashing_test.go +++ b/beacon-chain/sync/validate_attester_slashing_test.go @@ -14,6 +14,7 @@ import ( "github.com/prysmaticlabs/prysm/shared/bls" "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/testutil" + mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" ) func setupValidAttesterSlashing(t *testing.T) (*ethpb.AttesterSlashing, *pb.BeaconState) { @@ -94,7 +95,7 @@ func TestValidateAttesterSlashing_ValidSlashing(t *testing.T) { r := &RegularSync{ p2p: p2p, - chain: &mockChainService{headState: s}, + chain: &mock.ChainService{State: s}, } if !r.validateAttesterSlashing(ctx, slashing, p2p) { diff --git a/beacon-chain/sync/validate_proposer_slashing_test.go b/beacon-chain/sync/validate_proposer_slashing_test.go index ae20f3dcaf..663ed47371 100644 --- a/beacon-chain/sync/validate_proposer_slashing_test.go +++ b/beacon-chain/sync/validate_proposer_slashing_test.go @@ -12,6 +12,7 @@ import ( ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" "github.com/prysmaticlabs/prysm/shared/bls" "github.com/prysmaticlabs/prysm/shared/params" + mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" ) func setupValidProposerSlashing(t *testing.T) (*ethpb.ProposerSlashing, *pb.BeaconState) { @@ -99,7 +100,7 @@ func TestValidateProposerSlashing_ValidSlashing(t *testing.T) { r := &RegularSync{ p2p: p2p, - chain: &mockChainService{headState: s}, + chain: &mock.ChainService{State: s}, } if !r.validateProposerSlashing(ctx, slashing, p2p) { diff --git a/beacon-chain/sync/validate_voluntary_exit_test.go b/beacon-chain/sync/validate_voluntary_exit_test.go index 99415a91b3..ff68d08ff8 100644 --- a/beacon-chain/sync/validate_voluntary_exit_test.go +++ b/beacon-chain/sync/validate_voluntary_exit_test.go @@ -12,6 +12,7 @@ import ( ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" "github.com/prysmaticlabs/prysm/shared/bls" "github.com/prysmaticlabs/prysm/shared/params" + mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" ) func setupValidExit(t *testing.T) (*ethpb.VoluntaryExit, *pb.BeaconState) { @@ -62,8 +63,10 @@ func TestValidateVoluntaryExit_ValidExit(t *testing.T) { exit, s := setupValidExit(t) r := &RegularSync{ - p2p: p2p, - chain: &mockChainService{headState: s}, + p2p: p2p, + chain: &mock.ChainService{ + State: s, + }, } if !r.validateVoluntaryExit(ctx, exit, p2p) {