mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
Clean up post --next (#3411)
* Delete old code * RPC mock testing * Fixed BUILD * Conflict * Lint * More lint
This commit is contained in:
committed by
Raul Jordan
parent
fb20fc7881
commit
4235980511
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 := ðpb.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")
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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())))
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 := ðpb.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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 ðpb.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 := ðpb.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
|
||||
}
|
||||
|
||||
@@ -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 := ðpb.BeaconBlockBody{
|
||||
Eth1Data: ðpb.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 := ðpb.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 := ðpb.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 := ðpb.BeaconBlockHeader{
|
||||
Slot: 10,
|
||||
Signature: []byte{'S'},
|
||||
ParentRoot: []byte("Parent"),
|
||||
StateRoot: []byte("State"),
|
||||
}
|
||||
|
||||
block := BlockFromHeader(dummyHeader)
|
||||
|
||||
expectedBlock := ðpb.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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 := ðpb.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: ðpb.Eth1Data{
|
||||
DepositRoot: []byte{2},
|
||||
BlockHash: []byte{3},
|
||||
},
|
||||
}
|
||||
db := &mockDB{
|
||||
hasBlock: true,
|
||||
}
|
||||
powClient := &mockPOWClient{
|
||||
blockExists: true,
|
||||
}
|
||||
block := ðpb.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 := ðpb.BeaconBlock{
|
||||
Slot: 4,
|
||||
}
|
||||
|
||||
genesisTime := time.Unix(0, 0)
|
||||
|
||||
db.hasBlock = true
|
||||
block.Slot = 4
|
||||
powClient.blockExists = false
|
||||
beaconState.Eth1Data = ðpb.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 = ðpb.Eth1Data{
|
||||
DepositRoot: []byte{2},
|
||||
BlockHash: []byte{3},
|
||||
}
|
||||
|
||||
genesisTime := time.Unix(0, 0)
|
||||
block := ðpb.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 = ðpb.Eth1Data{
|
||||
DepositRoot: []byte{2},
|
||||
BlockHash: []byte{3},
|
||||
}
|
||||
|
||||
genesisTime := time.Unix(0, 0)
|
||||
|
||||
block := ðpb.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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] = ðpb.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: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0x05},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 5,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 5,
|
||||
},
|
||||
{
|
||||
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0x06},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 10,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 10,
|
||||
},
|
||||
{
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0x06},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 20,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 20,
|
||||
},
|
||||
{
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0xFF, 0xC0, 0x01},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 5,
|
||||
},
|
||||
Target: ðpb.Checkpoint{},
|
||||
},
|
||||
},
|
||||
stateSlot: 5,
|
||||
errorExists: true,
|
||||
},
|
||||
{
|
||||
attestation: ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0xFF, 0x01},
|
||||
Data: ðpb.AttestationData{
|
||||
Crosslink: ðpb.Crosslink{
|
||||
Shard: 20,
|
||||
},
|
||||
Target: ðpb.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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 := ðpb.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 := ðpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 100, BlockHash: []byte{10}}
|
||||
ed2 := ðpb.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 := ðpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 100, BlockHash: []byte{10}}
|
||||
ed2 := ðpb.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 := ðpb.Eth1Data{DepositRoot: []byte{1}, DepositCount: 100, BlockHash: []byte{10}}
|
||||
ed2 := ðpb.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,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
//
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 := ðpb.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++ {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{},
|
||||
|
||||
@@ -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 := ðpb.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 = ðpb.Eth1Data{
|
||||
DepositCount: uint64(len(w.chainStartDeposits)),
|
||||
s.chainStartETH1Data = ðpb.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
|
||||
|
||||
@@ -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{},
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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{},
|
||||
|
||||
@@ -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",
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user