mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-07 22:54:17 -05:00
[Interop] Improve RPC Codebase + Start Beacon Chain With Mock ETH1 Values (#3407)
* add main.go * interop readme * proper visibility * standardize and abstract into simpler funcs * formatting * no os pkg * add test * no panics anywhere, properly and nicely handle errors * proper comments * fix broken test * readme * comment * recommend ssz * install * tool now works * README * build * readme * 64 validators * rem print * register the no powchain flag * work on mock eth1 start * common interface * getting closer with the interface defs * only two uses of powchain * remove powchain dependency * remove powchain dependency * common powchain interface * proper comment in case of flag * proper args into rpc services * rename fields * pass in mock flag into RPC * conforms to iface * use client instead of block fetcher iface * broken tests * block fetcher * finalized * resolved broken build * fix build * comment * fix tests * tests pass * resolved confs * took them out * rename into smaller interfaces * resolve some confs * ensure tests pass * properly utilize mock instead of localized mock * res lint * lint * finish test for mock eth1data * run gazelle * include flag again * fix broken build * disable powchain * dont dial eth1 nodes * reenable pow * use smaller interfaces, standardize naming * abstract mock into its own package * faulty mock lint * fix stutter in lint * rpc tests all passing * use mocks for operations * no more mocks in the entire rpc package * no mock * viz * testonly
This commit is contained in:
@@ -9,33 +9,32 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/shared/params"
|
"github.com/prysmaticlabs/prysm/shared/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChainInfoRetriever defines a common interface for methods in blockchain service which
|
// ChainInfoFetcher defines a common interface for methods in blockchain service which
|
||||||
// directly retrieves chain info related data.
|
// directly retrieves chain info related data.
|
||||||
type ChainInfoRetriever interface {
|
type ChainInfoFetcher interface {
|
||||||
HeadRetriever
|
HeadFetcher
|
||||||
CanonicalRetriever
|
CanonicalRootFetcher
|
||||||
FinalizationRetriever
|
FinalizationFetcher
|
||||||
GenesisTime() time.Time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HeadRetriever defines a common interface for methods in blockchain service which
|
// HeadFetcher defines a common interface for methods in blockchain service which
|
||||||
// directly retrieves head related data.
|
// directly retrieves head related data.
|
||||||
type HeadRetriever interface {
|
type HeadFetcher interface {
|
||||||
HeadSlot() uint64
|
HeadSlot() uint64
|
||||||
HeadRoot() []byte
|
HeadRoot() []byte
|
||||||
HeadBlock() *ethpb.BeaconBlock
|
HeadBlock() *ethpb.BeaconBlock
|
||||||
HeadState() *pb.BeaconState
|
HeadState() *pb.BeaconState
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanonicalRetriever defines a common interface for methods in blockchain service which
|
// CanonicalRootFetcher defines a common interface for methods in blockchain service which
|
||||||
// directly retrieves canonical roots related data.
|
// directly retrieves canonical roots related data.
|
||||||
type CanonicalRetriever interface {
|
type CanonicalRootFetcher interface {
|
||||||
CanonicalRoot(slot uint64) []byte
|
CanonicalRoot(slot uint64) []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinalizationRetriever defines a common interface for methods in blockchain service which
|
// FinalizationFetcher defines a common interface for methods in blockchain service which
|
||||||
// directly retrieves finalization related data.
|
// directly retrieves finalization related data.
|
||||||
type FinalizationRetriever interface {
|
type FinalizationFetcher interface {
|
||||||
FinalizedCheckpt() *ethpb.Checkpoint
|
FinalizedCheckpt() *ethpb.Checkpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
@@ -14,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Ensure Service implements chain info interface.
|
// Ensure Service implements chain info interface.
|
||||||
var _ = ChainInfoRetriever(&Service{})
|
var _ = ChainInfoFetcher(&Service{})
|
||||||
|
|
||||||
func TestFinalizedCheckpt_Nil(t *testing.T) {
|
func TestFinalizedCheckpt_Nil(t *testing.T) {
|
||||||
c := setupBeaconChain(t, nil)
|
c := setupBeaconChain(t, nil)
|
||||||
@@ -88,11 +87,3 @@ func TestCanonicalRoot_CanRetrieve(t *testing.T) {
|
|||||||
t.Errorf("Wanted head root: %v, got: %d", []byte{'A'}, c.CanonicalRoot(slot))
|
t.Errorf("Wanted head root: %v, got: %d", []byte{'A'}, c.CanonicalRoot(slot))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenesisTime_CanRetrieve(t *testing.T) {
|
|
||||||
c := &Service{}
|
|
||||||
c.genesisTime = time.Unix(100, 0)
|
|
||||||
if c.GenesisTime() != time.Unix(100, 0) {
|
|
||||||
t.Error("incorrect genesis time received")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ type Service struct {
|
|||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
beaconDB db.Database
|
beaconDB db.Database
|
||||||
depositCache *depositcache.DepositCache
|
depositCache *depositcache.DepositCache
|
||||||
web3Service *powchain.Service
|
chainStartFetcher powchain.ChainStartFetcher
|
||||||
opsPoolService operations.OperationFeeds
|
opsPoolService operations.OperationFeeds
|
||||||
forkChoiceStore forkchoice.ForkChoicer
|
forkChoiceStore forkchoice.ForkChoicer
|
||||||
chainStartChan chan time.Time
|
chainStartChan chan time.Time
|
||||||
@@ -61,14 +61,14 @@ type Service struct {
|
|||||||
|
|
||||||
// Config options for the service.
|
// Config options for the service.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
BeaconBlockBuf int
|
BeaconBlockBuf int
|
||||||
Web3Service *powchain.Service
|
ChainStartFetcher powchain.ChainStartFetcher
|
||||||
BeaconDB db.Database
|
BeaconDB db.Database
|
||||||
DepositCache *depositcache.DepositCache
|
DepositCache *depositcache.DepositCache
|
||||||
OpsPoolService operations.OperationFeeds
|
OpsPoolService operations.OperationFeeds
|
||||||
P2p p2p.Broadcaster
|
P2p p2p.Broadcaster
|
||||||
MaxRoutines int64
|
MaxRoutines int64
|
||||||
PreloadStatePath string
|
PreloadStatePath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService instantiates a new block service instance that will
|
// NewService instantiates a new block service instance that will
|
||||||
@@ -81,7 +81,7 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
|
|||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
beaconDB: cfg.BeaconDB,
|
beaconDB: cfg.BeaconDB,
|
||||||
depositCache: cfg.DepositCache,
|
depositCache: cfg.DepositCache,
|
||||||
web3Service: cfg.Web3Service,
|
chainStartFetcher: cfg.ChainStartFetcher,
|
||||||
opsPoolService: cfg.OpsPoolService,
|
opsPoolService: cfg.OpsPoolService,
|
||||||
forkChoiceStore: store,
|
forkChoiceStore: store,
|
||||||
chainStartChan: make(chan time.Time),
|
chainStartChan: make(chan time.Time),
|
||||||
@@ -136,11 +136,11 @@ func (s *Service) Start() {
|
|||||||
s.stateInitializedFeed.Send(s.genesisTime)
|
s.stateInitializedFeed.Send(s.genesisTime)
|
||||||
} else {
|
} else {
|
||||||
log.Info("Waiting for ChainStart log from the Validator Deposit Contract to start the beacon chain...")
|
log.Info("Waiting for ChainStart log from the Validator Deposit Contract to start the beacon chain...")
|
||||||
if s.web3Service == nil {
|
if s.chainStartFetcher == nil {
|
||||||
log.Fatal("Not configured web3Service for POW chain")
|
log.Fatal("Not configured web3Service for POW chain")
|
||||||
return // return need for TestStartUninitializedChainWithoutConfigPOWChain.
|
return // return need for TestStartUninitializedChainWithoutConfigPOWChain.
|
||||||
}
|
}
|
||||||
subChainStart := s.web3Service.ChainStartFeed().Subscribe(s.chainStartChan)
|
subChainStart := s.chainStartFetcher.ChainStartFeed().Subscribe(s.chainStartChan)
|
||||||
go func() {
|
go func() {
|
||||||
genesisTime := <-s.chainStartChan
|
genesisTime := <-s.chainStartChan
|
||||||
s.processChainStartTime(ctx, genesisTime, subChainStart)
|
s.processChainStartTime(ctx, genesisTime, subChainStart)
|
||||||
@@ -152,8 +152,8 @@ func (s *Service) Start() {
|
|||||||
// processChainStartTime initializes a series of deposits from the ChainStart deposits in the eth1
|
// processChainStartTime initializes a series of deposits from the ChainStart deposits in the eth1
|
||||||
// deposit contract, initializes the beacon chain's state, and kicks off the beacon chain.
|
// deposit contract, initializes the beacon chain's state, and kicks off the beacon chain.
|
||||||
func (s *Service) processChainStartTime(ctx context.Context, genesisTime time.Time, chainStartSub event.Subscription) {
|
func (s *Service) processChainStartTime(ctx context.Context, genesisTime time.Time, chainStartSub event.Subscription) {
|
||||||
initialDeposits := s.web3Service.ChainStartDeposits()
|
initialDeposits := s.chainStartFetcher.ChainStartDeposits()
|
||||||
if err := s.initializeBeaconChain(ctx, genesisTime, initialDeposits, s.web3Service.ChainStartETH1Data()); err != nil {
|
if err := s.initializeBeaconChain(ctx, genesisTime, initialDeposits, s.chainStartFetcher.ChainStartEth1Data()); err != nil {
|
||||||
log.Fatalf("Could not initialize beacon chain: %v", err)
|
log.Fatalf("Could not initialize beacon chain: %v", err)
|
||||||
}
|
}
|
||||||
s.stateInitializedFeed.Send(genesisTime)
|
s.stateInitializedFeed.Send(genesisTime)
|
||||||
|
|||||||
@@ -206,12 +206,12 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
BeaconBlockBuf: 0,
|
BeaconBlockBuf: 0,
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
DepositCache: depositcache.NewDepositCache(),
|
DepositCache: depositcache.NewDepositCache(),
|
||||||
Web3Service: web3Service,
|
ChainStartFetcher: web3Service,
|
||||||
OpsPoolService: &mockOperationService{},
|
OpsPoolService: &mockOperationService{},
|
||||||
P2p: &mockBroadcaster{},
|
P2p: &mockBroadcaster{},
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("could not register blockchain service: %v", err)
|
t.Fatalf("could not register blockchain service: %v", err)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package testing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
@@ -67,7 +68,12 @@ func (ms *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attes
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// StateInitializedFeed mocks StateInitializedFeed method in chain service.
|
// GenesisTime mocks the same method in the chain service.
|
||||||
|
func (ms *ChainService) GenesisTime() time.Time {
|
||||||
|
return time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateInitializedFeed mocks the same method in the chain service.
|
||||||
func (ms *ChainService) StateInitializedFeed() *event.Feed {
|
func (ms *ChainService) StateInitializedFeed() *event.Feed {
|
||||||
return new(event.Feed)
|
return new(event.Feed)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,13 @@ var (
|
|||||||
Name: "grpc-gateway-port",
|
Name: "grpc-gateway-port",
|
||||||
Usage: "Enable gRPC gateway for JSON requests",
|
Usage: "Enable gRPC gateway for JSON requests",
|
||||||
}
|
}
|
||||||
// GenesisState defines a flag for the beacon node to load genesis state via file.
|
// InteropMockEth1DataVotesFlag enables mocking the eth1 proof-of-work chain data put into blocks by proposers.
|
||||||
GenesisState = cli.StringFlag{
|
InteropMockEth1DataVotesFlag = cli.BoolFlag{
|
||||||
|
Name: "interop-eth1data-votes",
|
||||||
|
Usage: "Enable mocking of eth1 data votes for proposers to package into blocks",
|
||||||
|
}
|
||||||
|
// InteropGenesisStateFlag defines a flag for the beacon node to load genesis state via file.
|
||||||
|
InteropGenesisStateFlag = cli.StringFlag{
|
||||||
Name: "interop-genesis-state",
|
Name: "interop-genesis-state",
|
||||||
Usage: "The genesis state file (.SSZ) to load from",
|
Usage: "The genesis state file (.SSZ) to load from",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ var appFlags = []cli.Flag{
|
|||||||
flags.KeyFlag,
|
flags.KeyFlag,
|
||||||
flags.EnableDBCleanup,
|
flags.EnableDBCleanup,
|
||||||
flags.GRPCGatewayPort,
|
flags.GRPCGatewayPort,
|
||||||
flags.GenesisState,
|
flags.InteropMockEth1DataVotesFlag,
|
||||||
|
flags.InteropGenesisStateFlag,
|
||||||
cmd.BootstrapNode,
|
cmd.BootstrapNode,
|
||||||
cmd.NoDiscovery,
|
cmd.NoDiscovery,
|
||||||
cmd.StaticPeers,
|
cmd.StaticPeers,
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ func (b *BeaconNode) startDB(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *BeaconNode) registerP2P(ctx *cli.Context) error {
|
func (b *BeaconNode) registerP2P(ctx *cli.Context) error {
|
||||||
// Bootnode ENR may be a filepath to an ENR file.
|
// Bootnode ENR may be a filepath to an ENR file.
|
||||||
bootnodeENR := ctx.GlobalString(cmd.BootstrapNode.Name)
|
bootnodeENR := ctx.GlobalString(cmd.BootstrapNode.Name)
|
||||||
if filepath.Ext(bootnodeENR) == ".enr" {
|
if filepath.Ext(bootnodeENR) == ".enr" {
|
||||||
b, err := ioutil.ReadFile(bootnodeENR)
|
b, err := ioutil.ReadFile(bootnodeENR)
|
||||||
@@ -249,14 +249,15 @@ func (b *BeaconNode) registerBlockchainService(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
maxRoutines := ctx.GlobalInt64(cmd.MaxGoroutines.Name)
|
maxRoutines := ctx.GlobalInt64(cmd.MaxGoroutines.Name)
|
||||||
|
interopLoadGenesisFlag := ctx.GlobalString(flags.InteropGenesisStateFlag.Name)
|
||||||
blockchainService, err := blockchain.NewService(context.Background(), &blockchain.Config{
|
blockchainService, err := blockchain.NewService(context.Background(), &blockchain.Config{
|
||||||
BeaconDB: b.db,
|
BeaconDB: b.db,
|
||||||
DepositCache: b.depositCache,
|
DepositCache: b.depositCache,
|
||||||
Web3Service: web3Service,
|
ChainStartFetcher: web3Service,
|
||||||
OpsPoolService: opsService,
|
OpsPoolService: opsService,
|
||||||
P2p: b.fetchP2P(ctx),
|
P2p: b.fetchP2P(ctx),
|
||||||
MaxRoutines: maxRoutines,
|
MaxRoutines: maxRoutines,
|
||||||
|
PreloadStatePath: interopLoadGenesisFlag,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not register blockchain service")
|
return errors.Wrap(err, "could not register blockchain service")
|
||||||
@@ -277,9 +278,7 @@ func (b *BeaconNode) registerPOWChainService(cliCtx *cli.Context) error {
|
|||||||
if cliCtx.GlobalBool(testSkipPowFlag) {
|
if cliCtx.GlobalBool(testSkipPowFlag) {
|
||||||
return b.services.RegisterService(&powchain.Service{})
|
return b.services.RegisterService(&powchain.Service{})
|
||||||
}
|
}
|
||||||
|
|
||||||
depAddress := cliCtx.GlobalString(flags.DepositContractFlag.Name)
|
depAddress := cliCtx.GlobalString(flags.DepositContractFlag.Name)
|
||||||
|
|
||||||
if depAddress == "" {
|
if depAddress == "" {
|
||||||
var err error
|
var err error
|
||||||
depAddress, err = fetchDepositContract()
|
depAddress, err = fetchDepositContract()
|
||||||
@@ -404,17 +403,23 @@ func (b *BeaconNode) registerRPCService(ctx *cli.Context) error {
|
|||||||
port := ctx.GlobalString(flags.RPCPort.Name)
|
port := ctx.GlobalString(flags.RPCPort.Name)
|
||||||
cert := ctx.GlobalString(flags.CertFlag.Name)
|
cert := ctx.GlobalString(flags.CertFlag.Name)
|
||||||
key := ctx.GlobalString(flags.KeyFlag.Name)
|
key := ctx.GlobalString(flags.KeyFlag.Name)
|
||||||
|
mockEth1DataVotes := ctx.GlobalBool(flags.InteropMockEth1DataVotesFlag.Name)
|
||||||
rpcService := rpc.NewService(context.Background(), &rpc.Config{
|
rpcService := rpc.NewService(context.Background(), &rpc.Config{
|
||||||
Port: port,
|
Port: port,
|
||||||
CertFlag: cert,
|
CertFlag: cert,
|
||||||
KeyFlag: key,
|
KeyFlag: key,
|
||||||
BeaconDB: b.db,
|
BeaconDB: b.db,
|
||||||
Broadcaster: b.fetchP2P(ctx),
|
Broadcaster: b.fetchP2P(ctx),
|
||||||
ChainService: chainService,
|
HeadFetcher: chainService,
|
||||||
OperationService: operationService,
|
BlockReceiver: chainService,
|
||||||
POWChainService: web3Service,
|
AttestationReceiver: chainService,
|
||||||
SyncService: syncService,
|
StateFeedListener: chainService,
|
||||||
DepositCache: b.depositCache,
|
AttestationsPool: operationService,
|
||||||
|
OperationsHandler: operationService,
|
||||||
|
POWChainService: web3Service,
|
||||||
|
MockEth1Votes: mockEth1DataVotes,
|
||||||
|
SyncService: syncService,
|
||||||
|
DepositCache: b.depositCache,
|
||||||
})
|
})
|
||||||
|
|
||||||
return b.services.RegisterService(rpcService)
|
return b.services.RegisterService(rpcService)
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ type Pool interface {
|
|||||||
AttestationPool(ctx context.Context, requestedSlot uint64) ([]*ethpb.Attestation, error)
|
AttestationPool(ctx context.Context, requestedSlot uint64) ([]*ethpb.Attestation, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handler defines an interface for a struct equipped for receiving block operations.
|
||||||
|
type Handler interface {
|
||||||
|
HandleAttestation(context.Context, proto.Message) error
|
||||||
|
}
|
||||||
|
|
||||||
// OperationFeeds inteface defines the informational feeds from the operations
|
// OperationFeeds inteface defines the informational feeds from the operations
|
||||||
// service.
|
// service.
|
||||||
type OperationFeeds interface {
|
type OperationFeeds interface {
|
||||||
|
|||||||
13
beacon-chain/operations/testing/BUILD.bazel
Normal file
13
beacon-chain/operations/testing/BUILD.bazel
Normal file
@@ -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/operations/testing",
|
||||||
|
visibility = ["//beacon-chain:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
"//proto/eth/v1alpha1:go_default_library",
|
||||||
|
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
23
beacon-chain/operations/testing/mock.go
Normal file
23
beacon-chain/operations/testing/mock.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Operations defines a mock for the operations service.
|
||||||
|
type Operations struct {
|
||||||
|
Attestations []*ethpb.Attestation
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttestationPool --
|
||||||
|
func (op *Operations) AttestationPool(ctx context.Context, requestedSlot uint64) ([]*ethpb.Attestation, error) {
|
||||||
|
return op.Attestations, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleAttestation --
|
||||||
|
func (op *Operations) HandleAttestation(context.Context, proto.Message) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -25,10 +25,10 @@ func TestLatestMainchainInfo_OK(t *testing.T) {
|
|||||||
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
|
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
DepositContract: testAcc.ContractAddr,
|
DepositContract: testAcc.ContractAddr,
|
||||||
|
BlockFetcher: &goodFetcher{},
|
||||||
Reader: &goodReader{},
|
Reader: &goodReader{},
|
||||||
Logger: &goodLogger{},
|
Logger: &goodLogger{},
|
||||||
HTTPLogger: &goodLogger{},
|
HTTPLogger: &goodLogger{},
|
||||||
BlockFetcher: &goodFetcher{},
|
|
||||||
ContractBackend: testAcc.Backend,
|
ContractBackend: testAcc.Backend,
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ var (
|
|||||||
depositEventSignature = []byte("DepositEvent(bytes,bytes,bytes,bytes,bytes)")
|
depositEventSignature = []byte("DepositEvent(bytes,bytes,bytes,bytes,bytes)")
|
||||||
)
|
)
|
||||||
|
|
||||||
// ETH2GenesisTime retrieves the genesis time and eth1 block number of the beacon chain
|
// Eth2GenesisPowchainInfo retrieves the genesis time and eth1 block number of the beacon chain
|
||||||
// from the deposit contract.
|
// from the deposit contract.
|
||||||
func (s *Service) ETH2GenesisTime() (uint64, *big.Int) {
|
func (s *Service) Eth2GenesisPowchainInfo() (uint64, *big.Int) {
|
||||||
return s.eth2GenesisTime, s.chainStartBlockNumber
|
return s.eth2GenesisTime, s.chainStartBlockNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,22 +50,52 @@ type Reader interface {
|
|||||||
SubscribeNewHead(ctx context.Context, ch chan<- *gethTypes.Header) (ethereum.Subscription, error)
|
SubscribeNewHead(ctx context.Context, ch chan<- *gethTypes.Header) (ethereum.Subscription, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ChainStartFetcher retrieves information pertaining to the chain start event
|
||||||
|
// of the beacon chain for usage across various services.
|
||||||
|
type ChainStartFetcher interface {
|
||||||
|
ChainStartDeposits() []*ethpb.Deposit
|
||||||
|
ChainStartEth1Data() *ethpb.Eth1Data
|
||||||
|
ChainStartFeed() *event.Feed
|
||||||
|
HasChainStarted() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainInfoFetcher retrieves information about eth1 metadata at the eth2 genesis time.
|
||||||
|
type ChainInfoFetcher interface {
|
||||||
|
Eth2GenesisPowchainInfo() (uint64, *big.Int)
|
||||||
|
}
|
||||||
|
|
||||||
// POWBlockFetcher defines a struct that can retrieve mainchain blocks.
|
// POWBlockFetcher defines a struct that can retrieve mainchain blocks.
|
||||||
type POWBlockFetcher interface {
|
type POWBlockFetcher interface {
|
||||||
BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error)
|
BlockTimeByHeight(ctx context.Context, height *big.Int) (uint64, error)
|
||||||
BlockByNumber(ctx context.Context, number *big.Int) (*gethTypes.Block, error)
|
BlockNumberByTimestamp(ctx context.Context, time uint64) (*big.Int, error)
|
||||||
HeaderByNumber(ctx context.Context, number *big.Int) (*gethTypes.Header, error)
|
BlockHashByHeight(ctx context.Context, height *big.Int) (common.Hash, error)
|
||||||
|
BlockExists(ctx context.Context, hash common.Hash) (bool, *big.Int, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chain defines a standard interface for the powchain service in Prysm.
|
||||||
|
type Chain interface {
|
||||||
|
ChainStartFetcher
|
||||||
|
ChainInfoFetcher
|
||||||
|
POWBlockFetcher
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client defines a struct that combines all relevant ETH1.0 mainchain interactions required
|
// Client defines a struct that combines all relevant ETH1.0 mainchain interactions required
|
||||||
// by the beacon chain node.
|
// by the beacon chain node.
|
||||||
type Client interface {
|
type Client interface {
|
||||||
Reader
|
Reader
|
||||||
POWBlockFetcher
|
RPCBlockFetcher
|
||||||
bind.ContractFilterer
|
bind.ContractFilterer
|
||||||
bind.ContractCaller
|
bind.ContractCaller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RPCBlockFetcher defines a subset of methods conformed to by ETH1.0 RPC clients for
|
||||||
|
// fetching block information.
|
||||||
|
type RPCBlockFetcher interface {
|
||||||
|
HeaderByNumber(ctx context.Context, number *big.Int) (*gethTypes.Header, error)
|
||||||
|
BlockByNumber(ctx context.Context, number *big.Int) (*gethTypes.Block, error)
|
||||||
|
BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error)
|
||||||
|
}
|
||||||
|
|
||||||
// Service fetches important information about the canonical
|
// Service fetches important information about the canonical
|
||||||
// Ethereum ETH1.0 chain via a web3 endpoint using an ethclient. The Random
|
// Ethereum ETH1.0 chain via a web3 endpoint using an ethclient. The Random
|
||||||
// Beacon Chain requires synchronization with the ETH1.0 chain's current
|
// Beacon Chain requires synchronization with the ETH1.0 chain's current
|
||||||
@@ -83,7 +113,7 @@ type Service struct {
|
|||||||
reader Reader
|
reader Reader
|
||||||
logger bind.ContractFilterer
|
logger bind.ContractFilterer
|
||||||
httpLogger bind.ContractFilterer
|
httpLogger bind.ContractFilterer
|
||||||
blockFetcher POWBlockFetcher
|
blockFetcher RPCBlockFetcher
|
||||||
blockHeight *big.Int // the latest ETH1.0 chain blockHeight.
|
blockHeight *big.Int // the latest ETH1.0 chain blockHeight.
|
||||||
blockHash common.Hash // the latest ETH1.0 chain blockHash.
|
blockHash common.Hash // the latest ETH1.0 chain blockHash.
|
||||||
blockTime time.Time // the latest ETH1.0 chain blockTime.
|
blockTime time.Time // the latest ETH1.0 chain blockTime.
|
||||||
@@ -115,7 +145,7 @@ type Web3ServiceConfig struct {
|
|||||||
Reader Reader
|
Reader Reader
|
||||||
Logger bind.ContractFilterer
|
Logger bind.ContractFilterer
|
||||||
HTTPLogger bind.ContractFilterer
|
HTTPLogger bind.ContractFilterer
|
||||||
BlockFetcher POWBlockFetcher
|
BlockFetcher RPCBlockFetcher
|
||||||
ContractBackend bind.ContractBackend
|
ContractBackend bind.ContractBackend
|
||||||
BeaconDB db.Database
|
BeaconDB db.Database
|
||||||
DepositCache *depositcache.DepositCache
|
DepositCache *depositcache.DepositCache
|
||||||
@@ -201,8 +231,8 @@ func (s *Service) ChainStartDeposits() []*ethpb.Deposit {
|
|||||||
return s.chainStartDeposits
|
return s.chainStartDeposits
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainStartETH1Data returns the eth1 data at chainstart.
|
// ChainStartEth1Data returns the eth1 data at chainstart.
|
||||||
func (s *Service) ChainStartETH1Data() *ethpb.Eth1Data {
|
func (s *Service) ChainStartEth1Data() *ethpb.Eth1Data {
|
||||||
return s.chainStartETH1Data
|
return s.chainStartETH1Data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ import (
|
|||||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ = ChainStartFetcher(&Service{})
|
||||||
|
var _ = ChainInfoFetcher(&Service{})
|
||||||
|
var _ = POWBlockFetcher(&Service{})
|
||||||
|
var _ = Chain(&Service{})
|
||||||
|
|
||||||
type badReader struct{}
|
type badReader struct{}
|
||||||
|
|
||||||
func (b *badReader) SubscribeNewHead(ctx context.Context, ch chan<- *gethTypes.Header) (ethereum.Subscription, error) {
|
func (b *badReader) SubscribeNewHead(ctx context.Context, ch chan<- *gethTypes.Header) (ethereum.Subscription, error) {
|
||||||
|
|||||||
19
beacon-chain/powchain/testing/BUILD.bazel
Normal file
19
beacon-chain/powchain/testing/BUILD.bazel
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
testonly = True,
|
||||||
|
srcs = [
|
||||||
|
"faulty_mock.go",
|
||||||
|
"mock.go",
|
||||||
|
],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing",
|
||||||
|
visibility = ["//beacon-chain:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
"//proto/eth/v1alpha1:go_default_library",
|
||||||
|
"//shared/bytesutil:go_default_library",
|
||||||
|
"//shared/event:go_default_library",
|
||||||
|
"//shared/trieutil:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
87
beacon-chain/powchain/testing/faulty_mock.go
generated
Normal file
87
beacon-chain/powchain/testing/faulty_mock.go
generated
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/shared/event"
|
||||||
|
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FaultyMockPOWChain defines an incorrectly functioning powchain service.
|
||||||
|
type FaultyMockPOWChain struct {
|
||||||
|
ChainFeed *event.Feed
|
||||||
|
HashesByHeight map[int][]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasChainStarted --
|
||||||
|
func (f *FaultyMockPOWChain) HasChainStarted() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eth2GenesisPowchainInfo --
|
||||||
|
func (f *FaultyMockPOWChain) Eth2GenesisPowchainInfo() (uint64, *big.Int) {
|
||||||
|
return 0, big.NewInt(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStartFeed --
|
||||||
|
func (f *FaultyMockPOWChain) ChainStartFeed() *event.Feed {
|
||||||
|
return f.ChainFeed
|
||||||
|
}
|
||||||
|
|
||||||
|
// LatestBlockHeight --
|
||||||
|
func (f *FaultyMockPOWChain) LatestBlockHeight() *big.Int {
|
||||||
|
return big.NewInt(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockExists --
|
||||||
|
func (f *FaultyMockPOWChain) BlockExists(_ context.Context, hash common.Hash) (bool, *big.Int, error) {
|
||||||
|
if f.HashesByHeight == nil {
|
||||||
|
return false, big.NewInt(1), errors.New("failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, big.NewInt(1), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockHashByHeight --
|
||||||
|
func (f *FaultyMockPOWChain) BlockHashByHeight(_ context.Context, height *big.Int) (common.Hash, error) {
|
||||||
|
return [32]byte{}, errors.New("failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockTimeByHeight --
|
||||||
|
func (f *FaultyMockPOWChain) BlockTimeByHeight(_ context.Context, height *big.Int) (uint64, error) {
|
||||||
|
return 0, errors.New("failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockNumberByTimestamp --
|
||||||
|
func (f *FaultyMockPOWChain) BlockNumberByTimestamp(_ context.Context, _ uint64) (*big.Int, error) {
|
||||||
|
return big.NewInt(0), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DepositRoot --
|
||||||
|
func (f *FaultyMockPOWChain) DepositRoot() [32]byte {
|
||||||
|
return [32]byte{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DepositTrie --
|
||||||
|
func (f *FaultyMockPOWChain) DepositTrie() *trieutil.MerkleTrie {
|
||||||
|
return &trieutil.MerkleTrie{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStartDeposits --
|
||||||
|
func (f *FaultyMockPOWChain) ChainStartDeposits() []*ethpb.Deposit {
|
||||||
|
return []*ethpb.Deposit{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStartDepositHashes --
|
||||||
|
func (f *FaultyMockPOWChain) ChainStartDepositHashes() ([][]byte, error) {
|
||||||
|
return [][]byte{}, errors.New("hashing failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStartEth1Data --
|
||||||
|
func (f *FaultyMockPOWChain) ChainStartEth1Data() *ethpb.Eth1Data {
|
||||||
|
return ðpb.Eth1Data{}
|
||||||
|
}
|
||||||
106
beacon-chain/powchain/testing/mock.go
Normal file
106
beacon-chain/powchain/testing/mock.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||||
|
"github.com/prysmaticlabs/prysm/shared/event"
|
||||||
|
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// POWChain defines a properly functioning mock for the powchain service.
|
||||||
|
type POWChain struct {
|
||||||
|
ChainFeed *event.Feed
|
||||||
|
LatestBlockNumber *big.Int
|
||||||
|
HashesByHeight map[int][]byte
|
||||||
|
TimesByHeight map[int]uint64
|
||||||
|
BlockNumberByHeight map[uint64]*big.Int
|
||||||
|
Eth1Data *ethpb.Eth1Data
|
||||||
|
GenesisEth1Block *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStartFeed --
|
||||||
|
func (m *POWChain) ChainStartFeed() *event.Feed {
|
||||||
|
return m.ChainFeed
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasChainStarted --
|
||||||
|
func (m *POWChain) HasChainStarted() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eth2GenesisPowchainInfo --
|
||||||
|
func (m *POWChain) Eth2GenesisPowchainInfo() (uint64, *big.Int) {
|
||||||
|
blk := m.GenesisEth1Block
|
||||||
|
if blk == nil {
|
||||||
|
blk = big.NewInt(0)
|
||||||
|
}
|
||||||
|
return uint64(time.Unix(0, 0).Unix()), blk
|
||||||
|
}
|
||||||
|
|
||||||
|
// DepositTrie --
|
||||||
|
func (m *POWChain) DepositTrie() *trieutil.MerkleTrie {
|
||||||
|
return &trieutil.MerkleTrie{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockExists --
|
||||||
|
func (m *POWChain) BlockExists(_ context.Context, hash common.Hash) (bool, *big.Int, error) {
|
||||||
|
// Reverse the map of heights by hash.
|
||||||
|
heightsByHash := make(map[[32]byte]int)
|
||||||
|
for k, v := range m.HashesByHeight {
|
||||||
|
h := bytesutil.ToBytes32(v)
|
||||||
|
heightsByHash[h] = k
|
||||||
|
}
|
||||||
|
val, ok := heightsByHash[hash]
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("could not fetch height for hash: %#x", hash)
|
||||||
|
}
|
||||||
|
return true, big.NewInt(int64(val)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockHashByHeight --
|
||||||
|
func (m *POWChain) BlockHashByHeight(_ context.Context, height *big.Int) (common.Hash, error) {
|
||||||
|
k := int(height.Int64())
|
||||||
|
val, ok := m.HashesByHeight[k]
|
||||||
|
if !ok {
|
||||||
|
return [32]byte{}, fmt.Errorf("could not fetch hash for height: %v", height)
|
||||||
|
}
|
||||||
|
return bytesutil.ToBytes32(val), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockTimeByHeight --
|
||||||
|
func (m *POWChain) BlockTimeByHeight(_ context.Context, height *big.Int) (uint64, error) {
|
||||||
|
h := int(height.Int64())
|
||||||
|
return m.TimesByHeight[h], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockNumberByTimestamp --
|
||||||
|
func (m *POWChain) BlockNumberByTimestamp(_ context.Context, time uint64) (*big.Int, error) {
|
||||||
|
return m.BlockNumberByHeight[time], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DepositRoot --
|
||||||
|
func (m *POWChain) DepositRoot() [32]byte {
|
||||||
|
root := []byte("depositroot")
|
||||||
|
return bytesutil.ToBytes32(root)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStartDeposits --
|
||||||
|
func (m *POWChain) ChainStartDeposits() []*ethpb.Deposit {
|
||||||
|
return []*ethpb.Deposit{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStartDepositHashes --
|
||||||
|
func (m *POWChain) ChainStartDepositHashes() ([][]byte, error) {
|
||||||
|
return [][]byte{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStartEth1Data --
|
||||||
|
func (m *POWChain) ChainStartEth1Data() *ethpb.Eth1Data {
|
||||||
|
return m.Eth1Data
|
||||||
|
}
|
||||||
@@ -27,18 +27,17 @@ go_library(
|
|||||||
"//beacon-chain/db/kv:go_default_library",
|
"//beacon-chain/db/kv:go_default_library",
|
||||||
"//beacon-chain/operations:go_default_library",
|
"//beacon-chain/operations:go_default_library",
|
||||||
"//beacon-chain/p2p:go_default_library",
|
"//beacon-chain/p2p:go_default_library",
|
||||||
|
"//beacon-chain/powchain:go_default_library",
|
||||||
"//beacon-chain/sync:go_default_library",
|
"//beacon-chain/sync:go_default_library",
|
||||||
"//proto/beacon/p2p/v1:go_default_library",
|
"//proto/beacon/p2p/v1:go_default_library",
|
||||||
"//proto/beacon/rpc/v1:go_default_library",
|
"//proto/beacon/rpc/v1:go_default_library",
|
||||||
"//proto/eth/v1alpha1:go_default_library",
|
"//proto/eth/v1alpha1:go_default_library",
|
||||||
"//shared/bytesutil:go_default_library",
|
"//shared/bytesutil:go_default_library",
|
||||||
"//shared/event:go_default_library",
|
"//shared/hashutil:go_default_library",
|
||||||
"//shared/pagination:go_default_library",
|
"//shared/pagination:go_default_library",
|
||||||
"//shared/params:go_default_library",
|
"//shared/params:go_default_library",
|
||||||
"//shared/trieutil:go_default_library",
|
"//shared/trieutil:go_default_library",
|
||||||
"//shared/version:go_default_library",
|
"//shared/version: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_gogo_protobuf//types:go_default_library",
|
||||||
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_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_middleware//recovery:go_default_library",
|
||||||
@@ -78,7 +77,11 @@ go_test(
|
|||||||
"//beacon-chain/core/state:go_default_library",
|
"//beacon-chain/core/state:go_default_library",
|
||||||
"//beacon-chain/db:go_default_library",
|
"//beacon-chain/db:go_default_library",
|
||||||
"//beacon-chain/db/testing:go_default_library",
|
"//beacon-chain/db/testing:go_default_library",
|
||||||
|
"//beacon-chain/operations/testing:go_default_library",
|
||||||
|
"//beacon-chain/p2p/testing:go_default_library",
|
||||||
|
"//beacon-chain/powchain/testing:go_default_library",
|
||||||
"//beacon-chain/rpc/testing:go_default_library",
|
"//beacon-chain/rpc/testing:go_default_library",
|
||||||
|
"//beacon-chain/sync/testing:go_default_library",
|
||||||
"//proto/beacon/p2p/v1:go_default_library",
|
"//proto/beacon/p2p/v1:go_default_library",
|
||||||
"//proto/beacon/rpc/v1:go_default_library",
|
"//proto/beacon/rpc/v1:go_default_library",
|
||||||
"//proto/eth/v1alpha1:go_default_library",
|
"//proto/eth/v1alpha1:go_default_library",
|
||||||
@@ -86,11 +89,11 @@ go_test(
|
|||||||
"//shared/bytesutil:go_default_library",
|
"//shared/bytesutil:go_default_library",
|
||||||
"//shared/event:go_default_library",
|
"//shared/event:go_default_library",
|
||||||
"//shared/featureconfig:go_default_library",
|
"//shared/featureconfig:go_default_library",
|
||||||
|
"//shared/hashutil:go_default_library",
|
||||||
"//shared/params:go_default_library",
|
"//shared/params:go_default_library",
|
||||||
"//shared/testutil:go_default_library",
|
"//shared/testutil:go_default_library",
|
||||||
"//shared/trieutil:go_default_library",
|
"//shared/trieutil:go_default_library",
|
||||||
"//shared/version:go_default_library",
|
"//shared/version:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
|
||||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||||
"@com_github_gogo_protobuf//types:go_default_library",
|
"@com_github_gogo_protobuf//types:go_default_library",
|
||||||
"@com_github_golang_mock//gomock:go_default_library",
|
"@com_github_golang_mock//gomock:go_default_library",
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/go-ssz"
|
"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/cache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/operations"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
|
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
@@ -19,11 +21,12 @@ import (
|
|||||||
// AttesterServer defines a server implementation of the gRPC Attester service,
|
// AttesterServer defines a server implementation of the gRPC Attester service,
|
||||||
// providing RPC methods for validators acting as attesters to broadcast votes on beacon blocks.
|
// providing RPC methods for validators acting as attesters to broadcast votes on beacon blocks.
|
||||||
type AttesterServer struct {
|
type AttesterServer struct {
|
||||||
p2p p2p.Broadcaster
|
p2p p2p.Broadcaster
|
||||||
beaconDB db.Database
|
beaconDB db.Database
|
||||||
operationService operationService
|
operationsHandler operations.Handler
|
||||||
chainService chainService
|
attReceiver blockchain.AttestationReceiver
|
||||||
cache *cache.AttestationCache
|
headFetcher blockchain.HeadFetcher
|
||||||
|
depositCache *cache.AttestationCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubmitAttestation is a function called by an attester in a sharding validator to vote
|
// SubmitAttestation is a function called by an attester in a sharding validator to vote
|
||||||
@@ -34,12 +37,12 @@ func (as *AttesterServer) SubmitAttestation(ctx context.Context, att *ethpb.Atte
|
|||||||
return nil, errors.Wrap(err, "failed to sign root attestation")
|
return nil, errors.Wrap(err, "failed to sign root attestation")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := as.operationService.HandleAttestation(ctx, att); err != nil {
|
if err := as.operationsHandler.HandleAttestation(ctx, att); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := as.chainService.ReceiveAttestation(ctx, att); err != nil {
|
if err := as.attReceiver.ReceiveAttestation(ctx, att); err != nil {
|
||||||
log.WithError(err).Error("could not receive attestation in chain service")
|
log.WithError(err).Error("could not receive attestation in chain service")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -56,7 +59,7 @@ func (as *AttesterServer) RequestAttestation(ctx context.Context, req *pb.Attest
|
|||||||
trace.Int64Attribute("slot", int64(req.Slot)),
|
trace.Int64Attribute("slot", int64(req.Slot)),
|
||||||
trace.Int64Attribute("shard", int64(req.Shard)),
|
trace.Int64Attribute("shard", int64(req.Shard)),
|
||||||
)
|
)
|
||||||
res, err := as.cache.Get(ctx, req)
|
res, err := as.depositCache.Get(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -65,9 +68,9 @@ func (as *AttesterServer) RequestAttestation(ctx context.Context, req *pb.Attest
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := as.cache.MarkInProgress(req); err != nil {
|
if err := as.depositCache.MarkInProgress(req); err != nil {
|
||||||
if err == cache.ErrAlreadyInProgress {
|
if err == cache.ErrAlreadyInProgress {
|
||||||
res, err := as.cache.Get(ctx, req)
|
res, err := as.depositCache.Get(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,13 +83,13 @@ func (as *AttesterServer) RequestAttestation(ctx context.Context, req *pb.Attest
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := as.cache.MarkNotInProgress(req); err != nil {
|
if err := as.depositCache.MarkNotInProgress(req); err != nil {
|
||||||
log.WithError(err).Error("Failed to mark cache not in progress")
|
log.WithError(err).Error("Failed to mark cache not in progress")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
headState := as.chainService.HeadState()
|
headState := as.headFetcher.HeadState()
|
||||||
headRoot := as.chainService.HeadRoot()
|
headRoot := as.headFetcher.HeadRoot()
|
||||||
|
|
||||||
headState, err = state.ProcessSlots(ctx, headState, req.Slot)
|
headState, err = state.ProcessSlots(ctx, headState, req.Slot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -130,7 +133,7 @@ func (as *AttesterServer) RequestAttestation(ctx context.Context, req *pb.Attest
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := as.cache.Put(ctx, req, res); err != nil {
|
if err := as.depositCache.Put(ctx, req, res); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
|
mockOps "github.com/prysmaticlabs/prysm/beacon-chain/operations/testing"
|
||||||
|
mockp2p "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
|
||||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
@@ -18,24 +20,18 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/shared/params"
|
"github.com/prysmaticlabs/prysm/shared/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockBroadcaster struct{}
|
|
||||||
|
|
||||||
func (m *mockBroadcaster) Broadcast(ctx context.Context, msg proto.Message) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSubmitAttestation_OK(t *testing.T) {
|
func TestSubmitAttestation_OK(t *testing.T) {
|
||||||
db := dbutil.SetupDB(t)
|
db := dbutil.SetupDB(t)
|
||||||
defer dbutil.TeardownDB(t, db)
|
defer dbutil.TeardownDB(t, db)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
mockOperationService := &mockOperationService{}
|
|
||||||
attesterServer := &AttesterServer{
|
attesterServer := &AttesterServer{
|
||||||
chainService: &mock.ChainService{},
|
headFetcher: &mock.ChainService{},
|
||||||
operationService: mockOperationService,
|
attReceiver: &mock.ChainService{},
|
||||||
p2p: &mockBroadcaster{},
|
operationsHandler: &mockOps.Operations{},
|
||||||
beaconDB: db,
|
p2p: &mockp2p.MockBroadcaster{},
|
||||||
cache: cache.NewAttestationCache(),
|
beaconDB: db,
|
||||||
|
depositCache: cache.NewAttestationCache(),
|
||||||
}
|
}
|
||||||
head := ðpb.BeaconBlock{
|
head := ðpb.BeaconBlock{
|
||||||
Slot: 999,
|
Slot: 999,
|
||||||
@@ -132,9 +128,10 @@ func TestRequestAttestation_OK(t *testing.T) {
|
|||||||
beaconState.BlockRoots[1*params.BeaconConfig().SlotsPerEpoch] = targetRoot[:]
|
beaconState.BlockRoots[1*params.BeaconConfig().SlotsPerEpoch] = targetRoot[:]
|
||||||
beaconState.BlockRoots[2*params.BeaconConfig().SlotsPerEpoch] = justifiedRoot[:]
|
beaconState.BlockRoots[2*params.BeaconConfig().SlotsPerEpoch] = justifiedRoot[:]
|
||||||
attesterServer := &AttesterServer{
|
attesterServer := &AttesterServer{
|
||||||
p2p: &mockBroadcaster{},
|
p2p: &mockp2p.MockBroadcaster{},
|
||||||
cache: cache.NewAttestationCache(),
|
depositCache: cache.NewAttestationCache(),
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blockRoot[:]},
|
headFetcher: &mock.ChainService{State: beaconState, Root: blockRoot[:]},
|
||||||
|
attReceiver: &mock.ChainService{State: beaconState, Root: blockRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &pb.AttestationRequest{
|
req := &pb.AttestationRequest{
|
||||||
@@ -232,9 +229,10 @@ func TestAttestationDataAtSlot_handlesFarAwayJustifiedEpoch(t *testing.T) {
|
|||||||
beaconState.BlockRoots[1*params.BeaconConfig().SlotsPerEpoch] = epochBoundaryRoot[:]
|
beaconState.BlockRoots[1*params.BeaconConfig().SlotsPerEpoch] = epochBoundaryRoot[:]
|
||||||
beaconState.BlockRoots[2*params.BeaconConfig().SlotsPerEpoch] = justifiedBlockRoot[:]
|
beaconState.BlockRoots[2*params.BeaconConfig().SlotsPerEpoch] = justifiedBlockRoot[:]
|
||||||
attesterServer := &AttesterServer{
|
attesterServer := &AttesterServer{
|
||||||
p2p: &mockBroadcaster{},
|
p2p: &mockp2p.MockBroadcaster{},
|
||||||
cache: cache.NewAttestationCache(),
|
depositCache: cache.NewAttestationCache(),
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blockRoot[:]},
|
headFetcher: &mock.ChainService{State: beaconState, Root: blockRoot[:]},
|
||||||
|
attReceiver: &mock.ChainService{State: beaconState, Root: blockRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &pb.AttestationRequest{
|
req := &pb.AttestationRequest{
|
||||||
@@ -283,7 +281,7 @@ func TestAttestationDataAtSlot_handlesInProgressRequest(t *testing.T) {
|
|||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
server := &AttesterServer{
|
server := &AttesterServer{
|
||||||
cache: cache.NewAttestationCache(),
|
depositCache: cache.NewAttestationCache(),
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &pb.AttestationRequest{
|
req := &pb.AttestationRequest{
|
||||||
@@ -295,7 +293,7 @@ func TestAttestationDataAtSlot_handlesInProgressRequest(t *testing.T) {
|
|||||||
Target: ðpb.Checkpoint{Epoch: 55},
|
Target: ðpb.Checkpoint{Epoch: 55},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := server.cache.MarkInProgress(req); err != nil {
|
if err := server.depositCache.MarkInProgress(req); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,10 +315,10 @@ func TestAttestationDataAtSlot_handlesInProgressRequest(t *testing.T) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
if err := server.cache.Put(ctx, req, res); err != nil {
|
if err := server.depositCache.Put(ctx, req, res); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
if err := server.cache.MarkNotInProgress(req); err != nil {
|
if err := server.depositCache.MarkNotInProgress(req); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ import (
|
|||||||
// providing RPC endpoints to access data relevant to the Ethereum 2.0 phase 0
|
// providing RPC endpoints to access data relevant to the Ethereum 2.0 phase 0
|
||||||
// beacon chain.
|
// beacon chain.
|
||||||
type BeaconChainServer struct {
|
type BeaconChainServer struct {
|
||||||
beaconDB db.Database
|
beaconDB db.Database
|
||||||
chainService blockchain.HeadRetriever
|
headFetcher blockchain.HeadFetcher
|
||||||
pool operations.Pool
|
pool operations.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
// sortableAttestations implements the Sort interface to sort attestations
|
// sortableAttestations implements the Sort interface to sort attestations
|
||||||
@@ -197,13 +197,13 @@ func (bs *BeaconChainServer) ListBlocks(
|
|||||||
// This includes the head block slot and root as well as information about
|
// This includes the head block slot and root as well as information about
|
||||||
// the most recent finalized and justified slots.
|
// the most recent finalized and justified slots.
|
||||||
func (bs *BeaconChainServer) GetChainHead(ctx context.Context, _ *ptypes.Empty) (*ethpb.ChainHead, error) {
|
func (bs *BeaconChainServer) GetChainHead(ctx context.Context, _ *ptypes.Empty) (*ethpb.ChainHead, error) {
|
||||||
finalizedCheckpoint := bs.chainService.HeadState().FinalizedCheckpoint
|
finalizedCheckpoint := bs.headFetcher.HeadState().FinalizedCheckpoint
|
||||||
justifiedCheckpoint := bs.chainService.HeadState().CurrentJustifiedCheckpoint
|
justifiedCheckpoint := bs.headFetcher.HeadState().CurrentJustifiedCheckpoint
|
||||||
prevJustifiedCheckpoint := bs.chainService.HeadState().PreviousJustifiedCheckpoint
|
prevJustifiedCheckpoint := bs.headFetcher.HeadState().PreviousJustifiedCheckpoint
|
||||||
|
|
||||||
return ðpb.ChainHead{
|
return ðpb.ChainHead{
|
||||||
BlockRoot: bs.chainService.HeadRoot(),
|
BlockRoot: bs.headFetcher.HeadRoot(),
|
||||||
BlockSlot: bs.chainService.HeadSlot(),
|
BlockSlot: bs.headFetcher.HeadSlot(),
|
||||||
FinalizedBlockRoot: finalizedCheckpoint.Root,
|
FinalizedBlockRoot: finalizedCheckpoint.Root,
|
||||||
FinalizedSlot: finalizedCheckpoint.Epoch * params.BeaconConfig().SlotsPerEpoch,
|
FinalizedSlot: finalizedCheckpoint.Epoch * params.BeaconConfig().SlotsPerEpoch,
|
||||||
JustifiedBlockRoot: justifiedCheckpoint.Root,
|
JustifiedBlockRoot: justifiedCheckpoint.Root,
|
||||||
@@ -460,7 +460,7 @@ func (bs *BeaconChainServer) GetValidatorParticipation(
|
|||||||
ctx context.Context, req *ethpb.GetValidatorParticipationRequest,
|
ctx context.Context, req *ethpb.GetValidatorParticipationRequest,
|
||||||
) (*ethpb.ValidatorParticipation, error) {
|
) (*ethpb.ValidatorParticipation, error) {
|
||||||
|
|
||||||
headState := bs.chainService.HeadState()
|
headState := bs.headFetcher.HeadState()
|
||||||
currentEpoch := helpers.SlotToEpoch(headState.Slot)
|
currentEpoch := helpers.SlotToEpoch(headState.Slot)
|
||||||
finalized := currentEpoch == headState.FinalizedCheckpoint.Epoch
|
finalized := currentEpoch == headState.FinalizedCheckpoint.Epoch
|
||||||
|
|
||||||
|
|||||||
@@ -17,28 +17,12 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
testutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
|
mockOps "github.com/prysmaticlabs/prysm/beacon-chain/operations/testing"
|
||||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/shared/params"
|
"github.com/prysmaticlabs/prysm/shared/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockPool struct{}
|
|
||||||
|
|
||||||
func (m *mockPool) AttestationPool(ctx context.Context, expectedSlot uint64) ([]*ethpb.Attestation, error) {
|
|
||||||
return []*ethpb.Attestation{
|
|
||||||
{
|
|
||||||
Data: ðpb.AttestationData{
|
|
||||||
BeaconBlockRoot: []byte("1"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Data: ðpb.AttestationData{
|
|
||||||
BeaconBlockRoot: []byte("2"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconChainServer_ListAttestationsNoPagination(t *testing.T) {
|
func TestBeaconChainServer_ListAttestationsNoPagination(t *testing.T) {
|
||||||
db := testutil.SetupDB(t)
|
db := testutil.SetupDB(t)
|
||||||
defer testutil.TeardownDB(t, db)
|
defer testutil.TeardownDB(t, db)
|
||||||
@@ -259,7 +243,20 @@ func TestBeaconChainServer_AttestationPool(t *testing.T) {
|
|||||||
db := testutil.SetupDB(t)
|
db := testutil.SetupDB(t)
|
||||||
defer testutil.TeardownDB(t, db)
|
defer testutil.TeardownDB(t, db)
|
||||||
bs := &BeaconChainServer{
|
bs := &BeaconChainServer{
|
||||||
pool: &mockPool{},
|
pool: &mockOps.Operations{
|
||||||
|
Attestations: []*ethpb.Attestation{
|
||||||
|
{
|
||||||
|
Data: ðpb.AttestationData{
|
||||||
|
BeaconBlockRoot: []byte("1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: ðpb.AttestationData{
|
||||||
|
BeaconBlockRoot: []byte("2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
}
|
}
|
||||||
block := ðpb.BeaconBlock{
|
block := ðpb.BeaconBlock{
|
||||||
@@ -806,8 +803,8 @@ func TestBeaconChainServer_GetValidatorsParticipation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bs := &BeaconChainServer{
|
bs := &BeaconChainServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
chainService: &mock.ChainService{State: s},
|
headFetcher: &mock.ChainService{State: s},
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := bs.GetValidatorParticipation(ctx, ðpb.GetValidatorParticipationRequest{Epoch: epoch})
|
res, err := bs.GetValidatorParticipation(ctx, ðpb.GetValidatorParticipationRequest{Epoch: epoch})
|
||||||
@@ -1000,7 +997,7 @@ func TestBeaconChainServer_GetChainHead(t *testing.T) {
|
|||||||
FinalizedCheckpoint: ðpb.Checkpoint{Epoch: 1, Root: []byte{'C'}},
|
FinalizedCheckpoint: ðpb.Checkpoint{Epoch: 1, Root: []byte{'C'}},
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := &BeaconChainServer{chainService: &mock.ChainService{State: s}}
|
bs := &BeaconChainServer{headFetcher: &mock.ChainService{State: s}}
|
||||||
|
|
||||||
head, err := bs.GetChainHead(context.Background(), nil)
|
head, err := bs.GetChainHead(context.Background(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
@@ -22,9 +23,10 @@ import (
|
|||||||
type BeaconServer struct {
|
type BeaconServer struct {
|
||||||
beaconDB db.Database
|
beaconDB db.Database
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
powChainService powChainService
|
chainStartFetcher powchain.ChainStartFetcher
|
||||||
chainService chainService
|
eth1InfoFetcher powchain.ChainInfoFetcher
|
||||||
operationService operationService
|
headFetcher blockchain.HeadFetcher
|
||||||
|
stateFeedListener blockchain.ChainFeeds
|
||||||
incomingAttestation chan *ethpb.Attestation
|
incomingAttestation chan *ethpb.Attestation
|
||||||
canonicalStateChan chan *pbp2p.BeaconState
|
canonicalStateChan chan *pbp2p.BeaconState
|
||||||
chainStartChan chan time.Time
|
chainStartChan chan time.Time
|
||||||
@@ -35,11 +37,9 @@ type BeaconServer struct {
|
|||||||
// subscribes to an event stream triggered by the powchain service whenever the ChainStart log does
|
// subscribes to an event stream triggered by the powchain service whenever the ChainStart log does
|
||||||
// occur in the Deposit Contract on ETH 1.0.
|
// occur in the Deposit Contract on ETH 1.0.
|
||||||
func (bs *BeaconServer) WaitForChainStart(req *ptypes.Empty, stream pb.BeaconService_WaitForChainStartServer) error {
|
func (bs *BeaconServer) WaitForChainStart(req *ptypes.Empty, stream pb.BeaconService_WaitForChainStartServer) error {
|
||||||
ok := bs.powChainService.HasChainStarted()
|
ok := bs.chainStartFetcher.HasChainStarted()
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
genesisTime, _ := bs.powChainService.ETH2GenesisTime()
|
genesisTime, _ := bs.eth1InfoFetcher.Eth2GenesisPowchainInfo()
|
||||||
|
|
||||||
res := &pb.ChainStartResponse{
|
res := &pb.ChainStartResponse{
|
||||||
Started: true,
|
Started: true,
|
||||||
GenesisTime: genesisTime,
|
GenesisTime: genesisTime,
|
||||||
@@ -47,7 +47,7 @@ func (bs *BeaconServer) WaitForChainStart(req *ptypes.Empty, stream pb.BeaconSer
|
|||||||
return stream.Send(res)
|
return stream.Send(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
sub := bs.chainService.StateInitializedFeed().Subscribe(bs.chainStartChan)
|
sub := bs.stateFeedListener.StateInitializedFeed().Subscribe(bs.chainStartChan)
|
||||||
defer sub.Unsubscribe()
|
defer sub.Unsubscribe()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -69,8 +69,7 @@ func (bs *BeaconServer) WaitForChainStart(req *ptypes.Empty, stream pb.BeaconSer
|
|||||||
// CanonicalHead of the current beacon chain. This method is requested on-demand
|
// CanonicalHead of the current beacon chain. This method is requested on-demand
|
||||||
// by a validator when it is their time to propose or attest.
|
// by a validator when it is their time to propose or attest.
|
||||||
func (bs *BeaconServer) CanonicalHead(ctx context.Context, req *ptypes.Empty) (*ethpb.BeaconBlock, error) {
|
func (bs *BeaconServer) CanonicalHead(ctx context.Context, req *ptypes.Empty) (*ethpb.BeaconBlock, error) {
|
||||||
headBlock := bs.chainService.(blockchain.HeadRetriever).HeadBlock()
|
return bs.headFetcher.HeadBlock(), nil
|
||||||
return headBlock, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockTree returns the current tree of saved blocks and their votes starting from the justified state.
|
// BlockTree returns the current tree of saved blocks and their votes starting from the justified state.
|
||||||
|
|||||||
@@ -2,186 +2,37 @@ package rpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
ptypes "github.com/gogo/protobuf/types"
|
ptypes "github.com/gogo/protobuf/types"
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
mockClient "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
mockChain "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
|
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
|
||||||
mockRPC "github.com/prysmaticlabs/prysm/beacon-chain/rpc/testing"
|
mockRPC "github.com/prysmaticlabs/prysm/beacon-chain/rpc/testing"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
|
||||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
|
||||||
"github.com/prysmaticlabs/prysm/shared/event"
|
"github.com/prysmaticlabs/prysm/shared/event"
|
||||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||||
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
|
||||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
var closedContext = "context closed"
|
|
||||||
var mockSig [96]byte
|
|
||||||
var mockCreds [32]byte
|
|
||||||
|
|
||||||
type faultyPOWChainService struct {
|
|
||||||
chainStartFeed *event.Feed
|
|
||||||
hashesByHeight map[int][]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) HasChainStarted() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
func (f *faultyPOWChainService) ETH2GenesisTime() (uint64, *big.Int) {
|
|
||||||
return 0, big.NewInt(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) ChainStartFeed() *event.Feed {
|
|
||||||
return f.chainStartFeed
|
|
||||||
}
|
|
||||||
func (f *faultyPOWChainService) LatestBlockHeight() *big.Int {
|
|
||||||
return big.NewInt(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) BlockExists(_ context.Context, hash common.Hash) (bool, *big.Int, error) {
|
|
||||||
if f.hashesByHeight == nil {
|
|
||||||
return false, big.NewInt(1), errors.New("failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, big.NewInt(1), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) BlockHashByHeight(_ context.Context, height *big.Int) (common.Hash, error) {
|
|
||||||
return [32]byte{}, errors.New("failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) BlockTimeByHeight(_ context.Context, height *big.Int) (uint64, error) {
|
|
||||||
return 0, errors.New("failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) BlockNumberByTimestamp(_ context.Context, _ uint64) (*big.Int, error) {
|
|
||||||
return big.NewInt(0), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) DepositRoot() [32]byte {
|
|
||||||
return [32]byte{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) DepositTrie() *trieutil.MerkleTrie {
|
|
||||||
return &trieutil.MerkleTrie{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) ChainStartDeposits() []*ethpb.Deposit {
|
|
||||||
return []*ethpb.Deposit{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) ChainStartDepositHashes() ([][]byte, error) {
|
|
||||||
return [][]byte{}, errors.New("hashing failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *faultyPOWChainService) ChainStartETH1Data() *ethpb.Eth1Data {
|
|
||||||
return ðpb.Eth1Data{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockPOWChainService struct {
|
|
||||||
chainStartFeed *event.Feed
|
|
||||||
latestBlockNumber *big.Int
|
|
||||||
hashesByHeight map[int][]byte
|
|
||||||
blockTimeByHeight map[int]uint64
|
|
||||||
blockNumberByHeight map[uint64]*big.Int
|
|
||||||
eth1Data *ethpb.Eth1Data
|
|
||||||
genesisEth1Block *big.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) HasChainStarted() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) ETH2GenesisTime() (uint64, *big.Int) {
|
|
||||||
blk := m.genesisEth1Block
|
|
||||||
if blk == nil {
|
|
||||||
blk = big.NewInt(0)
|
|
||||||
}
|
|
||||||
return uint64(time.Unix(0, 0).Unix()), blk
|
|
||||||
}
|
|
||||||
func (m *mockPOWChainService) ChainStartFeed() *event.Feed {
|
|
||||||
return m.chainStartFeed
|
|
||||||
}
|
|
||||||
func (m *mockPOWChainService) LatestBlockHeight() *big.Int {
|
|
||||||
return m.latestBlockNumber
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) DepositTrie() *trieutil.MerkleTrie {
|
|
||||||
return &trieutil.MerkleTrie{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) BlockExists(_ context.Context, hash common.Hash) (bool, *big.Int, error) {
|
|
||||||
// Reverse the map of heights by hash.
|
|
||||||
heightsByHash := make(map[[32]byte]int)
|
|
||||||
for k, v := range m.hashesByHeight {
|
|
||||||
h := bytesutil.ToBytes32(v)
|
|
||||||
heightsByHash[h] = k
|
|
||||||
}
|
|
||||||
val, ok := heightsByHash[hash]
|
|
||||||
if !ok {
|
|
||||||
return false, nil, fmt.Errorf("could not fetch height for hash: %#x", hash)
|
|
||||||
}
|
|
||||||
return true, big.NewInt(int64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) BlockHashByHeight(_ context.Context, height *big.Int) (common.Hash, error) {
|
|
||||||
k := int(height.Int64())
|
|
||||||
val, ok := m.hashesByHeight[k]
|
|
||||||
if !ok {
|
|
||||||
return [32]byte{}, fmt.Errorf("could not fetch hash for height: %v", height)
|
|
||||||
}
|
|
||||||
return bytesutil.ToBytes32(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) BlockTimeByHeight(_ context.Context, height *big.Int) (uint64, error) {
|
|
||||||
h := int(height.Int64())
|
|
||||||
return m.blockTimeByHeight[h], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) BlockNumberByTimestamp(_ context.Context, time uint64) (*big.Int, error) {
|
|
||||||
return m.blockNumberByHeight[time], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) DepositRoot() [32]byte {
|
|
||||||
root := []byte("depositroot")
|
|
||||||
return bytesutil.ToBytes32(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) ChainStartDeposits() []*ethpb.Deposit {
|
|
||||||
return []*ethpb.Deposit{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) ChainStartDepositHashes() ([][]byte, error) {
|
|
||||||
return [][]byte{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockPOWChainService) ChainStartETH1Data() *ethpb.Eth1Data {
|
|
||||||
return m.eth1Data
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWaitForChainStart_ContextClosed(t *testing.T) {
|
func TestWaitForChainStart_ContextClosed(t *testing.T) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
beaconServer := &BeaconServer{
|
beaconServer := &BeaconServer{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
powChainService: &faultyPOWChainService{
|
chainStartFetcher: &mockPOW.FaultyMockPOWChain{
|
||||||
chainStartFeed: new(event.Feed),
|
ChainFeed: new(event.Feed),
|
||||||
},
|
},
|
||||||
chainService: &mockClient.ChainService{},
|
eth1InfoFetcher: &mockPOW.POWChain{},
|
||||||
|
stateFeedListener: &mockChain.ChainService{},
|
||||||
}
|
}
|
||||||
exitRoutine := make(chan bool)
|
exitRoutine := make(chan bool)
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
defer ctrl.Finish()
|
defer ctrl.Finish()
|
||||||
mockStream := mockRPC.NewMockBeaconService_WaitForChainStartServer(ctrl)
|
mockStream := mockRPC.NewMockBeaconService_WaitForChainStartServer(ctrl)
|
||||||
go func(tt *testing.T) {
|
go func(tt *testing.T) {
|
||||||
if err := beaconServer.WaitForChainStart(&ptypes.Empty{}, mockStream); !strings.Contains(err.Error(), closedContext) {
|
if err := beaconServer.WaitForChainStart(&ptypes.Empty{}, mockStream); !strings.Contains(err.Error(), "context closed") {
|
||||||
tt.Errorf("Could not call RPC method: %v", err)
|
tt.Errorf("Could not call RPC method: %v", err)
|
||||||
}
|
}
|
||||||
<-exitRoutine
|
<-exitRoutine
|
||||||
@@ -193,10 +44,11 @@ func TestWaitForChainStart_ContextClosed(t *testing.T) {
|
|||||||
func TestWaitForChainStart_AlreadyStarted(t *testing.T) {
|
func TestWaitForChainStart_AlreadyStarted(t *testing.T) {
|
||||||
beaconServer := &BeaconServer{
|
beaconServer := &BeaconServer{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
powChainService: &mockPOWChainService{
|
chainStartFetcher: &mockPOW.POWChain{
|
||||||
chainStartFeed: new(event.Feed),
|
ChainFeed: new(event.Feed),
|
||||||
},
|
},
|
||||||
chainService: &mockClient.ChainService{},
|
eth1InfoFetcher: &mockPOW.POWChain{},
|
||||||
|
stateFeedListener: &mockChain.ChainService{},
|
||||||
}
|
}
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
defer ctrl.Finish()
|
defer ctrl.Finish()
|
||||||
@@ -217,10 +69,11 @@ func TestWaitForChainStart_NotStartedThenLogFired(t *testing.T) {
|
|||||||
beaconServer := &BeaconServer{
|
beaconServer := &BeaconServer{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
chainStartChan: make(chan time.Time, 1),
|
chainStartChan: make(chan time.Time, 1),
|
||||||
powChainService: &faultyPOWChainService{
|
chainStartFetcher: &mockPOW.FaultyMockPOWChain{
|
||||||
chainStartFeed: new(event.Feed),
|
ChainFeed: new(event.Feed),
|
||||||
},
|
},
|
||||||
chainService: &mockClient.ChainService{},
|
eth1InfoFetcher: &mockPOW.POWChain{},
|
||||||
|
stateFeedListener: &mockChain.ChainService{},
|
||||||
}
|
}
|
||||||
exitRoutine := make(chan bool)
|
exitRoutine := make(chan bool)
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
|
|||||||
@@ -7,15 +7,19 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/go-ssz"
|
"github.com/prysmaticlabs/go-ssz"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/operations"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||||
|
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||||
"github.com/prysmaticlabs/prysm/shared/params"
|
"github.com/prysmaticlabs/prysm/shared/params"
|
||||||
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -27,9 +31,13 @@ import (
|
|||||||
// beacon blocks to a beacon node, and more.
|
// beacon blocks to a beacon node, and more.
|
||||||
type ProposerServer struct {
|
type ProposerServer struct {
|
||||||
beaconDB db.Database
|
beaconDB db.Database
|
||||||
chainService chainService
|
headFetcher blockchain.HeadFetcher
|
||||||
powChainService powChainService
|
blockReceiver blockchain.BlockReceiver
|
||||||
operationService operationService
|
mockEth1Votes bool
|
||||||
|
chainStartFetcher powchain.ChainStartFetcher
|
||||||
|
eth1InfoFetcher powchain.ChainInfoFetcher
|
||||||
|
eth1BlockFetcher powchain.POWBlockFetcher
|
||||||
|
pool operations.Pool
|
||||||
canonicalStateChan chan *pbp2p.BeaconState
|
canonicalStateChan chan *pbp2p.BeaconState
|
||||||
depositCache *depositcache.DepositCache
|
depositCache *depositcache.DepositCache
|
||||||
}
|
}
|
||||||
@@ -42,15 +50,13 @@ func (ps *ProposerServer) RequestBlock(ctx context.Context, req *pb.BlockRequest
|
|||||||
span.AddAttributes(trace.Int64Attribute("slot", int64(req.Slot)))
|
span.AddAttributes(trace.Int64Attribute("slot", int64(req.Slot)))
|
||||||
|
|
||||||
// Retrieve the parent block as the current head of the canonical chain
|
// Retrieve the parent block as the current head of the canonical chain
|
||||||
parent := ps.chainService.HeadBlock()
|
parent := ps.headFetcher.HeadBlock()
|
||||||
|
|
||||||
parentRoot, err := ssz.SigningRoot(parent)
|
parentRoot, err := ssz.SigningRoot(parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get parent block signing root")
|
return nil, errors.Wrap(err, "could not get parent block signing root")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct block body
|
|
||||||
// Pack ETH1 deposits which have not been included in the beacon chain
|
|
||||||
eth1Data, err := ps.eth1Data(ctx, req.Slot)
|
eth1Data, err := ps.eth1Data(ctx, req.Slot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get ETH1 data")
|
return nil, errors.Wrap(err, "could not get ETH1 data")
|
||||||
@@ -114,8 +120,7 @@ func (ps *ProposerServer) ProposeBlock(ctx context.Context, blk *ethpb.BeaconBlo
|
|||||||
}
|
}
|
||||||
log.WithField("blockRoot", fmt.Sprintf("%#x", bytesutil.Trunc(root[:]))).Debugf(
|
log.WithField("blockRoot", fmt.Sprintf("%#x", bytesutil.Trunc(root[:]))).Debugf(
|
||||||
"Block proposal received via RPC")
|
"Block proposal received via RPC")
|
||||||
|
if err := ps.blockReceiver.ReceiveBlock(ctx, blk); err != nil {
|
||||||
if err := ps.chainService.ReceiveBlock(ctx, blk); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not process beacon block")
|
return nil, errors.Wrap(err, "could not process beacon block")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,15 +133,15 @@ func (ps *ProposerServer) ProposeBlock(ctx context.Context, blk *ethpb.BeaconBlo
|
|||||||
// attestations which are ready for inclusion. That is, attestations that satisfy:
|
// attestations which are ready for inclusion. That is, attestations that satisfy:
|
||||||
// attestation.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot.
|
// attestation.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot.
|
||||||
func (ps *ProposerServer) attestations(ctx context.Context, expectedSlot uint64) ([]*ethpb.Attestation, error) {
|
func (ps *ProposerServer) attestations(ctx context.Context, expectedSlot uint64) ([]*ethpb.Attestation, error) {
|
||||||
headState := ps.chainService.HeadState()
|
beaconState := ps.headFetcher.HeadState()
|
||||||
atts, err := ps.operationService.AttestationPool(ctx, expectedSlot)
|
atts, err := ps.pool.AttestationPool(ctx, expectedSlot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not retrieve pending attestations from operations service")
|
return nil, errors.Wrap(err, "could not retrieve pending attestations from operations service")
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance slot, if it is behind
|
// advance slot, if it is behind
|
||||||
if headState.Slot < expectedSlot {
|
if beaconState.Slot < expectedSlot {
|
||||||
headState, err = state.ProcessSlots(ctx, headState, expectedSlot)
|
beaconState, err = state.ProcessSlots(ctx, beaconState, expectedSlot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -144,24 +149,24 @@ func (ps *ProposerServer) attestations(ctx context.Context, expectedSlot uint64)
|
|||||||
|
|
||||||
var attsReadyForInclusion []*ethpb.Attestation
|
var attsReadyForInclusion []*ethpb.Attestation
|
||||||
for _, att := range atts {
|
for _, att := range atts {
|
||||||
slot, err := helpers.AttestationDataSlot(headState, att.Data)
|
slot, err := helpers.AttestationDataSlot(beaconState, att.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get attestation slot")
|
return nil, errors.Wrap(err, "could not get attestation slot")
|
||||||
}
|
}
|
||||||
if slot+params.BeaconConfig().MinAttestationInclusionDelay <= headState.Slot &&
|
if slot+params.BeaconConfig().MinAttestationInclusionDelay <= beaconState.Slot &&
|
||||||
headState.Slot <= slot+params.BeaconConfig().SlotsPerEpoch {
|
beaconState.Slot <= slot+params.BeaconConfig().SlotsPerEpoch {
|
||||||
attsReadyForInclusion = append(attsReadyForInclusion, att)
|
attsReadyForInclusion = append(attsReadyForInclusion, att)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validAtts := make([]*ethpb.Attestation, 0, len(attsReadyForInclusion))
|
validAtts := make([]*ethpb.Attestation, 0, len(attsReadyForInclusion))
|
||||||
for _, att := range attsReadyForInclusion {
|
for _, att := range attsReadyForInclusion {
|
||||||
slot, err := helpers.AttestationDataSlot(headState, att.Data)
|
slot, err := helpers.AttestationDataSlot(beaconState, att.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get attestation slot")
|
return nil, errors.Wrap(err, "could not get attestation slot")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := blocks.ProcessAttestationNoVerify(headState, att); err != nil {
|
if _, err := blocks.ProcessAttestationNoVerify(beaconState, att); err != nil {
|
||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
}
|
}
|
||||||
@@ -175,7 +180,6 @@ func (ps *ProposerServer) attestations(ctx context.Context, expectedSlot uint64)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ps.beaconDB.DeleteAttestation(ctx, root); err != nil {
|
if err := ps.beaconDB.DeleteAttestation(ctx, root); err != nil {
|
||||||
return nil, errors.Wrap(err, "could not delete failed attestation")
|
return nil, errors.Wrap(err, "could not delete failed attestation")
|
||||||
}
|
}
|
||||||
@@ -194,11 +198,39 @@ func (ps *ProposerServer) attestations(ctx context.Context, expectedSlot uint64)
|
|||||||
// - Subtract that eth1block.number by ETH1_FOLLOW_DISTANCE.
|
// - Subtract that eth1block.number by ETH1_FOLLOW_DISTANCE.
|
||||||
// - This is the eth1block to use for the block proposal.
|
// - This is the eth1block to use for the block proposal.
|
||||||
func (ps *ProposerServer) eth1Data(ctx context.Context, slot uint64) (*ethpb.Eth1Data, error) {
|
func (ps *ProposerServer) eth1Data(ctx context.Context, slot uint64) (*ethpb.Eth1Data, error) {
|
||||||
eth1VotingPeriodStartTime, _ := ps.powChainService.ETH2GenesisTime()
|
if ps.mockEth1Votes {
|
||||||
|
// If a mock eth1 data votes is specified, we use the following for the
|
||||||
|
// eth1data we provide to every proposer based on https://github.com/ethereum/eth2.0-pm/issues/62:
|
||||||
|
//
|
||||||
|
// slot_in_voting_period = current_slot % SLOTS_PER_ETH1_VOTING_PERIOD
|
||||||
|
// Eth1Data(
|
||||||
|
// DepositRoot = hash(current_epoch + slot_in_voting_period),
|
||||||
|
// DepositCount = state.eth1_deposit_index,
|
||||||
|
// BlockHash = hash(hash(current_epoch + slot_in_voting_period)),
|
||||||
|
// )
|
||||||
|
slotInVotingPeriod := slot % params.BeaconConfig().SlotsPerEth1VotingPeriod
|
||||||
|
headState, err := ps.beaconDB.HeadState(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not get head state")
|
||||||
|
}
|
||||||
|
enc, err := ssz.Marshal(helpers.SlotToEpoch(slot) + slotInVotingPeriod)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
depRoot := hashutil.Hash(enc)
|
||||||
|
blockHash := hashutil.Hash(depRoot[:])
|
||||||
|
return ðpb.Eth1Data{
|
||||||
|
DepositRoot: depRoot[:],
|
||||||
|
DepositCount: headState.Eth1DepositIndex,
|
||||||
|
BlockHash: blockHash[:],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
eth1VotingPeriodStartTime, _ := ps.eth1InfoFetcher.Eth2GenesisPowchainInfo()
|
||||||
eth1VotingPeriodStartTime += (slot - (slot % params.BeaconConfig().SlotsPerEth1VotingPeriod)) * params.BeaconConfig().SecondsPerSlot
|
eth1VotingPeriodStartTime += (slot - (slot % params.BeaconConfig().SlotsPerEth1VotingPeriod)) * params.BeaconConfig().SecondsPerSlot
|
||||||
|
|
||||||
// Look up most recent block up to timestamp
|
// Look up most recent block up to timestamp
|
||||||
blockNumber, err := ps.powChainService.BlockNumberByTimestamp(ctx, eth1VotingPeriodStartTime)
|
blockNumber, err := ps.eth1BlockFetcher.BlockNumberByTimestamp(ctx, eth1VotingPeriodStartTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -239,14 +271,13 @@ func (ps *ProposerServer) computeStateRoot(ctx context.Context, block *ethpb.Bea
|
|||||||
func (ps *ProposerServer) deposits(ctx context.Context, currentVote *ethpb.Eth1Data) ([]*ethpb.Deposit, error) {
|
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
|
// 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.
|
// the number of all deposits in this RPC call. If not, then we return nil.
|
||||||
headState := ps.chainService.HeadState()
|
beaconState := ps.headFetcher.HeadState()
|
||||||
|
canonicalEth1Data, latestEth1DataHeight, err := ps.canonicalEth1Data(ctx, beaconState, currentVote)
|
||||||
canonicalEth1Data, latestEth1DataHeight, err := ps.canonicalEth1Data(ctx, headState, currentVote)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, genesisEth1Block := ps.powChainService.ETH2GenesisTime()
|
_, genesisEth1Block := ps.eth1InfoFetcher.Eth2GenesisPowchainInfo()
|
||||||
if genesisEth1Block.Cmp(latestEth1DataHeight) == 0 {
|
if genesisEth1Block.Cmp(latestEth1DataHeight) == 0 {
|
||||||
return []*ethpb.Deposit{}, nil
|
return []*ethpb.Deposit{}, nil
|
||||||
}
|
}
|
||||||
@@ -272,7 +303,7 @@ func (ps *ProposerServer) deposits(ctx context.Context, currentVote *ethpb.Eth1D
|
|||||||
// deposits are sorted from lowest to highest.
|
// deposits are sorted from lowest to highest.
|
||||||
var pendingDeps []*depositcache.DepositContainer
|
var pendingDeps []*depositcache.DepositContainer
|
||||||
for _, dep := range allPendingContainers {
|
for _, dep := range allPendingContainers {
|
||||||
if uint64(dep.Index) >= headState.Eth1DepositIndex && uint64(dep.Index) < canonicalEth1Data.DepositCount {
|
if uint64(dep.Index) >= beaconState.Eth1DepositIndex && uint64(dep.Index) < canonicalEth1Data.DepositCount {
|
||||||
pendingDeps = append(pendingDeps, dep)
|
pendingDeps = append(pendingDeps, dep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,7 +344,7 @@ func (ps *ProposerServer) canonicalEth1Data(ctx context.Context, beaconState *pb
|
|||||||
canonicalEth1Data = beaconState.Eth1Data
|
canonicalEth1Data = beaconState.Eth1Data
|
||||||
eth1BlockHash = bytesutil.ToBytes32(beaconState.Eth1Data.BlockHash)
|
eth1BlockHash = bytesutil.ToBytes32(beaconState.Eth1Data.BlockHash)
|
||||||
}
|
}
|
||||||
_, latestEth1DataHeight, err := ps.powChainService.BlockExists(ctx, eth1BlockHash)
|
_, latestEth1DataHeight, err := ps.eth1BlockFetcher.BlockExists(ctx, eth1BlockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "could not fetch eth1data height")
|
return nil, nil, errors.Wrap(err, "could not fetch eth1data height")
|
||||||
}
|
}
|
||||||
@@ -327,14 +358,14 @@ func (ps *ProposerServer) canonicalEth1Data(ctx context.Context, beaconState *pb
|
|||||||
func (ps *ProposerServer) defaultEth1DataResponse(ctx context.Context, currentHeight *big.Int) (*ethpb.Eth1Data, error) {
|
func (ps *ProposerServer) defaultEth1DataResponse(ctx context.Context, currentHeight *big.Int) (*ethpb.Eth1Data, error) {
|
||||||
eth1FollowDistance := int64(params.BeaconConfig().Eth1FollowDistance)
|
eth1FollowDistance := int64(params.BeaconConfig().Eth1FollowDistance)
|
||||||
ancestorHeight := big.NewInt(0).Sub(currentHeight, big.NewInt(eth1FollowDistance))
|
ancestorHeight := big.NewInt(0).Sub(currentHeight, big.NewInt(eth1FollowDistance))
|
||||||
blockHash, err := ps.powChainService.BlockHashByHeight(ctx, ancestorHeight)
|
blockHash, err := ps.eth1BlockFetcher.BlockHashByHeight(ctx, ancestorHeight)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not fetch ETH1_FOLLOW_DISTANCE ancestor")
|
return nil, errors.Wrap(err, "could not fetch ETH1_FOLLOW_DISTANCE ancestor")
|
||||||
}
|
}
|
||||||
// Fetch all historical deposits up to an ancestor height.
|
// Fetch all historical deposits up to an ancestor height.
|
||||||
depositsTillHeight, depositRoot := ps.depositCache.DepositsNumberAndRootAtHeight(ctx, ancestorHeight)
|
depositsTillHeight, depositRoot := ps.depositCache.DepositsNumberAndRootAtHeight(ctx, ancestorHeight)
|
||||||
if depositsTillHeight == 0 {
|
if depositsTillHeight == 0 {
|
||||||
return ps.powChainService.ChainStartETH1Data(), nil
|
return ps.chainStartFetcher.ChainStartEth1Data(), nil
|
||||||
}
|
}
|
||||||
return ðpb.Eth1Data{
|
return ðpb.Eth1Data{
|
||||||
DepositRoot: depositRoot[:],
|
DepositRoot: depositRoot[:],
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||||
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
|
mockOps "github.com/prysmaticlabs/prysm/beacon-chain/operations/testing"
|
||||||
|
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
|
||||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||||
|
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||||
"github.com/prysmaticlabs/prysm/shared/params"
|
"github.com/prysmaticlabs/prysm/shared/params"
|
||||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||||
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
||||||
@@ -60,9 +63,12 @@ func TestProposeBlock_OK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proposerServer := &ProposerServer{
|
proposerServer := &ProposerServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
powChainService: &mockPOWChainService{},
|
chainStartFetcher: &mockPOW.POWChain{},
|
||||||
chainService: &mock.ChainService{},
|
eth1InfoFetcher: &mockPOW.POWChain{},
|
||||||
|
eth1BlockFetcher: &mockPOW.POWChain{},
|
||||||
|
blockReceiver: &mock.ChainService{},
|
||||||
|
headFetcher: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
req := ðpb.BeaconBlock{
|
req := ðpb.BeaconBlock{
|
||||||
Slot: 5,
|
Slot: 5,
|
||||||
@@ -113,8 +119,10 @@ func TestComputeStateRoot_OK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proposerServer := &ProposerServer{
|
proposerServer := &ProposerServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
powChainService: &mockPOWChainService{},
|
chainStartFetcher: &mockPOW.POWChain{},
|
||||||
|
eth1InfoFetcher: &mockPOW.POWChain{},
|
||||||
|
eth1BlockFetcher: &mockPOW.POWChain{},
|
||||||
}
|
}
|
||||||
|
|
||||||
req := ðpb.BeaconBlock{
|
req := ðpb.BeaconBlock{
|
||||||
@@ -256,10 +264,11 @@ func TestPendingAttestations_FiltersWithinInclusionDelay(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proposerServer := &ProposerServer{
|
proposerServer := &ProposerServer{
|
||||||
operationService: &mockOperationService{
|
pool: &mockOps.Operations{
|
||||||
pendingAttestations: []*ethpb.Attestation{att},
|
Attestations: []*ethpb.Attestation{att},
|
||||||
},
|
},
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
atts, err := proposerServer.attestations(context.Background(), stateSlot)
|
atts, err := proposerServer.attestations(context.Background(), stateSlot)
|
||||||
@@ -375,8 +384,8 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
|
|||||||
att2 := proto.Clone(att).(*ethpb.Attestation)
|
att2 := proto.Clone(att).(*ethpb.Attestation)
|
||||||
att3 := proto.Clone(att).(*ethpb.Attestation)
|
att3 := proto.Clone(att).(*ethpb.Attestation)
|
||||||
|
|
||||||
opService := &mockOperationService{
|
opService := &mockOps.Operations{
|
||||||
pendingAttestations: []*ethpb.Attestation{
|
Attestations: []*ethpb.Attestation{
|
||||||
//Expired attestations
|
//Expired attestations
|
||||||
{
|
{
|
||||||
Data: ðpb.AttestationData{
|
Data: ðpb.AttestationData{
|
||||||
@@ -448,9 +457,10 @@ func TestPendingAttestations_FiltersExpiredAttestations(t *testing.T) {
|
|||||||
|
|
||||||
expectedNumberOfAttestations := 3
|
expectedNumberOfAttestations := 3
|
||||||
proposerServer := &ProposerServer{
|
proposerServer := &ProposerServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
operationService: opService,
|
pool: opService,
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
atts, err := proposerServer.attestations(context.Background(), currentSlot+params.BeaconConfig().MinAttestationInclusionDelay+1)
|
atts, err := proposerServer.attestations(context.Background(), currentSlot+params.BeaconConfig().MinAttestationInclusionDelay+1)
|
||||||
@@ -507,9 +517,9 @@ func TestPendingDeposits_Eth1DataVoteOK(t *testing.T) {
|
|||||||
|
|
||||||
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
||||||
newHeight := big.NewInt(height.Int64() + 11000)
|
newHeight := big.NewInt(height.Int64() + 11000)
|
||||||
p := &mockPOWChainService{
|
p := &mockPOW.POWChain{
|
||||||
latestBlockNumber: height,
|
LatestBlockNumber: height,
|
||||||
hashesByHeight: map[int][]byte{
|
HashesByHeight: map[int][]byte{
|
||||||
int(height.Int64()): []byte("0x0"),
|
int(height.Int64()): []byte("0x0"),
|
||||||
int(newHeight.Int64()): []byte("0x1"),
|
int(newHeight.Int64()): []byte("0x1"),
|
||||||
},
|
},
|
||||||
@@ -544,12 +554,15 @@ func TestPendingDeposits_Eth1DataVoteOK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bs := &ProposerServer{
|
bs := &ProposerServer{
|
||||||
powChainService: p,
|
chainStartFetcher: p,
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
eth1InfoFetcher: p,
|
||||||
|
eth1BlockFetcher: p,
|
||||||
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
// It should also return the recent deposits after their follow window.
|
// It should also return the recent deposits after their follow window.
|
||||||
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
|
p.LatestBlockNumber = big.NewInt(0).Add(p.LatestBlockNumber, big.NewInt(10000))
|
||||||
_, eth1Height, err := bs.canonicalEth1Data(ctx, beaconState, ðpb.Eth1Data{})
|
_, eth1Height, err := bs.canonicalEth1Data(ctx, beaconState, ðpb.Eth1Data{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -596,9 +609,9 @@ func TestPendingDeposits_OutsideEth1FollowWindow(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
||||||
p := &mockPOWChainService{
|
p := &mockPOW.POWChain{
|
||||||
latestBlockNumber: height,
|
LatestBlockNumber: height,
|
||||||
hashesByHeight: map[int][]byte{
|
HashesByHeight: map[int][]byte{
|
||||||
int(height.Int64()): []byte("0x0"),
|
int(height.Int64()): []byte("0x0"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -690,9 +703,12 @@ func TestPendingDeposits_OutsideEth1FollowWindow(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bs := &ProposerServer{
|
bs := &ProposerServer{
|
||||||
powChainService: p,
|
chainStartFetcher: p,
|
||||||
depositCache: depositCache,
|
eth1InfoFetcher: p,
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
eth1BlockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
||||||
@@ -705,7 +721,7 @@ func TestPendingDeposits_OutsideEth1FollowWindow(t *testing.T) {
|
|||||||
|
|
||||||
// It should not return the recent deposits after their follow window.
|
// It should not return the recent deposits after their follow window.
|
||||||
// as latest block number makes no difference in retrieval of deposits
|
// as latest block number makes no difference in retrieval of deposits
|
||||||
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
|
p.LatestBlockNumber = big.NewInt(0).Add(p.LatestBlockNumber, big.NewInt(10000))
|
||||||
deposits, err = bs.deposits(ctx, ðpb.Eth1Data{})
|
deposits, err = bs.deposits(ctx, ðpb.Eth1Data{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -724,9 +740,9 @@ func TestPendingDeposits_FollowsCorrectEth1Block(t *testing.T) {
|
|||||||
|
|
||||||
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
||||||
newHeight := big.NewInt(height.Int64() + 11000)
|
newHeight := big.NewInt(height.Int64() + 11000)
|
||||||
p := &mockPOWChainService{
|
p := &mockPOW.POWChain{
|
||||||
latestBlockNumber: height,
|
LatestBlockNumber: height,
|
||||||
hashesByHeight: map[int][]byte{
|
HashesByHeight: map[int][]byte{
|
||||||
int(height.Int64()): []byte("0x0"),
|
int(height.Int64()): []byte("0x0"),
|
||||||
int(newHeight.Int64()): []byte("0x1"),
|
int(newHeight.Int64()): []byte("0x1"),
|
||||||
},
|
},
|
||||||
@@ -830,9 +846,12 @@ func TestPendingDeposits_FollowsCorrectEth1Block(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bs := &ProposerServer{
|
bs := &ProposerServer{
|
||||||
powChainService: p,
|
chainStartFetcher: p,
|
||||||
depositCache: depositCache,
|
eth1InfoFetcher: p,
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
eth1BlockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
||||||
@@ -844,7 +863,7 @@ func TestPendingDeposits_FollowsCorrectEth1Block(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// It should also return the recent deposits after their follow window.
|
// It should also return the recent deposits after their follow window.
|
||||||
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
|
p.LatestBlockNumber = big.NewInt(0).Add(p.LatestBlockNumber, big.NewInt(10000))
|
||||||
// we should get our pending deposits once this vote pushes the vote tally to include
|
// we should get our pending deposits once this vote pushes the vote tally to include
|
||||||
// the updated eth1 data.
|
// the updated eth1 data.
|
||||||
deposits, err = bs.deposits(ctx, vote)
|
deposits, err = bs.deposits(ctx, vote)
|
||||||
@@ -863,9 +882,9 @@ func TestPendingDeposits_FollowsCorrectEth1Block(t *testing.T) {
|
|||||||
func TestPendingDeposits_CantReturnBelowStateEth1DepositIndex(t *testing.T) {
|
func TestPendingDeposits_CantReturnBelowStateEth1DepositIndex(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
||||||
p := &mockPOWChainService{
|
p := &mockPOW.POWChain{
|
||||||
latestBlockNumber: height,
|
LatestBlockNumber: height,
|
||||||
hashesByHeight: map[int][]byte{
|
HashesByHeight: map[int][]byte{
|
||||||
int(height.Int64()): []byte("0x0"),
|
int(height.Int64()): []byte("0x0"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -943,13 +962,16 @@ func TestPendingDeposits_CantReturnBelowStateEth1DepositIndex(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bs := &ProposerServer{
|
bs := &ProposerServer{
|
||||||
powChainService: p,
|
chainStartFetcher: p,
|
||||||
depositCache: depositCache,
|
eth1InfoFetcher: p,
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
eth1BlockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
// It should also return the recent deposits after their follow window.
|
// It should also return the recent deposits after their follow window.
|
||||||
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
|
p.LatestBlockNumber = big.NewInt(0).Add(p.LatestBlockNumber, big.NewInt(10000))
|
||||||
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -969,9 +991,9 @@ func TestPendingDeposits_CantReturnMoreThanMax(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
||||||
p := &mockPOWChainService{
|
p := &mockPOW.POWChain{
|
||||||
latestBlockNumber: height,
|
LatestBlockNumber: height,
|
||||||
hashesByHeight: map[int][]byte{
|
HashesByHeight: map[int][]byte{
|
||||||
int(height.Int64()): []byte("0x0"),
|
int(height.Int64()): []byte("0x0"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1048,13 +1070,16 @@ func TestPendingDeposits_CantReturnMoreThanMax(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bs := &ProposerServer{
|
bs := &ProposerServer{
|
||||||
powChainService: p,
|
chainStartFetcher: p,
|
||||||
depositCache: depositCache,
|
eth1InfoFetcher: p,
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
eth1BlockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
// It should also return the recent deposits after their follow window.
|
// It should also return the recent deposits after their follow window.
|
||||||
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
|
p.LatestBlockNumber = big.NewInt(0).Add(p.LatestBlockNumber, big.NewInt(10000))
|
||||||
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -1072,9 +1097,9 @@ func TestPendingDeposits_CantReturnMoreDepositCount(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
||||||
p := &mockPOWChainService{
|
p := &mockPOW.POWChain{
|
||||||
latestBlockNumber: height,
|
LatestBlockNumber: height,
|
||||||
hashesByHeight: map[int][]byte{
|
HashesByHeight: map[int][]byte{
|
||||||
int(height.Int64()): []byte("0x0"),
|
int(height.Int64()): []byte("0x0"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1151,13 +1176,16 @@ func TestPendingDeposits_CantReturnMoreDepositCount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bs := &ProposerServer{
|
bs := &ProposerServer{
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
powChainService: p,
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
depositCache: depositCache,
|
chainStartFetcher: p,
|
||||||
|
eth1InfoFetcher: p,
|
||||||
|
eth1BlockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
// It should also return the recent deposits after their follow window.
|
// It should also return the recent deposits after their follow window.
|
||||||
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
|
p.LatestBlockNumber = big.NewInt(0).Add(p.LatestBlockNumber, big.NewInt(10000))
|
||||||
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -1178,11 +1206,15 @@ func TestEth1Data_EmptyVotesFetchBlockHashFailure(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Eth1DataVotes: []*ethpb.Eth1Data{},
|
Eth1DataVotes: []*ethpb.Eth1Data{},
|
||||||
}
|
}
|
||||||
|
p := &mockPOW.FaultyMockPOWChain{
|
||||||
|
HashesByHeight: make(map[int][]byte),
|
||||||
|
}
|
||||||
proposerServer := &ProposerServer{
|
proposerServer := &ProposerServer{
|
||||||
powChainService: &faultyPOWChainService{
|
chainStartFetcher: p,
|
||||||
hashesByHeight: make(map[int][]byte),
|
eth1InfoFetcher: p,
|
||||||
},
|
eth1BlockFetcher: p,
|
||||||
chainService: &mock.ChainService{State: beaconState},
|
blockReceiver: &mock.ChainService{State: beaconState},
|
||||||
|
headFetcher: &mock.ChainService{State: beaconState},
|
||||||
}
|
}
|
||||||
want := "could not fetch ETH1_FOLLOW_DISTANCE ancestor"
|
want := "could not fetch ETH1_FOLLOW_DISTANCE ancestor"
|
||||||
if _, err := proposerServer.eth1Data(context.Background(), beaconState.Slot+1); !strings.Contains(err.Error(), want) {
|
if _, err := proposerServer.eth1Data(context.Background(), beaconState.Slot+1); !strings.Contains(err.Error(), want) {
|
||||||
@@ -1201,8 +1233,8 @@ func TestDefaultEth1Data_NoBlockExists(t *testing.T) {
|
|||||||
Deposit: ðpb.Deposit{
|
Deposit: ðpb.Deposit{
|
||||||
Data: ðpb.Deposit_Data{
|
Data: ðpb.Deposit_Data{
|
||||||
PublicKey: []byte("a"),
|
PublicKey: []byte("a"),
|
||||||
Signature: mockSig[:],
|
Signature: make([]byte, 96),
|
||||||
WithdrawalCredentials: mockCreds[:],
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1211,8 +1243,8 @@ func TestDefaultEth1Data_NoBlockExists(t *testing.T) {
|
|||||||
Deposit: ðpb.Deposit{
|
Deposit: ðpb.Deposit{
|
||||||
Data: ðpb.Deposit_Data{
|
Data: ðpb.Deposit_Data{
|
||||||
PublicKey: []byte("b"),
|
PublicKey: []byte("b"),
|
||||||
Signature: mockSig[:],
|
Signature: make([]byte, 96),
|
||||||
WithdrawalCredentials: mockCreds[:],
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1225,16 +1257,18 @@ func TestDefaultEth1Data_NoBlockExists(t *testing.T) {
|
|||||||
depositCache.InsertDeposit(context.Background(), dp.Deposit, dp.Block, dp.Index, depositTrie.Root())
|
depositCache.InsertDeposit(context.Background(), dp.Deposit, dp.Block, dp.Index, depositTrie.Root())
|
||||||
}
|
}
|
||||||
|
|
||||||
powChainService := &mockPOWChainService{
|
p := &mockPOW.POWChain{
|
||||||
latestBlockNumber: height,
|
LatestBlockNumber: height,
|
||||||
hashesByHeight: map[int][]byte{
|
HashesByHeight: map[int][]byte{
|
||||||
0: []byte("hash0"),
|
0: []byte("hash0"),
|
||||||
476: []byte("hash1024"),
|
476: []byte("hash1024"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
proposerServer := &ProposerServer{
|
proposerServer := &ProposerServer{
|
||||||
powChainService: powChainService,
|
chainStartFetcher: p,
|
||||||
depositCache: depositCache,
|
eth1InfoFetcher: p,
|
||||||
|
eth1BlockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
defEth1Data := ðpb.Eth1Data{
|
defEth1Data := ðpb.Eth1Data{
|
||||||
@@ -1243,7 +1277,7 @@ func TestDefaultEth1Data_NoBlockExists(t *testing.T) {
|
|||||||
DepositRoot: []byte{'r', 'o', 'o', 't'},
|
DepositRoot: []byte{'r', 'o', 'o', 't'},
|
||||||
}
|
}
|
||||||
|
|
||||||
powChainService.eth1Data = defEth1Data
|
p.Eth1Data = defEth1Data
|
||||||
|
|
||||||
result, err := proposerServer.defaultEth1DataResponse(ctx, big.NewInt(1500))
|
result, err := proposerServer.defaultEth1DataResponse(ctx, big.NewInt(1500))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1260,19 +1294,22 @@ func TestEth1Data(t *testing.T) {
|
|||||||
|
|
||||||
slot := uint64(10000)
|
slot := uint64(10000)
|
||||||
|
|
||||||
ps := &ProposerServer{
|
p := &mockPOW.POWChain{
|
||||||
powChainService: &mockPOWChainService{
|
BlockNumberByHeight: map[uint64]*big.Int{
|
||||||
blockNumberByHeight: map[uint64]*big.Int{
|
60000: big.NewInt(4096),
|
||||||
60000: big.NewInt(4096),
|
|
||||||
},
|
|
||||||
hashesByHeight: map[int][]byte{
|
|
||||||
3072: []byte("3072"),
|
|
||||||
},
|
|
||||||
eth1Data: ðpb.Eth1Data{
|
|
||||||
DepositCount: 55,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
depositCache: depositcache.NewDepositCache(),
|
HashesByHeight: map[int][]byte{
|
||||||
|
3072: []byte("3072"),
|
||||||
|
},
|
||||||
|
Eth1Data: ðpb.Eth1Data{
|
||||||
|
DepositCount: 55,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ps := &ProposerServer{
|
||||||
|
chainStartFetcher: p,
|
||||||
|
eth1InfoFetcher: p,
|
||||||
|
eth1BlockFetcher: p,
|
||||||
|
depositCache: depositcache.NewDepositCache(),
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@@ -1286,6 +1323,57 @@ func TestEth1Data(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEth1Data_MockEnabled(t *testing.T) {
|
||||||
|
db := dbutil.SetupDB(t)
|
||||||
|
defer dbutil.TeardownDB(t, db)
|
||||||
|
// If a mock eth1 data votes is specified, we use the following for the
|
||||||
|
// eth1data we provide to every proposer based on https://github.com/ethereum/eth2.0-pm/issues/62:
|
||||||
|
//
|
||||||
|
// slot_in_voting_period = current_slot % SLOTS_PER_ETH1_VOTING_PERIOD
|
||||||
|
// Eth1Data(
|
||||||
|
// DepositRoot = hash(current_epoch + slot_in_voting_period),
|
||||||
|
// DepositCount = state.eth1_deposit_index,
|
||||||
|
// BlockHash = hash(hash(current_epoch + slot_in_voting_period)),
|
||||||
|
// )
|
||||||
|
ctx := context.Background()
|
||||||
|
ps := &ProposerServer{
|
||||||
|
headFetcher: &mock.ChainService{},
|
||||||
|
beaconDB: db,
|
||||||
|
mockEth1Votes: true,
|
||||||
|
}
|
||||||
|
headBlockRoot := [32]byte{1, 2, 3}
|
||||||
|
headState := &pbp2p.BeaconState{
|
||||||
|
Eth1DepositIndex: 64,
|
||||||
|
}
|
||||||
|
if err := db.SaveHeadBlockRoot(ctx, headBlockRoot); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := db.SaveState(ctx, headState, headBlockRoot); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
eth1Data, err := ps.eth1Data(ctx, 100)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
wantedSlot := 100 % params.BeaconConfig().SlotsPerEth1VotingPeriod
|
||||||
|
currentEpoch := helpers.SlotToEpoch(100)
|
||||||
|
enc, err := ssz.Marshal(currentEpoch + wantedSlot)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
depRoot := hashutil.Hash(enc)
|
||||||
|
blockHash := hashutil.Hash(depRoot[:])
|
||||||
|
want := ðpb.Eth1Data{
|
||||||
|
DepositRoot: depRoot[:],
|
||||||
|
DepositCount: 64,
|
||||||
|
BlockHash: blockHash[:],
|
||||||
|
}
|
||||||
|
if !proto.Equal(eth1Data, want) {
|
||||||
|
t.Errorf("Wanted %v, received %v", want, eth1Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Benchmark_Eth1Data(b *testing.B) {
|
func Benchmark_Eth1Data(b *testing.B) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
@@ -1347,13 +1435,17 @@ func Benchmark_Eth1Data(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentHeight := params.BeaconConfig().Eth1FollowDistance + 5
|
currentHeight := params.BeaconConfig().Eth1FollowDistance + 5
|
||||||
|
p := &mockPOW.POWChain{
|
||||||
|
LatestBlockNumber: big.NewInt(int64(currentHeight)),
|
||||||
|
HashesByHeight: hashesByHeight,
|
||||||
|
}
|
||||||
proposerServer := &ProposerServer{
|
proposerServer := &ProposerServer{
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
powChainService: &mockPOWChainService{
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
latestBlockNumber: big.NewInt(int64(currentHeight)),
|
chainStartFetcher: p,
|
||||||
hashesByHeight: hashesByHeight,
|
eth1InfoFetcher: p,
|
||||||
},
|
eth1BlockFetcher: p,
|
||||||
depositCache: depositCache,
|
depositCache: depositCache,
|
||||||
}
|
}
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@@ -1368,12 +1460,12 @@ func TestDeposits_ReturnsEmptyList_IfLatestEth1DataEqGenesisEth1Block(t *testing
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
height := big.NewInt(int64(params.BeaconConfig().Eth1FollowDistance))
|
||||||
p := &mockPOWChainService{
|
p := &mockPOW.POWChain{
|
||||||
latestBlockNumber: height,
|
LatestBlockNumber: height,
|
||||||
hashesByHeight: map[int][]byte{
|
HashesByHeight: map[int][]byte{
|
||||||
int(height.Int64()): []byte("0x0"),
|
int(height.Int64()): []byte("0x0"),
|
||||||
},
|
},
|
||||||
genesisEth1Block: height,
|
GenesisEth1Block: height,
|
||||||
}
|
}
|
||||||
|
|
||||||
beaconState := &pbp2p.BeaconState{
|
beaconState := &pbp2p.BeaconState{
|
||||||
@@ -1448,13 +1540,16 @@ func TestDeposits_ReturnsEmptyList_IfLatestEth1DataEqGenesisEth1Block(t *testing
|
|||||||
}
|
}
|
||||||
|
|
||||||
bs := &ProposerServer{
|
bs := &ProposerServer{
|
||||||
chainService: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
blockReceiver: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
powChainService: p,
|
headFetcher: &mock.ChainService{State: beaconState, Root: blkRoot[:]},
|
||||||
depositCache: depositCache,
|
chainStartFetcher: p,
|
||||||
|
eth1InfoFetcher: p,
|
||||||
|
eth1BlockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
// It should also return the recent deposits after their follow window.
|
// It should also return the recent deposits after their follow window.
|
||||||
p.latestBlockNumber = big.NewInt(0).Add(p.latestBlockNumber, big.NewInt(10000))
|
p.LatestBlockNumber = big.NewInt(0).Add(p.LatestBlockNumber, big.NewInt(10000))
|
||||||
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
deposits, err := bs.deposits(ctx, ðpb.Eth1Data{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -4,12 +4,9 @@ package rpc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/gogo/protobuf/proto"
|
|
||||||
middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||||
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
||||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||||
@@ -19,13 +16,12 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations"
|
"github.com/prysmaticlabs/prysm/beacon-chain/operations"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
|
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/sync"
|
"github.com/prysmaticlabs/prysm/beacon-chain/sync"
|
||||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/shared/event"
|
|
||||||
"github.com/prysmaticlabs/prysm/shared/params"
|
"github.com/prysmaticlabs/prysm/shared/params"
|
||||||
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"go.opencensus.io/plugin/ocgrpc"
|
"go.opencensus.io/plugin/ocgrpc"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
@@ -39,43 +35,19 @@ func init() {
|
|||||||
log = logrus.WithField("prefix", "rpc")
|
log = logrus.WithField("prefix", "rpc")
|
||||||
}
|
}
|
||||||
|
|
||||||
type chainService interface {
|
|
||||||
blockchain.HeadRetriever
|
|
||||||
blockchain.AttestationReceiver
|
|
||||||
blockchain.BlockReceiver
|
|
||||||
StateInitializedFeed() *event.Feed
|
|
||||||
}
|
|
||||||
|
|
||||||
type operationService interface {
|
|
||||||
operations.Pool
|
|
||||||
HandleAttestation(context.Context, proto.Message) error
|
|
||||||
IncomingAttFeed() *event.Feed
|
|
||||||
}
|
|
||||||
|
|
||||||
type powChainService interface {
|
|
||||||
HasChainStarted() bool
|
|
||||||
ETH2GenesisTime() (uint64, *big.Int)
|
|
||||||
ChainStartFeed() *event.Feed
|
|
||||||
LatestBlockHeight() *big.Int
|
|
||||||
BlockExists(ctx context.Context, hash common.Hash) (bool, *big.Int, error)
|
|
||||||
BlockHashByHeight(ctx context.Context, height *big.Int) (common.Hash, error)
|
|
||||||
BlockTimeByHeight(ctx context.Context, height *big.Int) (uint64, error)
|
|
||||||
BlockNumberByTimestamp(ctx context.Context, time uint64) (*big.Int, error)
|
|
||||||
DepositRoot() [32]byte
|
|
||||||
DepositTrie() *trieutil.MerkleTrie
|
|
||||||
ChainStartDepositHashes() ([][]byte, error)
|
|
||||||
ChainStartDeposits() []*ethpb.Deposit
|
|
||||||
ChainStartETH1Data() *ethpb.Eth1Data
|
|
||||||
}
|
|
||||||
|
|
||||||
// Service defining an RPC server for a beacon node.
|
// Service defining an RPC server for a beacon node.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
beaconDB db.Database
|
beaconDB db.Database
|
||||||
chainService chainService
|
stateFeedListener blockchain.ChainFeeds
|
||||||
powChainService powChainService
|
headFetcher blockchain.HeadFetcher
|
||||||
operationService operationService
|
attestationReceiver blockchain.AttestationReceiver
|
||||||
|
blockReceiver blockchain.BlockReceiver
|
||||||
|
powChainService powchain.Chain
|
||||||
|
mockEth1Votes bool
|
||||||
|
attestationsPool operations.Pool
|
||||||
|
operationsHandler operations.Handler
|
||||||
syncService sync.Checker
|
syncService sync.Checker
|
||||||
port string
|
port string
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
@@ -91,16 +63,21 @@ type Service struct {
|
|||||||
|
|
||||||
// Config options for the beacon node RPC server.
|
// Config options for the beacon node RPC server.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Port string
|
Port string
|
||||||
CertFlag string
|
CertFlag string
|
||||||
KeyFlag string
|
KeyFlag string
|
||||||
BeaconDB db.Database
|
BeaconDB db.Database
|
||||||
ChainService chainService
|
StateFeedListener blockchain.ChainFeeds
|
||||||
POWChainService powChainService
|
HeadFetcher blockchain.HeadFetcher
|
||||||
OperationService operationService
|
AttestationReceiver blockchain.AttestationReceiver
|
||||||
SyncService sync.Checker
|
BlockReceiver blockchain.BlockReceiver
|
||||||
Broadcaster p2p.Broadcaster
|
POWChainService powchain.Chain
|
||||||
DepositCache *depositcache.DepositCache
|
MockEth1Votes bool
|
||||||
|
OperationsHandler operations.Handler
|
||||||
|
AttestationsPool operations.Pool
|
||||||
|
SyncService sync.Checker
|
||||||
|
Broadcaster p2p.Broadcaster
|
||||||
|
DepositCache *depositcache.DepositCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService instantiates a new RPC service instance that will
|
// NewService instantiates a new RPC service instance that will
|
||||||
@@ -111,10 +88,15 @@ func NewService(ctx context.Context, cfg *Config) *Service {
|
|||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
beaconDB: cfg.BeaconDB,
|
beaconDB: cfg.BeaconDB,
|
||||||
|
stateFeedListener: cfg.StateFeedListener,
|
||||||
|
headFetcher: cfg.HeadFetcher,
|
||||||
|
attestationReceiver: cfg.AttestationReceiver,
|
||||||
|
blockReceiver: cfg.BlockReceiver,
|
||||||
p2p: cfg.Broadcaster,
|
p2p: cfg.Broadcaster,
|
||||||
chainService: cfg.ChainService,
|
|
||||||
powChainService: cfg.POWChainService,
|
powChainService: cfg.POWChainService,
|
||||||
operationService: cfg.OperationService,
|
mockEth1Votes: cfg.MockEth1Votes,
|
||||||
|
attestationsPool: cfg.AttestationsPool,
|
||||||
|
operationsHandler: cfg.OperationsHandler,
|
||||||
syncService: cfg.SyncService,
|
syncService: cfg.SyncService,
|
||||||
port: cfg.Port,
|
port: cfg.Port,
|
||||||
withCert: cfg.CertFlag,
|
withCert: cfg.CertFlag,
|
||||||
@@ -163,34 +145,41 @@ func (s *Service) Start() {
|
|||||||
beaconServer := &BeaconServer{
|
beaconServer := &BeaconServer{
|
||||||
beaconDB: s.beaconDB,
|
beaconDB: s.beaconDB,
|
||||||
ctx: s.ctx,
|
ctx: s.ctx,
|
||||||
powChainService: s.powChainService,
|
chainStartFetcher: s.powChainService,
|
||||||
chainService: s.chainService,
|
eth1InfoFetcher: s.powChainService,
|
||||||
operationService: s.operationService,
|
headFetcher: s.headFetcher,
|
||||||
|
stateFeedListener: s.stateFeedListener,
|
||||||
incomingAttestation: s.incomingAttestation,
|
incomingAttestation: s.incomingAttestation,
|
||||||
canonicalStateChan: s.canonicalStateChan,
|
canonicalStateChan: s.canonicalStateChan,
|
||||||
chainStartChan: make(chan time.Time, 1),
|
chainStartChan: make(chan time.Time, 1),
|
||||||
}
|
}
|
||||||
proposerServer := &ProposerServer{
|
proposerServer := &ProposerServer{
|
||||||
beaconDB: s.beaconDB,
|
beaconDB: s.beaconDB,
|
||||||
chainService: s.chainService,
|
headFetcher: s.headFetcher,
|
||||||
powChainService: s.powChainService,
|
blockReceiver: s.blockReceiver,
|
||||||
operationService: s.operationService,
|
chainStartFetcher: s.powChainService,
|
||||||
|
eth1InfoFetcher: s.powChainService,
|
||||||
|
eth1BlockFetcher: s.powChainService,
|
||||||
|
mockEth1Votes: s.mockEth1Votes,
|
||||||
|
pool: s.attestationsPool,
|
||||||
canonicalStateChan: s.canonicalStateChan,
|
canonicalStateChan: s.canonicalStateChan,
|
||||||
depositCache: s.depositCache,
|
depositCache: s.depositCache,
|
||||||
}
|
}
|
||||||
attesterServer := &AttesterServer{
|
attesterServer := &AttesterServer{
|
||||||
beaconDB: s.beaconDB,
|
p2p: s.p2p,
|
||||||
operationService: s.operationService,
|
beaconDB: s.beaconDB,
|
||||||
p2p: s.p2p,
|
operationsHandler: s.operationsHandler,
|
||||||
chainService: s.chainService,
|
attReceiver: s.attestationReceiver,
|
||||||
cache: cache.NewAttestationCache(),
|
headFetcher: s.headFetcher,
|
||||||
|
depositCache: cache.NewAttestationCache(),
|
||||||
}
|
}
|
||||||
validatorServer := &ValidatorServer{
|
validatorServer := &ValidatorServer{
|
||||||
ctx: s.ctx,
|
ctx: s.ctx,
|
||||||
beaconDB: s.beaconDB,
|
beaconDB: s.beaconDB,
|
||||||
chainService: s.chainService,
|
headFetcher: s.headFetcher,
|
||||||
canonicalStateChan: s.canonicalStateChan,
|
canonicalStateChan: s.canonicalStateChan,
|
||||||
powChainService: s.powChainService,
|
blockFetcher: s.powChainService,
|
||||||
|
chainStartFetcher: s.powChainService,
|
||||||
depositCache: s.depositCache,
|
depositCache: s.depositCache,
|
||||||
}
|
}
|
||||||
nodeServer := &NodeServer{
|
nodeServer := &NodeServer{
|
||||||
@@ -199,9 +188,9 @@ func (s *Service) Start() {
|
|||||||
syncChecker: s.syncService,
|
syncChecker: s.syncService,
|
||||||
}
|
}
|
||||||
beaconChainServer := &BeaconChainServer{
|
beaconChainServer := &BeaconChainServer{
|
||||||
beaconDB: s.beaconDB,
|
beaconDB: s.beaconDB,
|
||||||
pool: s.operationService,
|
pool: s.attestationsPool,
|
||||||
chainService: s.chainService,
|
headFetcher: s.headFetcher,
|
||||||
}
|
}
|
||||||
pb.RegisterBeaconServiceServer(s.grpcServer, beaconServer)
|
pb.RegisterBeaconServiceServer(s.grpcServer, beaconServer)
|
||||||
pb.RegisterProposerServiceServer(s.grpcServer, proposerServer)
|
pb.RegisterProposerServiceServer(s.grpcServer, proposerServer)
|
||||||
|
|||||||
@@ -7,11 +7,8 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
|
||||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/testing"
|
||||||
"github.com/prysmaticlabs/prysm/shared/event"
|
|
||||||
"github.com/prysmaticlabs/prysm/shared/params"
|
|
||||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||||
@@ -22,80 +19,17 @@ func init() {
|
|||||||
logrus.SetOutput(ioutil.Discard)
|
logrus.SetOutput(ioutil.Discard)
|
||||||
}
|
}
|
||||||
|
|
||||||
type mockOperationService struct {
|
|
||||||
pendingAttestations []*ethpb.Attestation
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mockOperationService) IncomingAttFeed() *event.Feed {
|
|
||||||
return new(event.Feed)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mockOperationService) IncomingExitFeed() *event.Feed {
|
|
||||||
return new(event.Feed)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mockOperationService) HandleAttestation(_ context.Context, _ proto.Message) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mockOperationService) IsAttCanonical(_ context.Context, att *ethpb.Attestation) (bool, error) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mockOperationService) AttestationPool(_ context.Context, expectedSlot uint64) ([]*ethpb.Attestation, error) {
|
|
||||||
if ms.pendingAttestations != nil {
|
|
||||||
return ms.pendingAttestations, nil
|
|
||||||
}
|
|
||||||
return []*ethpb.Attestation{
|
|
||||||
{
|
|
||||||
AggregationBits: []byte{0xC0},
|
|
||||||
Data: ðpb.AttestationData{
|
|
||||||
Crosslink: ðpb.Crosslink{
|
|
||||||
Shard: params.BeaconConfig().SlotsPerEpoch,
|
|
||||||
DataRoot: params.BeaconConfig().ZeroHash[:],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
AggregationBits: []byte{0xC1},
|
|
||||||
Data: ðpb.AttestationData{
|
|
||||||
Crosslink: ðpb.Crosslink{
|
|
||||||
Shard: params.BeaconConfig().SlotsPerEpoch,
|
|
||||||
DataRoot: params.BeaconConfig().ZeroHash[:],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
AggregationBits: []byte{0xC2},
|
|
||||||
Data: ðpb.AttestationData{
|
|
||||||
Crosslink: ðpb.Crosslink{
|
|
||||||
Shard: params.BeaconConfig().SlotsPerEpoch,
|
|
||||||
DataRoot: params.BeaconConfig().ZeroHash[:],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockSyncService struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mockSyncService) Status() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mockSyncService) Syncing() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLifecycle_OK(t *testing.T) {
|
func TestLifecycle_OK(t *testing.T) {
|
||||||
hook := logTest.NewGlobal()
|
hook := logTest.NewGlobal()
|
||||||
rpcService := NewService(context.Background(), &Config{
|
rpcService := NewService(context.Background(), &Config{
|
||||||
Port: "7348",
|
Port: "7348",
|
||||||
CertFlag: "alice.crt",
|
CertFlag: "alice.crt",
|
||||||
KeyFlag: "alice.key",
|
KeyFlag: "alice.key",
|
||||||
SyncService: &mockSyncService{},
|
SyncService: &mockSync.Sync{IsSyncing: false},
|
||||||
ChainService: &mock.ChainService{},
|
BlockReceiver: &mock.ChainService{},
|
||||||
|
AttestationReceiver: &mock.ChainService{},
|
||||||
|
HeadFetcher: &mock.ChainService{},
|
||||||
|
StateFeedListener: &mock.ChainService{},
|
||||||
})
|
})
|
||||||
|
|
||||||
rpcService.Start()
|
rpcService.Start()
|
||||||
@@ -112,9 +46,12 @@ func TestRPC_BadEndpoint(t *testing.T) {
|
|||||||
hook := logTest.NewGlobal()
|
hook := logTest.NewGlobal()
|
||||||
|
|
||||||
rpcService := NewService(context.Background(), &Config{
|
rpcService := NewService(context.Background(), &Config{
|
||||||
Port: "ralph merkle!!!",
|
Port: "ralph merkle!!!",
|
||||||
SyncService: &mockSyncService{},
|
SyncService: &mockSync.Sync{IsSyncing: false},
|
||||||
ChainService: &mock.ChainService{},
|
BlockReceiver: &mock.ChainService{},
|
||||||
|
AttestationReceiver: &mock.ChainService{},
|
||||||
|
HeadFetcher: &mock.ChainService{},
|
||||||
|
StateFeedListener: &mock.ChainService{},
|
||||||
})
|
})
|
||||||
|
|
||||||
testutil.AssertLogsDoNotContain(t, hook, "Could not listen to port in Start()")
|
testutil.AssertLogsDoNotContain(t, hook, "Could not listen to port in Start()")
|
||||||
@@ -141,9 +78,12 @@ func TestStatus_CredentialError(t *testing.T) {
|
|||||||
func TestRPC_InsecureEndpoint(t *testing.T) {
|
func TestRPC_InsecureEndpoint(t *testing.T) {
|
||||||
hook := logTest.NewGlobal()
|
hook := logTest.NewGlobal()
|
||||||
rpcService := NewService(context.Background(), &Config{
|
rpcService := NewService(context.Background(), &Config{
|
||||||
Port: "7777",
|
Port: "7777",
|
||||||
SyncService: &mockSyncService{},
|
SyncService: &mockSync.Sync{IsSyncing: false},
|
||||||
ChainService: &mock.ChainService{},
|
BlockReceiver: &mock.ChainService{},
|
||||||
|
AttestationReceiver: &mock.ChainService{},
|
||||||
|
HeadFetcher: &mock.ChainService{},
|
||||||
|
StateFeedListener: &mock.ChainService{},
|
||||||
})
|
})
|
||||||
|
|
||||||
rpcService.Start()
|
rpcService.Start()
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"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/cache/depositcache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state/stateutils"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/state/stateutils"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||||
@@ -29,9 +31,10 @@ import (
|
|||||||
type ValidatorServer struct {
|
type ValidatorServer struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
beaconDB db.Database
|
beaconDB db.Database
|
||||||
chainService chainService
|
headFetcher blockchain.HeadFetcher
|
||||||
canonicalStateChan chan *pbp2p.BeaconState
|
canonicalStateChan chan *pbp2p.BeaconState
|
||||||
powChainService powChainService
|
blockFetcher powchain.POWBlockFetcher
|
||||||
|
chainStartFetcher powchain.ChainStartFetcher
|
||||||
depositCache *depositcache.DepositCache
|
depositCache *depositcache.DepositCache
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +106,7 @@ func (vs *ValidatorServer) ValidatorPerformance(
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, status.Errorf(codes.Internal, "could not find validator index for public key %#x not found", req.PublicKey)
|
return nil, status.Errorf(codes.Internal, "could not find validator index for public key %#x not found", req.PublicKey)
|
||||||
}
|
}
|
||||||
headState := vs.chainService.HeadState()
|
headState := vs.headFetcher.HeadState()
|
||||||
|
|
||||||
activeCount, err := helpers.ActiveValidatorCount(headState, helpers.SlotToEpoch(req.Slot))
|
activeCount, err := helpers.ActiveValidatorCount(headState, helpers.SlotToEpoch(req.Slot))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -133,7 +136,7 @@ func (vs *ValidatorServer) ValidatorPerformance(
|
|||||||
// 4.) The bool signaling if the validator is expected to propose a block at the assigned slot.
|
// 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) {
|
func (vs *ValidatorServer) CommitteeAssignment(ctx context.Context, req *pb.AssignmentRequest) (*pb.AssignmentResponse, error) {
|
||||||
var err error
|
var err error
|
||||||
s := vs.chainService.HeadState()
|
s := vs.headFetcher.HeadState()
|
||||||
|
|
||||||
// Advance state with empty transitions up to the requested epoch start slot.
|
// Advance state with empty transitions up to the requested epoch start slot.
|
||||||
if epochStartSlot := helpers.StartSlot(req.EpochStart); s.Slot < epochStartSlot {
|
if epochStartSlot := helpers.StartSlot(req.EpochStart); s.Slot < epochStartSlot {
|
||||||
@@ -226,9 +229,9 @@ func (vs *ValidatorServer) assignment(
|
|||||||
func (vs *ValidatorServer) ValidatorStatus(
|
func (vs *ValidatorServer) ValidatorStatus(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *pb.ValidatorIndexRequest) (*pb.ValidatorStatusResponse, error) {
|
req *pb.ValidatorIndexRequest) (*pb.ValidatorStatusResponse, error) {
|
||||||
headState := vs.chainService.HeadState()
|
headState := vs.headFetcher.HeadState()
|
||||||
|
|
||||||
chainStarted := vs.powChainService.HasChainStarted()
|
chainStarted := vs.chainStartFetcher.HasChainStarted()
|
||||||
chainStartKeys := vs.chainStartPubkeys()
|
chainStartKeys := vs.chainStartPubkeys()
|
||||||
validatorIndexMap := stateutils.ValidatorIndexMap(headState)
|
validatorIndexMap := stateutils.ValidatorIndexMap(headState)
|
||||||
return vs.validatorStatus(ctx, req.PublicKey, chainStarted, chainStartKeys, validatorIndexMap, headState), nil
|
return vs.validatorStatus(ctx, req.PublicKey, chainStarted, chainStartKeys, validatorIndexMap, headState), nil
|
||||||
@@ -239,13 +242,13 @@ func (vs *ValidatorServer) ValidatorStatus(
|
|||||||
func (vs *ValidatorServer) MultipleValidatorStatus(
|
func (vs *ValidatorServer) MultipleValidatorStatus(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
pubkeys [][]byte) (bool, []*pb.ValidatorActivationResponse_Status, error) {
|
pubkeys [][]byte) (bool, []*pb.ValidatorActivationResponse_Status, error) {
|
||||||
chainStarted := vs.powChainService.HasChainStarted()
|
chainStarted := vs.chainStartFetcher.HasChainStarted()
|
||||||
if !chainStarted {
|
if !chainStarted {
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
activeValidatorExists := false
|
activeValidatorExists := false
|
||||||
statusResponses := make([]*pb.ValidatorActivationResponse_Status, len(pubkeys))
|
statusResponses := make([]*pb.ValidatorActivationResponse_Status, len(pubkeys))
|
||||||
headState := vs.chainService.HeadState()
|
headState := vs.headFetcher.HeadState()
|
||||||
|
|
||||||
chainStartKeys := vs.chainStartPubkeys()
|
chainStartKeys := vs.chainStartPubkeys()
|
||||||
validatorIndexMap := stateutils.ValidatorIndexMap(headState)
|
validatorIndexMap := stateutils.ValidatorIndexMap(headState)
|
||||||
@@ -425,7 +428,7 @@ func (vs *ValidatorServer) lookupValidatorStatus(validatorIdx uint64, beaconStat
|
|||||||
|
|
||||||
func (vs *ValidatorServer) depositBlockSlot(ctx context.Context, currentSlot uint64,
|
func (vs *ValidatorServer) depositBlockSlot(ctx context.Context, currentSlot uint64,
|
||||||
eth1BlockNumBigInt *big.Int, beaconState *pbp2p.BeaconState) (uint64, error) {
|
eth1BlockNumBigInt *big.Int, beaconState *pbp2p.BeaconState) (uint64, error) {
|
||||||
blockTimeStamp, err := vs.powChainService.BlockTimeByHeight(ctx, eth1BlockNumBigInt)
|
blockTimeStamp, err := vs.blockFetcher.BlockTimeByHeight(ctx, eth1BlockNumBigInt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -449,7 +452,7 @@ func (vs *ValidatorServer) depositBlockSlot(ctx context.Context, currentSlot uin
|
|||||||
|
|
||||||
func (vs *ValidatorServer) chainStartPubkeys() map[[96]byte]bool {
|
func (vs *ValidatorServer) chainStartPubkeys() map[[96]byte]bool {
|
||||||
pubkeys := make(map[[96]byte]bool)
|
pubkeys := make(map[[96]byte]bool)
|
||||||
deposits := vs.powChainService.ChainStartDeposits()
|
deposits := vs.chainStartFetcher.ChainStartDeposits()
|
||||||
for _, dep := range deposits {
|
for _, dep := range deposits {
|
||||||
pubkeys[bytesutil.ToBytes96(dep.Data.PublicKey)] = true
|
pubkeys[bytesutil.ToBytes96(dep.Data.PublicKey)] = true
|
||||||
}
|
}
|
||||||
@@ -458,7 +461,7 @@ func (vs *ValidatorServer) chainStartPubkeys() map[[96]byte]bool {
|
|||||||
|
|
||||||
// DomainData fetches the current domain version information from the beacon state.
|
// DomainData fetches the current domain version information from the beacon state.
|
||||||
func (vs *ValidatorServer) DomainData(ctx context.Context, request *pb.DomainRequest) (*pb.DomainResponse, error) {
|
func (vs *ValidatorServer) DomainData(ctx context.Context, request *pb.DomainRequest) (*pb.DomainResponse, error) {
|
||||||
headState := vs.chainService.HeadState()
|
headState := vs.headFetcher.HeadState()
|
||||||
dv := helpers.Domain(headState, request.Epoch, request.Domain)
|
dv := helpers.Domain(headState, request.Epoch, request.Domain)
|
||||||
return &pb.DomainResponse{
|
return &pb.DomainResponse{
|
||||||
SignatureDomain: dv,
|
SignatureDomain: dv,
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||||
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/testing"
|
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
|
||||||
|
internal "github.com/prysmaticlabs/prysm/beacon-chain/rpc/testing"
|
||||||
mockRPC "github.com/prysmaticlabs/prysm/beacon-chain/rpc/testing"
|
mockRPC "github.com/prysmaticlabs/prysm/beacon-chain/rpc/testing"
|
||||||
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||||
@@ -78,8 +79,8 @@ func TestNextEpochCommitteeAssignment_WrongPubkeyLength(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validatorServer := &ValidatorServer{
|
validatorServer := &ValidatorServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.AssignmentRequest{
|
req := &pb.AssignmentRequest{
|
||||||
PublicKeys: [][]byte{{1}},
|
PublicKeys: [][]byte{{1}},
|
||||||
@@ -107,7 +108,7 @@ func TestNextEpochCommitteeAssignment_CantFindValidatorIdx(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vs := &ValidatorServer{
|
vs := &ValidatorServer{
|
||||||
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKey := make([]byte, 96)
|
pubKey := make([]byte, 96)
|
||||||
@@ -159,8 +160,8 @@ func TestCommitteeAssignment_OK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vs := &ValidatorServer{
|
vs := &ValidatorServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the first validator in registry.
|
// Test the first validator in registry.
|
||||||
@@ -241,8 +242,8 @@ func TestCommitteeAssignment_CurrentEpoch_ShouldNotFail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vs := &ValidatorServer{
|
vs := &ValidatorServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the first validator in registry.
|
// Test the first validator in registry.
|
||||||
@@ -295,8 +296,8 @@ func TestCommitteeAssignment_MultipleKeys_OK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vs := &ValidatorServer{
|
vs := &ValidatorServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey0 := deposits[0].Data.PublicKey
|
pubkey0 := deposits[0].Data.PublicKey
|
||||||
@@ -367,15 +368,17 @@ func TestValidatorStatus_PendingActive(t *testing.T) {
|
|||||||
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
||||||
|
|
||||||
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
||||||
vs := &ValidatorServer{
|
p := &mockPOW.POWChain{
|
||||||
beaconDB: db,
|
TimesByHeight: map[int]uint64{
|
||||||
powChainService: &mockPOWChainService{
|
0: uint64(height),
|
||||||
blockTimeByHeight: map[int]uint64{
|
|
||||||
0: uint64(height),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
depositCache: depositCache,
|
}
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
vs := &ValidatorServer{
|
||||||
|
beaconDB: db,
|
||||||
|
chainStartFetcher: p,
|
||||||
|
blockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorIndexRequest{
|
req := &pb.ValidatorIndexRequest{
|
||||||
PublicKey: pubKey,
|
PublicKey: pubKey,
|
||||||
@@ -440,15 +443,17 @@ func TestValidatorStatus_Active(t *testing.T) {
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
timestamp := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
timestamp := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
||||||
vs := &ValidatorServer{
|
p := &mockPOW.POWChain{
|
||||||
beaconDB: db,
|
TimesByHeight: map[int]uint64{
|
||||||
powChainService: &mockPOWChainService{
|
int(params.BeaconConfig().Eth1FollowDistance): uint64(timestamp),
|
||||||
blockTimeByHeight: map[int]uint64{
|
|
||||||
int(params.BeaconConfig().Eth1FollowDistance): uint64(timestamp),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
depositCache: depositCache,
|
}
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
vs := &ValidatorServer{
|
||||||
|
beaconDB: db,
|
||||||
|
chainStartFetcher: p,
|
||||||
|
blockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorIndexRequest{
|
req := &pb.ValidatorIndexRequest{
|
||||||
PublicKey: pubKey,
|
PublicKey: pubKey,
|
||||||
@@ -517,15 +522,17 @@ func TestValidatorStatus_InitiatedExit(t *testing.T) {
|
|||||||
depositCache := depositcache.NewDepositCache()
|
depositCache := depositcache.NewDepositCache()
|
||||||
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
||||||
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
||||||
vs := &ValidatorServer{
|
p := &mockPOW.POWChain{
|
||||||
beaconDB: db,
|
TimesByHeight: map[int]uint64{
|
||||||
powChainService: &mockPOWChainService{
|
0: uint64(height),
|
||||||
blockTimeByHeight: map[int]uint64{
|
|
||||||
0: uint64(height),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
depositCache: depositCache,
|
}
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
vs := &ValidatorServer{
|
||||||
|
beaconDB: db,
|
||||||
|
chainStartFetcher: p,
|
||||||
|
blockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorIndexRequest{
|
req := &pb.ValidatorIndexRequest{
|
||||||
PublicKey: pubKey,
|
PublicKey: pubKey,
|
||||||
@@ -584,15 +591,17 @@ func TestValidatorStatus_Withdrawable(t *testing.T) {
|
|||||||
depositCache := depositcache.NewDepositCache()
|
depositCache := depositcache.NewDepositCache()
|
||||||
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
||||||
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
||||||
vs := &ValidatorServer{
|
p := &mockPOW.POWChain{
|
||||||
beaconDB: db,
|
TimesByHeight: map[int]uint64{
|
||||||
powChainService: &mockPOWChainService{
|
0: uint64(height),
|
||||||
blockTimeByHeight: map[int]uint64{
|
|
||||||
0: uint64(height),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
depositCache: depositCache,
|
}
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
vs := &ValidatorServer{
|
||||||
|
beaconDB: db,
|
||||||
|
chainStartFetcher: p,
|
||||||
|
blockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorIndexRequest{
|
req := &pb.ValidatorIndexRequest{
|
||||||
PublicKey: pubKey,
|
PublicKey: pubKey,
|
||||||
@@ -651,15 +660,17 @@ func TestValidatorStatus_ExitedSlashed(t *testing.T) {
|
|||||||
depositCache := depositcache.NewDepositCache()
|
depositCache := depositcache.NewDepositCache()
|
||||||
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
||||||
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
||||||
vs := &ValidatorServer{
|
p := &mockPOW.POWChain{
|
||||||
beaconDB: db,
|
TimesByHeight: map[int]uint64{
|
||||||
powChainService: &mockPOWChainService{
|
0: uint64(height),
|
||||||
blockTimeByHeight: map[int]uint64{
|
|
||||||
0: uint64(height),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
depositCache: depositCache,
|
}
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
vs := &ValidatorServer{
|
||||||
|
beaconDB: db,
|
||||||
|
chainStartFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
blockFetcher: p,
|
||||||
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorIndexRequest{
|
req := &pb.ValidatorIndexRequest{
|
||||||
PublicKey: pubKey,
|
PublicKey: pubKey,
|
||||||
@@ -719,15 +730,17 @@ func TestValidatorStatus_Exited(t *testing.T) {
|
|||||||
depositCache := depositcache.NewDepositCache()
|
depositCache := depositcache.NewDepositCache()
|
||||||
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
||||||
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
||||||
vs := &ValidatorServer{
|
p := &mockPOW.POWChain{
|
||||||
beaconDB: db,
|
TimesByHeight: map[int]uint64{
|
||||||
powChainService: &mockPOWChainService{
|
0: uint64(height),
|
||||||
blockTimeByHeight: map[int]uint64{
|
|
||||||
0: uint64(height),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
depositCache: depositCache,
|
}
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
vs := &ValidatorServer{
|
||||||
|
beaconDB: db,
|
||||||
|
chainStartFetcher: p,
|
||||||
|
blockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorIndexRequest{
|
req := &pb.ValidatorIndexRequest{
|
||||||
PublicKey: pubKey,
|
PublicKey: pubKey,
|
||||||
@@ -782,15 +795,17 @@ func TestValidatorStatus_UnknownStatus(t *testing.T) {
|
|||||||
depositCache := depositcache.NewDepositCache()
|
depositCache := depositcache.NewDepositCache()
|
||||||
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
depositCache.InsertDeposit(ctx, deposit, big.NewInt(0) /*blockNum*/, 0, depositTrie.Root())
|
||||||
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
height := time.Unix(int64(params.BeaconConfig().Eth1FollowDistance), 0).Unix()
|
||||||
vs := &ValidatorServer{
|
p := &mockPOW.POWChain{
|
||||||
beaconDB: db,
|
TimesByHeight: map[int]uint64{
|
||||||
powChainService: &mockPOWChainService{
|
0: uint64(height),
|
||||||
blockTimeByHeight: map[int]uint64{
|
|
||||||
0: uint64(height),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
depositCache: depositCache,
|
}
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
vs := &ValidatorServer{
|
||||||
|
beaconDB: db,
|
||||||
|
chainStartFetcher: p,
|
||||||
|
blockFetcher: p,
|
||||||
|
depositCache: depositCache,
|
||||||
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorIndexRequest{
|
req := &pb.ValidatorIndexRequest{
|
||||||
PublicKey: pubKey,
|
PublicKey: pubKey,
|
||||||
@@ -826,10 +841,11 @@ func TestWaitForActivation_ContextClosed(t *testing.T) {
|
|||||||
vs := &ValidatorServer{
|
vs := &ValidatorServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
powChainService: &mockPOWChainService{},
|
chainStartFetcher: &mockPOW.POWChain{},
|
||||||
|
blockFetcher: &mockPOW.POWChain{},
|
||||||
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
|
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
|
||||||
depositCache: depositcache.NewDepositCache(),
|
depositCache: depositcache.NewDepositCache(),
|
||||||
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorActivationRequest{
|
req := &pb.ValidatorActivationRequest{
|
||||||
PublicKeys: [][]byte{[]byte("A")},
|
PublicKeys: [][]byte{[]byte("A")},
|
||||||
@@ -929,9 +945,10 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) {
|
|||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
|
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
|
||||||
powChainService: &mockPOWChainService{},
|
chainStartFetcher: &mockPOW.POWChain{},
|
||||||
|
blockFetcher: &mockPOW.POWChain{},
|
||||||
depositCache: depositCache,
|
depositCache: depositCache,
|
||||||
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
req := &pb.ValidatorActivationRequest{
|
req := &pb.ValidatorActivationRequest{
|
||||||
PublicKeys: [][]byte{pubKey1, pubKey2},
|
PublicKeys: [][]byte{pubKey1, pubKey2},
|
||||||
@@ -1042,9 +1059,10 @@ func TestMultipleValidatorStatus_OK(t *testing.T) {
|
|||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
|
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
|
||||||
powChainService: &mockPOWChainService{},
|
chainStartFetcher: &mockPOW.POWChain{},
|
||||||
|
blockFetcher: &mockPOW.POWChain{},
|
||||||
depositCache: depositCache,
|
depositCache: depositCache,
|
||||||
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
activeExists, response, err := vs.MultipleValidatorStatus(context.Background(), pubKeys)
|
activeExists, response, err := vs.MultipleValidatorStatus(context.Background(), pubKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1108,8 +1126,8 @@ func BenchmarkAssignment(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vs := &ValidatorServer{
|
vs := &ValidatorServer{
|
||||||
beaconDB: db,
|
beaconDB: db,
|
||||||
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
headFetcher: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up request for 100 public keys at a time
|
// Set up request for 100 public keys at a time
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ var _ = shared.Service(&InitialSync{})
|
|||||||
|
|
||||||
type blockchainService interface {
|
type blockchainService interface {
|
||||||
blockchain.BlockReceiver
|
blockchain.BlockReceiver
|
||||||
blockchain.HeadRetriever
|
blockchain.HeadFetcher
|
||||||
blockchain.ChainFeeds
|
blockchain.ChainFeeds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ type Config struct {
|
|||||||
// This defines the interface for interacting with block chain service
|
// This defines the interface for interacting with block chain service
|
||||||
type blockchainService interface {
|
type blockchainService interface {
|
||||||
blockchain.BlockReceiver
|
blockchain.BlockReceiver
|
||||||
blockchain.HeadRetriever
|
blockchain.HeadFetcher
|
||||||
blockchain.FinalizationRetriever
|
blockchain.FinalizationFetcher
|
||||||
blockchain.AttestationReceiver
|
blockchain.AttestationReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
beacon-chain/sync/testing/BUILD.bazel
Normal file
9
beacon-chain/sync/testing/BUILD.bazel
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
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/sync/testing",
|
||||||
|
visibility = ["//beacon-chain:__subpackages__"],
|
||||||
|
)
|
||||||
16
beacon-chain/sync/testing/mock.go
Normal file
16
beacon-chain/sync/testing/mock.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
// Sync defines a mock for the sync service.
|
||||||
|
type Sync struct {
|
||||||
|
IsSyncing bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syncing --
|
||||||
|
func (s *Sync) Syncing() bool {
|
||||||
|
return s.IsSyncing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status --
|
||||||
|
func (s *Sync) Status() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -75,6 +75,8 @@ var appHelpFlagGroups = []flagGroup{
|
|||||||
Name: "beacon-chain",
|
Name: "beacon-chain",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
flags.NoCustomConfigFlag,
|
flags.NoCustomConfigFlag,
|
||||||
|
flags.InteropMockEth1DataVotesFlag,
|
||||||
|
flags.InteropGenesisStateFlag,
|
||||||
flags.DepositContractFlag,
|
flags.DepositContractFlag,
|
||||||
flags.Web3ProviderFlag,
|
flags.Web3ProviderFlag,
|
||||||
flags.RPCPort,
|
flags.RPCPort,
|
||||||
@@ -83,7 +85,6 @@ var appHelpFlagGroups = []flagGroup{
|
|||||||
flags.EnableDBCleanup,
|
flags.EnableDBCleanup,
|
||||||
flags.GRPCGatewayPort,
|
flags.GRPCGatewayPort,
|
||||||
flags.HTTPWeb3ProviderFlag,
|
flags.HTTPWeb3ProviderFlag,
|
||||||
flags.GenesisState,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user