mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 13:58:09 -05:00
Compare commits
4 Commits
process-ex
...
old-clock-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a4adba3ae | ||
|
|
eb2303f02f | ||
|
|
cd7fd7ebb6 | ||
|
|
c10cbd9291 |
@@ -4,6 +4,7 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
"chain_info.go",
|
"chain_info.go",
|
||||||
|
"clock.go",
|
||||||
"error.go",
|
"error.go",
|
||||||
"execution_engine.go",
|
"execution_engine.go",
|
||||||
"head.go",
|
"head.go",
|
||||||
@@ -52,6 +53,7 @@ go_library(
|
|||||||
"//beacon-chain/forkchoice/doubly-linked-tree:go_default_library",
|
"//beacon-chain/forkchoice/doubly-linked-tree:go_default_library",
|
||||||
"//beacon-chain/forkchoice/protoarray:go_default_library",
|
"//beacon-chain/forkchoice/protoarray:go_default_library",
|
||||||
"//beacon-chain/forkchoice/types:go_default_library",
|
"//beacon-chain/forkchoice/types:go_default_library",
|
||||||
|
"//beacon-chain/geninit:go_default_library",
|
||||||
"//beacon-chain/operations/attestations:go_default_library",
|
"//beacon-chain/operations/attestations:go_default_library",
|
||||||
"//beacon-chain/operations/slashings:go_default_library",
|
"//beacon-chain/operations/slashings:go_default_library",
|
||||||
"//beacon-chain/operations/voluntaryexits:go_default_library",
|
"//beacon-chain/operations/voluntaryexits:go_default_library",
|
||||||
@@ -59,7 +61,6 @@ go_library(
|
|||||||
"//beacon-chain/powchain:go_default_library",
|
"//beacon-chain/powchain:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/stategen:go_default_library",
|
"//beacon-chain/state/stategen:go_default_library",
|
||||||
"//cmd/beacon-chain/flags:go_default_library",
|
|
||||||
"//config/features:go_default_library",
|
"//config/features:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ type ChainInfoFetcher interface {
|
|||||||
GenesisFetcher
|
GenesisFetcher
|
||||||
CanonicalFetcher
|
CanonicalFetcher
|
||||||
ForkFetcher
|
ForkFetcher
|
||||||
TimeFetcher
|
|
||||||
HeadDomainFetcher
|
HeadDomainFetcher
|
||||||
|
ClockProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// HeadUpdater defines a common interface for methods in blockchain service
|
// HeadUpdater defines a common interface for methods in blockchain service
|
||||||
@@ -37,9 +37,7 @@ type HeadUpdater interface {
|
|||||||
UpdateHead(context.Context) error
|
UpdateHead(context.Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimeFetcher retrieves the Ethereum consensus data that's related to time.
|
type CurrentSlotter interface {
|
||||||
type TimeFetcher interface {
|
|
||||||
GenesisTime() time.Time
|
|
||||||
CurrentSlot() types.Slot
|
CurrentSlot() types.Slot
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,11 +218,6 @@ func (s *Service) HeadETH1Data() *ethpb.Eth1Data {
|
|||||||
return s.head.state.Eth1Data()
|
return s.head.state.Eth1Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenesisTime returns the genesis time of beacon chain.
|
|
||||||
func (s *Service) GenesisTime() time.Time {
|
|
||||||
return s.genesisTime
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenesisValidatorsRoot returns the genesis validators
|
// GenesisValidatorsRoot returns the genesis validators
|
||||||
// root of the chain.
|
// root of the chain.
|
||||||
func (s *Service) GenesisValidatorsRoot() [32]byte {
|
func (s *Service) GenesisValidatorsRoot() [32]byte {
|
||||||
@@ -370,10 +363,44 @@ func (s *Service) IsOptimisticForRoot(ctx context.Context, root [32]byte) (bool,
|
|||||||
|
|
||||||
// SetGenesisTime sets the genesis time of beacon chain.
|
// SetGenesisTime sets the genesis time of beacon chain.
|
||||||
func (s *Service) SetGenesisTime(t time.Time) {
|
func (s *Service) SetGenesisTime(t time.Time) {
|
||||||
s.genesisTime = t
|
s.clock = NewClock(t)
|
||||||
|
close(s.clockReady)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) setClock(c Clock) {
|
||||||
|
s.clock = c
|
||||||
|
close(s.clockReady)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) genesisTime() time.Time {
|
||||||
|
c, err := s.WaitForClock(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return c.GenesisTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForkChoiceStore returns the fork choice store in the service.
|
// ForkChoiceStore returns the fork choice store in the service.
|
||||||
func (s *Service) ForkChoiceStore() forkchoice.ForkChoicer {
|
func (s *Service) ForkChoiceStore() forkchoice.ForkChoicer {
|
||||||
return s.cfg.ForkChoiceStore
|
return s.cfg.ForkChoiceStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClockProvider implements WaitForClock, yielding a clock type that can be used to get
|
||||||
|
// the genesis time, slot values derived from genesis, or a possibly synthetic time.Now value
|
||||||
|
type ClockProvider interface {
|
||||||
|
WaitForClock(context.Context) (Clock, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForClock will block until the Clock is ready. This provides a syncronization mechanism for services that
|
||||||
|
// need the clock to be available before they can start running.
|
||||||
|
func (s *Service) WaitForClock(ctx context.Context) (Clock, error) {
|
||||||
|
if s.clockReady != nil {
|
||||||
|
select {
|
||||||
|
case <-s.clockReady:
|
||||||
|
return s.clock, nil
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s.clock, nil
|
||||||
|
}
|
||||||
@@ -28,7 +28,6 @@ import (
|
|||||||
|
|
||||||
// Ensure Service implements chain info interface.
|
// Ensure Service implements chain info interface.
|
||||||
var _ ChainInfoFetcher = (*Service)(nil)
|
var _ ChainInfoFetcher = (*Service)(nil)
|
||||||
var _ TimeFetcher = (*Service)(nil)
|
|
||||||
var _ ForkFetcher = (*Service)(nil)
|
var _ ForkFetcher = (*Service)(nil)
|
||||||
|
|
||||||
// prepareForkchoiceState prepares a beacon state with the given data to mock
|
// prepareForkchoiceState prepares a beacon state with the given data to mock
|
||||||
@@ -202,9 +201,9 @@ func TestHeadState_CanRetrieve(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGenesisTime_CanRetrieve(t *testing.T) {
|
func TestGenesisTime_CanRetrieve(t *testing.T) {
|
||||||
c := &Service{genesisTime: time.Unix(999, 0)}
|
c := &Service{clock: NewClock(time.Unix(999, 0))}
|
||||||
wanted := time.Unix(999, 0)
|
wanted := time.Unix(999, 0)
|
||||||
assert.Equal(t, wanted, c.GenesisTime(), "Did not get wanted genesis time")
|
assert.Equal(t, wanted, c.genesisTime(), "Did not get wanted genesis time")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCurrentFork_CanRetrieve(t *testing.T) {
|
func TestCurrentFork_CanRetrieve(t *testing.T) {
|
||||||
@@ -304,6 +303,7 @@ func TestService_HeadGenesisValidatorsRoot(t *testing.T) {
|
|||||||
root = c.HeadGenesisValidatorsRoot()
|
root = c.HeadGenesisValidatorsRoot()
|
||||||
require.DeepEqual(t, root[:], s.GenesisValidatorsRoot())
|
require.DeepEqual(t, root[:], s.GenesisValidatorsRoot())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestService_ChainHeads_ProtoArray(t *testing.T) {
|
func TestService_ChainHeads_ProtoArray(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
c := &Service{cfg: &config{ForkChoiceStore: protoarray.New()}}
|
c := &Service{cfg: &config{ForkChoiceStore: protoarray.New()}}
|
||||||
@@ -474,7 +474,7 @@ func TestService_IsOptimistic_DoublyLinkedTree(t *testing.T) {
|
|||||||
|
|
||||||
func TestService_IsOptimisticBeforeBellatrix(t *testing.T) {
|
func TestService_IsOptimisticBeforeBellatrix(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
c := &Service{genesisTime: time.Now()}
|
c := &Service{clock: NewClock(time.Now())}
|
||||||
opt, err := c.IsOptimistic(ctx)
|
opt, err := c.IsOptimistic(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, false, opt)
|
require.Equal(t, false, opt)
|
||||||
|
|||||||
69
beacon-chain/blockchain/clock.go
Normal file
69
beacon-chain/blockchain/clock.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package blockchain
|
||||||
|
|
||||||
|
import (
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clock abstracts important time-related concerns in the beacon chain:
|
||||||
|
// - genesis time
|
||||||
|
// - provides a time.Now() construct that can be overriden in tests
|
||||||
|
// - syncronization point for code that needs to know the genesis time
|
||||||
|
// - CurrentSlot: convenience conversion for current time -> slot
|
||||||
|
// - support backwards compatibility with the TimeFetcher interface
|
||||||
|
type Clock interface {
|
||||||
|
GenesisTime() time.Time
|
||||||
|
CurrentSlot() types.Slot
|
||||||
|
Now() time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// clock is a type that fulfills the TimeFetcher interface. This can be used in a number of places where
|
||||||
|
// blockchain.ChainInfoFetcher has historically been used.
|
||||||
|
type clock struct {
|
||||||
|
time.Time
|
||||||
|
now Now
|
||||||
|
}
|
||||||
|
var _ Clock = &clock{}
|
||||||
|
|
||||||
|
// clock provides an accessor to the embedded time, also fulfilling the blockchain.TimeFetcher interface.
|
||||||
|
func (gt clock) GenesisTime() time.Time {
|
||||||
|
return gt.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentSlot returns the current slot relative to the time.Time value clock embeds.
|
||||||
|
func (gt clock) CurrentSlot() types.Slot {
|
||||||
|
return slots.Duration(gt.Time, gt.now())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now provides a value for time.Now() that can be overriden in tests.
|
||||||
|
func (gt clock) Now() time.Time {
|
||||||
|
return gt.now()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClockOpt is a functional option to change the behavior of a clock value made by NewClock.
|
||||||
|
// It is primarily intended as a way to inject an alternate time.Now() callback (WithNow) for testing.
|
||||||
|
type ClockOpt func(*clock)
|
||||||
|
|
||||||
|
// WithNow allows tests in particular to inject an alternate implementation of time.Now (vs using system time)
|
||||||
|
func WithNow(n Now) ClockOpt {
|
||||||
|
return func(gt *clock) {
|
||||||
|
gt.now = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClock constructs a clock value using the given time value. Optional ClockOpt can be provided.
|
||||||
|
// If an implementation of the Now function type is not provided (via WithNow), time.Now (system time) will be used by default.
|
||||||
|
func NewClock(t time.Time, opts ...ClockOpt) clock {
|
||||||
|
gt := clock{Time: t}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(>)
|
||||||
|
}
|
||||||
|
if gt.now == nil {
|
||||||
|
gt.now = time.Now
|
||||||
|
}
|
||||||
|
return gt
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now is a function that can return the current time. This will be time.Now by default, but can be overridden for tests.
|
||||||
|
type Now func() time.Time
|
||||||
31
beacon-chain/blockchain/clock_test.go
Normal file
31
beacon-chain/blockchain/clock_test.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package blockchain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClock_GenesisTime(t *testing.T) {
|
||||||
|
n := time.Now()
|
||||||
|
gt := NewClock(n)
|
||||||
|
gtt := gt.GenesisTime()
|
||||||
|
require.Equal(t, gt.Time, gtt)
|
||||||
|
require.Equal(t, n, gtt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithNow(t *testing.T) {
|
||||||
|
genUnix := time.Unix(0, 0)
|
||||||
|
var expectedSlots uint64 = 7200 // a day worth of slots
|
||||||
|
now := genUnix.Add(time.Second * time.Duration(params.BeaconConfig().SecondsPerSlot * expectedSlots))
|
||||||
|
fn := func() time.Time {
|
||||||
|
return now
|
||||||
|
}
|
||||||
|
|
||||||
|
gt := NewClock(genUnix, WithNow(fn))
|
||||||
|
// in this scenario, "genesis" is exactly 24 hours before "now"
|
||||||
|
// so "now" should be 7200 slots after "genesis"
|
||||||
|
require.Equal(t, types.Slot(expectedSlots), gt.CurrentSlot())
|
||||||
|
}
|
||||||
@@ -315,7 +315,7 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get timestamp.
|
// Get timestamp.
|
||||||
t, err := slots.ToTime(uint64(s.genesisTime.Unix()), slot)
|
t, err := slots.ToTime(uint64(s.genesisTime().Unix()), slot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, 0, err
|
return false, nil, 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -535,7 +535,7 @@ func Test_NotifyNewPayload(t *testing.T) {
|
|||||||
service, err := NewService(ctx, opts...)
|
service, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
st := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epochsSinceFinalitySaveHotStateDB))
|
st := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epochsSinceFinalitySaveHotStateDB))
|
||||||
service.genesisTime = time.Now().Add(time.Duration(-1*int64(st)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
service.SetGenesisTime(time.Now().Add(time.Duration(-1*int64(st)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second))
|
||||||
r, err := bellatrixBlk.Block().HashTreeRoot()
|
r, err := bellatrixBlk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
ojc := ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
ojc := ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||||
@@ -800,7 +800,7 @@ func Test_IsOptimisticCandidateBlock(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
params.BeaconConfig().SafeSlotsToImportOptimistically = 128
|
params.BeaconConfig().SafeSlotsToImportOptimistically = 128
|
||||||
service.genesisTime = time.Now().Add(-time.Second * 12 * 2 * 128)
|
service.SetGenesisTime(time.Now().Add(-time.Second * 12 * 2 * 128))
|
||||||
|
|
||||||
parentBlk := util.NewBeaconBlockBellatrix()
|
parentBlk := util.NewBeaconBlockBellatrix()
|
||||||
wrappedParentBlock, err := wrapper.WrappedSignedBeaconBlock(parentBlk)
|
wrappedParentBlock, err := wrapper.WrappedSignedBeaconBlock(parentBlk)
|
||||||
@@ -903,7 +903,7 @@ func Test_IsOptimisticShallowExecutionParent(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
params.BeaconConfig().SafeSlotsToImportOptimistically = 128
|
params.BeaconConfig().SafeSlotsToImportOptimistically = 128
|
||||||
service.genesisTime = time.Now().Add(-time.Second * 12 * 2 * 128)
|
service.SetGenesisTime(time.Now().Add(-time.Second * 12 * 2 * 128))
|
||||||
payload := &v1.ExecutionPayload{
|
payload := &v1.ExecutionPayload{
|
||||||
ParentHash: make([]byte, 32),
|
ParentHash: make([]byte, 32),
|
||||||
FeeRecipient: make([]byte, 20),
|
FeeRecipient: make([]byte, 20),
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ func TestSaveOrphanedAtts_NoCommonAncestor(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
beaconDB := testDB.SetupDB(t)
|
beaconDB := testDB.SetupDB(t)
|
||||||
service := setupBeaconChain(t, beaconDB)
|
service := setupBeaconChain(t, beaconDB)
|
||||||
service.genesisTime = time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
service.SetGenesisTime(time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second))
|
||||||
|
|
||||||
// Chain setup
|
// Chain setup
|
||||||
// 0 -- 1 -- 2 -- 3
|
// 0 -- 1 -- 2 -- 3
|
||||||
@@ -273,7 +273,7 @@ func TestSaveOrphanedAtts(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
beaconDB := testDB.SetupDB(t)
|
beaconDB := testDB.SetupDB(t)
|
||||||
service := setupBeaconChain(t, beaconDB)
|
service := setupBeaconChain(t, beaconDB)
|
||||||
service.genesisTime = time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
service.SetGenesisTime(time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second))
|
||||||
|
|
||||||
// Chain setup
|
// Chain setup
|
||||||
// 0 -- 1 -- 2 -- 3
|
// 0 -- 1 -- 2 -- 3
|
||||||
@@ -339,7 +339,7 @@ func TestSaveOrphanedAtts_CanFilter(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
beaconDB := testDB.SetupDB(t)
|
beaconDB := testDB.SetupDB(t)
|
||||||
service := setupBeaconChain(t, beaconDB)
|
service := setupBeaconChain(t, beaconDB)
|
||||||
service.genesisTime = time.Now().Add(time.Duration(-1*int64(params.BeaconConfig().SlotsPerEpoch+2)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
service.SetGenesisTime(time.Now().Add(time.Duration(-1*int64(params.BeaconConfig().SlotsPerEpoch+2)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second))
|
||||||
|
|
||||||
// Chain setup
|
// Chain setup
|
||||||
// 0 -- 1 -- 2
|
// 0 -- 1 -- 2
|
||||||
@@ -393,7 +393,7 @@ func TestSaveOrphanedAtts_NoCommonAncestor_DoublyLinkedTrie(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
beaconDB := testDB.SetupDB(t)
|
beaconDB := testDB.SetupDB(t)
|
||||||
service := setupBeaconChain(t, beaconDB)
|
service := setupBeaconChain(t, beaconDB)
|
||||||
service.genesisTime = time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
service.SetGenesisTime(time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second))
|
||||||
|
|
||||||
// Chain setup
|
// Chain setup
|
||||||
// 0 -- 1 -- 2 -- 3
|
// 0 -- 1 -- 2 -- 3
|
||||||
@@ -452,7 +452,7 @@ func TestSaveOrphanedAtts_DoublyLinkedTrie(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
beaconDB := testDB.SetupDB(t)
|
beaconDB := testDB.SetupDB(t)
|
||||||
service := setupBeaconChain(t, beaconDB)
|
service := setupBeaconChain(t, beaconDB)
|
||||||
service.genesisTime = time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
service.SetGenesisTime(time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second))
|
||||||
|
|
||||||
// Chain setup
|
// Chain setup
|
||||||
// 0 -- 1 -- 2 -- 3
|
// 0 -- 1 -- 2 -- 3
|
||||||
@@ -522,7 +522,7 @@ func TestSaveOrphanedAtts_CanFilter_DoublyLinkedTrie(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
beaconDB := testDB.SetupDB(t)
|
beaconDB := testDB.SetupDB(t)
|
||||||
service := setupBeaconChain(t, beaconDB)
|
service := setupBeaconChain(t, beaconDB)
|
||||||
service.genesisTime = time.Now().Add(time.Duration(-1*int64(params.BeaconConfig().SlotsPerEpoch+2)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
service.SetGenesisTime(time.Now().Add(time.Duration(-1*int64(params.BeaconConfig().SlotsPerEpoch+2)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second))
|
||||||
|
|
||||||
// Chain setup
|
// Chain setup
|
||||||
// 0 -- 1 -- 2
|
// 0 -- 1 -- 2
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func TestService_getBlock(t *testing.T) {
|
|||||||
// block in cache
|
// block in cache
|
||||||
b, err := wrapper.WrappedSignedBeaconBlock(b1)
|
b, err := wrapper.WrappedSignedBeaconBlock(b1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.saveInitSyncBlock(ctx, r1, b)
|
require.NoError(t, s.saveInitSyncBlock(ctx, r1, b))
|
||||||
got, err := s.getBlock(ctx, r1)
|
got, err := s.getBlock(ctx, r1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.DeepEqual(t, b, got)
|
require.DeepEqual(t, b, got)
|
||||||
@@ -59,7 +59,7 @@ func TestService_hasBlockInInitSyncOrDB(t *testing.T) {
|
|||||||
// block in cache
|
// block in cache
|
||||||
b, err := wrapper.WrappedSignedBeaconBlock(b1)
|
b, err := wrapper.WrappedSignedBeaconBlock(b1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.saveInitSyncBlock(ctx, r1, b)
|
require.NoError(t, s.saveInitSyncBlock(ctx, r1, b))
|
||||||
require.Equal(t, true, s.hasBlockInInitSyncOrDB(ctx, r1))
|
require.Equal(t, true, s.hasBlockInInitSyncOrDB(ctx, r1))
|
||||||
|
|
||||||
// block in db
|
// block in db
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func (s *Service) OnAttestation(ctx context.Context, a *ethpb.Attestation) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
genesisTime := uint64(s.genesisTime.Unix())
|
genesisTime := uint64(s.genesisTime().Unix())
|
||||||
|
|
||||||
// Verify attestation target is from current epoch or previous epoch.
|
// Verify attestation target is from current epoch or previous epoch.
|
||||||
if err := verifyAttTargetEpoch(ctx, genesisTime, uint64(time.Now().Unix()), tgt); err != nil {
|
if err := verifyAttTargetEpoch(ctx, genesisTime, uint64(time.Now().Unix()), tgt); err != nil {
|
||||||
|
|||||||
@@ -132,8 +132,12 @@ func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlo
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState); err != nil {
|
|
||||||
return err
|
if err := s.cfg.BeaconDB.SaveBlock(ctx, signed); err != nil {
|
||||||
|
return errors.Wrapf(err, "could not save block from slot %d", signed.Block().Slot())
|
||||||
|
}
|
||||||
|
if err := s.cfg.StateGen.SaveState(ctx, blockRoot, postState); err != nil {
|
||||||
|
return errors.Wrap(err, "could not save state")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, signed.Block(), blockRoot, postState); err != nil {
|
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, signed.Block(), blockRoot, postState); err != nil {
|
||||||
@@ -538,20 +542,6 @@ func (s *Service) InsertSlashingsToForkChoiceStore(ctx context.Context, slashing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This saves post state info to DB or cache. This also saves post state info to fork choice store.
|
|
||||||
// Post state info consists of processed block and state. Do not call this method unless the block and state are verified.
|
|
||||||
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interfaces.SignedBeaconBlock, st state.BeaconState) error {
|
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.savePostStateInfo")
|
|
||||||
defer span.End()
|
|
||||||
if err := s.cfg.BeaconDB.SaveBlock(ctx, b); err != nil {
|
|
||||||
return errors.Wrapf(err, "could not save block from slot %d", b.Block().Slot())
|
|
||||||
}
|
|
||||||
if err := s.cfg.StateGen.SaveState(ctx, r, st); err != nil {
|
|
||||||
return errors.Wrap(err, "could not save state")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// This removes the attestations from the mem pool. It will only remove the attestations if input root `r` is canonical,
|
// This removes the attestations from the mem pool. It will only remove the attestations if input root `r` is canonical,
|
||||||
// meaning the block `b` is part of the canonical chain.
|
// meaning the block `b` is part of the canonical chain.
|
||||||
func (s *Service) pruneCanonicalAttsFromPool(ctx context.Context, r [32]byte, b interfaces.SignedBeaconBlock) error {
|
func (s *Service) pruneCanonicalAttsFromPool(ctx context.Context, r [32]byte, b interfaces.SignedBeaconBlock) error {
|
||||||
|
|||||||
@@ -24,7 +24,11 @@ import (
|
|||||||
|
|
||||||
// CurrentSlot returns the current slot based on time.
|
// CurrentSlot returns the current slot based on time.
|
||||||
func (s *Service) CurrentSlot() types.Slot {
|
func (s *Service) CurrentSlot() types.Slot {
|
||||||
return slots.CurrentSlot(uint64(s.genesisTime.Unix()))
|
c, err := s.WaitForClock(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return c.CurrentSlot()
|
||||||
}
|
}
|
||||||
|
|
||||||
// getBlockPreState returns the pre state of an incoming block. It uses the parent root of the block
|
// getBlockPreState returns the pre state of an incoming block. It uses the parent root of the block
|
||||||
@@ -48,7 +52,7 @@ func (s *Service) getBlockPreState(ctx context.Context, b interfaces.BeaconBlock
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify block slot time is not from the future.
|
// Verify block slot time is not from the future.
|
||||||
if err := slots.VerifyTime(uint64(s.genesisTime.Unix()), b.Slot(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
if err := slots.VerifyTime(uint64(s.genesisTime().Unix()), b.Slot(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -873,7 +873,7 @@ func blockTree1(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][]byt
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCurrentSlot_HandlesOverflow(t *testing.T) {
|
func TestCurrentSlot_HandlesOverflow(t *testing.T) {
|
||||||
svc := Service{genesisTime: prysmTime.Now().Add(1 * time.Hour)}
|
svc := Service{clock: NewClock(prysmTime.Now().Add(1 * time.Hour))}
|
||||||
|
|
||||||
slot := svc.CurrentSlot()
|
slot := svc.CurrentSlot()
|
||||||
require.Equal(t, types.Slot(0), slot, "Unexpected slot")
|
require.Equal(t, types.Slot(0), slot, "Unexpected slot")
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/prysm/async/event"
|
"github.com/prysmaticlabs/prysm/async/event"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||||
@@ -38,7 +36,7 @@ func (s *Service) AttestationTargetState(ctx context.Context, target *ethpb.Chec
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := slots.ValidateClock(ss, uint64(s.genesisTime.Unix())); err != nil {
|
if err := slots.ValidateClock(ss, uint64(s.genesisTime().Unix())); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return s.getAttPreState(ctx, target)
|
return s.getAttPreState(ctx, target)
|
||||||
@@ -102,19 +100,14 @@ func (s *Service) spawnProcessAttestationsRoutine(stateFeed *event.Feed) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.genesisTime.IsZero() {
|
log.Warn("ProcessAttestations routine waiting for genesis time")
|
||||||
log.Warn("ProcessAttestations routine waiting for genesis time")
|
c, err := s.WaitForClock(s.ctx)
|
||||||
for s.genesisTime.IsZero() {
|
if err != nil {
|
||||||
if err := s.ctx.Err(); err != nil {
|
log.WithError(err).Error("timeout waiting for genesis time in spawnProcessAttestationsRoutine")
|
||||||
log.WithError(err).Error("Giving up waiting for genesis time")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
}
|
|
||||||
log.Warn("Genesis time received, now available to process attestations")
|
|
||||||
}
|
}
|
||||||
|
log.Warn("Genesis time received, now available to process attestations")
|
||||||
|
|
||||||
st := slots.NewSlotTicker(s.genesisTime, params.BeaconConfig().SecondsPerSlot)
|
st := slots.NewSlotTicker(c.GenesisTime(), params.BeaconConfig().SecondsPerSlot)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-s.ctx.Done():
|
case <-s.ctx.Done():
|
||||||
@@ -219,7 +212,7 @@ func (s *Service) processAttestations(ctx context.Context) {
|
|||||||
// This delays consideration in the fork choice until their slot is in the past.
|
// This delays consideration in the fork choice until their slot is in the past.
|
||||||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/fork-choice.md#validate_on_attestation
|
// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/fork-choice.md#validate_on_attestation
|
||||||
nextSlot := a.Data.Slot + 1
|
nextSlot := a.Data.Slot + 1
|
||||||
if err := slots.VerifyTime(uint64(s.genesisTime.Unix()), nextSlot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
if err := slots.VerifyTime(uint64(s.genesisTime().Unix()), nextSlot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +226,7 @@ func (s *Service) processAttestations(ctx context.Context) {
|
|||||||
log.WithError(err).Error("Could not delete fork choice attestation in pool")
|
log.WithError(err).Error("Could not delete fork choice attestation in pool")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !helpers.VerifyCheckpointEpoch(a.Data.Target, s.genesisTime) {
|
if !helpers.VerifyCheckpointEpoch(a.Data.Target, s.genesisTime()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func TestAttestationCheckPtState_FarFutureSlot(t *testing.T) {
|
|||||||
beaconDB := testDB.SetupDB(t)
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
|
||||||
chainService := setupBeaconChain(t, beaconDB)
|
chainService := setupBeaconChain(t, beaconDB)
|
||||||
chainService.genesisTime = time.Now()
|
chainService.SetGenesisTime(time.Now())
|
||||||
|
|
||||||
e := types.Epoch(slots.MaxSlotBuffer/uint64(params.BeaconConfig().SlotsPerEpoch) + 1)
|
e := types.Epoch(slots.MaxSlotBuffer/uint64(params.BeaconConfig().SlotsPerEpoch) + 1)
|
||||||
_, err := chainService.AttestationTargetState(context.Background(), ðpb.Checkpoint{Epoch: e})
|
_, err := chainService.AttestationTargetState(context.Background(), ðpb.Checkpoint{Epoch: e})
|
||||||
@@ -102,7 +102,7 @@ func TestProcessAttestations_Ok(t *testing.T) {
|
|||||||
|
|
||||||
service, err := NewService(ctx, opts...)
|
service, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.genesisTime = prysmTime.Now().Add(-1 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
|
service.SetGenesisTime(prysmTime.Now().Add(-1 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second))
|
||||||
genesisState, pks := util.DeterministicGenesisState(t, 64)
|
genesisState, pks := util.DeterministicGenesisState(t, 64)
|
||||||
require.NoError(t, genesisState.SetGenesisTime(uint64(prysmTime.Now().Unix())-params.BeaconConfig().SecondsPerSlot))
|
require.NoError(t, genesisState.SetGenesisTime(uint64(prysmTime.Now().Unix())-params.BeaconConfig().SecondsPerSlot))
|
||||||
require.NoError(t, service.saveGenesisData(ctx, genesisState))
|
require.NoError(t, service.saveGenesisData(ctx, genesisState))
|
||||||
@@ -209,7 +209,7 @@ func TestService_ProcessAttestationsAndUpdateHead(t *testing.T) {
|
|||||||
|
|
||||||
service, err := NewService(ctx, opts...)
|
service, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.genesisTime = prysmTime.Now().Add(-2 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
|
service.SetGenesisTime(prysmTime.Now().Add(-2 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second))
|
||||||
genesisState, pks := util.DeterministicGenesisState(t, 64)
|
genesisState, pks := util.DeterministicGenesisState(t, 64)
|
||||||
require.NoError(t, service.saveGenesisData(ctx, genesisState))
|
require.NoError(t, service.saveGenesisData(ctx, genesisState))
|
||||||
copied := genesisState.Copy()
|
copied := genesisState.Copy()
|
||||||
|
|||||||
@@ -7,17 +7,12 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/time"
|
"github.com/prysmaticlabs/prysm/time"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This defines how many epochs since finality the run time will begin to save hot state on to the DB.
|
|
||||||
var epochsSinceFinalitySaveHotStateDB = types.Epoch(100)
|
|
||||||
|
|
||||||
// BlockReceiver interface defines the methods of chain service for receiving and processing new blocks.
|
// BlockReceiver interface defines the methods of chain service for receiving and processing new blocks.
|
||||||
type BlockReceiver interface {
|
type BlockReceiver interface {
|
||||||
ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error
|
ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error
|
||||||
@@ -53,18 +48,13 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaco
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have we been finalizing? Should we start saving hot states to db?
|
|
||||||
if err := s.checkSaveHotStateDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reports on block and fork choice metrics.
|
// Reports on block and fork choice metrics.
|
||||||
finalized := s.FinalizedCheckpt()
|
finalized := s.FinalizedCheckpt()
|
||||||
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), finalized)
|
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), finalized)
|
||||||
|
|
||||||
// Log block sync status.
|
// Log block sync status.
|
||||||
justified := s.CurrentJustifiedCheckpt()
|
justified := s.CurrentJustifiedCheckpt()
|
||||||
if err := logBlockSyncStatus(blockCopy.Block(), blockRoot, justified, finalized, receivedTime, uint64(s.genesisTime.Unix())); err != nil {
|
if err := logBlockSyncStatus(blockCopy.Block(), blockRoot, justified, finalized, receivedTime, uint64(s.genesisTime().Unix())); err != nil {
|
||||||
log.WithError(err).Error("Unable to log block sync status")
|
log.WithError(err).Error("Unable to log block sync status")
|
||||||
}
|
}
|
||||||
// Log payload data
|
// Log payload data
|
||||||
@@ -160,25 +150,3 @@ func (s *Service) handlePostBlockOperations(b interfaces.BeaconBlock) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This checks whether it's time to start saving hot state to DB.
|
|
||||||
// It's time when there's `epochsSinceFinalitySaveHotStateDB` epochs of non-finality.
|
|
||||||
func (s *Service) checkSaveHotStateDB(ctx context.Context) error {
|
|
||||||
currentEpoch := slots.ToEpoch(s.CurrentSlot())
|
|
||||||
// Prevent `sinceFinality` going underflow.
|
|
||||||
var sinceFinality types.Epoch
|
|
||||||
finalized := s.FinalizedCheckpt()
|
|
||||||
if finalized == nil {
|
|
||||||
return errNilFinalizedInStore
|
|
||||||
}
|
|
||||||
if currentEpoch > finalized.Epoch {
|
|
||||||
sinceFinality = currentEpoch - finalized.Epoch
|
|
||||||
}
|
|
||||||
|
|
||||||
if sinceFinality >= epochsSinceFinalitySaveHotStateDB {
|
|
||||||
s.cfg.StateGen.EnableSaveHotStateToDB(ctx)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.cfg.StateGen.DisableSaveHotStateToDB(ctx)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ package blockchain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
blockchainTesting "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
blockchainTesting "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||||
@@ -21,7 +17,8 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
"sync"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestService_ReceiveBlock(t *testing.T) {
|
func TestService_ReceiveBlock(t *testing.T) {
|
||||||
@@ -284,40 +281,3 @@ func TestService_HasBlock(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, true, s.HasBlock(context.Background(), r))
|
require.Equal(t, true, s.HasBlock(context.Background(), r))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
|
|
||||||
opts := testServiceOptsWithDB(t)
|
|
||||||
hook := logTest.NewGlobal()
|
|
||||||
s, err := NewService(context.Background(), opts...)
|
|
||||||
require.NoError(t, err)
|
|
||||||
st := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epochsSinceFinalitySaveHotStateDB))
|
|
||||||
s.genesisTime = time.Now().Add(time.Duration(-1*int64(st)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
|
||||||
|
|
||||||
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
|
||||||
assert.LogsContain(t, hook, "Entering mode to save hot states in DB")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
|
|
||||||
hook := logTest.NewGlobal()
|
|
||||||
opts := testServiceOptsWithDB(t)
|
|
||||||
s, err := NewService(context.Background(), opts...)
|
|
||||||
require.NoError(t, err)
|
|
||||||
st := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epochsSinceFinalitySaveHotStateDB))
|
|
||||||
s.genesisTime = time.Now().Add(time.Duration(-1*int64(st)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
|
||||||
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
|
||||||
s.genesisTime = time.Now()
|
|
||||||
|
|
||||||
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
|
||||||
assert.LogsContain(t, hook, "Exiting mode to save hot states in DB")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckSaveHotStateDB_Overflow(t *testing.T) {
|
|
||||||
hook := logTest.NewGlobal()
|
|
||||||
opts := testServiceOptsWithDB(t)
|
|
||||||
s, err := NewService(context.Background(), opts...)
|
|
||||||
require.NoError(t, err)
|
|
||||||
s.genesisTime = time.Now()
|
|
||||||
|
|
||||||
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
|
||||||
assert.LogsDoNotContain(t, hook, "Entering mode to save hot states in DB")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/geninit"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -17,7 +18,6 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
f "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
|
f "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
|
||||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||||
@@ -30,7 +30,6 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
"github.com/prysmaticlabs/prysm/config/features"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
@@ -53,7 +52,6 @@ type Service struct {
|
|||||||
cfg *config
|
cfg *config
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
genesisTime time.Time
|
|
||||||
head *head
|
head *head
|
||||||
headLock sync.RWMutex
|
headLock sync.RWMutex
|
||||||
originBlockRoot [32]byte // genesis root, or weak subjectivity checkpoint root, depending on how the node is initialized
|
originBlockRoot [32]byte // genesis root, or weak subjectivity checkpoint root, depending on how the node is initialized
|
||||||
@@ -65,6 +63,9 @@ type Service struct {
|
|||||||
justifiedBalances *stateBalanceCache
|
justifiedBalances *stateBalanceCache
|
||||||
wsVerifier *WeakSubjectivityVerifier
|
wsVerifier *WeakSubjectivityVerifier
|
||||||
processAttestationsLock sync.Mutex
|
processAttestationsLock sync.Mutex
|
||||||
|
clock Clock
|
||||||
|
clockReady chan struct{}
|
||||||
|
clockWaiter geninit.ClockWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
// config options for the service.
|
// config options for the service.
|
||||||
@@ -138,6 +139,70 @@ func (s *Service) Start() {
|
|||||||
s.fillMissingPayloadIDRoutine(s.ctx, s.cfg.StateNotifier.StateFeed())
|
s.fillMissingPayloadIDRoutine(s.ctx, s.cfg.StateNotifier.StateFeed())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) CombinedStart(genesis state.BeaconState) error {
|
||||||
|
// TODO: we only do this on the genesis code path, not from disk - why?
|
||||||
|
/*
|
||||||
|
// Update committee shuffled indices for genesis epoch.
|
||||||
|
if err := helpers.UpdateCommitteeCache(ctx, genesisState, 0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := helpers.UpdateProposerIndicesInCache(ctx, genesisState); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
gt := time.Unix(int64(genesis.GenesisTime()), 0)
|
||||||
|
s.SetGenesisTime(gt)
|
||||||
|
s.cfg.AttService.SetGenesisTime(genesis.GenesisTime())
|
||||||
|
|
||||||
|
if features.Get().EnableForkChoiceDoublyLinkedTree {
|
||||||
|
s.cfg.ForkChoiceStore = doublylinkedtree.New()
|
||||||
|
} else {
|
||||||
|
s.cfg.ForkChoiceStore = protoarray.New()
|
||||||
|
}
|
||||||
|
// TODO: move head to use fork choice - we currently do not call initializeHeadFromDB!!
|
||||||
|
|
||||||
|
gb, err := s.cfg.BeaconDB.GenesisBlock(s.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "could not get genesis block from db")
|
||||||
|
}
|
||||||
|
if err := wrapper.BeaconBlockIsNil(gb); err != nil {
|
||||||
|
return errors.Wrap(err, "nil value from database block query")
|
||||||
|
}
|
||||||
|
gbr, err := gb.Block().HashTreeRoot()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "could not compute hash_tree_root of genesis block")
|
||||||
|
}
|
||||||
|
if err := s.cfg.ForkChoiceStore.InsertNode(s.ctx, genesis, gbr); err != nil {
|
||||||
|
log.Fatalf("Could not process genesis block for fork choice: %v", err)
|
||||||
|
}
|
||||||
|
s.cfg.ForkChoiceStore.SetGenesisTime(genesis.GenesisTime())
|
||||||
|
|
||||||
|
obr, err := s.cfg.BeaconDB.OriginCheckpointBlockRoot(s.ctx)
|
||||||
|
if err == nil {
|
||||||
|
// this means checkpoint sync was used, use the database origin root value
|
||||||
|
s.originBlockRoot = obr
|
||||||
|
} else {
|
||||||
|
if !errors.Is(err, db.ErrNotFound) {
|
||||||
|
return errors.Wrap(err, "could not retrieve checkpoint sync chain origin data from db")
|
||||||
|
}
|
||||||
|
// this means we got ErrNotFound, meaning checkpoint sync wasn't used, so the node should
|
||||||
|
// be synced from genesis. In this case, use the genesis block root as origin.
|
||||||
|
s.originBlockRoot = gbr
|
||||||
|
}
|
||||||
|
// TODO: should we set origin root when its the genesis block root, or is this method only for checkpoint sync?
|
||||||
|
s.cfg.ForkChoiceStore.SetOriginRoot(s.originBlockRoot)
|
||||||
|
|
||||||
|
spawnCountdownIfPreGenesis(s.ctx, gt, genesis)
|
||||||
|
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||||
|
Type: statefeed.Initialized,
|
||||||
|
Data: &statefeed.InitializedData{
|
||||||
|
StartTime: gt,
|
||||||
|
GenesisValidatorsRoot: genesis.GenesisValidatorsRoot(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Stop the blockchain service's main event loop and associated goroutines.
|
// Stop the blockchain service's main event loop and associated goroutines.
|
||||||
func (s *Service) Stop() error {
|
func (s *Service) Stop() error {
|
||||||
defer s.cancel()
|
defer s.cancel()
|
||||||
@@ -173,7 +238,7 @@ func (s *Service) Status() error {
|
|||||||
// StartFromSavedState initializes the blockchain using a previously saved finalized checkpoint.
|
// StartFromSavedState initializes the blockchain using a previously saved finalized checkpoint.
|
||||||
func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
||||||
log.Info("Blockchain data already exists in DB, initializing...")
|
log.Info("Blockchain data already exists in DB, initializing...")
|
||||||
s.genesisTime = time.Unix(int64(saved.GenesisTime()), 0) // lint:ignore uintcast -- Genesis time will not exceed int64 in your lifetime.
|
s.SetGenesisTime(time.Unix(int64(saved.GenesisTime()), 0)) // lint:ignore uintcast -- Genesis time will not exceed int64 in your lifetime.
|
||||||
s.cfg.AttService.SetGenesisTime(saved.GenesisTime())
|
s.cfg.AttService.SetGenesisTime(saved.GenesisTime())
|
||||||
|
|
||||||
originRoot, err := s.originRootFromSavedState(s.ctx)
|
originRoot, err := s.originRootFromSavedState(s.ctx)
|
||||||
@@ -185,7 +250,12 @@ func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
|||||||
if err := s.initializeHeadFromDB(s.ctx); err != nil {
|
if err := s.initializeHeadFromDB(s.ctx); err != nil {
|
||||||
return errors.Wrap(err, "could not set up chain info")
|
return errors.Wrap(err, "could not set up chain info")
|
||||||
}
|
}
|
||||||
spawnCountdownIfPreGenesis(s.ctx, s.genesisTime, s.cfg.BeaconDB)
|
gs, err := s.cfg.BeaconDB.GenesisState(s.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
gt := time.Unix(int64(gs.GenesisTime()), 0)
|
||||||
|
spawnCountdownIfPreGenesis(s.ctx, gt, gs)
|
||||||
|
|
||||||
justified, err := s.cfg.BeaconDB.JustifiedCheckpoint(s.ctx)
|
justified, err := s.cfg.BeaconDB.JustifiedCheckpoint(s.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -218,7 +288,7 @@ func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
|||||||
Root: bytesutil.ToBytes32(finalized.Root)}); err != nil {
|
Root: bytesutil.ToBytes32(finalized.Root)}); err != nil {
|
||||||
return errors.Wrap(err, "could not update forkchoice's finalized checkpoint")
|
return errors.Wrap(err, "could not update forkchoice's finalized checkpoint")
|
||||||
}
|
}
|
||||||
forkChoicer.SetGenesisTime(uint64(s.genesisTime.Unix()))
|
forkChoicer.SetGenesisTime(uint64(s.genesisTime().Unix()))
|
||||||
|
|
||||||
st, err := s.cfg.StateGen.StateByRoot(s.ctx, fRoot)
|
st, err := s.cfg.StateGen.StateByRoot(s.ctx, fRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -247,7 +317,7 @@ func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
|||||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||||
Type: statefeed.Initialized,
|
Type: statefeed.Initialized,
|
||||||
Data: &statefeed.InitializedData{
|
Data: &statefeed.InitializedData{
|
||||||
StartTime: s.genesisTime,
|
StartTime: s.genesisTime(),
|
||||||
GenesisValidatorsRoot: saved.GenesisValidatorsRoot(),
|
GenesisValidatorsRoot: saved.GenesisValidatorsRoot(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -295,48 +365,11 @@ func (s *Service) initializeHeadFromDB(ctx context.Context) error {
|
|||||||
return errors.New("no finalized epoch in the database")
|
return errors.New("no finalized epoch in the database")
|
||||||
}
|
}
|
||||||
finalizedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(finalized.Root))
|
finalizedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(finalized.Root))
|
||||||
var finalizedState state.BeaconState
|
finalizedState, err := s.cfg.StateGen.Resume(ctx, s.cfg.FinalizedStateAtStartUp)
|
||||||
|
|
||||||
finalizedState, err = s.cfg.StateGen.Resume(ctx, s.cfg.FinalizedStateAtStartUp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not get finalized state from db")
|
return errors.Wrap(err, "could not get finalized state from db")
|
||||||
}
|
}
|
||||||
|
|
||||||
if flags.Get().HeadSync {
|
|
||||||
headBlock, err := s.cfg.BeaconDB.HeadBlock(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not retrieve head block")
|
|
||||||
}
|
|
||||||
headEpoch := slots.ToEpoch(headBlock.Block().Slot())
|
|
||||||
var epochsSinceFinality types.Epoch
|
|
||||||
if headEpoch > finalized.Epoch {
|
|
||||||
epochsSinceFinality = headEpoch - finalized.Epoch
|
|
||||||
}
|
|
||||||
// Head sync when node is far enough beyond known finalized epoch,
|
|
||||||
// this becomes really useful during long period of non-finality.
|
|
||||||
if epochsSinceFinality >= headSyncMinEpochsAfterCheckpoint {
|
|
||||||
headRoot, err := headBlock.Block().HashTreeRoot()
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not hash head block")
|
|
||||||
}
|
|
||||||
finalizedState, err := s.cfg.StateGen.Resume(ctx, s.cfg.FinalizedStateAtStartUp)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not get finalized state from db")
|
|
||||||
}
|
|
||||||
log.Infof("Regenerating state from the last checkpoint at slot %d to current head slot of %d."+
|
|
||||||
"This process may take a while, please wait.", finalizedState.Slot(), headBlock.Block().Slot())
|
|
||||||
headState, err := s.cfg.StateGen.StateByRoot(ctx, headRoot)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not retrieve head state")
|
|
||||||
}
|
|
||||||
s.setHead(headRoot, headBlock, headState)
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
log.Warnf("Finalized checkpoint at slot %d is too close to the current head slot, "+
|
|
||||||
"resetting head from the checkpoint ('--%s' flag is ignored).",
|
|
||||||
finalizedState.Slot(), flags.HeadSync.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if finalizedState == nil || finalizedState.IsNil() {
|
if finalizedState == nil || finalizedState.IsNil() {
|
||||||
return errors.New("finalized state can't be nil")
|
return errors.New("finalized state can't be nil")
|
||||||
}
|
}
|
||||||
@@ -352,34 +385,15 @@ func (s *Service) initializeHeadFromDB(ctx context.Context) error {
|
|||||||
|
|
||||||
func (s *Service) startFromPOWChain() error {
|
func (s *Service) startFromPOWChain() error {
|
||||||
log.Info("Waiting to reach the validator deposit threshold to start the beacon chain...")
|
log.Info("Waiting to reach the validator deposit threshold to start the beacon chain...")
|
||||||
if s.cfg.ChainStartFetcher == nil {
|
|
||||||
return errors.New("not configured web3Service for POW chain")
|
|
||||||
}
|
|
||||||
go func() {
|
go func() {
|
||||||
stateChannel := make(chan *feed.Event, 1)
|
c, err := s.clockWaiter.WaitForClock(s.ctx)
|
||||||
stateSub := s.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
|
if err != nil {
|
||||||
defer stateSub.Unsubscribe()
|
log.WithError(err).Error("timeout while waiting for genesis during blockchain service startup")
|
||||||
for {
|
return
|
||||||
select {
|
|
||||||
case e := <-stateChannel:
|
|
||||||
if e.Type == statefeed.ChainStarted {
|
|
||||||
data, ok := e.Data.(*statefeed.ChainStartedData)
|
|
||||||
if !ok {
|
|
||||||
log.Error("event data is not type *statefeed.ChainStartedData")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.WithField("starttime", data.StartTime).Debug("Received chain start event")
|
|
||||||
s.onPowchainStart(s.ctx, data.StartTime)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case <-s.ctx.Done():
|
|
||||||
log.Debug("Context closed, exiting goroutine")
|
|
||||||
return
|
|
||||||
case err := <-stateSub.Err():
|
|
||||||
log.WithError(err).Error("Subscription to state notifier failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
log.WithField("starttime", c.GenesisTime()).Debug("Received chain start event")
|
||||||
|
s.onPowchainStart(s.ctx, c.GenesisTime())
|
||||||
|
s.setClock(c)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -388,8 +402,7 @@ func (s *Service) startFromPOWChain() error {
|
|||||||
// onPowchainStart initializes a series of deposits from the ChainStart deposits in the eth1
|
// onPowchainStart initializes a series of deposits from the ChainStart deposits in the eth1
|
||||||
// deposit contract, initializes the beacon chain's state, and kicks off the beacon chain.
|
// deposit contract, initializes the beacon chain's state, and kicks off the beacon chain.
|
||||||
func (s *Service) onPowchainStart(ctx context.Context, genesisTime time.Time) {
|
func (s *Service) onPowchainStart(ctx context.Context, genesisTime time.Time) {
|
||||||
preGenesisState := s.cfg.ChainStartFetcher.PreGenesisState()
|
initializedState, err := s.initializeBeaconChain(ctx, genesisTime, preGenesisState)
|
||||||
initializedState, err := s.initializeBeaconChain(ctx, genesisTime, preGenesisState, s.cfg.ChainStartFetcher.ChainStartEth1Data())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Could not initialize beacon chain: %v", err)
|
log.Fatalf("Could not initialize beacon chain: %v", err)
|
||||||
}
|
}
|
||||||
@@ -414,29 +427,10 @@ func (s *Service) onPowchainStart(ctx context.Context, genesisTime time.Time) {
|
|||||||
// initializes the state and genesis block of the beacon chain to persistent storage
|
// 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
|
// 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.
|
// by the ETH1.0 Deposit Contract and the POWChain service of the node.
|
||||||
func (s *Service) initializeBeaconChain(
|
func (s *Service) initializeBeaconChain(ctx context.Context, genesisTime time.Time) (state.BeaconState, error) {
|
||||||
ctx context.Context,
|
|
||||||
genesisTime time.Time,
|
|
||||||
preGenesisState state.BeaconState,
|
|
||||||
eth1data *ethpb.Eth1Data) (state.BeaconState, error) {
|
|
||||||
ctx, span := trace.StartSpan(ctx, "beacon-chain.Service.initializeBeaconChain")
|
ctx, span := trace.StartSpan(ctx, "beacon-chain.Service.initializeBeaconChain")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
s.genesisTime = genesisTime
|
s.SetGenesisTime(genesisTime)
|
||||||
unixTime := uint64(genesisTime.Unix())
|
|
||||||
|
|
||||||
genesisState, err := transition.OptimizedGenesisBeaconState(unixTime, preGenesisState, eth1data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not initialize genesis state")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.saveGenesisData(ctx, genesisState); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not save genesis data")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Initialized beacon chain genesis state")
|
|
||||||
|
|
||||||
// Clear out all pre-genesis data now that the state is initialized.
|
|
||||||
s.cfg.ChainStartFetcher.ClearPreGenesisData()
|
|
||||||
|
|
||||||
// Update committee shuffled indices for genesis epoch.
|
// Update committee shuffled indices for genesis epoch.
|
||||||
if err := helpers.UpdateCommitteeCache(ctx, genesisState, 0); err != nil {
|
if err := helpers.UpdateCommitteeCache(ctx, genesisState, 0); err != nil {
|
||||||
@@ -447,15 +441,11 @@ func (s *Service) initializeBeaconChain(
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.cfg.AttService.SetGenesisTime(genesisState.GenesisTime())
|
s.cfg.AttService.SetGenesisTime(genesisState.GenesisTime())
|
||||||
|
|
||||||
return genesisState, nil
|
return genesisState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This gets called when beacon chain is first initialized to save genesis data (state, block, and more) in db.
|
// This gets called when beacon chain is first initialized to save genesis data (state, block, and more) in db.
|
||||||
func (s *Service) saveGenesisData(ctx context.Context, genesisState state.BeaconState) error {
|
func (s *Service) saveGenesisData(ctx context.Context, genesisState state.BeaconState) error {
|
||||||
if err := s.cfg.BeaconDB.SaveGenesisData(ctx, genesisState); err != nil {
|
|
||||||
return errors.Wrap(err, "could not save genesis data")
|
|
||||||
}
|
|
||||||
genesisBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
genesisBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
||||||
if err != nil || genesisBlk == nil || genesisBlk.IsNil() {
|
if err != nil || genesisBlk == nil || genesisBlk.IsNil() {
|
||||||
return fmt.Errorf("could not load genesis block: %v", err)
|
return fmt.Errorf("could not load genesis block: %v", err)
|
||||||
@@ -476,7 +466,7 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState state.Beacon
|
|||||||
if err := s.cfg.ForkChoiceStore.SetOptimisticToValid(ctx, genesisBlkRoot); err != nil {
|
if err := s.cfg.ForkChoiceStore.SetOptimisticToValid(ctx, genesisBlkRoot); err != nil {
|
||||||
return errors.Wrap(err, "Could not set optimistic status of genesis block to false")
|
return errors.Wrap(err, "Could not set optimistic status of genesis block to false")
|
||||||
}
|
}
|
||||||
s.cfg.ForkChoiceStore.SetGenesisTime(uint64(s.genesisTime.Unix()))
|
s.cfg.ForkChoiceStore.SetGenesisTime(uint64(s.genesisTime().Unix()))
|
||||||
|
|
||||||
s.setHead(genesisBlkRoot, genesisBlk, genesisState)
|
s.setHead(genesisBlkRoot, genesisBlk, genesisState)
|
||||||
return nil
|
return nil
|
||||||
@@ -494,19 +484,14 @@ func (s *Service) hasBlock(ctx context.Context, root [32]byte) bool {
|
|||||||
return s.cfg.BeaconDB.HasBlock(ctx, root)
|
return s.cfg.BeaconDB.HasBlock(ctx, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
func spawnCountdownIfPreGenesis(ctx context.Context, genesisTime time.Time, db db.HeadAccessDatabase) {
|
func spawnCountdownIfPreGenesis(ctx context.Context, gt time.Time, gs state.BeaconState) {
|
||||||
currentTime := prysmTime.Now()
|
// only proceed if this function runs before genesis time
|
||||||
if currentTime.After(genesisTime) {
|
if prysmTime.Now().After(gt) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
gr, err := gs.HashTreeRoot(ctx)
|
||||||
gState, err := db.GenesisState(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Could not retrieve genesis state: %v", err)
|
log.WithError(err).Fatal("Could not compute hash_tree_root of genesis state")
|
||||||
}
|
}
|
||||||
gRoot, err := gState.HashTreeRoot(ctx)
|
go slots.CountdownToGenesis(ctx, gt, uint64(gs.NumValidators()), gr)
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not hash tree root genesis state: %v", err)
|
|
||||||
}
|
|
||||||
go slots.CountdownToGenesis(ctx, genesisTime, uint64(gState.NumValidators()), gRoot)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
|
|||||||
|
|
||||||
chainService, err := NewService(ctx, opts...)
|
chainService, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err, "Unable to setup chain service")
|
require.NoError(t, err, "Unable to setup chain service")
|
||||||
chainService.genesisTime = time.Unix(1, 0) // non-zero time
|
chainService.SetGenesisTime(time.Unix(1, 0)) // non-zero time
|
||||||
|
|
||||||
return chainService
|
return chainService
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ go_library(
|
|||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
"//async/event:go_default_library",
|
"//async/event:go_default_library",
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/core/epoch/precompute:go_default_library",
|
"//beacon-chain/core/epoch/precompute:go_default_library",
|
||||||
"//beacon-chain/core/feed:go_default_library",
|
"//beacon-chain/core/feed:go_default_library",
|
||||||
"//beacon-chain/core/feed/block:go_default_library",
|
"//beacon-chain/core/feed/block:go_default_library",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package testing
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ type ChainService struct {
|
|||||||
ReceiveBlockMockErr error
|
ReceiveBlockMockErr error
|
||||||
OptimisticCheckRootReceived [32]byte
|
OptimisticCheckRootReceived [32]byte
|
||||||
FinalizedRoots map[[32]byte]bool
|
FinalizedRoots map[[32]byte]bool
|
||||||
|
Clock blockchain.Clock
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForkChoicer mocks the same method in the chain service
|
// ForkChoicer mocks the same method in the chain service
|
||||||
@@ -326,6 +328,13 @@ func (s *ChainService) GenesisTime() time.Time {
|
|||||||
return s.Genesis
|
return s.Genesis
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ChainService) WaitForClock(ctx context.Context) (blockchain.Clock, error) {
|
||||||
|
if s.Clock == nil {
|
||||||
|
return blockchain.NewClock(time.Now()), nil
|
||||||
|
}
|
||||||
|
return s.Clock, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GenesisValidatorsRoot mocks the same method in the chain service.
|
// GenesisValidatorsRoot mocks the same method in the chain service.
|
||||||
func (s *ChainService) GenesisValidatorsRoot() [32]byte {
|
func (s *ChainService) GenesisValidatorsRoot() [32]byte {
|
||||||
return s.ValidatorsRoot
|
return s.ValidatorsRoot
|
||||||
@@ -336,7 +345,7 @@ func (s *ChainService) CurrentSlot() types.Slot {
|
|||||||
if s.Slot != nil {
|
if s.Slot != nil {
|
||||||
return *s.Slot
|
return *s.Slot
|
||||||
}
|
}
|
||||||
return types.Slot(uint64(time.Now().Unix()-s.Genesis.Unix()) / params.BeaconConfig().SecondsPerSlot)
|
return s.Clock.CurrentSlot()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Participation mocks the same method in the chain service.
|
// Participation mocks the same method in the chain service.
|
||||||
@@ -464,3 +473,11 @@ func (s *ChainService) ReceiveAttesterSlashing(context.Context, *ethpb.AttesterS
|
|||||||
func (s *ChainService) IsFinalized(_ context.Context, blockRoot [32]byte) bool {
|
func (s *ChainService) IsFinalized(_ context.Context, blockRoot [32]byte) bool {
|
||||||
return s.FinalizedRoots[blockRoot]
|
return s.FinalizedRoots[blockRoot]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewMockClock(now time.Time, slotsAfterGenesis types.Slot) blockchain.Clock {
|
||||||
|
offset := uint64(slotsAfterGenesis) * params.BeaconConfig().SecondsPerSlot
|
||||||
|
genesis := now.Add(-1 * time.Second * time.Duration(offset))
|
||||||
|
return blockchain.NewClock(genesis, blockchain.WithNow(func() time.Time {
|
||||||
|
return genesis
|
||||||
|
}))
|
||||||
|
}
|
||||||
69
beacon-chain/geninit/clock.go
Normal file
69
beacon-chain/geninit/clock.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package geninit
|
||||||
|
|
||||||
|
import (
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clock abstracts important time-related concerns in the beacon chain:
|
||||||
|
// - genesis time
|
||||||
|
// - provides a time.Now() construct that can be overriden in tests
|
||||||
|
// - syncronization point for code that needs to know the genesis time
|
||||||
|
// - CurrentSlot: convenience conversion for current time -> slot
|
||||||
|
// - support backwards compatibility with the TimeFetcher interface
|
||||||
|
type Clock interface {
|
||||||
|
GenesisTime() time.Time
|
||||||
|
CurrentSlot() types.Slot
|
||||||
|
Now() time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// clock is a type that fulfills the TimeFetcher interface. This can be used in a number of places where
|
||||||
|
// blockchain.ChainInfoFetcher has historically been used.
|
||||||
|
type clock struct {
|
||||||
|
genesis time.Time
|
||||||
|
now Now
|
||||||
|
}
|
||||||
|
var _ Clock = &clock{}
|
||||||
|
|
||||||
|
// clock provides an accessor to the embedded time, also fulfilling the blockchain.TimeFetcher interface.
|
||||||
|
func (gt clock) GenesisTime() time.Time {
|
||||||
|
return gt.genesis
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentSlot returns the current slot relative to the time.Time value clock embeds.
|
||||||
|
func (gt clock) CurrentSlot() types.Slot {
|
||||||
|
return slots.Duration(gt.genesis, gt.now())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now provides a value for time.Now() that can be overriden in tests.
|
||||||
|
func (gt clock) Now() time.Time {
|
||||||
|
return gt.now()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClockOpt is a functional option to change the behavior of a clock value made by NewClock.
|
||||||
|
// It is primarily intended as a way to inject an alternate time.Now() callback (WithNow) for testing.
|
||||||
|
type ClockOpt func(*clock)
|
||||||
|
|
||||||
|
// WithNow allows tests in particular to inject an alternate implementation of time.Now (vs using system time)
|
||||||
|
func WithNow(n Now) ClockOpt {
|
||||||
|
return func(gt *clock) {
|
||||||
|
gt.now = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClock constructs a clock value using the given time value. Optional ClockOpt can be provided.
|
||||||
|
// If an implementation of the Now function type is not provided (via WithNow), time.Now (system time) will be used by default.
|
||||||
|
func NewClock(t time.Time, opts ...ClockOpt) clock {
|
||||||
|
gt := clock{genesis: t}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(>)
|
||||||
|
}
|
||||||
|
if gt.now == nil {
|
||||||
|
gt.now = time.Now
|
||||||
|
}
|
||||||
|
return gt
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now is a function that can return the current time. This will be time.Now by default, but can be overridden for tests.
|
||||||
|
type Now func() time.Time
|
||||||
84
beacon-chain/geninit/service.go
Normal file
84
beacon-chain/geninit/service.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package geninit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||||
|
"go.opencensus.io/trace"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
ctx context.Context
|
||||||
|
powWaiter ClockWaiter
|
||||||
|
genesisSetter ClockSetter
|
||||||
|
powFetcher powchain.ChainStartFetcher
|
||||||
|
d db.HeadAccessDatabase
|
||||||
|
}
|
||||||
|
var _ runtime.Service = &Service{}
|
||||||
|
|
||||||
|
type ServiceOption func(*Service)
|
||||||
|
|
||||||
|
func New(ctx context.Context, pw ClockWaiter, gs ClockSetter, f powchain.ChainStartFetcher, d db.HeadAccessDatabase, opts ...ServiceOption) (*Service, error) {
|
||||||
|
s := &Service{
|
||||||
|
ctx: ctx,
|
||||||
|
powWaiter: pw,
|
||||||
|
genesisSetter: gs,
|
||||||
|
powFetcher: f,
|
||||||
|
d: d,
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(s)
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Start() {
|
||||||
|
go s.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) run() {
|
||||||
|
c, err := s.powWaiter.WaitForClock(s.ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("timeout waiting for genesis timestamp")
|
||||||
|
}
|
||||||
|
if err = s.saveGenesis(c); err != nil {
|
||||||
|
log.Fatalf("Could not initialize beacon chain, %s", err.Error())
|
||||||
|
}
|
||||||
|
s.genesisSetter.SetGenesisClock(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) saveGenesis(c Clock) error {
|
||||||
|
ctx, span := trace.StartSpan(s.ctx, "beacon-chain.geninit.Service.saveGenesis")
|
||||||
|
defer span.End()
|
||||||
|
eth1 := s.powFetcher.ChainStartEth1Data()
|
||||||
|
pst := s.powFetcher.PreGenesisState()
|
||||||
|
st, err := transition.OptimizedGenesisBeaconState(uint64(c.GenesisTime().Unix()), pst, eth1)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.d.SaveGenesisData(ctx, st); err != nil {
|
||||||
|
return errors.Wrap(err, "db error, could not save genesis data")
|
||||||
|
}
|
||||||
|
log.Info("Initialized beacon chain genesis state")
|
||||||
|
// Clear out all pre-genesis data now that the state is initialized.
|
||||||
|
s.powFetcher.ClearPreGenesisData()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Stop() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Status() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenesisReady struct {
|
||||||
|
time time.Time
|
||||||
|
}
|
||||||
50
beacon-chain/geninit/waiter.go
Normal file
50
beacon-chain/geninit/waiter.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package geninit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClockWaiter interface {
|
||||||
|
WaitForClock(context.Context) (Clock, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClockSetter interface {
|
||||||
|
SetGenesisTime(time.Time)
|
||||||
|
SetGenesisClock(Clock)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClockSync struct {
|
||||||
|
ready chan struct{}
|
||||||
|
c Clock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ClockSync) SetGenesisTime(g time.Time) {
|
||||||
|
w.c = NewClock(g)
|
||||||
|
close(w.ready)
|
||||||
|
w.ready = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ClockSync) SetGenesisClock(c Clock) {
|
||||||
|
w.c = c
|
||||||
|
close(w.ready)
|
||||||
|
w.ready = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ClockSync) WaitForClock(ctx context.Context) (Clock, error) {
|
||||||
|
if w.ready == nil {
|
||||||
|
return w.c, nil
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-w.ready:
|
||||||
|
return w.c, nil
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClockSync() *ClockSync {
|
||||||
|
return &ClockSync{
|
||||||
|
ready: make(chan struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ go_library(
|
|||||||
"//beacon-chain/forkchoice/doubly-linked-tree:go_default_library",
|
"//beacon-chain/forkchoice/doubly-linked-tree:go_default_library",
|
||||||
"//beacon-chain/forkchoice/protoarray:go_default_library",
|
"//beacon-chain/forkchoice/protoarray:go_default_library",
|
||||||
"//beacon-chain/gateway:go_default_library",
|
"//beacon-chain/gateway:go_default_library",
|
||||||
|
"//beacon-chain/geninit:go_default_library",
|
||||||
"//beacon-chain/monitor:go_default_library",
|
"//beacon-chain/monitor:go_default_library",
|
||||||
"//beacon-chain/node/registration:go_default_library",
|
"//beacon-chain/node/registration:go_default_library",
|
||||||
"//beacon-chain/operations/attestations:go_default_library",
|
"//beacon-chain/operations/attestations:go_default_library",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import (
|
|||||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/gateway"
|
"github.com/prysmaticlabs/prysm/beacon-chain/gateway"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/geninit"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/monitor"
|
"github.com/prysmaticlabs/prysm/beacon-chain/monitor"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/node/registration"
|
"github.com/prysmaticlabs/prysm/beacon-chain/node/registration"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
|
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
|
||||||
@@ -211,8 +212,17 @@ func New(cliCtx *cli.Context, opts ...Option) (*BeaconNode, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
powSync := geninit.NewClockSync()
|
||||||
|
genSync := geninit.NewClockSync()
|
||||||
|
|
||||||
log.Debugln("Registering POW Chain Service")
|
log.Debugln("Registering POW Chain Service")
|
||||||
if err := beacon.registerPOWChainService(); err != nil {
|
powService, err := beacon.registerPOWChainService(powSync)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugln("Registering Genesis Init Service")
|
||||||
|
if err := beacon.registerGenesisInitService(powSync, genSync, powService, beacon.db); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,17 +639,17 @@ func (b *BeaconNode) registerBlockchainService() error {
|
|||||||
return b.services.RegisterService(blockchainService)
|
return b.services.RegisterService(blockchainService)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BeaconNode) registerPOWChainService() error {
|
func (b *BeaconNode) registerPOWChainService(gcs geninit.ClockSetter) (*powchain.Service, error) {
|
||||||
if b.cliCtx.Bool(testSkipPowFlag) {
|
if b.cliCtx.Bool(testSkipPowFlag) {
|
||||||
return b.services.RegisterService(&powchain.Service{})
|
return nil, b.services.RegisterService(&powchain.Service{})
|
||||||
}
|
}
|
||||||
bs, err := powchain.NewPowchainCollector(b.ctx)
|
bs, err := powchain.NewPowchainCollector(b.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
depositContractAddr, err := powchain.DepositContractAddress()
|
depositContractAddr, err := powchain.DepositContractAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// skipcq: CRT-D0001
|
// skipcq: CRT-D0001
|
||||||
@@ -652,13 +662,23 @@ func (b *BeaconNode) registerPOWChainService() error {
|
|||||||
powchain.WithStateGen(b.stateGen),
|
powchain.WithStateGen(b.stateGen),
|
||||||
powchain.WithBeaconNodeStatsUpdater(bs),
|
powchain.WithBeaconNodeStatsUpdater(bs),
|
||||||
powchain.WithFinalizedStateAtStartup(b.finalizedStateAtStartUp),
|
powchain.WithFinalizedStateAtStartup(b.finalizedStateAtStartUp),
|
||||||
|
powchain.WithGenesisClockSetter(gcs),
|
||||||
)
|
)
|
||||||
web3Service, err := powchain.NewService(b.ctx, opts...)
|
srv, err := powchain.NewService(b.ctx, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not register proof-of-work chain web3Service")
|
return nil, errors.Wrap(err, "could not register proof-of-work chain web3Service")
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.services.RegisterService(web3Service)
|
err = b.services.RegisterService(srv)
|
||||||
|
return srv, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BeaconNode) registerGenesisInitService(w geninit.ClockWaiter, s geninit.ClockSetter, f powchain.ChainStartFetcher, d db.HeadAccessDatabase) error {
|
||||||
|
g, err := geninit.New(b.ctx, w, s, f, d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return b.services.RegisterService(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BeaconNode) registerSyncService() error {
|
func (b *BeaconNode) registerSyncService() error {
|
||||||
@@ -821,7 +841,6 @@ func (b *BeaconNode) registerRPCService() error {
|
|||||||
FinalizationFetcher: chainService,
|
FinalizationFetcher: chainService,
|
||||||
BlockReceiver: chainService,
|
BlockReceiver: chainService,
|
||||||
AttestationReceiver: chainService,
|
AttestationReceiver: chainService,
|
||||||
GenesisTimeFetcher: chainService,
|
|
||||||
GenesisFetcher: chainService,
|
GenesisFetcher: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
AttestationsPool: b.attestationPool,
|
AttestationsPool: b.attestationPool,
|
||||||
@@ -844,6 +863,7 @@ func (b *BeaconNode) registerRPCService() error {
|
|||||||
MaxMsgSize: maxMsgSize,
|
MaxMsgSize: maxMsgSize,
|
||||||
ProposerIdsCache: b.proposerIdsCache,
|
ProposerIdsCache: b.proposerIdsCache,
|
||||||
BlockBuilder: b.fetchBuilderService(),
|
BlockBuilder: b.fetchBuilderService(),
|
||||||
|
ClockProvider: chainService,
|
||||||
})
|
})
|
||||||
|
|
||||||
return b.services.RegisterService(rpcService)
|
return b.services.RegisterService(rpcService)
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ go_library(
|
|||||||
"//beacon-chain/core/helpers:go_default_library",
|
"//beacon-chain/core/helpers:go_default_library",
|
||||||
"//beacon-chain/core/transition:go_default_library",
|
"//beacon-chain/core/transition:go_default_library",
|
||||||
"//beacon-chain/db:go_default_library",
|
"//beacon-chain/db:go_default_library",
|
||||||
|
"//beacon-chain/geninit:go_default_library",
|
||||||
"//beacon-chain/powchain/types:go_default_library",
|
"//beacon-chain/powchain/types:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/state-native:go_default_library",
|
"//beacon-chain/state/state-native:go_default_library",
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ func (s *Service) ProcessChainStart(genesisTime uint64, eth1BlockHash [32]byte,
|
|||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"ChainStartTime": chainStartTime,
|
"ChainStartTime": chainStartTime,
|
||||||
}).Info("Minimum number of validators reached for beacon-chain to start")
|
}).Info("Minimum number of validators reached for beacon-chain to start")
|
||||||
|
s.genSync.SetGenesisTime(chainStartTime)
|
||||||
s.cfg.stateNotifier.StateFeed().Send(&feed.Event{
|
s.cfg.stateNotifier.StateFeed().Send(&feed.Event{
|
||||||
Type: statefeed.ChainStarted,
|
Type: statefeed.ChainStarted,
|
||||||
Data: &statefeed.ChainStartedData{
|
Data: &statefeed.ChainStartedData{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
||||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/geninit"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
"github.com/prysmaticlabs/prysm/network"
|
"github.com/prysmaticlabs/prysm/network"
|
||||||
@@ -123,3 +124,10 @@ func WithFinalizedStateAtStartup(st state.BeaconState) Option {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithGenesisClockSetter(cs geninit.ClockSetter) Option {
|
||||||
|
return func(s *Service) error {
|
||||||
|
s.genSync = cs
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/geninit"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain/types"
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
native "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
native "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
@@ -161,6 +162,7 @@ type Service struct {
|
|||||||
lastReceivedMerkleIndex int64 // Keeps track of the last received index to prevent log spam.
|
lastReceivedMerkleIndex int64 // Keeps track of the last received index to prevent log spam.
|
||||||
runError error
|
runError error
|
||||||
preGenesisState state.BeaconState
|
preGenesisState state.BeaconState
|
||||||
|
genSync geninit.ClockSetter
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService sets up a new instance with an ethclient when given a web3 endpoint as a string in the config.
|
// NewService sets up a new instance with an ethclient when given a web3 endpoint as a string in the config.
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ go_library(
|
|||||||
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
|
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
|
||||||
"@com_github_grpc_ecosystem_go_grpc_middleware//tracing/opentracing:go_default_library",
|
"@com_github_grpc_ecosystem_go_grpc_middleware//tracing/opentracing:go_default_library",
|
||||||
"@com_github_grpc_ecosystem_go_grpc_prometheus//:go_default_library",
|
"@com_github_grpc_ecosystem_go_grpc_prometheus//:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@io_opencensus_go//plugin/ocgrpc:go_default_library",
|
"@io_opencensus_go//plugin/ocgrpc:go_default_library",
|
||||||
"@org_golang_google_grpc//:go_default_library",
|
"@org_golang_google_grpc//:go_default_library",
|
||||||
@@ -61,6 +62,7 @@ go_test(
|
|||||||
srcs = ["service_test.go"],
|
srcs = ["service_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/blockchain/testing:go_default_library",
|
"//beacon-chain/blockchain/testing:go_default_library",
|
||||||
"//beacon-chain/powchain/testing:go_default_library",
|
"//beacon-chain/powchain/testing:go_default_library",
|
||||||
"//beacon-chain/sync/initial-sync/testing:go_default_library",
|
"//beacon-chain/sync/initial-sync/testing:go_default_library",
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//api/grpc:go_default_library",
|
"//api/grpc:go_default_library",
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/blockchain/testing:go_default_library",
|
"//beacon-chain/blockchain/testing:go_default_library",
|
||||||
"//beacon-chain/core/signing:go_default_library",
|
"//beacon-chain/core/signing:go_default_library",
|
||||||
"//beacon-chain/db:go_default_library",
|
"//beacon-chain/db:go_default_library",
|
||||||
|
|||||||
@@ -53,7 +53,11 @@ func (e *blockIdParseError) Error() string {
|
|||||||
// GetWeakSubjectivity computes the starting epoch of the current weak subjectivity period, and then also
|
// GetWeakSubjectivity computes the starting epoch of the current weak subjectivity period, and then also
|
||||||
// determines the best block root and state root to use for a Checkpoint Sync starting from that point.
|
// determines the best block root and state root to use for a Checkpoint Sync starting from that point.
|
||||||
func (bs *Server) GetWeakSubjectivity(ctx context.Context, _ *empty.Empty) (*ethpbv1.WeakSubjectivityResponse, error) {
|
func (bs *Server) GetWeakSubjectivity(ctx context.Context, _ *empty.Empty) (*ethpbv1.WeakSubjectivityResponse, error) {
|
||||||
if err := rpchelpers.ValidateSync(ctx, bs.SyncChecker, bs.HeadFetcher, bs.GenesisTimeFetcher, bs.OptimisticModeFetcher); err != nil {
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, bs.SyncChecker, bs.HeadFetcher, c, bs.OptimisticModeFetcher); err != nil {
|
||||||
// This is already a grpc error, so we can't wrap it any further
|
// This is already a grpc error, so we can't wrap it any further
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -70,7 +74,11 @@ func (bs *Server) GetWeakSubjectivity(ctx context.Context, _ *empty.Empty) (*eth
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "could not get weak subjectivity slot: %v", err)
|
return nil, status.Errorf(codes.Internal, "could not get weak subjectivity slot: %v", err)
|
||||||
}
|
}
|
||||||
cbr, err := bs.CanonicalHistory.BlockRootForSlot(ctx, wsSlot)
|
h, err := bs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
cbr, err := h.BlockRootForSlot(ctx, wsSlot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, fmt.Sprintf("could not find highest block below slot %d", wsSlot))
|
return nil, status.Errorf(codes.Internal, fmt.Sprintf("could not find highest block below slot %d", wsSlot))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
type Server struct {
|
type Server struct {
|
||||||
BeaconDB db.ReadOnlyDatabase
|
BeaconDB db.ReadOnlyDatabase
|
||||||
ChainInfoFetcher blockchain.ChainInfoFetcher
|
ChainInfoFetcher blockchain.ChainInfoFetcher
|
||||||
GenesisTimeFetcher blockchain.TimeFetcher
|
|
||||||
BlockReceiver blockchain.BlockReceiver
|
BlockReceiver blockchain.BlockReceiver
|
||||||
BlockNotifier blockfeed.Notifier
|
BlockNotifier blockfeed.Notifier
|
||||||
OperationNotifier operation.Notifier
|
OperationNotifier operation.Notifier
|
||||||
@@ -37,8 +36,9 @@ type Server struct {
|
|||||||
HeadFetcher blockchain.HeadFetcher
|
HeadFetcher blockchain.HeadFetcher
|
||||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||||
V1Alpha1ValidatorServer *v1alpha1validator.Server
|
V1Alpha1ValidatorServer *v1alpha1validator.Server
|
||||||
SyncChecker sync.Checker
|
SyncChecker sync.Checker
|
||||||
CanonicalHistory *stategen.CanonicalHistory
|
CanonicalHistoryWaiter stategen.CanonicalHistoryWaiter
|
||||||
HeadUpdater blockchain.HeadUpdater
|
HeadUpdater blockchain.HeadUpdater
|
||||||
ExecutionPayloadReconstructor powchain.ExecutionPayloadReconstructor
|
ExecutionPayloadReconstructor powchain.ExecutionPayloadReconstructor
|
||||||
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,11 @@ func (bs *Server) GetGenesis(ctx context.Context, _ *emptypb.Empty) (*ethpb.Gene
|
|||||||
ctx, span := trace.StartSpan(ctx, "beacon.GetGenesis")
|
ctx, span := trace.StartSpan(ctx, "beacon.GetGenesis")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
genesisTime := bs.GenesisTimeFetcher.GenesisTime()
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
if genesisTime.IsZero() {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.NotFound, "Chain genesis info is not yet known")
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
}
|
}
|
||||||
|
genesisTime := c.GenesisTime()
|
||||||
validatorRoot := bs.ChainInfoFetcher.GenesisValidatorsRoot()
|
validatorRoot := bs.ChainInfoFetcher.GenesisValidatorsRoot()
|
||||||
if bytes.Equal(validatorRoot[:], params.BeaconConfig().ZeroHash[:]) {
|
if bytes.Equal(validatorRoot[:], params.BeaconConfig().ZeroHash[:]) {
|
||||||
return nil, status.Errorf(codes.NotFound, "Chain genesis info is not yet known")
|
return nil, status.Errorf(codes.NotFound, "Chain genesis info is not yet known")
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package beacon
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -29,11 +30,11 @@ func TestGetGenesis(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("OK", func(t *testing.T) {
|
t.Run("OK", func(t *testing.T) {
|
||||||
chainService := &chainMock.ChainService{
|
chainService := &chainMock.ChainService{
|
||||||
Genesis: genesis,
|
Clock: blockchain.NewClock(genesis),
|
||||||
ValidatorsRoot: validatorsRoot,
|
ValidatorsRoot: validatorsRoot,
|
||||||
}
|
}
|
||||||
s := Server{
|
s := Server{
|
||||||
GenesisTimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
ChainInfoFetcher: chainService,
|
ChainInfoFetcher: chainService,
|
||||||
}
|
}
|
||||||
resp, err := s.GetGenesis(ctx, &emptypb.Empty{})
|
resp, err := s.GetGenesis(ctx, &emptypb.Empty{})
|
||||||
@@ -46,11 +47,11 @@ func TestGetGenesis(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("No genesis time", func(t *testing.T) {
|
t.Run("No genesis time", func(t *testing.T) {
|
||||||
chainService := &chainMock.ChainService{
|
chainService := &chainMock.ChainService{
|
||||||
Genesis: time.Time{},
|
Clock: blockchain.NewClock(time.Time{}),
|
||||||
ValidatorsRoot: validatorsRoot,
|
ValidatorsRoot: validatorsRoot,
|
||||||
}
|
}
|
||||||
s := Server{
|
s := Server{
|
||||||
GenesisTimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
ChainInfoFetcher: chainService,
|
ChainInfoFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err := s.GetGenesis(ctx, &emptypb.Empty{})
|
_, err := s.GetGenesis(ctx, &emptypb.Empty{})
|
||||||
@@ -59,11 +60,11 @@ func TestGetGenesis(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("No genesis validators root", func(t *testing.T) {
|
t.Run("No genesis validators root", func(t *testing.T) {
|
||||||
chainService := &chainMock.ChainService{
|
chainService := &chainMock.ChainService{
|
||||||
Genesis: genesis,
|
Clock: blockchain.NewClock(genesis),
|
||||||
ValidatorsRoot: [32]byte{},
|
ValidatorsRoot: [32]byte{},
|
||||||
}
|
}
|
||||||
s := Server{
|
s := Server{
|
||||||
GenesisTimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
ChainInfoFetcher: chainService,
|
ChainInfoFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err := s.GetGenesis(ctx, &emptypb.Empty{})
|
_, err := s.GetGenesis(ctx, &emptypb.Empty{})
|
||||||
|
|||||||
@@ -27,7 +27,11 @@ func (bs *Server) ListSyncCommittees(ctx context.Context, req *ethpbv2.StateSync
|
|||||||
ctx, span := trace.StartSpan(ctx, "beacon.ListSyncCommittees")
|
ctx, span := trace.StartSpan(ctx, "beacon.ListSyncCommittees")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
currentSlot := bs.GenesisTimeFetcher.CurrentSlot()
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
currentSlot := c.CurrentSlot()
|
||||||
currentEpoch := slots.ToEpoch(currentSlot)
|
currentEpoch := slots.ToEpoch(currentSlot)
|
||||||
currentPeriodStartEpoch, err := slots.SyncCommitteePeriodStartEpoch(currentEpoch)
|
currentPeriodStartEpoch, err := slots.SyncCommitteePeriodStartEpoch(currentEpoch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package beacon
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -161,11 +162,9 @@ func TestListSyncCommittees(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
db := dbTest.SetupDB(t)
|
db := dbTest.SetupDB(t)
|
||||||
|
|
||||||
chainService := &mock.ChainService{}
|
chainService := &mock.ChainService{Clock: blockchain.NewClock(time.Now())}
|
||||||
s := &Server{
|
s := &Server{
|
||||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
ClockProvider: chainService,
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateFetcher: &testutil.MockFetcher{
|
StateFetcher: &testutil.MockFetcher{
|
||||||
BeaconState: st,
|
BeaconState: st,
|
||||||
},
|
},
|
||||||
@@ -204,11 +203,9 @@ func TestListSyncCommittees(t *testing.T) {
|
|||||||
util.SaveBlock(t, ctx, db, blk)
|
util.SaveBlock(t, ctx, db, blk)
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
|
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
|
||||||
|
|
||||||
chainService := &mock.ChainService{Optimistic: true}
|
chainService := &mock.ChainService{Optimistic: true, Clock: blockchain.NewClock(time.Now())}
|
||||||
s := &Server{
|
s := &Server{
|
||||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
ClockProvider: chainService,
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateFetcher: &testutil.MockFetcher{
|
StateFetcher: &testutil.MockFetcher{
|
||||||
BeaconState: st,
|
BeaconState: st,
|
||||||
},
|
},
|
||||||
@@ -262,11 +259,9 @@ func TestListSyncCommitteesFuture(t *testing.T) {
|
|||||||
}))
|
}))
|
||||||
db := dbTest.SetupDB(t)
|
db := dbTest.SetupDB(t)
|
||||||
|
|
||||||
chainService := &mock.ChainService{}
|
chainService := &mock.ChainService{Clock: blockchain.NewClock(time.Now())}
|
||||||
s := &Server{
|
s := &Server{
|
||||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
ClockProvider: chainService,
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateFetcher: &futureSyncMockFetcher{
|
StateFetcher: &futureSyncMockFetcher{
|
||||||
BeaconState: st,
|
BeaconState: st,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func ValidateSync(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
syncChecker sync.Checker,
|
syncChecker sync.Checker,
|
||||||
headFetcher blockchain.HeadFetcher,
|
headFetcher blockchain.HeadFetcher,
|
||||||
timeFetcher blockchain.TimeFetcher,
|
clock blockchain.Clock,
|
||||||
optimisticModeFetcher blockchain.OptimisticModeFetcher,
|
optimisticModeFetcher blockchain.OptimisticModeFetcher,
|
||||||
) error {
|
) error {
|
||||||
if !syncChecker.Syncing() {
|
if !syncChecker.Syncing() {
|
||||||
@@ -36,7 +36,7 @@ func ValidateSync(
|
|||||||
syncDetailsContainer := &syncDetailsContainer{
|
syncDetailsContainer := &syncDetailsContainer{
|
||||||
SyncDetails: &SyncDetailsJson{
|
SyncDetails: &SyncDetailsJson{
|
||||||
HeadSlot: strconv.FormatUint(uint64(headSlot), 10),
|
HeadSlot: strconv.FormatUint(uint64(headSlot), 10),
|
||||||
SyncDistance: strconv.FormatUint(uint64(timeFetcher.CurrentSlot()-headSlot), 10),
|
SyncDistance: strconv.FormatUint(uint64(clock.CurrentSlot()-headSlot), 10),
|
||||||
IsSyncing: true,
|
IsSyncing: true,
|
||||||
IsOptimistic: isOptimistic,
|
IsOptimistic: isOptimistic,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -270,11 +270,19 @@ func (ns *Server) GetSyncStatus(ctx context.Context, _ *emptypb.Empty) (*ethpb.S
|
|||||||
return nil, status.Errorf(codes.Internal, "Could not check optimistic status: %v", err)
|
return nil, status.Errorf(codes.Internal, "Could not check optimistic status: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c, err := ns.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
headSlot := ns.HeadFetcher.HeadSlot()
|
headSlot := ns.HeadFetcher.HeadSlot()
|
||||||
|
sd, err := c.CurrentSlot().SafeSubSlot(headSlot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "error computing sync_distance, head > current slot, %s", err)
|
||||||
|
}
|
||||||
return ðpb.SyncingResponse{
|
return ðpb.SyncingResponse{
|
||||||
Data: ðpb.SyncInfo{
|
Data: ðpb.SyncInfo{
|
||||||
HeadSlot: headSlot,
|
HeadSlot: headSlot,
|
||||||
SyncDistance: ns.GenesisTimeFetcher.CurrentSlot() - headSlot,
|
SyncDistance: sd,
|
||||||
IsSyncing: ns.SyncChecker.Syncing(),
|
IsSyncing: ns.SyncChecker.Syncing(),
|
||||||
IsOptimistic: isOptimistic,
|
IsOptimistic: isOptimistic,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ func TestSyncStatus(t *testing.T) {
|
|||||||
|
|
||||||
s := &Server{
|
s := &Server{
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
GenesisTimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
SyncChecker: syncChecker,
|
SyncChecker: syncChecker,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ type Server struct {
|
|||||||
PeersFetcher p2p.PeersProvider
|
PeersFetcher p2p.PeersProvider
|
||||||
PeerManager p2p.PeerManager
|
PeerManager p2p.PeerManager
|
||||||
MetadataProvider p2p.MetadataProvider
|
MetadataProvider p2p.MetadataProvider
|
||||||
GenesisTimeFetcher blockchain.TimeFetcher
|
|
||||||
HeadFetcher blockchain.HeadFetcher
|
HeadFetcher blockchain.HeadFetcher
|
||||||
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ go_test(
|
|||||||
srcs = ["validator_test.go"],
|
srcs = ["validator_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/blockchain/testing:go_default_library",
|
"//beacon-chain/blockchain/testing:go_default_library",
|
||||||
"//beacon-chain/cache:go_default_library",
|
"//beacon-chain/cache:go_default_library",
|
||||||
"//beacon-chain/core/altair:go_default_library",
|
"//beacon-chain/core/altair:go_default_library",
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import (
|
|||||||
type Server struct {
|
type Server struct {
|
||||||
HeadFetcher blockchain.HeadFetcher
|
HeadFetcher blockchain.HeadFetcher
|
||||||
HeadUpdater blockchain.HeadUpdater
|
HeadUpdater blockchain.HeadUpdater
|
||||||
TimeFetcher blockchain.TimeFetcher
|
|
||||||
SyncChecker sync.Checker
|
SyncChecker sync.Checker
|
||||||
AttestationsPool attestations.Pool
|
AttestationsPool attestations.Pool
|
||||||
PeerManager p2p.PeerManager
|
PeerManager p2p.PeerManager
|
||||||
@@ -24,4 +23,5 @@ type Server struct {
|
|||||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||||
SyncCommitteePool synccommittee.Pool
|
SyncCommitteePool synccommittee.Pool
|
||||||
V1Alpha1Server *v1alpha1validator.Server
|
V1Alpha1Server *v1alpha1validator.Server
|
||||||
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,12 +42,16 @@ func (vs *Server) GetAttesterDuties(ctx context.Context, req *ethpbv1.AttesterDu
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.GetAttesterDuties")
|
ctx, span := trace.StartSpan(ctx, "validator.GetAttesterDuties")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := vs.TimeFetcher.CurrentSlot()
|
cs := c.CurrentSlot()
|
||||||
currentEpoch := slots.ToEpoch(cs)
|
currentEpoch := slots.ToEpoch(cs)
|
||||||
if req.Epoch > currentEpoch+1 {
|
if req.Epoch > currentEpoch+1 {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "Request epoch %d can not be greater than next epoch %d", req.Epoch, currentEpoch+1)
|
return nil, status.Errorf(codes.InvalidArgument, "Request epoch %d can not be greater than next epoch %d", req.Epoch, currentEpoch+1)
|
||||||
@@ -125,12 +129,16 @@ func (vs *Server) GetProposerDuties(ctx context.Context, req *ethpbv1.ProposerDu
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.GetProposerDuties")
|
ctx, span := trace.StartSpan(ctx, "validator.GetProposerDuties")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := vs.TimeFetcher.CurrentSlot()
|
cs := c.CurrentSlot()
|
||||||
currentEpoch := slots.ToEpoch(cs)
|
currentEpoch := slots.ToEpoch(cs)
|
||||||
if req.Epoch > currentEpoch+1 {
|
if req.Epoch > currentEpoch+1 {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "Request epoch %d can not be greater than next epoch %d", req.Epoch, currentEpoch+1)
|
return nil, status.Errorf(codes.InvalidArgument, "Request epoch %d can not be greater than next epoch %d", req.Epoch, currentEpoch+1)
|
||||||
@@ -202,12 +210,16 @@ func (vs *Server) GetSyncCommitteeDuties(ctx context.Context, req *ethpbv2.SyncC
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.GetSyncCommitteeDuties")
|
ctx, span := trace.StartSpan(ctx, "validator.GetSyncCommitteeDuties")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
currentEpoch := slots.ToEpoch(vs.TimeFetcher.CurrentSlot())
|
currentEpoch := slots.ToEpoch(c.CurrentSlot())
|
||||||
lastValidEpoch := syncCommitteeDutiesLastValidEpoch(currentEpoch)
|
lastValidEpoch := syncCommitteeDutiesLastValidEpoch(currentEpoch)
|
||||||
if req.Epoch > lastValidEpoch {
|
if req.Epoch > lastValidEpoch {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "Epoch is too far in the future. Maximum valid epoch is %v.", lastValidEpoch)
|
return nil, status.Errorf(codes.InvalidArgument, "Epoch is too far in the future. Maximum valid epoch is %v.", lastValidEpoch)
|
||||||
@@ -272,7 +284,11 @@ func (vs *Server) ProduceBlock(ctx context.Context, req *ethpbv1.ProduceBlockReq
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlock")
|
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlock")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -289,7 +305,11 @@ func (vs *Server) ProduceBlockV2(ctx context.Context, req *ethpbv1.ProduceBlockR
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlockV2")
|
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlockV2")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -353,7 +373,11 @@ func (vs *Server) ProduceBlockV2SSZ(ctx context.Context, req *ethpbv1.ProduceBlo
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlockV2SSZ")
|
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlockV2SSZ")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -424,7 +448,11 @@ func (vs *Server) ProduceBlindedBlock(ctx context.Context, req *ethpbv1.ProduceB
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlindedBlock")
|
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlindedBlock")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -491,7 +519,11 @@ func (vs *Server) ProduceBlindedBlockSSZ(ctx context.Context, req *ethpbv1.Produ
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlindedBlockSSZ")
|
ctx, span := trace.StartSpan(ctx, "validator.ProduceBlindedBlockSSZ")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -633,6 +665,10 @@ func (vs *Server) SubmitAggregateAndProofs(ctx context.Context, req *ethpbv1.Sub
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.SubmitAggregateAndProofs")
|
ctx, span := trace.StartSpan(ctx, "validator.SubmitAggregateAndProofs")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
for _, agg := range req.Data {
|
for _, agg := range req.Data {
|
||||||
if agg == nil || agg.Message == nil || agg.Message.Aggregate == nil || agg.Message.Aggregate.Data == nil {
|
if agg == nil || agg.Message == nil || agg.Message.Aggregate == nil || agg.Message.Aggregate.Data == nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, "Signed aggregate request can't be nil")
|
return nil, status.Error(codes.InvalidArgument, "Signed aggregate request can't be nil")
|
||||||
@@ -648,7 +684,7 @@ func (vs *Server) SubmitAggregateAndProofs(ctx context.Context, req *ethpbv1.Sub
|
|||||||
|
|
||||||
// As a preventive measure, a beacon node shouldn't broadcast an attestation whose slot is out of range.
|
// As a preventive measure, a beacon node shouldn't broadcast an attestation whose slot is out of range.
|
||||||
if err := helpers.ValidateAttestationTime(agg.Message.Aggregate.Data.Slot,
|
if err := helpers.ValidateAttestationTime(agg.Message.Aggregate.Data.Slot,
|
||||||
vs.TimeFetcher.GenesisTime(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
c.GenesisTime(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, "Attestation slot is no longer valid from current time")
|
return nil, status.Error(codes.InvalidArgument, "Attestation slot is no longer valid from current time")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -683,7 +719,11 @@ func (vs *Server) SubmitBeaconCommitteeSubscription(ctx context.Context, req *et
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.SubmitBeaconCommitteeSubscription")
|
ctx, span := trace.StartSpan(ctx, "validator.SubmitBeaconCommitteeSubscription")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -760,7 +800,11 @@ func (vs *Server) SubmitSyncCommitteeSubscription(ctx context.Context, req *ethp
|
|||||||
ctx, span := trace.StartSpan(ctx, "validator.SubmitSyncCommitteeSubscription")
|
ctx, span := trace.StartSpan(ctx, "validator.SubmitSyncCommitteeSubscription")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, vs.TimeFetcher, vs.OptimisticModeFetcher); err != nil {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := rpchelpers.ValidateSync(ctx, vs.SyncChecker, vs.HeadFetcher, c, vs.OptimisticModeFetcher); err != nil {
|
||||||
// We simply return the error because it's already a gRPC error.
|
// We simply return the error because it's already a gRPC error.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package validator
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -75,13 +76,12 @@ func TestGetAttesterDuties(t *testing.T) {
|
|||||||
pubKeys[i] = deposits[i].Data.PublicKey
|
pubKeys[i] = deposits[i].Data.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
chainSlot := types.Slot(0)
|
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
|
State: bs, Root: genesisRoot[:],
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: chain,
|
OptimisticModeFetcher: chain,
|
||||||
}
|
}
|
||||||
@@ -155,12 +155,13 @@ func TestGetAttesterDuties(t *testing.T) {
|
|||||||
indices[i] = uint64(i)
|
indices[i] = uint64(i)
|
||||||
}
|
}
|
||||||
chainSlot := params.BeaconConfig().SlotsPerEpoch.Mul(2)
|
chainSlot := params.BeaconConfig().SlotsPerEpoch.Mul(2)
|
||||||
|
clock := mockChain.NewMockClock(time.Now(), chainSlot)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
|
State: bs, Root: genesisRoot[:], Clock: clock,
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
OptimisticModeFetcher: chain,
|
OptimisticModeFetcher: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
}
|
}
|
||||||
@@ -224,13 +225,12 @@ func TestGetAttesterDuties(t *testing.T) {
|
|||||||
util.SaveBlock(t, ctx, db, blk)
|
util.SaveBlock(t, ctx, db, blk)
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
|
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
|
||||||
|
|
||||||
chainSlot := types.Slot(0)
|
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Slot: &chainSlot, Optimistic: true,
|
State: bs, Root: genesisRoot[:], Optimistic: true,
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
OptimisticModeFetcher: chain,
|
OptimisticModeFetcher: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ func TestGetAttesterDuties_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.GetAttesterDuties(context.Background(), ðpbv1.AttesterDutiesRequest{})
|
_, err = vs.GetAttesterDuties(context.Background(), ðpbv1.AttesterDutiesRequest{})
|
||||||
@@ -282,13 +282,12 @@ func TestGetProposerDuties(t *testing.T) {
|
|||||||
pubKeys[i] = deposits[i].Data.PublicKey
|
pubKeys[i] = deposits[i].Data.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
chainSlot := types.Slot(0)
|
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
|
State: bs, Root: genesisRoot[:],
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
OptimisticModeFetcher: chain,
|
OptimisticModeFetcher: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
}
|
}
|
||||||
@@ -334,12 +333,15 @@ func TestGetProposerDuties(t *testing.T) {
|
|||||||
indices[i] = uint64(i)
|
indices[i] = uint64(i)
|
||||||
}
|
}
|
||||||
chainSlot := params.BeaconConfig().SlotsPerEpoch.Mul(2)
|
chainSlot := params.BeaconConfig().SlotsPerEpoch.Mul(2)
|
||||||
|
clock := mockChain.NewMockClock(time.Now(), chainSlot)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
|
State: bs,
|
||||||
|
Root: genesisRoot[:],
|
||||||
|
Clock: clock,
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
OptimisticModeFetcher: chain,
|
OptimisticModeFetcher: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
}
|
}
|
||||||
@@ -383,13 +385,12 @@ func TestGetProposerDuties(t *testing.T) {
|
|||||||
util.SaveBlock(t, ctx, db, blk)
|
util.SaveBlock(t, ctx, db, blk)
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
|
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
|
||||||
|
|
||||||
chainSlot := types.Slot(0)
|
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Slot: &chainSlot, Optimistic: true,
|
State: bs, Root: genesisRoot[:], Optimistic: true,
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
OptimisticModeFetcher: chain,
|
OptimisticModeFetcher: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
}
|
}
|
||||||
@@ -409,7 +410,7 @@ func TestGetProposerDuties_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.GetProposerDuties(context.Background(), ðpbv1.ProposerDutiesRequest{})
|
_, err = vs.GetProposerDuties(context.Background(), ðpbv1.ProposerDutiesRequest{})
|
||||||
@@ -437,11 +438,11 @@ func TestGetSyncCommitteeDuties(t *testing.T) {
|
|||||||
require.NoError(t, st.SetNextSyncCommittee(nextCommittee))
|
require.NoError(t, st.SetNextSyncCommittee(nextCommittee))
|
||||||
db := dbutil.SetupDB(t)
|
db := dbutil.SetupDB(t)
|
||||||
|
|
||||||
mockChainService := &mockChain.ChainService{Genesis: genesisTime}
|
mockChainService := &mockChain.ChainService{Clock: blockchain.NewClock(genesisTime)}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
StateFetcher: &testutil.MockFetcher{BeaconState: st},
|
StateFetcher: &testutil.MockFetcher{BeaconState: st},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: mockChainService,
|
ClockProvider: mockChainService,
|
||||||
HeadFetcher: mockChainService,
|
HeadFetcher: mockChainService,
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
}
|
}
|
||||||
@@ -576,11 +577,14 @@ func TestGetSyncCommitteeDuties(t *testing.T) {
|
|||||||
return newSyncPeriodSt
|
return newSyncPeriodSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mockChainService := &mockChain.ChainService{Genesis: genesisTime, Slot: &newSyncPeriodStartSlot}
|
clock := mockChain.NewMockClock(time.Now(), newSyncPeriodStartSlot)
|
||||||
|
mockChainService := &mockChain.ChainService{
|
||||||
|
Clock: clock,
|
||||||
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
StateFetcher: &testutil.MockFetcher{BeaconState: stateFetchFn(newSyncPeriodStartSlot)},
|
StateFetcher: &testutil.MockFetcher{BeaconState: stateFetchFn(newSyncPeriodStartSlot)},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: mockChainService,
|
ClockProvider: mockChainService,
|
||||||
HeadFetcher: mockChainService,
|
HeadFetcher: mockChainService,
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
}
|
}
|
||||||
@@ -610,11 +614,14 @@ func TestGetSyncCommitteeDuties(t *testing.T) {
|
|||||||
util.SaveBlock(t, ctx, db, blk)
|
util.SaveBlock(t, ctx, db, blk)
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
|
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
|
||||||
|
|
||||||
mockChainService := &mockChain.ChainService{Genesis: genesisTime, Optimistic: true}
|
mockChainService := &mockChain.ChainService{
|
||||||
|
Clock: blockchain.NewClock(genesisTime),
|
||||||
|
Optimistic: true,
|
||||||
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
StateFetcher: &testutil.MockFetcher{BeaconState: st},
|
StateFetcher: &testutil.MockFetcher{BeaconState: st},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: mockChainService,
|
ClockProvider: mockChainService,
|
||||||
HeadFetcher: mockChainService,
|
HeadFetcher: mockChainService,
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
}
|
}
|
||||||
@@ -635,7 +642,7 @@ func TestGetSyncCommitteeDuties_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.GetSyncCommitteeDuties(context.Background(), ðpbv2.SyncCommitteeDutiesRequest{})
|
_, err = vs.GetSyncCommitteeDuties(context.Background(), ðpbv2.SyncCommitteeDutiesRequest{})
|
||||||
@@ -745,7 +752,7 @@ func TestProduceBlock_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.ProduceBlock(context.Background(), ðpbv1.ProduceBlockRequest{})
|
_, err = vs.ProduceBlock(context.Background(), ðpbv1.ProduceBlockRequest{})
|
||||||
@@ -1011,7 +1018,7 @@ func TestProduceBlockV2(t *testing.T) {
|
|||||||
TotalDifficulty: "0x1",
|
TotalDifficulty: "0x1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TimeFetcher: &mockChain.ChainService{},
|
ClockProvider: &mockChain.ChainService{},
|
||||||
HeadFetcher: &mockChain.ChainService{State: beaconState, Root: parentRoot[:]},
|
HeadFetcher: &mockChain.ChainService{State: beaconState, Root: parentRoot[:]},
|
||||||
OptimisticModeFetcher: &mockChain.ChainService{},
|
OptimisticModeFetcher: &mockChain.ChainService{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
@@ -1500,7 +1507,7 @@ func TestProduceBlockV2SSZ(t *testing.T) {
|
|||||||
TotalDifficulty: "0x1",
|
TotalDifficulty: "0x1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TimeFetcher: &mockChain.ChainService{},
|
ClockProvider: &mockChain.ChainService{},
|
||||||
HeadFetcher: &mockChain.ChainService{State: bs, Root: parentRoot[:]},
|
HeadFetcher: &mockChain.ChainService{State: bs, Root: parentRoot[:]},
|
||||||
OptimisticModeFetcher: &mockChain.ChainService{},
|
OptimisticModeFetcher: &mockChain.ChainService{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
@@ -1691,7 +1698,7 @@ func TestProduceBlockV2_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.ProduceBlockV2(context.Background(), ðpbv1.ProduceBlockRequest{})
|
_, err = vs.ProduceBlockV2(context.Background(), ðpbv1.ProduceBlockRequest{})
|
||||||
@@ -1705,7 +1712,7 @@ func TestProduceBlockV2SSZ_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.ProduceBlockV2SSZ(context.Background(), ðpbv1.ProduceBlockRequest{})
|
_, err = vs.ProduceBlockV2SSZ(context.Background(), ðpbv1.ProduceBlockRequest{})
|
||||||
@@ -1971,7 +1978,7 @@ func TestProduceBlindedBlock(t *testing.T) {
|
|||||||
TotalDifficulty: "0x1",
|
TotalDifficulty: "0x1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TimeFetcher: &mockChain.ChainService{},
|
ClockProvider: &mockChain.ChainService{},
|
||||||
HeadFetcher: &mockChain.ChainService{State: beaconState, Root: parentRoot[:]},
|
HeadFetcher: &mockChain.ChainService{State: beaconState, Root: parentRoot[:]},
|
||||||
OptimisticModeFetcher: &mockChain.ChainService{},
|
OptimisticModeFetcher: &mockChain.ChainService{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
@@ -2460,7 +2467,7 @@ func TestProduceBlindedBlockSSZ(t *testing.T) {
|
|||||||
TotalDifficulty: "0x1",
|
TotalDifficulty: "0x1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TimeFetcher: &mockChain.ChainService{},
|
ClockProvider: &mockChain.ChainService{},
|
||||||
HeadFetcher: &mockChain.ChainService{State: bs, Root: parentRoot[:]},
|
HeadFetcher: &mockChain.ChainService{State: bs, Root: parentRoot[:]},
|
||||||
OptimisticModeFetcher: &mockChain.ChainService{},
|
OptimisticModeFetcher: &mockChain.ChainService{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
@@ -2651,7 +2658,7 @@ func TestProduceBlindedBlock_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.ProduceBlindedBlock(context.Background(), ðpbv1.ProduceBlockRequest{})
|
_, err = vs.ProduceBlindedBlock(context.Background(), ðpbv1.ProduceBlockRequest{})
|
||||||
@@ -2665,7 +2672,7 @@ func TestProduceBlindedBlockSSZ_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.ProduceBlindedBlockSSZ(context.Background(), ðpbv1.ProduceBlockRequest{})
|
_, err = vs.ProduceBlindedBlockSSZ(context.Background(), ðpbv1.ProduceBlockRequest{})
|
||||||
@@ -2704,6 +2711,7 @@ func TestProduceAttestationData(t *testing.T) {
|
|||||||
Genesis: time.Now(),
|
Genesis: time.Now(),
|
||||||
}
|
}
|
||||||
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
v1Alpha1Server := &v1alpha1validator.Server{
|
v1Alpha1Server := &v1alpha1validator.Server{
|
||||||
P2P: &p2pmock.MockBroadcaster{},
|
P2P: &p2pmock.MockBroadcaster{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
@@ -2714,8 +2722,8 @@ func TestProduceAttestationData(t *testing.T) {
|
|||||||
FinalizationFetcher: &mockChain.ChainService{
|
FinalizationFetcher: &mockChain.ChainService{
|
||||||
CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint(),
|
CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint(),
|
||||||
},
|
},
|
||||||
TimeFetcher: &mockChain.ChainService{
|
ClockProvider: &mockChain.ChainService{
|
||||||
Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second),
|
Clock: blockchain.NewClock(gent),
|
||||||
},
|
},
|
||||||
StateNotifier: chainService.StateNotifier(),
|
StateNotifier: chainService.StateNotifier(),
|
||||||
}
|
}
|
||||||
@@ -2925,11 +2933,11 @@ func TestSubmitBeaconCommitteeSubscription(t *testing.T) {
|
|||||||
|
|
||||||
chainSlot := types.Slot(0)
|
chainSlot := types.Slot(0)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
|
State: bs, Root:genesisRoot[:], Slot: &chainSlot,
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
V1Alpha1Server: &v1alpha1validator.Server{},
|
V1Alpha1Server: &v1alpha1validator.Server{},
|
||||||
}
|
}
|
||||||
@@ -3040,7 +3048,7 @@ func TestSubmitBeaconCommitteeSubscription_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.SubmitBeaconCommitteeSubscription(context.Background(), ðpbv1.SubmitBeaconCommitteeSubscriptionsRequest{})
|
_, err = vs.SubmitBeaconCommitteeSubscription(context.Background(), ðpbv1.SubmitBeaconCommitteeSubscriptionsRequest{})
|
||||||
@@ -3069,11 +3077,12 @@ func TestSubmitSyncCommitteeSubscription(t *testing.T) {
|
|||||||
|
|
||||||
chainSlot := types.Slot(0)
|
chainSlot := types.Slot(0)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
|
State: bs,
|
||||||
|
Root: genesisRoot[:],
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
V1Alpha1Server: &v1alpha1validator.Server{},
|
V1Alpha1Server: &v1alpha1validator.Server{},
|
||||||
}
|
}
|
||||||
@@ -3199,7 +3208,7 @@ func TestSubmitSyncCommitteeSubscription_SyncNotReady(t *testing.T) {
|
|||||||
vs := &Server{
|
vs := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
SyncChecker: &mockSync.Sync{IsSyncing: true},
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
TimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
OptimisticModeFetcher: chainService,
|
OptimisticModeFetcher: chainService,
|
||||||
}
|
}
|
||||||
_, err = vs.SubmitSyncCommitteeSubscription(context.Background(), ðpbv2.SubmitSyncCommitteeSubscriptionsRequest{})
|
_, err = vs.SubmitSyncCommitteeSubscription(context.Background(), ðpbv2.SubmitSyncCommitteeSubscriptionsRequest{})
|
||||||
@@ -3236,11 +3245,12 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
|
|||||||
t.Run("OK", func(t *testing.T) {
|
t.Run("OK", func(t *testing.T) {
|
||||||
chainSlot := types.Slot(0)
|
chainSlot := types.Slot(0)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
Genesis: time.Now(), Slot: &chainSlot,
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
|
Slot: &chainSlot,
|
||||||
}
|
}
|
||||||
broadcaster := &p2pmock.MockBroadcaster{}
|
broadcaster := &p2pmock.MockBroadcaster{}
|
||||||
vs := Server{
|
vs := Server{
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
Broadcaster: broadcaster,
|
Broadcaster: broadcaster,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3458,11 +3468,11 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
|
|||||||
t.Run("invalid attestation time", func(t *testing.T) {
|
t.Run("invalid attestation time", func(t *testing.T) {
|
||||||
chainSlot := types.Slot(0)
|
chainSlot := types.Slot(0)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
Genesis: time.Now().Add(time.Hour * 2), Slot: &chainSlot,
|
Clock: blockchain.NewClock(time.Now().Add(time.Hour * 2)), Slot: &chainSlot,
|
||||||
}
|
}
|
||||||
broadcaster := &p2pmock.MockBroadcaster{}
|
broadcaster := &p2pmock.MockBroadcaster{}
|
||||||
vs := Server{
|
vs := Server{
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
Broadcaster: broadcaster,
|
Broadcaster: broadcaster,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
shard_count = 4,
|
shard_count = 4,
|
||||||
deps = [
|
deps = [
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/blockchain/testing:go_default_library",
|
"//beacon-chain/blockchain/testing:go_default_library",
|
||||||
"//beacon-chain/core/altair:go_default_library",
|
"//beacon-chain/core/altair:go_default_library",
|
||||||
"//beacon-chain/core/epoch/precompute:go_default_library",
|
"//beacon-chain/core/epoch/precompute:go_default_library",
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ func (bs *Server) ListValidatorAssignments(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
var res []*ethpb.ValidatorAssignments_CommitteeAssignment
|
var res []*ethpb.ValidatorAssignments_CommitteeAssignment
|
||||||
filtered := map[types.ValidatorIndex]bool{} // track filtered validators to prevent duplication in the response.
|
filtered := map[types.ValidatorIndex]bool{} // track filtered validators to prevent duplication in the response.
|
||||||
filteredIndices := make([]types.ValidatorIndex, 0)
|
filteredIndices := make([]types.ValidatorIndex, 0)
|
||||||
@@ -45,7 +49,7 @@ func (bs *Server) ListValidatorAssignments(
|
|||||||
requestedEpoch = q.Epoch
|
requestedEpoch = q.Epoch
|
||||||
}
|
}
|
||||||
|
|
||||||
currentEpoch := slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot())
|
currentEpoch := slots.ToEpoch(c.CurrentSlot())
|
||||||
if requestedEpoch > currentEpoch {
|
if requestedEpoch > currentEpoch {
|
||||||
return nil, status.Errorf(
|
return nil, status.Errorf(
|
||||||
codes.InvalidArgument,
|
codes.InvalidArgument,
|
||||||
@@ -59,7 +63,11 @@ func (bs *Server) ListValidatorAssignments(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
requestedState, err := bs.ReplayerBuilder.ReplayerForSlot(startSlot).ReplayBlocks(ctx)
|
b, err := bs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
requestedState, err := b.ReplayerForSlot(startSlot).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg := fmt.Sprintf("could not replay all blocks from the closest stored state (at slot %d) "+
|
msg := fmt.Sprintf("could not replay all blocks from the closest stored state (at slot %d) "+
|
||||||
"to the requested epoch (%d) - %v", startSlot, requestedEpoch, err)
|
"to the requested epoch (%d) - %v", startSlot, requestedEpoch, err)
|
||||||
|
|||||||
@@ -28,16 +28,18 @@ func TestServer_ListAssignments_CannotRequestFutureEpoch(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, db)
|
addDefaultReplayerBuilder(bs, db)
|
||||||
|
|
||||||
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
wanted := errNoEpochInfoError
|
wanted := errNoEpochInfoError
|
||||||
_, err := bs.ListValidatorAssignments(
|
_, err = bs.ListValidatorAssignments(
|
||||||
ctx,
|
ctx,
|
||||||
ðpb.ListValidatorAssignmentsRequest{
|
ðpb.ListValidatorAssignmentsRequest{
|
||||||
QueryFilter: ðpb.ListValidatorAssignmentsRequest_Epoch{
|
QueryFilter: ðpb.ListValidatorAssignmentsRequest_Epoch{
|
||||||
Epoch: slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) + 1,
|
Epoch: slots.ToEpoch(c.CurrentSlot()) + 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -59,7 +61,7 @@ func TestServer_ListAssignments_NoResults(t *testing.T) {
|
|||||||
|
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st)),
|
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st)),
|
||||||
}
|
}
|
||||||
@@ -121,7 +123,7 @@ func TestServer_ListAssignments_Pagination_InputOutOfRange(t *testing.T) {
|
|||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(s)),
|
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(s)),
|
||||||
}
|
}
|
||||||
@@ -197,7 +199,7 @@ func TestServer_ListAssignments_Pagination_DefaultPageSize_NoArchive(t *testing.
|
|||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(s)),
|
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(s)),
|
||||||
}
|
}
|
||||||
@@ -264,7 +266,7 @@ func TestServer_ListAssignments_FilterPubkeysIndices_NoPagination(t *testing.T)
|
|||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(s)),
|
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(s)),
|
||||||
}
|
}
|
||||||
@@ -335,7 +337,7 @@ func TestServer_ListAssignments_CanFilterPubkeysIndices_WithPagination(t *testin
|
|||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -340,7 +340,12 @@ func (bs *Server) StreamIndexedAttestations(
|
|||||||
func (bs *Server) collectReceivedAttestations(ctx context.Context) {
|
func (bs *Server) collectReceivedAttestations(ctx context.Context) {
|
||||||
attsByRoot := make(map[[32]byte][]*ethpb.Attestation)
|
attsByRoot := make(map[[32]byte][]*ethpb.Attestation)
|
||||||
twoThirdsASlot := 2 * slots.DivideSlotBy(3) /* 2/3 slot duration */
|
twoThirdsASlot := 2 * slots.DivideSlotBy(3) /* 2/3 slot duration */
|
||||||
ticker := slots.NewSlotTickerWithOffset(bs.GenesisTimeFetcher.GenesisTime(), twoThirdsASlot, params.BeaconConfig().SecondsPerSlot)
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("timeout while waiting for genesis timestamp in collectReceivedAttestations")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ticker := slots.NewSlotTickerWithOffset(c.GenesisTime(), twoThirdsASlot, params.BeaconConfig().SecondsPerSlot)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C():
|
case <-ticker.C():
|
||||||
|
|||||||
@@ -3,11 +3,6 @@ package beacon
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
chainMock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
chainMock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
@@ -36,6 +31,9 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestServer_ListAttestations_NoResults(t *testing.T) {
|
func TestServer_ListAttestations_NoResults(t *testing.T) {
|
||||||
@@ -567,7 +565,7 @@ func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) {
|
|||||||
|
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
GenesisTimeFetcher: &chainMock.ChainService{State: state},
|
ClockProvider: &chainMock.ChainService{State: state},
|
||||||
HeadFetcher: &chainMock.ChainService{State: state},
|
HeadFetcher: &chainMock.ChainService{State: state},
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
}
|
}
|
||||||
@@ -666,9 +664,7 @@ func TestServer_ListIndexedAttestations_OldEpoch(t *testing.T) {
|
|||||||
|
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
GenesisTimeFetcher: &chainMock.ChainService{
|
ClockProvider: &chainMock.ChainService{},
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
}
|
}
|
||||||
err = db.SaveStateSummary(ctx, ðpb.StateSummary{
|
err = db.SaveStateSummary(ctx, ðpb.StateSummary{
|
||||||
@@ -831,9 +827,7 @@ func TestServer_StreamIndexedAttestations_ContextCanceled(t *testing.T) {
|
|||||||
server := &Server{
|
server := &Server{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
AttestationNotifier: chainService.OperationNotifier(),
|
AttestationNotifier: chainService.OperationNotifier(),
|
||||||
GenesisTimeFetcher: &chainMock.ChainService{
|
ClockProvider: &chainMock.ChainService{},
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exitRoutine := make(chan bool)
|
exitRoutine := make(chan bool)
|
||||||
@@ -935,9 +929,7 @@ func TestServer_StreamIndexedAttestations_OK(t *testing.T) {
|
|||||||
HeadFetcher: &chainMock.ChainService{
|
HeadFetcher: &chainMock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &chainMock.ChainService{
|
ClockProvider: &chainMock.ChainService{},
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
AttestationNotifier: chainService.OperationNotifier(),
|
AttestationNotifier: chainService.OperationNotifier(),
|
||||||
CollectedAttestationsBuffer: make(chan []*ethpb.Attestation, 1),
|
CollectedAttestationsBuffer: make(chan []*ethpb.Attestation, 1),
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ func (bs *Server) ListBeaconCommittees(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *ethpb.ListCommitteesRequest,
|
req *ethpb.ListCommitteesRequest,
|
||||||
) (*ethpb.BeaconCommittees, error) {
|
) (*ethpb.BeaconCommittees, error) {
|
||||||
currentSlot := bs.GenesisTimeFetcher.CurrentSlot()
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
currentSlot := c.CurrentSlot()
|
||||||
var requestedSlot types.Slot
|
var requestedSlot types.Slot
|
||||||
switch q := req.QueryFilter.(type) {
|
switch q := req.QueryFilter.(type) {
|
||||||
case *ethpb.ListCommitteesRequest_Epoch:
|
case *ethpb.ListCommitteesRequest_Epoch:
|
||||||
@@ -74,7 +78,11 @@ func (bs *Server) retrieveCommitteesForEpoch(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
requestedState, err := bs.ReplayerBuilder.ReplayerForSlot(startSlot).ReplayBlocks(ctx)
|
b, err := bs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
requestedState, err := b.ReplayerForSlot(startSlot).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, status.Errorf(codes.Internal, "error replaying blocks for state at slot %d: %v", startSlot, err)
|
return nil, nil, status.Errorf(codes.Internal, "error replaying blocks for state at slot %d: %v", startSlot, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package beacon
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -35,12 +36,13 @@ func TestServer_ListBeaconCommittees_CurrentEpoch(t *testing.T) {
|
|||||||
headState := setupActiveValidators(t, numValidators)
|
headState := setupActiveValidators(t, numValidators)
|
||||||
|
|
||||||
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
m := &mock.ChainService{
|
m := &mock.ChainService{
|
||||||
Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second),
|
Clock: blockchain.NewClock(gent),
|
||||||
}
|
}
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: m,
|
HeadFetcher: m,
|
||||||
GenesisTimeFetcher: m,
|
ClockProvider: m,
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
}
|
}
|
||||||
b := util.NewBeaconBlock()
|
b := util.NewBeaconBlock()
|
||||||
@@ -106,13 +108,14 @@ func TestServer_ListBeaconCommittees_PreviousEpoch(t *testing.T) {
|
|||||||
require.NoError(t, db.SaveState(ctx, headState, gRoot))
|
require.NoError(t, db.SaveState(ctx, headState, gRoot))
|
||||||
|
|
||||||
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
m := &mock.ChainService{
|
m := &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second),
|
Clock: blockchain.NewClock(gent),
|
||||||
}
|
}
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: m,
|
HeadFetcher: m,
|
||||||
GenesisTimeFetcher: m,
|
ClockProvider: m,
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, db)
|
addDefaultReplayerBuilder(bs, db)
|
||||||
@@ -162,12 +165,13 @@ func TestRetrieveCommitteesForRoot(t *testing.T) {
|
|||||||
headState := setupActiveValidators(t, numValidators)
|
headState := setupActiveValidators(t, numValidators)
|
||||||
|
|
||||||
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
m := &mock.ChainService{
|
m := &mock.ChainService{
|
||||||
Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second),
|
Clock: blockchain.NewClock(gent),
|
||||||
}
|
}
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: m,
|
HeadFetcher: m,
|
||||||
GenesisTimeFetcher: m,
|
ClockProvider: m,
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
}
|
}
|
||||||
b := util.NewBeaconBlock()
|
b := util.NewBeaconBlock()
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ type Server struct {
|
|||||||
FinalizationFetcher blockchain.FinalizationFetcher
|
FinalizationFetcher blockchain.FinalizationFetcher
|
||||||
DepositFetcher depositcache.DepositFetcher
|
DepositFetcher depositcache.DepositFetcher
|
||||||
BlockFetcher powchain.POWBlockFetcher
|
BlockFetcher powchain.POWBlockFetcher
|
||||||
GenesisTimeFetcher blockchain.TimeFetcher
|
|
||||||
StateNotifier statefeed.Notifier
|
StateNotifier statefeed.Notifier
|
||||||
BlockNotifier blockfeed.Notifier
|
BlockNotifier blockfeed.Notifier
|
||||||
AttestationNotifier operation.Notifier
|
AttestationNotifier operation.Notifier
|
||||||
@@ -44,8 +43,9 @@ type Server struct {
|
|||||||
ReceivedAttestationsBuffer chan *ethpb.Attestation
|
ReceivedAttestationsBuffer chan *ethpb.Attestation
|
||||||
CollectedAttestationsBuffer chan []*ethpb.Attestation
|
CollectedAttestationsBuffer chan []*ethpb.Attestation
|
||||||
StateGen stategen.StateManager
|
StateGen stategen.StateManager
|
||||||
SyncChecker sync.Checker
|
SyncChecker sync.Checker
|
||||||
ReplayerBuilder stategen.ReplayerBuilder
|
CanonicalHistoryWaiter stategen.CanonicalHistoryWaiter
|
||||||
HeadUpdater blockchain.HeadUpdater
|
HeadUpdater blockchain.HeadUpdater
|
||||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||||
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,11 @@ func (bs *Server) ListValidatorBalances(
|
|||||||
req.PageSize, cmd.Get().MaxRPCPageSize)
|
req.PageSize, cmd.Get().MaxRPCPageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
if bs.GenesisTimeFetcher == nil {
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
return nil, status.Errorf(codes.Internal, "Nil genesis time fetcher")
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
}
|
}
|
||||||
currentEpoch := slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot())
|
currentEpoch := slots.ToEpoch(c.CurrentSlot())
|
||||||
requestedEpoch := currentEpoch
|
requestedEpoch := currentEpoch
|
||||||
switch q := req.QueryFilter.(type) {
|
switch q := req.QueryFilter.(type) {
|
||||||
case *ethpb.ListValidatorBalancesRequest_Epoch:
|
case *ethpb.ListValidatorBalancesRequest_Epoch:
|
||||||
@@ -65,7 +66,11 @@ func (bs *Server) ListValidatorBalances(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
requestedState, err := bs.ReplayerBuilder.ReplayerForSlot(startSlot).ReplayBlocks(ctx)
|
b, err := bs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
requestedState, err := b.ReplayerForSlot(startSlot).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", startSlot, err))
|
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", startSlot, err))
|
||||||
}
|
}
|
||||||
@@ -193,7 +198,11 @@ func (bs *Server) ListValidators(
|
|||||||
req.PageSize, cmd.Get().MaxRPCPageSize)
|
req.PageSize, cmd.Get().MaxRPCPageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
currentEpoch := slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot())
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
currentEpoch := slots.ToEpoch(c.CurrentSlot())
|
||||||
requestedEpoch := currentEpoch
|
requestedEpoch := currentEpoch
|
||||||
|
|
||||||
switch q := req.QueryFilter.(type) {
|
switch q := req.QueryFilter.(type) {
|
||||||
@@ -213,14 +222,17 @@ func (bs *Server) ListValidators(
|
|||||||
requestedEpoch = q.Epoch
|
requestedEpoch = q.Epoch
|
||||||
}
|
}
|
||||||
var reqState state.BeaconState
|
var reqState state.BeaconState
|
||||||
var err error
|
|
||||||
if requestedEpoch != currentEpoch {
|
if requestedEpoch != currentEpoch {
|
||||||
var s types.Slot
|
var s types.Slot
|
||||||
s, err = slots.EpochStart(requestedEpoch)
|
s, err = slots.EpochStart(requestedEpoch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
reqState, err = bs.ReplayerBuilder.ReplayerForSlot(s).ReplayBlocks(ctx)
|
b, err := bs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
reqState, err = b.ReplayerForSlot(s).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", s, err))
|
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", s, err))
|
||||||
}
|
}
|
||||||
@@ -391,7 +403,11 @@ func (bs *Server) GetValidator(
|
|||||||
func (bs *Server) GetValidatorActiveSetChanges(
|
func (bs *Server) GetValidatorActiveSetChanges(
|
||||||
ctx context.Context, req *ethpb.GetValidatorActiveSetChangesRequest,
|
ctx context.Context, req *ethpb.GetValidatorActiveSetChangesRequest,
|
||||||
) (*ethpb.ActiveSetChanges, error) {
|
) (*ethpb.ActiveSetChanges, error) {
|
||||||
currentEpoch := slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot())
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
currentEpoch := slots.ToEpoch(c.CurrentSlot())
|
||||||
|
|
||||||
var requestedEpoch types.Epoch
|
var requestedEpoch types.Epoch
|
||||||
switch q := req.QueryFilter.(type) {
|
switch q := req.QueryFilter.(type) {
|
||||||
@@ -415,7 +431,11 @@ func (bs *Server) GetValidatorActiveSetChanges(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
requestedState, err := bs.ReplayerBuilder.ReplayerForSlot(s).ReplayBlocks(ctx)
|
b, err := bs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
requestedState, err := b.ReplayerForSlot(s).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", s, err))
|
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", s, err))
|
||||||
}
|
}
|
||||||
@@ -476,7 +496,11 @@ func (bs *Server) GetValidatorActiveSetChanges(
|
|||||||
func (bs *Server) GetValidatorParticipation(
|
func (bs *Server) GetValidatorParticipation(
|
||||||
ctx context.Context, req *ethpb.GetValidatorParticipationRequest,
|
ctx context.Context, req *ethpb.GetValidatorParticipationRequest,
|
||||||
) (*ethpb.ValidatorParticipationResponse, error) {
|
) (*ethpb.ValidatorParticipationResponse, error) {
|
||||||
currentSlot := bs.GenesisTimeFetcher.CurrentSlot()
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
currentSlot := c.CurrentSlot()
|
||||||
currentEpoch := slots.ToEpoch(currentSlot)
|
currentEpoch := slots.ToEpoch(currentSlot)
|
||||||
|
|
||||||
var requestedEpoch types.Epoch
|
var requestedEpoch types.Epoch
|
||||||
@@ -512,7 +536,11 @@ func (bs *Server) GetValidatorParticipation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReplayerBuilder ensures that a canonical chain is followed to the slot
|
// ReplayerBuilder ensures that a canonical chain is followed to the slot
|
||||||
beaconState, err := bs.ReplayerBuilder.ReplayerForSlot(endSlot).ReplayBlocks(ctx)
|
rb, err := bs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
beaconState, err := rb.ReplayerForSlot(endSlot).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", endSlot, err))
|
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", endSlot, err))
|
||||||
}
|
}
|
||||||
@@ -660,12 +688,16 @@ func (bs *Server) GetValidatorPerformance(
|
|||||||
if bs.SyncChecker.Syncing() {
|
if bs.SyncChecker.Syncing() {
|
||||||
return nil, status.Errorf(codes.Unavailable, "Syncing to latest head, not ready to respond")
|
return nil, status.Errorf(codes.Unavailable, "Syncing to latest head, not ready to respond")
|
||||||
}
|
}
|
||||||
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
headState, err := bs.HeadFetcher.HeadState(ctx)
|
headState, err := bs.HeadFetcher.HeadState(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "Could not get head state: %v", err)
|
return nil, status.Errorf(codes.Internal, "Could not get head state: %v", err)
|
||||||
}
|
}
|
||||||
currSlot := bs.GenesisTimeFetcher.CurrentSlot()
|
currSlot := c.CurrentSlot()
|
||||||
|
|
||||||
if currSlot > headState.Slot() {
|
if currSlot > headState.Slot() {
|
||||||
headRoot, err := bs.HeadFetcher.HeadRoot(ctx)
|
headRoot, err := bs.HeadFetcher.HeadRoot(ctx)
|
||||||
@@ -817,7 +849,11 @@ func (bs *Server) GetIndividualVotes(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *ethpb.IndividualVotesRequest,
|
req *ethpb.IndividualVotesRequest,
|
||||||
) (*ethpb.IndividualVotesRespond, error) {
|
) (*ethpb.IndividualVotesRespond, error) {
|
||||||
currentEpoch := slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot())
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
currentEpoch := slots.ToEpoch(c.CurrentSlot())
|
||||||
if req.Epoch > currentEpoch {
|
if req.Epoch > currentEpoch {
|
||||||
return nil, status.Errorf(
|
return nil, status.Errorf(
|
||||||
codes.InvalidArgument,
|
codes.InvalidArgument,
|
||||||
@@ -831,7 +867,11 @@ func (bs *Server) GetIndividualVotes(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
st, err := bs.ReplayerBuilder.ReplayerForSlot(s).ReplayBlocks(ctx)
|
b, err := bs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
st, err := b.ReplayerForSlot(s).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to replay blocks for state at epoch %d: %v", req.Epoch, err)
|
return nil, status.Errorf(codes.Internal, "failed to replay blocks for state at epoch %d: %v", req.Epoch, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -51,19 +52,21 @@ func TestServer_GetValidatorActiveSetChanges_CannotRequestFutureEpoch(t *testing
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, st.SetSlot(0))
|
require.NoError(t, st.SetSlot(0))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
},
|
},
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
wanted := errNoEpochInfoError
|
wanted := errNoEpochInfoError
|
||||||
_, err = bs.GetValidatorActiveSetChanges(
|
_, err = bs.GetValidatorActiveSetChanges(
|
||||||
ctx,
|
ctx,
|
||||||
ðpb.GetValidatorActiveSetChangesRequest{
|
ðpb.GetValidatorActiveSetChangesRequest{
|
||||||
QueryFilter: ðpb.GetValidatorActiveSetChangesRequest_Epoch{
|
QueryFilter: ðpb.GetValidatorActiveSetChangesRequest_Epoch{
|
||||||
Epoch: slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) + 1,
|
Epoch: slots.ToEpoch(c.CurrentSlot()) + 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -82,15 +85,17 @@ func TestServer_ListValidatorBalances_CannotRequestFutureEpoch(t *testing.T) {
|
|||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
|
|
||||||
wanted := errNoEpochInfoError
|
wanted := errNoEpochInfoError
|
||||||
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
_, err = bs.ListValidatorBalances(
|
_, err = bs.ListValidatorBalances(
|
||||||
ctx,
|
ctx,
|
||||||
ðpb.ListValidatorBalancesRequest{
|
ðpb.ListValidatorBalancesRequest{
|
||||||
QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{
|
QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{
|
||||||
Epoch: slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) + 1,
|
Epoch: slots.ToEpoch(c.CurrentSlot()) + 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -105,7 +110,7 @@ func TestServer_ListValidatorBalances_NoResults(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, st.SetSlot(0))
|
require.NoError(t, st.SetSlot(0))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +177,7 @@ func TestServer_ListValidatorBalances_DefaultResponse_NoArchive(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
||||||
require.NoError(t, beaconDB.SaveState(ctx, st, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, st, gRoot))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
@@ -201,7 +206,7 @@ func TestServer_ListValidatorBalances_PaginationOutOfRange(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
||||||
|
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
@@ -250,7 +255,7 @@ func TestServer_ListValidatorBalances_Pagination_Default(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
||||||
|
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
@@ -334,7 +339,7 @@ func TestServer_ListValidatorBalances_Pagination_CustomPageSizes(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
||||||
|
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
@@ -402,7 +407,7 @@ func TestServer_ListValidatorBalances_OutOfRange(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
||||||
|
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
@@ -425,10 +430,7 @@ func TestServer_ListValidators_CannotRequestFutureEpoch(t *testing.T) {
|
|||||||
require.NoError(t, st.SetSlot(0))
|
require.NoError(t, st.SetSlot(0))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
},
|
},
|
||||||
@@ -449,12 +451,10 @@ func TestServer_ListValidators_CannotRequestFutureEpoch(t *testing.T) {
|
|||||||
func TestServer_ListValidators_reqStateIsNil(t *testing.T) {
|
func TestServer_ListValidators_reqStateIsNil(t *testing.T) {
|
||||||
beaconDB := dbTest.SetupDB(t)
|
beaconDB := dbTest.SetupDB(t)
|
||||||
secondsPerEpoch := params.BeaconConfig().SecondsPerSlot * uint64(params.BeaconConfig().SlotsPerEpoch)
|
secondsPerEpoch := params.BeaconConfig().SecondsPerSlot * uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||||
|
gent := time.Now().Add(time.Duration(-1*int64(secondsPerEpoch)) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
// We are in epoch 1.
|
|
||||||
Genesis: time.Now().Add(time.Duration(-1*int64(secondsPerEpoch)) * time.Second),
|
|
||||||
},
|
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: nil,
|
State: nil,
|
||||||
},
|
},
|
||||||
@@ -492,10 +492,7 @@ func TestServer_ListValidators_NoResults(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, st, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, st, gRoot))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
},
|
},
|
||||||
@@ -562,10 +559,7 @@ func TestServer_ListValidators_OnlyActiveValidators(t *testing.T) {
|
|||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,10 +624,7 @@ func TestServer_ListValidators_InactiveInTheMiddle(t *testing.T) {
|
|||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,7 +656,7 @@ func TestServer_ListValidatorBalances_UnknownValidatorInResponse(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, headState, gRoot))
|
||||||
|
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
@@ -715,10 +706,7 @@ func TestServer_ListValidators_NoPagination(t *testing.T) {
|
|||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
FinalizationFetcher: &mock.ChainService{
|
FinalizationFetcher: &mock.ChainService{
|
||||||
FinalizedCheckPoint: ðpb.Checkpoint{
|
FinalizedCheckPoint: ðpb.Checkpoint{
|
||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
@@ -748,10 +736,7 @@ func TestServer_ListValidators_StategenNotUsed(t *testing.T) {
|
|||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
received, err := bs.ListValidators(context.Background(), ðpb.ListValidatorsRequest{})
|
received, err := bs.ListValidators(context.Background(), ðpb.ListValidatorsRequest{})
|
||||||
@@ -786,10 +771,7 @@ func TestServer_ListValidators_IndicesPubKeys(t *testing.T) {
|
|||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -822,10 +804,7 @@ func TestServer_ListValidators_Pagination(t *testing.T) {
|
|||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -959,10 +938,7 @@ func TestServer_ListValidators_PaginationOutOfRange(t *testing.T) {
|
|||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1003,10 +979,7 @@ func TestServer_ListValidators_DefaultPageSize(t *testing.T) {
|
|||||||
Epoch: 0,
|
Epoch: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{},
|
||||||
// We are in epoch 0.
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1045,13 +1018,12 @@ func TestServer_ListValidators_FromOldEpoch(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, r))
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, r))
|
||||||
|
|
||||||
secondsPerEpoch := params.BeaconConfig().SecondsPerSlot * uint64(params.BeaconConfig().SlotsPerEpoch)
|
secondsPerEpoch := params.BeaconConfig().SecondsPerSlot * uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||||
|
gent := time.Now().Add(time.Duration(-1*int64(uint64(epochs)*secondsPerEpoch)) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
Genesis: time.Now().Add(time.Duration(-1*int64(uint64(epochs)*secondsPerEpoch)) * time.Second),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, beaconDB)
|
addDefaultReplayerBuilder(bs, beaconDB)
|
||||||
|
|
||||||
@@ -1124,13 +1096,12 @@ func TestServer_ListValidators_ProcessHeadStateSlots(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, st, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, st, gRoot))
|
||||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
||||||
secondsPerEpoch := params.BeaconConfig().SecondsPerSlot * uint64(params.BeaconConfig().SlotsPerEpoch)
|
secondsPerEpoch := params.BeaconConfig().SecondsPerSlot * uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||||
|
gent := time.Now().Add(time.Duration(-1*int64(secondsPerEpoch)) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
Genesis: time.Now().Add(time.Duration(-1*int64(secondsPerEpoch)) * time.Second),
|
|
||||||
},
|
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1283,7 +1254,7 @@ func TestServer_GetValidatorActiveSetChanges(t *testing.T) {
|
|||||||
FinalizationFetcher: &mock.ChainService{
|
FinalizationFetcher: &mock.ChainService{
|
||||||
FinalizedCheckPoint: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, fieldparams.RootLength)},
|
FinalizedCheckPoint: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, fieldparams.RootLength)},
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, beaconDB)
|
addDefaultReplayerBuilder(bs, beaconDB)
|
||||||
res, err := bs.GetValidatorActiveSetChanges(ctx, ðpb.GetValidatorActiveSetChangesRequest{
|
res, err := bs.GetValidatorActiveSetChanges(ctx, ðpb.GetValidatorActiveSetChangesRequest{
|
||||||
@@ -1487,16 +1458,18 @@ func TestServer_GetValidatorParticipation_CannotRequestFutureEpoch(t *testing.T)
|
|||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
}
|
}
|
||||||
|
|
||||||
wanted := "Cannot retrieve information about an epoch"
|
wanted := "Cannot retrieve information about an epoch"
|
||||||
|
c, err := bs.ClockProvider.WaitForClock(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
_, err = bs.GetValidatorParticipation(
|
_, err = bs.GetValidatorParticipation(
|
||||||
ctx,
|
ctx,
|
||||||
ðpb.GetValidatorParticipationRequest{
|
ðpb.GetValidatorParticipationRequest{
|
||||||
QueryFilter: ðpb.GetValidatorParticipationRequest_Epoch{
|
QueryFilter: ðpb.GetValidatorParticipationRequest_Epoch{
|
||||||
Epoch: slots.ToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) + 1,
|
Epoch: slots.ToEpoch(c.CurrentSlot()) + 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -1550,13 +1523,12 @@ func TestServer_GetValidatorParticipation_CurrentAndPrevEpoch(t *testing.T) {
|
|||||||
|
|
||||||
m := &mock.ChainService{State: headState}
|
m := &mock.ChainService{State: headState}
|
||||||
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
HeadFetcher: m,
|
HeadFetcher: m,
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second),
|
|
||||||
},
|
|
||||||
CanonicalFetcher: &mock.ChainService{
|
CanonicalFetcher: &mock.ChainService{
|
||||||
CanonicalRoots: map[[32]byte]bool{
|
CanonicalRoots: map[[32]byte]bool{
|
||||||
bRoot: true,
|
bRoot: true,
|
||||||
@@ -1629,13 +1601,12 @@ func TestServer_GetValidatorParticipation_OrphanedUntilGenesis(t *testing.T) {
|
|||||||
|
|
||||||
m := &mock.ChainService{State: headState}
|
m := &mock.ChainService{State: headState}
|
||||||
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
HeadFetcher: m,
|
HeadFetcher: m,
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent),
|
||||||
Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second),
|
|
||||||
},
|
|
||||||
CanonicalFetcher: &mock.ChainService{
|
CanonicalFetcher: &mock.ChainService{
|
||||||
CanonicalRoots: map[[32]byte]bool{
|
CanonicalRoots: map[[32]byte]bool{
|
||||||
bRoot: true,
|
bRoot: true,
|
||||||
@@ -1726,13 +1697,12 @@ func runGetValidatorParticipationCurrentAndPrevEpoch(t *testing.T, genState stat
|
|||||||
|
|
||||||
m := &mock.ChainService{State: genState}
|
m := &mock.ChainService{State: genState}
|
||||||
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: beaconDB,
|
BeaconDB: beaconDB,
|
||||||
HeadFetcher: m,
|
HeadFetcher: m,
|
||||||
StateGen: stategen.New(beaconDB),
|
StateGen: stategen.New(beaconDB),
|
||||||
GenesisTimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second),
|
|
||||||
},
|
|
||||||
FinalizationFetcher: &mock.ChainService{FinalizedCheckPoint: ðpb.Checkpoint{Epoch: 100}},
|
FinalizationFetcher: &mock.ChainService{FinalizedCheckPoint: ðpb.Checkpoint{Epoch: 100}},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, beaconDB)
|
addDefaultReplayerBuilder(bs, beaconDB)
|
||||||
@@ -1837,11 +1807,12 @@ func TestGetValidatorPerformance_OK(t *testing.T) {
|
|||||||
require.NoError(t, headState.SetValidators(validators))
|
require.NoError(t, headState.SetValidators(validators))
|
||||||
require.NoError(t, headState.SetBalances([]uint64{100, 101, 102}))
|
require.NoError(t, headState.SetBalances([]uint64{100, 101, 102}))
|
||||||
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
}
|
}
|
||||||
farFuture := params.BeaconConfig().FarFutureSlot
|
farFuture := params.BeaconConfig().FarFutureSlot
|
||||||
@@ -1901,13 +1872,14 @@ func TestGetValidatorPerformance_Indices(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, headState.SetValidators(validators))
|
require.NoError(t, headState.SetValidators(validators))
|
||||||
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
// 10 epochs into the future.
|
// 10 epochs into the future.
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
}
|
}
|
||||||
c := headState.Copy()
|
c := headState.Copy()
|
||||||
vp, bp, err := precompute.New(ctx, c)
|
vp, bp, err := precompute.New(ctx, c)
|
||||||
@@ -1974,13 +1946,14 @@ func TestGetValidatorPerformance_IndicesPubkeys(t *testing.T) {
|
|||||||
require.NoError(t, headState.SetValidators(validators))
|
require.NoError(t, headState.SetValidators(validators))
|
||||||
|
|
||||||
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
// 10 epochs into the future.
|
// 10 epochs into the future.
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
}
|
}
|
||||||
c := headState.Copy()
|
c := headState.Copy()
|
||||||
vp, bp, err := precompute.New(ctx, c)
|
vp, bp, err := precompute.New(ctx, c)
|
||||||
@@ -2053,11 +2026,12 @@ func TestGetValidatorPerformanceAltair_OK(t *testing.T) {
|
|||||||
require.NoError(t, headState.SetInactivityScores([]uint64{0, 0, 0}))
|
require.NoError(t, headState.SetInactivityScores([]uint64{0, 0, 0}))
|
||||||
require.NoError(t, headState.SetBalances([]uint64{100, 101, 102}))
|
require.NoError(t, headState.SetBalances([]uint64{100, 101, 102}))
|
||||||
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
}
|
}
|
||||||
want := ðpb.ValidatorPerformanceResponse{
|
want := ðpb.ValidatorPerformanceResponse{
|
||||||
@@ -2123,11 +2097,13 @@ func TestGetValidatorPerformanceBellatrix_OK(t *testing.T) {
|
|||||||
require.NoError(t, headState.SetInactivityScores([]uint64{0, 0, 0}))
|
require.NoError(t, headState.SetInactivityScores([]uint64{0, 0, 0}))
|
||||||
require.NoError(t, headState.SetBalances([]uint64{100, 101, 102}))
|
require.NoError(t, headState.SetBalances([]uint64{100, 101, 102}))
|
||||||
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
|
clock := blockchain.NewClock(gent)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: &mock.ChainService{
|
||||||
State: headState,
|
State: headState,
|
||||||
},
|
},
|
||||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: clock},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
}
|
}
|
||||||
want := ðpb.ValidatorPerformanceResponse{
|
want := ðpb.ValidatorPerformanceResponse{
|
||||||
@@ -2194,12 +2170,14 @@ func setupValidators(t testing.TB, _ db.Database, count int) ([]*ethpb.Validator
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_GetIndividualVotes_RequestFutureSlot(t *testing.T) {
|
func TestServer_GetIndividualVotes_RequestFutureSlot(t *testing.T) {
|
||||||
ds := &Server{GenesisTimeFetcher: &mock.ChainService{}}
|
ds := &Server{ClockProvider: &mock.ChainService{}}
|
||||||
|
c, err := ds.ClockProvider.WaitForClock(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
req := ðpb.IndividualVotesRequest{
|
req := ðpb.IndividualVotesRequest{
|
||||||
Epoch: slots.ToEpoch(ds.GenesisTimeFetcher.CurrentSlot()) + 1,
|
Epoch: slots.ToEpoch(c.CurrentSlot()) + 1,
|
||||||
}
|
}
|
||||||
wanted := errNoEpochInfoError
|
wanted := errNoEpochInfoError
|
||||||
_, err := ds.GetIndividualVotes(context.Background(), req)
|
_, err = ds.GetIndividualVotes(context.Background(), req)
|
||||||
assert.ErrorContains(t, wanted, err)
|
assert.ErrorContains(t, wanted, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2229,7 +2207,7 @@ func TestServer_GetIndividualVotes_ValidatorsDontExist(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
StateGen: gen,
|
StateGen: gen,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, beaconDB)
|
addDefaultReplayerBuilder(bs, beaconDB)
|
||||||
|
|
||||||
@@ -2325,7 +2303,7 @@ func TestServer_GetIndividualVotes_Working(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
StateGen: gen,
|
StateGen: gen,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, beaconDB)
|
addDefaultReplayerBuilder(bs, beaconDB)
|
||||||
|
|
||||||
@@ -2390,7 +2368,7 @@ func TestServer_GetIndividualVotes_WorkingAltair(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
StateGen: gen,
|
StateGen: gen,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, beaconDB)
|
addDefaultReplayerBuilder(bs, beaconDB)
|
||||||
|
|
||||||
@@ -2476,7 +2454,7 @@ func TestServer_GetIndividualVotes_AltairEndOfEpoch(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, beaconState, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, beaconState, gRoot))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
StateGen: gen,
|
StateGen: gen,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, beaconDB)
|
addDefaultReplayerBuilder(bs, beaconDB)
|
||||||
|
|
||||||
@@ -2564,7 +2542,7 @@ func TestServer_GetIndividualVotes_BellatrixEndOfEpoch(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveState(ctx, beaconState, gRoot))
|
require.NoError(t, beaconDB.SaveState(ctx, beaconState, gRoot))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
StateGen: gen,
|
StateGen: gen,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, beaconDB)
|
addDefaultReplayerBuilder(bs, beaconDB)
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ go_test(
|
|||||||
],
|
],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/blockchain/testing:go_default_library",
|
"//beacon-chain/blockchain/testing:go_default_library",
|
||||||
"//beacon-chain/core/helpers:go_default_library",
|
"//beacon-chain/core/helpers:go_default_library",
|
||||||
"//beacon-chain/db/testing:go_default_library",
|
"//beacon-chain/db/testing:go_default_library",
|
||||||
|
|||||||
@@ -41,12 +41,14 @@ func (ds *Server) GetBlock(
|
|||||||
|
|
||||||
// GetInclusionSlot of an attestation in block.
|
// GetInclusionSlot of an attestation in block.
|
||||||
func (ds *Server) GetInclusionSlot(ctx context.Context, req *pbrpc.InclusionSlotRequest) (*pbrpc.InclusionSlotResponse, error) {
|
func (ds *Server) GetInclusionSlot(ctx context.Context, req *pbrpc.InclusionSlotRequest) (*pbrpc.InclusionSlotResponse, error) {
|
||||||
ds.GenesisTimeFetcher.CurrentSlot()
|
c, err := ds.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
// Attestation has one epoch to get included in the chain. This blocks users from requesting too soon.
|
// Attestation has one epoch to get included in the chain. This blocks users from requesting too soon.
|
||||||
epochBack := types.Slot(0)
|
epochBack := types.Slot(0)
|
||||||
if ds.GenesisTimeFetcher.CurrentSlot() > params.BeaconConfig().SlotsPerEpoch {
|
if c.CurrentSlot() > params.BeaconConfig().SlotsPerEpoch {
|
||||||
epochBack = ds.GenesisTimeFetcher.CurrentSlot() - params.BeaconConfig().SlotsPerEpoch
|
epochBack = c.CurrentSlot() - params.BeaconConfig().SlotsPerEpoch
|
||||||
}
|
}
|
||||||
if epochBack < req.Slot {
|
if epochBack < req.Slot {
|
||||||
return nil, fmt.Errorf("attestation has one epoch window, please request slot older than %d", epochBack)
|
return nil, fmt.Errorf("attestation has one epoch window, please request slot older than %d", epochBack)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
@@ -51,10 +52,11 @@ func TestServer_GetAttestationInclusionSlot(t *testing.T) {
|
|||||||
db := dbTest.SetupDB(t)
|
db := dbTest.SetupDB(t)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
offset := int64(2 * params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(2 * params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(gent)},
|
||||||
}
|
}
|
||||||
|
|
||||||
s, _ := util.DeterministicGenesisState(t, 2048)
|
s, _ := util.DeterministicGenesisState(t, 2048)
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ import (
|
|||||||
// gated behind the feature flag --enable-debug-rpc-endpoints.
|
// gated behind the feature flag --enable-debug-rpc-endpoints.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
BeaconDB db.NoHeadAccessDatabase
|
BeaconDB db.NoHeadAccessDatabase
|
||||||
GenesisTimeFetcher blockchain.TimeFetcher
|
|
||||||
StateGen *stategen.State
|
StateGen *stategen.State
|
||||||
HeadFetcher blockchain.HeadFetcher
|
HeadFetcher blockchain.HeadFetcher
|
||||||
ForkFetcher blockchain.ForkFetcher
|
ForkFetcher blockchain.ForkFetcher
|
||||||
PeerManager p2p.PeerManager
|
PeerManager p2p.PeerManager
|
||||||
PeersFetcher p2p.PeersProvider
|
PeersFetcher p2p.PeersProvider
|
||||||
ReplayerBuilder stategen.ReplayerBuilder
|
CanonicalHistoryWaiter stategen.CanonicalHistoryWaiter
|
||||||
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLoggingLevel of a beacon node according to a request type,
|
// SetLoggingLevel of a beacon node according to a request type,
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ func (ds *Server) GetBeaconState(
|
|||||||
) (*pbrpc.SSZResponse, error) {
|
) (*pbrpc.SSZResponse, error) {
|
||||||
switch q := req.QueryFilter.(type) {
|
switch q := req.QueryFilter.(type) {
|
||||||
case *pbrpc.BeaconStateRequest_Slot:
|
case *pbrpc.BeaconStateRequest_Slot:
|
||||||
currentSlot := ds.GenesisTimeFetcher.CurrentSlot()
|
c, err := ds.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
currentSlot := c.CurrentSlot()
|
||||||
requestedSlot := q.Slot
|
requestedSlot := q.Slot
|
||||||
if requestedSlot > currentSlot {
|
if requestedSlot > currentSlot {
|
||||||
return nil, status.Errorf(
|
return nil, status.Errorf(
|
||||||
@@ -29,7 +33,11 @@ func (ds *Server) GetBeaconState(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
st, err := ds.ReplayerBuilder.ReplayerForSlot(q.Slot).ReplayBlocks(ctx)
|
b, err := ds.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
st, err := b.ReplayerForSlot(q.Slot).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", q.Slot, err))
|
return nil, status.Error(codes.Internal, fmt.Sprintf("error replaying blocks for state at slot %d: %v", q.Slot, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func TestServer_GetBeaconState(t *testing.T) {
|
|||||||
require.NoError(t, db.SaveState(ctx, st, gRoot))
|
require.NoError(t, db.SaveState(ctx, st, gRoot))
|
||||||
bs := &Server{
|
bs := &Server{
|
||||||
StateGen: gen,
|
StateGen: gen,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
}
|
}
|
||||||
addDefaultReplayerBuilder(bs, db)
|
addDefaultReplayerBuilder(bs, db)
|
||||||
_, err = bs.GetBeaconState(ctx, &pbrpc.BeaconStateRequest{})
|
_, err = bs.GetBeaconState(ctx, &pbrpc.BeaconStateRequest{})
|
||||||
@@ -95,13 +95,15 @@ func TestServer_GetBeaconState(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_GetBeaconState_RequestFutureSlot(t *testing.T) {
|
func TestServer_GetBeaconState_RequestFutureSlot(t *testing.T) {
|
||||||
ds := &Server{GenesisTimeFetcher: &mock.ChainService{}}
|
ds := &Server{ClockProvider: &mock.ChainService{}}
|
||||||
|
c, err := ds.ClockProvider.WaitForClock(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
req := &pbrpc.BeaconStateRequest{
|
req := &pbrpc.BeaconStateRequest{
|
||||||
QueryFilter: &pbrpc.BeaconStateRequest_Slot{
|
QueryFilter: &pbrpc.BeaconStateRequest_Slot{
|
||||||
Slot: ds.GenesisTimeFetcher.CurrentSlot() + 1,
|
Slot: c.CurrentSlot() + 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
wanted := "Cannot retrieve information about a slot in the future"
|
wanted := "Cannot retrieve information about a slot in the future"
|
||||||
_, err := ds.GetBeaconState(context.Background(), req)
|
_, err = ds.GetBeaconState(context.Background(), req)
|
||||||
assert.ErrorContains(t, wanted, err)
|
assert.ErrorContains(t, wanted, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ go_test(
|
|||||||
srcs = ["server_test.go"],
|
srcs = ["server_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/blockchain/testing:go_default_library",
|
"//beacon-chain/blockchain/testing:go_default_library",
|
||||||
"//beacon-chain/db/testing:go_default_library",
|
"//beacon-chain/db/testing:go_default_library",
|
||||||
"//beacon-chain/p2p:go_default_library",
|
"//beacon-chain/p2p:go_default_library",
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ type Server struct {
|
|||||||
BeaconDB db.ReadOnlyDatabase
|
BeaconDB db.ReadOnlyDatabase
|
||||||
PeersFetcher p2p.PeersProvider
|
PeersFetcher p2p.PeersProvider
|
||||||
PeerManager p2p.PeerManager
|
PeerManager p2p.PeerManager
|
||||||
GenesisTimeFetcher blockchain.TimeFetcher
|
|
||||||
GenesisFetcher blockchain.GenesisFetcher
|
GenesisFetcher blockchain.GenesisFetcher
|
||||||
POWChainInfoFetcher powchain.ChainInfoFetcher
|
POWChainInfoFetcher powchain.ChainInfoFetcher
|
||||||
BeaconMonitoringHost string
|
BeaconMonitoringHost string
|
||||||
BeaconMonitoringPort int
|
BeaconMonitoringPort int
|
||||||
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSyncStatus checks the current network sync status of the node.
|
// GetSyncStatus checks the current network sync status of the node.
|
||||||
@@ -59,7 +59,11 @@ func (ns *Server) GetGenesis(ctx context.Context, _ *empty.Empty) (*ethpb.Genesi
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "Could not retrieve contract address from db: %v", err)
|
return nil, status.Errorf(codes.Internal, "Could not retrieve contract address from db: %v", err)
|
||||||
}
|
}
|
||||||
genesisTime := ns.GenesisTimeFetcher.GenesisTime()
|
c, err := ns.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
genesisTime := c.GenesisTime()
|
||||||
var defaultGenesisTime time.Time
|
var defaultGenesisTime time.Time
|
||||||
var gt *timestamp.Timestamp
|
var gt *timestamp.Timestamp
|
||||||
if genesisTime == defaultGenesisTime {
|
if genesisTime == defaultGenesisTime {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package node
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ func TestNodeServer_GetGenesis(t *testing.T) {
|
|||||||
genValRoot := bytesutil.ToBytes32([]byte("I am root"))
|
genValRoot := bytesutil.ToBytes32([]byte("I am root"))
|
||||||
ns := &Server{
|
ns := &Server{
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
GenesisTimeFetcher: &mock.ChainService{},
|
ClockProvider: &mock.ChainService{},
|
||||||
GenesisFetcher: &mock.ChainService{
|
GenesisFetcher: &mock.ChainService{
|
||||||
State: st,
|
State: st,
|
||||||
ValidatorsRoot: genValRoot,
|
ValidatorsRoot: genValRoot,
|
||||||
@@ -64,7 +65,7 @@ func TestNodeServer_GetGenesis(t *testing.T) {
|
|||||||
assert.Equal(t, res.GenesisTime.Seconds, pUnix.Seconds)
|
assert.Equal(t, res.GenesisTime.Seconds, pUnix.Seconds)
|
||||||
assert.DeepEqual(t, genValRoot[:], res.GenesisValidatorsRoot)
|
assert.DeepEqual(t, genValRoot[:], res.GenesisValidatorsRoot)
|
||||||
|
|
||||||
ns.GenesisTimeFetcher = &mock.ChainService{Genesis: time.Unix(10, 0)}
|
ns.ClockProvider = &mock.ChainService{Clock: blockchain.NewClock(time.Unix(10, 0))}
|
||||||
res, err = ns.GetGenesis(context.Background(), &emptypb.Empty{})
|
res, err = ns.GetGenesis(context.Background(), &emptypb.Empty{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
pUnix = timestamppb.New(time.Unix(10, 0))
|
pUnix = timestamppb.New(time.Unix(10, 0))
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//async/event:go_default_library",
|
"//async/event:go_default_library",
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/blockchain/testing:go_default_library",
|
"//beacon-chain/blockchain/testing:go_default_library",
|
||||||
"//beacon-chain/builder/testing:go_default_library",
|
"//beacon-chain/builder/testing:go_default_library",
|
||||||
"//beacon-chain/cache:go_default_library",
|
"//beacon-chain/cache:go_default_library",
|
||||||
|
|||||||
@@ -129,9 +129,13 @@ func (vs *Server) SubmitSignedAggregateSelectionProof(
|
|||||||
return nil, status.Error(codes.InvalidArgument, "Signed signatures can't be zero hashes")
|
return nil, status.Error(codes.InvalidArgument, "Signed signatures can't be zero hashes")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout waiting for genesis time initialization, %s", err)
|
||||||
|
}
|
||||||
// As a preventive measure, a beacon node shouldn't broadcast an attestation whose slot is out of range.
|
// As a preventive measure, a beacon node shouldn't broadcast an attestation whose slot is out of range.
|
||||||
if err := helpers.ValidateAttestationTime(req.SignedAggregateAndProof.Message.Aggregate.Data.Slot,
|
if err := helpers.ValidateAttestationTime(req.SignedAggregateAndProof.Message.Aggregate.Data.Slot,
|
||||||
vs.TimeFetcher.GenesisTime(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
c.GenesisTime(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, "Attestation slot is no longer valid from current time")
|
return nil, status.Error(codes.InvalidArgument, "Attestation slot is no longer valid from current time")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package validator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -55,7 +56,7 @@ func TestSubmitAggregateAndProof_CantFindValidatorIndex(t *testing.T) {
|
|||||||
server := &Server{
|
server := &Server{
|
||||||
HeadFetcher: &mock.ChainService{State: s},
|
HeadFetcher: &mock.ChainService{State: s},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
}
|
}
|
||||||
|
|
||||||
priv, err := bls.RandKey()
|
priv, err := bls.RandKey()
|
||||||
@@ -83,7 +84,7 @@ func TestSubmitAggregateAndProof_IsAggregatorAndNoAtts(t *testing.T) {
|
|||||||
HeadFetcher: &mock.ChainService{State: s},
|
HeadFetcher: &mock.ChainService{State: s},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
AttPool: attestations.NewPool(),
|
AttPool: attestations.NewPool(),
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
}
|
}
|
||||||
|
|
||||||
priv, err := bls.RandKey()
|
priv, err := bls.RandKey()
|
||||||
@@ -117,7 +118,7 @@ func TestSubmitAggregateAndProof_UnaggregateOk(t *testing.T) {
|
|||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
AttPool: attestations.NewPool(),
|
AttPool: attestations.NewPool(),
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
}
|
}
|
||||||
|
|
||||||
priv, err := bls.RandKey()
|
priv, err := bls.RandKey()
|
||||||
@@ -155,7 +156,7 @@ func TestSubmitAggregateAndProof_AggregateOk(t *testing.T) {
|
|||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
AttPool: attestations.NewPool(),
|
AttPool: attestations.NewPool(),
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
}
|
}
|
||||||
|
|
||||||
priv, err := bls.RandKey()
|
priv, err := bls.RandKey()
|
||||||
@@ -195,7 +196,7 @@ func TestSubmitAggregateAndProof_AggregateNotOk(t *testing.T) {
|
|||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
AttPool: attestations.NewPool(),
|
AttPool: attestations.NewPool(),
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
}
|
}
|
||||||
|
|
||||||
priv, err := bls.RandKey()
|
priv, err := bls.RandKey()
|
||||||
@@ -324,7 +325,7 @@ func TestSubmitAggregateAndProof_PreferOwnAttestation(t *testing.T) {
|
|||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
AttPool: attestations.NewPool(),
|
AttPool: attestations.NewPool(),
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
}
|
}
|
||||||
|
|
||||||
priv, err := bls.RandKey()
|
priv, err := bls.RandKey()
|
||||||
@@ -375,7 +376,7 @@ func TestSubmitAggregateAndProof_SelectsMostBitsWhenOwnAttestationNotPresent(t *
|
|||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
AttPool: attestations.NewPool(),
|
AttPool: attestations.NewPool(),
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
}
|
}
|
||||||
|
|
||||||
priv, err := bls.RandKey()
|
priv, err := bls.RandKey()
|
||||||
@@ -428,8 +429,8 @@ func TestSubmitSignedAggregateSelectionProof_ZeroHashesSignatures(t *testing.T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSubmitSignedAggregateSelectionProof_InvalidSlot(t *testing.T) {
|
func TestSubmitSignedAggregateSelectionProof_InvalidSlot(t *testing.T) {
|
||||||
c := &mock.ChainService{Genesis: time.Now()}
|
c := &mock.ChainService{Clock: blockchain.NewClock(time.Now())}
|
||||||
aggregatorServer := &Server{TimeFetcher: c}
|
aggregatorServer := &Server{ClockProvider: c}
|
||||||
req := ðpb.SignedAggregateSubmitRequest{
|
req := ðpb.SignedAggregateSubmitRequest{
|
||||||
SignedAggregateAndProof: ðpb.SignedAggregateAttestationAndProof{
|
SignedAggregateAndProof: ðpb.SignedAggregateAttestationAndProof{
|
||||||
Signature: []byte{'a'},
|
Signature: []byte{'a'},
|
||||||
|
|||||||
@@ -41,15 +41,16 @@ func (vs *Server) StreamDuties(req *ethpb.DutiesRequest, stream ethpb.BeaconNode
|
|||||||
return status.Error(codes.Unavailable, "Syncing to latest head, not ready to respond")
|
return status.Error(codes.Unavailable, "Syncing to latest head, not ready to respond")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c, err := vs.ClockProvider.WaitForClock(stream.Context())
|
||||||
|
if err != nil {
|
||||||
|
return status.Errorf(codes.Internal, "timeout waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
// If we are post-genesis time, then set the current epoch to
|
// If we are post-genesis time, then set the current epoch to
|
||||||
// the number epochs since the genesis time, otherwise 0 by default.
|
// the number epochs since the genesis time, otherwise 0 by default.
|
||||||
genesisTime := vs.TimeFetcher.GenesisTime()
|
genesisTime := c.GenesisTime()
|
||||||
if genesisTime.IsZero() {
|
|
||||||
return status.Error(codes.Unavailable, "genesis time is not set")
|
|
||||||
}
|
|
||||||
var currentEpoch types.Epoch
|
var currentEpoch types.Epoch
|
||||||
if genesisTime.Before(prysmTime.Now()) {
|
if genesisTime.Before(c.Now()) {
|
||||||
currentEpoch = slots.EpochsSinceGenesis(vs.TimeFetcher.GenesisTime())
|
currentEpoch = slots.EpochsSinceGenesis(genesisTime)
|
||||||
}
|
}
|
||||||
req.Epoch = currentEpoch
|
req.Epoch = currentEpoch
|
||||||
res, err := vs.duties(stream.Context(), req)
|
res, err := vs.duties(stream.Context(), req)
|
||||||
@@ -66,7 +67,7 @@ func (vs *Server) StreamDuties(req *ethpb.DutiesRequest, stream ethpb.BeaconNode
|
|||||||
defer stateSub.Unsubscribe()
|
defer stateSub.Unsubscribe()
|
||||||
|
|
||||||
secondsPerEpoch := params.BeaconConfig().SecondsPerSlot * uint64(params.BeaconConfig().SlotsPerEpoch)
|
secondsPerEpoch := params.BeaconConfig().SecondsPerSlot * uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||||
epochTicker := slots.NewSlotTicker(vs.TimeFetcher.GenesisTime(), secondsPerEpoch)
|
epochTicker := slots.NewSlotTicker(genesisTime, secondsPerEpoch)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
// Ticks every epoch to submit assignments to connected validator clients.
|
// Ticks every epoch to submit assignments to connected validator clients.
|
||||||
@@ -82,7 +83,7 @@ func (vs *Server) StreamDuties(req *ethpb.DutiesRequest, stream ethpb.BeaconNode
|
|||||||
case ev := <-stateChannel:
|
case ev := <-stateChannel:
|
||||||
// If a reorg occurred, we recompute duties for the connected validator clients
|
// If a reorg occurred, we recompute duties for the connected validator clients
|
||||||
// and send another response over the server stream right away.
|
// and send another response over the server stream right away.
|
||||||
currentEpoch = slots.EpochsSinceGenesis(vs.TimeFetcher.GenesisTime())
|
currentEpoch = slots.EpochsSinceGenesis(genesisTime)
|
||||||
if ev.Type == statefeed.Reorg {
|
if ev.Type == statefeed.Reorg {
|
||||||
data, ok := ev.Data.(*ethpbv1.EventChainReorg)
|
data, ok := ev.Data.(*ethpbv1.EventChainReorg)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -108,7 +109,11 @@ func (vs *Server) StreamDuties(req *ethpb.DutiesRequest, stream ethpb.BeaconNode
|
|||||||
// Compute the validator duties from the head state's corresponding epoch
|
// Compute the validator duties from the head state's corresponding epoch
|
||||||
// for validators public key / indices requested.
|
// for validators public key / indices requested.
|
||||||
func (vs *Server) duties(ctx context.Context, req *ethpb.DutiesRequest) (*ethpb.DutiesResponse, error) {
|
func (vs *Server) duties(ctx context.Context, req *ethpb.DutiesRequest) (*ethpb.DutiesResponse, error) {
|
||||||
currentEpoch := slots.ToEpoch(vs.TimeFetcher.CurrentSlot())
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
currentEpoch := slots.ToEpoch(c.CurrentSlot())
|
||||||
if req.Epoch > currentEpoch+1 {
|
if req.Epoch > currentEpoch+1 {
|
||||||
return nil, status.Errorf(codes.Unavailable, "Request epoch %d can not be greater than next epoch %d", req.Epoch, currentEpoch+1)
|
return nil, status.Errorf(codes.Unavailable, "Request epoch %d can not be greater than next epoch %d", req.Epoch, currentEpoch+1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package validator
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -57,11 +58,13 @@ func TestGetDuties_OK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Genesis: time.Now(),
|
State: bs,
|
||||||
|
Root: genesisRoot[:],
|
||||||
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
||||||
}
|
}
|
||||||
@@ -141,12 +144,15 @@ func TestGetAltairDuties_SyncCommitteeOK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
slot := uint64(params.BeaconConfig().SlotsPerEpoch) * uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod) * params.BeaconConfig().SecondsPerSlot
|
slot := uint64(params.BeaconConfig().SlotsPerEpoch) * uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod) * params.BeaconConfig().SecondsPerSlot
|
||||||
|
gent := time.Now().Add(time.Duration(-1*int64(slot-1)) * time.Second)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Genesis: time.Now().Add(time.Duration(-1*int64(slot-1)) * time.Second),
|
State: bs,
|
||||||
|
Root: genesisRoot[:],
|
||||||
|
Clock: blockchain.NewClock(gent),
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
Eth1InfoFetcher: &mockPOW.POWChain{},
|
Eth1InfoFetcher: &mockPOW.POWChain{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
||||||
@@ -247,12 +253,15 @@ func TestGetBellatrixDuties_SyncCommitteeOK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
slot := uint64(params.BeaconConfig().SlotsPerEpoch) * uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod) * params.BeaconConfig().SecondsPerSlot
|
slot := uint64(params.BeaconConfig().SlotsPerEpoch) * uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod) * params.BeaconConfig().SecondsPerSlot
|
||||||
|
gent := time.Now().Add(time.Duration(-1*int64(slot-1)) * time.Second)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Genesis: time.Now().Add(time.Duration(-1*int64(slot-1)) * time.Second),
|
State: bs,
|
||||||
|
Root: genesisRoot[:],
|
||||||
|
Clock: blockchain.NewClock(gent),
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
Eth1InfoFetcher: &mockPOW.POWChain{},
|
Eth1InfoFetcher: &mockPOW.POWChain{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
||||||
@@ -336,15 +345,18 @@ func TestGetAltairDuties_UnknownPubkey(t *testing.T) {
|
|||||||
require.NoError(t, helpers.UpdateSyncCommitteeCache(bs))
|
require.NoError(t, helpers.UpdateSyncCommitteeCache(bs))
|
||||||
|
|
||||||
slot := uint64(params.BeaconConfig().SlotsPerEpoch) * uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod) * params.BeaconConfig().SecondsPerSlot
|
slot := uint64(params.BeaconConfig().SlotsPerEpoch) * uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod) * params.BeaconConfig().SecondsPerSlot
|
||||||
|
gent := time.Now().Add(time.Duration(-1*int64(slot-1)) * time.Second)
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Genesis: time.Now().Add(time.Duration(-1*int64(slot-1)) * time.Second),
|
State: bs,
|
||||||
|
Root: genesisRoot[:],
|
||||||
|
Clock: blockchain.NewClock(gent),
|
||||||
}
|
}
|
||||||
depositCache, err := depositcache.New()
|
depositCache, err := depositcache.New()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
Eth1InfoFetcher: &mockPOW.POWChain{},
|
Eth1InfoFetcher: &mockPOW.POWChain{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
DepositFetcher: depositCache,
|
DepositFetcher: depositCache,
|
||||||
@@ -365,10 +377,10 @@ func TestGetAltairDuties_UnknownPubkey(t *testing.T) {
|
|||||||
|
|
||||||
func TestGetDuties_SlotOutOfUpperBound(t *testing.T) {
|
func TestGetDuties_SlotOutOfUpperBound(t *testing.T) {
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
Genesis: time.Now(),
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
}
|
}
|
||||||
req := ðpb.DutiesRequest{
|
req := ðpb.DutiesRequest{
|
||||||
Epoch: types.Epoch(chain.CurrentSlot()/params.BeaconConfig().SlotsPerEpoch + 2),
|
Epoch: types.Epoch(chain.CurrentSlot()/params.BeaconConfig().SlotsPerEpoch + 2),
|
||||||
@@ -400,11 +412,13 @@ func TestGetDuties_CurrentEpoch_ShouldNotFail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bState, Root: genesisRoot[:], Genesis: time.Now(),
|
State: bState,
|
||||||
|
Root: genesisRoot[:],
|
||||||
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
||||||
}
|
}
|
||||||
@@ -439,11 +453,12 @@ func TestGetDuties_MultipleKeys_OK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chain := &mockChain.ChainService{
|
chain := &mockChain.ChainService{
|
||||||
State: bs, Root: genesisRoot[:], Genesis: time.Now(),
|
State: bs, Root: genesisRoot[:],
|
||||||
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
HeadFetcher: chain,
|
HeadFetcher: chain,
|
||||||
TimeFetcher: chain,
|
ClockProvider: chain,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
||||||
}
|
}
|
||||||
@@ -506,13 +521,13 @@ func TestStreamDuties_OK(t *testing.T) {
|
|||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
c := &mockChain.ChainService{
|
c := &mockChain.ChainService{
|
||||||
Genesis: time.Now(),
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
HeadFetcher: &mockChain.ChainService{State: bs, Root: genesisRoot[:]},
|
HeadFetcher: &mockChain.ChainService{State: bs, Root: genesisRoot[:]},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: c,
|
ClockProvider: c,
|
||||||
StateNotifier: &mockChain.MockStateNotifier{},
|
StateNotifier: &mockChain.MockStateNotifier{},
|
||||||
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
||||||
}
|
}
|
||||||
@@ -564,13 +579,13 @@ func TestStreamDuties_OK_ChainReorg(t *testing.T) {
|
|||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
c := &mockChain.ChainService{
|
c := &mockChain.ChainService{
|
||||||
Genesis: time.Now(),
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
}
|
}
|
||||||
vs := &Server{
|
vs := &Server{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
HeadFetcher: &mockChain.ChainService{State: bs, Root: genesisRoot[:]},
|
HeadFetcher: &mockChain.ChainService{State: bs, Root: genesisRoot[:]},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: c,
|
ClockProvider: c,
|
||||||
StateNotifier: &mockChain.MockStateNotifier{},
|
StateNotifier: &mockChain.MockStateNotifier{},
|
||||||
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,11 @@ func (vs *Server) GetAttestationData(ctx context.Context, req *ethpb.Attestation
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := helpers.ValidateAttestationTime(req.Slot, vs.TimeFetcher.GenesisTime(),
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if err := helpers.ValidateAttestationTime(req.Slot, c.GenesisTime(),
|
||||||
params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid request: %v", err))
|
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid request: %v", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package validator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -121,6 +122,7 @@ func TestGetAttestationData_OK(t *testing.T) {
|
|||||||
Genesis: time.Now(),
|
Genesis: time.Now(),
|
||||||
}
|
}
|
||||||
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
attesterServer := &Server{
|
attesterServer := &Server{
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
@@ -131,8 +133,8 @@ func TestGetAttestationData_OK(t *testing.T) {
|
|||||||
FinalizationFetcher: &mock.ChainService{
|
FinalizationFetcher: &mock.ChainService{
|
||||||
CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint(),
|
CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint(),
|
||||||
},
|
},
|
||||||
TimeFetcher: &mock.ChainService{
|
ClockProvider: &mock.ChainService{
|
||||||
Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second),
|
Clock: blockchain.NewClock(gent),
|
||||||
},
|
},
|
||||||
StateNotifier: chainService.StateNotifier(),
|
StateNotifier: chainService.StateNotifier(),
|
||||||
}
|
}
|
||||||
@@ -178,7 +180,7 @@ func TestGetAttestationData_Optimistic(t *testing.T) {
|
|||||||
|
|
||||||
as := &Server{
|
as := &Server{
|
||||||
SyncChecker: &mockSync.Sync{},
|
SyncChecker: &mockSync.Sync{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
HeadFetcher: &mock.ChainService{},
|
HeadFetcher: &mock.ChainService{},
|
||||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: true},
|
OptimisticModeFetcher: &mock.ChainService{Optimistic: true},
|
||||||
}
|
}
|
||||||
@@ -192,7 +194,7 @@ func TestGetAttestationData_Optimistic(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
as = &Server{
|
as = &Server{
|
||||||
SyncChecker: &mockSync.Sync{},
|
SyncChecker: &mockSync.Sync{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
HeadFetcher: &mock.ChainService{Optimistic: false, State: beaconState},
|
HeadFetcher: &mock.ChainService{Optimistic: false, State: beaconState},
|
||||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||||
AttestationCache: cache.NewAttestationCache(),
|
AttestationCache: cache.NewAttestationCache(),
|
||||||
@@ -252,6 +254,8 @@ func TestAttestationDataAtSlot_HandlesFarAwayJustifiedEpoch(t *testing.T) {
|
|||||||
Genesis: time.Now(),
|
Genesis: time.Now(),
|
||||||
}
|
}
|
||||||
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
|
clock := blockchain.NewClock(gent)
|
||||||
attesterServer := &Server{
|
attesterServer := &Server{
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
AttestationCache: cache.NewAttestationCache(),
|
AttestationCache: cache.NewAttestationCache(),
|
||||||
@@ -260,7 +264,7 @@ func TestAttestationDataAtSlot_HandlesFarAwayJustifiedEpoch(t *testing.T) {
|
|||||||
CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint(),
|
CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint(),
|
||||||
},
|
},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: clock},
|
||||||
StateNotifier: chainService.StateNotifier(),
|
StateNotifier: chainService.StateNotifier(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,11 +303,13 @@ func TestAttestationDataSlot_handlesInProgressRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
slot := types.Slot(2)
|
slot := types.Slot(2)
|
||||||
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
|
clock := blockchain.NewClock(gent)
|
||||||
server := &Server{
|
server := &Server{
|
||||||
HeadFetcher: &mock.ChainService{State: state},
|
HeadFetcher: &mock.ChainService{State: state},
|
||||||
AttestationCache: cache.NewAttestationCache(),
|
AttestationCache: cache.NewAttestationCache(),
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: clock},
|
||||||
StateNotifier: chainService.StateNotifier(),
|
StateNotifier: chainService.StateNotifier(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,10 +353,12 @@ func TestServer_GetAttestationData_InvalidRequestSlot(t *testing.T) {
|
|||||||
|
|
||||||
slot := 3*params.BeaconConfig().SlotsPerEpoch + 1
|
slot := 3*params.BeaconConfig().SlotsPerEpoch + 1
|
||||||
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
|
clock := blockchain.NewClock(gent)
|
||||||
attesterServer := &Server{
|
attesterServer := &Server{
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
HeadFetcher: &mock.ChainService{},
|
HeadFetcher: &mock.ChainService{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: clock},
|
||||||
}
|
}
|
||||||
|
|
||||||
req := ðpb.AttestationDataRequest{
|
req := ðpb.AttestationDataRequest{
|
||||||
@@ -411,17 +419,19 @@ func TestServer_GetAttestationData_HeadStateSlotGreaterThanRequestSlot(t *testin
|
|||||||
beaconstate := beaconState.Copy()
|
beaconstate := beaconState.Copy()
|
||||||
require.NoError(t, beaconstate.SetSlot(beaconstate.Slot()-1))
|
require.NoError(t, beaconstate.SetSlot(beaconstate.Slot()-1))
|
||||||
require.NoError(t, db.SaveState(ctx, beaconstate, blockRoot2))
|
require.NoError(t, db.SaveState(ctx, beaconstate, blockRoot2))
|
||||||
chainService := &mock.ChainService{
|
|
||||||
Genesis: time.Now(),
|
|
||||||
}
|
|
||||||
offset = int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset = int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := time.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
|
clock := blockchain.NewClock(gent)
|
||||||
|
chainService := &mock.ChainService{
|
||||||
|
Clock: clock,
|
||||||
|
}
|
||||||
attesterServer := &Server{
|
attesterServer := &Server{
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
AttestationCache: cache.NewAttestationCache(),
|
AttestationCache: cache.NewAttestationCache(),
|
||||||
HeadFetcher: &mock.ChainService{State: beaconState, Root: blockRoot[:]},
|
HeadFetcher: &mock.ChainService{State: beaconState, Root: blockRoot[:]},
|
||||||
FinalizationFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint()},
|
FinalizationFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint()},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: chainService,
|
||||||
StateNotifier: chainService.StateNotifier(),
|
StateNotifier: chainService.StateNotifier(),
|
||||||
StateGen: stategen.New(db),
|
StateGen: stategen.New(db),
|
||||||
}
|
}
|
||||||
@@ -486,6 +496,8 @@ func TestGetAttestationData_SucceedsInFirstEpoch(t *testing.T) {
|
|||||||
Genesis: time.Now(),
|
Genesis: time.Now(),
|
||||||
}
|
}
|
||||||
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
gent := prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)
|
||||||
|
clock := blockchain.NewClock(gent)
|
||||||
attesterServer := &Server{
|
attesterServer := &Server{
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
@@ -496,7 +508,7 @@ func TestGetAttestationData_SucceedsInFirstEpoch(t *testing.T) {
|
|||||||
FinalizationFetcher: &mock.ChainService{
|
FinalizationFetcher: &mock.ChainService{
|
||||||
CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint(),
|
CurrentJustifiedCheckPoint: beaconState.CurrentJustifiedCheckpoint(),
|
||||||
},
|
},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)},
|
ClockProvider: &mock.ChainService{Clock: clock},
|
||||||
StateNotifier: chainService.StateNotifier(),
|
StateNotifier: chainService.StateNotifier(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package validator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -39,11 +40,15 @@ func TestProposeExit_Notification(t *testing.T) {
|
|||||||
// Set genesis time to be 100 epochs ago.
|
// Set genesis time to be 100 epochs ago.
|
||||||
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
genesisTime := time.Now().Add(time.Duration(-100*offset) * time.Second)
|
genesisTime := time.Now().Add(time.Duration(-100*offset) * time.Second)
|
||||||
mockChainService := &mockChain.ChainService{State: beaconState, Root: genesisRoot[:], Genesis: genesisTime}
|
mockChainService := &mockChain.ChainService{
|
||||||
|
State: beaconState,
|
||||||
|
Root: genesisRoot[:],
|
||||||
|
Clock: blockchain.NewClock(genesisTime),
|
||||||
|
}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
HeadFetcher: mockChainService,
|
HeadFetcher: mockChainService,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: mockChainService,
|
ClockProvider: mockChainService,
|
||||||
StateNotifier: mockChainService.StateNotifier(),
|
StateNotifier: mockChainService.StateNotifier(),
|
||||||
OperationNotifier: mockChainService.OperationNotifier(),
|
OperationNotifier: mockChainService.OperationNotifier(),
|
||||||
ExitPool: voluntaryexits.NewPool(),
|
ExitPool: voluntaryexits.NewPool(),
|
||||||
@@ -106,11 +111,15 @@ func TestProposeExit_NoPanic(t *testing.T) {
|
|||||||
// Set genesis time to be 100 epochs ago.
|
// Set genesis time to be 100 epochs ago.
|
||||||
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
offset := int64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
genesisTime := time.Now().Add(time.Duration(-100*offset) * time.Second)
|
genesisTime := time.Now().Add(time.Duration(-100*offset) * time.Second)
|
||||||
mockChainService := &mockChain.ChainService{State: beaconState, Root: genesisRoot[:], Genesis: genesisTime}
|
mockChainService := &mockChain.ChainService{
|
||||||
|
State: beaconState,
|
||||||
|
Root: genesisRoot[:],
|
||||||
|
Clock: blockchain.NewClock(genesisTime),
|
||||||
|
}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
HeadFetcher: mockChainService,
|
HeadFetcher: mockChainService,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
TimeFetcher: mockChainService,
|
ClockProvider: mockChainService,
|
||||||
StateNotifier: mockChainService.StateNotifier(),
|
StateNotifier: mockChainService.StateNotifier(),
|
||||||
OperationNotifier: mockChainService.OperationNotifier(),
|
OperationNotifier: mockChainService.OperationNotifier(),
|
||||||
ExitPool: voluntaryexits.NewPool(),
|
ExitPool: voluntaryexits.NewPool(),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package validator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -441,7 +442,7 @@ func TestServer_GetBellatrixBeaconBlock_HappyCase(t *testing.T) {
|
|||||||
|
|
||||||
proposerServer := &Server{
|
proposerServer := &Server{
|
||||||
HeadFetcher: &blockchainTest.ChainService{State: beaconState, Root: parentRoot[:], Optimistic: false},
|
HeadFetcher: &blockchainTest.ChainService{State: beaconState, Root: parentRoot[:], Optimistic: false},
|
||||||
TimeFetcher: &blockchainTest.ChainService{Genesis: time.Now()},
|
ClockProvider: &blockchainTest.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
BlockReceiver: &blockchainTest.ChainService{},
|
BlockReceiver: &blockchainTest.ChainService{},
|
||||||
HeadUpdater: &blockchainTest.ChainService{},
|
HeadUpdater: &blockchainTest.ChainService{},
|
||||||
@@ -570,7 +571,7 @@ func TestServer_GetBellatrixBeaconBlock_BuilderCase(t *testing.T) {
|
|||||||
proposerServer := &Server{
|
proposerServer := &Server{
|
||||||
FinalizationFetcher: &blockchainTest.ChainService{FinalizedCheckPoint: ðpb.Checkpoint{Root: wbr1[:]}},
|
FinalizationFetcher: &blockchainTest.ChainService{FinalizedCheckPoint: ðpb.Checkpoint{Root: wbr1[:]}},
|
||||||
HeadFetcher: &blockchainTest.ChainService{State: beaconState, Root: parentRoot[:], Optimistic: false, Block: wb1},
|
HeadFetcher: &blockchainTest.ChainService{State: beaconState, Root: parentRoot[:], Optimistic: false, Block: wb1},
|
||||||
TimeFetcher: &blockchainTest.ChainService{Genesis: time.Unix(int64(beaconState.GenesisTime()), 0)},
|
ClockProvider: &blockchainTest.ChainService{Clock: blockchain.NewClock(time.Unix(int64(beaconState.GenesisTime()), 0))},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
BlockReceiver: &blockchainTest.ChainService{},
|
BlockReceiver: &blockchainTest.ChainService{},
|
||||||
HeadUpdater: &blockchainTest.ChainService{},
|
HeadUpdater: &blockchainTest.ChainService{},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package validator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -2329,7 +2330,7 @@ func TestProposer_GetBeaconBlock_BellatrixEpoch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
proposerServer := &Server{
|
proposerServer := &Server{
|
||||||
HeadFetcher: &mock.ChainService{State: beaconState, Root: parentRoot[:], Optimistic: false},
|
HeadFetcher: &mock.ChainService{State: beaconState, Root: parentRoot[:], Optimistic: false},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
BlockReceiver: &mock.ChainService{},
|
BlockReceiver: &mock.ChainService{},
|
||||||
HeadUpdater: &mock.ChainService{},
|
HeadUpdater: &mock.ChainService{},
|
||||||
@@ -2394,8 +2395,8 @@ func TestProposer_GetBeaconBlock_Optimistic(t *testing.T) {
|
|||||||
|
|
||||||
bellatrixSlot, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch)
|
bellatrixSlot, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
clockp := &mock.ChainService{Clock: blockchain.NewClock(time.Now())}
|
||||||
proposerServer := &Server{OptimisticModeFetcher: &mock.ChainService{Optimistic: true}, TimeFetcher: &mock.ChainService{}}
|
proposerServer := &Server{OptimisticModeFetcher: &mock.ChainService{Optimistic: true}, ClockProvider: clockp}
|
||||||
req := ðpb.BlockRequest{
|
req := ðpb.BlockRequest{
|
||||||
Slot: bellatrixSlot + 1,
|
Slot: bellatrixSlot + 1,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ type Server struct {
|
|||||||
HeadUpdater blockchain.HeadUpdater
|
HeadUpdater blockchain.HeadUpdater
|
||||||
ForkFetcher blockchain.ForkFetcher
|
ForkFetcher blockchain.ForkFetcher
|
||||||
FinalizationFetcher blockchain.FinalizationFetcher
|
FinalizationFetcher blockchain.FinalizationFetcher
|
||||||
TimeFetcher blockchain.TimeFetcher
|
|
||||||
BlockFetcher powchain.POWBlockFetcher
|
BlockFetcher powchain.POWBlockFetcher
|
||||||
DepositFetcher depositcache.DepositFetcher
|
DepositFetcher depositcache.DepositFetcher
|
||||||
ChainStartFetcher powchain.ChainStartFetcher
|
ChainStartFetcher powchain.ChainStartFetcher
|
||||||
@@ -67,10 +66,11 @@ type Server struct {
|
|||||||
PendingDepositsFetcher depositcache.PendingDepositsFetcher
|
PendingDepositsFetcher depositcache.PendingDepositsFetcher
|
||||||
OperationNotifier opfeed.Notifier
|
OperationNotifier opfeed.Notifier
|
||||||
StateGen stategen.StateManager
|
StateGen stategen.StateManager
|
||||||
ReplayerBuilder stategen.ReplayerBuilder
|
CanonicalHistoryWaiter stategen.CanonicalHistoryWaiter
|
||||||
BeaconDB db.HeadAccessDatabase
|
BeaconDB db.HeadAccessDatabase
|
||||||
ExecutionEngineCaller powchain.EngineCaller
|
ExecutionEngineCaller powchain.EngineCaller
|
||||||
BlockBuilder builder.BlockBuilder
|
BlockBuilder builder.BlockBuilder
|
||||||
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForActivation checks if a validator public key exists in the active validator registry of the current
|
// WaitForActivation checks if a validator public key exists in the active validator registry of the current
|
||||||
|
|||||||
@@ -146,7 +146,11 @@ func (vs *Server) CheckDoppelGanger(ctx context.Context, req *ethpb.DoppelGanger
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, "Could not get previous epoch's end")
|
return nil, status.Error(codes.Internal, "Could not get previous epoch's end")
|
||||||
}
|
}
|
||||||
prevState, err := vs.ReplayerBuilder.ReplayerForSlot(prevEpochEnd).ReplayBlocks(ctx)
|
b, err := vs.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
prevState, err := b.ReplayerForSlot(prevEpochEnd).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, "Could not get previous state")
|
return nil, status.Error(codes.Internal, "Could not get previous state")
|
||||||
}
|
}
|
||||||
@@ -252,7 +256,11 @@ func (vs *Server) activationStatus(
|
|||||||
// Spec:
|
// Spec:
|
||||||
// https://github.com/ethereum/consensus-specs/blob/dev/sync/optimistic.md
|
// https://github.com/ethereum/consensus-specs/blob/dev/sync/optimistic.md
|
||||||
func (vs *Server) optimisticStatus(ctx context.Context) error {
|
func (vs *Server) optimisticStatus(ctx context.Context) error {
|
||||||
if slots.ToEpoch(vs.TimeFetcher.CurrentSlot()) < params.BeaconConfig().BellatrixForkEpoch {
|
c, err := vs.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return status.Errorf(codes.Internal, "timeout while waiting for genesis timestamp, %s", err)
|
||||||
|
}
|
||||||
|
if slots.ToEpoch(c.CurrentSlot()) < params.BeaconConfig().BellatrixForkEpoch {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
optimistic, err := vs.OptimisticModeFetcher.IsOptimistic(ctx)
|
optimistic, err := vs.OptimisticModeFetcher.IsOptimistic(ctx)
|
||||||
@@ -363,15 +371,6 @@ func (vs *Server) validatorStatus(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vs *Server) retrieveAfterEpochTransition(ctx context.Context, epoch types.Epoch) (state.BeaconState, error) {
|
|
||||||
endSlot, err := slots.EpochEnd(epoch)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// replay to first slot of following epoch
|
|
||||||
return vs.ReplayerBuilder.ReplayerForSlot(endSlot).ReplayToSlot(ctx, endSlot+1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkValidatorsAreRecent(headEpoch types.Epoch, req *ethpb.DoppelGangerRequest) (bool, *ethpb.DoppelGangerResponse) {
|
func checkValidatorsAreRecent(headEpoch types.Epoch, req *ethpb.DoppelGangerRequest) (bool, *ethpb.DoppelGangerResponse) {
|
||||||
validatorsAreRecent := true
|
validatorsAreRecent := true
|
||||||
resp := ðpb.DoppelGangerResponse{
|
resp := ðpb.DoppelGangerResponse{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package validator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -604,7 +605,8 @@ func TestActivationStatus_OK(t *testing.T) {
|
|||||||
|
|
||||||
func TestOptimisticStatus(t *testing.T) {
|
func TestOptimisticStatus(t *testing.T) {
|
||||||
params.SetupTestConfigCleanup(t)
|
params.SetupTestConfigCleanup(t)
|
||||||
server := &Server{OptimisticModeFetcher: &mockChain.ChainService{}, TimeFetcher: &mockChain.ChainService{}}
|
clockp := &mockChain.ChainService{Clock: blockchain.NewClock(time.Now())}
|
||||||
|
server := &Server{OptimisticModeFetcher: &mockChain.ChainService{}, ClockProvider: clockp}
|
||||||
err := server.optimisticStatus(context.Background())
|
err := server.optimisticStatus(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -612,14 +614,14 @@ func TestOptimisticStatus(t *testing.T) {
|
|||||||
cfg.BellatrixForkEpoch = 2
|
cfg.BellatrixForkEpoch = 2
|
||||||
params.OverrideBeaconConfig(cfg)
|
params.OverrideBeaconConfig(cfg)
|
||||||
|
|
||||||
server = &Server{OptimisticModeFetcher: &mockChain.ChainService{Optimistic: true}, TimeFetcher: &mockChain.ChainService{}}
|
server = &Server{OptimisticModeFetcher: &mockChain.ChainService{Optimistic: true}, ClockProvider: clockp}
|
||||||
err = server.optimisticStatus(context.Background())
|
err = server.optimisticStatus(context.Background())
|
||||||
s, ok := status.FromError(err)
|
s, ok := status.FromError(err)
|
||||||
require.Equal(t, true, ok)
|
require.Equal(t, true, ok)
|
||||||
require.DeepEqual(t, codes.Unavailable, s.Code())
|
require.DeepEqual(t, codes.Unavailable, s.Code())
|
||||||
require.ErrorContains(t, errOptimisticMode.Error(), err)
|
require.ErrorContains(t, errOptimisticMode.Error(), err)
|
||||||
|
|
||||||
server = &Server{OptimisticModeFetcher: &mockChain.ChainService{Optimistic: false}, TimeFetcher: &mockChain.ChainService{}}
|
server = &Server{OptimisticModeFetcher: &mockChain.ChainService{Optimistic: false}, ClockProvider: clockp}
|
||||||
err = server.optimisticStatus(context.Background())
|
err = server.optimisticStatus(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||||
opfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/operation"
|
opfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/operation"
|
||||||
@@ -27,8 +28,8 @@ import (
|
|||||||
func TestGetSyncMessageBlockRoot_OK(t *testing.T) {
|
func TestGetSyncMessageBlockRoot_OK(t *testing.T) {
|
||||||
r := []byte{'a'}
|
r := []byte{'a'}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
HeadFetcher: &mock.ChainService{Root: r},
|
HeadFetcher: &mock.ChainService{Root: r},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
}
|
}
|
||||||
res, err := server.GetSyncMessageBlockRoot(context.Background(), &emptypb.Empty{})
|
res, err := server.GetSyncMessageBlockRoot(context.Background(), &emptypb.Empty{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -43,7 +44,7 @@ func TestGetSyncMessageBlockRoot_Optimistic(t *testing.T) {
|
|||||||
|
|
||||||
server := &Server{
|
server := &Server{
|
||||||
HeadFetcher: &mock.ChainService{},
|
HeadFetcher: &mock.ChainService{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: true},
|
OptimisticModeFetcher: &mock.ChainService{Optimistic: true},
|
||||||
}
|
}
|
||||||
_, err := server.GetSyncMessageBlockRoot(context.Background(), &emptypb.Empty{})
|
_, err := server.GetSyncMessageBlockRoot(context.Background(), &emptypb.Empty{})
|
||||||
@@ -54,7 +55,7 @@ func TestGetSyncMessageBlockRoot_Optimistic(t *testing.T) {
|
|||||||
|
|
||||||
server = &Server{
|
server = &Server{
|
||||||
HeadFetcher: &mock.ChainService{},
|
HeadFetcher: &mock.ChainService{},
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
ClockProvider: &mock.ChainService{Clock: blockchain.NewClock(time.Now())},
|
||||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||||
}
|
}
|
||||||
_, err = server.GetSyncMessageBlockRoot(context.Background(), &emptypb.Empty{})
|
_, err = server.GetSyncMessageBlockRoot(context.Background(), &emptypb.Empty{})
|
||||||
@@ -103,14 +104,16 @@ func TestGetSyncSubcommitteeIndex_Ok(t *testing.T) {
|
|||||||
|
|
||||||
func TestGetSyncCommitteeContribution_FiltersDuplicates(t *testing.T) {
|
func TestGetSyncCommitteeContribution_FiltersDuplicates(t *testing.T) {
|
||||||
st, _ := util.DeterministicGenesisStateAltair(t, 10)
|
st, _ := util.DeterministicGenesisStateAltair(t, 10)
|
||||||
|
chain := &mock.ChainService{
|
||||||
|
State: st,
|
||||||
|
SyncCommitteeIndices: []types.CommitteeIndex{10},
|
||||||
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
|
}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
SyncCommitteePool: synccommittee.NewStore(),
|
SyncCommitteePool: synccommittee.NewStore(),
|
||||||
P2P: &mockp2p.MockBroadcaster{},
|
P2P: &mockp2p.MockBroadcaster{},
|
||||||
HeadFetcher: &mock.ChainService{
|
HeadFetcher: chain,
|
||||||
State: st,
|
ClockProvider: chain,
|
||||||
SyncCommitteeIndices: []types.CommitteeIndex{10},
|
|
||||||
},
|
|
||||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
|
||||||
}
|
}
|
||||||
secKey, err := bls.RandKey()
|
secKey, err := bls.RandKey()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package rpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -13,6 +12,7 @@ import (
|
|||||||
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
||||||
grpcopentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
|
grpcopentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
|
||||||
grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/builder"
|
"github.com/prysmaticlabs/prysm/beacon-chain/builder"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
@@ -90,7 +90,6 @@ type Config struct {
|
|||||||
POWChainService powchain.Chain
|
POWChainService powchain.Chain
|
||||||
ChainStartFetcher powchain.ChainStartFetcher
|
ChainStartFetcher powchain.ChainStartFetcher
|
||||||
POWChainInfoFetcher powchain.ChainInfoFetcher
|
POWChainInfoFetcher powchain.ChainInfoFetcher
|
||||||
GenesisTimeFetcher blockchain.TimeFetcher
|
|
||||||
GenesisFetcher blockchain.GenesisFetcher
|
GenesisFetcher blockchain.GenesisFetcher
|
||||||
EnableDebugRPCEndpoints bool
|
EnableDebugRPCEndpoints bool
|
||||||
MockEth1Votes bool
|
MockEth1Votes bool
|
||||||
@@ -115,6 +114,7 @@ type Config struct {
|
|||||||
ProposerIdsCache *cache.ProposerPayloadIDsCache
|
ProposerIdsCache *cache.ProposerPayloadIDsCache
|
||||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||||
BlockBuilder builder.BlockBuilder
|
BlockBuilder builder.BlockBuilder
|
||||||
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService instantiates a new RPC service instance that will
|
// NewService instantiates a new RPC service instance that will
|
||||||
@@ -175,7 +175,6 @@ func NewService(ctx context.Context, cfg *Config) *Service {
|
|||||||
|
|
||||||
// paranoid build time check to ensure ChainInfoFetcher implements required interfaces
|
// paranoid build time check to ensure ChainInfoFetcher implements required interfaces
|
||||||
var _ stategen.CanonicalChecker = blockchain.ChainInfoFetcher(nil)
|
var _ stategen.CanonicalChecker = blockchain.ChainInfoFetcher(nil)
|
||||||
var _ stategen.CurrentSlotter = blockchain.ChainInfoFetcher(nil)
|
|
||||||
|
|
||||||
// Start the gRPC server.
|
// Start the gRPC server.
|
||||||
func (s *Service) Start() {
|
func (s *Service) Start() {
|
||||||
@@ -186,7 +185,8 @@ func (s *Service) Start() {
|
|||||||
stateCache = s.cfg.StateGen.CombinedCache()
|
stateCache = s.cfg.StateGen.CombinedCache()
|
||||||
}
|
}
|
||||||
withCache := stategen.WithCache(stateCache)
|
withCache := stategen.WithCache(stateCache)
|
||||||
ch := stategen.NewCanonicalHistory(s.cfg.BeaconDB, s.cfg.ChainInfoFetcher, s.cfg.ChainInfoFetcher, withCache)
|
//ch := stategen.NewCanonicalHistory(s.cfg.BeaconDB, s.cfg.ChainInfoFetcher, s.cfg.ChainInfoFetcher, withCache)
|
||||||
|
rbw := NewCanonicalHistoryWaiter(s.cfg.ChainInfoFetcher, s.cfg.BeaconDB, s.cfg.ChainInfoFetcher, withCache)
|
||||||
|
|
||||||
validatorServer := &validatorv1alpha1.Server{
|
validatorServer := &validatorv1alpha1.Server{
|
||||||
Ctx: s.ctx,
|
Ctx: s.ctx,
|
||||||
@@ -197,7 +197,6 @@ func (s *Service) Start() {
|
|||||||
HeadUpdater: s.cfg.HeadUpdater,
|
HeadUpdater: s.cfg.HeadUpdater,
|
||||||
ForkFetcher: s.cfg.ForkFetcher,
|
ForkFetcher: s.cfg.ForkFetcher,
|
||||||
FinalizationFetcher: s.cfg.FinalizationFetcher,
|
FinalizationFetcher: s.cfg.FinalizationFetcher,
|
||||||
TimeFetcher: s.cfg.GenesisTimeFetcher,
|
|
||||||
BlockFetcher: s.cfg.POWChainService,
|
BlockFetcher: s.cfg.POWChainService,
|
||||||
DepositFetcher: s.cfg.DepositFetcher,
|
DepositFetcher: s.cfg.DepositFetcher,
|
||||||
ChainStartFetcher: s.cfg.ChainStartFetcher,
|
ChainStartFetcher: s.cfg.ChainStartFetcher,
|
||||||
@@ -215,16 +214,16 @@ func (s *Service) Start() {
|
|||||||
SlashingsPool: s.cfg.SlashingsPool,
|
SlashingsPool: s.cfg.SlashingsPool,
|
||||||
StateGen: s.cfg.StateGen,
|
StateGen: s.cfg.StateGen,
|
||||||
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
|
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
|
||||||
ReplayerBuilder: ch,
|
CanonicalHistoryWaiter: rbw,
|
||||||
ExecutionEngineCaller: s.cfg.ExecutionEngineCaller,
|
ExecutionEngineCaller: s.cfg.ExecutionEngineCaller,
|
||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
ProposerSlotIndexCache: s.cfg.ProposerIdsCache,
|
ProposerSlotIndexCache: s.cfg.ProposerIdsCache,
|
||||||
BlockBuilder: s.cfg.BlockBuilder,
|
BlockBuilder: s.cfg.BlockBuilder,
|
||||||
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
}
|
}
|
||||||
validatorServerV1 := &validator.Server{
|
validatorServerV1 := &validator.Server{
|
||||||
HeadFetcher: s.cfg.HeadFetcher,
|
HeadFetcher: s.cfg.HeadFetcher,
|
||||||
HeadUpdater: s.cfg.HeadUpdater,
|
HeadUpdater: s.cfg.HeadUpdater,
|
||||||
TimeFetcher: s.cfg.GenesisTimeFetcher,
|
|
||||||
SyncChecker: s.cfg.SyncService,
|
SyncChecker: s.cfg.SyncService,
|
||||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||||
AttestationsPool: s.cfg.AttestationsPool,
|
AttestationsPool: s.cfg.AttestationsPool,
|
||||||
@@ -232,13 +231,14 @@ func (s *Service) Start() {
|
|||||||
Broadcaster: s.cfg.Broadcaster,
|
Broadcaster: s.cfg.Broadcaster,
|
||||||
V1Alpha1Server: validatorServer,
|
V1Alpha1Server: validatorServer,
|
||||||
StateFetcher: &statefetcher.StateProvider{
|
StateFetcher: &statefetcher.StateProvider{
|
||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
||||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
StateGenService: s.cfg.StateGen,
|
||||||
StateGenService: s.cfg.StateGen,
|
CanonicalHistoryWaiter: rbw,
|
||||||
ReplayerBuilder: ch,
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
},
|
},
|
||||||
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
|
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
|
||||||
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeServer := &nodev1alpha1.Server{
|
nodeServer := &nodev1alpha1.Server{
|
||||||
@@ -247,24 +247,24 @@ func (s *Service) Start() {
|
|||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
Server: s.grpcServer,
|
Server: s.grpcServer,
|
||||||
SyncChecker: s.cfg.SyncService,
|
SyncChecker: s.cfg.SyncService,
|
||||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
|
||||||
PeersFetcher: s.cfg.PeersFetcher,
|
PeersFetcher: s.cfg.PeersFetcher,
|
||||||
PeerManager: s.cfg.PeerManager,
|
PeerManager: s.cfg.PeerManager,
|
||||||
GenesisFetcher: s.cfg.GenesisFetcher,
|
GenesisFetcher: s.cfg.GenesisFetcher,
|
||||||
POWChainInfoFetcher: s.cfg.POWChainInfoFetcher,
|
POWChainInfoFetcher: s.cfg.POWChainInfoFetcher,
|
||||||
BeaconMonitoringHost: s.cfg.BeaconMonitoringHost,
|
BeaconMonitoringHost: s.cfg.BeaconMonitoringHost,
|
||||||
BeaconMonitoringPort: s.cfg.BeaconMonitoringPort,
|
BeaconMonitoringPort: s.cfg.BeaconMonitoringPort,
|
||||||
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
}
|
}
|
||||||
nodeServerV1 := &node.Server{
|
nodeServerV1 := &node.Server{
|
||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
Server: s.grpcServer,
|
Server: s.grpcServer,
|
||||||
SyncChecker: s.cfg.SyncService,
|
SyncChecker: s.cfg.SyncService,
|
||||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
|
||||||
PeersFetcher: s.cfg.PeersFetcher,
|
PeersFetcher: s.cfg.PeersFetcher,
|
||||||
PeerManager: s.cfg.PeerManager,
|
PeerManager: s.cfg.PeerManager,
|
||||||
MetadataProvider: s.cfg.MetadataProvider,
|
MetadataProvider: s.cfg.MetadataProvider,
|
||||||
HeadFetcher: s.cfg.HeadFetcher,
|
HeadFetcher: s.cfg.HeadFetcher,
|
||||||
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
beaconChainServer := &beaconv1alpha1.Server{
|
beaconChainServer := &beaconv1alpha1.Server{
|
||||||
@@ -280,7 +280,6 @@ func (s *Service) Start() {
|
|||||||
ChainStartFetcher: s.cfg.ChainStartFetcher,
|
ChainStartFetcher: s.cfg.ChainStartFetcher,
|
||||||
DepositFetcher: s.cfg.DepositFetcher,
|
DepositFetcher: s.cfg.DepositFetcher,
|
||||||
BlockFetcher: s.cfg.POWChainService,
|
BlockFetcher: s.cfg.POWChainService,
|
||||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
|
||||||
StateNotifier: s.cfg.StateNotifier,
|
StateNotifier: s.cfg.StateNotifier,
|
||||||
BlockNotifier: s.cfg.BlockNotifier,
|
BlockNotifier: s.cfg.BlockNotifier,
|
||||||
AttestationNotifier: s.cfg.OperationNotifier,
|
AttestationNotifier: s.cfg.OperationNotifier,
|
||||||
@@ -289,26 +288,26 @@ func (s *Service) Start() {
|
|||||||
SyncChecker: s.cfg.SyncService,
|
SyncChecker: s.cfg.SyncService,
|
||||||
ReceivedAttestationsBuffer: make(chan *ethpbv1alpha1.Attestation, attestationBufferSize),
|
ReceivedAttestationsBuffer: make(chan *ethpbv1alpha1.Attestation, attestationBufferSize),
|
||||||
CollectedAttestationsBuffer: make(chan []*ethpbv1alpha1.Attestation, attestationBufferSize),
|
CollectedAttestationsBuffer: make(chan []*ethpbv1alpha1.Attestation, attestationBufferSize),
|
||||||
ReplayerBuilder: ch,
|
CanonicalHistoryWaiter: rbw,
|
||||||
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
}
|
}
|
||||||
beaconChainServerV1 := &beacon.Server{
|
beaconChainServerV1 := &beacon.Server{
|
||||||
CanonicalHistory: ch,
|
CanonicalHistoryWaiter: rbw,
|
||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
AttestationsPool: s.cfg.AttestationsPool,
|
AttestationsPool: s.cfg.AttestationsPool,
|
||||||
SlashingsPool: s.cfg.SlashingsPool,
|
SlashingsPool: s.cfg.SlashingsPool,
|
||||||
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
||||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
BlockNotifier: s.cfg.BlockNotifier,
|
||||||
BlockNotifier: s.cfg.BlockNotifier,
|
OperationNotifier: s.cfg.OperationNotifier,
|
||||||
OperationNotifier: s.cfg.OperationNotifier,
|
Broadcaster: s.cfg.Broadcaster,
|
||||||
Broadcaster: s.cfg.Broadcaster,
|
BlockReceiver: s.cfg.BlockReceiver,
|
||||||
BlockReceiver: s.cfg.BlockReceiver,
|
StateGenService: s.cfg.StateGen,
|
||||||
StateGenService: s.cfg.StateGen,
|
|
||||||
StateFetcher: &statefetcher.StateProvider{
|
StateFetcher: &statefetcher.StateProvider{
|
||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
||||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
StateGenService: s.cfg.StateGen,
|
||||||
StateGenService: s.cfg.StateGen,
|
CanonicalHistoryWaiter: rbw,
|
||||||
ReplayerBuilder: ch,
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
},
|
},
|
||||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||||
HeadFetcher: s.cfg.HeadFetcher,
|
HeadFetcher: s.cfg.HeadFetcher,
|
||||||
@@ -316,6 +315,7 @@ func (s *Service) Start() {
|
|||||||
V1Alpha1ValidatorServer: validatorServer,
|
V1Alpha1ValidatorServer: validatorServer,
|
||||||
SyncChecker: s.cfg.SyncService,
|
SyncChecker: s.cfg.SyncService,
|
||||||
ExecutionPayloadReconstructor: s.cfg.ExecutionPayloadReconstructor,
|
ExecutionPayloadReconstructor: s.cfg.ExecutionPayloadReconstructor,
|
||||||
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
}
|
}
|
||||||
ethpbv1alpha1.RegisterNodeServer(s.grpcServer, nodeServer)
|
ethpbv1alpha1.RegisterNodeServer(s.grpcServer, nodeServer)
|
||||||
ethpbservice.RegisterBeaconNodeServer(s.grpcServer, nodeServerV1)
|
ethpbservice.RegisterBeaconNodeServer(s.grpcServer, nodeServerV1)
|
||||||
@@ -331,24 +331,24 @@ func (s *Service) Start() {
|
|||||||
if s.cfg.EnableDebugRPCEndpoints {
|
if s.cfg.EnableDebugRPCEndpoints {
|
||||||
log.Info("Enabled debug gRPC endpoints")
|
log.Info("Enabled debug gRPC endpoints")
|
||||||
debugServer := &debugv1alpha1.Server{
|
debugServer := &debugv1alpha1.Server{
|
||||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
BeaconDB: s.cfg.BeaconDB,
|
StateGen: s.cfg.StateGen,
|
||||||
StateGen: s.cfg.StateGen,
|
HeadFetcher: s.cfg.HeadFetcher,
|
||||||
HeadFetcher: s.cfg.HeadFetcher,
|
ForkFetcher: s.cfg.ForkFetcher,
|
||||||
ForkFetcher: s.cfg.ForkFetcher,
|
PeerManager: s.cfg.PeerManager,
|
||||||
PeerManager: s.cfg.PeerManager,
|
PeersFetcher: s.cfg.PeersFetcher,
|
||||||
PeersFetcher: s.cfg.PeersFetcher,
|
CanonicalHistoryWaiter: rbw,
|
||||||
ReplayerBuilder: ch,
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
}
|
}
|
||||||
debugServerV1 := &debug.Server{
|
debugServerV1 := &debug.Server{
|
||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
HeadFetcher: s.cfg.HeadFetcher,
|
HeadFetcher: s.cfg.HeadFetcher,
|
||||||
StateFetcher: &statefetcher.StateProvider{
|
StateFetcher: &statefetcher.StateProvider{
|
||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
||||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
StateGenService: s.cfg.StateGen,
|
||||||
StateGenService: s.cfg.StateGen,
|
CanonicalHistoryWaiter: rbw,
|
||||||
ReplayerBuilder: ch,
|
ClockProvider: s.cfg.ClockProvider,
|
||||||
},
|
},
|
||||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||||
}
|
}
|
||||||
@@ -429,3 +429,27 @@ func (s *Service) logNewClientConnection(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewCanonicalHistoryWaiter(c blockchain.ClockProvider, h stategen.HistoryAccessor, cc stategen.CanonicalChecker, opts ...stategen.CanonicalHistoryOption) stategen.CanonicalHistoryWaiter {
|
||||||
|
return &canonicalHistoryWaiter{
|
||||||
|
c: c,
|
||||||
|
h: h,
|
||||||
|
cc: cc,
|
||||||
|
opts: opts,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type canonicalHistoryWaiter struct {
|
||||||
|
c blockchain.ClockProvider
|
||||||
|
h stategen.HistoryAccessor
|
||||||
|
cc stategen.CanonicalChecker
|
||||||
|
opts []stategen.CanonicalHistoryOption
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *canonicalHistoryWaiter) WaitForCanonicalHistory(ctx context.Context) (*stategen.CanonicalHistory, error) {
|
||||||
|
c, err := w.c.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "timeout waiting for genesis timestamp")
|
||||||
|
}
|
||||||
|
return stategen.NewCanonicalHistory(w.h, w.cc, c, w.opts...), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package rpc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -24,7 +25,7 @@ func init() {
|
|||||||
func TestLifecycle_OK(t *testing.T) {
|
func TestLifecycle_OK(t *testing.T) {
|
||||||
hook := logTest.NewGlobal()
|
hook := logTest.NewGlobal()
|
||||||
chainService := &mock.ChainService{
|
chainService := &mock.ChainService{
|
||||||
Genesis: time.Now(),
|
Clock: blockchain.NewClock(time.Now()),
|
||||||
}
|
}
|
||||||
rpcService := NewService(context.Background(), &Config{
|
rpcService := NewService(context.Background(), &Config{
|
||||||
Port: "7348",
|
Port: "7348",
|
||||||
@@ -32,9 +33,9 @@ func TestLifecycle_OK(t *testing.T) {
|
|||||||
BlockReceiver: chainService,
|
BlockReceiver: chainService,
|
||||||
AttestationReceiver: chainService,
|
AttestationReceiver: chainService,
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
GenesisTimeFetcher: chainService,
|
|
||||||
POWChainService: &mockPOW.POWChain{},
|
POWChainService: &mockPOW.POWChain{},
|
||||||
StateNotifier: chainService.StateNotifier(),
|
StateNotifier: chainService.StateNotifier(),
|
||||||
|
ClockProvider: chainService,
|
||||||
})
|
})
|
||||||
|
|
||||||
rpcService.Start()
|
rpcService.Start()
|
||||||
@@ -55,12 +56,12 @@ func TestStatus_CredentialError(t *testing.T) {
|
|||||||
|
|
||||||
func TestRPC_InsecureEndpoint(t *testing.T) {
|
func TestRPC_InsecureEndpoint(t *testing.T) {
|
||||||
hook := logTest.NewGlobal()
|
hook := logTest.NewGlobal()
|
||||||
chainService := &mock.ChainService{Genesis: time.Now()}
|
chainService := &mock.ChainService{Clock: blockchain.NewClock(time.Now())}
|
||||||
rpcService := NewService(context.Background(), &Config{
|
rpcService := NewService(context.Background(), &Config{
|
||||||
Port: "7777",
|
Port: "7777",
|
||||||
SyncService: &mockSync.Sync{IsSyncing: false},
|
SyncService: &mockSync.Sync{IsSyncing: false},
|
||||||
BlockReceiver: chainService,
|
BlockReceiver: chainService,
|
||||||
GenesisTimeFetcher: chainService,
|
ClockProvider: chainService,
|
||||||
AttestationReceiver: chainService,
|
AttestationReceiver: chainService,
|
||||||
HeadFetcher: chainService,
|
HeadFetcher: chainService,
|
||||||
POWChainService: &mockPOW.POWChain{},
|
POWChainService: &mockPOW.POWChain{},
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ go_test(
|
|||||||
srcs = ["fetcher_test.go"],
|
srcs = ["fetcher_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/blockchain/testing:go_default_library",
|
"//beacon-chain/blockchain/testing:go_default_library",
|
||||||
"//beacon-chain/db/testing:go_default_library",
|
"//beacon-chain/db/testing:go_default_library",
|
||||||
"//beacon-chain/state/state-native:go_default_library",
|
"//beacon-chain/state/state-native:go_default_library",
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ type Fetcher interface {
|
|||||||
type StateProvider struct {
|
type StateProvider struct {
|
||||||
BeaconDB db.ReadOnlyDatabase
|
BeaconDB db.ReadOnlyDatabase
|
||||||
ChainInfoFetcher blockchain.ChainInfoFetcher
|
ChainInfoFetcher blockchain.ChainInfoFetcher
|
||||||
GenesisTimeFetcher blockchain.TimeFetcher
|
StateGenService stategen.StateManager
|
||||||
StateGenService stategen.StateManager
|
CanonicalHistoryWaiter stategen.CanonicalHistoryWaiter
|
||||||
ReplayerBuilder stategen.ReplayerBuilder
|
ClockProvider blockchain.ClockProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// State returns the BeaconState for a given identifier. The identifier can be one of:
|
// State returns the BeaconState for a given identifier. The identifier can be one of:
|
||||||
@@ -200,14 +200,22 @@ func (p *StateProvider) StateBySlot(ctx context.Context, target types.Slot) (sta
|
|||||||
ctx, span := trace.StartSpan(ctx, "statefetcher.StateBySlot")
|
ctx, span := trace.StartSpan(ctx, "statefetcher.StateBySlot")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if target > p.GenesisTimeFetcher.CurrentSlot() {
|
c, err := p.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "timeout while waiting for genesis timestamp")
|
||||||
|
}
|
||||||
|
if target > c.CurrentSlot() {
|
||||||
return nil, errors.New("requested slot is in the future")
|
return nil, errors.New("requested slot is in the future")
|
||||||
}
|
}
|
||||||
if target > p.ChainInfoFetcher.HeadSlot() {
|
if target > p.ChainInfoFetcher.HeadSlot() {
|
||||||
return nil, errors.New("requested slot number is higher than head slot number")
|
return nil, errors.New("requested slot number is higher than head slot number")
|
||||||
}
|
}
|
||||||
|
|
||||||
st, err := p.ReplayerBuilder.ReplayerForSlot(target).ReplayBlocks(ctx)
|
b, err := p.ReplayerBuilder(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
st, err := b.ReplayerForSlot(target).ReplayBlocks(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg := fmt.Sprintf("error while replaying history to slot=%d", target)
|
msg := fmt.Sprintf("error while replaying history to slot=%d", target)
|
||||||
return nil, errors.Wrap(err, msg)
|
return nil, errors.Wrap(err, msg)
|
||||||
@@ -285,7 +293,11 @@ func (p *StateProvider) stateRootByHex(ctx context.Context, stateId []byte) ([]b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *StateProvider) stateRootBySlot(ctx context.Context, slot types.Slot) ([]byte, error) {
|
func (p *StateProvider) stateRootBySlot(ctx context.Context, slot types.Slot) ([]byte, error) {
|
||||||
currentSlot := p.GenesisTimeFetcher.CurrentSlot()
|
c, err := p.ClockProvider.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "timeout waiting for genesis time")
|
||||||
|
}
|
||||||
|
currentSlot := c.CurrentSlot()
|
||||||
if slot > currentSlot {
|
if slot > currentSlot {
|
||||||
return nil, errors.New("slot cannot be in the future")
|
return nil, errors.New("slot cannot be in the future")
|
||||||
}
|
}
|
||||||
@@ -304,3 +316,7 @@ func (p *StateProvider) stateRootBySlot(ctx context.Context, slot types.Slot) ([
|
|||||||
}
|
}
|
||||||
return blks[0].Block().StateRoot(), nil
|
return blks[0].Block().StateRoot(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *StateProvider) ReplayerBuilder(ctx context.Context) (stategen.ReplayerBuilder, error) {
|
||||||
|
return p.CanonicalHistoryWaiter.WaitForCanonicalHistory(ctx)
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package statefetcher
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -77,11 +78,11 @@ func TestGetState(t *testing.T) {
|
|||||||
cc := &mockstategen.MockCanonicalChecker{Is: true}
|
cc := &mockstategen.MockCanonicalChecker{Is: true}
|
||||||
cs := &mockstategen.MockCurrentSlotter{Slot: bs.Slot() + 1}
|
cs := &mockstategen.MockCurrentSlotter{Slot: bs.Slot() + 1}
|
||||||
ch := stategen.NewCanonicalHistory(db, cc, cs)
|
ch := stategen.NewCanonicalHistory(db, cc, cs)
|
||||||
currentSlot := types.Slot(0)
|
clock := blockchain.NewClock(time.Now())
|
||||||
p := StateProvider{
|
p := StateProvider{
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
ReplayerBuilder: ch,
|
ReplayerBuilder: ch,
|
||||||
GenesisTimeFetcher: &chainMock.ChainService{Slot: ¤tSlot},
|
ClockProvider: &chainMock.ChainService{Clock: clock},
|
||||||
ChainInfoFetcher: &chainMock.ChainService{State: bs},
|
ChainInfoFetcher: &chainMock.ChainService{State: bs},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +162,10 @@ func TestGetState(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("slot", func(t *testing.T) {
|
t.Run("slot", func(t *testing.T) {
|
||||||
|
|
||||||
|
clock := NewMockClock(time.Now(), headSlot)
|
||||||
p := StateProvider{
|
p := StateProvider{
|
||||||
GenesisTimeFetcher: &chainMock.ChainService{Slot: &headSlot},
|
ClockProvider: &chainMock.ChainService{Clock: clock},
|
||||||
ChainInfoFetcher: &chainMock.ChainService{
|
ChainInfoFetcher: &chainMock.ChainService{
|
||||||
CanonicalRoots: map[[32]byte]bool{
|
CanonicalRoots: map[[32]byte]bool{
|
||||||
bytesutil.ToBytes32(newBeaconState.LatestBlockHeader().ParentRoot): true,
|
bytesutil.ToBytes32(newBeaconState.LatestBlockHeader().ParentRoot): true,
|
||||||
@@ -346,8 +349,9 @@ func TestGetStateRoot(t *testing.T) {
|
|||||||
require.NoError(t, db.SaveState(ctx, st, root))
|
require.NoError(t, db.SaveState(ctx, st, root))
|
||||||
|
|
||||||
slot := types.Slot(40)
|
slot := types.Slot(40)
|
||||||
|
clock := NewMockClock(time.Now(), slot)
|
||||||
p := StateProvider{
|
p := StateProvider{
|
||||||
GenesisTimeFetcher: &chainMock.ChainService{Slot: &slot},
|
ClockProvider: &chainMock.ChainService{Clock: clock},
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,11 +361,7 @@ func TestGetStateRoot(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("slot_too_big", func(t *testing.T) {
|
t.Run("slot_too_big", func(t *testing.T) {
|
||||||
p := StateProvider{
|
p := StateProvider{ClockProvider: &chainMock.ChainService{Clock: blockchain.NewClock(time.Now())}}
|
||||||
GenesisTimeFetcher: &chainMock.ChainService{
|
|
||||||
Genesis: time.Now(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
_, err := p.StateRoot(ctx, []byte(strconv.FormatUint(1, 10)))
|
_, err := p.StateRoot(ctx, []byte(strconv.FormatUint(1, 10)))
|
||||||
assert.ErrorContains(t, "slot cannot be in the future", err)
|
assert.ErrorContains(t, "slot cannot be in the future", err)
|
||||||
})
|
})
|
||||||
@@ -380,7 +380,8 @@ func TestNewStateNotFoundError(t *testing.T) {
|
|||||||
|
|
||||||
func TestStateBySlot_FutureSlot(t *testing.T) {
|
func TestStateBySlot_FutureSlot(t *testing.T) {
|
||||||
slot := types.Slot(100)
|
slot := types.Slot(100)
|
||||||
p := StateProvider{GenesisTimeFetcher: &chainMock.ChainService{Slot: &slot}}
|
clock := NewMockClock(time.Now(), slot)
|
||||||
|
p := StateProvider{ClockProvider: &chainMock.ChainService{Clock: clock}}
|
||||||
_, err := p.StateBySlot(context.Background(), 101)
|
_, err := p.StateBySlot(context.Background(), 101)
|
||||||
assert.ErrorContains(t, "requested slot is in the future", err)
|
assert.ErrorContains(t, "requested slot is in the future", err)
|
||||||
}
|
}
|
||||||
@@ -389,8 +390,17 @@ func TestStateBySlot_AfterHeadSlot(t *testing.T) {
|
|||||||
st, err := statenative.InitializeFromProtoPhase0(ðpb.BeaconState{Slot: 100})
|
st, err := statenative.InitializeFromProtoPhase0(ðpb.BeaconState{Slot: 100})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
currentSlot := types.Slot(102)
|
currentSlot := types.Slot(102)
|
||||||
mock := &chainMock.ChainService{State: st, Slot: ¤tSlot}
|
clock := NewMockClock(time.Now(), currentSlot)
|
||||||
p := StateProvider{ChainInfoFetcher: mock, GenesisTimeFetcher: mock}
|
mock := &chainMock.ChainService{State: st, Slot: ¤tSlot, Clock: clock}
|
||||||
|
p := StateProvider{ChainInfoFetcher: mock, ClockProvider: mock}
|
||||||
_, err = p.StateBySlot(context.Background(), 101)
|
_, err = p.StateBySlot(context.Background(), 101)
|
||||||
assert.ErrorContains(t, "requested slot number is higher than head slot number", err)
|
assert.ErrorContains(t, "requested slot number is higher than head slot number", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewMockClock(now time.Time, slotsAfterGenesis types.Slot) blockchain.Clock {
|
||||||
|
offset := uint64(slotsAfterGenesis) * params.BeaconConfig().SecondsPerSlot
|
||||||
|
genesis := now.Add(-1 * time.Second * time.Duration(offset))
|
||||||
|
return blockchain.NewClock(genesis, blockchain.WithNow(func() time.Time {
|
||||||
|
return genesis
|
||||||
|
}))
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
testonly = True,
|
testonly = True,
|
||||||
srcs = [
|
srcs = [
|
||||||
"mock_genesis_timefetcher.go",
|
|
||||||
"mock_powchain_info_fetcher.go",
|
"mock_powchain_info_fetcher.go",
|
||||||
"mock_state_fetcher.go",
|
"mock_state_fetcher.go",
|
||||||
],
|
],
|
||||||
@@ -12,7 +11,6 @@ go_library(
|
|||||||
visibility = ["//beacon-chain:__subpackages__"],
|
visibility = ["//beacon-chain:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//config/params:go_default_library",
|
|
||||||
"//consensus-types/primitives:go_default_library",
|
"//consensus-types/primitives:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package testutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MockGenesisTimeFetcher is a fake implementation of the blockchain.TimeFetcher
|
|
||||||
type MockGenesisTimeFetcher struct {
|
|
||||||
Genesis time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockGenesisTimeFetcher) GenesisTime() time.Time {
|
|
||||||
return m.Genesis
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockGenesisTimeFetcher) CurrentSlot() types.Slot {
|
|
||||||
return types.Slot(uint64(time.Now().Unix()-m.Genesis.Unix()) / params.BeaconConfig().SecondsPerSlot)
|
|
||||||
}
|
|
||||||
@@ -26,6 +26,7 @@ go_library(
|
|||||||
"//beacon-chain/core/transition:go_default_library",
|
"//beacon-chain/core/transition:go_default_library",
|
||||||
"//beacon-chain/db:go_default_library",
|
"//beacon-chain/db:go_default_library",
|
||||||
"//beacon-chain/db/filters:go_default_library",
|
"//beacon-chain/db/filters:go_default_library",
|
||||||
|
"//beacon-chain/forkchoice/types:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/sync/backfill:go_default_library",
|
"//beacon-chain/sync/backfill:go_default_library",
|
||||||
"//cache/lru:go_default_library",
|
"//cache/lru:go_default_library",
|
||||||
@@ -70,6 +71,7 @@ go_test(
|
|||||||
"//beacon-chain/core/transition:go_default_library",
|
"//beacon-chain/core/transition:go_default_library",
|
||||||
"//beacon-chain/db:go_default_library",
|
"//beacon-chain/db:go_default_library",
|
||||||
"//beacon-chain/db/testing:go_default_library",
|
"//beacon-chain/db/testing:go_default_library",
|
||||||
|
"//beacon-chain/forkchoice/types:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/v1:go_default_library",
|
"//beacon-chain/state/v1:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ var ErrNoDataForSlot = errors.New("cannot retrieve data for slot")
|
|||||||
|
|
||||||
// HasState returns true if the state exists in cache or in DB.
|
// HasState returns true if the state exists in cache or in DB.
|
||||||
func (s *State) HasState(ctx context.Context, blockRoot [32]byte) (bool, error) {
|
func (s *State) HasState(ctx context.Context, blockRoot [32]byte) (bool, error) {
|
||||||
has, err := s.HasStateInCache(ctx, blockRoot)
|
has, err := s.hasStateInCache(ctx, blockRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -27,8 +27,8 @@ func (s *State) HasState(ctx context.Context, blockRoot [32]byte) (bool, error)
|
|||||||
return s.beaconDB.HasState(ctx, blockRoot), nil
|
return s.beaconDB.HasState(ctx, blockRoot), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasStateInCache returns true if the state exists in cache.
|
// hasStateInCache returns true if the state exists in cache.
|
||||||
func (s *State) HasStateInCache(_ context.Context, blockRoot [32]byte) (bool, error) {
|
func (s *State) hasStateInCache(_ context.Context, blockRoot [32]byte) (bool, error) {
|
||||||
if s.hotStateCache.has(blockRoot) {
|
if s.hotStateCache.has(blockRoot) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ func (s *State) StateByRootInitialSync(ctx context.Context, blockRoot [32]byte)
|
|||||||
return cachedInfo.state, nil
|
return cachedInfo.state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
startState, err := s.LastAncestorState(ctx, blockRoot)
|
startState, err := s.latestAncestor(ctx, blockRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get ancestor state")
|
return nil, errors.Wrap(err, "could not get ancestor state")
|
||||||
}
|
}
|
||||||
@@ -102,11 +102,11 @@ func (s *State) StateByRootInitialSync(ctx context.Context, blockRoot [32]byte)
|
|||||||
return startState, nil
|
return startState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
blks, err := s.LoadBlocks(ctx, startState.Slot()+1, summary.Slot, bytesutil.ToBytes32(summary.Root))
|
blks, err := s.loadBlocks(ctx, startState.Slot()+1, summary.Slot, bytesutil.ToBytes32(summary.Root))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not load blocks")
|
return nil, errors.Wrap(err, "could not load blocks")
|
||||||
}
|
}
|
||||||
startState, err = s.ReplayBlocks(ctx, startState, blks, summary.Slot)
|
startState, err = s.replayBlocks(ctx, startState, blks, summary.Slot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not replay blocks")
|
return nil, errors.Wrap(err, "could not replay blocks")
|
||||||
}
|
}
|
||||||
@@ -125,13 +125,13 @@ func (s *State) stateSummary(ctx context.Context, blockRoot [32]byte) (*ethpb.St
|
|||||||
}
|
}
|
||||||
|
|
||||||
if summary == nil {
|
if summary == nil {
|
||||||
return s.RecoverStateSummary(ctx, blockRoot)
|
return s.recoverStateSummary(ctx, blockRoot)
|
||||||
}
|
}
|
||||||
return summary, nil
|
return summary, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecoverStateSummary recovers state summary object of a given block root by using the saved block in DB.
|
// RecoverStateSummary recovers state summary object of a given block root by using the saved block in DB.
|
||||||
func (s *State) RecoverStateSummary(ctx context.Context, blockRoot [32]byte) (*ethpb.StateSummary, error) {
|
func (s *State) recoverStateSummary(ctx context.Context, blockRoot [32]byte) (*ethpb.StateSummary, error) {
|
||||||
if s.beaconDB.HasBlock(ctx, blockRoot) {
|
if s.beaconDB.HasBlock(ctx, blockRoot) {
|
||||||
b, err := s.beaconDB.Block(ctx, blockRoot)
|
b, err := s.beaconDB.Block(ctx, blockRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -185,7 +185,7 @@ func (s *State) loadStateByRoot(ctx context.Context, blockRoot [32]byte) (state.
|
|||||||
|
|
||||||
// Since the requested state is not in caches or DB, start replaying using the last
|
// Since the requested state is not in caches or DB, start replaying using the last
|
||||||
// available ancestor state which is retrieved using input block's root.
|
// available ancestor state which is retrieved using input block's root.
|
||||||
startState, err := s.LastAncestorState(ctx, blockRoot)
|
startState, err := s.latestAncestor(ctx, blockRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get ancestor state")
|
return nil, errors.Wrap(err, "could not get ancestor state")
|
||||||
}
|
}
|
||||||
@@ -197,17 +197,17 @@ func (s *State) loadStateByRoot(ctx context.Context, blockRoot [32]byte) (state.
|
|||||||
return startState, nil
|
return startState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
blks, err := s.LoadBlocks(ctx, startState.Slot()+1, targetSlot, bytesutil.ToBytes32(summary.Root))
|
blks, err := s.loadBlocks(ctx, startState.Slot()+1, targetSlot, bytesutil.ToBytes32(summary.Root))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not load blocks for hot state using root")
|
return nil, errors.Wrap(err, "could not load blocks for hot state using root")
|
||||||
}
|
}
|
||||||
|
|
||||||
replayBlockCount.Observe(float64(len(blks)))
|
replayBlockCount.Observe(float64(len(blks)))
|
||||||
|
|
||||||
return s.ReplayBlocks(ctx, startState, blks, targetSlot)
|
return s.replayBlocks(ctx, startState, blks, targetSlot)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LastAncestorState returns the highest available ancestor state of the input block root.
|
// latestAncestor returns the highest available ancestor state of the input block root.
|
||||||
// It recursively looks up block's parent until a corresponding state of the block root
|
// It recursively looks up block's parent until a corresponding state of the block root
|
||||||
// is found in the caches or DB.
|
// is found in the caches or DB.
|
||||||
//
|
//
|
||||||
@@ -215,8 +215,8 @@ func (s *State) loadStateByRoot(ctx context.Context, blockRoot [32]byte) (state.
|
|||||||
// 1) block parent state is the last finalized state
|
// 1) block parent state is the last finalized state
|
||||||
// 2) block parent state is the epoch boundary state and exists in epoch boundary cache
|
// 2) block parent state is the epoch boundary state and exists in epoch boundary cache
|
||||||
// 3) block parent state is in DB
|
// 3) block parent state is in DB
|
||||||
func (s *State) LastAncestorState(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error) {
|
func (s *State) latestAncestor(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "stateGen.LastAncestorState")
|
ctx, span := trace.StartSpan(ctx, "stateGen.latestAncestor")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if s.isFinalizedRoot(blockRoot) && s.finalizedState() != nil {
|
if s.isFinalizedRoot(blockRoot) && s.finalizedState() != nil {
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ func TestLastAncestorState_CanGetUsingDB(t *testing.T) {
|
|||||||
util.SaveBlock(t, ctx, service.beaconDB, b3)
|
util.SaveBlock(t, ctx, service.beaconDB, b3)
|
||||||
require.NoError(t, service.beaconDB.SaveState(ctx, b1State, r1))
|
require.NoError(t, service.beaconDB.SaveState(ctx, b1State, r1))
|
||||||
|
|
||||||
lastState, err := service.LastAncestorState(ctx, r3)
|
lastState, err := service.latestAncestor(ctx, r3)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, b1State.Slot(), lastState.Slot(), "Did not get wanted state")
|
assert.Equal(t, b1State.Slot(), lastState.Slot(), "Did not get wanted state")
|
||||||
}
|
}
|
||||||
@@ -425,7 +425,7 @@ func TestLastAncestorState_CanGetUsingCache(t *testing.T) {
|
|||||||
util.SaveBlock(t, ctx, service.beaconDB, b3)
|
util.SaveBlock(t, ctx, service.beaconDB, b3)
|
||||||
service.hotStateCache.put(r1, b1State)
|
service.hotStateCache.put(r1, b1State)
|
||||||
|
|
||||||
lastState, err := service.LastAncestorState(ctx, r3)
|
lastState, err := service.latestAncestor(ctx, r3)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, b1State.Slot(), lastState.Slot(), "Did not get wanted state")
|
assert.Equal(t, b1State.Slot(), lastState.Slot(), "Did not get wanted state")
|
||||||
}
|
}
|
||||||
@@ -483,7 +483,7 @@ func TestState_HasStateInCache(t *testing.T) {
|
|||||||
{rMiss, false},
|
{rMiss, false},
|
||||||
}
|
}
|
||||||
for _, tc := range tt {
|
for _, tc := range tt {
|
||||||
got, err := service.HasStateInCache(ctx, tc.root)
|
got, err := service.hasStateInCache(ctx, tc.root)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tc.want, got)
|
require.Equal(t, tc.want, got)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/stategen:go_default_library",
|
"//beacon-chain/state/stategen:go_default_library",
|
||||||
"//consensus-types/interfaces:go_default_library",
|
|
||||||
"//consensus-types/primitives:go_default_library",
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockStateManager is a fake implementation of StateManager.
|
// MockStateManager is a fake implementation of StateManager.
|
||||||
@@ -43,35 +41,11 @@ func (_ *MockStateManager) MigrateToCold(_ context.Context, _ [32]byte) error {
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReplayBlocks --
|
|
||||||
func (_ *MockStateManager) ReplayBlocks(
|
|
||||||
_ context.Context,
|
|
||||||
_ state.BeaconState,
|
|
||||||
_ []interfaces.SignedBeaconBlock,
|
|
||||||
_ types.Slot,
|
|
||||||
) (state.BeaconState, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadBlocks --
|
|
||||||
func (_ *MockStateManager) LoadBlocks(
|
|
||||||
_ context.Context,
|
|
||||||
_, _ types.Slot,
|
|
||||||
_ [32]byte,
|
|
||||||
) ([]interfaces.SignedBeaconBlock, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasState --
|
// HasState --
|
||||||
func (_ *MockStateManager) HasState(_ context.Context, _ [32]byte) (bool, error) {
|
func (_ *MockStateManager) HasState(_ context.Context, _ [32]byte) (bool, error) {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasStateInCache --
|
|
||||||
func (_ *MockStateManager) HasStateInCache(_ context.Context, _ [32]byte) (bool, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
// StateByRoot --
|
// StateByRoot --
|
||||||
func (m *MockStateManager) StateByRoot(_ context.Context, blockRoot [32]byte) (state.BeaconState, error) {
|
func (m *MockStateManager) StateByRoot(_ context.Context, blockRoot [32]byte) (state.BeaconState, error) {
|
||||||
return m.StatesByRoot[blockRoot], nil
|
return m.StatesByRoot[blockRoot], nil
|
||||||
@@ -87,14 +61,6 @@ func (m *MockStateManager) StateBySlot(_ context.Context, slot types.Slot) (stat
|
|||||||
return m.StatesBySlot[slot], nil
|
return m.StatesBySlot[slot], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecoverStateSummary --
|
|
||||||
func (_ *MockStateManager) RecoverStateSummary(
|
|
||||||
_ context.Context,
|
|
||||||
_ [32]byte,
|
|
||||||
) (*ethpb.StateSummary, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveState --
|
// SaveState --
|
||||||
func (_ *MockStateManager) SaveState(_ context.Context, _ [32]byte, _ state.BeaconState) error {
|
func (_ *MockStateManager) SaveState(_ context.Context, _ [32]byte, _ state.BeaconState) error {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
@@ -105,16 +71,6 @@ func (_ *MockStateManager) ForceCheckpoint(_ context.Context, _ []byte) error {
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableSaveHotStateToDB --
|
|
||||||
func (_ *MockStateManager) EnableSaveHotStateToDB(_ context.Context) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisableSaveHotStateToDB --
|
|
||||||
func (_ *MockStateManager) DisableSaveHotStateToDB(_ context.Context) error {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddStateForRoot --
|
// AddStateForRoot --
|
||||||
func (m *MockStateManager) AddStateForRoot(state state.BeaconState, blockRoot [32]byte) {
|
func (m *MockStateManager) AddStateForRoot(state state.BeaconState, blockRoot [32]byte) {
|
||||||
m.StatesByRoot[blockRoot] = state
|
m.StatesByRoot[blockRoot] = state
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ import (
|
|||||||
// ReplayBlocks replays the input blocks on the input state until the target slot is reached.
|
// ReplayBlocks replays the input blocks on the input state until the target slot is reached.
|
||||||
//
|
//
|
||||||
// WARNING Blocks passed to the function must be in decreasing slots order.
|
// WARNING Blocks passed to the function must be in decreasing slots order.
|
||||||
func (_ *State) ReplayBlocks(
|
func (_ *State) replayBlocks(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
state state.BeaconState,
|
state state.BeaconState,
|
||||||
signed []interfaces.SignedBeaconBlock,
|
signed []interfaces.SignedBeaconBlock,
|
||||||
targetSlot types.Slot,
|
targetSlot types.Slot,
|
||||||
) (state.BeaconState, error) {
|
) (state.BeaconState, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "stateGen.ReplayBlocks")
|
ctx, span := trace.StartSpan(ctx, "stateGen.replayBlocks")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -77,9 +77,9 @@ func (_ *State) ReplayBlocks(
|
|||||||
return state, nil
|
return state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadBlocks loads the blocks between start slot and end slot by recursively fetching from end block root.
|
// loadBlocks loads the blocks between start slot and end slot by recursively fetching from end block root.
|
||||||
// The Blocks are returned in slot-descending order.
|
// The Blocks are returned in slot-descending order.
|
||||||
func (s *State) LoadBlocks(ctx context.Context, startSlot, endSlot types.Slot, endBlockRoot [32]byte) ([]interfaces.SignedBeaconBlock, error) {
|
func (s *State) loadBlocks(ctx context.Context, startSlot, endSlot types.Slot, endBlockRoot [32]byte) ([]interfaces.SignedBeaconBlock, error) {
|
||||||
// Nothing to load for invalid range.
|
// Nothing to load for invalid range.
|
||||||
if endSlot < startSlot {
|
if endSlot < startSlot {
|
||||||
return nil, fmt.Errorf("start slot %d >= end slot %d", startSlot, endSlot)
|
return nil, fmt.Errorf("start slot %d >= end slot %d", startSlot, endSlot)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func TestReplayBlocks_AllSkipSlots(t *testing.T) {
|
|||||||
|
|
||||||
service := New(beaconDB)
|
service := New(beaconDB)
|
||||||
targetSlot := params.BeaconConfig().SlotsPerEpoch - 1
|
targetSlot := params.BeaconConfig().SlotsPerEpoch - 1
|
||||||
newState, err := service.ReplayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot)
|
newState, err := service.replayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots")
|
assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots")
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ func TestReplayBlocks_SameSlot(t *testing.T) {
|
|||||||
|
|
||||||
service := New(beaconDB)
|
service := New(beaconDB)
|
||||||
targetSlot := beaconState.Slot()
|
targetSlot := beaconState.Slot()
|
||||||
newState, err := service.ReplayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot)
|
newState, err := service.replayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots")
|
assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots")
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ func TestReplayBlocks_LowerSlotBlock(t *testing.T) {
|
|||||||
b.Block.Slot = beaconState.Slot() - 1
|
b.Block.Slot = beaconState.Slot() - 1
|
||||||
wsb, err := wrapper.WrappedSignedBeaconBlock(b)
|
wsb, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
newState, err := service.ReplayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{wsb}, targetSlot)
|
newState, err := service.replayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{wsb}, targetSlot)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots")
|
assert.Equal(t, targetSlot, newState.Slot(), "Did not advance slots")
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ func TestReplayBlocks_ThroughForkBoundary(t *testing.T) {
|
|||||||
|
|
||||||
service := New(testDB.SetupDB(t))
|
service := New(testDB.SetupDB(t))
|
||||||
targetSlot := params.BeaconConfig().SlotsPerEpoch
|
targetSlot := params.BeaconConfig().SlotsPerEpoch
|
||||||
newState, err := service.ReplayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot)
|
newState, err := service.replayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Verify state is version Altair.
|
// Verify state is version Altair.
|
||||||
@@ -162,7 +162,7 @@ func TestReplayBlocks_ThroughBellatrixForkBoundary(t *testing.T) {
|
|||||||
|
|
||||||
service := New(testDB.SetupDB(t))
|
service := New(testDB.SetupDB(t))
|
||||||
targetSlot := params.BeaconConfig().SlotsPerEpoch * 2
|
targetSlot := params.BeaconConfig().SlotsPerEpoch * 2
|
||||||
newState, err := service.ReplayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot)
|
newState, err := service.replayBlocks(context.Background(), beaconState, []interfaces.SignedBeaconBlock{}, targetSlot)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Verify state is version Altair.
|
// Verify state is version Altair.
|
||||||
@@ -179,7 +179,7 @@ func TestLoadBlocks_FirstBranch(t *testing.T) {
|
|||||||
roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
filteredBlocks, err := s.LoadBlocks(ctx, 0, 8, roots[len(roots)-1])
|
filteredBlocks, err := s.loadBlocks(ctx, 0, 8, roots[len(roots)-1])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
wanted := []*ethpb.SignedBeaconBlock{
|
wanted := []*ethpb.SignedBeaconBlock{
|
||||||
@@ -208,7 +208,7 @@ func TestLoadBlocks_SecondBranch(t *testing.T) {
|
|||||||
roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
filteredBlocks, err := s.LoadBlocks(ctx, 0, 5, roots[5])
|
filteredBlocks, err := s.loadBlocks(ctx, 0, 5, roots[5])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
wanted := []*ethpb.SignedBeaconBlock{
|
wanted := []*ethpb.SignedBeaconBlock{
|
||||||
@@ -235,7 +235,7 @@ func TestLoadBlocks_ThirdBranch(t *testing.T) {
|
|||||||
roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
roots, savedBlocks, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
filteredBlocks, err := s.LoadBlocks(ctx, 0, 7, roots[7])
|
filteredBlocks, err := s.loadBlocks(ctx, 0, 7, roots[7])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
wanted := []*ethpb.SignedBeaconBlock{
|
wanted := []*ethpb.SignedBeaconBlock{
|
||||||
@@ -264,7 +264,7 @@ func TestLoadBlocks_SameSlots(t *testing.T) {
|
|||||||
roots, savedBlocks, err := tree2(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
roots, savedBlocks, err := tree2(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
filteredBlocks, err := s.LoadBlocks(ctx, 0, 3, roots[6])
|
filteredBlocks, err := s.loadBlocks(ctx, 0, 3, roots[6])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
wanted := []*ethpb.SignedBeaconBlock{
|
wanted := []*ethpb.SignedBeaconBlock{
|
||||||
@@ -291,7 +291,7 @@ func TestLoadBlocks_SameEndSlots(t *testing.T) {
|
|||||||
roots, savedBlocks, err := tree3(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
roots, savedBlocks, err := tree3(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
filteredBlocks, err := s.LoadBlocks(ctx, 0, 2, roots[2])
|
filteredBlocks, err := s.loadBlocks(ctx, 0, 2, roots[2])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
wanted := []*ethpb.SignedBeaconBlock{
|
wanted := []*ethpb.SignedBeaconBlock{
|
||||||
@@ -317,7 +317,7 @@ func TestLoadBlocks_SameEndSlotsWith2blocks(t *testing.T) {
|
|||||||
roots, savedBlocks, err := tree4(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
roots, savedBlocks, err := tree4(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
filteredBlocks, err := s.LoadBlocks(ctx, 0, 2, roots[1])
|
filteredBlocks, err := s.loadBlocks(ctx, 0, 2, roots[1])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
wanted := []*ethpb.SignedBeaconBlock{
|
wanted := []*ethpb.SignedBeaconBlock{
|
||||||
@@ -341,7 +341,7 @@ func TestLoadBlocks_BadStart(t *testing.T) {
|
|||||||
|
|
||||||
roots, _, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
roots, _, err := tree1(t, beaconDB, bytesutil.PadTo([]byte{'A'}, 32))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = s.LoadBlocks(ctx, 0, 5, roots[8])
|
_, err = s.loadBlocks(ctx, 0, 5, roots[8])
|
||||||
assert.ErrorContains(t, "end block roots don't match", err)
|
assert.ErrorContains(t, "end block roots don't match", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,3 +173,10 @@ type ReplayerBuilder interface {
|
|||||||
// slots via process_slots.
|
// slots via process_slots.
|
||||||
ReplayerForSlot(target types.Slot) Replayer
|
ReplayerForSlot(target types.Slot) Replayer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReplayerBuiilderWaiter is designed for situations where services need to start up before it is possible to init
|
||||||
|
// a ReplayerBuilder. When WaitForReplayerBuilder is called,
|
||||||
|
// it will block until prerequisites for a replayer are available, or the parent context is canceled.
|
||||||
|
type CanonicalHistoryWaiter interface {
|
||||||
|
WaitForCanonicalHistory(context.Context) (*CanonicalHistory, error)
|
||||||
|
}
|
||||||
@@ -6,16 +6,15 @@ package stategen
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
forkchoicetypes "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/types"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/sync/backfill"
|
"github.com/prysmaticlabs/prysm/beacon-chain/sync/backfill"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -25,21 +24,15 @@ var defaultHotStateDBInterval types.Slot = 128
|
|||||||
// logic of maintaining both hot and cold states in DB.
|
// logic of maintaining both hot and cold states in DB.
|
||||||
type StateManager interface {
|
type StateManager interface {
|
||||||
Resume(ctx context.Context, fState state.BeaconState) (state.BeaconState, error)
|
Resume(ctx context.Context, fState state.BeaconState) (state.BeaconState, error)
|
||||||
|
HasState(ctx context.Context, blockRoot [32]byte) (bool, error)
|
||||||
|
DeleteStateFromCaches(ctx context.Context, blockRoot [32]byte) error
|
||||||
|
ForceCheckpoint(ctx context.Context, root []byte) error
|
||||||
|
SaveState(ctx context.Context, blockRoot [32]byte, st state.BeaconState) error
|
||||||
SaveFinalizedState(fSlot types.Slot, fRoot [32]byte, fState state.BeaconState)
|
SaveFinalizedState(fSlot types.Slot, fRoot [32]byte, fState state.BeaconState)
|
||||||
MigrateToCold(ctx context.Context, fRoot [32]byte) error
|
MigrateToCold(ctx context.Context, fRoot [32]byte) error
|
||||||
ReplayBlocks(ctx context.Context, state state.BeaconState, signed []interfaces.SignedBeaconBlock, targetSlot types.Slot) (state.BeaconState, error)
|
|
||||||
LoadBlocks(ctx context.Context, startSlot, endSlot types.Slot, endBlockRoot [32]byte) ([]interfaces.SignedBeaconBlock, error)
|
|
||||||
HasState(ctx context.Context, blockRoot [32]byte) (bool, error)
|
|
||||||
HasStateInCache(ctx context.Context, blockRoot [32]byte) (bool, error)
|
|
||||||
StateByRoot(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
StateByRoot(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
||||||
StateByRootIfCachedNoCopy(blockRoot [32]byte) state.BeaconState
|
StateByRootIfCachedNoCopy(blockRoot [32]byte) state.BeaconState
|
||||||
StateByRootInitialSync(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
StateByRootInitialSync(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
||||||
RecoverStateSummary(ctx context.Context, blockRoot [32]byte) (*ethpb.StateSummary, error)
|
|
||||||
SaveState(ctx context.Context, blockRoot [32]byte, st state.BeaconState) error
|
|
||||||
ForceCheckpoint(ctx context.Context, root []byte) error
|
|
||||||
EnableSaveHotStateToDB(_ context.Context)
|
|
||||||
DisableSaveHotStateToDB(ctx context.Context) error
|
|
||||||
DeleteStateFromCaches(ctx context.Context, blockRoot [32]byte) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// State is a concrete implementation of StateManager.
|
// State is a concrete implementation of StateManager.
|
||||||
@@ -51,6 +44,12 @@ type State struct {
|
|||||||
epochBoundaryStateCache *epochBoundaryState
|
epochBoundaryStateCache *epochBoundaryState
|
||||||
saveHotStateDB *saveHotStateDbConfig
|
saveHotStateDB *saveHotStateDbConfig
|
||||||
backfillStatus *backfill.Status
|
backfillStatus *backfill.Status
|
||||||
|
fc minimumForkChoicer
|
||||||
|
cs CurrentSlotter
|
||||||
|
}
|
||||||
|
|
||||||
|
type minimumForkChoicer interface {
|
||||||
|
FinalizedCheckpoint() *forkchoicetypes.Checkpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// This tracks the config in the event of long non-finality,
|
// This tracks the config in the event of long non-finality,
|
||||||
@@ -81,6 +80,18 @@ func WithBackfillStatus(bfs *backfill.Status) StateGenOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithMinimumForkChoicer(fc minimumForkChoicer) StateGenOption {
|
||||||
|
return func(sg *State) {
|
||||||
|
sg.fc = fc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithCurrentSlotter(cs CurrentSlotter) StateGenOption {
|
||||||
|
return func(sg *State) {
|
||||||
|
sg.cs = cs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// New returns a new state management object.
|
// New returns a new state management object.
|
||||||
func New(beaconDB db.NoHeadAccessDatabase, opts ...StateGenOption) *State {
|
func New(beaconDB db.NoHeadAccessDatabase, opts ...StateGenOption) *State {
|
||||||
s := &State{
|
s := &State{
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package stategen
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
@@ -13,12 +15,38 @@ import (
|
|||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
var errForkChoiceFinalizedNil = errors.New("nil finalized checkpoint returned from forkchoice store")
|
||||||
|
|
||||||
|
// number of epochs of non-finality before the hot state store will begin saving snapshots for faster recovery.
|
||||||
|
var hotStateSaveThreshold = types.Epoch(100)
|
||||||
|
|
||||||
// SaveState saves the state in the cache and/or DB.
|
// SaveState saves the state in the cache and/or DB.
|
||||||
func (s *State) SaveState(ctx context.Context, blockRoot [32]byte, st state.BeaconState) error {
|
func (s *State) SaveState(ctx context.Context, blockRoot [32]byte, st state.BeaconState) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "stateGen.SaveState")
|
ctx, span := trace.StartSpan(ctx, "stateGen.SaveState")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
return s.saveStateByRoot(ctx, blockRoot, st)
|
if err := s.saveStateByRoot(ctx, blockRoot, st); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.toggleHotStateSaving(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) toggleHotStateSaving(ctx context.Context) error {
|
||||||
|
finalized := s.fc.FinalizedCheckpoint()
|
||||||
|
if finalized == nil {
|
||||||
|
return errForkChoiceFinalizedNil
|
||||||
|
}
|
||||||
|
|
||||||
|
currentEpoch := slots.ToEpoch(s.cs.CurrentSlot())
|
||||||
|
if currentEpoch > finalized.Epoch {
|
||||||
|
if currentEpoch - finalized.Epoch > hotStateSaveThreshold {
|
||||||
|
s.EnableSaveHotStateToDB(ctx)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.DisableSaveHotStateToDB(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForceCheckpoint initiates a cold state save of the given block root's state. This method does not update the
|
// ForceCheckpoint initiates a cold state save of the given block root's state. This method does not update the
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ package stategen
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
|
||||||
|
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
|
forkchoicetypes "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/types"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSaveState_HotStateCanBeSaved(t *testing.T) {
|
func TestSaveState_HotStateCanBeSaved(t *testing.T) {
|
||||||
@@ -201,3 +201,28 @@ func TestEnableSaveHotStateToDB_AlreadyDisabled(t *testing.T) {
|
|||||||
require.LogsDoNotContain(t, hook, "Exiting mode to save hot states in DB")
|
require.LogsDoNotContain(t, hook, "Exiting mode to save hot states in DB")
|
||||||
require.Equal(t, false, service.saveHotStateDB.enabled)
|
require.Equal(t, false, service.saveHotStateDB.enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mockMinForkChoicer struct {
|
||||||
|
finalizedCheckpoint *forkchoicetypes.Checkpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ minimumForkChoicer = &mockMinForkChoicer{}
|
||||||
|
|
||||||
|
func (fc *mockMinForkChoicer) FinalizedCheckpoint() *forkchoicetypes.Checkpoint {
|
||||||
|
return fc.finalizedCheckpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSaveHotStateDB_EnableDisable(t *testing.T) {
|
||||||
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
service := New(beaconDB)
|
||||||
|
// the zero value will return a finalized checkpoint at slot 0 with zero-value for root - this is fine!
|
||||||
|
service.fc = &mockMinForkChoicer{}
|
||||||
|
// set current slot as over the threshhold for hot state to be enabled
|
||||||
|
service.cs = &mockCurrentSlotter{Slot: params.BeaconConfig().SlotsPerEpoch.Mul(uint64(hotStateSaveThreshold))}
|
||||||
|
|
||||||
|
require.NoError(t, service.toggleHotStateSaving(context.Background()))
|
||||||
|
require.Equal(t, true, service.saveHotStateDB.enabled)
|
||||||
|
// set the finalized checkpoint to the same slot as the current slotter, assert that hot state saving is now disabled
|
||||||
|
service.fc = &mockMinForkChoicer{finalizedCheckpoint: &forkchoicetypes.Checkpoint{Epoch: hotStateSaveThreshold}}
|
||||||
|
require.Equal(t, false, service.saveHotStateDB.enabled)
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ import (
|
|||||||
// Is a background routine that observes for new incoming forks. Depending on the epoch
|
// Is a background routine that observes for new incoming forks. Depending on the epoch
|
||||||
// it will be in charge of subscribing/unsubscribing the relevant topics at the fork boundaries.
|
// it will be in charge of subscribing/unsubscribing the relevant topics at the fork boundaries.
|
||||||
func (s *Service) forkWatcher() {
|
func (s *Service) forkWatcher() {
|
||||||
slotTicker := slots.NewSlotTicker(s.cfg.chain.GenesisTime(), params.BeaconConfig().SecondsPerSlot)
|
clock, err := s.cfg.chain.WaitForClock(s.ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("timeout waiting for genesis time in forkWatcher()")
|
||||||
|
}
|
||||||
|
slotTicker := slots.NewSlotTicker(clock.GenesisTime(), params.BeaconConfig().SecondsPerSlot)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
// In the event of a node restart, we will still end up subscribing to the correct
|
// In the event of a node restart, we will still end up subscribing to the correct
|
||||||
@@ -40,7 +44,11 @@ func (s *Service) forkWatcher() {
|
|||||||
// it registers the appropriate gossip and rpc topics.
|
// it registers the appropriate gossip and rpc topics.
|
||||||
func (s *Service) registerForUpcomingFork(currEpoch types.Epoch) error {
|
func (s *Service) registerForUpcomingFork(currEpoch types.Epoch) error {
|
||||||
genRoot := s.cfg.chain.GenesisValidatorsRoot()
|
genRoot := s.cfg.chain.GenesisValidatorsRoot()
|
||||||
isNextForkEpoch, err := forks.IsForkNextEpoch(s.cfg.chain.GenesisTime(), genRoot[:])
|
clock, err := s.cfg.chain.WaitForClock(s.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "timeout waiting for genesis time in registerForUpcomingFork")
|
||||||
|
}
|
||||||
|
isNextForkEpoch, err := forks.IsForkNextEpoch(clock.GenesisTime(), genRoot[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Could not retrieve next fork epoch")
|
return errors.Wrap(err, "Could not retrieve next fork epoch")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package sync
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/prysmaticlabs/prysm/async"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -91,57 +92,61 @@ var (
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Service) updateMetrics() {
|
func (s *Service) spawnUpdateMetrics() {
|
||||||
// do not update metrics if genesis time
|
// do not update metrics if genesis time has not been initialized
|
||||||
// has not been initialized
|
c, err := s.cfg.chain.WaitForClock(s.ctx)
|
||||||
if s.cfg.chain.GenesisTime().IsZero() {
|
if err != nil {
|
||||||
|
log.WithError(err).Error("timeout while waiting for geenesis time in spawnUpdateMetrics")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// We update the dynamic subnet topics.
|
async.RunEvery(s.ctx, syncMetricsInterval, func() {
|
||||||
digest, err := s.currentForkDigest()
|
// We update the dynamic subnet topics.
|
||||||
if err != nil {
|
digest, err := s.currentForkDigest()
|
||||||
log.WithError(err).Debugf("Could not compute fork digest")
|
if err != nil {
|
||||||
}
|
log.WithError(err).Debugf("Could not compute fork digest")
|
||||||
indices := s.aggregatorSubnetIndices(s.cfg.chain.CurrentSlot())
|
|
||||||
syncIndices := cache.SyncSubnetIDs.GetAllSubnets(slots.ToEpoch(s.cfg.chain.CurrentSlot()))
|
|
||||||
attTopic := p2p.GossipTypeMapping[reflect.TypeOf(&pb.Attestation{})]
|
|
||||||
syncTopic := p2p.GossipTypeMapping[reflect.TypeOf(&pb.SyncCommitteeMessage{})]
|
|
||||||
attTopic += s.cfg.p2p.Encoding().ProtocolSuffix()
|
|
||||||
syncTopic += s.cfg.p2p.Encoding().ProtocolSuffix()
|
|
||||||
if flags.Get().SubscribeToAllSubnets {
|
|
||||||
for i := uint64(0); i < params.BeaconNetworkConfig().AttestationSubnetCount; i++ {
|
|
||||||
s.collectMetricForSubnet(attTopic, digest, i)
|
|
||||||
}
|
}
|
||||||
for i := uint64(0); i < params.BeaconConfig().SyncCommitteeSubnetCount; i++ {
|
indices := s.aggregatorSubnetIndices(c.CurrentSlot())
|
||||||
s.collectMetricForSubnet(syncTopic, digest, i)
|
syncIndices := cache.SyncSubnetIDs.GetAllSubnets(slots.ToEpoch(c.CurrentSlot()))
|
||||||
|
attTopic := p2p.GossipTypeMapping[reflect.TypeOf(&pb.Attestation{})]
|
||||||
|
syncTopic := p2p.GossipTypeMapping[reflect.TypeOf(&pb.SyncCommitteeMessage{})]
|
||||||
|
attTopic += s.cfg.p2p.Encoding().ProtocolSuffix()
|
||||||
|
syncTopic += s.cfg.p2p.Encoding().ProtocolSuffix()
|
||||||
|
if flags.Get().SubscribeToAllSubnets {
|
||||||
|
for i := uint64(0); i < params.BeaconNetworkConfig().AttestationSubnetCount; i++ {
|
||||||
|
s.collectMetricForSubnet(attTopic, digest, i)
|
||||||
|
}
|
||||||
|
for i := uint64(0); i < params.BeaconConfig().SyncCommitteeSubnetCount; i++ {
|
||||||
|
s.collectMetricForSubnet(syncTopic, digest, i)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, committeeIdx := range indices {
|
||||||
|
s.collectMetricForSubnet(attTopic, digest, committeeIdx)
|
||||||
|
}
|
||||||
|
for _, committeeIdx := range syncIndices {
|
||||||
|
s.collectMetricForSubnet(syncTopic, digest, committeeIdx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for _, committeeIdx := range indices {
|
|
||||||
s.collectMetricForSubnet(attTopic, digest, committeeIdx)
|
|
||||||
}
|
|
||||||
for _, committeeIdx := range syncIndices {
|
|
||||||
s.collectMetricForSubnet(syncTopic, digest, committeeIdx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We update all other gossip topics.
|
// We update all other gossip topics.
|
||||||
for _, topic := range p2p.AllTopics() {
|
for _, topic := range p2p.AllTopics() {
|
||||||
// We already updated attestation subnet topics.
|
// We already updated attestation subnet topics.
|
||||||
if strings.Contains(topic, p2p.GossipAttestationMessage) || strings.Contains(topic, p2p.GossipSyncCommitteeMessage) {
|
if strings.Contains(topic, p2p.GossipAttestationMessage) || strings.Contains(topic, p2p.GossipSyncCommitteeMessage) {
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
topic += s.cfg.p2p.Encoding().ProtocolSuffix()
|
||||||
|
if !strings.Contains(topic, "%x") {
|
||||||
|
topicPeerCount.WithLabelValues(topic).Set(float64(len(s.cfg.p2p.PubSub().ListPeers(topic))))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
formattedTopic := fmt.Sprintf(topic, digest)
|
||||||
|
topicPeerCount.WithLabelValues(formattedTopic).Set(float64(len(s.cfg.p2p.PubSub().ListPeers(formattedTopic))))
|
||||||
}
|
}
|
||||||
topic += s.cfg.p2p.Encoding().ProtocolSuffix()
|
|
||||||
if !strings.Contains(topic, "%x") {
|
|
||||||
topicPeerCount.WithLabelValues(topic).Set(float64(len(s.cfg.p2p.PubSub().ListPeers(topic))))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
formattedTopic := fmt.Sprintf(topic, digest)
|
|
||||||
topicPeerCount.WithLabelValues(formattedTopic).Set(float64(len(s.cfg.p2p.PubSub().ListPeers(formattedTopic))))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, topic := range s.cfg.p2p.PubSub().GetTopics() {
|
for _, topic := range s.cfg.p2p.PubSub().GetTopics() {
|
||||||
subscribedTopicPeerCount.WithLabelValues(topic).Set(float64(len(s.cfg.p2p.PubSub().ListPeers(topic))))
|
subscribedTopicPeerCount.WithLabelValues(topic).Set(float64(len(s.cfg.p2p.PubSub().ListPeers(topic))))
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) collectMetricForSubnet(topic string, digest [4]byte, index uint64) {
|
func (s *Service) collectMetricForSubnet(topic string, digest [4]byte, index uint64) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package sync
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||||
@@ -42,10 +43,14 @@ func (s *Service) processPendingAtts(ctx context.Context) error {
|
|||||||
ctx, span := trace.StartSpan(ctx, "processPendingAtts")
|
ctx, span := trace.StartSpan(ctx, "processPendingAtts")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
c, err := s.cfg.chain.WaitForClock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "timeout while waiting for genesis timestamp")
|
||||||
|
}
|
||||||
// Before a node processes pending attestations queue, it verifies
|
// Before a node processes pending attestations queue, it verifies
|
||||||
// the attestations in the queue are still valid. Attestations will
|
// the attestations in the queue are still valid. Attestations will
|
||||||
// be deleted from the queue if invalid (ie. getting staled from falling too many slots behind).
|
// be deleted from the queue if invalid (ie. getting staled from falling too many slots behind).
|
||||||
s.validatePendingAtts(ctx, s.cfg.chain.CurrentSlot())
|
s.validatePendingAtts(ctx, c.CurrentSlot())
|
||||||
|
|
||||||
s.pendingAttsLock.RLock()
|
s.pendingAttsLock.RLock()
|
||||||
roots := make([][32]byte, 0, len(s.blkRootToPendingAtts))
|
roots := make([][32]byte, 0, len(s.blkRootToPendingAtts))
|
||||||
@@ -75,7 +80,7 @@ func (s *Service) processPendingAtts(ctx context.Context) error {
|
|||||||
} else {
|
} else {
|
||||||
// Pending attestation's missing block has not arrived yet.
|
// Pending attestation's missing block has not arrived yet.
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"currentSlot": s.cfg.chain.CurrentSlot(),
|
"currentSlot": c.CurrentSlot(),
|
||||||
"attSlot": attestations[0].Message.Aggregate.Data.Slot,
|
"attSlot": attestations[0].Message.Aggregate.Data.Slot,
|
||||||
"attCount": len(attestations),
|
"attCount": len(attestations),
|
||||||
"blockRoot": hex.EncodeToString(bytesutil.Trunc(bRoot[:])),
|
"blockRoot": hex.EncodeToString(bytesutil.Trunc(bRoot[:])),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user