updating rpc package

This commit is contained in:
nisdas
2019-06-10 14:41:51 +08:00
parent 7a0f4c0ed2
commit 26d275568d
9 changed files with 776 additions and 1302 deletions

View File

@@ -15,7 +15,6 @@ go_library(
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/cache:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/epoch:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/state:go_default_library",
"//beacon-chain/core/state/stateutils:go_default_library",
@@ -35,7 +34,6 @@ go_library(
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_prometheus//:go_default_library",
"@com_github_prysmaticlabs_prysm//shared/ssz:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//plugin/ocgrpc:go_default_library",
"@org_golang_google_grpc//:go_default_library",
@@ -68,13 +66,13 @@ go_test(
"//shared/featureconfig:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/ssz:go_default_library",
"//shared/testutil:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_gogo_protobuf//types:go_default_library",
"@com_github_golang_mock//gomock:go_default_library",
"@com_github_prysmaticlabs_prysm//shared/ssz:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
],

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
@@ -131,7 +132,7 @@ func (as *AttesterServer) AttestationDataAtSlot(ctx context.Context, req *pb.Att
if epochStartSlot == headState.Slot {
epochBoundaryRoot = headRoot[:]
} else {
epochBoundaryRoot, err = helpers.BlockRootAtSlot(headState, epochStartSlot)
epochBoundaryRoot, err = blocks.BlockRoot(headState, epochStartSlot)
if err != nil {
return nil, fmt.Errorf("could not get epoch boundary block for slot %d: %v",
epochStartSlot, err)

View File

@@ -105,7 +105,7 @@ func TestAttestationDataAtSlot_OK(t *testing.T) {
beaconState := &pbp2p.BeaconState{
Slot: 3*params.BeaconConfig().SlotsPerEpoch + 1,
CurrentJustifiedEpoch: 2 + 0,
LatestBlockRoots: make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot),
LatestBlockRoots: make([][]byte, params.BeaconConfig().LatestBlockRootsLength),
CurrentCrosslinks: []*pbp2p.Crosslink{
{
DataRoot: []byte("A"),
@@ -166,16 +166,16 @@ func TestAttestationDataAtSlot_handlesFarAwayJustifiedEpoch(t *testing.T) {
//
// State slot = 10000
// Last justified slot = epoch start of 1500
// SlotsPerHistoricalRoot = 8192
// LatestBlockRootsLength = 8192
//
// More background: https://github.com/prysmaticlabs/prysm/issues/2153
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
ctx := context.Background()
// Ensure SlotsPerHistoricalRoot matches scenario
// Ensure LatestBlockRootsLength matches scenario
cfg := params.BeaconConfig()
cfg.SlotsPerHistoricalRoot = 8192
cfg.LatestBlockRootsLength = 8192
params.OverrideBeaconConfig(cfg)
block := &pbp2p.BeaconBlock{
@@ -202,7 +202,7 @@ func TestAttestationDataAtSlot_handlesFarAwayJustifiedEpoch(t *testing.T) {
beaconState := &pbp2p.BeaconState{
Slot: 10000,
CurrentJustifiedEpoch: helpers.SlotToEpoch(1500),
LatestBlockRoots: make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot),
LatestBlockRoots: make([][]byte, params.BeaconConfig().LatestBlockRootsLength),
CurrentCrosslinks: []*pbp2p.Crosslink{
{
DataRoot: []byte("A"),

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/db"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/trieutil"
@@ -85,6 +86,127 @@ func (bs *BeaconServer) CanonicalHead(ctx context.Context, req *ptypes.Empty) (*
return block, nil
}
// LatestAttestation streams the latest processed attestations to the rpc clients.
func (bs *BeaconServer) LatestAttestation(req *ptypes.Empty, stream pb.BeaconService_LatestAttestationServer) error {
sub := bs.operationService.IncomingAttFeed().Subscribe(bs.incomingAttestation)
defer sub.Unsubscribe()
for {
select {
case attestation := <-bs.incomingAttestation:
log.Info("Sending attestation to RPC clients")
if err := stream.Send(attestation); err != nil {
return err
}
case <-sub.Err():
log.Debug("Subscriber closed, exiting goroutine")
return nil
case <-bs.ctx.Done():
log.Debug("RPC context closed, exiting goroutine")
return nil
}
}
}
// DomainData fetches the current domain version information from the beacon state.
func (bs *BeaconServer) DomainData(ctx context.Context, request *pb.DomainRequest) (*pb.DomainResponse, error) {
state, err := bs.beaconDB.HeadState(ctx)
if err != nil {
return nil, fmt.Errorf("could not retrieve beacon state: %v", err)
}
dv := helpers.DomainVersion(state, request.Epoch, params.BeaconConfig().DomainRandao)
return &pb.DomainResponse{
SignatureDomain: dv,
}, nil
}
// Eth1Data is a mechanism used by block proposers vote on a recent Ethereum 1.0 block hash and an
// associated deposit root found in the Ethereum 1.0 deposit contract. When consensus is formed,
// state.latest_eth1_data is updated, and validator deposits up to this root can be processed.
// The deposit root can be calculated by calling the get_deposit_root() function of
// the deposit contract using the post-state of the block hash.
//
// TODO(#2307): Refactor for v0.6.
func (bs *BeaconServer) Eth1Data(ctx context.Context, _ *ptypes.Empty) (*pb.Eth1DataResponse, error) {
return nil, nil
}
// PendingDeposits returns a list of pending deposits that are ready for
// inclusion in the next beacon block.
func (bs *BeaconServer) PendingDeposits(ctx context.Context, _ *ptypes.Empty) (*pb.PendingDepositsResponse, error) {
bNum := bs.powChainService.LatestBlockHeight()
if bNum == nil {
return nil, errors.New("latest PoW block number is unknown")
}
// Only request deposits that have passed the ETH1 follow distance window.
bNum = bNum.Sub(bNum, big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)))
allDeps := bs.beaconDB.AllDeposits(ctx, bNum)
if len(allDeps) == 0 {
return &pb.PendingDepositsResponse{PendingDeposits: nil}, nil
}
// 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 := bs.beaconDB.HeadState(ctx)
if err != nil {
return nil, fmt.Errorf("could not fetch beacon state: %v", err)
}
h := bytesutil.ToBytes32(beaconState.LatestEth1Data.BlockRoot)
_, latestEth1DataHeight, err := bs.powChainService.BlockExists(ctx, h)
if err != nil {
return nil, fmt.Errorf("could not fetch eth1data height: %v", err)
}
// If the state's latest eth1 data's block hash has a height of 100, we fetch all the deposits up to height 100.
// If this doesn't match the number of deposits stored in the cache, the generated trie will not be the same and
// root will fail to verify. This can happen in a scenario where we perhaps have a deposit from height 101,
// so we want to avoid any possible mismatches in these lengths.
upToLatestEth1DataDeposits := bs.beaconDB.AllDeposits(ctx, latestEth1DataHeight)
if len(upToLatestEth1DataDeposits) != len(allDeps) {
return &pb.PendingDepositsResponse{PendingDeposits: nil}, nil
}
depositData := [][]byte{}
for _, dep := range upToLatestEth1DataDeposits {
depHash, err := hashutil.DepositHash(dep.Data)
if err != nil {
return nil, fmt.Errorf("coulf not hash deposit data %v", err)
}
depositData = append(depositData, depHash[:])
}
depositTrie, err := trieutil.GenerateTrieFromItems(depositData, int(params.BeaconConfig().DepositContractTreeDepth))
if err != nil {
return nil, fmt.Errorf("could not generate historical deposit trie from deposits: %v", err)
}
allPendingDeps := bs.beaconDB.PendingDeposits(ctx, bNum)
// Deposits need to be received in order of merkle index root, so this has to make sure
// deposits are sorted from lowest to highest.
var pendingDeps []*pbp2p.Deposit
for _, dep := range allPendingDeps {
if dep.Index >= beaconState.DepositIndex {
pendingDeps = append(pendingDeps, dep)
}
}
for i := range pendingDeps {
// Don't construct merkle proof if the number of deposits is more than max allowed in block.
if uint64(i) == params.BeaconConfig().MaxDeposits {
break
}
pendingDeps[i], err = constructMerkleProof(depositTrie, pendingDeps[i])
if err != nil {
return nil, err
}
}
// Limit the return of pending deposits to not be more than max deposits allowed in block.
var pendingDeposits []*pbp2p.Deposit
for i := 0; i < len(pendingDeps) && i < int(params.BeaconConfig().MaxDeposits); i++ {
pendingDeposits = append(pendingDeposits, pendingDeps[i])
}
return &pb.PendingDepositsResponse{PendingDeposits: pendingDeposits}, nil
}
// BlockTree returns the current tree of saved blocks and their votes starting from the justified state.
func (bs *BeaconServer) BlockTree(ctx context.Context, _ *ptypes.Empty) (*pb.BlockTreeResponse, error) {
justifiedState, err := bs.beaconDB.JustifiedState()
@@ -124,25 +246,10 @@ func (bs *BeaconServer) BlockTree(ctx context.Context, _ *ptypes.Empty) (*pb.Blo
if err != nil {
return nil, err
}
hState, err := bs.beaconDB.HistoricalStateFromSlot(ctx, kid.Slot, blockRoot)
if err != nil {
return nil, err
}
activeValidatorIndices, err := helpers.ActiveValidatorIndices(hState, helpers.CurrentEpoch(hState))
if err != nil {
return nil, err
}
totalVotes, err := helpers.TotalBalance(hState, activeValidatorIndices)
if err != nil {
return nil, err
}
tree = append(tree, &pb.BlockTreeResponse_TreeNode{
BlockRoot: blockRoot[:],
Block: kid,
ParticipatedVotes: uint64(participatedVotes),
TotalVotes: uint64(totalVotes),
})
}
return &pb.BlockTreeResponse{
@@ -150,89 +257,9 @@ func (bs *BeaconServer) BlockTree(ctx context.Context, _ *ptypes.Empty) (*pb.Blo
}, nil
}
// BlockTreeBySlots returns the current tree of saved blocks and their votes starting from the justified state.
func (bs *BeaconServer) BlockTreeBySlots(ctx context.Context, req *pb.TreeBlockSlotRequest) (*pb.BlockTreeResponse, error) {
justifiedState, err := bs.beaconDB.JustifiedState()
if err != nil {
return nil, fmt.Errorf("could not retrieve justified state: %v", err)
}
attestationTargets, err := bs.targetsFetcher.AttestationTargets(justifiedState)
if err != nil {
return nil, fmt.Errorf("could not retrieve attestation target: %v", err)
}
justifiedBlock, err := bs.beaconDB.JustifiedBlock()
if err != nil {
return nil, err
}
if req == nil {
return nil, errors.New("argument 'TreeBlockSlotRequest' cannot be nil")
}
if !(req.SlotFrom <= req.SlotTo) {
return nil, fmt.Errorf("upper limit (%d) of slot range cannot be lower than the lower limit (%d)", req.SlotTo, req.SlotFrom)
}
highestSlot := bs.beaconDB.HighestBlockSlot()
fullBlockTree := []*pbp2p.BeaconBlock{}
for i := justifiedBlock.Slot + 1; i < highestSlot; i++ {
if ctx.Err() != nil {
return nil, ctx.Err()
}
if i >= req.SlotFrom && i <= req.SlotTo {
nextLayer, err := bs.beaconDB.BlocksBySlot(ctx, i)
if err != nil {
return nil, err
}
if nextLayer != nil {
fullBlockTree = append(fullBlockTree, nextLayer...)
}
}
if i > req.SlotTo {
break
}
}
tree := []*pb.BlockTreeResponse_TreeNode{}
for _, kid := range fullBlockTree {
if ctx.Err() != nil {
return nil, ctx.Err()
}
participatedVotes, err := blockchain.VoteCount(kid, justifiedState, attestationTargets, bs.beaconDB)
if err != nil {
return nil, err
}
blockRoot, err := hashutil.HashBeaconBlock(kid)
if err != nil {
return nil, err
}
hState, err := bs.beaconDB.HistoricalStateFromSlot(ctx, kid.Slot, blockRoot)
if err != nil {
return nil, err
}
if kid.Slot >= req.SlotFrom && kid.Slot <= req.SlotTo {
activeValidatorIndices, err := helpers.ActiveValidatorIndices(hState, helpers.CurrentEpoch(hState))
if err != nil {
return nil, err
}
totalVotes, err := helpers.TotalBalance(hState, activeValidatorIndices)
if err != nil {
return nil, err
}
tree = append(tree, &pb.BlockTreeResponse_TreeNode{
BlockRoot: blockRoot[:],
Block: kid,
ParticipatedVotes: uint64(participatedVotes),
TotalVotes: uint64(totalVotes),
})
}
}
return &pb.BlockTreeResponse{
Tree: tree,
}, nil
}
// TODO(#2307): Refactor for v0.6.
// nolint
func (bs *BeaconServer) defaultDataResponse(ctx context.Context, currentHeight *big.Int, eth1FollowDistance int64) (*pbp2p.Eth1Data, error) {
func (bs *BeaconServer) defaultDataResponse(ctx context.Context, currentHeight *big.Int, eth1FollowDistance int64) (*pb.Eth1DataResponse, error) {
ancestorHeight := big.NewInt(0).Sub(currentHeight, big.NewInt(eth1FollowDistance))
blockHash, err := bs.powChainService.BlockHashByHeight(ctx, ancestorHeight)
if err != nil {
@@ -263,9 +290,11 @@ func (bs *BeaconServer) defaultDataResponse(ctx context.Context, currentHeight *
return nil, fmt.Errorf("could not generate historical deposit trie from deposits: %v", err)
}
depositRoot := depositTrie.Root()
return &pbp2p.Eth1Data{
DepositRoot: depositRoot[:],
BlockRoot: blockHash[:],
return &pb.Eth1DataResponse{
Eth1Data: &pbp2p.Eth1Data{
DepositRoot: depositRoot[:],
BlockRoot: blockHash[:],
},
}, nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,11 +2,8 @@ package rpc
import (
"context"
"errors"
"fmt"
"math/big"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
@@ -17,7 +14,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/trieutil"
"github.com/sirupsen/logrus"
)
@@ -32,110 +28,62 @@ type ProposerServer struct {
canonicalStateChan chan *pbp2p.BeaconState
}
// RequestBlock is called by a proposer during its assigned slot to request a block to sign
// by passing in the slot and the signed randao reveal of the slot.
func (ps *ProposerServer) RequestBlock(ctx context.Context, req *pb.BlockRequest) (*pbp2p.BeaconBlock, error) {
// Retrieve the parent block as the current head of the canonical chain
parent, err := ps.beaconDB.ChainHead()
// ProposerIndex sends a response to the client which returns the proposer index for a given slot. Validators
// are shuffled and assigned slots to attest/propose to. This method will look for the validator that is assigned
// to propose a beacon block at the given slot.
func (ps *ProposerServer) ProposerIndex(ctx context.Context, req *pb.ProposerIndexRequest) (*pb.ProposerIndexResponse, error) {
beaconState, err := ps.beaconDB.HeadState(ctx)
if err != nil {
return nil, fmt.Errorf("could not get canonical head block: %v", err)
return nil, fmt.Errorf("could not get beacon state: %v", err)
}
parentRoot, err := ssz.SigningRoot(parent)
beaconState.Slot = req.SlotNumber
proposerIndex, err := helpers.BeaconProposerIndex(beaconState)
if err != nil {
return nil, fmt.Errorf("could not get parent block root: %v", err)
return nil, fmt.Errorf("could not get index of previous proposer: %v", err)
}
// Construct block body
// Pack ETH1 deposits which have not been included in the beacon chain
eth1Data, err := ps.eth1Data(ctx)
if err != nil {
return nil, fmt.Errorf("could not get ETH1 data: %v", err)
}
// Pack ETH1 deposits which have not been included in the beacon chain.
deposits, err := ps.deposits(ctx)
if err != nil {
return nil, fmt.Errorf("could not get eth1 deposits: %v", err)
}
// Pack aggregated attestations which have not been included in the beacon chain.
attestations, err := ps.attestations(ctx)
if err != nil {
return nil, fmt.Errorf("could not get pending attestations: %v", err)
}
// Use zero hash as stub for state root to compute later.
stateRoot := params.BeaconConfig().ZeroHash[:]
blk := &pbp2p.BeaconBlock{
Slot: req.Slot,
ParentRoot: parentRoot[:],
StateRoot: stateRoot,
Body: &pbp2p.BeaconBlockBody{
Eth1Data: eth1Data,
Deposits: deposits,
Attestations: attestations,
// TODO(2766): Implement rest of the retrievals for beacon block operations
ProposerSlashings: nil,
AttesterSlashings: nil,
VoluntaryExits: nil,
},
}
if !featureconfig.FeatureConfig().EnableComputeStateRoot {
// Compute state root with the newly constructed block.
stateRoot, err = ps.computeStateRoot(ctx, blk)
if err != nil {
return nil, fmt.Errorf("could not get compute state root: %v", err)
}
blk.StateRoot = stateRoot
}
return blk, nil
return &pb.ProposerIndexResponse{
Index: proposerIndex,
}, nil
}
// ProposeBlock is called by a proposer during its assigned slot to create a block in an attempt
// to get it processed by the beacon node as the canonical head.
func (ps *ProposerServer) ProposeBlock(ctx context.Context, blk *pbp2p.BeaconBlock) (*pb.ProposeResponse, error) {
root, err := hashutil.HashBeaconBlock(blk)
h, err := hashutil.HashBeaconBlock(blk)
if err != nil {
return nil, fmt.Errorf("could not tree hash block: %v", err)
}
log.WithField("blockRoot", fmt.Sprintf("%#x", bytesutil.Trunc(root[:]))).Debugf(
log.WithField("blockRoot", fmt.Sprintf("%#x", bytesutil.Trunc(h[:]))).Debugf(
"Block proposal received via RPC")
beaconState, err := ps.chainService.ReceiveBlock(ctx, blk)
if err != nil {
return nil, fmt.Errorf("could not process beacon block: %v", err)
}
if err := ps.beaconDB.UpdateChainHead(ctx, blk, beaconState); err != nil {
return nil, fmt.Errorf("failed to update chain: %v", err)
}
ps.chainService.UpdateCanonicalRoots(blk, root)
ps.chainService.UpdateCanonicalRoots(blk, h)
log.WithFields(logrus.Fields{
"headRoot": fmt.Sprintf("%#x", bytesutil.Trunc(root[:])),
"headRoot": fmt.Sprintf("%#x", bytesutil.Trunc(h[:])),
"headSlot": blk.Slot,
}).Info("Chain head block and state updated")
return &pb.ProposeResponse{BlockRoot: root[:]}, nil
return &pb.ProposeResponse{BlockRootHash32: h[:]}, nil
}
// attestations retrieves aggregated attestations kept in the beacon node's operations pool which have
// PendingAttestations retrieves attestations kept in the beacon node's operations pool which have
// not yet been included into the beacon chain. Proposers include these pending attestations in their
// proposed blocks when performing their responsibility. If desired, callers can choose to filter pending
// 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) ([]*pbp2p.Attestation, error) {
func (ps *ProposerServer) PendingAttestations(ctx context.Context, req *pb.PendingAttestationsRequest) (*pb.PendingAttestationsResponse, error) {
beaconState, err := ps.beaconDB.HeadState(ctx)
if err != nil {
return nil, fmt.Errorf("could not retrieve beacon state: %v", err)
}
atts, err := ps.operationService.PendingAttestations(ctx)
if err != nil {
return nil, fmt.Errorf("could not retrieve pending attest ations from operations service: %v", err)
return nil, fmt.Errorf("could not retrieve pending attestations from operations service: %v", err)
}
beaconState.Slot++
@@ -157,7 +105,7 @@ func (ps *ProposerServer) attestations(ctx context.Context) ([]*pbp2p.Attestatio
return nil, fmt.Errorf("could not get attestation slot: %v", err)
}
if _, err := blocks.ProcessAttestation(beaconState, att, false); err != nil {
if _, err := blocks.VerifyAttestation(beaconState, att, false); err != nil {
if ctx.Err() != nil {
return nil, ctx.Err()
}
@@ -187,121 +135,40 @@ func (ps *ProposerServer) attestations(ctx context.Context) ([]*pbp2p.Attestatio
validAtts = append(validAtts, att)
}
return validAtts, nil
return &pb.PendingAttestationsResponse{
PendingAttestations: validAtts,
}, nil
}
// Eth1Data is a mechanism used by block proposers vote on a recent Ethereum 1.0 block hash and an
// associated deposit root found in the Ethereum 1.0 deposit contract. When consensus is formed,
// state.latest_eth1_data is updated, and validator deposits up to this root can be processed.
// The deposit root can be calculated by calling the get_deposit_root() function of
// the deposit contract using the post-state of the block hash.
//
// TODO(#2307): Refactor for v0.6.
func (ps *ProposerServer) eth1Data(ctx context.Context) (*pbp2p.Eth1Data, error) {
return nil, nil
}
// computeStateRoot computes the state root after a block has been processed through a state transition and
// ComputeStateRoot computes the state root after a block has been processed through a state transition and
// returns it to the validator client.
func (ps *ProposerServer) computeStateRoot(ctx context.Context, block *pbp2p.BeaconBlock) ([]byte, error) {
func (ps *ProposerServer) ComputeStateRoot(ctx context.Context, req *pbp2p.BeaconBlock) (*pb.StateRootResponse, error) {
if !featureconfig.FeatureConfig().EnableComputeStateRoot {
log.Debug("Compute state root disabled, returning no-op result")
return &pb.StateRootResponse{StateRoot: []byte("no-op")}, nil
}
beaconState, err := ps.beaconDB.HeadState(ctx)
if err != nil {
return nil, fmt.Errorf("could not get beacon state: %v", err)
}
s, err := state.ExecuteStateTransition(
beaconState, err = state.ExecuteStateTransition(
ctx,
beaconState,
block,
req,
state.DefaultConfig(),
)
if err != nil {
return nil, fmt.Errorf("could not execute state transition for state root %v", err)
return nil, fmt.Errorf("could not execute state transition %v", err)
}
root, err := hashutil.HashProto(s)
beaconStateHash, err := hashutil.HashProto(beaconState)
if err != nil {
return nil, fmt.Errorf("could not tree hash beacon state: %v", err)
}
log.WithField("beaconStateRoot", fmt.Sprintf("%#x", root)).Debugf("Computed state hash")
return root[:], nil
}
// deposits returns a list of pending deposits that are ready for
// inclusion in the next beacon block.
func (ps *ProposerServer) deposits(ctx context.Context) ([]*pbp2p.Deposit, error) {
bNum := ps.powChainService.LatestBlockHeight()
if bNum == nil {
return nil, errors.New("latest PoW block number is unknown")
}
// Only request deposits that have passed the ETH1 follow distance window.
bNum = bNum.Sub(bNum, big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance)))
allDeps := ps.beaconDB.AllDeposits(ctx, bNum)
if len(allDeps) == 0 {
return nil, nil
}
// 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, fmt.Errorf("could not fetch beacon state: %v", err)
}
h := bytesutil.ToBytes32(beaconState.LatestEth1Data.BlockRoot)
_, latestEth1DataHeight, err := ps.powChainService.BlockExists(ctx, h)
if err != nil {
return nil, fmt.Errorf("could not fetch eth1data height: %v", err)
}
// If the state's latest eth1 data's block hash has a height of 100, we fetch all the deposits up to height 100.
// If this doesn't match the number of deposits stored in the cache, the generated trie will not be the same and
// root will fail to verify. This can happen in a scenario where we perhaps have a deposit from height 101,
// so we want to avoid any possible mismatches in these lengths.
upToLatestEth1DataDeposits := ps.beaconDB.AllDeposits(ctx, latestEth1DataHeight)
if len(upToLatestEth1DataDeposits) != len(allDeps) {
return nil, nil
}
depositData := [][]byte{}
for _, dep := range upToLatestEth1DataDeposits {
depHash, err := hashutil.DepositHash(dep.Data)
if err != nil {
return nil, fmt.Errorf("coulf not hash deposit data %v", err)
}
depositData = append(depositData, depHash[:])
}
depositTrie, err := trieutil.GenerateTrieFromItems(depositData, int(params.BeaconConfig().DepositContractTreeDepth))
if err != nil {
return nil, fmt.Errorf("could not generate historical deposit trie from deposits: %v", err)
}
allPendingDeps := ps.beaconDB.PendingDeposits(ctx, bNum)
// Deposits need to be received in order of merkle index root, so this has to make sure
// deposits are sorted from lowest to highest.
var pendingDeps []*pbp2p.Deposit
for _, dep := range allPendingDeps {
if dep.Index >= beaconState.DepositIndex {
pendingDeps = append(pendingDeps, dep)
}
}
for i := range pendingDeps {
// Don't construct merkle proof if the number of deposits is more than max allowed in block.
if uint64(i) == params.BeaconConfig().MaxDeposits {
break
}
pendingDeps[i], err = constructMerkleProof(depositTrie, pendingDeps[i])
if err != nil {
return nil, err
}
}
// Limit the return of pending deposits to not be more than max deposits allowed in block.
var pendingDeposits []*pbp2p.Deposit
for i := 0; i < len(pendingDeps) && i < int(params.BeaconConfig().MaxDeposits); i++ {
pendingDeposits = append(pendingDeposits, pendingDeps[i])
}
return pendingDeposits, nil
log.WithField("beaconStateHash", fmt.Sprintf("%#x", beaconStateHash)).Debugf("Computed state hash")
return &pb.StateRootResponse{
StateRoot: beaconStateHash[:],
}, nil
}

View File

@@ -1,24 +1,20 @@
package rpc
import (
"bytes"
"context"
"math/big"
"reflect"
"strconv"
"strings"
"testing"
"github.com/prysmaticlabs/go-ssz"
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/featureconfig"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/trieutil"
"github.com/prysmaticlabs/prysm/shared/ssz"
)
func init() {
@@ -128,16 +124,13 @@ func TestComputeStateRoot_OK(t *testing.T) {
RandaoReveal: nil,
ProposerSlashings: nil,
AttesterSlashings: nil,
Eth1Data: &pbp2p.Eth1Data{},
},
}
_, _ = proposerServer.computeStateRoot(context.Background(), req)
_, _ = proposerServer.ComputeStateRoot(context.Background(), req)
}
func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) {
helpers.ClearAllCaches()
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
ctx := context.Background()
@@ -205,11 +198,13 @@ func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) {
t.Fatalf("couldnt update chainhead: %v", err)
}
atts, err := proposerServer.attestations(context.Background())
res, err := proposerServer.PendingAttestations(context.Background(), &pb.PendingAttestationsRequest{
ProposalBlockSlot: blk.Slot + 1,
})
if err != nil {
t.Fatalf("Unexpected error fetching pending attestations: %v", err)
}
if len(atts) == 0 {
if len(res.PendingAttestations) == 0 {
t.Error("Expected pending attestations list to be non-empty")
}
}
@@ -222,7 +217,7 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
// Edge case: current slot is at the end of an epoch. The pending attestation
// for the next slot should come from currentSlot + 1.
currentSlot := helpers.StartSlot(
params.BeaconConfig().GenesisEpoch+10,
10,
) - 1
expectedEpoch := uint64(100)
@@ -328,15 +323,20 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
t.Fatalf("couldnt update chainhead: %v", err)
}
atts, err := proposerServer.attestations(context.Background())
res, err := proposerServer.PendingAttestations(
context.Background(),
&pb.PendingAttestationsRequest{
ProposalBlockSlot: currentSlot,
},
)
if err != nil {
t.Fatalf("Unexpected error fetching pending attestations: %v", err)
}
if len(atts) != expectedNumberOfAttestations {
if len(res.PendingAttestations) != expectedNumberOfAttestations {
t.Errorf(
"Expected pending attestations list length %d, but was %d",
expectedNumberOfAttestations,
len(atts),
len(res.PendingAttestations),
)
}
@@ -357,502 +357,7 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
Crosslink: &pbp2p.Crosslink{Epoch: 10, DataRoot: params.BeaconConfig().ZeroHash[:], ParentRoot: encoded[:]},
}, AggregationBitfield: []byte{0xC0, 0xC0, 0xC0, 0xC0}},
}
if !reflect.DeepEqual(atts, expectedAtts) {
if !reflect.DeepEqual(res.PendingAttestations, expectedAtts) {
t.Error("Did not receive expected attestations")
}
}
func TestPendingDeposits_UnknownBlockNum(t *testing.T) {
p := &mockPOWChainService{
latestBlockNumber: nil,
}
ps := ProposerServer{powChainService: p}
_, err := ps.deposits(context.Background())
if err.Error() != "latest PoW block number is unknown" {
t.Errorf("Received unexpected error: %v", err)
}
}
func TestPendingDeposits_OutsideEth1FollowWindow(t *testing.T) {
ctx := context.Background()
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
p := &mockPOWChainService{
latestBlockNumber: height,
hashesByHeight: map[int][]byte{
int(height.Int64()): []byte("0x0"),
},
}
d := internal.SetupDB(t)
beaconState := &pbp2p.BeaconState{
LatestEth1Data: &pbp2p.Eth1Data{
BlockRoot: []byte("0x0"),
},
DepositIndex: 2,
}
if err := d.SaveState(ctx, beaconState); err != nil {
t.Fatal(err)
}
var mockSig [96]byte
var mockCreds [32]byte
// Using the merkleTreeIndex as the block number for this test...
readyDeposits := []*pbp2p.Deposit{
{
Index: 0,
Data: &pbp2p.DepositData{
Pubkey: []byte("a"),
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
},
{
Index: 1,
Data: &pbp2p.DepositData{
Pubkey: []byte("b"),
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
},
}
recentDeposits := []*pbp2p.Deposit{
{
Index: 2,
Data: &pbp2p.DepositData{
Pubkey: []byte("c"),
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
},
{
Index: 3,
Data: &pbp2p.DepositData{
Pubkey: []byte("d"),
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
},
}
for _, dp := range append(readyDeposits, recentDeposits...) {
d.InsertDeposit(ctx, dp, big.NewInt(int64(dp.Index)))
}
for _, dp := range recentDeposits {
d.InsertPendingDeposit(ctx, dp, big.NewInt(int64(dp.Index)))
}
bs := &ProposerServer{
beaconDB: d,
powChainService: p,
chainService: newMockChainService(),
}
deposits, err := bs.deposits(ctx)
if err != nil {
t.Fatal(err)
}
if len(deposits) != 0 {
t.Errorf("Received unexpected list of deposits: %+v, wanted: 0", len(deposits))
}
// It should also return the recent deposits after their follow window.
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
deposits, err = bs.deposits(ctx)
if err != nil {
t.Fatal(err)
}
if len(deposits) != len(recentDeposits) {
t.Errorf(
"Received unexpected number of pending deposits: %d, wanted: %d",
len(deposits),
len(recentDeposits),
)
}
}
func Benchmark_Eth1Data(b *testing.B) {
db := internal.SetupDB(b)
defer internal.TeardownDB(b, db)
ctx := context.Background()
hashesByHeight := make(map[int][]byte)
beaconState := &pbp2p.BeaconState{
Eth1DataVotes: []*pbp2p.Eth1Data{},
LatestEth1Data: &pbp2p.Eth1Data{
BlockRoot: []byte("stub"),
},
}
numOfVotes := 1000
for i := 0; i < numOfVotes; i++ {
blockhash := []byte{'b', 'l', 'o', 'c', 'k', byte(i)}
deposit := []byte{'d', 'e', 'p', 'o', 's', 'i', 't', byte(i)}
beaconState.Eth1DataVotes = append(beaconState.Eth1DataVotes, &pbp2p.Eth1Data{
BlockRoot: blockhash,
DepositRoot: deposit,
})
hashesByHeight[i] = blockhash
}
hashesByHeight[numOfVotes+1] = []byte("stub")
if err := db.SaveState(ctx, beaconState); err != nil {
b.Fatal(err)
}
currentHeight := params.BeaconConfig().Eth1FollowDistance + 5
proposerServer := &ProposerServer{
beaconDB: db,
powChainService: &mockPOWChainService{
latestBlockNumber: big.NewInt(int64(currentHeight)),
hashesByHeight: hashesByHeight,
},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := proposerServer.eth1Data(context.Background())
if err != nil {
b.Fatal(err)
}
}
}
func TestPendingDeposits_CantReturnBelowStateDepositIndex(t *testing.T) {
ctx := context.Background()
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
p := &mockPOWChainService{
latestBlockNumber: height,
hashesByHeight: map[int][]byte{
int(height.Int64()): []byte("0x0"),
},
}
d := internal.SetupDB(t)
beaconState := &pbp2p.BeaconState{
LatestEth1Data: &pbp2p.Eth1Data{
BlockRoot: []byte("0x0"),
},
DepositIndex: 10,
}
if err := d.SaveState(ctx, beaconState); err != nil {
t.Fatal(err)
}
var mockSig [96]byte
var mockCreds [32]byte
readyDeposits := []*pbp2p.Deposit{
{
Index: 0,
Data: &pbp2p.DepositData{
Pubkey: []byte("a"),
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
},
{
Index: 1,
Data: &pbp2p.DepositData{
Pubkey: []byte("b"),
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
},
}
var recentDeposits []*pbp2p.Deposit
for i := 2; i < 16; i++ {
recentDeposits = append(recentDeposits, &pbp2p.Deposit{
Index: uint64(i),
Data: &pbp2p.DepositData{
Pubkey: []byte{byte(i)},
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
})
}
for _, dp := range append(readyDeposits, recentDeposits...) {
d.InsertDeposit(ctx, dp, big.NewInt(int64(dp.Index)))
}
for _, dp := range recentDeposits {
d.InsertPendingDeposit(ctx, dp, big.NewInt(int64(dp.Index)))
}
bs := &ProposerServer{
beaconDB: d,
powChainService: p,
chainService: newMockChainService(),
}
// It should also return the recent deposits after their follow window.
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
deposits, err := bs.deposits(ctx)
if err != nil {
t.Fatal(err)
}
expectedDeposits := 6
if len(deposits) != expectedDeposits {
t.Errorf(
"Received unexpected number of pending deposits: %d, wanted: %d",
len(deposits),
expectedDeposits,
)
}
if deposits[0].Index != beaconState.DepositIndex {
t.Errorf(
"Received unexpected merkle index: %d, wanted: %d",
deposits[0].Index,
beaconState.DepositIndex,
)
}
}
func TestPendingDeposits_CantReturnMoreThanMax(t *testing.T) {
ctx := context.Background()
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
p := &mockPOWChainService{
latestBlockNumber: height,
hashesByHeight: map[int][]byte{
int(height.Int64()): []byte("0x0"),
},
}
d := internal.SetupDB(t)
beaconState := &pbp2p.BeaconState{
LatestEth1Data: &pbp2p.Eth1Data{
BlockRoot: []byte("0x0"),
},
DepositIndex: 2,
}
if err := d.SaveState(ctx, beaconState); err != nil {
t.Fatal(err)
}
var mockSig [96]byte
var mockCreds [32]byte
readyDeposits := []*pbp2p.Deposit{
{
Index: 0,
Data: &pbp2p.DepositData{
Pubkey: []byte("a"),
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
},
{
Index: 1,
Data: &pbp2p.DepositData{
Pubkey: []byte("b"),
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
},
}
var recentDeposits []*pbp2p.Deposit
for i := 2; i < 22; i++ {
recentDeposits = append(recentDeposits, &pbp2p.Deposit{
Index: uint64(i),
Data: &pbp2p.DepositData{
Pubkey: []byte{byte(i)},
Signature: mockSig[:],
WithdrawalCredentials: mockCreds[:],
},
})
}
for _, dp := range append(readyDeposits, recentDeposits...) {
d.InsertDeposit(ctx, dp, big.NewInt(int64(dp.Index)))
}
for _, dp := range recentDeposits {
d.InsertPendingDeposit(ctx, dp, big.NewInt(int64(dp.Index)))
}
bs := &ProposerServer{
beaconDB: d,
powChainService: p,
chainService: newMockChainService(),
}
// It should also return the recent deposits after their follow window.
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
deposits, err := bs.deposits(ctx)
if err != nil {
t.Fatal(err)
}
if len(deposits) != int(params.BeaconConfig().MaxDeposits) {
t.Errorf(
"Received unexpected number of pending deposits: %d, wanted: %d",
len(deposits),
int(params.BeaconConfig().MaxDeposits),
)
}
}
func TestEth1Data_EmptyVotesFetchBlockHashFailure(t *testing.T) {
t.Skip()
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
ctx := context.Background()
proposerServer := &ProposerServer{
beaconDB: db,
powChainService: &faultyPOWChainService{
hashesByHeight: make(map[int][]byte),
},
}
validators := make([]*pbp2p.Validator, 2*params.BeaconConfig().SlotsPerEpoch)
for i := 0; i < len(validators); i++ {
validators[i] = &pbp2p.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
}
}
crosslinks := make([]*pbp2p.Crosslink, 2*params.BeaconConfig().SlotsPerEpoch)
for i := range crosslinks {
crosslinks[i] = &pbp2p.Crosslink{
Epoch: params.BeaconConfig().GenesisEpoch + 1,
CrosslinkDataRootHash32: params.BeaconConfig().ZeroHash[:],
}
}
beaconState := &pbp2p.BeaconState{
LatestEth1Data: &pbp2p.Eth1Data{
BlockRoot: []byte{'a'},
},
Eth1DataVotes: []*pbp2p.Eth1Data{},
}
if err := proposerServer.beaconDB.SaveState(ctx, beaconState); err != nil {
t.Fatal(err)
}
want := "could not fetch ETH1_FOLLOW_DISTANCE ancestor"
if _, err := proposerServer.eth1Data(context.Background()); !strings.Contains(err.Error(), want) {
t.Errorf("Expected error %v, received %v", want, err)
}
}
func TestEth1Data_EmptyVotesOk(t *testing.T) {
t.Skip()
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
ctx := context.Background()
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
deps := []*pbp2p.Deposit{
{Index: 0, Data: &pbp2p.DepositData{
Pubkey: []byte("a"),
}},
{Index: 1, Data: &pbp2p.DepositData{
Pubkey: []byte("b"),
}},
}
depsData := [][]byte{}
for _, dp := range deps {
db.InsertDeposit(context.Background(), dp, big.NewInt(0))
depHash, err := hashutil.DepositHash(dp.Data)
if err != nil {
t.Errorf("Could not hash deposit")
}
depsData = append(depsData, depHash[:])
}
depositTrie, err := trieutil.GenerateTrieFromItems(depsData, int(params.BeaconConfig().DepositContractTreeDepth))
if err != nil {
t.Fatal(err)
}
depositRoot := depositTrie.Root()
beaconState := &pbp2p.BeaconState{
LatestEth1Data: &pbp2p.Eth1Data{
BlockRoot: []byte("hash0"),
DepositRoot: depositRoot[:],
},
Eth1DataVotes: []*pbp2p.Eth1Data{},
}
powChainService := &mockPOWChainService{
latestBlockNumber: height,
hashesByHeight: map[int][]byte{
0: []byte("hash0"),
1: beaconState.LatestEth1Data.BlockRoot,
},
}
proposerServer := &ProposerServer{
beaconDB: db,
powChainService: powChainService,
}
if err := proposerServer.beaconDB.SaveState(ctx, beaconState); err != nil {
t.Fatal(err)
}
eth1data, err := proposerServer.eth1Data(context.Background())
if err != nil {
t.Fatal(err)
}
// If the data vote objects are empty, the deposit root should be the one corresponding
// to the deposit contract in the powchain service, fetched using powChainService.DepositRoot()
if !bytes.Equal(eth1data.DepositRoot, depositRoot[:]) {
t.Errorf(
"Expected deposit roots to match, received %#x == %#x",
eth1data.DepositRoot,
depositRoot,
)
}
}
func TestEth1Data_NonEmptyVotesSelectsBestVote(t *testing.T) {
t.Skip()
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
ctx := context.Background()
eth1DataVotes := []*pbp2p.Eth1Data{}
beaconState := &pbp2p.BeaconState{
Eth1DataVotes: eth1DataVotes,
LatestEth1Data: &pbp2p.Eth1Data{
BlockRoot: []byte("stub"),
},
}
if err := db.SaveState(ctx, beaconState); err != nil {
t.Fatal(err)
}
currentHeight := params.BeaconConfig().Eth1FollowDistance + 5
proposerServer := &ProposerServer{
beaconDB: db,
powChainService: &mockPOWChainService{
latestBlockNumber: big.NewInt(int64(currentHeight)),
hashesByHeight: map[int][]byte{
0: beaconState.LatestEth1Data.BlockRoot,
1: beaconState.Eth1DataVotes[0].BlockRoot,
2: beaconState.Eth1DataVotes[1].BlockRoot,
3: beaconState.Eth1DataVotes[3].BlockRoot,
// We will give the hash at index 2 in the beacon state's latest eth1 votes
// priority in being selected as the best vote by giving it the highest block number.
4: beaconState.Eth1DataVotes[2].BlockRoot,
},
},
}
eth1data, err := proposerServer.eth1Data(context.Background())
if err != nil {
t.Fatal(err)
}
// Vote at index 2 should have won the best vote selection mechanism as it had the highest block number
// despite being tied at vote count with the vote at index 3.
if !bytes.Equal(eth1data.BlockRoot, beaconState.Eth1DataVotes[2].BlockRoot) {
t.Errorf(
"Expected block hashes to match, received %#x == %#x",
eth1data.BlockRoot,
beaconState.Eth1DataVotes[2].BlockRoot,
)
}
if !bytes.Equal(eth1data.DepositRoot, beaconState.Eth1DataVotes[2].DepositRoot) {
t.Errorf(
"Expected deposit roots to match, received %#x == %#x",
eth1data.DepositRoot,
beaconState.Eth1DataVotes[2].DepositRoot,
)
}
}

View File

@@ -101,28 +101,22 @@ func (vs *ValidatorServer) ValidatorPerformance(
return nil, fmt.Errorf("could not retrieve beacon state: %v", err)
}
activeCount, err := helpers.ActiveValidatorCount(head, helpers.SlotToEpoch(req.Slot))
if err != nil {
return nil, fmt.Errorf("could not retrieve active validator count: %v", err)
}
totalActiveBalance, err := helpers.TotalActiveBalance(head)
if err != nil {
return nil, fmt.Errorf("could not retrieve active balance: %v", err)
}
activeIndices := helpers.ActiveValidatorIndices(head, helpers.SlotToEpoch(req.Slot))
validatorBalances, err := vs.beaconDB.Balances(ctx)
if err != nil {
return nil, fmt.Errorf("could not retrieve validator balances %v", err)
}
avgBalance := float32(totalActiveBalance / activeCount)
totalActiveBalance := float32(0)
for _, idx := range activeIndices {
totalActiveBalance += float32(validatorBalances[idx])
}
avgBalance := totalActiveBalance / float32(len(activeIndices))
balance := validatorBalances[index]
return &pb.ValidatorPerformanceResponse{
Balance: balance,
AverageActiveValidatorBalance: avgBalance,
TotalValidators: uint64(len(validatorRegistry)),
TotalActiveValidators: uint64(activeCount),
TotalActiveValidators: uint64(len(activeIndices)),
}, nil
}
@@ -213,7 +207,6 @@ func (vs *ValidatorServer) ValidatorStatus(
if err != nil {
return nil, err
}
chainStartKeys := vs.chainStartPubkeys()
validatorIndexMap := stateutils.ValidatorIndexMap(beaconState)
return vs.validatorStatus(ctx, req.PublicKey, chainStarted, chainStartKeys, validatorIndexMap, beaconState), nil
@@ -465,7 +458,7 @@ func (vs *ValidatorServer) depositBlockSlot(ctx context.Context, currentSlot uin
followTime := time.Duration(params.BeaconConfig().Eth1FollowDistance*params.BeaconConfig().GoerliBlockTime) * time.Second
eth1UnixTime := time.Unix(int64(blockTimeStamp), 0).Add(followTime)
votingPeriodSlots := helpers.StartSlot(params.BeaconConfig().SlotsPerEth1VotingPeriod / params.BeaconConfig().SlotsPerEpoch)
votingPeriodSlots := helpers.StartSlot(params.BeaconConfig().EpochsPerEth1VotingPeriod)
votingPeriodSeconds := time.Duration(votingPeriodSlots*params.BeaconConfig().SecondsPerSlot) * time.Second
timeToInclusion := eth1UnixTime.Add(votingPeriodSeconds)
@@ -488,15 +481,3 @@ func (vs *ValidatorServer) chainStartPubkeys() map[[96]byte]bool {
}
return pubkeys
}
// 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, fmt.Errorf("could not retrieve beacon state: %v", err)
}
dv := helpers.DomainVersion(state, request.Epoch, params.BeaconConfig().DomainRandao)
return &pb.DomainResponse{
SignatureDomain: dv,
}, nil
}

View File

@@ -163,8 +163,6 @@ func TestNextEpochCommitteeAssignment_CantFindValidatorIdx(t *testing.T) {
}
func TestCommitteeAssignment_OK(t *testing.T) {
helpers.ClearAllCaches()
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
ctx := context.Background()