diff --git a/beacon-chain/core/blocks/block_operations.go b/beacon-chain/core/blocks/block_operations.go index 82ca35c31..075a5c661 100644 --- a/beacon-chain/core/blocks/block_operations.go +++ b/beacon-chain/core/blocks/block_operations.go @@ -82,7 +82,7 @@ func ProcessBlockRandao(beaconState *pb.BeaconState, block *pb.BeaconBlock, veri if err != nil { return nil, fmt.Errorf("could not get beacon proposer index: %v", err) } - log.WithField("proposerIndex", proposerIdx).Info("Verifying randao") + log.WithField("proposerIndex", proposerIdx).Info("RANDAO expected proposer") proposer := beaconState.ValidatorRegistry[proposerIdx] if verifySignatures { if err := verifyBlockRandao(beaconState, block, proposer); err != nil { diff --git a/beacon-chain/operations/service.go b/beacon-chain/operations/service.go index e3e19f9ec..2db1b44c6 100644 --- a/beacon-chain/operations/service.go +++ b/beacon-chain/operations/service.go @@ -116,7 +116,6 @@ func (s *Service) PendingAttestations() ([]*pb.Attestation, error) { } attestations = append(attestations, attestationsFromDB[i]) } - log.Infof("%d Attestations obtained from DB in operations service", len(attestations)) return attestations, nil } diff --git a/beacon-chain/rpc/attester_server.go b/beacon-chain/rpc/attester_server.go index 6bf9ee15f..00e4f7a80 100644 --- a/beacon-chain/rpc/attester_server.go +++ b/beacon-chain/rpc/attester_server.go @@ -88,8 +88,6 @@ func (as *AttesterServer) AttestationDataAtSlot(ctx context.Context, req *pb.Att epochBoundaryRoot = blockRoot[:] justifiedBlockRoot = blockRoot[:] } - log.Infof("Fetching epoch boundary root: %#x, state slot: %d", epochBoundaryRoot, beaconState.Slot-params.BeaconConfig().GenesisSlot) - log.Infof("Fetching justified block root: %#x, state slot: %d", justifiedBlockRoot, beaconState.Slot-params.BeaconConfig().GenesisSlot) return &pb.AttestationDataResponse{ BeaconBlockRootHash32: blockRoot[:], EpochBoundaryRootHash32: epochBoundaryRoot, diff --git a/beacon-chain/rpc/validator_server.go b/beacon-chain/rpc/validator_server.go index 1b73cbb7d..0cd266b6d 100644 --- a/beacon-chain/rpc/validator_server.go +++ b/beacon-chain/rpc/validator_server.go @@ -4,6 +4,9 @@ import ( "context" "fmt" + "github.com/prysmaticlabs/prysm/beacon-chain/core/state" + "github.com/prysmaticlabs/prysm/shared/bytesutil" + "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/beacon-chain/db" pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1" @@ -47,6 +50,17 @@ func (vs *ValidatorServer) ValidatorEpochAssignments( if err != nil { return nil, fmt.Errorf("could not get beacon state: %v", err) } + head, err := vs.beaconDB.ChainHead() + if err != nil { + return nil, fmt.Errorf("could not get chain head: %v", err) + } + headRoot := bytesutil.ToBytes32(head.ParentRootHash32) + beaconState, err = state.ExecuteStateTransition( + beaconState, nil /* block */, headRoot, false, /* verify signatures */ + ) + if err != nil { + return nil, fmt.Errorf("could not execute head transition: %v", err) + } validatorIndex, err := vs.beaconDB.ValidatorIndex(req.PublicKey) if err != nil { return nil, fmt.Errorf("could not get validator index: %v", err) @@ -98,6 +112,19 @@ func (vs *ValidatorServer) ValidatorCommitteeAtSlot(ctx context.Context, req *pb if err != nil { return nil, fmt.Errorf("could not fetch beacon state: %v", err) } + if req.Slot%params.BeaconConfig().SlotsPerEpoch == 0 { + head, err := vs.beaconDB.ChainHead() + if err != nil { + return nil, fmt.Errorf("could not get chain head: %v", err) + } + headRoot := bytesutil.ToBytes32(head.ParentRootHash32) + beaconState, err = state.ExecuteStateTransition( + beaconState, nil /* block */, headRoot, false, /* verify signatures */ + ) + if err != nil { + return nil, fmt.Errorf("could not execute head transition: %v", err) + } + } var registryChanged bool if beaconState.ValidatorRegistryUpdateEpoch == helpers.SlotToEpoch(req.Slot)-1 && beaconState.ValidatorRegistryUpdateEpoch != params.BeaconConfig().GenesisEpoch { @@ -141,7 +168,7 @@ func (vs *ValidatorServer) CommitteeAssignment( ctx context.Context, req *pb.ValidatorEpochAssignmentsRequest) (*pb.CommitteeAssignmentResponse, error) { - state, err := vs.beaconDB.State(ctx) + beaconState, err := vs.beaconDB.State(ctx) if err != nil { return nil, fmt.Errorf("could not fetch beacon state: %v", err) } @@ -151,7 +178,7 @@ func (vs *ValidatorServer) CommitteeAssignment( } committee, shard, slot, isProposer, err := - helpers.CommitteeAssignment(state, req.EpochStart, uint64(idx), false) + helpers.CommitteeAssignment(beaconState, req.EpochStart, uint64(idx), false) if err != nil { return nil, fmt.Errorf("could not get next epoch committee assignment: %v", err) } diff --git a/beacon-chain/rpc/validator_server_test.go b/beacon-chain/rpc/validator_server_test.go index c09fa6e7f..18df1a5a1 100644 --- a/beacon-chain/rpc/validator_server_test.go +++ b/beacon-chain/rpc/validator_server_test.go @@ -10,12 +10,14 @@ import ( "testing" "time" + "github.com/gogo/protobuf/proto" b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/beacon-chain/core/state" "github.com/prysmaticlabs/prysm/beacon-chain/internal" pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1" + "github.com/prysmaticlabs/prysm/shared/hashutil" "github.com/prysmaticlabs/prysm/shared/params" ) @@ -40,6 +42,76 @@ func TestValidatorIndex_OK(t *testing.T) { } } +func TestValidatorEpochAssignments_CorrectAssignmentsAtEpochBoundary(t *testing.T) { + db := internal.SetupDB(t) + defer internal.TeardownDB(t, db) + + genesis := b.NewGenesisBlock([]byte{}) + if err := db.SaveBlock(genesis); err != nil { + t.Fatalf("Could not save genesis block: %v", err) + } + genesisRoot, err := hashutil.HashBeaconBlock(genesis) + if err != nil { + t.Fatal(err) + } + + var pubKey [96]byte + copy(pubKey[:], []byte("0")) + if err := db.SaveValidatorIndex(pubKey[:], 0); err != nil { + t.Fatalf("Could not save validator index: %v", err) + } + + beaconState, err := genesisState(1000) + if err != nil { + t.Fatalf("Could not setup genesis state: %v", err) + } + + if err := db.UpdateChainHead(genesis, beaconState); err != nil { + t.Fatalf("Could not save genesis state: %v", err) + } + + validatorServer := &ValidatorServer{ + beaconDB: db, + } + req := &pb.ValidatorEpochAssignmentsRequest{ + EpochStart: params.BeaconConfig().GenesisSlot, + PublicKey: pubKey[:], + } + assignmentsForEpoch0, err := validatorServer.ValidatorEpochAssignments(context.Background(), req) + if err != nil { + t.Fatalf("Could not fetch assignments for epoch 1: %v", err) + } + + lastSlotInEpoch0 := params.BeaconConfig().GenesisSlot + (params.BeaconConfig().SlotsPerEpoch) - 1 + for beaconState.Slot < lastSlotInEpoch0 { + beaconState, err = state.ExecuteStateTransition( + beaconState, + nil, + genesisRoot, + true, /* sig verify */ + ) + if err != nil { + t.Fatalf("could not execute state transition") + } + } + beaconState.CurrentShufflingSeedHash32 = []byte("random seed") + if err := db.UpdateChainHead(genesis, beaconState); err != nil { + t.Fatalf("Could not save state: %v", err) + } + firstSlotForEpoch1 := lastSlotInEpoch0 + 1 + req2 := &pb.ValidatorEpochAssignmentsRequest{ + EpochStart: firstSlotForEpoch1, + PublicKey: pubKey[:], + } + assignmentsForEpoch2, err := validatorServer.ValidatorEpochAssignments(context.Background(), req2) + if err != nil { + t.Fatalf("Could not fetch assignments for epoch 2: %v", err) + } + if proto.Equal(assignmentsForEpoch0, assignmentsForEpoch2) { + t.Error("Expected assignments to change from previous epoch, did not") + } +} + func TestValidatorEpochAssignments_OK(t *testing.T) { db := internal.SetupDB(t) defer internal.TeardownDB(t, db)