Clean up post --next (#3411)

* Delete old code

* RPC mock testing

* Fixed BUILD

* Conflict

* Lint

* More lint
This commit is contained in:
terence tsao
2019-09-06 22:39:14 -04:00
committed by Raul Jordan
parent fb20fc7881
commit 4235980511
39 changed files with 408 additions and 1183 deletions

View File

@@ -40,8 +40,8 @@ type FinalizationRetriever interface {
}
// FinalizedCheckpt returns the latest finalized checkpoint tracked in fork choice service.
func (c *ChainService) FinalizedCheckpt() *ethpb.Checkpoint {
cp := c.forkChoiceStore.FinalizedCheckpt()
func (s *Service) FinalizedCheckpt() *ethpb.Checkpoint {
cp := s.forkChoiceStore.FinalizedCheckpt()
if cp != nil {
return cp
}
@@ -50,16 +50,16 @@ func (c *ChainService) FinalizedCheckpt() *ethpb.Checkpoint {
}
// HeadSlot returns the slot of the head of the chain.
func (c *ChainService) HeadSlot() uint64 {
return c.headSlot
func (s *Service) HeadSlot() uint64 {
return s.headSlot
}
// HeadRoot returns the root of the head of the chain.
func (c *ChainService) HeadRoot() []byte {
c.canonicalRootsLock.RLock()
defer c.canonicalRootsLock.RUnlock()
func (s *Service) HeadRoot() []byte {
s.canonicalRootsLock.RLock()
defer s.canonicalRootsLock.RUnlock()
root := c.canonicalRoots[c.headSlot]
root := s.canonicalRoots[s.headSlot]
if len(root) != 0 {
return root
}
@@ -68,24 +68,24 @@ func (c *ChainService) HeadRoot() []byte {
}
// HeadBlock returns the head block of the chain.
func (c *ChainService) HeadBlock() *ethpb.BeaconBlock {
return proto.Clone(c.headBlock).(*ethpb.BeaconBlock)
func (s *Service) HeadBlock() *ethpb.BeaconBlock {
return proto.Clone(s.headBlock).(*ethpb.BeaconBlock)
}
// HeadState returns the head state of the chain.
func (c *ChainService) HeadState() *pb.BeaconState {
return proto.Clone(c.headState).(*pb.BeaconState)
func (s *Service) HeadState() *pb.BeaconState {
return proto.Clone(s.headState).(*pb.BeaconState)
}
// CanonicalRoot returns the canonical root of a given slot.
func (c *ChainService) CanonicalRoot(slot uint64) []byte {
c.canonicalRootsLock.RLock()
defer c.canonicalRootsLock.RUnlock()
func (s *Service) CanonicalRoot(slot uint64) []byte {
s.canonicalRootsLock.RLock()
defer s.canonicalRootsLock.RUnlock()
return c.canonicalRoots[slot]
return s.canonicalRoots[slot]
}
// GenesisTime returns the genesis time of beacon chain.
func (c *ChainService) GenesisTime() time.Time {
return c.genesisTime
func (s *Service) GenesisTime() time.Time {
return s.genesisTime
}

View File

@@ -13,8 +13,8 @@ import (
"github.com/prysmaticlabs/prysm/shared/params"
)
// Ensure ChainService implements chain info interface.
var _ = ChainInfoRetriever(&ChainService{})
// Ensure Service implements chain info interface.
var _ = ChainInfoRetriever(&Service{})
func TestFinalizedCheckpt_Nil(t *testing.T) {
c := setupBeaconChain(t, nil)
@@ -47,7 +47,7 @@ func TestFinalizedCheckpt_CanRetrieve(t *testing.T) {
}
func TestHeadSlot_CanRetrieve(t *testing.T) {
c := &ChainService{}
c := &Service{}
c.headSlot = 100
if c.HeadSlot() != 100 {
t.Errorf("Wanted head slot: %d, got: %d", 100, c.HeadSlot())
@@ -55,7 +55,7 @@ func TestHeadSlot_CanRetrieve(t *testing.T) {
}
func TestHeadRoot_CanRetrieve(t *testing.T) {
c := &ChainService{canonicalRoots: make(map[uint64][]byte)}
c := &Service{canonicalRoots: make(map[uint64][]byte)}
c.headSlot = 100
c.canonicalRoots[c.headSlot] = []byte{'A'}
if !bytes.Equal([]byte{'A'}, c.HeadRoot()) {
@@ -65,7 +65,7 @@ func TestHeadRoot_CanRetrieve(t *testing.T) {
func TestHeadBlock_CanRetrieve(t *testing.T) {
b := &ethpb.BeaconBlock{Slot: 1}
c := &ChainService{headBlock: b}
c := &Service{headBlock: b}
if !reflect.DeepEqual(b, c.HeadBlock()) {
t.Error("incorrect head block received")
}
@@ -73,14 +73,14 @@ func TestHeadBlock_CanRetrieve(t *testing.T) {
func TestHeadState_CanRetrieve(t *testing.T) {
s := &pb.BeaconState{Slot: 2}
c := &ChainService{headState: s}
c := &Service{headState: s}
if !reflect.DeepEqual(s, c.HeadState()) {
t.Error("incorrect head state received")
}
}
func TestCanonicalRoot_CanRetrieve(t *testing.T) {
c := &ChainService{canonicalRoots: make(map[uint64][]byte)}
c := &Service{canonicalRoots: make(map[uint64][]byte)}
slot := uint64(123)
r := []byte{'B'}
c.canonicalRoots[slot] = r
@@ -90,7 +90,7 @@ func TestCanonicalRoot_CanRetrieve(t *testing.T) {
}
func TestGenesisTime_CanRetrieve(t *testing.T) {
c := &ChainService{}
c := &Service{}
c.genesisTime = time.Unix(100, 0)
if c.GenesisTime() != time.Unix(100, 0) {
t.Error("incorrect genesis time received")

View File

@@ -14,7 +14,7 @@ import (
const latestSlotCount = 10
// HeadsHandler is a handler to serve /heads page in metrics.
func (c *ChainService) HeadsHandler(w http.ResponseWriter, _ *http.Request) {
func (s *Service) HeadsHandler(w http.ResponseWriter, _ *http.Request) {
buf := new(bytes.Buffer)
if _, err := fmt.Fprintf(w, "\n %s\t%s\t", "Head slot", "Head root"); err != nil {
@@ -27,10 +27,10 @@ func (c *ChainService) HeadsHandler(w http.ResponseWriter, _ *http.Request) {
return
}
slots := c.latestHeadSlots()
for _, s := range slots {
r := hex.EncodeToString(bytesutil.Trunc(c.canonicalRoots[uint64(s)]))
if _, err := fmt.Fprintf(w, "\n %d\t\t%s\t", s, r); err != nil {
slots := s.latestHeadSlots()
for _, slot := range slots {
r := hex.EncodeToString(bytesutil.Trunc(s.canonicalRoots[uint64(slot)]))
if _, err := fmt.Fprintf(w, "\n %d\t\t%s\t", slot, r); err != nil {
logrus.WithError(err).Error("Failed to render chain heads page")
return
}
@@ -44,14 +44,14 @@ func (c *ChainService) HeadsHandler(w http.ResponseWriter, _ *http.Request) {
}
// This returns the latest head slots in a slice and up to latestSlotCount
func (c *ChainService) latestHeadSlots() []int {
s := make([]int, 0, len(c.canonicalRoots))
for k := range c.canonicalRoots {
s = append(s, int(k))
func (s *Service) latestHeadSlots() []int {
slots := make([]int, 0, len(s.canonicalRoots))
for k := range s.canonicalRoots {
slots = append(slots, int(k))
}
sort.Ints(s)
if (len(s)) > latestSlotCount {
return s[len(s)-latestSlotCount:]
sort.Ints(slots)
if (len(slots)) > latestSlotCount {
return slots[len(slots)-latestSlotCount:]
}
return s
return slots
}

View File

@@ -49,8 +49,8 @@ var (
})
)
func (c *ChainService) reportSlotMetrics(currentSlot uint64) {
func (s *Service) reportSlotMetrics(currentSlot uint64) {
beaconSlot.Set(float64(currentSlot))
beaconHeadSlot.Set(float64(c.HeadSlot()))
beaconHeadRoot.Set(float64(bytesutil.ToLowInt64(c.HeadRoot())))
beaconHeadSlot.Set(float64(s.HeadSlot()))
beaconHeadRoot.Set(float64(bytesutil.ToLowInt64(s.HeadRoot())))
}

View File

@@ -26,12 +26,12 @@ type AttestationReceiver interface {
// 2. Validate attestation, update validator's latest vote
// 3. Apply fork choice to the processed attestation
// 4. Save latest head info
func (c *ChainService) ReceiveAttestation(ctx context.Context, att *ethpb.Attestation) error {
func (s *Service) ReceiveAttestation(ctx context.Context, att *ethpb.Attestation) error {
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveAttestation")
defer span.End()
// Broadcast the new attestation to the network.
if err := c.p2p.Broadcast(ctx, att); err != nil {
if err := s.p2p.Broadcast(ctx, att); err != nil {
return errors.Wrap(err, "could not broadcast attestation")
}
@@ -45,7 +45,7 @@ func (c *ChainService) ReceiveAttestation(ctx context.Context, att *ethpb.Attest
"attDataRoot": hex.EncodeToString(att.Data.BeaconBlockRoot),
}).Debug("Broadcasting attestation")
if err := c.ReceiveAttestationNoPubsub(ctx, att); err != nil {
if err := s.ReceiveAttestationNoPubsub(ctx, att); err != nil {
return err
}
@@ -58,12 +58,12 @@ func (c *ChainService) ReceiveAttestation(ctx context.Context, att *ethpb.Attest
// 1. Validate attestation, update validator's latest vote
// 2. Apply fork choice to the processed attestation
// 3. Save latest head info
func (c *ChainService) ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Attestation) error {
func (s *Service) ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Attestation) error {
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveAttestationNoPubsub")
defer span.End()
// Update forkchoice store for the new attestation
attSlot, err := c.forkChoiceStore.OnAttestation(ctx, att)
attSlot, err := s.forkChoiceStore.OnAttestation(ctx, att)
if err != nil {
return errors.Wrap(err, "could not process block from fork choice service")
}
@@ -74,11 +74,11 @@ func (c *ChainService) ReceiveAttestationNoPubsub(ctx context.Context, att *ethp
}).Debug("Finished updating fork choice store for attestation")
// Run fork choice for head block after updating fork choice store.
headRoot, err := c.forkChoiceStore.Head(ctx)
headRoot, err := s.forkChoiceStore.Head(ctx)
if err != nil {
return errors.Wrap(err, "could not get head from fork choice service")
}
headBlk, err := c.beaconDB.Block(ctx, bytesutil.ToBytes32(headRoot))
headBlk, err := s.beaconDB.Block(ctx, bytesutil.ToBytes32(headRoot))
if err != nil {
return errors.Wrap(err, "could not compute state from block head")
}
@@ -89,7 +89,7 @@ func (c *ChainService) ReceiveAttestationNoPubsub(ctx context.Context, att *ethp
// Skip checking for competing attestation's target roots at epoch boundary.
if !helpers.IsEpochStart(attSlot) {
targetRoot, err := helpers.BlockRoot(c.headState, att.Data.Target.Epoch)
targetRoot, err := helpers.BlockRoot(s.headState, att.Data.Target.Epoch)
if err != nil {
return errors.Wrapf(err, "could not get target root for epoch %d", att.Data.Target.Epoch)
}
@@ -97,7 +97,7 @@ func (c *ChainService) ReceiveAttestationNoPubsub(ctx context.Context, att *ethp
}
// Save head info after running fork choice.
if err := c.saveHead(ctx, headBlk, bytesutil.ToBytes32(headRoot)); err != nil {
if err := s.saveHead(ctx, headBlk, bytesutil.ToBytes32(headRoot)); err != nil {
return errors.Wrap(err, "could not save head")
}

View File

@@ -26,7 +26,7 @@ type BlockReceiver interface {
// 2. Validate block, apply state transition and update check points
// 3. Apply fork choice to the processed block
// 4. Save latest head info
func (c *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.BeaconBlock) error {
func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.BeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveBlock")
defer span.End()
@@ -36,14 +36,14 @@ func (c *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.BeaconBloc
}
// Broadcast the new block to the network.
if err := c.p2p.Broadcast(ctx, block); err != nil {
if err := s.p2p.Broadcast(ctx, block); err != nil {
return errors.Wrap(err, "could not broadcast block")
}
log.WithFields(logrus.Fields{
"blockRoot": hex.EncodeToString(root[:]),
}).Info("Broadcasting block")
if err := c.ReceiveBlockNoPubsub(ctx, block); err != nil {
if err := s.ReceiveBlockNoPubsub(ctx, block); err != nil {
return err
}
@@ -56,12 +56,12 @@ func (c *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.BeaconBloc
// 1. Validate block, apply state transition and update check points
// 2. Apply fork choice to the processed block
// 3. Save latest head info
func (c *ChainService) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.BeaconBlock) error {
func (s *Service) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.BeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveBlockNoPubsub")
defer span.End()
// Apply state transition on the new block.
if err := c.forkChoiceStore.OnBlock(ctx, block); err != nil {
if err := s.forkChoiceStore.OnBlock(ctx, block); err != nil {
return errors.Wrap(err, "could not process block from fork choice service")
}
root, err := ssz.SigningRoot(block)
@@ -71,11 +71,11 @@ func (c *ChainService) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.Be
logStateTransitionData(block, root[:])
// Run fork choice after applying state transition on the new block.
headRoot, err := c.forkChoiceStore.Head(ctx)
headRoot, err := s.forkChoiceStore.Head(ctx)
if err != nil {
return errors.Wrap(err, "could not get head from fork choice service")
}
headBlk, err := c.beaconDB.Block(ctx, bytesutil.ToBytes32(headRoot))
headBlk, err := s.beaconDB.Block(ctx, bytesutil.ToBytes32(headRoot))
if err != nil {
return errors.Wrap(err, "could not compute state from block head")
}
@@ -87,17 +87,17 @@ func (c *ChainService) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.Be
isCompetingBlock(root[:], block.Slot, headRoot, headBlk.Slot)
// Save head info after running fork choice.
if err := c.saveHead(ctx, headBlk, bytesutil.ToBytes32(headRoot)); err != nil {
if err := s.saveHead(ctx, headBlk, bytesutil.ToBytes32(headRoot)); err != nil {
return errors.Wrap(err, "could not save head")
}
// Remove block's contained deposits, attestations, and other operations from persistent storage.
if err := c.cleanupBlockOperations(ctx, block); err != nil {
if err := s.cleanupBlockOperations(ctx, block); err != nil {
return errors.Wrap(err, "could not clean up block deposits, attestations, and other operations")
}
// Reports on block and fork choice metrics.
c.reportSlotMetrics(block.Slot)
s.reportSlotMetrics(block.Slot)
processedBlkNoPubsub.Inc()
return nil
@@ -107,12 +107,12 @@ func (c *ChainService) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.Be
// that are preformed blocks that is received from initial sync service. The operations consists of:
// 1. Validate block, apply state transition and update check points
// 2. Save latest head info
func (c *ChainService) ReceiveBlockNoPubsubForkchoice(ctx context.Context, block *ethpb.BeaconBlock) error {
func (s *Service) ReceiveBlockNoPubsubForkchoice(ctx context.Context, block *ethpb.BeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveBlockNoForkchoice")
defer span.End()
// Apply state transition on the incoming newly received block.
if err := c.forkChoiceStore.OnBlock(ctx, block); err != nil {
if err := s.forkChoiceStore.OnBlock(ctx, block); err != nil {
return errors.Wrap(err, "could not process block from fork choice service")
}
root, err := ssz.SigningRoot(block)
@@ -122,17 +122,17 @@ func (c *ChainService) ReceiveBlockNoPubsubForkchoice(ctx context.Context, block
logStateTransitionData(block, root[:])
// Save new block as head.
if err := c.saveHead(ctx, block, root); err != nil {
if err := s.saveHead(ctx, block, root); err != nil {
return errors.Wrap(err, "could not save head")
}
// Remove block's contained deposits, attestations, and other operations from persistent storage.
if err := c.cleanupBlockOperations(ctx, block); err != nil {
if err := s.cleanupBlockOperations(ctx, block); err != nil {
return errors.Wrap(err, "could not clean up block deposits, attestations, and other operations")
}
// Reports on block and fork choice metrics.
c.reportSlotMetrics(block.Slot)
s.reportSlotMetrics(block.Slot)
processedBlkNoPubsubForkchoice.Inc()
return nil
@@ -142,15 +142,15 @@ func (c *ChainService) ReceiveBlockNoPubsubForkchoice(ctx context.Context, block
// such as attestations, exits, and deposits. We update the latest seen attestation by validator
// in the local node's runtime, cleanup and remove pending deposits which have been included in the block
// from our node's local cache, and process validator exits and more.
func (c *ChainService) cleanupBlockOperations(ctx context.Context, block *ethpb.BeaconBlock) error {
func (s *Service) cleanupBlockOperations(ctx context.Context, block *ethpb.BeaconBlock) error {
// Forward processed block to operation pool to remove individual operation from DB.
if c.opsPoolService.IncomingProcessedBlockFeed().Send(block) == 0 {
if s.opsPoolService.IncomingProcessedBlockFeed().Send(block) == 0 {
log.Error("Sent processed block to no subscribers")
}
// Remove pending deposits from the deposit queue.
for _, dep := range block.Body.Deposits {
c.depositCache.RemovePendingDeposit(ctx, dep)
s.depositCache.RemovePendingDeposit(ctx, dep)
}
return nil
}

View File

@@ -30,20 +30,20 @@ import (
"go.opencensus.io/trace"
)
// ChainFeeds interface defines the methods of the ChainService which provide
// ChainFeeds interface defines the methods of the Service which provide
// information feeds.
type ChainFeeds interface {
StateInitializedFeed() *event.Feed
}
// ChainService represents a service that handles the internal
// Service represents a service that handles the internal
// logic of managing the full PoS beacon chain.
type ChainService struct {
type Service struct {
ctx context.Context
cancel context.CancelFunc
beaconDB db.Database
depositCache *depositcache.DepositCache
web3Service *powchain.Web3Service
web3Service *powchain.Service
opsPoolService operations.OperationFeeds
forkChoiceStore forkchoice.ForkChoicer
chainStartChan chan time.Time
@@ -62,7 +62,7 @@ type ChainService struct {
// Config options for the service.
type Config struct {
BeaconBlockBuf int
Web3Service *powchain.Web3Service
Web3Service *powchain.Service
BeaconDB db.Database
DepositCache *depositcache.DepositCache
OpsPoolService operations.OperationFeeds
@@ -71,12 +71,12 @@ type Config struct {
PreloadStatePath string
}
// NewChainService instantiates a new service instance that will
// NewService instantiates a new block service instance that will
// be registered into a running beacon node.
func NewChainService(ctx context.Context, cfg *Config) (*ChainService, error) {
func NewService(ctx context.Context, cfg *Config) (*Service, error) {
ctx, cancel := context.WithCancel(ctx)
store := forkchoice.NewForkChoiceService(ctx, cfg.BeaconDB)
return &ChainService{
return &Service{
ctx: ctx,
cancel: cancel,
beaconDB: cfg.BeaconDB,
@@ -94,56 +94,56 @@ func NewChainService(ctx context.Context, cfg *Config) (*ChainService, error) {
}
// Start a blockchain service's main event loop.
func (c *ChainService) Start() {
func (s *Service) Start() {
ctx := context.TODO()
beaconState, err := c.beaconDB.HeadState(ctx)
beaconState, err := s.beaconDB.HeadState(ctx)
if err != nil {
log.Fatalf("Could not fetch beacon state: %v", err)
}
// If the chain has already been initialized, simply start the block processing routine.
if beaconState != nil {
log.Info("Beacon chain data already exists, starting service")
c.genesisTime = time.Unix(int64(beaconState.GenesisTime), 0)
if err := c.initializeChainInfo(ctx); err != nil {
s.genesisTime = time.Unix(int64(beaconState.GenesisTime), 0)
if err := s.initializeChainInfo(ctx); err != nil {
log.Fatalf("Could not set up chain info: %v", err)
}
justifiedCheckpoint, err := c.beaconDB.JustifiedCheckpoint(ctx)
justifiedCheckpoint, err := s.beaconDB.JustifiedCheckpoint(ctx)
if err != nil {
log.Fatalf("Could not get justified checkpoint: %v", err)
}
finalizedCheckpoint, err := c.beaconDB.FinalizedCheckpoint(ctx)
finalizedCheckpoint, err := s.beaconDB.FinalizedCheckpoint(ctx)
if err != nil {
log.Fatalf("Could not get finalized checkpoint: %v", err)
}
if err := c.forkChoiceStore.GenesisStore(ctx, justifiedCheckpoint, finalizedCheckpoint); err != nil {
if err := s.forkChoiceStore.GenesisStore(ctx, justifiedCheckpoint, finalizedCheckpoint); err != nil {
log.Fatalf("Could not start fork choice service: %v", err)
}
c.stateInitializedFeed.Send(c.genesisTime)
} else if c.preloadStatePath != "" {
log.Infof("Loading generated genesis state from %v", c.preloadStatePath)
s, err := ioutil.ReadFile(c.preloadStatePath)
s.stateInitializedFeed.Send(s.genesisTime)
} else if s.preloadStatePath != "" {
log.Infof("Loading generated genesis state from %v", s.preloadStatePath)
data, err := ioutil.ReadFile(s.preloadStatePath)
if err != nil {
log.Fatalf("Could not read pre-loaded state: %v", err)
}
genesisState := &pb.BeaconState{}
if err := ssz.Unmarshal(s, genesisState); err != nil {
if err := ssz.Unmarshal(data, genesisState); err != nil {
log.Fatalf("Could not unmarshal pre-loaded state: %v", err)
}
c.genesisTime = time.Unix(int64(genesisState.GenesisTime), 0)
if err := c.saveGenesisData(ctx, genesisState); err != nil {
s.genesisTime = time.Unix(int64(genesisState.GenesisTime), 0)
if err := s.saveGenesisData(ctx, genesisState); err != nil {
log.Fatalf("Could not save genesis data: %v", err)
}
c.stateInitializedFeed.Send(c.genesisTime)
s.stateInitializedFeed.Send(s.genesisTime)
} else {
log.Info("Waiting for ChainStart log from the Validator Deposit Contract to start the beacon chain...")
if c.web3Service == nil {
if s.web3Service == nil {
log.Fatal("Not configured web3Service for POW chain")
return // return need for TestStartUninitializedChainWithoutConfigPOWChain.
}
subChainStart := c.web3Service.ChainStartFeed().Subscribe(c.chainStartChan)
subChainStart := s.web3Service.ChainStartFeed().Subscribe(s.chainStartChan)
go func() {
genesisTime := <-c.chainStartChan
c.processChainStartTime(ctx, genesisTime, subChainStart)
genesisTime := <-s.chainStartChan
s.processChainStartTime(ctx, genesisTime, subChainStart)
return
}()
}
@@ -151,27 +151,27 @@ func (c *ChainService) Start() {
// 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.
func (c *ChainService) processChainStartTime(ctx context.Context, genesisTime time.Time, chainStartSub event.Subscription) {
initialDeposits := c.web3Service.ChainStartDeposits()
if err := c.initializeBeaconChain(ctx, genesisTime, initialDeposits, c.web3Service.ChainStartETH1Data()); err != nil {
func (s *Service) processChainStartTime(ctx context.Context, genesisTime time.Time, chainStartSub event.Subscription) {
initialDeposits := s.web3Service.ChainStartDeposits()
if err := s.initializeBeaconChain(ctx, genesisTime, initialDeposits, s.web3Service.ChainStartETH1Data()); err != nil {
log.Fatalf("Could not initialize beacon chain: %v", err)
}
c.stateInitializedFeed.Send(genesisTime)
s.stateInitializedFeed.Send(genesisTime)
chainStartSub.Unsubscribe()
}
// initializes the state and genesis block of the beacon chain to persistent storage
// based on a genesis timestamp value obtained from the ChainStart event emitted
// by the ETH1.0 Deposit Contract and the POWChain service of the node.
func (c *ChainService) initializeBeaconChain(
func (s *Service) initializeBeaconChain(
ctx context.Context,
genesisTime time.Time,
deposits []*ethpb.Deposit,
eth1data *ethpb.Eth1Data) error {
_, span := trace.StartSpan(context.Background(), "beacon-chain.ChainService.initializeBeaconChain")
_, span := trace.StartSpan(context.Background(), "beacon-chain.Service.initializeBeaconChain")
defer span.End()
log.Info("ChainStart time reached, starting the beacon chain!")
c.genesisTime = genesisTime
s.genesisTime = genesisTime
unixTime := uint64(genesisTime.Unix())
genesisState, err := state.GenesisBeaconState(deposits, unixTime, eth1data)
@@ -179,7 +179,7 @@ func (c *ChainService) initializeBeaconChain(
return errors.Wrap(err, "could not initialize genesis state")
}
if err := c.saveGenesisData(ctx, genesisState); err != nil {
if err := s.saveGenesisData(ctx, genesisState); err != nil {
return errors.Wrap(err, "could not save genesis data")
}
@@ -187,8 +187,8 @@ func (c *ChainService) initializeBeaconChain(
}
// Stop the blockchain service's main event loop and associated goroutines.
func (c *ChainService) Stop() error {
defer c.cancel()
func (s *Service) Stop() error {
defer s.cancel()
log.Info("Stopping service")
return nil
@@ -196,8 +196,8 @@ func (c *ChainService) Stop() error {
// Status always returns nil.
// TODO(1202): Add service health checks.
func (c *ChainService) Status() error {
if runtime.NumGoroutine() > int(c.maxRoutines) {
func (s *Service) Status() error {
if runtime.NumGoroutine() > int(s.maxRoutines) {
return fmt.Errorf("too many goroutines %d", runtime.NumGoroutine())
}
return nil
@@ -205,28 +205,28 @@ func (c *ChainService) Status() error {
// StateInitializedFeed returns a feed that is written to
// when the beacon state is first initialized.
func (c *ChainService) StateInitializedFeed() *event.Feed {
return c.stateInitializedFeed
func (s *Service) StateInitializedFeed() *event.Feed {
return s.stateInitializedFeed
}
// This gets called to update canonical root mapping.
func (c *ChainService) saveHead(ctx context.Context, b *ethpb.BeaconBlock, r [32]byte) error {
c.headSlot = b.Slot
func (s *Service) saveHead(ctx context.Context, b *ethpb.BeaconBlock, r [32]byte) error {
s.headSlot = b.Slot
c.canonicalRootsLock.Lock()
c.canonicalRoots[b.Slot] = r[:]
defer c.canonicalRootsLock.Unlock()
s.canonicalRootsLock.Lock()
s.canonicalRoots[b.Slot] = r[:]
defer s.canonicalRootsLock.Unlock()
if err := c.beaconDB.SaveHeadBlockRoot(ctx, r); err != nil {
if err := s.beaconDB.SaveHeadBlockRoot(ctx, r); err != nil {
return errors.Wrap(err, "could not save head root in DB")
}
c.headBlock = b
s.headBlock = b
s, err := c.beaconDB.State(ctx, r)
headState, err := s.beaconDB.State(ctx, r)
if err != nil {
return errors.Wrap(err, "could not retrieve head state in DB")
}
c.headState = s
s.headState = headState
log.WithFields(logrus.Fields{
"slots": b.Slot,
@@ -236,9 +236,9 @@ func (c *ChainService) saveHead(ctx context.Context, b *ethpb.BeaconBlock, r [32
}
// This gets called when beacon chain is first initialized to save validator indices and pubkeys in db
func (c *ChainService) saveGenesisValidators(ctx context.Context, s *pb.BeaconState) error {
for i, v := range s.Validators {
if err := c.beaconDB.SaveValidatorIndex(ctx, bytesutil.ToBytes48(v.PublicKey), uint64(i)); err != nil {
func (s *Service) saveGenesisValidators(ctx context.Context, state *pb.BeaconState) error {
for i, v := range state.Validators {
if err := s.beaconDB.SaveValidatorIndex(ctx, bytesutil.ToBytes48(v.PublicKey), uint64(i)); err != nil {
return errors.Wrapf(err, "could not save validator index: %d", i)
}
}
@@ -246,7 +246,7 @@ func (c *ChainService) saveGenesisValidators(ctx context.Context, s *pb.BeaconSt
}
// This gets called when beacon chain is first initialized to save genesis data (state, block, and more) in db
func (c *ChainService) saveGenesisData(ctx context.Context, genesisState *pb.BeaconState) error {
func (s *Service) saveGenesisData(ctx context.Context, genesisState *pb.BeaconState) error {
stateRoot, err := ssz.HashTreeRoot(genesisState)
if err != nil {
return errors.Wrap(err, "could not tree hash genesis state")
@@ -257,57 +257,57 @@ func (c *ChainService) saveGenesisData(ctx context.Context, genesisState *pb.Bea
return errors.Wrap(err, "could not get genesis block root")
}
if err := c.beaconDB.SaveBlock(ctx, genesisBlk); err != nil {
if err := s.beaconDB.SaveBlock(ctx, genesisBlk); err != nil {
return errors.Wrap(err, "could not save genesis block")
}
if err := c.beaconDB.SaveHeadBlockRoot(ctx, genesisBlkRoot); err != nil {
if err := s.beaconDB.SaveHeadBlockRoot(ctx, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save head block root")
}
if err := c.beaconDB.SaveGenesisBlockRoot(ctx, genesisBlkRoot); err != nil {
if err := s.beaconDB.SaveGenesisBlockRoot(ctx, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could save genesis block root")
}
if err := c.beaconDB.SaveState(ctx, genesisState, genesisBlkRoot); err != nil {
if err := s.beaconDB.SaveState(ctx, genesisState, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save genesis state")
}
if err := c.saveGenesisValidators(ctx, genesisState); err != nil {
if err := s.saveGenesisValidators(ctx, genesisState); err != nil {
return errors.Wrap(err, "could not save genesis validators")
}
genesisCheckpoint := &ethpb.Checkpoint{Root: genesisBlkRoot[:]}
if err := c.forkChoiceStore.GenesisStore(ctx, genesisCheckpoint, genesisCheckpoint); err != nil {
if err := s.forkChoiceStore.GenesisStore(ctx, genesisCheckpoint, genesisCheckpoint); err != nil {
return errors.Wrap(err, "Could not start fork choice service: %v")
}
if err := c.beaconDB.SaveGenesisBlockRoot(ctx, bytesutil.ToBytes32(c.FinalizedCheckpt().Root)); err != nil {
if err := s.beaconDB.SaveGenesisBlockRoot(ctx, bytesutil.ToBytes32(s.FinalizedCheckpt().Root)); err != nil {
return errors.Wrap(err, "could save genesis block root")
}
c.headBlock = genesisBlk
c.headState = genesisState
c.canonicalRoots[genesisState.Slot] = genesisBlkRoot[:]
s.headBlock = genesisBlk
s.headState = genesisState
s.canonicalRoots[genesisState.Slot] = genesisBlkRoot[:]
return nil
}
// This gets called to initialize chain info variables using the head stored in DB
func (c *ChainService) initializeChainInfo(ctx context.Context) error {
headBlock, err := c.beaconDB.HeadBlock(ctx)
func (s *Service) initializeChainInfo(ctx context.Context) error {
headBlock, err := s.beaconDB.HeadBlock(ctx)
if err != nil {
return errors.Wrap(err, "could not get head block in db")
}
headState, err := c.beaconDB.HeadState(ctx)
headState, err := s.beaconDB.HeadState(ctx)
if err != nil {
return errors.Wrap(err, "could not get head state in db")
}
c.headSlot = headBlock.Slot
c.headBlock = headBlock
c.headState = headState
s.headSlot = headBlock.Slot
s.headBlock = headBlock
s.headState = headState
headRoot, err := ssz.SigningRoot(headBlock)
if err != nil {
return errors.Wrap(err, "could not sign root on head block")
}
c.canonicalRoots[c.headSlot] = headRoot[:]
s.canonicalRoots[s.headSlot] = headRoot[:]
return nil
}

View File

@@ -32,8 +32,8 @@ import (
logTest "github.com/sirupsen/logrus/hooks/test"
)
// Ensure ChainService implements interfaces.
var _ = ChainFeeds(&ChainService{})
// Ensure Service implements interfaces.
var _ = ChainFeeds(&Service{})
func init() {
logrus.SetLevel(logrus.DebugLevel)
@@ -176,7 +176,7 @@ func (mb *mockBroadcaster) Broadcast(_ context.Context, _ proto.Message) error {
var _ = p2p.Broadcaster(&mockBroadcaster{})
func setupGenesisBlock(t *testing.T, cs *ChainService) ([32]byte, *ethpb.BeaconBlock) {
func setupGenesisBlock(t *testing.T, cs *Service) ([32]byte, *ethpb.BeaconBlock) {
genesis := b.NewGenesisBlock([]byte{})
if err := cs.beaconDB.SaveBlock(context.Background(), genesis); err != nil {
t.Fatalf("could not save block to db: %v", err)
@@ -188,13 +188,13 @@ func setupGenesisBlock(t *testing.T, cs *ChainService) ([32]byte, *ethpb.BeaconB
return parentHash, genesis
}
func setupBeaconChain(t *testing.T, beaconDB db.Database) *ChainService {
func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
endpoint := "ws://127.0.0.1"
ctx := context.Background()
var web3Service *powchain.Web3Service
var web3Service *powchain.Service
var err error
client := &mockClient{}
web3Service, err = powchain.NewWeb3Service(ctx, &powchain.Web3ServiceConfig{
web3Service, err = powchain.NewService(ctx, &powchain.Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: common.Address{},
Reader: client,
@@ -216,7 +216,7 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *ChainService {
if err != nil {
t.Fatalf("could not register blockchain service: %v", err)
}
chainService, err := NewChainService(ctx, cfg)
chainService, err := NewService(ctx, cfg)
if err != nil {
t.Fatalf("unable to setup chain service: %v", err)
}
@@ -360,7 +360,7 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
if err := db.SaveHeadBlockRoot(ctx, headRoot); err != nil {
t.Fatal(err)
}
c := &ChainService{beaconDB: db, canonicalRoots: make(map[uint64][]byte)}
c := &Service{beaconDB: db, canonicalRoots: make(map[uint64][]byte)}
if err := c.initializeChainInfo(ctx); err != nil {
t.Fatal(err)
}

View File

@@ -5,7 +5,6 @@ go_library(
srcs = [
"block.go",
"block_operations.go",
"validity_conditions.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks",
visibility = ["//beacon-chain:__subpackages__"],
@@ -20,11 +19,8 @@ go_library(
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/roughtime:go_default_library",
"//shared/sliceutil:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
@@ -39,7 +35,6 @@ go_test(
"block_operations_test.go",
"block_test.go",
"eth1_data_test.go",
"validity_conditions_test.go",
],
embed = [":go_default_library"],
deps = [
@@ -53,11 +48,8 @@ go_test(
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/roughtime:go_default_library",
"//shared/testutil:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_phoreproject_bls//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",

View File

@@ -4,8 +4,6 @@
package blocks
import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/go-ssz"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -21,30 +19,3 @@ func NewGenesisBlock(stateRoot []byte) *ethpb.BeaconBlock {
}
return genBlock
}
// BlockFromHeader manufactures a block from its header. It contains all its fields,
// except for the block body.
func BlockFromHeader(header *ethpb.BeaconBlockHeader) *ethpb.BeaconBlock {
return &ethpb.BeaconBlock{
StateRoot: header.StateRoot,
Slot: header.Slot,
Signature: header.Signature,
ParentRoot: header.ParentRoot,
}
}
// HeaderFromBlock extracts the block header from a block.
func HeaderFromBlock(block *ethpb.BeaconBlock) (*ethpb.BeaconBlockHeader, error) {
header := &ethpb.BeaconBlockHeader{
Slot: block.Slot,
ParentRoot: block.ParentRoot,
Signature: block.Signature,
StateRoot: block.StateRoot,
}
root, err := ssz.HashTreeRoot(block.Body)
if err != nil {
return nil, errors.Wrap(err, "could not tree hash block body")
}
header.BodyRoot = root[:]
return header, nil
}

View File

@@ -3,10 +3,6 @@ package blocks
import (
"bytes"
"testing"
"github.com/gogo/protobuf/proto"
"github.com/prysmaticlabs/go-ssz"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
)
func TestGenesisBlock_InitializedCorrectly(t *testing.T) {
@@ -21,72 +17,3 @@ func TestGenesisBlock_InitializedCorrectly(t *testing.T) {
t.Error("genesis block StateRootHash32 isn't initialized correctly")
}
}
func TestHeaderFromBlock(t *testing.T) {
dummyBody := &ethpb.BeaconBlockBody{
Eth1Data: &ethpb.Eth1Data{},
Graffiti: []byte{},
RandaoReveal: []byte("Reveal"),
AttesterSlashings: []*ethpb.AttesterSlashing{},
ProposerSlashings: []*ethpb.ProposerSlashing{},
Attestations: []*ethpb.Attestation{},
Transfers: []*ethpb.Transfer{},
Deposits: []*ethpb.Deposit{},
VoluntaryExits: []*ethpb.VoluntaryExit{},
}
dummyBlock := &ethpb.BeaconBlock{
Slot: 10,
Signature: []byte{'S'},
ParentRoot: []byte("Parent"),
StateRoot: []byte("State"),
Body: dummyBody,
}
header, err := HeaderFromBlock(dummyBlock)
if err != nil {
t.Fatal(err)
}
expectedHeader := &ethpb.BeaconBlockHeader{
Slot: dummyBlock.Slot,
Signature: dummyBlock.Signature,
ParentRoot: dummyBlock.ParentRoot,
StateRoot: dummyBlock.StateRoot,
}
bodyRoot, err := ssz.HashTreeRoot(dummyBody)
if err != nil {
t.Fatal(err)
}
expectedHeader.BodyRoot = bodyRoot[:]
if !proto.Equal(expectedHeader, header) {
t.Errorf("Expected Header not Equal to Retrieved Header. Expected %v , Got %v",
proto.MarshalTextString(expectedHeader), proto.MarshalTextString(header))
}
}
func TestBlockFromHeader(t *testing.T) {
dummyHeader := &ethpb.BeaconBlockHeader{
Slot: 10,
Signature: []byte{'S'},
ParentRoot: []byte("Parent"),
StateRoot: []byte("State"),
}
block := BlockFromHeader(dummyHeader)
expectedBlock := &ethpb.BeaconBlock{
Slot: dummyHeader.Slot,
Signature: dummyHeader.Signature,
ParentRoot: dummyHeader.ParentRoot,
StateRoot: dummyHeader.StateRoot,
}
if !proto.Equal(expectedBlock, block) {
t.Errorf("Expected block not equal to retrieved block. Expected %v , Got %v",
proto.MarshalTextString(expectedBlock), proto.MarshalTextString(block))
}
}

View File

@@ -1,66 +0,0 @@
package blocks
import (
"context"
"fmt"
"time"
"github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime"
)
// IsValidBlock ensures that the block is compliant with the block processing validity conditions.
func IsValidBlock(
ctx context.Context,
state *pb.BeaconState,
block *ethpb.BeaconBlock,
HasBlock func(ctx context.Context, hash [32]byte) bool,
GetPOWBlock func(ctx context.Context, hash common.Hash) (*gethTypes.Block, error),
genesisTime time.Time) error {
// Pre-Processing Condition 1:
// Check that the parent Block has been processed and saved.
parentRoot := bytesutil.ToBytes32(block.ParentRoot)
parentBlock := HasBlock(ctx, parentRoot)
if !parentBlock {
return fmt.Errorf("unprocessed parent block as it is not saved in the db: %#x", parentRoot)
}
h := common.BytesToHash(state.Eth1Data.BlockHash)
powBlock, err := GetPOWBlock(ctx, h)
if err != nil {
return errors.Wrap(err, "unable to retrieve POW chain reference block")
}
// Pre-Processing Condition 2:
// The block pointed to by the state in state.processed_pow_receipt_root has
// been processed in the ETH 1.0 chain.
if powBlock == nil {
return fmt.Errorf("proof-of-Work chain reference in state does not exist: %#x", state.Eth1Data.BlockHash)
}
// Pre-Processing Condition 4:
// The node's local time is greater than or equal to
// state.genesis_time + (block.slot-GENESIS_SLOT)* SECONDS_PER_SLOT.
if !IsSlotValid(block.Slot, genesisTime) {
return fmt.Errorf("slot of block is too high: %d", block.Slot)
}
return nil
}
// IsSlotValid compares the slot to the system clock to determine if the block is valid.
func IsSlotValid(slot uint64, genesisTime time.Time) bool {
secondsSinceGenesis := time.Duration(slot*params.BeaconConfig().SecondsPerSlot) * time.Second
validTimeThreshold := genesisTime.Add(secondsSinceGenesis)
now := roughtime.Now()
isValid := now.After(validTimeThreshold)
return isValid
}

View File

@@ -1,209 +0,0 @@
package blocks
import (
"context"
"strings"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime"
"github.com/sirupsen/logrus"
)
func init() {
logrus.SetLevel(logrus.DebugLevel)
}
type mockDB struct {
hasBlock bool
}
func (f *mockDB) HasBlock(ctx context.Context, h [32]byte) bool {
return f.hasBlock
}
type mockPOWClient struct {
blockExists bool
}
func (m *mockPOWClient) BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error) {
if m.blockExists {
return &gethTypes.Block{}, nil
}
return nil, nil
}
func TestIsValidBlock_NoParent(t *testing.T) {
beaconState := &pb.BeaconState{}
ctx := context.Background()
db := &mockDB{}
powClient := &mockPOWClient{}
beaconState.Slot = 3
block := &ethpb.BeaconBlock{
Slot: 4,
}
genesisTime := time.Unix(0, 0)
db.hasBlock = false
if err := IsValidBlock(ctx, beaconState, block,
db.HasBlock, powClient.BlockByHash, genesisTime); err == nil {
t.Fatal("block is valid despite not having a parent")
}
}
func TestIsValidBlock_InvalidSlot(t *testing.T) {
ctx := context.Background()
beaconState := &pb.BeaconState{
Slot: 3,
Eth1Data: &ethpb.Eth1Data{
DepositRoot: []byte{2},
BlockHash: []byte{3},
},
}
db := &mockDB{
hasBlock: true,
}
powClient := &mockPOWClient{
blockExists: true,
}
block := &ethpb.BeaconBlock{
Slot: 4,
}
genesisTime := time.Now()
err := IsValidBlock(ctx, beaconState, block, db.HasBlock, powClient.BlockByHash, genesisTime)
if err == nil {
t.Fatalf("block is valid despite having an invalid slot %d", block.Slot)
}
if !strings.HasPrefix(err.Error(), "slot of block is too high: ") {
t.Fatalf("expected the error about too high slot, but got an error: %v", err)
}
}
func TestIsValidBlock_InvalidPoWReference(t *testing.T) {
beaconState := &pb.BeaconState{}
ctx := context.Background()
db := &mockDB{}
powClient := &mockPOWClient{}
beaconState.Slot = 3
block := &ethpb.BeaconBlock{
Slot: 4,
}
genesisTime := time.Unix(0, 0)
db.hasBlock = true
block.Slot = 4
powClient.blockExists = false
beaconState.Eth1Data = &ethpb.Eth1Data{
DepositRoot: []byte{2},
BlockHash: []byte{3},
}
if err := IsValidBlock(ctx, beaconState, block,
db.HasBlock, powClient.BlockByHash, genesisTime); err == nil {
t.Fatalf("block is valid despite having an invalid pow reference block")
}
}
func TestIsValidBlock_InvalidGenesis(t *testing.T) {
beaconState := &pb.BeaconState{}
ctx := context.Background()
db := &mockDB{}
db.hasBlock = true
powClient := &mockPOWClient{}
powClient.blockExists = false
beaconState.Slot = 3
beaconState.Eth1Data = &ethpb.Eth1Data{
DepositRoot: []byte{2},
BlockHash: []byte{3},
}
genesisTime := time.Unix(0, 0)
block := &ethpb.BeaconBlock{
Slot: 4,
}
invalidTime := time.Now().AddDate(1, 2, 3)
if err := IsValidBlock(ctx, beaconState, block,
db.HasBlock, powClient.BlockByHash, genesisTime); err == nil {
t.Fatalf("block is valid despite having an invalid genesis time %v", invalidTime)
}
}
func TestIsValidBlock_GoodBlock(t *testing.T) {
beaconState := &pb.BeaconState{}
ctx := context.Background()
db := &mockDB{}
db.hasBlock = true
powClient := &mockPOWClient{}
powClient.blockExists = true
beaconState.Slot = 3
beaconState.Eth1Data = &ethpb.Eth1Data{
DepositRoot: []byte{2},
BlockHash: []byte{3},
}
genesisTime := time.Unix(0, 0)
block := &ethpb.BeaconBlock{
Slot: 4,
}
if err := IsValidBlock(ctx, beaconState, block,
db.HasBlock, powClient.BlockByHash, genesisTime); err != nil {
t.Fatal(err)
}
}
func TestIsSlotValid(t *testing.T) {
type testCaseStruct struct {
slot uint64
genesisTime time.Time
result bool
}
testCases := []testCaseStruct{
{
slot: 5,
genesisTime: roughtime.Now(),
result: false,
},
{
slot: 5,
genesisTime: roughtime.Now().Add(
-time.Duration(params.BeaconConfig().SecondsPerSlot*5) * time.Second,
),
result: true,
},
}
for _, testCase := range testCases {
if testCase.result != IsSlotValid(testCase.slot, testCase.genesisTime) {
t.Fatalf("invalid IsSlotValid result for %v", testCase)
}
}
}

View File

@@ -7,7 +7,6 @@ go_library(
"block.go",
"cache.go",
"committee.go",
"eth1data.go",
"randao.go",
"rewards_penalties.go",
"shuffle.go",
@@ -42,7 +41,6 @@ go_test(
"attestation_test.go",
"block_test.go",
"committee_test.go",
"eth1data_test.go",
"randao_test.go",
"rewards_penalties_test.go",
"shuffle_test.go",

View File

@@ -175,17 +175,6 @@ func AttestingIndices(state *pb.BeaconState, data *ethpb.AttestationData, bf bit
return indices, nil
}
// VerifyBitfield validates a bitfield with a given committee size.
func VerifyBitfield(bf bitfield.Bitfield, committeeSize uint64) (bool, error) {
if bf.Len() != committeeSize {
return false, fmt.Errorf(
"wanted participants bitfield length %d, got: %d",
committeeSize,
bf.Len())
}
return true, nil
}
// CommitteeAssignment is used to query committee assignment from
// current and previous epoch.
//
@@ -357,20 +346,6 @@ func StartShard(state *pb.BeaconState, epoch uint64) (uint64, error) {
return startShard, nil
}
// VerifyAttestationBitfield verifies that an attestations bitfield is valid in respect
// to the committees at that slot.
func VerifyAttestationBitfield(bState *pb.BeaconState, att *ethpb.Attestation) (bool, error) {
committee, err := CrosslinkCommittee(bState, att.Data.Target.Epoch, att.Data.Crosslink.Shard)
if err != nil {
return false, errors.Wrap(err, "could not retrieve crosslink committees at slot")
}
if committee == nil {
return false, fmt.Errorf("no committee exist for shard in the attestation")
}
return VerifyBitfield(att.AggregationBits, uint64(len(committee)))
}
// CompactCommitteesRoot returns the index root of a given epoch.
//
// Spec pseudocode definition:

View File

@@ -318,31 +318,6 @@ func TestAttestationParticipants_EmptyBitfield(t *testing.T) {
}
}
func TestVerifyBitfield_OK(t *testing.T) {
bf := bitfield.Bitlist{0xFF, 0x01}
committeeSize := uint64(8)
isValidated, err := VerifyBitfield(bf, committeeSize)
if err != nil {
t.Fatal(err)
}
if !isValidated {
t.Error("bitfield is not validated when it was supposed to be")
}
bf = bitfield.Bitlist{0xFF, 0x07}
committeeSize = 10
isValidated, err = VerifyBitfield(bf, committeeSize)
if err != nil {
t.Fatal(err)
}
if !isValidated {
t.Error("bitfield is not validated when it was supposed to be")
}
}
func TestCommitteeAssignment_CanRetrieve(t *testing.T) {
// Initialize test with 128 validators, each slot and each shard gets 2 validators.
validators := make([]*ethpb.Validator, 2*params.BeaconConfig().SlotsPerEpoch)
@@ -597,123 +572,6 @@ func TestEpochStartShard_MixedActivationValidators(t *testing.T) {
}
}
func TestVerifyAttestationBitfield_OK(t *testing.T) {
if params.BeaconConfig().SlotsPerEpoch != 64 {
t.Errorf("SlotsPerEpoch should be 64 for these tests to pass")
}
validators := make([]*ethpb.Validator, 2*params.BeaconConfig().SlotsPerEpoch)
activeRoots := make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
}
activeRoots[i] = []byte{'A'}
}
state := &pb.BeaconState{
Validators: validators,
ActiveIndexRoots: activeRoots,
RandaoMixes: activeRoots,
}
tests := []struct {
attestation *ethpb.Attestation
stateSlot uint64
errorExists bool
verificationFailure bool
}{
{
attestation: &ethpb.Attestation{
AggregationBits: bitfield.Bitlist{0x05},
Data: &ethpb.AttestationData{
Crosslink: &ethpb.Crosslink{
Shard: 5,
},
Target: &ethpb.Checkpoint{},
},
},
stateSlot: 5,
},
{
attestation: &ethpb.Attestation{
AggregationBits: bitfield.Bitlist{0x06},
Data: &ethpb.AttestationData{
Crosslink: &ethpb.Crosslink{
Shard: 10,
},
Target: &ethpb.Checkpoint{},
},
},
stateSlot: 10,
},
{
attestation: &ethpb.Attestation{
AggregationBits: bitfield.Bitlist{0x06},
Data: &ethpb.AttestationData{
Crosslink: &ethpb.Crosslink{
Shard: 20,
},
Target: &ethpb.Checkpoint{},
},
},
stateSlot: 20,
},
{
attestation: &ethpb.Attestation{
AggregationBits: bitfield.Bitlist{0xFF, 0xC0, 0x01},
Data: &ethpb.AttestationData{
Crosslink: &ethpb.Crosslink{
Shard: 5,
},
Target: &ethpb.Checkpoint{},
},
},
stateSlot: 5,
errorExists: true,
},
{
attestation: &ethpb.Attestation{
AggregationBits: bitfield.Bitlist{0xFF, 0x01},
Data: &ethpb.AttestationData{
Crosslink: &ethpb.Crosslink{
Shard: 20,
},
Target: &ethpb.Checkpoint{},
},
},
stateSlot: 20,
verificationFailure: true,
},
}
for i, tt := range tests {
ClearAllCaches()
state.Slot = tt.stateSlot
verified, err := VerifyAttestationBitfield(state, tt.attestation)
if tt.errorExists {
if err == nil {
t.Error("error is nil, when verification is supposed to fail")
}
continue
}
if tt.verificationFailure {
if verified {
t.Error("verification succeeded when it was supposed to fail")
}
continue
}
if err != nil {
t.Errorf("%d Failed to verify bitfield: %v", i, err)
continue
}
if !verified {
t.Errorf("Bitfield isnt verified: %08b", tt.attestation.AggregationBits)
}
}
}
func TestCompactCommitteesRoot_OK(t *testing.T) {
ClearAllCaches()
// Create 10 committees

View File

@@ -1,63 +0,0 @@
package helpers
import (
"math/big"
"github.com/pkg/errors"
"github.com/prysmaticlabs/go-ssz"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/hashutil"
)
// VoteHierarchyMap struct that holds all the relevant data in order to count and
// choose the best vote.
type VoteHierarchyMap struct {
BestVote *ethpb.Eth1Data
bestVoteHeight *big.Int
mostVotes uint64
voteCountMap map[string]voteHierarchy
}
// voteHierarchy is a structure we use in order to count deposit votes and
// break ties between similarly voted deposits
type voteHierarchy struct {
votes uint64
height *big.Int
eth1Data *ethpb.Eth1Data
}
// EmptyVoteHierarchyMap creates and returns an empty VoteHierarchyMap.
func EmptyVoteHierarchyMap() *VoteHierarchyMap {
vm := &VoteHierarchyMap{}
vm.voteCountMap = make(map[string]voteHierarchy)
return vm
}
// CountVote takes a votecount map and adds the given vote to it in the relevant
// position while updating the best vote, most votes and best vote hash.
func CountVote(voteMap *VoteHierarchyMap, vote *ethpb.Eth1Data, blockHeight *big.Int) (*VoteHierarchyMap, error) {
encoded, err := ssz.Marshal(vote)
if err != nil {
return &VoteHierarchyMap{}, errors.Wrap(err, "could not get encoded hash of eth1data object")
}
he := hashutil.Hash(encoded)
v, ok := voteMap.voteCountMap[string(he[:])]
if !ok {
v = voteHierarchy{votes: 1, height: blockHeight, eth1Data: vote}
voteMap.voteCountMap[string(he[:])] = v
} else {
v.votes = v.votes + 1
voteMap.voteCountMap[string(he[:])] = v
}
if v.votes > voteMap.mostVotes {
voteMap.mostVotes = v.votes
voteMap.BestVote = vote
voteMap.bestVoteHeight = blockHeight
} else if v.votes == voteMap.mostVotes && v.height.Cmp(voteMap.bestVoteHeight) == 1 {
//breaking ties by favoring votes with higher block height.
voteMap.BestVote = vote
voteMap.bestVoteHeight = v.height
}
return voteMap, nil
}

View File

@@ -1,100 +0,0 @@
package helpers
import (
"math/big"
"reflect"
"testing"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
)
func TestCountVote_OK(t *testing.T) {
vm := EmptyVoteHierarchyMap()
ed := &ethpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 100, BlockHash: []byte{10}}
vm, err := CountVote(vm, ed, big.NewInt(0))
if err != nil {
t.Fatal("fail to add deposit to map")
}
if !reflect.DeepEqual(ed, vm.BestVote) {
t.Errorf(
"Expected best vote to be %v, got %v",
ed,
vm.BestVote,
)
}
}
func TestCountVote_ByVoteCount(t *testing.T) {
vm := EmptyVoteHierarchyMap()
ed1 := &ethpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 100, BlockHash: []byte{10}}
ed2 := &ethpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 101, BlockHash: []byte{10}}
vm, err := CountVote(vm, ed1, big.NewInt(0))
if err != nil {
t.Fatal("fail to add deposit to map")
}
vm, err = CountVote(vm, ed2, big.NewInt(0))
if err != nil {
t.Fatal("fail to add deposit to map")
}
vm, err = CountVote(vm, ed2, big.NewInt(0))
if err != nil {
t.Fatal("fail to add deposit to map")
}
if !reflect.DeepEqual(ed2, vm.BestVote) {
t.Errorf(
"Expected best vote to be %v, got %v",
ed2,
vm.BestVote,
)
}
}
func TestCountVote_PreferVoteCountToHeight(t *testing.T) {
vm := EmptyVoteHierarchyMap()
ed1 := &ethpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 100, BlockHash: []byte{10}}
ed2 := &ethpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 101, BlockHash: []byte{10}}
vm, err := CountVote(vm, ed1, big.NewInt(10))
if err != nil {
t.Fatal("fail to add deposit to map")
}
vm, err = CountVote(vm, ed2, big.NewInt(0))
if err != nil {
t.Fatal("fail to add deposit to map")
}
vm, err = CountVote(vm, ed2, big.NewInt(0))
if err != nil {
t.Fatal("fail to add deposit to map")
}
if !reflect.DeepEqual(ed2, vm.BestVote) {
t.Errorf(
"Expected best vote to be %v, got %v",
ed2,
vm.BestVote,
)
}
}
func TestCountVote_BreakTiesByHeight(t *testing.T) {
vm := EmptyVoteHierarchyMap()
ed1 := &ethpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 100, BlockHash: []byte{10}}
ed2 := &ethpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 101, BlockHash: []byte{10}}
vm, err := CountVote(vm, ed1, big.NewInt(10))
if err != nil {
t.Fatal("fail to add deposit to map")
}
vm, err = CountVote(vm, ed2, big.NewInt(0))
if err != nil {
t.Fatal("fail to add deposit to map")
}
if !reflect.DeepEqual(ed1, vm.BestVote) {
t.Errorf(
"Expected best vote to be %v, got %v",
ed1,
vm.BestVote,
)
}
}

View File

@@ -76,32 +76,6 @@ func InitiateValidatorExit(state *pb.BeaconState, idx uint64) (*pb.BeaconState,
return state, nil
}
// ExitValidator takes in validator index and does house
// keeping work to exit validator with entry exit delay.
//
// Spec pseudocode definition:
// def exit_validator(state: BeaconState, index: ValidatorIndex) -> None:
// """
// Exit the validator of the given ``index``.
// Note that this function mutates ``state``.
// """
// validator = state.validator_registry[index]
//
// # The following updates only occur if not previous exited
// if validator.exit_epoch <= get_entry_exit_effect_epoch(get_current_epoch(state)):
// return
//
// validator.exit_epoch = get_entry_exit_effect_epoch(get_current_epoch(state))
func ExitValidator(state *pb.BeaconState, idx uint64) *pb.BeaconState {
validator := state.Validators[idx]
if validator.ExitEpoch != params.BeaconConfig().FarFutureEpoch {
return state
}
validator.ExitEpoch = helpers.DelayedActivationExitEpoch(helpers.CurrentEpoch(state))
return state
}
// SlashValidator slashes the malicious validator's balance and awards
// the whistleblower's balance.
//

View File

@@ -97,38 +97,6 @@ func TestInitiateValidatorExit_ChurnOverflow(t *testing.T) {
}
}
func TestExitValidator_OK(t *testing.T) {
state := &pb.BeaconState{
Slot: 100, // epoch 2
Slashings: []uint64{0},
Validators: []*ethpb.Validator{
{ExitEpoch: params.BeaconConfig().FarFutureEpoch, PublicKey: []byte{'B'}},
},
}
newState := ExitValidator(state, 0)
currentEpoch := helpers.CurrentEpoch(state)
wantedEpoch := helpers.DelayedActivationExitEpoch(currentEpoch)
if newState.Validators[0].ExitEpoch != wantedEpoch {
t.Errorf("Wanted exit slot %d, got %d",
wantedEpoch,
newState.Validators[0].ExitEpoch)
}
}
func TestExitValidator_AlreadyExited(t *testing.T) {
state := &pb.BeaconState{
Slot: 1000,
Validators: []*ethpb.Validator{
{ExitEpoch: params.BeaconConfig().ActivationExitDelay},
},
}
state = ExitValidator(state, 0)
if state.Validators[0].ExitEpoch != params.BeaconConfig().ActivationExitDelay {
t.Error("Expected exited validator to stay exited")
}
}
func TestSlashValidator_OK(t *testing.T) {
registry := make([]*ethpb.Validator, 0)
balances := make([]uint64, 0)

View File

@@ -227,7 +227,7 @@ func (b *BeaconNode) fetchP2P(ctx *cli.Context) p2p.P2P {
}
func (b *BeaconNode) registerBlockchainService(ctx *cli.Context) error {
var web3Service *powchain.Web3Service
var web3Service *powchain.Service
if err := b.services.FetchService(&web3Service); err != nil {
return err
}
@@ -238,7 +238,7 @@ func (b *BeaconNode) registerBlockchainService(ctx *cli.Context) error {
maxRoutines := ctx.GlobalInt64(cmd.MaxGoroutines.Name)
blockchainService, err := blockchain.NewChainService(context.Background(), &blockchain.Config{
blockchainService, err := blockchain.NewService(context.Background(), &blockchain.Config{
BeaconDB: b.db,
DepositCache: b.depositCache,
Web3Service: web3Service,
@@ -253,7 +253,7 @@ func (b *BeaconNode) registerBlockchainService(ctx *cli.Context) error {
}
func (b *BeaconNode) registerOperationService(ctx *cli.Context) error {
operationService := operations.NewOpsPoolService(context.Background(), &operations.Config{
operationService := operations.NewService(context.Background(), &operations.Config{
BeaconDB: b.db,
P2P: b.fetchP2P(ctx),
})
@@ -263,7 +263,7 @@ func (b *BeaconNode) registerOperationService(ctx *cli.Context) error {
func (b *BeaconNode) registerPOWChainService(cliCtx *cli.Context) error {
if cliCtx.GlobalBool(testSkipPowFlag) {
return b.services.RegisterService(&powchain.Web3Service{})
return b.services.RegisterService(&powchain.Service{})
}
depAddress := cliCtx.GlobalString(flags.DepositContractFlag.Name)
@@ -305,7 +305,7 @@ func (b *BeaconNode) registerPOWChainService(cliCtx *cli.Context) error {
BeaconDB: b.db,
DepositCache: b.depositCache,
}
web3Service, err := powchain.NewWeb3Service(ctx, cfg)
web3Service, err := powchain.NewService(ctx, cfg)
if err != nil {
return errors.Wrap(err, "could not register proof-of-work chain web3Service")
}
@@ -326,12 +326,12 @@ func (b *BeaconNode) registerSyncService(ctx *cli.Context) error {
return err
}
var web3Service *powchain.Web3Service
var web3Service *powchain.Service
if err := b.services.FetchService(&web3Service); err != nil {
return err
}
var chainService *blockchain.ChainService
var chainService *blockchain.Service
if err := b.services.FetchService(&chainService); err != nil {
return err
}
@@ -348,7 +348,7 @@ func (b *BeaconNode) registerSyncService(ctx *cli.Context) error {
func (b *BeaconNode) registerInitialSyncService(ctx *cli.Context) error {
var chainService *blockchain.ChainService
var chainService *blockchain.Service
if err := b.services.FetchService(&chainService); err != nil {
return err
}
@@ -369,7 +369,7 @@ func (b *BeaconNode) registerInitialSyncService(ctx *cli.Context) error {
}
func (b *BeaconNode) registerRPCService(ctx *cli.Context) error {
var chainService *blockchain.ChainService
var chainService *blockchain.Service
if err := b.services.FetchService(&chainService); err != nil {
return err
}
@@ -379,7 +379,7 @@ func (b *BeaconNode) registerRPCService(ctx *cli.Context) error {
return err
}
var web3Service *powchain.Web3Service
var web3Service *powchain.Service
if err := b.services.FetchService(&web3Service); err != nil {
return err
}
@@ -392,7 +392,7 @@ func (b *BeaconNode) registerRPCService(ctx *cli.Context) error {
port := ctx.GlobalString(flags.RPCPort.Name)
cert := ctx.GlobalString(flags.CertFlag.Name)
key := ctx.GlobalString(flags.KeyFlag.Name)
rpcService := rpc.NewRPCService(context.Background(), &rpc.Config{
rpcService := rpc.NewService(context.Background(), &rpc.Config{
Port: port,
CertFlag: cert,
KeyFlag: key,
@@ -416,7 +416,7 @@ func (b *BeaconNode) registerPrometheusService(ctx *cli.Context) error {
}
additionalHandlers = append(additionalHandlers, prometheus.Handler{Path: "/p2p", Handler: p.InfoHandler})
var c *blockchain.ChainService
var c *blockchain.Service
if err := b.services.FetchService(&c); err != nil {
panic(err)
}

View File

@@ -66,9 +66,9 @@ type Config struct {
P2P p2p.Broadcaster
}
// NewOpsPoolService instantiates a new service instance that will
// NewService instantiates a new operation service instance that will
// be registered into a running beacon node.
func NewOpsPoolService(ctx context.Context, cfg *Config) *Service {
func NewService(ctx context.Context, cfg *Config) *Service {
ctx, cancel := context.WithCancel(ctx)
return &Service{
ctx: ctx,

View File

@@ -37,7 +37,7 @@ func (mb *mockBroadcaster) Broadcast(_ context.Context, _ proto.Message) error {
func TestStop_OK(t *testing.T) {
hook := logTest.NewGlobal()
opsService := NewOpsPoolService(context.Background(), &Config{})
opsService := NewService(context.Background(), &Config{})
if err := opsService.Stop(); err != nil {
t.Fatalf("Unable to stop operation service: %v", err)
@@ -57,7 +57,7 @@ func TestStop_OK(t *testing.T) {
}
func TestServiceStatus_Error(t *testing.T) {
service := NewOpsPoolService(context.Background(), &Config{})
service := NewService(context.Background(), &Config{})
if service.Status() != nil {
t.Errorf("service status should be nil to begin with, got: %v", service.error)
}
@@ -73,7 +73,7 @@ func TestIncomingExits_Ok(t *testing.T) {
hook := logTest.NewGlobal()
beaconDB := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, beaconDB)
service := NewOpsPoolService(context.Background(), &Config{BeaconDB: beaconDB})
service := NewService(context.Background(), &Config{BeaconDB: beaconDB})
exit := &ethpb.VoluntaryExit{Epoch: 100}
if err := service.HandleValidatorExits(context.Background(), exit); err != nil {
@@ -88,7 +88,7 @@ func TestHandleAttestation_Saves_NewAttestation(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, beaconDB)
broadcaster := &mockBroadcaster{}
service := NewOpsPoolService(context.Background(), &Config{
service := NewService(context.Background(), &Config{
BeaconDB: beaconDB,
P2P: broadcaster,
})
@@ -175,7 +175,7 @@ func TestHandleAttestation_Aggregates_LargeNumValidators(t *testing.T) {
defer dbutil.TeardownDB(t, beaconDB)
ctx := context.Background()
broadcaster := &mockBroadcaster{}
opsSrv := NewOpsPoolService(ctx, &Config{
opsSrv := NewService(ctx, &Config{
BeaconDB: beaconDB,
P2P: broadcaster,
})
@@ -292,7 +292,7 @@ func TestHandleAttestation_Skips_PreviouslyAggregatedAttestations(t *testing.T)
ctx := context.Background()
helpers.ClearAllCaches()
broadcaster := &mockBroadcaster{}
service := NewOpsPoolService(context.Background(), &Config{
service := NewService(context.Background(), &Config{
BeaconDB: beaconDB,
P2P: broadcaster,
})
@@ -475,7 +475,7 @@ func TestRetrieveAttestations_OK(t *testing.T) {
helpers.ClearAllCaches()
beaconDB := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, beaconDB)
service := NewOpsPoolService(context.Background(), &Config{BeaconDB: beaconDB})
service := NewService(context.Background(), &Config{BeaconDB: beaconDB})
// Save 140 attestations for test. During 1st retrieval we should get slot:1 - slot:61 attestations.
// The 1st retrieval is set at slot 64.
@@ -522,7 +522,7 @@ func TestRetrieveAttestations_PruneInvalidAtts(t *testing.T) {
helpers.ClearAllCaches()
beaconDB := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, beaconDB)
service := NewOpsPoolService(context.Background(), &Config{BeaconDB: beaconDB})
service := NewService(context.Background(), &Config{BeaconDB: beaconDB})
// Save 140 attestations for slots 0 to 139.
origAttestations := make([]*ethpb.Attestation, 140)
@@ -576,7 +576,7 @@ func TestRetrieveAttestations_PruneInvalidAtts(t *testing.T) {
func TestRemoveProcessedAttestations_Ok(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, beaconDB)
s := NewOpsPoolService(context.Background(), &Config{BeaconDB: beaconDB})
s := NewService(context.Background(), &Config{BeaconDB: beaconDB})
attestations := make([]*ethpb.Attestation, 10)
for i := 0; i < len(attestations); i++ {
@@ -626,7 +626,7 @@ func TestRemoveProcessedAttestations_Ok(t *testing.T) {
func TestReceiveBlkRemoveOps_Ok(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, beaconDB)
s := NewOpsPoolService(context.Background(), &Config{BeaconDB: beaconDB})
s := NewService(context.Background(), &Config{BeaconDB: beaconDB})
attestations := make([]*ethpb.Attestation, 10)
for i := 0; i < len(attestations); i++ {

View File

@@ -10,11 +10,11 @@ import (
)
// BlockExists returns true if the block exists, it's height and any possible error encountered.
func (w *Web3Service) BlockExists(ctx context.Context, hash common.Hash) (bool, *big.Int, error) {
func (s *Service) BlockExists(ctx context.Context, hash common.Hash) (bool, *big.Int, error) {
ctx, span := trace.StartSpan(ctx, "beacon-chain.web3service.BlockExists")
defer span.End()
if exists, blkInfo, err := w.blockCache.BlockInfoByHash(hash); exists || err != nil {
if exists, blkInfo, err := s.blockCache.BlockInfoByHash(hash); exists || err != nil {
if err != nil {
return false, nil, err
}
@@ -22,12 +22,12 @@ func (w *Web3Service) BlockExists(ctx context.Context, hash common.Hash) (bool,
return true, blkInfo.Number, nil
}
span.AddAttributes(trace.BoolAttribute("blockCacheHit", false))
block, err := w.blockFetcher.BlockByHash(ctx, hash)
block, err := s.blockFetcher.BlockByHash(ctx, hash)
if err != nil {
return false, big.NewInt(0), errors.Wrap(err, "could not query block with given hash")
}
if err := w.blockCache.AddBlock(block); err != nil {
if err := s.blockCache.AddBlock(block); err != nil {
return false, big.NewInt(0), err
}
@@ -35,11 +35,11 @@ func (w *Web3Service) BlockExists(ctx context.Context, hash common.Hash) (bool,
}
// BlockHashByHeight returns the block hash of the block at the given height.
func (w *Web3Service) BlockHashByHeight(ctx context.Context, height *big.Int) (common.Hash, error) {
func (s *Service) BlockHashByHeight(ctx context.Context, height *big.Int) (common.Hash, error) {
ctx, span := trace.StartSpan(ctx, "beacon-chain.web3service.BlockHashByHeight")
defer span.End()
if exists, blkInfo, err := w.blockCache.BlockInfoByHeight(height); exists || err != nil {
if exists, blkInfo, err := s.blockCache.BlockInfoByHeight(height); exists || err != nil {
if err != nil {
return [32]byte{}, err
}
@@ -47,21 +47,21 @@ func (w *Web3Service) BlockHashByHeight(ctx context.Context, height *big.Int) (c
return blkInfo.Hash, nil
}
span.AddAttributes(trace.BoolAttribute("blockCacheHit", false))
block, err := w.blockFetcher.BlockByNumber(ctx, height)
block, err := s.blockFetcher.BlockByNumber(ctx, height)
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not query block with given height")
}
if err := w.blockCache.AddBlock(block); err != nil {
if err := s.blockCache.AddBlock(block); err != nil {
return [32]byte{}, err
}
return block.Hash(), nil
}
// BlockTimeByHeight fetches an eth1.0 block timestamp by its height.
func (w *Web3Service) BlockTimeByHeight(ctx context.Context, height *big.Int) (uint64, error) {
func (s *Service) BlockTimeByHeight(ctx context.Context, height *big.Int) (uint64, error) {
ctx, span := trace.StartSpan(ctx, "beacon-chain.web3service.BlockTimeByHeight")
defer span.End()
block, err := w.blockFetcher.BlockByNumber(ctx, height)
block, err := s.blockFetcher.BlockByNumber(ctx, height)
if err != nil {
return 0, errors.Wrap(err, "could not query block with given height")
}
@@ -72,11 +72,11 @@ func (w *Web3Service) BlockTimeByHeight(ctx context.Context, height *big.Int) (u
// This is a naive implementation that will use O(ETH1_FOLLOW_DISTANCE) calls to cache
// or ETH1. This is called for multiple times but only changes every
// SlotsPerEth1VotingPeriod (1024 slots) so the whole method should be cached.
func (w *Web3Service) BlockNumberByTimestamp(ctx context.Context, time uint64) (*big.Int, error) {
func (s *Service) BlockNumberByTimestamp(ctx context.Context, time uint64) (*big.Int, error) {
ctx, span := trace.StartSpan(ctx, "beacon-chain.web3service.BlockByTimestamp")
defer span.End()
head, err := w.blockFetcher.BlockByNumber(ctx, nil)
head, err := s.blockFetcher.BlockByNumber(ctx, nil)
if err != nil {
return nil, err
}
@@ -86,17 +86,17 @@ func (w *Web3Service) BlockNumberByTimestamp(ctx context.Context, time uint64) (
return nil, ctx.Err()
}
exists, info, err := w.blockCache.BlockInfoByHeight(bn)
exists, info, err := s.blockCache.BlockInfoByHeight(bn)
if err != nil {
return nil, err
}
if !exists {
blk, err := w.blockFetcher.BlockByNumber(ctx, bn)
blk, err := s.blockFetcher.BlockByNumber(ctx, bn)
if err != nil {
return nil, err
}
if err := w.blockCache.AddBlock(blk); err != nil {
if err := s.blockCache.AddBlock(blk); err != nil {
return nil, err
}
info = blockToBlockInfo(blk)

View File

@@ -22,7 +22,7 @@ func TestLatestMainchainInfo_OK(t *testing.T) {
}
beaconDB := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, beaconDB)
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -82,7 +82,7 @@ func TestLatestMainchainInfo_OK(t *testing.T) {
}
func TestBlockHashByHeight_ReturnsHash(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
BlockFetcher: &goodFetcher{},
})
@@ -121,7 +121,7 @@ func TestBlockHashByHeight_ReturnsHash(t *testing.T) {
}
func TestBlockExists_ValidHash(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
BlockFetcher: &goodFetcher{},
})
@@ -160,7 +160,7 @@ func TestBlockExists_ValidHash(t *testing.T) {
}
func TestBlockExists_InvalidHash(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
BlockFetcher: &goodFetcher{},
})
@@ -175,7 +175,7 @@ func TestBlockExists_InvalidHash(t *testing.T) {
}
func TestBlockExists_UsesCachedBlockInfo(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
BlockFetcher: nil, // nil blockFetcher would panic if cached value not used
})
@@ -210,7 +210,7 @@ func TestBlockExists_UsesCachedBlockInfo(t *testing.T) {
}
func TestBlockNumberByTimestamp(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
BlockFetcher: &goodFetcher{},
Client: nil,

View File

@@ -14,7 +14,7 @@ import (
// processDeposit is a copy of the core function of the same name which includes some optimizations
// and removes the requirement to pass in beacon state. This is for determining genesis validators.
func (w *Web3Service) processDeposit(
func (s *Service) processDeposit(
eth1Data *ethpb.Eth1Data,
deposit *ethpb.Deposit,
) error {
@@ -23,7 +23,7 @@ func (w *Web3Service) processDeposit(
}
pubKey := bytesutil.ToBytes48(deposit.Data.PublicKey)
amount := deposit.Data.Amount
currBal, ok := w.depositedPubkeys[pubKey]
currBal, ok := s.depositedPubkeys[pubKey]
if !ok {
pub, err := bls.PublicKeyFromBytes(pubKey[:])
if err != nil {
@@ -41,20 +41,20 @@ func (w *Web3Service) processDeposit(
if !sig.Verify(root[:], pub, domain) {
return fmt.Errorf("deposit signature did not verify")
}
w.depositedPubkeys[pubKey] = amount
s.depositedPubkeys[pubKey] = amount
if amount >= params.BeaconConfig().MaxEffectiveBalance {
w.activeValidatorCount++
s.activeValidatorCount++
}
} else {
newBal := currBal + amount
w.depositedPubkeys[pubKey] = newBal
s.depositedPubkeys[pubKey] = newBal
// exit if the validator is already an active validator previously
if currBal >= params.BeaconConfig().MaxEffectiveBalance {
return nil
}
if newBal >= params.BeaconConfig().MaxEffectiveBalance {
w.activeValidatorCount++
s.activeValidatorCount++
}
}
return nil

View File

@@ -20,7 +20,7 @@ import (
const pubKeyErr = "could not deserialize validator public key"
func TestProcessDeposit_OK(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
Reader: &goodReader{},
Logger: &goodLogger{},
@@ -61,7 +61,7 @@ func TestProcessDeposit_OK(t *testing.T) {
}
func TestProcessDeposit_InvalidMerkleBranch(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
Reader: &goodReader{},
Logger: &goodLogger{},
@@ -108,7 +108,7 @@ func TestProcessDeposit_InvalidMerkleBranch(t *testing.T) {
}
func TestProcessDeposit_InvalidPublicKey(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
Reader: &goodReader{},
Logger: &goodLogger{},
@@ -152,7 +152,7 @@ func TestProcessDeposit_InvalidPublicKey(t *testing.T) {
}
func TestProcessDeposit_InvalidSignature(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
Reader: &goodReader{},
Logger: &goodLogger{},
@@ -199,7 +199,7 @@ func TestProcessDeposit_InvalidSignature(t *testing.T) {
func TestProcessDeposit_UnableToVerify(t *testing.T) {
helpers.ClearAllCaches()
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
Reader: &goodReader{},
Logger: &goodLogger{},
@@ -231,7 +231,7 @@ func TestProcessDeposit_UnableToVerify(t *testing.T) {
}
func TestProcessDeposit_IncompleteDeposit(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
Reader: &goodReader{},
Logger: &goodLogger{},
@@ -285,7 +285,7 @@ func TestProcessDeposit_IncompleteDeposit(t *testing.T) {
}
func TestProcessDeposit_AllDepositedSuccessfully(t *testing.T) {
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
Reader: &goodReader{},
Logger: &goodLogger{},

View File

@@ -29,25 +29,25 @@ var (
// ETH2GenesisTime retrieves the genesis time and eth1 block number of the beacon chain
// from the deposit contract.
func (w *Web3Service) ETH2GenesisTime() (uint64, *big.Int) {
return w.eth2GenesisTime, w.chainStartBlockNumber
func (s *Service) ETH2GenesisTime() (uint64, *big.Int) {
return s.eth2GenesisTime, s.chainStartBlockNumber
}
// ProcessLog is the main method which handles the processing of all
// logs from the deposit contract on the ETH1.0 chain.
func (w *Web3Service) ProcessLog(ctx context.Context, depositLog gethTypes.Log) error {
w.processingLock.RLock()
defer w.processingLock.RUnlock()
func (s *Service) ProcessLog(ctx context.Context, depositLog gethTypes.Log) error {
s.processingLock.RLock()
defer s.processingLock.RUnlock()
// Process logs according to their event signature.
if depositLog.Topics[0] == hashutil.HashKeccak256(depositEventSignature) {
if err := w.ProcessDepositLog(ctx, depositLog); err != nil {
if err := s.ProcessDepositLog(ctx, depositLog); err != nil {
return errors.Wrap(err, "Could not process deposit log")
}
if !w.chainStarted {
if !s.chainStarted {
if depositLog.BlockHash == [32]byte{} {
return errors.New("got empty blockhash from powchain service")
}
blk, err := w.blockFetcher.BlockByHash(ctx, depositLog.BlockHash)
blk, err := s.blockFetcher.BlockByHash(ctx, depositLog.BlockHash)
if err != nil {
return errors.Wrap(err, "could not get eth1 block")
}
@@ -55,10 +55,10 @@ func (w *Web3Service) ProcessLog(ctx context.Context, depositLog gethTypes.Log)
return errors.Wrap(err, "got empty block from powchain service")
}
timeStamp := blk.Time()
triggered := state.IsValidGenesisState(w.activeValidatorCount, timeStamp)
triggered := state.IsValidGenesisState(s.activeValidatorCount, timeStamp)
if triggered {
w.setGenesisTime(timeStamp)
w.ProcessChainStart(uint64(w.eth2GenesisTime), depositLog.BlockHash, blk.Number())
s.setGenesisTime(timeStamp)
s.ProcessChainStart(uint64(s.eth2GenesisTime), depositLog.BlockHash, blk.Number())
}
}
return nil
@@ -70,7 +70,7 @@ func (w *Web3Service) ProcessLog(ctx context.Context, depositLog gethTypes.Log)
// ProcessDepositLog processes the log which had been received from
// the ETH1.0 chain by trying to ascertain which participant deposited
// in the contract.
func (w *Web3Service) ProcessDepositLog(ctx context.Context, depositLog gethTypes.Log) error {
func (s *Service) ProcessDepositLog(ctx context.Context, depositLog gethTypes.Log) error {
pubkey, withdrawalCredentials, amount, signature, merkleTreeIndex, err := contracts.UnpackDepositLogData(depositLog.Data)
if err != nil {
return errors.Wrap(err, "Could not unpack log")
@@ -80,17 +80,17 @@ func (w *Web3Service) ProcessDepositLog(ctx context.Context, depositLog gethType
// ETH1.0 network, and prevents us from updating our trie
// with the same log twice, causing an inconsistent state root.
index := binary.LittleEndian.Uint64(merkleTreeIndex)
if int64(index) <= w.lastReceivedMerkleIndex {
if int64(index) <= s.lastReceivedMerkleIndex {
return nil
}
if int64(index) != w.lastReceivedMerkleIndex+1 {
if int64(index) != s.lastReceivedMerkleIndex+1 {
missedDepositLogsCount.Inc()
if err := w.requestMissingLogs(ctx, depositLog.BlockNumber, int64(index-1)); err != nil {
if err := s.requestMissingLogs(ctx, depositLog.BlockNumber, int64(index-1)); err != nil {
return errors.Wrap(err, "Could not get correct merkle index")
}
}
w.lastReceivedMerkleIndex = int64(index)
s.lastReceivedMerkleIndex = int64(index)
// We then decode the deposit input in order to create a deposit object
// we can store in our persistent DB.
@@ -107,11 +107,11 @@ func (w *Web3Service) ProcessDepositLog(ctx context.Context, depositLog gethType
return errors.Wrap(err, "Unable to determine hashed value of deposit")
}
if err := w.depositTrie.InsertIntoTrie(depositHash[:], int(index)); err != nil {
if err := s.depositTrie.InsertIntoTrie(depositHash[:], int(index)); err != nil {
return errors.Wrap(err, "Unable to insert deposit into trie")
}
proof, err := w.depositTrie.MerkleProof(int(index))
proof, err := s.depositTrie.MerkleProof(int(index))
if err != nil {
return errors.Wrap(err, "Unable to generate merkle proof for deposit")
}
@@ -122,32 +122,32 @@ func (w *Web3Service) ProcessDepositLog(ctx context.Context, depositLog gethType
}
// Make sure duplicates are rejected pre-chainstart.
if !w.chainStarted && validData {
if !s.chainStarted && validData {
var pubkey = fmt.Sprintf("#%x", depositData.PublicKey)
if w.depositCache.PubkeyInChainstart(ctx, pubkey) {
if s.depositCache.PubkeyInChainstart(ctx, pubkey) {
log.Warnf("Pubkey %#x has already been submitted for chainstart", pubkey)
} else {
w.depositCache.MarkPubkeyForChainstart(ctx, pubkey)
s.depositCache.MarkPubkeyForChainstart(ctx, pubkey)
}
}
// We always store all historical deposits in the DB.
w.depositCache.InsertDeposit(ctx, deposit, big.NewInt(int64(depositLog.BlockNumber)), int(index), w.depositTrie.Root())
s.depositCache.InsertDeposit(ctx, deposit, big.NewInt(int64(depositLog.BlockNumber)), int(index), s.depositTrie.Root())
if !w.chainStarted {
w.chainStartDeposits = append(w.chainStartDeposits, deposit)
root := w.depositTrie.Root()
if !s.chainStarted {
s.chainStartDeposits = append(s.chainStartDeposits, deposit)
root := s.depositTrie.Root()
eth1Data := &ethpb.Eth1Data{
DepositRoot: root[:],
DepositCount: uint64(len(w.chainStartDeposits)),
DepositCount: uint64(len(s.chainStartDeposits)),
}
if err := w.processDeposit(eth1Data, deposit); err != nil {
if err := s.processDeposit(eth1Data, deposit); err != nil {
log.Errorf("Invalid deposit processed: %v", err)
validData = false
}
} else {
w.depositCache.InsertPendingDeposit(ctx, deposit, big.NewInt(int64(depositLog.BlockNumber)), int(index), w.depositTrie.Root())
s.depositCache.InsertPendingDeposit(ctx, deposit, big.NewInt(int64(depositLog.BlockNumber)), int(index), s.depositTrie.Root())
}
if validData {
log.WithFields(logrus.Fields{
@@ -165,12 +165,12 @@ func (w *Web3Service) ProcessDepositLog(ctx context.Context, depositLog gethType
// ProcessChainStart processes the log which had been received from
// the ETH1.0 chain by trying to determine when to start the beacon chain.
func (w *Web3Service) ProcessChainStart(genesisTime uint64, eth1BlockHash [32]byte, blockNumber *big.Int) {
w.chainStarted = true
w.chainStartBlockNumber = blockNumber
func (s *Service) ProcessChainStart(genesisTime uint64, eth1BlockHash [32]byte, blockNumber *big.Int) {
s.chainStarted = true
s.chainStartBlockNumber = blockNumber
chainStartTime := time.Unix(int64(genesisTime), 0)
depHashes, err := w.ChainStartDepositHashes()
depHashes, err := s.ChainStartDepositHashes()
if err != nil {
log.Errorf("Generating chainstart deposit hashes failed: %v", err)
return
@@ -187,18 +187,18 @@ func (w *Web3Service) ProcessChainStart(genesisTime uint64, eth1BlockHash [32]by
log.Fatalf("Unable to generate deposit trie from ChainStart deposits: %v", err)
}
for i := range w.chainStartDeposits {
for i := range s.chainStartDeposits {
proof, err := sparseMerkleTrie.MerkleProof(i)
if err != nil {
log.Errorf("Unable to generate deposit proof %v", err)
}
w.chainStartDeposits[i].Proof = proof
s.chainStartDeposits[i].Proof = proof
}
w.depositTrie = sparseMerkleTrie
s.depositTrie = sparseMerkleTrie
root := sparseMerkleTrie.Root()
w.chainStartETH1Data = &ethpb.Eth1Data{
DepositCount: uint64(len(w.chainStartDeposits)),
s.chainStartETH1Data = &ethpb.Eth1Data{
DepositCount: uint64(len(s.chainStartDeposits)),
DepositRoot: root[:],
BlockHash: eth1BlockHash[:],
}
@@ -206,47 +206,47 @@ func (w *Web3Service) ProcessChainStart(genesisTime uint64, eth1BlockHash [32]by
log.WithFields(logrus.Fields{
"ChainStartTime": chainStartTime,
}).Info("Minimum number of validators reached for beacon-chain to start")
w.chainStartFeed.Send(chainStartTime)
s.chainStartFeed.Send(chainStartTime)
}
func (w *Web3Service) setGenesisTime(timeStamp uint64) {
func (s *Service) setGenesisTime(timeStamp uint64) {
if featureconfig.FeatureConfig().NoGenesisDelay {
w.eth2GenesisTime = uint64(time.Unix(int64(timeStamp), 0).Add(30 * time.Second).Unix())
s.eth2GenesisTime = uint64(time.Unix(int64(timeStamp), 0).Add(30 * time.Second).Unix())
} else {
timeStampRdDown := timeStamp - timeStamp%params.BeaconConfig().SecondsPerDay
// genesisTime will be set to the first second of the day, two days after it was triggered.
w.eth2GenesisTime = timeStampRdDown + 2*params.BeaconConfig().SecondsPerDay
s.eth2GenesisTime = timeStampRdDown + 2*params.BeaconConfig().SecondsPerDay
}
}
// processPastLogs processes all the past logs from the deposit contract and
// updates the deposit trie with the data from each individual log.
func (w *Web3Service) processPastLogs(ctx context.Context) error {
func (s *Service) processPastLogs(ctx context.Context) error {
query := ethereum.FilterQuery{
Addresses: []common.Address{
w.depositContractAddress,
s.depositContractAddress,
},
}
logs, err := w.httpLogger.FilterLogs(ctx, query)
logs, err := s.httpLogger.FilterLogs(ctx, query)
if err != nil {
return err
}
for _, log := range logs {
if err := w.ProcessLog(ctx, log); err != nil {
if err := s.ProcessLog(ctx, log); err != nil {
return errors.Wrap(err, "could not process log")
}
}
w.lastRequestedBlock.Set(w.blockHeight)
s.lastRequestedBlock.Set(s.blockHeight)
currentState, err := w.beaconDB.HeadState(ctx)
currentState, err := s.beaconDB.HeadState(ctx)
if err != nil {
return errors.Wrap(err, "could not get head state")
}
if currentState != nil && currentState.Eth1DepositIndex > 0 {
w.depositCache.PrunePendingDeposits(ctx, int(currentState.Eth1DepositIndex))
s.depositCache.PrunePendingDeposits(ctx, int(currentState.Eth1DepositIndex))
}
return nil
@@ -254,18 +254,18 @@ func (w *Web3Service) processPastLogs(ctx context.Context) error {
// requestBatchedLogs requests and processes all the logs from the period
// last polled to now.
func (w *Web3Service) requestBatchedLogs(ctx context.Context) error {
func (s *Service) requestBatchedLogs(ctx context.Context) error {
// We request for the nth block behind the current head, in order to have
// stabilized logs when we retrieve it from the 1.0 chain.
requestedBlock := big.NewInt(0).Sub(w.blockHeight, big.NewInt(params.BeaconConfig().LogBlockDelay))
requestedBlock := big.NewInt(0).Sub(s.blockHeight, big.NewInt(params.BeaconConfig().LogBlockDelay))
query := ethereum.FilterQuery{
Addresses: []common.Address{
w.depositContractAddress,
s.depositContractAddress,
},
FromBlock: w.lastRequestedBlock.Add(w.lastRequestedBlock, big.NewInt(1)),
FromBlock: s.lastRequestedBlock.Add(s.lastRequestedBlock, big.NewInt(1)),
ToBlock: requestedBlock,
}
logs, err := w.httpLogger.FilterLogs(ctx, query)
logs, err := s.httpLogger.FilterLogs(ctx, query)
if err != nil {
return err
}
@@ -273,29 +273,29 @@ func (w *Web3Service) requestBatchedLogs(ctx context.Context) error {
// Only process log slices which are larger than zero.
if len(logs) > 0 {
for _, log := range logs {
if err := w.ProcessLog(ctx, log); err != nil {
if err := s.ProcessLog(ctx, log); err != nil {
return errors.Wrap(err, "could not process log")
}
}
}
w.lastRequestedBlock.Set(requestedBlock)
s.lastRequestedBlock.Set(requestedBlock)
return nil
}
// requestMissingLogs requests any logs that were missed by requesting from previous blocks
// until the current block(exclusive).
func (w *Web3Service) requestMissingLogs(ctx context.Context, blkNumber uint64, wantedIndex int64) error {
func (s *Service) requestMissingLogs(ctx context.Context, blkNumber uint64, wantedIndex int64) error {
// We request from the last requested block till the current block(exclusive)
beforeCurrentBlk := big.NewInt(int64(blkNumber) - 1)
query := ethereum.FilterQuery{
Addresses: []common.Address{
w.depositContractAddress,
s.depositContractAddress,
},
FromBlock: big.NewInt(0).Add(w.lastRequestedBlock, big.NewInt(1)),
FromBlock: big.NewInt(0).Add(s.lastRequestedBlock, big.NewInt(1)),
ToBlock: beforeCurrentBlk,
}
logs, err := w.httpLogger.FilterLogs(ctx, query)
logs, err := s.httpLogger.FilterLogs(ctx, query)
if err != nil {
return err
}
@@ -303,24 +303,24 @@ func (w *Web3Service) requestMissingLogs(ctx context.Context, blkNumber uint64,
// Only process log slices which are larger than zero.
if len(logs) > 0 {
for _, log := range logs {
if err := w.ProcessLog(ctx, log); err != nil {
if err := s.ProcessLog(ctx, log); err != nil {
return errors.Wrap(err, "could not process log")
}
}
}
if w.lastReceivedMerkleIndex != wantedIndex {
if s.lastReceivedMerkleIndex != wantedIndex {
return fmt.Errorf("despite requesting missing logs, latest index observed is not accurate. "+
"Wanted %d but got %d", wantedIndex, w.lastReceivedMerkleIndex)
"Wanted %d but got %d", wantedIndex, s.lastReceivedMerkleIndex)
}
return nil
}
// ChainStartDepositHashes returns the hashes of all the chainstart deposits
// stored in memory.
func (w *Web3Service) ChainStartDepositHashes() ([][]byte, error) {
hashes := make([][]byte, len(w.chainStartDeposits))
for i, dep := range w.chainStartDeposits {
func (s *Service) ChainStartDepositHashes() ([][]byte, error) {
hashes := make([][]byte, len(s.chainStartDeposits))
for i, dep := range s.chainStartDeposits {
hash, err := ssz.HashTreeRoot(dep.Data)
if err != nil {
return nil, err

View File

@@ -33,7 +33,7 @@ func TestProcessDepositLog_OK(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -95,7 +95,7 @@ func TestProcessDepositLog_InsertsPendingDeposit(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -164,7 +164,7 @@ func TestUnpackDepositLogData_OK(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -242,7 +242,7 @@ func TestProcessETH2GenesisLog_8DuplicatePubkeys(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -311,7 +311,7 @@ func TestProcessETH2GenesisLog(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -391,7 +391,7 @@ func TestWeb3ServiceProcessDepositLog_RequestMissedDeposits(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},

View File

@@ -66,13 +66,13 @@ type Client interface {
bind.ContractCaller
}
// Web3Service 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
// Beacon Chain requires synchronization with the ETH1.0 chain's current
// blockhash, block number, and access to logs within the
// Validator Registration Contract on the ETH1.0 chain to kick off the beacon
// chain's validator registration process.
type Web3Service struct {
type Service struct {
ctx context.Context
cancel context.CancelFunc
client Client
@@ -121,9 +121,9 @@ type Web3ServiceConfig struct {
DepositCache *depositcache.DepositCache
}
// NewWeb3Service sets up a new instance with an ethclient when
// NewService sets up a new instance with an ethclient when
// given a web3 endpoint as a string in the config.
func NewWeb3Service(ctx context.Context, config *Web3ServiceConfig) (*Web3Service, error) {
func NewService(ctx context.Context, config *Web3ServiceConfig) (*Service, error) {
if !strings.HasPrefix(config.Endpoint, "ws") && !strings.HasPrefix(config.Endpoint, "ipc") {
return nil, fmt.Errorf(
"powchain service requires either an IPC or WebSocket endpoint, provided %s",
@@ -142,7 +142,7 @@ func NewWeb3Service(ctx context.Context, config *Web3ServiceConfig) (*Web3Servic
cancel()
return nil, errors.Wrap(err, "could not setup deposit trie")
}
return &Web3Service{
return &Service{
ctx: ctx,
cancel: cancel,
headerChan: make(chan *gethTypes.Header),
@@ -170,20 +170,20 @@ func NewWeb3Service(ctx context.Context, config *Web3ServiceConfig) (*Web3Servic
}
// Start a web3 service's main event loop.
func (w *Web3Service) Start() {
func (s *Service) Start() {
log.WithFields(logrus.Fields{
"endpoint": w.endpoint,
"endpoint": s.endpoint,
}).Info("Starting service")
go w.run(w.ctx.Done())
go s.run(s.ctx.Done())
}
// Stop the web3 service's main event loop and associated goroutines.
func (w *Web3Service) Stop() error {
if w.cancel != nil {
defer w.cancel()
func (s *Service) Stop() error {
if s.cancel != nil {
defer s.cancel()
}
if w.headerChan != nil {
defer close(w.headerChan)
if s.headerChan != nil {
defer close(s.headerChan)
}
log.Info("Stopping service")
return nil
@@ -191,43 +191,43 @@ func (w *Web3Service) Stop() error {
// ChainStartFeed returns a feed that is written to
// whenever the deposit contract fires a ChainStart log.
func (w *Web3Service) ChainStartFeed() *event.Feed {
return w.chainStartFeed
func (s *Service) ChainStartFeed() *event.Feed {
return s.chainStartFeed
}
// ChainStartDeposits returns a slice of validator deposit data processed
// by the deposit contract and cached in the powchain service.
func (w *Web3Service) ChainStartDeposits() []*ethpb.Deposit {
return w.chainStartDeposits
func (s *Service) ChainStartDeposits() []*ethpb.Deposit {
return s.chainStartDeposits
}
// ChainStartETH1Data returns the eth1 data at chainstart.
func (w *Web3Service) ChainStartETH1Data() *ethpb.Eth1Data {
return w.chainStartETH1Data
func (s *Service) ChainStartETH1Data() *ethpb.Eth1Data {
return s.chainStartETH1Data
}
// HasChainStarted returns whether the deposits from
// the deposit contract received so far are valid enough
// to kick start the beacon chain.
func (w *Web3Service) HasChainStarted() bool {
return w.chainStarted
func (s *Service) HasChainStarted() bool {
return s.chainStarted
}
// Status is service health checks. Return nil or error.
func (w *Web3Service) Status() error {
// Web3Service don't start
if !w.isRunning {
func (s *Service) Status() error {
// Service don't start
if !s.isRunning {
return nil
}
// get error from run function
if w.runError != nil {
return w.runError
if s.runError != nil {
return s.runError
}
// use a 5 minutes timeout for block time, because the max mining time is 278 sec (block 7208027)
// (analyzed the time of the block from 2018-09-01 to 2019-02-13)
fiveMinutesTimeout := time.Now().Add(-5 * time.Minute)
// check that web3 client is syncing
if w.blockTime.Before(fiveMinutesTimeout) {
if s.blockTime.Before(fiveMinutesTimeout) {
return errors.New("eth1 client is not syncing")
}
return nil
@@ -235,42 +235,42 @@ func (w *Web3Service) Status() error {
// DepositRoot returns the Merkle root of the latest deposit trie
// from the ETH1.0 deposit contract.
func (w *Web3Service) DepositRoot() [32]byte {
return w.depositTrie.Root()
func (s *Service) DepositRoot() [32]byte {
return s.depositTrie.Root()
}
// DepositTrie returns the sparse Merkle trie used for storing
// deposits from the ETH1.0 deposit contract.
func (w *Web3Service) DepositTrie() *trieutil.MerkleTrie {
return w.depositTrie
func (s *Service) DepositTrie() *trieutil.MerkleTrie {
return s.depositTrie
}
// LatestBlockHeight in the ETH1.0 chain.
func (w *Web3Service) LatestBlockHeight() *big.Int {
return w.blockHeight
func (s *Service) LatestBlockHeight() *big.Int {
return s.blockHeight
}
// LatestBlockHash in the ETH1.0 chain.
func (w *Web3Service) LatestBlockHash() common.Hash {
return w.blockHash
func (s *Service) LatestBlockHash() common.Hash {
return s.blockHash
}
// Client for interacting with the ETH1.0 chain.
func (w *Web3Service) Client() Client {
return w.client
func (s *Service) Client() Client {
return s.client
}
// AreAllDepositsProcessed determines if all the logs from the deposit contract
// are processed.
func (w *Web3Service) AreAllDepositsProcessed() (bool, error) {
w.processingLock.RLock()
defer w.processingLock.RUnlock()
countByte, err := w.depositContractCaller.GetDepositCount(&bind.CallOpts{})
func (s *Service) AreAllDepositsProcessed() (bool, error) {
s.processingLock.RLock()
defer s.processingLock.RUnlock()
countByte, err := s.depositContractCaller.GetDepositCount(&bind.CallOpts{})
if err != nil {
return false, errors.Wrap(err, "could not get deposit count")
}
count := bytesutil.FromBytes8(countByte)
deposits := w.depositCache.AllDeposits(context.TODO(), nil)
deposits := s.depositCache.AllDeposits(context.TODO(), nil)
if count != uint64(len(deposits)) {
return false, nil
}
@@ -279,30 +279,30 @@ func (w *Web3Service) AreAllDepositsProcessed() (bool, error) {
// initDataFromContract calls the deposit contract and finds the deposit count
// and deposit root.
func (w *Web3Service) initDataFromContract() error {
root, err := w.depositContractCaller.GetHashTreeRoot(&bind.CallOpts{})
func (s *Service) initDataFromContract() error {
root, err := s.depositContractCaller.GetHashTreeRoot(&bind.CallOpts{})
if err != nil {
return errors.Wrap(err, "could not retrieve deposit root")
}
w.depositRoot = root[:]
s.depositRoot = root[:]
return nil
}
// processSubscribedHeaders adds a newly observed eth1 block to the block cache and
// updates the latest blockHeight, blockHash, and blockTime properties of the service.
func (w *Web3Service) processSubscribedHeaders(header *gethTypes.Header) {
func (s *Service) processSubscribedHeaders(header *gethTypes.Header) {
defer safelyHandlePanic()
blockNumberGauge.Set(float64(header.Number.Int64()))
w.blockHeight = header.Number
w.blockHash = header.Hash()
w.blockTime = time.Unix(int64(header.Time), 0)
s.blockHeight = header.Number
s.blockHash = header.Hash()
s.blockTime = time.Unix(int64(header.Time), 0)
log.WithFields(logrus.Fields{
"blockNumber": w.blockHeight,
"blockHash": w.blockHash.Hex(),
"blockNumber": s.blockHeight,
"blockHash": s.blockHash.Hex(),
}).Debug("Latest eth1 chain event")
if err := w.blockCache.AddBlock(gethTypes.NewBlockWithHeader(header)); err != nil {
w.runError = err
if err := s.blockCache.AddBlock(gethTypes.NewBlockWithHeader(header)); err != nil {
s.runError = err
log.Errorf("Unable to add block data to cache %v", err)
}
}
@@ -319,49 +319,49 @@ func safelyHandlePanic() {
}
}
func (w *Web3Service) handleDelayTicker() {
func (s *Service) handleDelayTicker() {
defer safelyHandlePanic()
// If the last requested block has not changed,
// we do not request batched logs as this means there are no new
// logs for the powchain service to process.
if w.lastRequestedBlock.Cmp(w.blockHeight) == 0 {
if s.lastRequestedBlock.Cmp(s.blockHeight) == 0 {
return
}
if err := w.requestBatchedLogs(context.Background()); err != nil {
w.runError = err
if err := s.requestBatchedLogs(context.Background()); err != nil {
s.runError = err
log.Error(err)
}
}
// run subscribes to all the services for the ETH1.0 chain.
func (w *Web3Service) run(done <-chan struct{}) {
w.isRunning = true
w.runError = nil
if err := w.initDataFromContract(); err != nil {
func (s *Service) run(done <-chan struct{}) {
s.isRunning = true
s.runError = nil
if err := s.initDataFromContract(); err != nil {
log.Errorf("Unable to retrieve data from deposit contract %v", err)
return
}
headSub, err := w.reader.SubscribeNewHead(w.ctx, w.headerChan)
headSub, err := s.reader.SubscribeNewHead(s.ctx, s.headerChan)
if err != nil {
log.Errorf("Unable to subscribe to incoming ETH1.0 chain headers: %v", err)
w.runError = err
s.runError = err
return
}
header, err := w.blockFetcher.HeaderByNumber(context.Background(), nil)
header, err := s.blockFetcher.HeaderByNumber(context.Background(), nil)
if err != nil {
log.Errorf("Unable to retrieve latest ETH1.0 chain header: %v", err)
w.runError = err
s.runError = err
return
}
w.blockHeight = header.Number
w.blockHash = header.Hash()
s.blockHeight = header.Number
s.blockHash = header.Hash()
if err := w.processPastLogs(context.Background()); err != nil {
if err := s.processPastLogs(context.Background()); err != nil {
log.Errorf("Unable to process past logs %v", err)
w.runError = err
s.runError = err
return
}
@@ -372,19 +372,19 @@ func (w *Web3Service) run(done <-chan struct{}) {
for {
select {
case <-done:
w.isRunning = false
w.runError = nil
s.isRunning = false
s.runError = nil
log.Debug("ETH1.0 chain service context closed, exiting goroutine")
return
case w.runError = <-headSub.Err():
log.Debugf("Unsubscribed to head events, exiting goroutine: %v", w.runError)
case s.runError = <-headSub.Err():
log.Debugf("Unsubscribed to head events, exiting goroutine: %v", s.runError)
return
case header, ok := <-w.headerChan:
case header, ok := <-s.headerChan:
if ok {
w.processSubscribedHeaders(header)
s.processSubscribedHeaders(header)
}
case <-ticker.C:
w.handleDelayTicker()
s.handleDelayTicker()
}
}
}

View File

@@ -97,7 +97,7 @@ func TestNewWeb3Service_OK(t *testing.T) {
endpoint := "http://127.0.0.1"
ctx := context.Background()
var err error
if _, err = NewWeb3Service(ctx, &Web3ServiceConfig{
if _, err = NewService(ctx, &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: common.Address{},
Reader: &goodReader{},
@@ -106,7 +106,7 @@ func TestNewWeb3Service_OK(t *testing.T) {
t.Errorf("passing in an HTTP endpoint should throw an error, received nil")
}
endpoint = "ftp://127.0.0.1"
if _, err = NewWeb3Service(ctx, &Web3ServiceConfig{
if _, err = NewService(ctx, &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: common.Address{},
Reader: &goodReader{},
@@ -115,7 +115,7 @@ func TestNewWeb3Service_OK(t *testing.T) {
t.Errorf("passing in a non-ws, wss, or ipc endpoint should throw an error, received nil")
}
endpoint = "ws://127.0.0.1"
if _, err = NewWeb3Service(ctx, &Web3ServiceConfig{
if _, err = NewService(ctx, &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: common.Address{},
Reader: &goodReader{},
@@ -124,7 +124,7 @@ func TestNewWeb3Service_OK(t *testing.T) {
t.Errorf("passing in as ws endpoint should not throw error, received %v", err)
}
endpoint = "ipc://geth.ipc"
if _, err = NewWeb3Service(ctx, &Web3ServiceConfig{
if _, err = NewService(ctx, &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: common.Address{},
Reader: &goodReader{},
@@ -142,7 +142,7 @@ func TestStart_OK(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -175,7 +175,7 @@ func TestStop_OK(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -212,7 +212,7 @@ func TestInitDataFromContract_OK(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &goodReader{},
@@ -237,7 +237,7 @@ func TestWeb3Service_BadReader(t *testing.T) {
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
Reader: &badReader{},
@@ -267,7 +267,7 @@ func TestStatus(t *testing.T) {
beforeFiveMinutesAgo := now.Add(-5*time.Minute - 30*time.Second)
afterFiveMinutesAgo := now.Add(-5*time.Minute + 30*time.Second)
testCases := map[*Web3Service]string{
testCases := map[*Service]string{
// "status is ok" cases
{}: "",
{isRunning: true, blockTime: afterFiveMinutesAgo}: "",
@@ -296,7 +296,7 @@ func TestStatus(t *testing.T) {
func TestHandlePanic_OK(t *testing.T) {
hook := logTest.NewGlobal()
web3Service, err := NewWeb3Service(context.Background(), &Web3ServiceConfig{
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
Endpoint: endpoint,
BlockFetcher: nil, // nil blockFetcher would panic if cached value not used
})

View File

@@ -78,7 +78,7 @@ go_test(
"//beacon-chain/core/state:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/db/testing:go_default_library",
"//beacon-chain/internal:go_default_library",
"//beacon-chain/rpc/testing:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/beacon/rpc/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",

View File

@@ -12,8 +12,8 @@ import (
"github.com/ethereum/go-ethereum/common"
ptypes "github.com/gogo/protobuf/types"
"github.com/golang/mock/gomock"
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/internal"
mockClient "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
mockRPC "github.com/prysmaticlabs/prysm/beacon-chain/rpc/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
@@ -174,12 +174,12 @@ func TestWaitForChainStart_ContextClosed(t *testing.T) {
powChainService: &faultyPOWChainService{
chainStartFeed: new(event.Feed),
},
chainService: &mock.ChainService{},
chainService: &mockClient.ChainService{},
}
exitRoutine := make(chan bool)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockStream := internal.NewMockBeaconService_WaitForChainStartServer(ctrl)
mockStream := mockRPC.NewMockBeaconService_WaitForChainStartServer(ctrl)
go func(tt *testing.T) {
if err := beaconServer.WaitForChainStart(&ptypes.Empty{}, mockStream); !strings.Contains(err.Error(), closedContext) {
tt.Errorf("Could not call RPC method: %v", err)
@@ -196,11 +196,11 @@ func TestWaitForChainStart_AlreadyStarted(t *testing.T) {
powChainService: &mockPOWChainService{
chainStartFeed: new(event.Feed),
},
chainService: &mock.ChainService{},
chainService: &mockClient.ChainService{},
}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockStream := internal.NewMockBeaconService_WaitForChainStartServer(ctrl)
mockStream := mockRPC.NewMockBeaconService_WaitForChainStartServer(ctrl)
mockStream.EXPECT().Send(
&pb.ChainStartResponse{
Started: true,
@@ -220,12 +220,12 @@ func TestWaitForChainStart_NotStartedThenLogFired(t *testing.T) {
powChainService: &faultyPOWChainService{
chainStartFeed: new(event.Feed),
},
chainService: &mock.ChainService{},
chainService: &mockClient.ChainService{},
}
exitRoutine := make(chan bool)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockStream := internal.NewMockBeaconService_WaitForChainStartServer(ctrl)
mockStream := mockRPC.NewMockBeaconService_WaitForChainStartServer(ctrl)
mockStream.EXPECT().Send(
&pb.ChainStartResponse{
Started: true,

View File

@@ -103,9 +103,9 @@ type Config struct {
DepositCache *depositcache.DepositCache
}
// NewRPCService creates a new instance of a struct implementing the BeaconServiceServer
// interface.
func NewRPCService(ctx context.Context, cfg *Config) *Service {
// NewService instantiates a new RPC service instance that will
// be registered into a running beacon node.
func NewService(ctx context.Context, cfg *Config) *Service {
ctx, cancel := context.WithCancel(ctx)
return &Service{
ctx: ctx,

View File

@@ -90,7 +90,7 @@ func (ms *mockSyncService) Syncing() bool {
func TestLifecycle_OK(t *testing.T) {
hook := logTest.NewGlobal()
rpcService := NewRPCService(context.Background(), &Config{
rpcService := NewService(context.Background(), &Config{
Port: "7348",
CertFlag: "alice.crt",
KeyFlag: "alice.key",
@@ -111,7 +111,7 @@ func TestLifecycle_OK(t *testing.T) {
func TestRPC_BadEndpoint(t *testing.T) {
hook := logTest.NewGlobal()
rpcService := NewRPCService(context.Background(), &Config{
rpcService := NewService(context.Background(), &Config{
Port: "ralph merkle!!!",
SyncService: &mockSyncService{},
ChainService: &mock.ChainService{},
@@ -140,7 +140,7 @@ func TestStatus_CredentialError(t *testing.T) {
func TestRPC_InsecureEndpoint(t *testing.T) {
hook := logTest.NewGlobal()
rpcService := NewRPCService(context.Background(), &Config{
rpcService := NewService(context.Background(), &Config{
Port: "7777",
SyncService: &mockSyncService{},
ChainService: &mock.ChainService{},

View File

@@ -1,14 +1,13 @@
package(default_testonly = True)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
testonly = True,
srcs = [
"beacon_service_mock.go",
"validator_service_mock.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/internal",
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/rpc/testing",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//proto/beacon/rpc/v1:go_default_library",

View File

@@ -14,13 +14,14 @@ import (
"github.com/gogo/protobuf/proto"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/go-ssz"
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
mockChain "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
blk "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/internal"
"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"
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
@@ -78,7 +79,7 @@ func TestNextEpochCommitteeAssignment_WrongPubkeyLength(t *testing.T) {
validatorServer := &ValidatorServer{
beaconDB: db,
chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
}
req := &pb.AssignmentRequest{
PublicKeys: [][]byte{{1}},
@@ -106,7 +107,7 @@ func TestNextEpochCommitteeAssignment_CantFindValidatorIdx(t *testing.T) {
}
vs := &ValidatorServer{
chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
}
pubKey := make([]byte, 96)
@@ -159,7 +160,7 @@ func TestCommitteeAssignment_OK(t *testing.T) {
vs := &ValidatorServer{
beaconDB: db,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
// Test the first validator in registry.
@@ -241,7 +242,7 @@ func TestCommitteeAssignment_CurrentEpoch_ShouldNotFail(t *testing.T) {
vs := &ValidatorServer{
beaconDB: db,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
// Test the first validator in registry.
@@ -295,7 +296,7 @@ func TestCommitteeAssignment_MultipleKeys_OK(t *testing.T) {
vs := &ValidatorServer{
beaconDB: db,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
pubkey0 := deposits[0].Data.PublicKey
@@ -374,7 +375,7 @@ func TestValidatorStatus_PendingActive(t *testing.T) {
},
},
depositCache: depositCache,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
req := &pb.ValidatorIndexRequest{
PublicKey: pubKey,
@@ -447,7 +448,7 @@ func TestValidatorStatus_Active(t *testing.T) {
},
},
depositCache: depositCache,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
req := &pb.ValidatorIndexRequest{
PublicKey: pubKey,
@@ -524,7 +525,7 @@ func TestValidatorStatus_InitiatedExit(t *testing.T) {
},
},
depositCache: depositCache,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
req := &pb.ValidatorIndexRequest{
PublicKey: pubKey,
@@ -591,7 +592,7 @@ func TestValidatorStatus_Withdrawable(t *testing.T) {
},
},
depositCache: depositCache,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
req := &pb.ValidatorIndexRequest{
PublicKey: pubKey,
@@ -658,7 +659,7 @@ func TestValidatorStatus_ExitedSlashed(t *testing.T) {
},
},
depositCache: depositCache,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
req := &pb.ValidatorIndexRequest{
PublicKey: pubKey,
@@ -726,7 +727,7 @@ func TestValidatorStatus_Exited(t *testing.T) {
},
},
depositCache: depositCache,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
req := &pb.ValidatorIndexRequest{
PublicKey: pubKey,
@@ -789,7 +790,7 @@ func TestValidatorStatus_UnknownStatus(t *testing.T) {
},
},
depositCache: depositCache,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
req := &pb.ValidatorIndexRequest{
PublicKey: pubKey,
@@ -828,7 +829,7 @@ func TestWaitForActivation_ContextClosed(t *testing.T) {
powChainService: &mockPOWChainService{},
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
depositCache: depositcache.NewDepositCache(),
chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
}
req := &pb.ValidatorActivationRequest{
PublicKeys: [][]byte{[]byte("A")},
@@ -836,14 +837,14 @@ func TestWaitForActivation_ContextClosed(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockStream := internal.NewMockValidatorService_WaitForActivationServer(ctrl)
mockStream.EXPECT().Context().Return(context.Background())
mockStream.EXPECT().Send(gomock.Any()).Return(nil)
mockStream.EXPECT().Context().Return(context.Background())
mockChainStream := mockRPC.NewMockValidatorService_WaitForActivationServer(ctrl)
mockChainStream.EXPECT().Context().Return(context.Background())
mockChainStream.EXPECT().Send(gomock.Any()).Return(nil)
mockChainStream.EXPECT().Context().Return(context.Background())
exitRoutine := make(chan bool)
go func(tt *testing.T) {
want := "context closed"
if err := vs.WaitForActivation(req, mockStream); !strings.Contains(err.Error(), want) {
if err := vs.WaitForActivation(req, mockChainStream); !strings.Contains(err.Error(), want) {
tt.Errorf("Could not call RPC method: %v", err)
}
<-exitRoutine
@@ -930,7 +931,7 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) {
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
powChainService: &mockPOWChainService{},
depositCache: depositCache,
chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
}
req := &pb.ValidatorActivationRequest{
PublicKeys: [][]byte{pubKey1, pubKey2},
@@ -938,9 +939,9 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockStream := internal.NewMockValidatorService_WaitForActivationServer(ctrl)
mockStream.EXPECT().Context().Return(context.Background())
mockStream.EXPECT().Send(
mockChainStream := internal.NewMockValidatorService_WaitForActivationServer(ctrl)
mockChainStream.EXPECT().Context().Return(context.Background())
mockChainStream.EXPECT().Send(
&pb.ValidatorActivationResponse{
Statuses: []*pb.ValidatorActivationResponse_Status{
{PublicKey: pubKey1,
@@ -960,7 +961,7 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) {
},
).Return(nil)
if err := vs.WaitForActivation(req, mockStream); err != nil {
if err := vs.WaitForActivation(req, mockChainStream); err != nil {
t.Fatalf("Could not setup wait for activation stream: %v", err)
}
}
@@ -1043,7 +1044,7 @@ func TestMultipleValidatorStatus_OK(t *testing.T) {
canonicalStateChan: make(chan *pbp2p.BeaconState, 1),
powChainService: &mockPOWChainService{},
depositCache: depositCache,
chainService: &mock.ChainService{State: beaconState, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
}
activeExists, response, err := vs.MultipleValidatorStatus(context.Background(), pubKeys)
if err != nil {
@@ -1108,7 +1109,7 @@ func BenchmarkAssignment(b *testing.B) {
vs := &ValidatorServer{
beaconDB: db,
chainService: &mock.ChainService{State: state, Root: genesisRoot[:]},
chainService: &mockChain.ChainService{State: state, Root: genesisRoot[:]},
}
// Set up request for 100 public keys at a time