mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-11 06:18:05 -05:00
Compare commits
46 Commits
e2e-blockr
...
v4.0.3-pat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9984b6cf38 | ||
|
|
f4681fde19 | ||
|
|
0c7292b85b | ||
|
|
10b438e2c8 | ||
|
|
e2386cfb11 | ||
|
|
898cb0b512 | ||
|
|
6944d22ce3 | ||
|
|
1eb00866ea | ||
|
|
4862d57b13 | ||
|
|
191b0c4652 | ||
|
|
c09977d8a8 | ||
|
|
52d72c989e | ||
|
|
9f7711e74a | ||
|
|
f376427add | ||
|
|
ff1b03ab13 | ||
|
|
5fdd4e9148 | ||
|
|
80e26143eb | ||
|
|
75338dd83d | ||
|
|
99eebe9bac | ||
|
|
6b1efff4e8 | ||
|
|
763e9e3361 | ||
|
|
37182168e3 | ||
|
|
0325741318 | ||
|
|
150e8aa14d | ||
|
|
f4307a902c | ||
|
|
d257ef1742 | ||
|
|
aad7aa79d4 | ||
|
|
2eb2f87913 | ||
|
|
9214364c5e | ||
|
|
fb65421678 | ||
|
|
35e3eeddf9 | ||
|
|
2618a114e5 | ||
|
|
aac47640b4 | ||
|
|
17cfc60bdd | ||
|
|
8d001d49d4 | ||
|
|
5ecebbe15a | ||
|
|
5ae7e17ada | ||
|
|
17488028a6 | ||
|
|
163f65f8a3 | ||
|
|
6ebe5ea8b2 | ||
|
|
5ea0417df2 | ||
|
|
61fed336e1 | ||
|
|
fed6a351cc | ||
|
|
98949d8075 | ||
|
|
5cbbd26df4 | ||
|
|
83ccb15e66 |
@@ -17,11 +17,12 @@ linters:
|
||||
- errcheck
|
||||
- gosimple
|
||||
- gocognit
|
||||
- misspell
|
||||
|
||||
linters-settings:
|
||||
gocognit:
|
||||
# TODO: We should target for < 50
|
||||
min-complexity: 69
|
||||
min-complexity: 65
|
||||
|
||||
output:
|
||||
print-issued-lines: true
|
||||
|
||||
@@ -164,7 +164,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains(
|
||||
go_version = "1.19.7",
|
||||
go_version = "1.19.8",
|
||||
nogo = "@//:nogo",
|
||||
)
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ func (fsr *forkScheduleResponse) OrderedForkSchedule() (forks.OrderedSchedule, e
|
||||
version := bytesutil.ToBytes4(vSlice)
|
||||
ofs = append(ofs, forks.ForkScheduleEntry{
|
||||
Version: version,
|
||||
Epoch: primitives.Epoch(epoch),
|
||||
Epoch: primitives.Epoch(uint64(epoch)),
|
||||
})
|
||||
}
|
||||
sort.Sort(ofs)
|
||||
|
||||
@@ -157,6 +157,7 @@ func (c *Client) do(ctx context.Context, method string, path string, body io.Rea
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.Header.Add("User-Agent", version.BuildData())
|
||||
for _, o := range opts {
|
||||
o(req)
|
||||
}
|
||||
|
||||
@@ -70,15 +70,16 @@ type Gateway struct {
|
||||
func New(ctx context.Context, opts ...Option) (*Gateway, error) {
|
||||
g := &Gateway{
|
||||
ctx: ctx,
|
||||
cfg: &config{
|
||||
router: mux.NewRouter(),
|
||||
},
|
||||
cfg: &config{},
|
||||
}
|
||||
for _, opt := range opts {
|
||||
if err := opt(g); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if g.cfg.router == nil {
|
||||
g.cfg.router = mux.NewRouter()
|
||||
}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,6 @@ import (
|
||||
|
||||
type Option func(g *Gateway) error
|
||||
|
||||
func (g *Gateway) SetRouter(r *mux.Router) *Gateway {
|
||||
g.cfg.router = r
|
||||
return g
|
||||
}
|
||||
|
||||
func WithPbHandlers(handlers []*PbMux) Option {
|
||||
return func(g *Gateway) error {
|
||||
g.cfg.pbHandlers = handlers
|
||||
|
||||
@@ -96,6 +96,8 @@ type FinalizationFetcher interface {
|
||||
FinalizedCheckpt() *ethpb.Checkpoint
|
||||
CurrentJustifiedCheckpt() *ethpb.Checkpoint
|
||||
PreviousJustifiedCheckpt() *ethpb.Checkpoint
|
||||
UnrealizedJustifiedPayloadBlockHash() ([32]byte, error)
|
||||
FinalizedBlockHash() [32]byte
|
||||
InForkchoice([32]byte) bool
|
||||
IsFinalized(ctx context.Context, blockRoot [32]byte) bool
|
||||
}
|
||||
@@ -400,7 +402,10 @@ func (s *Service) IsOptimisticForRoot(ctx context.Context, root [32]byte) (bool,
|
||||
}
|
||||
|
||||
if ss == nil {
|
||||
return true, errInvalidNilSummary
|
||||
ss, err = s.recoverStateSummary(ctx, root)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
validatedCheckpoint, err := s.cfg.BeaconDB.LastValidatedCheckpoint(ctx)
|
||||
if err != nil {
|
||||
@@ -426,7 +431,10 @@ func (s *Service) IsOptimisticForRoot(ctx context.Context, root [32]byte) (bool,
|
||||
return false, err
|
||||
}
|
||||
if lastValidated == nil {
|
||||
return false, errInvalidNilSummary
|
||||
lastValidated, err = s.recoverStateSummary(ctx, root)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
if ss.Slot > lastValidated.Slot {
|
||||
@@ -474,3 +482,18 @@ func (s *Service) Ancestor(ctx context.Context, root []byte, slot primitives.Slo
|
||||
func (s *Service) SetGenesisTime(t time.Time) {
|
||||
s.genesisTime = t
|
||||
}
|
||||
|
||||
func (s *Service) recoverStateSummary(ctx context.Context, blockRoot [32]byte) (*ethpb.StateSummary, error) {
|
||||
if s.cfg.BeaconDB.HasBlock(ctx, blockRoot) {
|
||||
b, err := s.cfg.BeaconDB.Block(ctx, blockRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
summary := ðpb.StateSummary{Slot: b.Block().Slot(), Root: blockRoot[:]}
|
||||
if err := s.cfg.BeaconDB.SaveStateSummary(ctx, summary); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return summary, nil
|
||||
}
|
||||
return nil, errBlockDoesNotExist
|
||||
}
|
||||
|
||||
@@ -78,3 +78,17 @@ func (s *Service) ChainHeads() ([][32]byte, []primitives.Slot) {
|
||||
defer s.cfg.ForkChoiceStore.RUnlock()
|
||||
return s.cfg.ForkChoiceStore.Tips()
|
||||
}
|
||||
|
||||
// UnrealizedJustifiedPayloadBlockHash returns unrealized justified payload block hash from forkchoice.
|
||||
func (s *Service) UnrealizedJustifiedPayloadBlockHash() ([32]byte, error) {
|
||||
s.cfg.ForkChoiceStore.RLock()
|
||||
defer s.cfg.ForkChoiceStore.RUnlock()
|
||||
return s.cfg.ForkChoiceStore.UnrealizedJustifiedPayloadBlockHash()
|
||||
}
|
||||
|
||||
// FinalizedBlockHash returns finalized payload block hash from forkchoice.
|
||||
func (s *Service) FinalizedBlockHash() [32]byte {
|
||||
s.cfg.ForkChoiceStore.RLock()
|
||||
defer s.cfg.ForkChoiceStore.RUnlock()
|
||||
return s.cfg.ForkChoiceStore.FinalizedPayloadBlockHash()
|
||||
}
|
||||
|
||||
@@ -119,6 +119,46 @@ func TestCurrentJustifiedCheckpt_CanRetrieve(t *testing.T) {
|
||||
require.Equal(t, cp.Root, bytesutil.ToBytes32(jp.Root))
|
||||
}
|
||||
|
||||
func TestFinalizedBlockHash(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
fcs := doublylinkedtree.New()
|
||||
opts := []Option{
|
||||
WithDatabase(beaconDB),
|
||||
WithForkChoiceStore(fcs),
|
||||
WithStateGen(stategen.New(beaconDB, fcs)),
|
||||
}
|
||||
service, err := NewService(ctx, opts...)
|
||||
require.NoError(t, err)
|
||||
|
||||
r := [32]byte{'f'}
|
||||
cp := &forkchoicetypes.Checkpoint{Epoch: 6, Root: r}
|
||||
bState, _ := util.DeterministicGenesisState(t, 10)
|
||||
require.NoError(t, beaconDB.SaveState(ctx, bState, r))
|
||||
|
||||
require.NoError(t, fcs.UpdateFinalizedCheckpoint(cp))
|
||||
h := service.FinalizedBlockHash()
|
||||
require.Equal(t, params.BeaconConfig().ZeroHash, h)
|
||||
require.Equal(t, r, fcs.FinalizedCheckpoint().Root)
|
||||
}
|
||||
|
||||
func TestUnrealizedJustifiedBlockHash(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
service := &Service{cfg: &config{ForkChoiceStore: doublylinkedtree.New()}}
|
||||
ojc := ðpb.Checkpoint{Root: []byte{'j'}}
|
||||
ofc := ðpb.Checkpoint{Root: []byte{'f'}}
|
||||
st, blkRoot, err := prepareForkchoiceState(ctx, 0, [32]byte{}, [32]byte{}, params.BeaconConfig().ZeroHash, ojc, ofc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, st, blkRoot))
|
||||
service.cfg.ForkChoiceStore.SetBalancesByRooter(func(_ context.Context, _ [32]byte) ([]uint64, error) { return []uint64{}, nil })
|
||||
require.NoError(t, service.cfg.ForkChoiceStore.UpdateJustifiedCheckpoint(ctx, &forkchoicetypes.Checkpoint{Epoch: 6, Root: [32]byte{'j'}}))
|
||||
|
||||
h, err := service.UnrealizedJustifiedPayloadBlockHash()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, params.BeaconConfig().ZeroHash, h)
|
||||
require.Equal(t, [32]byte{'j'}, service.cfg.ForkChoiceStore.JustifiedCheckpoint().Root)
|
||||
}
|
||||
|
||||
func TestHeadSlot_CanRetrieve(t *testing.T) {
|
||||
c := &Service{}
|
||||
s, err := state_native.InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||
@@ -478,15 +518,10 @@ func TestService_IsOptimisticForRoot_DB(t *testing.T) {
|
||||
validatedCheckpoint := ðpb.Checkpoint{Root: br[:]}
|
||||
require.NoError(t, beaconDB.SaveLastValidatedCheckpoint(ctx, validatedCheckpoint))
|
||||
|
||||
_, err = c.IsOptimisticForRoot(ctx, optimisticRoot)
|
||||
require.ErrorContains(t, "nil summary returned from the DB", err)
|
||||
|
||||
require.NoError(t, beaconDB.SaveStateSummary(context.Background(), ðpb.StateSummary{Root: optimisticRoot[:], Slot: 11}))
|
||||
optimistic, err := c.IsOptimisticForRoot(ctx, optimisticRoot)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, true, optimistic)
|
||||
|
||||
require.NoError(t, beaconDB.SaveStateSummary(context.Background(), ðpb.StateSummary{Root: validatedRoot[:], Slot: 9}))
|
||||
cp := ðpb.Checkpoint{
|
||||
Epoch: 1,
|
||||
Root: validatedRoot[:],
|
||||
@@ -548,6 +583,25 @@ func TestService_IsOptimisticForRoot_DB_non_canonical(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestService_IsOptimisticForRoot_StateSummaryRecovered(t *testing.T) {
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
c := &Service{cfg: &config{BeaconDB: beaconDB, ForkChoiceStore: doublylinkedtree.New()}, head: &head{root: [32]byte{'b'}}}
|
||||
c.head = &head{root: params.BeaconConfig().ZeroHash}
|
||||
b := util.NewBeaconBlock()
|
||||
b.Block.Slot = 10
|
||||
br, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
util.SaveBlock(t, context.Background(), beaconDB, b)
|
||||
_, err = c.IsOptimisticForRoot(ctx, br)
|
||||
assert.NoError(t, err)
|
||||
summ, err := beaconDB.StateSummary(ctx, br)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, summ)
|
||||
assert.Equal(t, 10, int(summ.Slot))
|
||||
assert.DeepEqual(t, br[:], summ.Root)
|
||||
}
|
||||
|
||||
func TestService_IsFinalized(t *testing.T) {
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
@@ -15,8 +15,8 @@ var (
|
||||
errNilFinalizedCheckpoint = errors.New("nil finalized checkpoint returned from state")
|
||||
// errNilJustifiedCheckpoint is returned when a nil justified checkpt is returned from a state.
|
||||
errNilJustifiedCheckpoint = errors.New("nil justified checkpoint returned from state")
|
||||
// errInvalidNilSummary is returned when a nil summary is returned from the DB.
|
||||
errInvalidNilSummary = errors.New("nil summary returned from the DB")
|
||||
// errBlockDoesNotExist is returned when a block does not exist for a particular state summary.
|
||||
errBlockDoesNotExist = errors.New("could not find block in DB")
|
||||
// errWrongBlockCount is returned when the wrong number of blocks or block roots is used
|
||||
errWrongBlockCount = errors.New("wrong number of blocks or block roots")
|
||||
// errBlockNotFoundInCacheOrDB is returned when a block is not found in the cache or DB.
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/kv"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/execution"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
consensusblocks "github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
||||
@@ -61,7 +62,11 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkcho
|
||||
return nil, nil
|
||||
}
|
||||
finalizedHash := s.cfg.ForkChoiceStore.FinalizedPayloadBlockHash()
|
||||
justifiedHash := s.cfg.ForkChoiceStore.JustifiedPayloadBlockHash()
|
||||
justifiedHash, err := s.cfg.ForkChoiceStore.UnrealizedJustifiedPayloadBlockHash()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get unrealized justified payload block hash")
|
||||
justifiedHash = finalizedHash
|
||||
}
|
||||
fcs := &enginev1.ForkchoiceState{
|
||||
HeadBlockHash: headPayload.BlockHash(),
|
||||
SafeBlockHash: justifiedHash[:],
|
||||
@@ -254,7 +259,7 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
|
||||
emptyAttri := payloadattribute.EmptyWithVersion(st.Version())
|
||||
// Root is `[32]byte{}` since we are retrieving proposer ID of a given slot. During insertion at assignment the root was not known.
|
||||
proposerID, _, ok := s.cfg.ProposerSlotIndexCache.GetProposerPayloadIDs(slot, [32]byte{} /* root */)
|
||||
if !ok { // There's no need to build attribute if there is no proposer for slot.
|
||||
if !ok && !features.Get().PrepareAllPayloads { // There's no need to build attribute if there is no proposer for slot.
|
||||
return false, emptyAttri, 0
|
||||
}
|
||||
|
||||
@@ -301,7 +306,7 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
|
||||
|
||||
var attr payloadattribute.Attributer
|
||||
switch st.Version() {
|
||||
case version.Capella, version.Deneb:
|
||||
case version.Capella:
|
||||
withdrawals, err := st.ExpectedWithdrawals()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get expected withdrawals to get payload attribute")
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
bstate "github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
consensusblocks "github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
@@ -824,6 +825,31 @@ func Test_GetPayloadAttribute(t *testing.T) {
|
||||
require.Equal(t, suggestedAddr, common.BytesToAddress(attr.SuggestedFeeRecipient()))
|
||||
}
|
||||
|
||||
func Test_GetPayloadAttribute_PrepareAllPayloads(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
resetCfg := features.InitWithReset(&features.Flags{
|
||||
PrepareAllPayloads: true,
|
||||
})
|
||||
defer resetCfg()
|
||||
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
opts := []Option{
|
||||
WithDatabase(beaconDB),
|
||||
WithStateGen(stategen.New(beaconDB, doublylinkedtree.New())),
|
||||
WithProposerIdsCache(cache.NewProposerPayloadIDsCache()),
|
||||
}
|
||||
|
||||
hook := logTest.NewGlobal()
|
||||
service, err := NewService(ctx, opts...)
|
||||
require.NoError(t, err)
|
||||
st, _ := util.DeterministicGenesisStateBellatrix(t, 1)
|
||||
hasPayload, attr, vId := service.getPayloadAttribute(ctx, st, 0)
|
||||
require.Equal(t, true, hasPayload)
|
||||
require.Equal(t, primitives.ValidatorIndex(0), vId)
|
||||
require.Equal(t, params.BeaconConfig().EthBurnAddressHex, common.BytesToAddress(attr.SuggestedFeeRecipient()).String())
|
||||
require.LogsContain(t, hook, "Fee recipient is currently using the burn address")
|
||||
}
|
||||
|
||||
func Test_GetPayloadAttributeV2(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
|
||||
func (s *Service) isNewProposer(slot primitives.Slot) bool {
|
||||
_, _, ok := s.cfg.ProposerSlotIndexCache.GetProposerPayloadIDs(slot, [32]byte{} /* root */)
|
||||
return ok
|
||||
return ok || features.Get().PrepareAllPayloads
|
||||
}
|
||||
|
||||
func (s *Service) isNewHead(r [32]byte) bool {
|
||||
|
||||
@@ -54,7 +54,7 @@ type head struct {
|
||||
|
||||
// This saves head info to the local service cache, it also saves the
|
||||
// new head root to the DB.
|
||||
// Caller of the method MUST aqcuire a lock on forkchoice.
|
||||
// Caller of the method MUST acquire a lock on forkchoice.
|
||||
func (s *Service) saveHead(ctx context.Context, newHeadRoot [32]byte, headBlock interfaces.ReadOnlySignedBeaconBlock, headState state.BeaconState) error {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.saveHead")
|
||||
defer span.End()
|
||||
@@ -89,13 +89,13 @@ func (s *Service) saveHead(ctx context.Context, newHeadRoot [32]byte, headBlock
|
||||
newHeadSlot := headBlock.Block().Slot()
|
||||
newStateRoot := headBlock.Block().StateRoot()
|
||||
|
||||
// A chain re-org occurred, so we fire an event notifying the rest of the services.
|
||||
r, err := s.HeadRoot(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get old head root")
|
||||
}
|
||||
oldHeadRoot := bytesutil.ToBytes32(r)
|
||||
if headBlock.Block().ParentRoot() != oldHeadRoot {
|
||||
// A chain re-org occurred, so we fire an event notifying the rest of the services.
|
||||
commonRoot, forkSlot, err := s.cfg.ForkChoiceStore.CommonAncestor(ctx, oldHeadRoot, newHeadRoot)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not find common ancestor root")
|
||||
@@ -403,6 +403,19 @@ func (s *Service) saveOrphanedOperations(ctx context.Context, orphanedRoot [32]b
|
||||
}
|
||||
saveOrphanedAttCount.Inc()
|
||||
}
|
||||
for _, as := range orphanedBlk.Block().Body().AttesterSlashings() {
|
||||
if err := s.cfg.SlashingPool.InsertAttesterSlashing(ctx, s.headStateReadOnly(ctx), as); err != nil {
|
||||
log.WithError(err).Error("Could not insert reorg attester slashing")
|
||||
}
|
||||
}
|
||||
for _, vs := range orphanedBlk.Block().Body().ProposerSlashings() {
|
||||
if err := s.cfg.SlashingPool.InsertProposerSlashing(ctx, s.headStateReadOnly(ctx), vs); err != nil {
|
||||
log.WithError(err).Error("Could not insert reorg proposer slashing")
|
||||
}
|
||||
}
|
||||
for _, v := range orphanedBlk.Block().Body().VoluntaryExits() {
|
||||
s.cfg.ExitPool.InsertVoluntaryExit(v)
|
||||
}
|
||||
if orphanedBlk.Version() >= version.Capella {
|
||||
changes, err := orphanedBlk.Block().Body().BLSToExecutionChanges()
|
||||
if err != nil {
|
||||
|
||||
@@ -326,6 +326,88 @@ func TestSaveOrphanedAtts(t *testing.T) {
|
||||
require.DeepEqual(t, wantAtts, atts)
|
||||
}
|
||||
|
||||
func TestSaveOrphanedOps(t *testing.T) {
|
||||
params.SetupTestConfigCleanup(t)
|
||||
config := params.BeaconConfig()
|
||||
config.ShardCommitteePeriod = 0
|
||||
params.OverrideBeaconConfig(config)
|
||||
|
||||
ctx := context.Background()
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
service := setupBeaconChain(t, beaconDB)
|
||||
service.genesisTime = time.Now().Add(time.Duration(-10*int64(1)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
||||
|
||||
// Chain setup
|
||||
// 0 -- 1 -- 2 -- 3
|
||||
// \-4
|
||||
st, keys := util.DeterministicGenesisState(t, 64)
|
||||
service.head = &head{state: st}
|
||||
blkG, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 0)
|
||||
assert.NoError(t, err)
|
||||
|
||||
util.SaveBlock(t, ctx, service.cfg.BeaconDB, blkG)
|
||||
rG, err := blkG.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
blk1, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 1)
|
||||
assert.NoError(t, err)
|
||||
blk1.Block.ParentRoot = rG[:]
|
||||
r1, err := blk1.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
blk2, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 2)
|
||||
assert.NoError(t, err)
|
||||
blk2.Block.ParentRoot = r1[:]
|
||||
r2, err := blk2.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
blkConfig := util.DefaultBlockGenConfig()
|
||||
blkConfig.NumBLSChanges = 5
|
||||
blkConfig.NumProposerSlashings = 1
|
||||
blkConfig.NumAttesterSlashings = 1
|
||||
blkConfig.NumVoluntaryExits = 1
|
||||
blk3, err := util.GenerateFullBlock(st, keys, blkConfig, 3)
|
||||
assert.NoError(t, err)
|
||||
blk3.Block.ParentRoot = r2[:]
|
||||
r3, err := blk3.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
blk4 := util.NewBeaconBlock()
|
||||
blk4.Block.Slot = 4
|
||||
blk4.Block.ParentRoot = rG[:]
|
||||
r4, err := blk4.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
ojc := ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
ofc := ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
|
||||
for _, blk := range []*ethpb.SignedBeaconBlock{blkG, blk1, blk2, blk3, blk4} {
|
||||
r, err := blk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, blk.Block.Slot, r, bytesutil.ToBytes32(blk.Block.ParentRoot), [32]byte{}, ojc, ofc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
|
||||
util.SaveBlock(t, ctx, beaconDB, blk)
|
||||
}
|
||||
|
||||
require.NoError(t, service.saveOrphanedOperations(ctx, r3, r4))
|
||||
require.Equal(t, 3, service.cfg.AttPool.AggregatedAttestationCount())
|
||||
wantAtts := []*ethpb.Attestation{
|
||||
blk3.Block.Body.Attestations[0],
|
||||
blk2.Block.Body.Attestations[0],
|
||||
blk1.Block.Body.Attestations[0],
|
||||
}
|
||||
atts := service.cfg.AttPool.AggregatedAttestations()
|
||||
sort.Slice(atts, func(i, j int) bool {
|
||||
return atts[i].Data.Slot > atts[j].Data.Slot
|
||||
})
|
||||
require.DeepEqual(t, wantAtts, atts)
|
||||
require.Equal(t, 1, len(service.cfg.SlashingPool.PendingProposerSlashings(ctx, st, false)))
|
||||
require.Equal(t, 1, len(service.cfg.SlashingPool.PendingAttesterSlashings(ctx, st, false)))
|
||||
exits, err := service.cfg.ExitPool.PendingExits()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(exits))
|
||||
}
|
||||
|
||||
func TestSaveOrphanedAtts_CanFilter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
|
||||
@@ -60,13 +60,7 @@ func logStateTransitionData(b interfaces.ReadOnlyBeaconBlock) error {
|
||||
log = log.WithField("txCount", len(txs))
|
||||
txsPerSlotCount.Set(float64(len(txs)))
|
||||
}
|
||||
}
|
||||
if b.Version() >= version.Deneb {
|
||||
k, err := b.Body().BlobKzgCommitments()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log = log.WithField("blobCount", len(k))
|
||||
|
||||
}
|
||||
log.Info("Finished applying state transition")
|
||||
return nil
|
||||
@@ -102,7 +96,6 @@ func logBlockSyncStatus(block interfaces.ReadOnlyBeaconBlock, blockRoot [32]byte
|
||||
"finalizedEpoch": finalized.Epoch,
|
||||
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
|
||||
"epoch": slots.ToEpoch(block.Slot()),
|
||||
"version": version.String(block.Version()),
|
||||
}).Info("Synced new block")
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -671,9 +671,7 @@ func (s *Service) fillMissingPayloadIDRoutine(ctx context.Context, stateFeed *ev
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C():
|
||||
if err := s.fillMissingBlockPayloadId(ctx); err != nil {
|
||||
log.WithError(err).Error("Could not fill missing payload ID")
|
||||
}
|
||||
s.lateBlockTasks(ctx)
|
||||
|
||||
case <-ctx.Done():
|
||||
log.Debug("Context closed, exiting routine")
|
||||
@@ -683,11 +681,13 @@ func (s *Service) fillMissingPayloadIDRoutine(ctx context.Context, stateFeed *ev
|
||||
}()
|
||||
}
|
||||
|
||||
// fillMissingBlockPayloadId is called 4 seconds into the slot and calls FCU if we are proposing next slot
|
||||
// and the cache has been missed
|
||||
func (s *Service) fillMissingBlockPayloadId(ctx context.Context) error {
|
||||
// lateBlockTasks is called 4 seconds into the slot and performs tasks
|
||||
// related to late blocks. It emits a MissedSlot state feed event.
|
||||
// It calls FCU and sets the right attributes if we are proposing next slot
|
||||
// it also updates the next slot cache to deal with skipped slots.
|
||||
func (s *Service) lateBlockTasks(ctx context.Context) {
|
||||
if s.CurrentSlot() == s.HeadSlot() {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.MissedSlot,
|
||||
@@ -696,22 +696,32 @@ func (s *Service) fillMissingBlockPayloadId(ctx context.Context) error {
|
||||
// Head root should be empty when retrieving proposer index for the next slot.
|
||||
_, id, has := s.cfg.ProposerSlotIndexCache.GetProposerPayloadIDs(s.CurrentSlot()+1, [32]byte{} /* head root */)
|
||||
// There exists proposer for next slot, but we haven't called fcu w/ payload attribute yet.
|
||||
if !has || id != [8]byte{} {
|
||||
return nil
|
||||
if (!has && !features.Get().PrepareAllPayloads) || id != [8]byte{} {
|
||||
return
|
||||
}
|
||||
s.headLock.RLock()
|
||||
headBlock, err := s.headBlock()
|
||||
if err != nil {
|
||||
s.headLock.RUnlock()
|
||||
return err
|
||||
log.WithError(err).Debug("could not perform late block tasks: failed to retrieve head block")
|
||||
return
|
||||
}
|
||||
headState := s.headState(ctx)
|
||||
headRoot := s.headRoot()
|
||||
headState := s.headState(ctx)
|
||||
s.headLock.RUnlock()
|
||||
_, err = s.notifyForkchoiceUpdate(ctx, ¬ifyForkchoiceUpdateArg{
|
||||
headState: headState,
|
||||
headRoot: headRoot,
|
||||
headBlock: headBlock.Block(),
|
||||
})
|
||||
return err
|
||||
if err != nil {
|
||||
log.WithError(err).Debug("could not perform late block tasks: failed to update forkchoice with engine")
|
||||
}
|
||||
lastRoot, lastState := transition.LastCachedState()
|
||||
if lastState == nil {
|
||||
lastRoot, lastState = headRoot[:], headState
|
||||
}
|
||||
if err = transition.UpdateNextSlotCache(ctx, lastRoot, lastState); err != nil {
|
||||
log.WithError(err).Debug("could not update next slot state cache")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/attestations"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
consensusblocks "github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
@@ -2153,6 +2154,7 @@ func TestOnBlock_HandleBlockAttestations(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFillMissingBlockPayloadId_DiffSlotExitEarly(t *testing.T) {
|
||||
logHook := logTest.NewGlobal()
|
||||
fc := doublylinkedtree.New()
|
||||
ctx := context.Background()
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
@@ -2164,7 +2166,30 @@ func TestFillMissingBlockPayloadId_DiffSlotExitEarly(t *testing.T) {
|
||||
|
||||
service, err := NewService(ctx, opts...)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.fillMissingBlockPayloadId(ctx), 0)
|
||||
service.lateBlockTasks(ctx)
|
||||
require.LogsDoNotContain(t, logHook, "could not perform late block tasks")
|
||||
}
|
||||
|
||||
func TestFillMissingBlockPayloadId_PrepareAllPayloads(t *testing.T) {
|
||||
logHook := logTest.NewGlobal()
|
||||
resetCfg := features.InitWithReset(&features.Flags{
|
||||
PrepareAllPayloads: true,
|
||||
})
|
||||
defer resetCfg()
|
||||
|
||||
fc := doublylinkedtree.New()
|
||||
ctx := context.Background()
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
|
||||
opts := []Option{
|
||||
WithForkChoiceStore(fc),
|
||||
WithStateGen(stategen.New(beaconDB, fc)),
|
||||
}
|
||||
|
||||
service, err := NewService(ctx, opts...)
|
||||
require.NoError(t, err)
|
||||
service.lateBlockTasks(ctx)
|
||||
require.LogsDoNotContain(t, logHook, "could not perform late block tasks")
|
||||
}
|
||||
|
||||
// Helper function to simulate the block being on time or delayed for proposer
|
||||
|
||||
@@ -133,6 +133,10 @@ func (s *Service) UpdateHead(ctx context.Context, proposingSlot primitives.Slot)
|
||||
newHeadRoot, err := s.cfg.ForkChoiceStore.Head(ctx)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not compute head from new attestations")
|
||||
// Fallback to our current head root in the event of a failure.
|
||||
s.headLock.RLock()
|
||||
newHeadRoot = s.headRoot()
|
||||
s.headLock.RUnlock()
|
||||
}
|
||||
newAttHeadElapsedTime.Observe(float64(time.Since(start).Milliseconds()))
|
||||
|
||||
|
||||
@@ -179,10 +179,14 @@ func (s *Service) prunePostBlockOperationPools(ctx context.Context, blk interfac
|
||||
return errors.Wrap(err, "could not process BLSToExecutionChanges")
|
||||
}
|
||||
|
||||
// Mark attester slashings as seen so we don't include same ones in future blocks.
|
||||
// Mark slashings as seen so we don't include same ones in future blocks.
|
||||
for _, as := range blk.Block().Body().AttesterSlashings() {
|
||||
s.cfg.SlashingPool.MarkIncludedAttesterSlashing(as)
|
||||
}
|
||||
for _, ps := range blk.Block().Body().ProposerSlashings() {
|
||||
s.cfg.SlashingPool.MarkIncludedProposerSlashing(ps)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import (
|
||||
mockExecution "github.com/prysmaticlabs/prysm/v4/beacon-chain/execution/testing"
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/attestations"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/slashings"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/voluntaryexits"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
|
||||
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
@@ -57,11 +59,6 @@ type mockBroadcaster struct {
|
||||
broadcastCalled bool
|
||||
}
|
||||
|
||||
func (mb *mockBroadcaster) BroadcastBlob(ctx context.Context, subnet uint64, blobSidecar *ethpb.SignedBlobSidecar) error {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (mb *mockBroadcaster) Broadcast(_ context.Context, _ proto.Message) error {
|
||||
mb.broadcastCalled = true
|
||||
return nil
|
||||
@@ -136,6 +133,8 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
|
||||
WithDepositCache(depositCache),
|
||||
WithChainStartFetcher(web3Service),
|
||||
WithAttestationPool(attestations.NewPool()),
|
||||
WithSlashingPool(slashings.NewPool()),
|
||||
WithExitPool(voluntaryexits.NewPool()),
|
||||
WithP2PBroadcaster(&mockBroadcaster{}),
|
||||
WithStateNotifier(&mockBeaconNode{}),
|
||||
WithForkChoiceStore(fc),
|
||||
|
||||
@@ -587,3 +587,13 @@ func (s *ChainService) ProposerBoost() [32]byte {
|
||||
}
|
||||
return [32]byte{}
|
||||
}
|
||||
|
||||
// FinalizedBlockHash mocks the same method in the chain service
|
||||
func (s *ChainService) FinalizedBlockHash() [32]byte {
|
||||
return [32]byte{}
|
||||
}
|
||||
|
||||
// UnrealizedJustifiedPayloadBlockHash mocks the same method in the chain service
|
||||
func (s *ChainService) UnrealizedJustifiedPayloadBlockHash() ([32]byte, error) {
|
||||
return [32]byte{}, nil
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@ func (s *Service) Start() {
|
||||
}
|
||||
|
||||
// Stop halts the service.
|
||||
func (*Service) Stop() error {
|
||||
func (s *Service) Stop() error {
|
||||
s.cancel()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -89,6 +90,9 @@ func (s *Service) SubmitBlindedBlock(ctx context.Context, b interfaces.ReadOnlyS
|
||||
defer func() {
|
||||
submitBlindedBlockLatency.Observe(float64(time.Since(start).Milliseconds()))
|
||||
}()
|
||||
if s.c == nil {
|
||||
return nil, ErrNoBuilder
|
||||
}
|
||||
|
||||
return s.c.SubmitBlindedBlock(ctx, b)
|
||||
}
|
||||
@@ -101,6 +105,9 @@ func (s *Service) GetHeader(ctx context.Context, slot primitives.Slot, parentHas
|
||||
defer func() {
|
||||
getHeaderLatency.Observe(float64(time.Since(start).Milliseconds()))
|
||||
}()
|
||||
if s.c == nil {
|
||||
return nil, ErrNoBuilder
|
||||
}
|
||||
|
||||
return s.c.GetHeader(ctx, slot, parentHash, pubKey)
|
||||
}
|
||||
@@ -124,6 +131,9 @@ func (s *Service) RegisterValidator(ctx context.Context, reg []*ethpb.SignedVali
|
||||
defer func() {
|
||||
registerValidatorLatency.Observe(float64(time.Since(start).Milliseconds()))
|
||||
}()
|
||||
if s.c == nil {
|
||||
return ErrNoBuilder
|
||||
}
|
||||
|
||||
idxs := make([]primitives.ValidatorIndex, 0)
|
||||
msgs := make([]*ethpb.ValidatorRegistrationV1, 0)
|
||||
|
||||
@@ -37,3 +37,18 @@ func Test_RegisterValidator(t *testing.T) {
|
||||
require.NoError(t, s.RegisterValidator(ctx, []*eth.SignedValidatorRegistrationV1{{Message: ð.ValidatorRegistrationV1{Pubkey: pubkey[:], FeeRecipient: feeRecipient[:]}}}))
|
||||
assert.Equal(t, true, builder.RegisteredVals[pubkey])
|
||||
}
|
||||
|
||||
func Test_BuilderMethodsWithouClient(t *testing.T) {
|
||||
s, err := NewService(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, s.Configured())
|
||||
|
||||
_, err = s.GetHeader(context.Background(), 0, [32]byte{}, [48]byte{})
|
||||
assert.ErrorContains(t, ErrNoBuilder.Error(), err)
|
||||
|
||||
_, err = s.SubmitBlindedBlock(context.Background(), nil)
|
||||
assert.ErrorContains(t, ErrNoBuilder.Error(), err)
|
||||
|
||||
err = s.RegisterValidator(context.Background(), nil)
|
||||
assert.ErrorContains(t, ErrNoBuilder.Error(), err)
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ func AttestationsDelta(beaconState state.BeaconState, bal *precompute.Balance, v
|
||||
finalizedEpoch := beaconState.FinalizedCheckpointEpoch()
|
||||
increment := cfg.EffectiveBalanceIncrement
|
||||
factor := cfg.BaseRewardFactor
|
||||
baseRewardMultiplier := increment * factor / math.IntegerSquareRoot(bal.ActiveCurrentEpoch)
|
||||
baseRewardMultiplier := increment * factor / math.CachedSquareRoot(bal.ActiveCurrentEpoch)
|
||||
leak := helpers.IsInInactivityLeak(prevEpoch, finalizedEpoch)
|
||||
|
||||
// Modified in Altair and Bellatrix.
|
||||
|
||||
@@ -58,5 +58,5 @@ func BaseRewardPerIncrement(activeBalance uint64) (uint64, error) {
|
||||
return 0, errors.New("active balance can't be 0")
|
||||
}
|
||||
cfg := params.BeaconConfig()
|
||||
return cfg.EffectiveBalanceIncrement * cfg.BaseRewardFactor / math.IntegerSquareRoot(activeBalance), nil
|
||||
return cfg.EffectiveBalanceIncrement * cfg.BaseRewardFactor / math.CachedSquareRoot(activeBalance), nil
|
||||
}
|
||||
|
||||
@@ -9,110 +9,6 @@ import (
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// UpgradeToDeneb updates inputs a generic state to return the version Deneb state.
|
||||
func UpgradeToDeneb(state state.BeaconState) (state.BeaconState, error) {
|
||||
epoch := time.CurrentEpoch(state)
|
||||
|
||||
currentSyncCommittee, err := state.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nextSyncCommittee, err := state.NextSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prevEpochParticipation, err := state.PreviousEpochParticipation()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentEpochParticipation, err := state.CurrentEpochParticipation()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inactivityScores, err := state.InactivityScores()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
payloadHeader, err := state.LatestExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
txRoot, err := payloadHeader.TransactionsRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wdRoot, err := payloadHeader.WithdrawalsRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wi, err := state.NextWithdrawalIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vi, err := state.NextWithdrawalValidatorIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
summarires, err := state.HistoricalSummaries()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := ðpb.BeaconStateDeneb{
|
||||
GenesisTime: state.GenesisTime(),
|
||||
GenesisValidatorsRoot: state.GenesisValidatorsRoot(),
|
||||
Slot: state.Slot(),
|
||||
Fork: ðpb.Fork{
|
||||
PreviousVersion: state.Fork().CurrentVersion,
|
||||
CurrentVersion: params.BeaconConfig().DenebForkVersion,
|
||||
Epoch: epoch,
|
||||
},
|
||||
LatestBlockHeader: state.LatestBlockHeader(),
|
||||
BlockRoots: state.BlockRoots(),
|
||||
StateRoots: state.StateRoots(),
|
||||
HistoricalRoots: [][]byte{},
|
||||
Eth1Data: state.Eth1Data(),
|
||||
Eth1DataVotes: state.Eth1DataVotes(),
|
||||
Eth1DepositIndex: state.Eth1DepositIndex(),
|
||||
Validators: state.Validators(),
|
||||
Balances: state.Balances(),
|
||||
RandaoMixes: state.RandaoMixes(),
|
||||
Slashings: state.Slashings(),
|
||||
PreviousEpochParticipation: prevEpochParticipation,
|
||||
CurrentEpochParticipation: currentEpochParticipation,
|
||||
JustificationBits: state.JustificationBits(),
|
||||
PreviousJustifiedCheckpoint: state.PreviousJustifiedCheckpoint(),
|
||||
CurrentJustifiedCheckpoint: state.CurrentJustifiedCheckpoint(),
|
||||
FinalizedCheckpoint: state.FinalizedCheckpoint(),
|
||||
InactivityScores: inactivityScores,
|
||||
CurrentSyncCommittee: currentSyncCommittee,
|
||||
NextSyncCommittee: nextSyncCommittee,
|
||||
LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderDeneb{
|
||||
ParentHash: payloadHeader.ParentHash(),
|
||||
FeeRecipient: payloadHeader.FeeRecipient(),
|
||||
StateRoot: payloadHeader.StateRoot(),
|
||||
ReceiptsRoot: payloadHeader.ReceiptsRoot(),
|
||||
LogsBloom: payloadHeader.LogsBloom(),
|
||||
PrevRandao: payloadHeader.PrevRandao(),
|
||||
BlockNumber: payloadHeader.BlockNumber(),
|
||||
GasLimit: payloadHeader.GasLimit(),
|
||||
GasUsed: payloadHeader.GasUsed(),
|
||||
Timestamp: payloadHeader.Timestamp(),
|
||||
ExtraData: payloadHeader.ExtraData(),
|
||||
BaseFeePerGas: payloadHeader.BaseFeePerGas(),
|
||||
BlockHash: payloadHeader.BlockHash(),
|
||||
ExcessDataGas: make([]byte, 32),
|
||||
TransactionsRoot: txRoot,
|
||||
WithdrawalsRoot: wdRoot,
|
||||
},
|
||||
NextWithdrawalIndex: wi,
|
||||
NextWithdrawalValidatorIndex: vi,
|
||||
HistoricalSummaries: summarires,
|
||||
}
|
||||
|
||||
return state_native.InitializeFromProtoUnsafeDeneb(s)
|
||||
}
|
||||
|
||||
// UpgradeToCapella updates a generic state to return the version Capella state.
|
||||
func UpgradeToCapella(state state.BeaconState) (state.BeaconState, error) {
|
||||
epoch := time.CurrentEpoch(state)
|
||||
|
||||
@@ -353,7 +353,7 @@ func ProcessRandaoMixesReset(state state.BeaconState) (state.BeaconState, error)
|
||||
}
|
||||
|
||||
// ProcessHistoricalDataUpdate processes the updates to historical data during epoch processing.
|
||||
// From Capella onward, per spec, state's historical summaries are updated instead of historical roots.
|
||||
// From Capella onward, per spec,state's historical summaries are updated instead of historical roots.
|
||||
func ProcessHistoricalDataUpdate(state state.BeaconState) (state.BeaconState, error) {
|
||||
currentEpoch := time.CurrentEpoch(state)
|
||||
nextEpoch := currentEpoch + 1
|
||||
|
||||
@@ -72,7 +72,7 @@ func AttestationsDelta(state state.ReadOnlyBeaconState, pBal *Balance, vp []*Val
|
||||
prevEpoch := time.PrevEpoch(state)
|
||||
finalizedEpoch := state.FinalizedCheckpointEpoch()
|
||||
|
||||
sqrtActiveCurrentEpoch := math.IntegerSquareRoot(pBal.ActiveCurrentEpoch)
|
||||
sqrtActiveCurrentEpoch := math.CachedSquareRoot(pBal.ActiveCurrentEpoch)
|
||||
for i, v := range vp {
|
||||
rewards[i], penalties[i] = attestationDelta(pBal, sqrtActiveCurrentEpoch, v, prevEpoch, finalizedEpoch)
|
||||
}
|
||||
@@ -161,7 +161,7 @@ func ProposersDelta(state state.ReadOnlyBeaconState, pBal *Balance, vp []*Valida
|
||||
rewards := make([]uint64, numofVals)
|
||||
|
||||
totalBalance := pBal.ActiveCurrentEpoch
|
||||
balanceSqrt := math.IntegerSquareRoot(totalBalance)
|
||||
balanceSqrt := math.CachedSquareRoot(totalBalance)
|
||||
// Balance square root cannot be 0, this prevents division by 0.
|
||||
if balanceSqrt == 0 {
|
||||
balanceSqrt = 1
|
||||
|
||||
@@ -19,8 +19,7 @@ const (
|
||||
Initialized
|
||||
// Synced is sent when the beacon node has completed syncing and is ready to participate in the network.
|
||||
Synced
|
||||
// Reorg is an event sent when the new head state's slot after a block
|
||||
// transition is lower than its previous head state slot value.
|
||||
// Reorg is an event sent when the new head is not a descendant of the previous head.
|
||||
Reorg
|
||||
// FinalizedCheckpoint event.
|
||||
FinalizedCheckpoint
|
||||
|
||||
@@ -81,15 +81,6 @@ func CanUpgradeToCapella(slot primitives.Slot) bool {
|
||||
return epochStart && capellaEpoch
|
||||
}
|
||||
|
||||
// CanUpgradeToDeneb returns true if the input `slot` can upgrade to Deneb.
|
||||
// Spec code:
|
||||
// If state.slot % SLOTS_PER_EPOCH == 0 and compute_epoch_at_slot(state.slot) == DENEB_FORK_EPOCH
|
||||
func CanUpgradeToDeneb(slot primitives.Slot) bool {
|
||||
epochStart := slots.IsEpochStart(slot)
|
||||
DenebEpoch := slots.ToEpoch(slot) == params.BeaconConfig().DenebForkEpoch
|
||||
return epochStart && DenebEpoch
|
||||
}
|
||||
|
||||
// CanProcessEpoch checks the eligibility to process epoch.
|
||||
// The epoch can be processed at the end of the last slot of every epoch.
|
||||
//
|
||||
|
||||
@@ -23,6 +23,7 @@ go_library(
|
||||
"//beacon-chain/core/execution:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/time:go_default_library",
|
||||
"//beacon-chain/core/transition/interop:go_default_library",
|
||||
"//beacon-chain/core/validators:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
@@ -45,7 +46,6 @@ go_library(
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_protolambda_go_kzg//eth:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
],
|
||||
|
||||
@@ -5,15 +5,20 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
types "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
)
|
||||
|
||||
type nextSlotCache struct {
|
||||
sync.RWMutex
|
||||
root []byte
|
||||
state state.BeaconState
|
||||
sync.Mutex
|
||||
prevRoot []byte
|
||||
lastRoot []byte
|
||||
prevState state.BeaconState
|
||||
lastState state.BeaconState
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -29,19 +34,22 @@ var (
|
||||
})
|
||||
)
|
||||
|
||||
// NextSlotState returns the saved state if the input root matches the root in `nextSlotCache`. Returns nil otherwise.
|
||||
// This is useful to check before processing slots. With a cache hit, it will return last processed state with slot plus
|
||||
// one advancement.
|
||||
func NextSlotState(_ context.Context, root []byte) (state.BeaconState, error) {
|
||||
nsc.RLock()
|
||||
defer nsc.RUnlock()
|
||||
if !bytes.Equal(root, nsc.root) || bytes.Equal(root, []byte{}) {
|
||||
nextSlotCacheMiss.Inc()
|
||||
return nil, nil
|
||||
// NextSlotState returns the saved state for the given blockroot.
|
||||
// It returns the last updated state if it matches. Otherwise it returns the previously
|
||||
// updated state if it matches its root. If no root matches it returns nil
|
||||
func NextSlotState(root []byte, wantedSlot types.Slot) state.BeaconState {
|
||||
nsc.Lock()
|
||||
defer nsc.Unlock()
|
||||
if bytes.Equal(root, nsc.lastRoot) && nsc.lastState.Slot() <= wantedSlot {
|
||||
nextSlotCacheHit.Inc()
|
||||
return nsc.lastState.Copy()
|
||||
}
|
||||
nextSlotCacheHit.Inc()
|
||||
// Returning copied state.
|
||||
return nsc.state.Copy(), nil
|
||||
if bytes.Equal(root, nsc.prevRoot) && nsc.prevState.Slot() <= wantedSlot {
|
||||
nextSlotCacheHit.Inc()
|
||||
return nsc.prevState.Copy()
|
||||
}
|
||||
nextSlotCacheMiss.Inc()
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateNextSlotCache updates the `nextSlotCache`. It saves the input state after advancing the state slot by 1
|
||||
@@ -52,13 +60,25 @@ func UpdateNextSlotCache(ctx context.Context, root []byte, state state.BeaconSta
|
||||
copied := state.Copy()
|
||||
copied, err := ProcessSlots(ctx, copied, copied.Slot()+1)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "could not process slots")
|
||||
}
|
||||
|
||||
nsc.Lock()
|
||||
defer nsc.Unlock()
|
||||
|
||||
nsc.root = root
|
||||
nsc.state = copied
|
||||
nsc.prevRoot = nsc.lastRoot
|
||||
nsc.prevState = nsc.lastState
|
||||
nsc.lastRoot = bytesutil.SafeCopyBytes(root)
|
||||
nsc.lastState = copied
|
||||
return nil
|
||||
}
|
||||
|
||||
// LastCachedState returns the last cached state and root in the cache
|
||||
func LastCachedState() ([]byte, state.BeaconState) {
|
||||
nsc.Lock()
|
||||
defer nsc.Unlock()
|
||||
if nsc.lastState == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return bytesutil.SafeCopyBytes(nsc.lastRoot), nsc.lastState.Copy()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
||||
)
|
||||
@@ -13,18 +14,36 @@ import (
|
||||
func TestTrailingSlotState_RoundTrip(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r := []byte{'a'}
|
||||
s, err := transition.NextSlotState(ctx, r)
|
||||
require.NoError(t, err)
|
||||
s := transition.NextSlotState(r, 0)
|
||||
require.Equal(t, nil, s)
|
||||
|
||||
s, _ = util.DeterministicGenesisState(t, 1)
|
||||
require.NoError(t, transition.UpdateNextSlotCache(ctx, r, s))
|
||||
s, err = transition.NextSlotState(ctx, r)
|
||||
require.NoError(t, err)
|
||||
s = transition.NextSlotState(r, 1)
|
||||
require.Equal(t, primitives.Slot(1), s.Slot())
|
||||
|
||||
lastRoot, lastState := transition.LastCachedState()
|
||||
require.DeepEqual(t, r, lastRoot)
|
||||
require.Equal(t, s.Slot(), lastState.Slot())
|
||||
|
||||
require.NoError(t, transition.UpdateNextSlotCache(ctx, r, s))
|
||||
s, err = transition.NextSlotState(ctx, r)
|
||||
require.NoError(t, err)
|
||||
s = transition.NextSlotState(r, 2)
|
||||
require.Equal(t, primitives.Slot(2), s.Slot())
|
||||
|
||||
lastRoot, lastState = transition.LastCachedState()
|
||||
require.DeepEqual(t, r, lastRoot)
|
||||
require.Equal(t, s.Slot(), lastState.Slot())
|
||||
}
|
||||
|
||||
func TestTrailingSlotState_StateAdvancedBeyondRequest(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r := []byte{'a'}
|
||||
s := transition.NextSlotState(r, 0)
|
||||
require.Equal(t, nil, s)
|
||||
|
||||
s, _ = util.DeterministicGenesisState(t, 1)
|
||||
assert.NoError(t, s.SetSlot(2))
|
||||
require.NoError(t, transition.UpdateNextSlotCache(ctx, r, s))
|
||||
s = transition.NextSlotState(r, 1)
|
||||
require.Equal(t, nil, s)
|
||||
}
|
||||
|
||||
@@ -147,25 +147,15 @@ func ProcessSlotsUsingNextSlotCache(
|
||||
ctx, span := trace.StartSpan(ctx, "core.state.ProcessSlotsUsingNextSlotCache")
|
||||
defer span.End()
|
||||
|
||||
// Check whether the parent state has been advanced by 1 slot in next slot cache.
|
||||
nextSlotState, err := NextSlotState(ctx, parentRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cachedStateExists := nextSlotState != nil && !nextSlotState.IsNil()
|
||||
// If the next slot state is not nil (i.e. cache hit).
|
||||
// We replace next slot state with parent state.
|
||||
if cachedStateExists {
|
||||
nextSlotState := NextSlotState(parentRoot, slot)
|
||||
if nextSlotState != nil {
|
||||
parentState = nextSlotState
|
||||
}
|
||||
|
||||
// In the event our cached state has advanced our
|
||||
// state to the desired slot, we exit early.
|
||||
if cachedStateExists && parentState.Slot() == slot {
|
||||
if parentState.Slot() == slot {
|
||||
return parentState, nil
|
||||
}
|
||||
// Since next slot cache only advances state by 1 slot,
|
||||
// we check if there's more slots that need to process.
|
||||
|
||||
var err error
|
||||
parentState, err = ProcessSlots(ctx, parentState, slot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not process slots")
|
||||
@@ -302,14 +292,6 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot primitives.
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if time.CanUpgradeToDeneb(state.Slot()) {
|
||||
state, err = capella.UpgradeToDeneb(state)
|
||||
if err != nil {
|
||||
tracing.AnnotateError(span, err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if highestSlot < state.Slot() {
|
||||
|
||||
@@ -6,18 +6,16 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/protolambda/go-kzg/eth"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/altair"
|
||||
b "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition/interop"
|
||||
v "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/validators"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/monitoring/tracing"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
@@ -59,6 +57,9 @@ func ExecuteStateTransitionNoVerifyAnySig(
|
||||
defer span.End()
|
||||
var err error
|
||||
|
||||
interop.WriteBlockToDisk(signed, false /* Has the block failed */)
|
||||
interop.WriteStateToDisk(st)
|
||||
|
||||
parentRoot := signed.Block().ParentRoot()
|
||||
st, err = ProcessSlotsUsingNextSlotCache(ctx, st, parentRoot[:], signed.Block().Slot())
|
||||
if err != nil {
|
||||
@@ -255,7 +256,7 @@ func ProcessOperationsNoVerifyAttsSigs(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case version.Altair, version.Bellatrix, version.Capella, version.Deneb:
|
||||
case version.Altair, version.Bellatrix, version.Capella:
|
||||
state, err = altairOperations(ctx, state, signedBeaconBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -355,48 +356,9 @@ func ProcessBlockForStateRoot(
|
||||
return nil, errors.Wrap(err, "process_sync_aggregate failed")
|
||||
}
|
||||
|
||||
if signed.Block().Version() == version.Deneb {
|
||||
err := ValidateBlobKzgs(ctx, signed.Block().Body())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not validate blob kzgs")
|
||||
}
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// ValidateBlobKzgs validates the blob kzgs in the beacon block.
|
||||
//
|
||||
// Spec code:
|
||||
// def process_blob_kzg_commitments(state: BeaconState, body: BeaconBlockBody):
|
||||
//
|
||||
// assert verify_kzg_commitments_against_transactions(body.execution_payload.transactions, body.blob_kzg_commitments)
|
||||
func ValidateBlobKzgs(ctx context.Context, body interfaces.ReadOnlyBeaconBlockBody) error {
|
||||
_, span := trace.StartSpan(ctx, "core.state.ValidateBlobKzgs")
|
||||
defer span.End()
|
||||
|
||||
payload, err := body.Execution()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get execution payload from block")
|
||||
}
|
||||
blkKzgs, err := body.BlobKzgCommitments()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get blob kzg commitments from block")
|
||||
}
|
||||
kzgs := make(eth.KZGCommitmentSequenceImpl, len(blkKzgs))
|
||||
for i := range blkKzgs {
|
||||
kzgs[i] = bytesutil.ToBytes48(blkKzgs[i])
|
||||
}
|
||||
txs, err := payload.Transactions()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get transactions from payload")
|
||||
}
|
||||
if err := eth.VerifyKZGCommitmentsAgainstTransactions(txs, kzgs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// This calls altair block operations.
|
||||
func altairOperations(
|
||||
ctx context.Context,
|
||||
|
||||
@@ -54,11 +54,6 @@ type ReadOnlyDatabase interface {
|
||||
// Fee recipients operations.
|
||||
FeeRecipientByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (common.Address, error)
|
||||
RegistrationByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (*ethpb.ValidatorRegistrationV1, error)
|
||||
|
||||
// Blob operations.
|
||||
BlobSidecarsByRoot(ctx context.Context, beaconBlockRoot [32]byte, indices ...uint64) ([]*ethpb.BlobSidecar, error)
|
||||
BlobSidecarsBySlot(ctx context.Context, slot primitives.Slot, indices ...uint64) ([]*ethpb.BlobSidecar, error)
|
||||
|
||||
// origin checkpoint sync support
|
||||
OriginCheckpointBlockRoot(ctx context.Context) ([32]byte, error)
|
||||
BackfillBlockRoot(ctx context.Context) ([32]byte, error)
|
||||
@@ -94,10 +89,6 @@ type NoHeadAccessDatabase interface {
|
||||
SaveFeeRecipientsByValidatorIDs(ctx context.Context, ids []primitives.ValidatorIndex, addrs []common.Address) error
|
||||
SaveRegistrationsByValidatorIDs(ctx context.Context, ids []primitives.ValidatorIndex, regs []*ethpb.ValidatorRegistrationV1) error
|
||||
|
||||
// Blob operations.
|
||||
SaveBlobSidecar(ctx context.Context, sidecars []*ethpb.BlobSidecar) error
|
||||
DeleteBlobSidecar(ctx context.Context, beaconBlockRoot [32]byte) error
|
||||
|
||||
CleanUpDirtyStates(ctx context.Context, slotsPerArchivedPoint primitives.Slot) error
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ go_library(
|
||||
srcs = [
|
||||
"archived_point.go",
|
||||
"backup.go",
|
||||
"blob.go",
|
||||
"blocks.go",
|
||||
"checkpoint.go",
|
||||
"deposit_contract.go",
|
||||
@@ -75,7 +74,6 @@ go_test(
|
||||
srcs = [
|
||||
"archived_point_test.go",
|
||||
"backup_test.go",
|
||||
"blob_test.go",
|
||||
"blocks_test.go",
|
||||
"checkpoint_test.go",
|
||||
"deposit_contract_test.go",
|
||||
@@ -109,11 +107,9 @@ go_test(
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/testing:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/assertions:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
package kv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
types "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// SaveBlobSidecar saves the blobs for a given epoch in the sidecar bucket. When we receive a blob:
|
||||
//
|
||||
// 1. Convert slot using a modulo operator to [0, maxSlots] where maxSlots = MAX_BLOB_EPOCHS*SLOTS_PER_EPOCH
|
||||
//
|
||||
// 2. Compute key for blob as bytes(slot_to_rotating_buffer(blob.slot)) ++ bytes(blob.slot) ++ blob.block_root
|
||||
//
|
||||
// 3. Begin the save algorithm: If the incoming blob has a slot bigger than the saved slot at the spot
|
||||
// in the rotating keys buffer, we overwrite all elements for that slot.
|
||||
func (s *Store) SaveBlobSidecar(ctx context.Context, scs []*ethpb.BlobSidecar) error {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.SaveBlobSidecar")
|
||||
defer span.End()
|
||||
|
||||
if len(scs) == 0 {
|
||||
return errors.New("nil or empty blob sidecars")
|
||||
}
|
||||
slot := scs[0].Slot
|
||||
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
encodedBlobSidecar, err := encode(ctx, ðpb.BlobSidecars{Sidecars: scs})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bkt := tx.Bucket(blobsBucket)
|
||||
c := bkt.Cursor()
|
||||
newKey := blobSidecarKey(scs[0])
|
||||
rotatingBufferPrefix := newKey[0:8]
|
||||
var replacingKey []byte
|
||||
for k, _ := c.Seek(rotatingBufferPrefix); bytes.HasPrefix(k, rotatingBufferPrefix); k, _ = c.Next() {
|
||||
if len(k) != 0 {
|
||||
replacingKey = k
|
||||
oldSlotBytes := replacingKey[8:16]
|
||||
oldSlot := bytesutil.BytesToSlotBigEndian(oldSlotBytes)
|
||||
if oldSlot >= slot {
|
||||
return fmt.Errorf("attempted to save blob with slot %d but already have older blob with slot %d", slot, oldSlot)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
// If there is no element stored at blob.slot % MAX_SLOTS_TO_PERSIST_BLOBS, then we simply
|
||||
// store the blob by key and exit early.
|
||||
if len(replacingKey) == 0 {
|
||||
return bkt.Put(newKey, encodedBlobSidecar)
|
||||
}
|
||||
|
||||
if err := bkt.Delete(replacingKey); err != nil {
|
||||
log.WithError(err).Warnf("Could not delete blob with key %#x", replacingKey)
|
||||
}
|
||||
return bkt.Put(newKey, encodedBlobSidecar)
|
||||
})
|
||||
}
|
||||
|
||||
// BlobSidecarsByRoot retrieves the blobs for the given beacon block root.
|
||||
// If the `indices` argument is omitted, all blobs for the root will be returned.
|
||||
// Otherwise, the result will be filtered to only include the specified indices.
|
||||
// An error will result if an invalid index is specified.
|
||||
func (s *Store) BlobSidecarsByRoot(ctx context.Context, root [32]byte, indices ...uint64) ([]*ethpb.BlobSidecar, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.BlobSidecarsByRoot")
|
||||
defer span.End()
|
||||
|
||||
var enc []byte
|
||||
if err := s.db.View(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket(blobsBucket).Cursor()
|
||||
// Bucket size is bounded and bolt cursors are fast. Moreover, a thin caching layer can be added.
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
if bytes.HasSuffix(k, root[:]) {
|
||||
enc = v
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if enc == nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
sc := ðpb.BlobSidecars{}
|
||||
if err := decode(ctx, enc, sc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return filterForIndices(sc, indices...)
|
||||
}
|
||||
|
||||
func filterForIndices(sc *ethpb.BlobSidecars, indices ...uint64) ([]*ethpb.BlobSidecar, error) {
|
||||
if len(indices) == 0 {
|
||||
return sc.Sidecars, nil
|
||||
}
|
||||
// NB: This loop assumes that the BlobSidecars value stores the complete set of blobs for a block
|
||||
// in ascending order from eg 0..3, without gaps. This allows us to assume the indices argument
|
||||
// maps 1:1 with indices in the BlobSidecars storage object.
|
||||
maxIdx := uint64(len(sc.Sidecars)) - 1
|
||||
sidecars := make([]*ethpb.BlobSidecar, len(indices))
|
||||
for i, idx := range indices {
|
||||
if idx > maxIdx {
|
||||
return nil, errors.Wrapf(ErrNotFound, "BlobSidecars missing index: index %d", idx)
|
||||
}
|
||||
sidecars[i] = sc.Sidecars[idx]
|
||||
}
|
||||
return sidecars, nil
|
||||
}
|
||||
|
||||
// BlobSidecarsBySlot retrieves BlobSidecars for the given slot.
|
||||
// If the `indices` argument is omitted, all blobs for the root will be returned.
|
||||
// Otherwise, the result will be filtered to only include the specified indices.
|
||||
// An error will result if an invalid index is specified.
|
||||
func (s *Store) BlobSidecarsBySlot(ctx context.Context, slot types.Slot, indices ...uint64) ([]*ethpb.BlobSidecar, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.BlobSidecarsBySlot")
|
||||
defer span.End()
|
||||
|
||||
var enc []byte
|
||||
if err := s.db.View(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket(blobsBucket).Cursor()
|
||||
// Bucket size is bounded and bolt cursors are fast. Moreover, a thin caching layer can be added.
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
slotInKey := bytesutil.BytesToSlotBigEndian(k[8:16])
|
||||
if slotInKey == slot {
|
||||
enc = v
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if enc == nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
sc := ðpb.BlobSidecars{}
|
||||
if err := decode(ctx, enc, sc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return filterForIndices(sc, indices...)
|
||||
}
|
||||
|
||||
// DeleteBlobSidecar returns true if the blobs are in the db.
|
||||
func (s *Store) DeleteBlobSidecar(ctx context.Context, beaconBlockRoot [32]byte) error {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.DeleteBlobSidecar")
|
||||
defer span.End()
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(blobsBucket)
|
||||
c := bkt.Cursor()
|
||||
for k, _ := c.First(); k != nil; k, _ = c.Next() {
|
||||
if bytes.HasSuffix(k, beaconBlockRoot[:]) {
|
||||
if err := bkt.Delete(k); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// We define a blob sidecar key as: bytes(slot_to_rotating_buffer(blob.slot)) ++ bytes(blob.slot) ++ blob.block_root
|
||||
// where slot_to_rotating_buffer(slot) = slot % MAX_SLOTS_TO_PERSIST_BLOBS.
|
||||
func blobSidecarKey(blob *ethpb.BlobSidecar) []byte {
|
||||
slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
|
||||
maxEpochsToPersistBlobs := params.BeaconNetworkConfig().MinEpochsForBlobsSidecarsRequest
|
||||
maxSlotsToPersistBlobs := types.Slot(maxEpochsToPersistBlobs.Mul(uint64(slotsPerEpoch)))
|
||||
slotInRotatingBuffer := blob.Slot.ModSlot(maxSlotsToPersistBlobs)
|
||||
key := bytesutil.SlotToBytesBigEndian(slotInRotatingBuffer)
|
||||
key = append(key, bytesutil.SlotToBytesBigEndian(blob.Slot)...)
|
||||
key = append(key, blob.BlockRoot...)
|
||||
return key
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
package kv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assertions"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
func equalBlobSlices(expect []*ethpb.BlobSidecar, got []*ethpb.BlobSidecar) error {
|
||||
if len(expect) != len(got) {
|
||||
return fmt.Errorf("mismatched lengths, expect=%d, got=%d", len(expect), len(got))
|
||||
}
|
||||
for i := 0; i < len(expect); i++ {
|
||||
es := expect[i]
|
||||
gs := got[i]
|
||||
var e string
|
||||
assertions.DeepEqual(assertions.SprintfAssertionLoggerFn(&e), es, gs)
|
||||
if e != "" {
|
||||
return errors.New(e)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestStore_BlobSidecars(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, 0)
|
||||
require.ErrorContains(t, "nil or empty blob sidecars", db.SaveBlobSidecar(ctx, scs))
|
||||
})
|
||||
t.Run("empty by root", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
got, err := db.BlobSidecarsByRoot(ctx, [32]byte{})
|
||||
require.ErrorIs(t, ErrNotFound, err)
|
||||
require.Equal(t, 0, len(got))
|
||||
})
|
||||
t.Run("empty by slot", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
got, err := db.BlobSidecarsBySlot(ctx, 1)
|
||||
require.ErrorIs(t, ErrNotFound, err)
|
||||
require.Equal(t, 0, len(got))
|
||||
})
|
||||
t.Run("save and retrieve by root (one)", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, 1)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, 1, len(scs))
|
||||
got, err := db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(scs[0].BlockRoot))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(scs, got))
|
||||
})
|
||||
t.Run("save and retrieve by root (max)", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
got, err := db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(scs[0].BlockRoot))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(scs, got))
|
||||
})
|
||||
t.Run("save and retrieve valid subset by root", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
|
||||
// we'll request indices 0 and 3, so make a slice with those indices for comparison
|
||||
expect := make([]*ethpb.BlobSidecar, 2)
|
||||
expect[0] = scs[0]
|
||||
expect[1] = scs[3]
|
||||
|
||||
got, err := db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(scs[0].BlockRoot), 0, 3)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(expect, got))
|
||||
require.Equal(t, uint64(0), got[0].Index)
|
||||
require.Equal(t, uint64(3), got[1].Index)
|
||||
})
|
||||
t.Run("error for invalid index when retrieving by root", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
|
||||
got, err := db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(scs[0].BlockRoot), uint64(len(scs)))
|
||||
require.ErrorIs(t, err, ErrNotFound)
|
||||
require.Equal(t, 0, len(got))
|
||||
})
|
||||
t.Run("save and retrieve by slot (one)", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, 1)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, 1, len(scs))
|
||||
got, err := db.BlobSidecarsBySlot(ctx, scs[0].Slot)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(scs, got))
|
||||
})
|
||||
t.Run("save and retrieve by slot (max)", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
got, err := db.BlobSidecarsBySlot(ctx, scs[0].Slot)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(scs, got))
|
||||
})
|
||||
t.Run("save and retrieve valid subset by slot", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
|
||||
// we'll request indices 0 and 3, so make a slice with those indices for comparison
|
||||
expect := make([]*ethpb.BlobSidecar, 2)
|
||||
expect[0] = scs[0]
|
||||
expect[1] = scs[3]
|
||||
|
||||
got, err := db.BlobSidecarsBySlot(ctx, scs[0].Slot, 0, 3)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(expect, got))
|
||||
|
||||
require.Equal(t, uint64(0), got[0].Index)
|
||||
require.Equal(t, uint64(3), got[1].Index)
|
||||
})
|
||||
t.Run("error for invalid index when retrieving by slot", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
|
||||
got, err := db.BlobSidecarsBySlot(ctx, scs[0].Slot, uint64(len(scs)))
|
||||
require.ErrorIs(t, err, ErrNotFound)
|
||||
require.Equal(t, 0, len(got))
|
||||
})
|
||||
t.Run("delete works", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
got, err := db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(scs[0].BlockRoot))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(scs, got))
|
||||
require.NoError(t, db.DeleteBlobSidecar(ctx, bytesutil.ToBytes32(scs[0].BlockRoot)))
|
||||
got, err = db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(scs[0].BlockRoot))
|
||||
require.ErrorIs(t, ErrNotFound, err)
|
||||
require.Equal(t, 0, len(got))
|
||||
})
|
||||
t.Run("saving a blob with older slot", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
got, err := db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(scs[0].BlockRoot))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(scs, got))
|
||||
require.ErrorContains(t, "but already have older blob with slot", db.SaveBlobSidecar(ctx, scs))
|
||||
})
|
||||
t.Run("saving a new blob for rotation", func(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
scs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, scs))
|
||||
require.Equal(t, int(params.BeaconConfig().MaxBlobsPerBlock), len(scs))
|
||||
oldBlockRoot := scs[0].BlockRoot
|
||||
got, err := db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(oldBlockRoot))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(scs, got))
|
||||
|
||||
newScs := generateBlobSidecars(t, params.BeaconConfig().MaxBlobsPerBlock)
|
||||
newRetentionSlot := primitives.Slot(params.BeaconNetworkConfig().MinEpochsForBlobsSidecarsRequest.Mul(uint64(params.BeaconConfig().SlotsPerEpoch)))
|
||||
newScs[0].Slot = scs[0].Slot + newRetentionSlot
|
||||
require.NoError(t, db.SaveBlobSidecar(ctx, newScs))
|
||||
|
||||
_, err = db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(oldBlockRoot))
|
||||
require.ErrorIs(t, ErrNotFound, err)
|
||||
|
||||
got, err = db.BlobSidecarsByRoot(ctx, bytesutil.ToBytes32(newScs[0].BlockRoot))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, equalBlobSlices(newScs, got))
|
||||
})
|
||||
}
|
||||
|
||||
func generateBlobSidecars(t *testing.T, n uint64) []*ethpb.BlobSidecar {
|
||||
blobSidecars := make([]*ethpb.BlobSidecar, n)
|
||||
for i := uint64(0); i < n; i++ {
|
||||
blobSidecars[i] = generateBlobSidecar(t, i)
|
||||
}
|
||||
return blobSidecars
|
||||
}
|
||||
|
||||
func generateBlobSidecar(t *testing.T, index uint64) *ethpb.BlobSidecar {
|
||||
blockRoot := make([]byte, 32)
|
||||
_, err := rand.Read(blockRoot)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
slot := make([]byte, 8)
|
||||
_, err = rand.Read(slot)
|
||||
require.NoError(t, err)
|
||||
blockParentRoot := make([]byte, 32)
|
||||
_, err = rand.Read(blockParentRoot)
|
||||
require.NoError(t, err)
|
||||
proposerIndex := make([]byte, 8)
|
||||
_, err = rand.Read(proposerIndex)
|
||||
require.NoError(t, err)
|
||||
blobData := make([]byte, 131072)
|
||||
_, err = rand.Read(blobData)
|
||||
require.NoError(t, err)
|
||||
blob := &enginev1.Blob{
|
||||
Data: blobData,
|
||||
}
|
||||
kzgCommitment := make([]byte, 48)
|
||||
_, err = rand.Read(kzgCommitment)
|
||||
require.NoError(t, err)
|
||||
kzgProof := make([]byte, 48)
|
||||
_, err = rand.Read(kzgProof)
|
||||
require.NoError(t, err)
|
||||
|
||||
return ðpb.BlobSidecar{
|
||||
BlockRoot: blockRoot,
|
||||
Index: index,
|
||||
Slot: primitives.Slot(binary.LittleEndian.Uint64(slot)),
|
||||
BlockParentRoot: blockParentRoot,
|
||||
ProposerIndex: primitives.ValidatorIndex(binary.LittleEndian.Uint64(proposerIndex)),
|
||||
Blob: blob,
|
||||
KzgCommitment: kzgCommitment,
|
||||
KzgProof: kzgProof,
|
||||
}
|
||||
}
|
||||
@@ -818,16 +818,6 @@ func unmarshalBlock(_ context.Context, enc []byte) (interfaces.ReadOnlySignedBea
|
||||
if err := rawBlock.UnmarshalSSZ(enc[len(capellaBlindKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal blinded Capella block")
|
||||
}
|
||||
case hasDenebKey(enc):
|
||||
rawBlock = ðpb.SignedBeaconBlockDeneb{}
|
||||
if err := rawBlock.UnmarshalSSZ(enc[len(denebKey):]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case hasDenebBlindKey(enc):
|
||||
rawBlock = ðpb.SignedBlindedBeaconBlockDeneb{}
|
||||
if err := rawBlock.UnmarshalSSZ(enc[len(denebBlindKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal blinded Deneb block")
|
||||
}
|
||||
default:
|
||||
// Marshal block bytes to phase 0 beacon block.
|
||||
rawBlock = ðpb.SignedBeaconBlock{}
|
||||
@@ -864,8 +854,6 @@ func marshalBlockFull(
|
||||
return nil, err
|
||||
}
|
||||
switch blk.Version() {
|
||||
case version.Deneb:
|
||||
return snappy.Encode(nil, append(denebKey, encodedBlock...)), nil
|
||||
case version.Capella:
|
||||
return snappy.Encode(nil, append(capellaKey, encodedBlock...)), nil
|
||||
case version.Bellatrix:
|
||||
@@ -900,8 +888,6 @@ func marshalBlockBlinded(
|
||||
return nil, errors.Wrap(err, "could not marshal blinded block")
|
||||
}
|
||||
switch blk.Version() {
|
||||
case version.Deneb:
|
||||
return snappy.Encode(nil, append(denebBlindKey, encodedBlock...)), nil
|
||||
case version.Capella:
|
||||
return snappy.Encode(nil, append(capellaBlindKey, encodedBlock...)), nil
|
||||
case version.Bellatrix:
|
||||
|
||||
@@ -37,17 +37,3 @@ func hasCapellaBlindKey(enc []byte) bool {
|
||||
}
|
||||
return bytes.Equal(enc[:len(capellaBlindKey)], capellaBlindKey)
|
||||
}
|
||||
|
||||
func hasDenebKey(enc []byte) bool {
|
||||
if len(denebKey) >= len(enc) {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(enc[:len(denebKey)], denebKey)
|
||||
}
|
||||
|
||||
func hasDenebBlindKey(enc []byte) bool {
|
||||
if len(denebBlindKey) >= len(enc) {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(enc[:len(denebBlindKey)], denebBlindKey)
|
||||
}
|
||||
|
||||
@@ -129,8 +129,6 @@ var Buckets = [][]byte{
|
||||
|
||||
feeRecipientBucket,
|
||||
registrationBucket,
|
||||
|
||||
blobsBucket,
|
||||
}
|
||||
|
||||
// NewKVStore initializes a new boltDB key-value store at the directory
|
||||
|
||||
@@ -46,7 +46,6 @@ var (
|
||||
finalizedCheckpointKey = []byte("finalized-checkpoint")
|
||||
powchainDataKey = []byte("powchain-data")
|
||||
lastValidatedCheckpointKey = []byte("last-validated-checkpoint")
|
||||
blobsBucket = []byte("blobs")
|
||||
|
||||
// Below keys are used to identify objects are to be fork compatible.
|
||||
// Objects that are only compatible with specific forks should be prefixed with such keys.
|
||||
@@ -56,9 +55,6 @@ var (
|
||||
capellaKey = []byte("capella")
|
||||
capellaBlindKey = []byte("blind-capella")
|
||||
saveBlindedBeaconBlocksKey = []byte("save-blinded-beacon-blocks")
|
||||
denebKey = []byte("deneb")
|
||||
denebBlindKey = []byte("blind-deneb")
|
||||
|
||||
// block root included in the beacon state used by weak subjectivity initial sync
|
||||
originCheckpointBlockRootKey = []byte("origin-checkpoint-block-root")
|
||||
// block root tracking the progress of backfill, or pointing at genesis if backfill has not been initiated
|
||||
|
||||
@@ -473,19 +473,6 @@ func (s *Store) unmarshalState(_ context.Context, enc []byte, validatorEntries [
|
||||
}
|
||||
|
||||
switch {
|
||||
case hasDenebKey(enc):
|
||||
protoState := ðpb.BeaconStateDeneb{}
|
||||
if err := protoState.UnmarshalSSZ(enc[len(denebKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal encoding for Deneb")
|
||||
}
|
||||
ok, err := s.isStateValidatorMigrationOver()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ok {
|
||||
protoState.Validators = validatorEntries
|
||||
}
|
||||
return statenative.InitializeFromProtoUnsafeDeneb(protoState)
|
||||
case hasCapellaKey(enc):
|
||||
// Marshal state bytes to capella beacon state.
|
||||
protoState := ðpb.BeaconStateCapella{}
|
||||
@@ -593,19 +580,6 @@ func marshalState(ctx context.Context, st state.ReadOnlyBeaconState) ([]byte, er
|
||||
return nil, err
|
||||
}
|
||||
return snappy.Encode(nil, append(capellaKey, rawObj...)), nil
|
||||
case *ethpb.BeaconStateDeneb:
|
||||
rState, ok := st.ToProtoUnsafe().(*ethpb.BeaconStateDeneb)
|
||||
if !ok {
|
||||
return nil, errors.New("non valid inner state")
|
||||
}
|
||||
if rState == nil {
|
||||
return nil, errors.New("nil state")
|
||||
}
|
||||
rawObj, err := rState.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return snappy.Encode(nil, append(denebKey, rawObj...)), nil
|
||||
default:
|
||||
return nil, errors.New("invalid inner state")
|
||||
}
|
||||
|
||||
@@ -30,12 +30,25 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
supportedEngineEndpoints = []string{
|
||||
NewPayloadMethod,
|
||||
NewPayloadMethodV2,
|
||||
ForkchoiceUpdatedMethod,
|
||||
ForkchoiceUpdatedMethodV2,
|
||||
GetPayloadMethod,
|
||||
GetPayloadMethodV2,
|
||||
ExchangeTransitionConfigurationMethod,
|
||||
GetPayloadBodiesByHashV1,
|
||||
GetPayloadBodiesByRangeV1,
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
// NewPayloadMethod v1 request string for JSON-RPC.
|
||||
NewPayloadMethod = "engine_newPayloadV1"
|
||||
// NewPayloadMethodV2 v2 request string for JSON-RPC.
|
||||
NewPayloadMethodV2 = "engine_newPayloadV2"
|
||||
NewPayloadMethodV3 = "engine_newPayloadV3"
|
||||
// ForkchoiceUpdatedMethod v1 request string for JSON-RPC.
|
||||
ForkchoiceUpdatedMethod = "engine_forkchoiceUpdatedV1"
|
||||
// ForkchoiceUpdatedMethodV2 v2 request string for JSON-RPC.
|
||||
@@ -44,9 +57,6 @@ const (
|
||||
GetPayloadMethod = "engine_getPayloadV1"
|
||||
// GetPayloadMethodV2 v2 request string for JSON-RPC.
|
||||
GetPayloadMethodV2 = "engine_getPayloadV2"
|
||||
GetPayloadMethodV3 = "engine_getPayloadV3"
|
||||
// GetBlobsBundleMethod v1 request string for JSON-RPC.
|
||||
GetBlobsBundleMethod = "engine_getBlobsBundleV1"
|
||||
// ExchangeTransitionConfigurationMethod v1 request string for JSON-RPC.
|
||||
ExchangeTransitionConfigurationMethod = "engine_exchangeTransitionConfigurationV1"
|
||||
// ExecutionBlockByHashMethod request string for JSON-RPC.
|
||||
@@ -57,6 +67,8 @@ const (
|
||||
GetPayloadBodiesByHashV1 = "engine_getPayloadBodiesByHashV1"
|
||||
// GetPayloadBodiesByRangeV1 v1 request string for JSON-RPC.
|
||||
GetPayloadBodiesByRangeV1 = "engine_getPayloadBodiesByRangeV1"
|
||||
// ExchangeCapabilities request string for JSON-RPC.
|
||||
ExchangeCapabilities = "engine_exchangeCapabilities"
|
||||
// Defines the seconds before timing out engine endpoints with non-block execution semantics.
|
||||
defaultEngineTimeout = time.Second
|
||||
)
|
||||
@@ -93,7 +105,6 @@ type EngineCaller interface {
|
||||
) error
|
||||
ExecutionBlockByHash(ctx context.Context, hash common.Hash, withTxs bool) (*pb.ExecutionBlock, error)
|
||||
GetTerminalBlockHash(ctx context.Context, transitionTime uint64) ([]byte, bool, error)
|
||||
GetBlobsBundle(ctx context.Context, payloadId [8]byte) (*pb.BlobsBundle, error)
|
||||
}
|
||||
|
||||
var EmptyBlockHash = errors.New("Block hash is empty 0x0000...")
|
||||
@@ -131,15 +142,6 @@ func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionDa
|
||||
if err != nil {
|
||||
return nil, handleRPCError(err)
|
||||
}
|
||||
case *pb.ExecutionPayloadDeneb:
|
||||
payloadPb, ok := payload.Proto().(*pb.ExecutionPayloadDeneb)
|
||||
if !ok {
|
||||
return nil, errors.New("execution data must be a Deneb execution payload")
|
||||
}
|
||||
err := s.rpcClient.CallContext(ctx, result, NewPayloadMethodV3, payloadPb)
|
||||
if err != nil {
|
||||
return nil, handleRPCError(err)
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("unknown execution data type")
|
||||
}
|
||||
@@ -187,7 +189,7 @@ func (s *Service) ForkchoiceUpdated(
|
||||
if err != nil {
|
||||
return nil, nil, handleRPCError(err)
|
||||
}
|
||||
case version.Capella, version.Deneb:
|
||||
case version.Capella:
|
||||
a, err := attrs.PbV2()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -229,15 +231,6 @@ func (s *Service) GetPayload(ctx context.Context, payloadId [8]byte, slot primit
|
||||
ctx, cancel := context.WithDeadline(ctx, d)
|
||||
defer cancel()
|
||||
|
||||
if slots.ToEpoch(slot) >= params.BeaconConfig().DenebForkEpoch {
|
||||
result := &pb.ExecutionPayloadDenebWithValue{}
|
||||
err := s.rpcClient.CallContext(ctx, result, GetPayloadMethodV3, pb.PayloadIDBytes(payloadId))
|
||||
if err != nil {
|
||||
return nil, handleRPCError(err)
|
||||
}
|
||||
return blocks.WrappedExecutionPayloadDeneb(result.Payload, big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(result.Value)))
|
||||
}
|
||||
|
||||
if slots.ToEpoch(slot) >= params.BeaconConfig().CapellaForkEpoch {
|
||||
result := &pb.ExecutionPayloadCapellaWithValue{}
|
||||
err := s.rpcClient.CallContext(ctx, result, GetPayloadMethodV2, pb.PayloadIDBytes(payloadId))
|
||||
@@ -301,6 +294,35 @@ func (s *Service) ExchangeTransitionConfiguration(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) ExchangeCapabilities(ctx context.Context) ([]string, error) {
|
||||
if !features.Get().EnableOptionalEngineMethods {
|
||||
return nil, errors.New("optional engine methods not enabled")
|
||||
}
|
||||
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.ExchangeCapabilities")
|
||||
defer span.End()
|
||||
|
||||
result := &pb.ExchangeCapabilities{}
|
||||
err := s.rpcClient.CallContext(ctx, &result, ExchangeCapabilities, supportedEngineEndpoints)
|
||||
|
||||
var unsupported []string
|
||||
for _, s1 := range supportedEngineEndpoints {
|
||||
supported := false
|
||||
for _, s2 := range result.SupportedMethods {
|
||||
if s1 == s2 {
|
||||
supported = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !supported {
|
||||
unsupported = append(unsupported, s1)
|
||||
}
|
||||
}
|
||||
if len(unsupported) != 0 {
|
||||
log.Warnf("Please update client, detected the following unsupported engine methods: %s", unsupported)
|
||||
}
|
||||
return result.SupportedMethods, handleRPCError(err)
|
||||
}
|
||||
|
||||
// GetTerminalBlockHash returns the valid terminal block hash based on total difficulty.
|
||||
//
|
||||
// Spec code:
|
||||
@@ -445,19 +467,6 @@ func (s *Service) ExecutionBlocksByHashes(ctx context.Context, hashes []common.H
|
||||
return execBlks, nil
|
||||
}
|
||||
|
||||
// GetBlobsBundle calls the engine_getBlobsV1 method via JSON-RPC.
|
||||
func (s *Service) GetBlobsBundle(ctx context.Context, payloadId [8]byte) (*pb.BlobsBundle, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.GetBlobsBundle")
|
||||
defer span.End()
|
||||
|
||||
d := time.Now().Add(defaultEngineTimeout)
|
||||
ctx, cancel := context.WithDeadline(ctx, d)
|
||||
defer cancel()
|
||||
result := &pb.BlobsBundle{}
|
||||
err := s.rpcClient.CallContext(ctx, result, GetBlobsBundleMethod, pb.PayloadIDBytes(payloadId))
|
||||
return result, handleRPCError(err)
|
||||
}
|
||||
|
||||
// HeaderByHash returns the relevant header details for the provided block hash.
|
||||
func (s *Service) HeaderByHash(ctx context.Context, hash common.Hash) (*types.HeaderInfo, error) {
|
||||
var hdr *types.HeaderInfo
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
@@ -2320,3 +2321,77 @@ func TestCapella_PayloadBodiesByRange(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ExchangeCapabilities(t *testing.T) {
|
||||
resetFn := features.InitWithReset(&features.Flags{
|
||||
EnableOptionalEngineMethods: true,
|
||||
})
|
||||
defer resetFn()
|
||||
t.Run("empty response works", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
exchangeCapabilities := &pb.ExchangeCapabilities{}
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": exchangeCapabilities,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
logHook := logTest.NewGlobal()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.ExchangeCapabilities(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
assert.LogsContain(t, logHook, "Please update client, detected the following unsupported engine methods:")
|
||||
})
|
||||
t.Run("list of items", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
exchangeCapabilities := &pb.ExchangeCapabilities{
|
||||
SupportedMethods: []string{"A", "B", "C"},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": exchangeCapabilities,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.ExchangeCapabilities(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package execution
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -15,6 +14,7 @@ import (
|
||||
contracts "github.com/prysmaticlabs/prysm/v4/contracts/deposit"
|
||||
"github.com/prysmaticlabs/prysm/v4/io/logs"
|
||||
"github.com/prysmaticlabs/prysm/v4/network"
|
||||
"github.com/prysmaticlabs/prysm/v4/network/authorization"
|
||||
)
|
||||
|
||||
func (s *Service) setupExecutionClientConnections(ctx context.Context, currEndpoint network.Endpoint) error {
|
||||
@@ -34,7 +34,7 @@ func (s *Service) setupExecutionClientConnections(ctx context.Context, currEndpo
|
||||
}
|
||||
s.depositContractCaller = depositContractCaller
|
||||
|
||||
//Ensure we have the correct chain and deposit IDs.
|
||||
// Ensure we have the correct chain and deposit IDs.
|
||||
if err := ensureCorrectExecutionChain(ctx, fetcher); err != nil {
|
||||
client.Close()
|
||||
errStr := err.Error()
|
||||
@@ -113,21 +113,9 @@ func (s *Service) newRPCClientWithAuth(ctx context.Context, endpoint network.End
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headers := http.Header{}
|
||||
for _, h := range s.cfg.headers {
|
||||
if h == "" {
|
||||
continue
|
||||
}
|
||||
keyValue := strings.Split(h, "=")
|
||||
if len(keyValue) < 2 {
|
||||
log.Warnf("Incorrect HTTP header flag format. Skipping %v", keyValue[0])
|
||||
continue
|
||||
}
|
||||
headers.Set(keyValue[0], strings.Join(keyValue[1:], "="))
|
||||
}
|
||||
switch u.Scheme {
|
||||
case "http", "https":
|
||||
client, err = gethRPC.DialOptions(ctx, endpoint.Url, gethRPC.WithHTTPClient(endpoint.HttpClient()), gethRPC.WithHeaders(headers))
|
||||
client, err = gethRPC.DialOptions(ctx, endpoint.Url, gethRPC.WithHTTPClient(endpoint.HttpClient()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -139,6 +127,13 @@ func (s *Service) newRPCClientWithAuth(ctx context.Context, endpoint network.End
|
||||
default:
|
||||
return nil, fmt.Errorf("no known transport for URL scheme %q", u.Scheme)
|
||||
}
|
||||
if endpoint.Auth.Method != authorization.None {
|
||||
header, err := endpoint.Auth.ToHeaderValue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.SetHeader("Authorization", header)
|
||||
}
|
||||
for _, h := range s.cfg.headers {
|
||||
if h != "" {
|
||||
keyValue := strings.Split(h, "=")
|
||||
|
||||
@@ -4,7 +4,6 @@ go_library(
|
||||
name = "go_default_library",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"genesis.go",
|
||||
"mock_engine_client.go",
|
||||
"mock_execution_chain.go",
|
||||
"mock_faulty_powchain.go",
|
||||
@@ -30,9 +29,7 @@ go_library(
|
||||
"@com_github_ethereum_go_ethereum//accounts/abi/bind/backends:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//params:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//rpc:go_default_library",
|
||||
"@com_github_holiman_uint256//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
|
||||
@@ -38,7 +38,6 @@ type EngineClient struct {
|
||||
TerminalBlockHash []byte
|
||||
TerminalBlockHashExists bool
|
||||
OverrideValidHash [32]byte
|
||||
BlobsBundle *pb.BlobsBundle
|
||||
BlockValue *big.Int
|
||||
}
|
||||
|
||||
@@ -173,8 +172,3 @@ func (e *EngineClient) GetTerminalBlockHash(ctx context.Context, transitionTime
|
||||
blk = parentBlk
|
||||
}
|
||||
}
|
||||
|
||||
// GetBlobsBundle --
|
||||
func (e *EngineClient) GetBlobsBundle(ctx context.Context, payloadId [8]byte) (*pb.BlobsBundle, error) {
|
||||
return e.BlobsBundle, nil
|
||||
}
|
||||
|
||||
@@ -508,6 +508,17 @@ func (f *ForkChoice) JustifiedPayloadBlockHash() [32]byte {
|
||||
return node.payloadHash
|
||||
}
|
||||
|
||||
// UnrealizedJustifiedPayloadBlockHash returns the hash of the payload at the unrealized justified checkpoint
|
||||
func (f *ForkChoice) UnrealizedJustifiedPayloadBlockHash() ([32]byte, error) {
|
||||
root := f.store.unrealizedJustifiedCheckpoint.Root
|
||||
node, ok := f.store.nodeByRoot[root]
|
||||
if !ok || node == nil {
|
||||
// This should not happen
|
||||
return [32]byte{}, ErrNilNode
|
||||
}
|
||||
return node.payloadHash, nil
|
||||
}
|
||||
|
||||
// ForkChoiceDump returns a full dump of forkchoice.
|
||||
func (f *ForkChoice) ForkChoiceDump(ctx context.Context) (*v1.ForkChoiceDump, error) {
|
||||
jc := &v1.Checkpoint{
|
||||
|
||||
@@ -740,5 +740,22 @@ func TestForkchoice_UpdateJustifiedBalances(t *testing.T) {
|
||||
require.Equal(t, uint64(7), f.numActiveValidators)
|
||||
require.Equal(t, uint64(430)/32, f.store.committeeWeight)
|
||||
require.DeepEqual(t, balances, f.justifiedBalances)
|
||||
|
||||
}
|
||||
|
||||
func TestForkChoice_UnrealizedJustifiedPayloadBlockHash(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
f := setup(0, 0)
|
||||
|
||||
st, blkRoot, err := prepareForkchoiceState(ctx, 0, [32]byte{'a'}, params.BeaconConfig().ZeroHash, [32]byte{'A'}, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, st, blkRoot))
|
||||
|
||||
f.store.unrealizedJustifiedCheckpoint.Root = [32]byte{'a'}
|
||||
got, err := f.UnrealizedJustifiedPayloadBlockHash()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{'A'}, got)
|
||||
|
||||
f.store.unrealizedJustifiedCheckpoint.Root = [32]byte{'b'}
|
||||
_, err = f.UnrealizedJustifiedPayloadBlockHash()
|
||||
require.ErrorIs(t, err, ErrNilNode)
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ type Getter interface {
|
||||
JustifiedCheckpoint() *forkchoicetypes.Checkpoint
|
||||
PreviousJustifiedCheckpoint() *forkchoicetypes.Checkpoint
|
||||
JustifiedPayloadBlockHash() [32]byte
|
||||
UnrealizedJustifiedPayloadBlockHash() ([32]byte, error)
|
||||
NodeCount() int
|
||||
HighestReceivedBlockSlot() primitives.Slot
|
||||
ReceivedBlocksLastEpoch() (uint64, error)
|
||||
|
||||
@@ -61,6 +61,7 @@ go_library(
|
||||
"//runtime/prereqs:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_gorilla_mux//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
|
||||
@@ -67,6 +67,13 @@ func configureBuilderCircuitBreaker(cliCtx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if cliCtx.IsSet(flags.LocalBlockValueBoost.Name) {
|
||||
c := params.BeaconConfig().Copy()
|
||||
c.LocalBlockValueBoost = cliCtx.Uint64(flags.LocalBlockValueBoost.Name)
|
||||
if err := params.SetActive(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pkg/errors"
|
||||
apigateway "github.com/prysmaticlabs/prysm/v4/api/gateway"
|
||||
"github.com/prysmaticlabs/prysm/v4/async/event"
|
||||
@@ -232,7 +233,7 @@ func New(cliCtx *cli.Context, opts ...Option) (*BeaconNode, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugln("Registering Intial Sync Service")
|
||||
log.Debugln("Registering Initial Sync Service")
|
||||
if err := beacon.registerInitialSyncService(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -253,12 +254,13 @@ func New(cliCtx *cli.Context, opts ...Option) (*BeaconNode, error) {
|
||||
}
|
||||
|
||||
log.Debugln("Registering RPC Service")
|
||||
if err := beacon.registerRPCService(); err != nil {
|
||||
router := mux.NewRouter()
|
||||
if err := beacon.registerRPCService(router); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugln("Registering GRPC Gateway Service")
|
||||
if err := beacon.registerGRPCGateway(); err != nil {
|
||||
if err := beacon.registerGRPCGateway(router); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -536,6 +538,7 @@ func (b *BeaconNode) registerP2P(cliCtx *cli.Context) error {
|
||||
HostAddress: cliCtx.String(cmd.P2PHost.Name),
|
||||
HostDNS: cliCtx.String(cmd.P2PHostDNS.Name),
|
||||
PrivateKey: cliCtx.String(cmd.P2PPrivKey.Name),
|
||||
StaticPeerID: cliCtx.Bool(cmd.P2PStaticID.Name),
|
||||
MetaDataDir: cliCtx.String(cmd.P2PMetadata.Name),
|
||||
TCPPort: cliCtx.Uint(cmd.P2PTCPPort.Name),
|
||||
UDPPort: cliCtx.Uint(cmd.P2PUDPPort.Name),
|
||||
@@ -734,7 +737,7 @@ func (b *BeaconNode) registerSlasherService() error {
|
||||
return b.services.RegisterService(slasherSrv)
|
||||
}
|
||||
|
||||
func (b *BeaconNode) registerRPCService() error {
|
||||
func (b *BeaconNode) registerRPCService(router *mux.Router) error {
|
||||
var chainService *blockchain.Service
|
||||
if err := b.services.FetchService(&chainService); err != nil {
|
||||
return err
|
||||
@@ -830,6 +833,7 @@ func (b *BeaconNode) registerRPCService() error {
|
||||
MaxMsgSize: maxMsgSize,
|
||||
ProposerIdsCache: b.proposerIdsCache,
|
||||
BlockBuilder: b.fetchBuilderService(),
|
||||
Router: router,
|
||||
})
|
||||
|
||||
return b.services.RegisterService(rpcService)
|
||||
@@ -858,7 +862,7 @@ func (b *BeaconNode) registerPrometheusService(_ *cli.Context) error {
|
||||
return b.services.RegisterService(service)
|
||||
}
|
||||
|
||||
func (b *BeaconNode) registerGRPCGateway() error {
|
||||
func (b *BeaconNode) registerGRPCGateway(router *mux.Router) error {
|
||||
if b.cliCtx.Bool(flags.DisableGRPCGateway.Name) {
|
||||
return nil
|
||||
}
|
||||
@@ -884,6 +888,7 @@ func (b *BeaconNode) registerGRPCGateway() error {
|
||||
}
|
||||
|
||||
opts := []apigateway.Option{
|
||||
apigateway.WithRouter(router),
|
||||
apigateway.WithGatewayAddr(gatewayAddress),
|
||||
apigateway.WithRemoteAddr(selfAddress),
|
||||
apigateway.WithPbHandlers(muxs),
|
||||
|
||||
@@ -141,35 +141,6 @@ func (s *Service) broadcastAttestation(ctx context.Context, subnet uint64, att *
|
||||
}
|
||||
}
|
||||
|
||||
// BroadcastBlob broadcasts a blob to the p2p network, the message is assumed to be
|
||||
// broadcasted to the current fork and to the input subnet.
|
||||
func (s *Service) BroadcastBlob(ctx context.Context, subnet uint64, blob *ethpb.SignedBlobSidecar) error {
|
||||
ctx, span := trace.StartSpan(ctx, "p2p.BroadcastBlob")
|
||||
defer span.End()
|
||||
forkDigest, err := s.currentForkDigest()
|
||||
if err != nil {
|
||||
err := errors.Wrap(err, "could not retrieve fork digest")
|
||||
tracing.AnnotateError(span, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Non-blocking broadcast, with attempts to discover a subnet peer if none available.
|
||||
go s.broadcastBlob(ctx, subnet, blob, forkDigest)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) broadcastBlob(ctx context.Context, subnet uint64, blobSidecar *ethpb.SignedBlobSidecar, forkDigest [4]byte) {
|
||||
ctx, span := trace.StartSpan(ctx, "p2p.broadcastBlob")
|
||||
defer span.End()
|
||||
ctx = trace.NewContext(context.Background(), span) // clear parent context / deadline.
|
||||
|
||||
if err := s.broadcastObject(ctx, blobSidecar, blobSubnetToTopic(subnet, forkDigest)); err != nil {
|
||||
log.WithError(err).Error("Failed to broadcast blob sidecar")
|
||||
tracing.AnnotateError(span, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) broadcastSyncCommittee(ctx context.Context, subnet uint64, sMsg *ethpb.SyncCommitteeMessage, forkDigest [4]byte) {
|
||||
ctx, span := trace.StartSpan(ctx, "p2p.broadcastSyncCommittee")
|
||||
defer span.End()
|
||||
@@ -261,7 +232,3 @@ func attestationToTopic(subnet uint64, forkDigest [4]byte) string {
|
||||
func syncCommitteeToTopic(subnet uint64, forkDigest [4]byte) string {
|
||||
return fmt.Sprintf(SyncCommitteeSubnetTopicFormat, forkDigest, subnet)
|
||||
}
|
||||
|
||||
func blobSubnetToTopic(subnet uint64, forkDigest [4]byte) string {
|
||||
return fmt.Sprintf(BlobSubnetTopicFormat, forkDigest, subnet)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
type Config struct {
|
||||
NoDiscovery bool
|
||||
EnableUPnP bool
|
||||
StaticPeerID bool
|
||||
StaticPeers []string
|
||||
BootstrapNodeAddr []string
|
||||
Discv5BootStrapAddr []string
|
||||
|
||||
@@ -332,7 +332,7 @@ func (s *Service) isPeerAtLimit(inbound bool) bool {
|
||||
return activePeers >= maxPeers || numOfConns >= maxPeers
|
||||
}
|
||||
|
||||
// PeersFromStringAddrs convers peer raw ENRs into multiaddrs for p2p.
|
||||
// PeersFromStringAddrs converts peer raw ENRs into multiaddrs for p2p.
|
||||
func PeersFromStringAddrs(addrs []string) ([]ma.Multiaddr, error) {
|
||||
var allAddrs []ma.Multiaddr
|
||||
enodeString, multiAddrString := parseGenericAddrs(addrs)
|
||||
|
||||
@@ -17,8 +17,7 @@ func (s *Service) forkWatcher() {
|
||||
currEpoch := slots.ToEpoch(currSlot)
|
||||
if currEpoch == params.BeaconConfig().AltairForkEpoch ||
|
||||
currEpoch == params.BeaconConfig().BellatrixForkEpoch ||
|
||||
currEpoch == params.BeaconConfig().CapellaForkEpoch ||
|
||||
currEpoch == params.BeaconConfig().DenebForkEpoch {
|
||||
currEpoch == params.BeaconConfig().CapellaForkEpoch {
|
||||
// If we are in the fork epoch, we update our enr with
|
||||
// the updated fork digest. These repeatedly does
|
||||
// this over the epoch, which might be slightly wasteful
|
||||
|
||||
@@ -119,9 +119,6 @@ func (s *Service) topicScoreParams(topic string) (*pubsub.TopicScoreParams, erro
|
||||
return defaultProposerSlashingTopicParams(), nil
|
||||
case strings.Contains(topic, GossipAttesterSlashingMessage):
|
||||
return defaultAttesterSlashingTopicParams(), nil
|
||||
case strings.Contains(topic, GossipBlobSidecarMessage):
|
||||
// TODO(Deneb): Using the default block scoring. But this should be updated.
|
||||
return defaultBlockTopicParams(), nil
|
||||
case strings.Contains(topic, GossipBlsToExecutionChangeMessage):
|
||||
return defaultBlsToExecutionChangeTopicParams(), nil
|
||||
default:
|
||||
|
||||
@@ -21,16 +21,12 @@ var gossipTopicMappings = map[string]proto.Message{
|
||||
SyncContributionAndProofSubnetTopicFormat: ðpb.SignedContributionAndProof{},
|
||||
SyncCommitteeSubnetTopicFormat: ðpb.SyncCommitteeMessage{},
|
||||
BlsToExecutionChangeSubnetTopicFormat: ðpb.SignedBLSToExecutionChange{},
|
||||
BlobSubnetTopicFormat: ðpb.SignedBlobSidecar{},
|
||||
}
|
||||
|
||||
// GossipTopicMappings is a function to return the assigned data type
|
||||
// versioned by epoch.
|
||||
func GossipTopicMappings(topic string, epoch primitives.Epoch) proto.Message {
|
||||
if topic == BlockSubnetTopicFormat {
|
||||
if epoch >= params.BeaconConfig().DenebForkEpoch {
|
||||
return ðpb.SignedBeaconBlockDeneb{}
|
||||
}
|
||||
if epoch >= params.BeaconConfig().CapellaForkEpoch {
|
||||
return ðpb.SignedBeaconBlockCapella{}
|
||||
}
|
||||
@@ -68,6 +64,4 @@ func init() {
|
||||
GossipTypeMapping[reflect.TypeOf(ðpb.SignedBeaconBlockBellatrix{})] = BlockSubnetTopicFormat
|
||||
// Specially handle Capella objects
|
||||
GossipTypeMapping[reflect.TypeOf(ðpb.SignedBeaconBlockCapella{})] = BlockSubnetTopicFormat
|
||||
// Specially handle Deneb objects
|
||||
GossipTypeMapping[reflect.TypeOf(ðpb.SignedBeaconBlockDeneb{})] = BlockSubnetTopicFormat
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ type Broadcaster interface {
|
||||
Broadcast(context.Context, proto.Message) error
|
||||
BroadcastAttestation(ctx context.Context, subnet uint64, att *ethpb.Attestation) error
|
||||
BroadcastSyncCommitteeMessage(ctx context.Context, subnet uint64, sMsg *ethpb.SyncCommitteeMessage) error
|
||||
BroadcastBlob(ctx context.Context, subnet uint64, blobSidecar *ethpb.SignedBlobSidecar) error
|
||||
}
|
||||
|
||||
// SetStreamHandler configures p2p to handle streams of a certain topic ID.
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/hex"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
gethCrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
@@ -50,6 +51,32 @@ func TestPrivateKeyLoading(t *testing.T) {
|
||||
assert.DeepEqual(t, rawBytes, newRaw, "Private keys do not match")
|
||||
}
|
||||
|
||||
func TestPrivateKeyLoading_StaticPrivateKey(t *testing.T) {
|
||||
params.SetupTestConfigCleanup(t)
|
||||
tempDir := t.TempDir()
|
||||
|
||||
cfg := &Config{
|
||||
StaticPeerID: true,
|
||||
DataDir: tempDir,
|
||||
}
|
||||
pKey, err := privKey(cfg)
|
||||
require.NoError(t, err, "Could not apply option")
|
||||
|
||||
newPkey, err := ecdsaprysm.ConvertToInterfacePrivkey(pKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
retrievedKey, err := privKeyFromFile(path.Join(tempDir, keyPath))
|
||||
require.NoError(t, err)
|
||||
retrievedPKey, err := ecdsaprysm.ConvertToInterfacePrivkey(retrievedKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
rawBytes, err := retrievedPKey.Raw()
|
||||
require.NoError(t, err)
|
||||
newRaw, err := newPkey.Raw()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, rawBytes, newRaw, "Private keys do not match")
|
||||
}
|
||||
|
||||
func TestIPV6Support(t *testing.T) {
|
||||
params.SetupTestConfigCleanup(t)
|
||||
key, err := gethCrypto.GenerateKey()
|
||||
|
||||
@@ -57,17 +57,12 @@ func (s *Service) CanSubscribe(topic string) bool {
|
||||
log.WithError(err).Error("Could not determine Capella fork digest")
|
||||
return false
|
||||
}
|
||||
denebForkDigest, err := forks.ForkDigestFromEpoch(params.BeaconConfig().DenebForkEpoch, s.genesisValidatorsRoot)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not determine Capella fork digest")
|
||||
return false
|
||||
}
|
||||
|
||||
switch parts[2] {
|
||||
case fmt.Sprintf("%x", phase0ForkDigest):
|
||||
case fmt.Sprintf("%x", altairForkDigest):
|
||||
case fmt.Sprintf("%x", bellatrixForkDigest):
|
||||
case fmt.Sprintf("%x", capellaForkDigest):
|
||||
case fmt.Sprintf("%x", denebForkDigest):
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ func TestService_CanSubscribe(t *testing.T) {
|
||||
formatting := []interface{}{digest}
|
||||
|
||||
// Special case for attestation subnets which have a second formatting placeholder.
|
||||
if topic == AttestationSubnetTopicFormat || topic == SyncCommitteeSubnetTopicFormat || topic == BlobSubnetTopicFormat {
|
||||
if topic == AttestationSubnetTopicFormat || topic == SyncCommitteeSubnetTopicFormat {
|
||||
formatting = append(formatting, 0 /* some subnet ID */)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,9 +37,6 @@ const PingMessageName = "/ping"
|
||||
// MetadataMessageName specifies the name for the metadata message topic.
|
||||
const MetadataMessageName = "/metadata"
|
||||
|
||||
const BlobSidecarsByRootName = "/blob_sidecars_by_root"
|
||||
const BlobSidecarsByRangeName = "/blob_sidecars_by_range"
|
||||
|
||||
const (
|
||||
// V1 RPC Topics
|
||||
// RPCStatusTopicV1 defines the v1 topic for the status rpc method.
|
||||
@@ -55,15 +52,6 @@ const (
|
||||
// RPCMetaDataTopicV1 defines the v1 topic for the metadata rpc method.
|
||||
RPCMetaDataTopicV1 = protocolPrefix + MetadataMessageName + SchemaVersionV1
|
||||
|
||||
// RPCBlobSidecarsByRootTopicV1 is a topic for requesting blob sidecars by their block root. New in deneb.
|
||||
// /eth2/beacon_chain/req/blob_sidecars_by_root/1/
|
||||
RPCBlobSidecarsByRootTopicV1 = protocolPrefix + BlobSidecarsByRootName + SchemaVersionV1
|
||||
|
||||
// RPCBlobSidecarsByRangeTopicV1 is a topic for requesting blob sidecars
|
||||
// in the slot range [start_slot, start_slot + count), leading up to the current head block as selected by fork choice.
|
||||
// Protocol ID: /eth2/beacon_chain/req/blob_sidecars_by_range/1/ - New in deneb.
|
||||
RPCBlobSidecarsByRangeTopicV1 = protocolPrefix + BlobSidecarsByRangeName + SchemaVersionV1
|
||||
|
||||
// V2 RPC Topics
|
||||
// RPCBlocksByRangeTopicV2 defines v2 the topic for the blocks by range rpc method.
|
||||
RPCBlocksByRangeTopicV2 = protocolPrefix + BeaconBlocksByRangeMessageName + SchemaVersionV2
|
||||
@@ -95,10 +83,6 @@ var RPCTopicMappings = map[string]interface{}{
|
||||
// RPC Metadata Message
|
||||
RPCMetaDataTopicV1: new(interface{}),
|
||||
RPCMetaDataTopicV2: new(interface{}),
|
||||
// BlobSidecarsByRange v1 Message
|
||||
RPCBlobSidecarsByRangeTopicV1: new(pb.BlobSidecarsByRangeRequest),
|
||||
// BlobSidecarsByRoot v1 Message
|
||||
RPCBlobSidecarsByRootTopicV1: new(p2ptypes.BlobSidecarsByRootReq),
|
||||
}
|
||||
|
||||
// Maps all registered protocol prefixes.
|
||||
@@ -115,8 +99,6 @@ var messageMapping = map[string]bool{
|
||||
BeaconBlocksByRootsMessageName: true,
|
||||
PingMessageName: true,
|
||||
MetadataMessageName: true,
|
||||
BlobSidecarsByRangeName: true,
|
||||
BlobSidecarsByRootName: true,
|
||||
}
|
||||
|
||||
// Maps all the RPC messages which are to updated in altair.
|
||||
@@ -131,15 +113,6 @@ var versionMapping = map[string]bool{
|
||||
SchemaVersionV2: true,
|
||||
}
|
||||
|
||||
var PreAltairV1SchemaMapping = map[string]bool{
|
||||
StatusMessageName: true,
|
||||
GoodbyeMessageName: true,
|
||||
BeaconBlocksByRangeMessageName: true,
|
||||
BeaconBlocksByRootsMessageName: true,
|
||||
PingMessageName: true,
|
||||
MetadataMessageName: true,
|
||||
}
|
||||
|
||||
// VerifyTopicMapping verifies that the topic and its accompanying
|
||||
// message type is correct.
|
||||
func VerifyTopicMapping(topic string, msg interface{}) error {
|
||||
|
||||
@@ -125,6 +125,7 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
|
||||
s.ipLimiter = leakybucket.NewCollector(ipLimit, ipBurst, 30*time.Second, true /* deleteEmptyBuckets */)
|
||||
|
||||
opts := s.buildOptions(ipAddr, s.privKey)
|
||||
opts = append(opts, libp2p.ResourceManager(&network.NullResourceManager{}))
|
||||
h, err := libp2p.New(opts...)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to create p2p host")
|
||||
|
||||
@@ -138,11 +138,6 @@ func (_ *FakeP2P) BroadcastAttestation(_ context.Context, _ uint64, _ *ethpb.Att
|
||||
return nil
|
||||
}
|
||||
|
||||
// BroadcastBlob -- fake.
|
||||
func (p *FakeP2P) BroadcastBlob(ctx context.Context, subnet uint64, blobSidecar *ethpb.SignedBlobSidecar) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// BroadcastSyncCommitteeMessage -- fake.
|
||||
func (_ *FakeP2P) BroadcastSyncCommitteeMessage(_ context.Context, _ uint64, _ *ethpb.SyncCommitteeMessage) error {
|
||||
return nil
|
||||
|
||||
@@ -33,9 +33,3 @@ func (m *MockBroadcaster) BroadcastSyncCommitteeMessage(_ context.Context, _ uin
|
||||
m.BroadcastCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// BroadcastSyncCommitteeMessage records a broadcast occurred.
|
||||
func (m *MockBroadcaster) BroadcastBlob(ctx context.Context, subnet uint64, blob *ethpb.SignedBlobSidecar) error {
|
||||
m.BroadcastCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -170,11 +170,6 @@ func (p *TestP2P) BroadcastAttestation(_ context.Context, _ uint64, _ *ethpb.Att
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *TestP2P) BroadcastBlob(ctx context.Context, subnet uint64, blobSidecar *ethpb.SignedBlobSidecar) error {
|
||||
p.BroadcastCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// BroadcastSyncCommitteeMessage broadcasts a sync committee message.
|
||||
func (p *TestP2P) BroadcastSyncCommitteeMessage(_ context.Context, _ uint64, _ *ethpb.SyncCommitteeMessage) error {
|
||||
p.BroadcastCalled = true
|
||||
@@ -277,7 +272,7 @@ func (p *TestP2P) AddConnectionHandler(f, _ func(ctx context.Context, id peer.ID
|
||||
|
||||
p.peers.SetConnectionState(conn.RemotePeer(), peers.PeerConnecting)
|
||||
if err := f(ctx, conn.RemotePeer()); err != nil {
|
||||
logrus.WithError(err).Error("Could not send succesful hello rpc request")
|
||||
logrus.WithError(err).Error("Could not send successful hello rpc request")
|
||||
if err := p.Disconnect(conn.RemotePeer()); err != nil {
|
||||
logrus.WithError(err).Errorf("Unable to close peer %s", conn.RemotePeer())
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@ const (
|
||||
GossipContributionAndProofMessage = "sync_committee_contribution_and_proof"
|
||||
// GossipBlsToExecutionChangeMessage is the name for the bls to execution change message type.
|
||||
GossipBlsToExecutionChangeMessage = "bls_to_execution_change"
|
||||
// GossipBlobSidecarMessage is the name for the blob sidecar message type.
|
||||
GossipBlobSidecarMessage = "blob_sidecar"
|
||||
|
||||
// Topic Formats
|
||||
//
|
||||
@@ -51,6 +49,4 @@ const (
|
||||
SyncContributionAndProofSubnetTopicFormat = GossipProtocolAndDigest + GossipContributionAndProofMessage
|
||||
// BlsToExecutionChangeSubnetTopicFormat is the topic format for the bls to execution change subnet.
|
||||
BlsToExecutionChangeSubnetTopicFormat = GossipProtocolAndDigest + GossipBlsToExecutionChangeMessage
|
||||
// BlobSubnetTopicFormat is the topic format for the blob subnet.
|
||||
BlobSubnetTopicFormat = GossipProtocolAndDigest + GossipBlobSidecarMessage + "_%d"
|
||||
)
|
||||
|
||||
@@ -53,11 +53,6 @@ func InitializeDataMaps() {
|
||||
ðpb.SignedBeaconBlockCapella{Block: ðpb.BeaconBlockCapella{Body: ðpb.BeaconBlockBodyCapella{}}},
|
||||
)
|
||||
},
|
||||
bytesutil.ToBytes4(params.BeaconConfig().DenebForkVersion): func() (interfaces.ReadOnlySignedBeaconBlock, error) {
|
||||
return blocks.NewSignedBeaconBlock(
|
||||
ðpb.SignedBeaconBlockDeneb{Block: ðpb.BeaconBlockDeneb{Body: ðpb.BeaconBlockBodyDeneb{}}},
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
// Reset our metadata map.
|
||||
@@ -74,8 +69,5 @@ func InitializeDataMaps() {
|
||||
bytesutil.ToBytes4(params.BeaconConfig().CapellaForkVersion): func() metadata.Metadata {
|
||||
return wrapper.WrappedMetadataV1(ðpb.MetaDataV1{})
|
||||
},
|
||||
bytesutil.ToBytes4(params.BeaconConfig().DenebForkVersion): func() metadata.Metadata {
|
||||
return wrapper.WrappedMetadataV1(ðpb.MetaDataV1{})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,5 +12,4 @@ var (
|
||||
ErrRateLimited = errors.New("rate limited")
|
||||
ErrIODeadline = errors.New("i/o deadline exceeded")
|
||||
ErrInvalidRequest = errors.New("invalid range, step or count")
|
||||
ErrBlobLTMinRequest = errors.New("blob slot < minimum_request_epoch")
|
||||
)
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
ssz "github.com/prysmaticlabs/fastssz"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
const rootLength = 32
|
||||
@@ -32,7 +31,6 @@ func (b *SSZBytes) HashTreeRootWith(hh *ssz.Hasher) error {
|
||||
|
||||
// BeaconBlockByRootsReq specifies the block by roots request type.
|
||||
type BeaconBlockByRootsReq [][rootLength]byte
|
||||
type BlobSidecarsByRootReq []*eth.BlobIdentifier
|
||||
|
||||
// MarshalSSZTo marshals the block by roots request with the provided byte slice.
|
||||
func (r *BeaconBlockByRootsReq) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
|
||||
@@ -49,23 +49,43 @@ func privKey(cfg *Config) (*ecdsa.PrivateKey, error) {
|
||||
defaultKeyPath := path.Join(cfg.DataDir, keyPath)
|
||||
privateKeyPath := cfg.PrivateKey
|
||||
|
||||
// PrivateKey cli flag takes highest precedence.
|
||||
if privateKeyPath != "" {
|
||||
return privKeyFromFile(cfg.PrivateKey)
|
||||
}
|
||||
|
||||
_, err := os.Stat(defaultKeyPath)
|
||||
defaultKeysExist := !os.IsNotExist(err)
|
||||
if err != nil && defaultKeysExist {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if privateKeyPath == "" && !defaultKeysExist {
|
||||
priv, _, err := crypto.GenerateSecp256k1Key(rand.Reader)
|
||||
// Default keys have the next highest precedence, if they exist.
|
||||
if defaultKeysExist {
|
||||
return privKeyFromFile(defaultKeyPath)
|
||||
}
|
||||
// There are no keys on the filesystem, so we need to generate one.
|
||||
priv, _, err := crypto.GenerateSecp256k1Key(rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If the StaticPeerID flag is set, save the generated key as the default
|
||||
// key, so that it will be used by default on the next node start.
|
||||
if cfg.StaticPeerID {
|
||||
rawbytes, err := priv.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ecdsaprysm.ConvertFromInterfacePrivKey(priv)
|
||||
dst := make([]byte, hex.EncodedLen(len(rawbytes)))
|
||||
hex.Encode(dst, rawbytes)
|
||||
if err := file.WriteFile(defaultKeyPath, dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Infof("Wrote network key to file")
|
||||
// Read the key from the defaultKeyPath file just written
|
||||
// for the strongest guarantee that the next start will be the same as this one.
|
||||
return privKeyFromFile(defaultKeyPath)
|
||||
}
|
||||
if defaultKeysExist && privateKeyPath == "" {
|
||||
privateKeyPath = defaultKeyPath
|
||||
}
|
||||
return privKeyFromFile(privateKeyPath)
|
||||
return ecdsaprysm.ConvertFromInterfacePrivKey(priv)
|
||||
}
|
||||
|
||||
// Retrieves a p2p networking private key from a file path.
|
||||
|
||||
@@ -28,12 +28,13 @@ go_library(
|
||||
"//beacon-chain/rpc/eth/debug:go_default_library",
|
||||
"//beacon-chain/rpc/eth/events:go_default_library",
|
||||
"//beacon-chain/rpc/eth/node:go_default_library",
|
||||
"//beacon-chain/rpc/eth/rewards:go_default_library",
|
||||
"//beacon-chain/rpc/eth/validator:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/beacon:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/debug:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/node:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
|
||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||
"//beacon-chain/slasher:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
@@ -43,6 +44,7 @@ go_library(
|
||||
"//monitoring/tracing:go_default_library",
|
||||
"//proto/eth/service:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_gorilla_mux//:go_default_library",
|
||||
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library",
|
||||
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
|
||||
"@com_github_grpc_ecosystem_go_grpc_middleware//tracing/opentracing:go_default_library",
|
||||
@@ -68,6 +70,7 @@ go_test(
|
||||
"//beacon-chain/sync/initial-sync/testing:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_gorilla_mux//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
],
|
||||
|
||||
@@ -503,13 +503,6 @@ type capellaBlockResponseJson struct {
|
||||
Finalized bool `json:"finalized"`
|
||||
}
|
||||
|
||||
type denebBlockResponseJson struct {
|
||||
Version string `json:"version"`
|
||||
Data *SignedBeaconBlockDenebContainerJson `json:"data"`
|
||||
ExecutionOptimistic bool `json:"execution_optimistic"`
|
||||
Finalized bool `json:"finalized"`
|
||||
}
|
||||
|
||||
type bellatrixBlindedBlockResponseJson struct {
|
||||
Version string `json:"version" enum:"true"`
|
||||
Data *SignedBlindedBeaconBlockBellatrixContainerJson `json:"data"`
|
||||
@@ -524,12 +517,6 @@ type capellaBlindedBlockResponseJson struct {
|
||||
Finalized bool `json:"finalized"`
|
||||
}
|
||||
|
||||
type denebBlindedBlockResponseJson struct {
|
||||
Version string `json:"version"`
|
||||
Data *SignedBlindedBeaconBlockDenebContainerJson `json:"data"`
|
||||
ExecutionOptimistic bool `json:"execution_optimistic"`
|
||||
}
|
||||
|
||||
func serializeV2Block(response interface{}) (apimiddleware.RunDefault, []byte, apimiddleware.ErrorJson) {
|
||||
respContainer, ok := response.(*BlockV2ResponseJson)
|
||||
if !ok {
|
||||
@@ -578,16 +565,6 @@ func serializeV2Block(response interface{}) (apimiddleware.RunDefault, []byte, a
|
||||
ExecutionOptimistic: respContainer.ExecutionOptimistic,
|
||||
Finalized: respContainer.Finalized,
|
||||
}
|
||||
case strings.EqualFold(respContainer.Version, strings.ToLower(ethpbv2.Version_Deneb.String())):
|
||||
actualRespContainer = &denebBlockResponseJson{
|
||||
Version: respContainer.Version,
|
||||
Data: &SignedBeaconBlockDenebContainerJson{
|
||||
Message: respContainer.Data.DenebBlock,
|
||||
Signature: respContainer.Data.Signature,
|
||||
},
|
||||
ExecutionOptimistic: respContainer.ExecutionOptimistic,
|
||||
Finalized: respContainer.Finalized,
|
||||
}
|
||||
default:
|
||||
return false, nil, apimiddleware.InternalServerError(fmt.Errorf("unsupported block version '%s'", respContainer.Version))
|
||||
}
|
||||
@@ -647,15 +624,6 @@ func serializeBlindedBlock(response interface{}) (apimiddleware.RunDefault, []by
|
||||
ExecutionOptimistic: respContainer.ExecutionOptimistic,
|
||||
Finalized: respContainer.Finalized,
|
||||
}
|
||||
case strings.EqualFold(respContainer.Version, strings.ToLower(ethpbv2.Version_Deneb.String())):
|
||||
actualRespContainer = &denebBlindedBlockResponseJson{
|
||||
Version: respContainer.Version,
|
||||
Data: &SignedBlindedBeaconBlockDenebContainerJson{
|
||||
Message: respContainer.Data.DenebBlock,
|
||||
Signature: respContainer.Data.Signature,
|
||||
},
|
||||
ExecutionOptimistic: respContainer.ExecutionOptimistic,
|
||||
}
|
||||
default:
|
||||
return false, nil, apimiddleware.InternalServerError(fmt.Errorf("unsupported block version '%s'", respContainer.Version))
|
||||
}
|
||||
@@ -687,11 +655,6 @@ type capellaStateResponseJson struct {
|
||||
Data *BeaconStateCapellaJson `json:"data"`
|
||||
}
|
||||
|
||||
type denebStateResponseJson struct {
|
||||
Version string `json:"version"`
|
||||
Data *BeaconStateDenebJson `json:"data"`
|
||||
}
|
||||
|
||||
func serializeV2State(response interface{}) (apimiddleware.RunDefault, []byte, apimiddleware.ErrorJson) {
|
||||
respContainer, ok := response.(*BeaconStateV2ResponseJson)
|
||||
if !ok {
|
||||
@@ -720,11 +683,6 @@ func serializeV2State(response interface{}) (apimiddleware.RunDefault, []byte, a
|
||||
Version: respContainer.Version,
|
||||
Data: respContainer.Data.CapellaState,
|
||||
}
|
||||
case strings.EqualFold(respContainer.Version, strings.ToLower(ethpbv2.Version_Deneb.String())):
|
||||
actualRespContainer = &denebStateResponseJson{
|
||||
Version: respContainer.Version,
|
||||
Data: respContainer.Data.DenebState,
|
||||
}
|
||||
default:
|
||||
return false, nil, apimiddleware.InternalServerError(fmt.Errorf("unsupported state version '%s'", respContainer.Version))
|
||||
}
|
||||
|
||||
@@ -395,7 +395,6 @@ type SignedBeaconBlockContainerV2Json struct {
|
||||
AltairBlock *BeaconBlockAltairJson `json:"altair_block"`
|
||||
BellatrixBlock *BeaconBlockBellatrixJson `json:"bellatrix_block"`
|
||||
CapellaBlock *BeaconBlockCapellaJson `json:"capella_block"`
|
||||
DenebBlock *BeaconBlockDenebJson `json:"deneb_block"`
|
||||
Signature string `json:"signature" hex:"true"`
|
||||
}
|
||||
|
||||
@@ -404,7 +403,6 @@ type SignedBlindedBeaconBlockContainerJson struct {
|
||||
AltairBlock *BeaconBlockAltairJson `json:"altair_block"`
|
||||
BellatrixBlock *BlindedBeaconBlockBellatrixJson `json:"bellatrix_block"`
|
||||
CapellaBlock *BlindedBeaconBlockCapellaJson `json:"capella_block"`
|
||||
DenebBlock *BlindedBeaconBlockDenebJson `json:"deneb_block"`
|
||||
Signature string `json:"signature" hex:"true"`
|
||||
}
|
||||
|
||||
@@ -413,7 +411,6 @@ type BeaconBlockContainerV2Json struct {
|
||||
AltairBlock *BeaconBlockAltairJson `json:"altair_block"`
|
||||
BellatrixBlock *BeaconBlockBellatrixJson `json:"bellatrix_block"`
|
||||
CapellaBlock *BeaconBlockCapellaJson `json:"capella_block"`
|
||||
DenebBlock *BeaconBlockDenebJson `json:"deneb_block"`
|
||||
}
|
||||
|
||||
type BlindedBeaconBlockContainerJson struct {
|
||||
@@ -421,7 +418,6 @@ type BlindedBeaconBlockContainerJson struct {
|
||||
AltairBlock *BeaconBlockAltairJson `json:"altair_block"`
|
||||
BellatrixBlock *BlindedBeaconBlockBellatrixJson `json:"bellatrix_block"`
|
||||
CapellaBlock *BlindedBeaconBlockCapellaJson `json:"capella_block"`
|
||||
DenebBlock *BlindedBeaconBlockDenebJson `json:"deneb_block"`
|
||||
}
|
||||
|
||||
type SignedBeaconBlockAltairContainerJson struct {
|
||||
@@ -439,11 +435,6 @@ type SignedBeaconBlockCapellaContainerJson struct {
|
||||
Signature string `json:"signature" hex:"true"`
|
||||
}
|
||||
|
||||
type SignedBeaconBlockDenebContainerJson struct {
|
||||
Message *BeaconBlockDenebJson `json:"message"`
|
||||
Signature string `json:"signature" hex:"true"`
|
||||
}
|
||||
|
||||
type SignedBlindedBeaconBlockBellatrixContainerJson struct {
|
||||
Message *BlindedBeaconBlockBellatrixJson `json:"message"`
|
||||
Signature string `json:"signature" hex:"true"`
|
||||
@@ -454,11 +445,6 @@ type SignedBlindedBeaconBlockCapellaContainerJson struct {
|
||||
Signature string `json:"signature" hex:"true"`
|
||||
}
|
||||
|
||||
type SignedBlindedBeaconBlockDenebContainerJson struct {
|
||||
Message *BlindedBeaconBlockDenebJson `json:"message"`
|
||||
Signature string `json:"signature" hex:"true"`
|
||||
}
|
||||
|
||||
type BeaconBlockAltairJson struct {
|
||||
Slot string `json:"slot"`
|
||||
ProposerIndex string `json:"proposer_index"`
|
||||
@@ -483,14 +469,6 @@ type BeaconBlockCapellaJson struct {
|
||||
Body *BeaconBlockBodyCapellaJson `json:"body"`
|
||||
}
|
||||
|
||||
type BeaconBlockDenebJson struct {
|
||||
Slot string `json:"slot"`
|
||||
ProposerIndex string `json:"proposer_index"`
|
||||
ParentRoot string `json:"parent_root" hex:"true"`
|
||||
StateRoot string `json:"state_root" hex:"true"`
|
||||
Body *BeaconBlockBodyDenebJson `json:"body"`
|
||||
}
|
||||
|
||||
type BlindedBeaconBlockBellatrixJson struct {
|
||||
Slot string `json:"slot"`
|
||||
ProposerIndex string `json:"proposer_index"`
|
||||
@@ -507,14 +485,6 @@ type BlindedBeaconBlockCapellaJson struct {
|
||||
Body *BlindedBeaconBlockBodyCapellaJson `json:"body"`
|
||||
}
|
||||
|
||||
type BlindedBeaconBlockDenebJson struct {
|
||||
Slot string `json:"slot"`
|
||||
ProposerIndex string `json:"proposer_index"`
|
||||
ParentRoot string `json:"parent_root" hex:"true"`
|
||||
StateRoot string `json:"state_root" hex:"true"`
|
||||
Body *BlindedBeaconBlockBodyDenebJson `json:"body"`
|
||||
}
|
||||
|
||||
type BeaconBlockBodyAltairJson struct {
|
||||
RandaoReveal string `json:"randao_reveal" hex:"true"`
|
||||
Eth1Data *Eth1DataJson `json:"eth1_data"`
|
||||
@@ -554,21 +524,6 @@ type BeaconBlockBodyCapellaJson struct {
|
||||
BLSToExecutionChanges []*SignedBLSToExecutionChangeJson `json:"bls_to_execution_changes"`
|
||||
}
|
||||
|
||||
type BeaconBlockBodyDenebJson struct {
|
||||
RandaoReveal string `json:"randao_reveal" hex:"true"`
|
||||
Eth1Data *Eth1DataJson `json:"eth1_data"`
|
||||
Graffiti string `json:"graffiti" hex:"true"`
|
||||
ProposerSlashings []*ProposerSlashingJson `json:"proposer_slashings"`
|
||||
AttesterSlashings []*AttesterSlashingJson `json:"attester_slashings"`
|
||||
Attestations []*AttestationJson `json:"attestations"`
|
||||
Deposits []*DepositJson `json:"deposits"`
|
||||
VoluntaryExits []*SignedVoluntaryExitJson `json:"voluntary_exits"`
|
||||
SyncAggregate *SyncAggregateJson `json:"sync_aggregate"`
|
||||
ExecutionPayload *ExecutionPayloadDenebJson `json:"execution_payload"`
|
||||
BLSToExecutionChanges []*SignedBLSToExecutionChangeJson `json:"bls_to_execution_changes"`
|
||||
BlobKzgCommitments []string `json:"blob_kzg_commitments" hex:"true"`
|
||||
}
|
||||
|
||||
type BlindedBeaconBlockBodyBellatrixJson struct {
|
||||
RandaoReveal string `json:"randao_reveal" hex:"true"`
|
||||
Eth1Data *Eth1DataJson `json:"eth1_data"`
|
||||
@@ -596,21 +551,6 @@ type BlindedBeaconBlockBodyCapellaJson struct {
|
||||
BLSToExecutionChanges []*SignedBLSToExecutionChangeJson `json:"bls_to_execution_changes"`
|
||||
}
|
||||
|
||||
type BlindedBeaconBlockBodyDenebJson struct {
|
||||
RandaoReveal string `json:"randao_reveal" hex:"true"`
|
||||
Eth1Data *Eth1DataJson `json:"eth1_data"`
|
||||
Graffiti string `json:"graffiti" hex:"true"`
|
||||
ProposerSlashings []*ProposerSlashingJson `json:"proposer_slashings"`
|
||||
AttesterSlashings []*AttesterSlashingJson `json:"attester_slashings"`
|
||||
Attestations []*AttestationJson `json:"attestations"`
|
||||
Deposits []*DepositJson `json:"deposits"`
|
||||
VoluntaryExits []*SignedVoluntaryExitJson `json:"voluntary_exits"`
|
||||
SyncAggregate *SyncAggregateJson `json:"sync_aggregate"`
|
||||
ExecutionPayloadHeader *ExecutionPayloadHeaderDenebJson `json:"execution_payload_header"`
|
||||
BLSToExecutionChanges []*SignedBLSToExecutionChangeJson `json:"bls_to_execution_changes"`
|
||||
BlobKzgCommitments []string `json:"blob_kzg_commitments" hex:"true"`
|
||||
}
|
||||
|
||||
type ExecutionPayloadJson struct {
|
||||
ParentHash string `json:"parent_hash" hex:"true"`
|
||||
FeeRecipient string `json:"fee_recipient" hex:"true"`
|
||||
@@ -646,25 +586,6 @@ type ExecutionPayloadCapellaJson struct {
|
||||
Withdrawals []*WithdrawalJson `json:"withdrawals"`
|
||||
}
|
||||
|
||||
type ExecutionPayloadDenebJson struct {
|
||||
ParentHash string `json:"parent_hash" hex:"true"`
|
||||
FeeRecipient string `json:"fee_recipient" hex:"true"`
|
||||
StateRoot string `json:"state_root" hex:"true"`
|
||||
ReceiptsRoot string `json:"receipts_root" hex:"true"`
|
||||
LogsBloom string `json:"logs_bloom" hex:"true"`
|
||||
PrevRandao string `json:"prev_randao" hex:"true"`
|
||||
BlockNumber string `json:"block_number"`
|
||||
GasLimit string `json:"gas_limit"`
|
||||
GasUsed string `json:"gas_used"`
|
||||
TimeStamp string `json:"timestamp"`
|
||||
ExtraData string `json:"extra_data" hex:"true"`
|
||||
BaseFeePerGas string `json:"base_fee_per_gas" uint256:"true"`
|
||||
ExcessDataGas string `json:"excess_data_gas" uint256:"true"`
|
||||
BlockHash string `json:"block_hash" hex:"true"`
|
||||
Transactions []string `json:"transactions" hex:"true"`
|
||||
Withdrawals []*WithdrawalJson `json:"withdrawals"`
|
||||
}
|
||||
|
||||
type ExecutionPayloadHeaderJson struct {
|
||||
ParentHash string `json:"parent_hash" hex:"true"`
|
||||
FeeRecipient string `json:"fee_recipient" hex:"true"`
|
||||
@@ -700,25 +621,6 @@ type ExecutionPayloadHeaderCapellaJson struct {
|
||||
WithdrawalsRoot string `json:"withdrawals_root" hex:"true"`
|
||||
}
|
||||
|
||||
type ExecutionPayloadHeaderDenebJson struct {
|
||||
ParentHash string `json:"parent_hash" hex:"true"`
|
||||
FeeRecipient string `json:"fee_recipient" hex:"true"`
|
||||
StateRoot string `json:"state_root" hex:"true"`
|
||||
ReceiptsRoot string `json:"receipts_root" hex:"true"`
|
||||
LogsBloom string `json:"logs_bloom" hex:"true"`
|
||||
PrevRandao string `json:"prev_randao" hex:"true"`
|
||||
BlockNumber string `json:"block_number"`
|
||||
GasLimit string `json:"gas_limit"`
|
||||
GasUsed string `json:"gas_used"`
|
||||
TimeStamp string `json:"timestamp"`
|
||||
ExtraData string `json:"extra_data" hex:"true"`
|
||||
BaseFeePerGas string `json:"base_fee_per_gas" uint256:"true"`
|
||||
ExcessDataGas string `json:"excess_data_gas" uint256:"true"`
|
||||
BlockHash string `json:"block_hash" hex:"true"`
|
||||
TransactionsRoot string `json:"transactions_root" hex:"true"`
|
||||
WithdrawalsRoot string `json:"withdrawals_root" hex:"true"`
|
||||
}
|
||||
|
||||
type SyncAggregateJson struct {
|
||||
SyncCommitteeBits string `json:"sync_committee_bits" hex:"true"`
|
||||
SyncCommitteeSignature string `json:"sync_committee_signature" hex:"true"`
|
||||
@@ -975,42 +877,11 @@ type BeaconStateCapellaJson struct {
|
||||
HistoricalSummaries []*HistoricalSummaryJson `json:"historical_summaries"`
|
||||
}
|
||||
|
||||
type BeaconStateDenebJson struct {
|
||||
GenesisTime string `json:"genesis_time"`
|
||||
GenesisValidatorsRoot string `json:"genesis_validators_root" hex:"true"`
|
||||
Slot string `json:"slot"`
|
||||
Fork *ForkJson `json:"fork"`
|
||||
LatestBlockHeader *BeaconBlockHeaderJson `json:"latest_block_header"`
|
||||
BlockRoots []string `json:"block_roots" hex:"true"`
|
||||
StateRoots []string `json:"state_roots" hex:"true"`
|
||||
HistoricalRoots []string `json:"historical_roots" hex:"true"`
|
||||
Eth1Data *Eth1DataJson `json:"eth1_data"`
|
||||
Eth1DataVotes []*Eth1DataJson `json:"eth1_data_votes"`
|
||||
Eth1DepositIndex string `json:"eth1_deposit_index"`
|
||||
Validators []*ValidatorJson `json:"validators"`
|
||||
Balances []string `json:"balances"`
|
||||
RandaoMixes []string `json:"randao_mixes" hex:"true"`
|
||||
Slashings []string `json:"slashings"`
|
||||
PreviousEpochParticipation EpochParticipation `json:"previous_epoch_participation"`
|
||||
CurrentEpochParticipation EpochParticipation `json:"current_epoch_participation"`
|
||||
JustificationBits string `json:"justification_bits" hex:"true"`
|
||||
PreviousJustifiedCheckpoint *CheckpointJson `json:"previous_justified_checkpoint"`
|
||||
CurrentJustifiedCheckpoint *CheckpointJson `json:"current_justified_checkpoint"`
|
||||
FinalizedCheckpoint *CheckpointJson `json:"finalized_checkpoint"`
|
||||
InactivityScores []string `json:"inactivity_scores"`
|
||||
CurrentSyncCommittee *SyncCommitteeJson `json:"current_sync_committee"`
|
||||
NextSyncCommittee *SyncCommitteeJson `json:"next_sync_committee"`
|
||||
LatestExecutionPayloadHeader *ExecutionPayloadHeaderDenebJson `json:"latest_execution_payload_header"`
|
||||
NextWithdrawalIndex string `json:"next_withdrawal_index"`
|
||||
NextWithdrawalValidatorIndex string `json:"next_withdrawal_validator_index"`
|
||||
}
|
||||
|
||||
type BeaconStateContainerV2Json struct {
|
||||
Phase0State *BeaconStateJson `json:"phase0_state"`
|
||||
AltairState *BeaconStateAltairJson `json:"altair_state"`
|
||||
BellatrixState *BeaconStateBellatrixJson `json:"bellatrix_state"`
|
||||
CapellaState *BeaconStateCapellaJson `json:"capella_state"`
|
||||
DenebState *BeaconStateDenebJson `json:"deneb_state"`
|
||||
}
|
||||
|
||||
type ForkJson struct {
|
||||
|
||||
@@ -34,8 +34,8 @@ go_library(
|
||||
"//beacon-chain/operations/voluntaryexits:go_default_library",
|
||||
"//beacon-chain/p2p:go_default_library",
|
||||
"//beacon-chain/rpc/eth/helpers:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
|
||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
@@ -92,7 +92,6 @@ go_test(
|
||||
"//beacon-chain/core/transition:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/db/testing:go_default_library",
|
||||
"//beacon-chain/execution/testing:go_default_library",
|
||||
"//beacon-chain/operations/attestations:go_default_library",
|
||||
"//beacon-chain/operations/blstoexec:go_default_library",
|
||||
"//beacon-chain/operations/blstoexec/mock:go_default_library",
|
||||
@@ -101,12 +100,11 @@ go_test(
|
||||
"//beacon-chain/operations/voluntaryexits/mock:go_default_library",
|
||||
"//beacon-chain/p2p/testing:go_default_library",
|
||||
"//beacon-chain/rpc/eth/helpers:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
|
||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||
"//beacon-chain/rpc/testutil:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
|
||||
@@ -25,7 +25,7 @@ func (bs *Server) GetBlindedBlock(ctx context.Context, req *ethpbv1.BlockRequest
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetBlindedBlock")
|
||||
defer span.End()
|
||||
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
blk, err := bs.Blocker.Block(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -80,7 +80,7 @@ func (bs *Server) GetBlindedBlockSSZ(ctx context.Context, req *ethpbv1.BlockRequ
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetBlindedBlockSSZ")
|
||||
defer span.End()
|
||||
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
blk, err := bs.Blocker.Block(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,17 +2,15 @@ package beacon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
||||
builderTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/builder/testing"
|
||||
dbTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
|
||||
executionTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/execution/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/synccommittee"
|
||||
mockp2p "github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
@@ -21,7 +19,6 @@ import (
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
|
||||
"github.com/prysmaticlabs/prysm/v4/proto/migration"
|
||||
ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
||||
@@ -29,774 +26,284 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_GetBlindedBlock(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("Phase 0", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
genBlk, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
|
||||
canonicalRoots := make(map[[32]byte]bool)
|
||||
for _, bContr := range blkContainers {
|
||||
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
|
||||
}
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
nextSlot := headBlock.GetPhase0Block().Block.Slot + 1
|
||||
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block)
|
||||
b := util.NewBeaconBlock()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: wsb,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
CanonicalRoots: canonicalRoots,
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
HeadFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
FinalizationFetcher: &mock.ChainService{},
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
}
|
||||
|
||||
root, err := genBlk.Block.HashTreeRoot()
|
||||
expected, err := migration.V1Alpha1ToV1SignedBlock(b)
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
blockID []byte
|
||||
want *ethpbalpha.SignedBeaconBlock
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "slot",
|
||||
blockID: []byte("30"),
|
||||
want: blkContainers[30].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
|
||||
},
|
||||
{
|
||||
name: "bad formatting",
|
||||
blockID: []byte("3bad0"),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "canonical",
|
||||
blockID: []byte("30"),
|
||||
want: blkContainers[30].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
|
||||
},
|
||||
{
|
||||
name: "non canonical",
|
||||
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "head",
|
||||
blockID: []byte("head"),
|
||||
want: headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
|
||||
},
|
||||
{
|
||||
name: "finalized",
|
||||
blockID: []byte("finalized"),
|
||||
want: blkContainers[64].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
|
||||
},
|
||||
{
|
||||
name: "genesis",
|
||||
blockID: []byte("genesis"),
|
||||
want: genBlk,
|
||||
},
|
||||
{
|
||||
name: "genesis root",
|
||||
blockID: root[:],
|
||||
want: genBlk,
|
||||
},
|
||||
{
|
||||
name: "root",
|
||||
blockID: blkContainers[20].BlockRoot,
|
||||
want: blkContainers[20].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
|
||||
},
|
||||
{
|
||||
name: "non-existent root",
|
||||
blockID: bytesutil.PadTo([]byte("hi there"), 32),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no block",
|
||||
blockID: []byte("105"),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
blk, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: tt.blockID,
|
||||
})
|
||||
if tt.wantErr {
|
||||
require.NotEqual(t, err, nil)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
v1Block, err := migration.V1Alpha1ToV1SignedBlock(tt.want)
|
||||
require.NoError(t, err)
|
||||
|
||||
phase0Block, ok := blk.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_Phase0Block)
|
||||
require.Equal(t, true, ok)
|
||||
if !reflect.DeepEqual(phase0Block.Phase0Block, v1Block.Block) {
|
||||
t.Error("Expected blocks to equal")
|
||||
}
|
||||
assert.Equal(t, ethpbv2.Version_PHASE0, blk.Version)
|
||||
})
|
||||
}
|
||||
resp, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
phase0Block, ok := resp.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_Phase0Block)
|
||||
require.Equal(t, true, ok)
|
||||
assert.DeepEqual(t, expected.Block, phase0Block.Phase0Block)
|
||||
assert.Equal(t, ethpbv2.Version_PHASE0, resp.Version)
|
||||
})
|
||||
|
||||
t.Run("Altair", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
genBlk, blkContainers := fillDBTestBlocksAltair(ctx, t, beaconDB)
|
||||
canonicalRoots := make(map[[32]byte]bool)
|
||||
for _, bContr := range blkContainers {
|
||||
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
|
||||
}
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
nextSlot := headBlock.GetAltairBlock().Block.Slot + 1
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetAltairBlock())
|
||||
b := util.NewBeaconBlockAltair()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
CanonicalRoots: canonicalRoots,
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
HeadFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
FinalizationFetcher: &mock.ChainService{},
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
}
|
||||
|
||||
root, err := genBlk.Block.HashTreeRoot()
|
||||
expected, err := migration.V1Alpha1BeaconBlockAltairToV2(b.Block)
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
blockID []byte
|
||||
want *ethpbalpha.SignedBeaconBlockAltair
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "slot",
|
||||
blockID: []byte("30"),
|
||||
want: blkContainers[30].GetAltairBlock(),
|
||||
},
|
||||
{
|
||||
name: "bad formatting",
|
||||
blockID: []byte("3bad0"),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "canonical",
|
||||
blockID: []byte("30"),
|
||||
want: blkContainers[30].GetAltairBlock(),
|
||||
},
|
||||
{
|
||||
name: "non canonical",
|
||||
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "head",
|
||||
blockID: []byte("head"),
|
||||
want: headBlock.GetAltairBlock(),
|
||||
},
|
||||
{
|
||||
name: "finalized",
|
||||
blockID: []byte("finalized"),
|
||||
want: blkContainers[64].GetAltairBlock(),
|
||||
},
|
||||
{
|
||||
name: "genesis",
|
||||
blockID: []byte("genesis"),
|
||||
want: genBlk,
|
||||
},
|
||||
{
|
||||
name: "genesis root",
|
||||
blockID: root[:],
|
||||
want: genBlk,
|
||||
},
|
||||
{
|
||||
name: "root",
|
||||
blockID: blkContainers[20].BlockRoot,
|
||||
want: blkContainers[20].GetAltairBlock(),
|
||||
},
|
||||
{
|
||||
name: "non-existent root",
|
||||
blockID: bytesutil.PadTo([]byte("hi there"), 32),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no block",
|
||||
blockID: []byte("105"),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
blk, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: tt.blockID,
|
||||
})
|
||||
if tt.wantErr {
|
||||
require.NotEqual(t, err, nil)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
v2Block, err := migration.V1Alpha1BeaconBlockAltairToV2(tt.want.Block)
|
||||
require.NoError(t, err)
|
||||
|
||||
altairBlock, ok := blk.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_AltairBlock)
|
||||
require.Equal(t, true, ok)
|
||||
if !reflect.DeepEqual(altairBlock.AltairBlock, v2Block) {
|
||||
t.Error("Expected blocks to equal")
|
||||
}
|
||||
assert.Equal(t, ethpbv2.Version_ALTAIR, blk.Version)
|
||||
})
|
||||
}
|
||||
resp, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
altairBlock, ok := resp.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_AltairBlock)
|
||||
require.Equal(t, true, ok)
|
||||
assert.DeepEqual(t, expected, altairBlock.AltairBlock)
|
||||
assert.Equal(t, ethpbv2.Version_ALTAIR, resp.Version)
|
||||
})
|
||||
|
||||
t.Run("Bellatrix", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
genBlk, blkContainers := fillDBTestBlocksBellatrixBlinded(ctx, t, beaconDB)
|
||||
canonicalRoots := make(map[[32]byte]bool)
|
||||
for _, bContr := range blkContainers {
|
||||
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
|
||||
}
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
nextSlot := headBlock.GetBlindedBellatrixBlock().Block.Slot + 1
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBlindedBellatrixBlock())
|
||||
b := util.NewBlindedBeaconBlockBellatrix()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
CanonicalRoots: canonicalRoots,
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
|
||||
mockChainService := &mock.ChainService{}
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
HeadFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
ExecutionPayloadReconstructor: &executionTest.EngineClient{
|
||||
ExecutionPayloadByBlockHash: map[[32]byte]*enginev1.ExecutionPayload{},
|
||||
},
|
||||
FinalizationFetcher: mockChainService,
|
||||
}
|
||||
|
||||
root, err := genBlk.Block.HashTreeRoot()
|
||||
expected, err := migration.V1Alpha1BeaconBlockBlindedBellatrixToV2Blinded(b.Block)
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
blockID []byte
|
||||
want *ethpbalpha.SignedBlindedBeaconBlockBellatrix
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "slot",
|
||||
blockID: []byte("30"),
|
||||
want: blkContainers[30].GetBlindedBellatrixBlock(),
|
||||
},
|
||||
{
|
||||
name: "bad formatting",
|
||||
blockID: []byte("3bad0"),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "canonical",
|
||||
blockID: []byte("30"),
|
||||
want: blkContainers[30].GetBlindedBellatrixBlock(),
|
||||
},
|
||||
{
|
||||
name: "non canonical",
|
||||
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "head",
|
||||
blockID: []byte("head"),
|
||||
want: headBlock.GetBlindedBellatrixBlock(),
|
||||
},
|
||||
{
|
||||
name: "finalized",
|
||||
blockID: []byte("finalized"),
|
||||
want: blkContainers[64].GetBlindedBellatrixBlock(),
|
||||
},
|
||||
{
|
||||
name: "genesis",
|
||||
blockID: []byte("genesis"),
|
||||
want: genBlk,
|
||||
},
|
||||
{
|
||||
name: "genesis root",
|
||||
blockID: root[:],
|
||||
want: genBlk,
|
||||
},
|
||||
{
|
||||
name: "root",
|
||||
blockID: blkContainers[20].BlockRoot,
|
||||
want: blkContainers[20].GetBlindedBellatrixBlock(),
|
||||
},
|
||||
{
|
||||
name: "non-existent root",
|
||||
blockID: bytesutil.PadTo([]byte("hi there"), 32),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no block",
|
||||
blockID: []byte("105"),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
blk, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: tt.blockID,
|
||||
})
|
||||
if tt.wantErr {
|
||||
require.NotEqual(t, err, nil)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
v2Block, err := migration.V1Alpha1BeaconBlockBlindedBellatrixToV2Blinded(tt.want.Block)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, ok := blk.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_BellatrixBlock)
|
||||
require.Equal(t, true, ok)
|
||||
if !reflect.DeepEqual(b.BellatrixBlock, v2Block) {
|
||||
t.Error("Expected blocks to equal")
|
||||
}
|
||||
assert.Equal(t, ethpbv2.Version_BELLATRIX, blk.Version)
|
||||
})
|
||||
}
|
||||
resp, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
bellatrixBlock, ok := resp.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_BellatrixBlock)
|
||||
require.Equal(t, true, ok)
|
||||
assert.DeepEqual(t, expected, bellatrixBlock.BellatrixBlock)
|
||||
assert.Equal(t, ethpbv2.Version_BELLATRIX, resp.Version)
|
||||
})
|
||||
|
||||
t.Run("Capella", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
genBlk, blkContainers := fillDBTestBlocksCapellaBlinded(ctx, t, beaconDB)
|
||||
canonicalRoots := make(map[[32]byte]bool)
|
||||
for _, bContr := range blkContainers {
|
||||
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
|
||||
}
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
nextSlot := headBlock.GetBlindedCapellaBlock().Block.Slot + 1
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBlindedCapellaBlock())
|
||||
b := util.NewBlindedBeaconBlockCapella()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
CanonicalRoots: canonicalRoots,
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
|
||||
mockChainService := &mock.ChainService{}
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
HeadFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
ExecutionPayloadReconstructor: &executionTest.EngineClient{
|
||||
ExecutionPayloadByBlockHash: map[[32]byte]*enginev1.ExecutionPayload{},
|
||||
},
|
||||
FinalizationFetcher: mockChainService,
|
||||
}
|
||||
|
||||
root, err := genBlk.Block.HashTreeRoot()
|
||||
expected, err := migration.V1Alpha1BeaconBlockBlindedCapellaToV2Blinded(b.Block)
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
blockID []byte
|
||||
want *ethpbalpha.SignedBlindedBeaconBlockCapella
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "slot",
|
||||
blockID: []byte("30"),
|
||||
want: blkContainers[30].GetBlindedCapellaBlock(),
|
||||
},
|
||||
{
|
||||
name: "bad formatting",
|
||||
blockID: []byte("3bad0"),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "canonical",
|
||||
blockID: []byte("30"),
|
||||
want: blkContainers[30].GetBlindedCapellaBlock(),
|
||||
},
|
||||
{
|
||||
name: "non canonical",
|
||||
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "head",
|
||||
blockID: []byte("head"),
|
||||
want: headBlock.GetBlindedCapellaBlock(),
|
||||
},
|
||||
{
|
||||
name: "finalized",
|
||||
blockID: []byte("finalized"),
|
||||
want: blkContainers[64].GetBlindedCapellaBlock(),
|
||||
},
|
||||
{
|
||||
name: "genesis",
|
||||
blockID: []byte("genesis"),
|
||||
want: genBlk,
|
||||
},
|
||||
{
|
||||
name: "genesis root",
|
||||
blockID: root[:],
|
||||
want: genBlk,
|
||||
},
|
||||
{
|
||||
name: "root",
|
||||
blockID: blkContainers[20].BlockRoot,
|
||||
want: blkContainers[20].GetBlindedCapellaBlock(),
|
||||
},
|
||||
{
|
||||
name: "non-existent root",
|
||||
blockID: bytesutil.PadTo([]byte("hi there"), 32),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no block",
|
||||
blockID: []byte("105"),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
blk, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: tt.blockID,
|
||||
})
|
||||
if tt.wantErr {
|
||||
require.NotEqual(t, err, nil)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
v2Block, err := migration.V1Alpha1BeaconBlockBlindedCapellaToV2Blinded(tt.want.Block)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, ok := blk.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_CapellaBlock)
|
||||
require.Equal(t, true, ok)
|
||||
if !reflect.DeepEqual(b.CapellaBlock, v2Block) {
|
||||
t.Error("Expected blocks to equal")
|
||||
}
|
||||
assert.Equal(t, ethpbv2.Version_CAPELLA, blk.Version)
|
||||
})
|
||||
}
|
||||
resp, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
capellaBlock, ok := resp.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_CapellaBlock)
|
||||
require.Equal(t, true, ok)
|
||||
assert.DeepEqual(t, expected, capellaBlock.CapellaBlock)
|
||||
assert.Equal(t, ethpbv2.Version_CAPELLA, resp.Version)
|
||||
})
|
||||
|
||||
t.Run("execution optimistic", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, blkContainers := fillDBTestBlocksBellatrix(ctx, t, beaconDB)
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBellatrixBlock())
|
||||
b := util.NewBlindedBeaconBlockBellatrix()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
r, err := blk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
OptimisticRoots: map[[32]byte]bool{
|
||||
bytesutil.ToBytes32(headBlock.BlockRoot): true,
|
||||
},
|
||||
OptimisticRoots: map[[32]byte]bool{r: true},
|
||||
}
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
HeadFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
}
|
||||
|
||||
blk, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: []byte("head"),
|
||||
})
|
||||
resp, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, blk.ExecutionOptimistic)
|
||||
assert.Equal(t, true, resp.ExecutionOptimistic)
|
||||
})
|
||||
|
||||
t.Run("finalized", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetPhase0Block())
|
||||
b := util.NewBeaconBlock()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
Optimistic: true,
|
||||
FinalizedRoots: map[[32]byte]bool{
|
||||
bytesutil.ToBytes32(blkContainers[32].BlockRoot): true,
|
||||
bytesutil.ToBytes32(blkContainers[64].BlockRoot): false,
|
||||
},
|
||||
FinalizedRoots: map[[32]byte]bool{root: true},
|
||||
}
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
HeadFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
}
|
||||
|
||||
t.Run("true", func(t *testing.T) {
|
||||
blk, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: []byte("32"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, blk.Finalized)
|
||||
})
|
||||
t.Run("false", func(t *testing.T) {
|
||||
blk, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: []byte("64"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, blk.Finalized)
|
||||
})
|
||||
resp, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{BlockId: root[:]})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, resp.Finalized)
|
||||
})
|
||||
t.Run("not finalized", func(t *testing.T) {
|
||||
b := util.NewBeaconBlock()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
mockChainService := &mock.ChainService{
|
||||
FinalizedRoots: map[[32]byte]bool{root: false},
|
||||
}
|
||||
bs := &Server{
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
}
|
||||
|
||||
resp, err := bs.GetBlindedBlock(ctx, ðpbv1.BlockRequest{BlockId: root[:]})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
}
|
||||
|
||||
func TestServer_GetBlindedBlockSSZ(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("Phase 0", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block)
|
||||
b := util.NewBeaconBlock()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: wsb,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
FinalizationFetcher: &mock.ChainService{},
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
}
|
||||
|
||||
blks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, len(blks) > 0)
|
||||
expected, err := blk.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
sszBlock, err := blks[0].MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{BlockId: []byte("30")})
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
assert.DeepEqual(t, sszBlock, resp.Data)
|
||||
assert.DeepEqual(t, expected, resp.Data)
|
||||
assert.Equal(t, ethpbv2.Version_PHASE0, resp.Version)
|
||||
})
|
||||
|
||||
t.Run("Altair", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, blkContainers := fillDBTestBlocksAltair(ctx, t, beaconDB)
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetAltairBlock())
|
||||
b := util.NewBeaconBlockAltair()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
FinalizationFetcher: &mock.ChainService{},
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
}
|
||||
|
||||
blks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, len(blks) > 0)
|
||||
expected, err := blk.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
sszBlock, err := blks[0].MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{BlockId: []byte("30")})
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
assert.DeepEqual(t, sszBlock, resp.Data)
|
||||
assert.DeepEqual(t, expected, resp.Data)
|
||||
assert.Equal(t, ethpbv2.Version_ALTAIR, resp.Version)
|
||||
})
|
||||
|
||||
t.Run("Bellatrix", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, blkContainers := fillDBTestBlocksBellatrixBlinded(ctx, t, beaconDB)
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBlindedBellatrixBlock())
|
||||
b := util.NewBlindedBeaconBlockBellatrix()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
|
||||
mockChainService := &mock.ChainService{}
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
}
|
||||
|
||||
blks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, len(blks) > 0)
|
||||
expected, err := blk.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
sszBlock, err := blks[0].MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{BlockId: []byte("30")})
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
assert.DeepEqual(t, sszBlock, resp.Data)
|
||||
assert.DeepEqual(t, expected, resp.Data)
|
||||
assert.Equal(t, ethpbv2.Version_BELLATRIX, resp.Version)
|
||||
})
|
||||
|
||||
t.Run("Capella", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, blkContainers := fillDBTestBlocksCapellaBlinded(ctx, t, beaconDB)
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBlindedCapellaBlock())
|
||||
b := util.NewBlindedBeaconBlockCapella()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
|
||||
mockChainService := &mock.ChainService{}
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
}
|
||||
|
||||
blks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, len(blks) > 0)
|
||||
expected, err := blk.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
sszBlock, err := blks[0].MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{BlockId: []byte("30")})
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
assert.DeepEqual(t, sszBlock, resp.Data)
|
||||
assert.DeepEqual(t, expected, resp.Data)
|
||||
assert.Equal(t, ethpbv2.Version_CAPELLA, resp.Version)
|
||||
})
|
||||
|
||||
t.Run("execution optimistic", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, blkContainers := fillDBTestBlocksBellatrix(ctx, t, beaconDB)
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBellatrixBlock())
|
||||
b := util.NewBlindedBeaconBlockBellatrix()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
r, err := blk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
OptimisticRoots: map[[32]byte]bool{
|
||||
bytesutil.ToBytes32(headBlock.BlockRoot): true,
|
||||
},
|
||||
OptimisticRoots: map[[32]byte]bool{r: true},
|
||||
}
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
HeadFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
}
|
||||
|
||||
blk, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: []byte("head"),
|
||||
})
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, blk.ExecutionOptimistic)
|
||||
assert.Equal(t, true, resp.ExecutionOptimistic)
|
||||
})
|
||||
|
||||
t.Run("finalized", func(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
|
||||
headBlock := blkContainers[len(blkContainers)-1]
|
||||
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetPhase0Block())
|
||||
b := util.NewBeaconBlock()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
mockChainService := &mock.ChainService{
|
||||
DB: beaconDB,
|
||||
Block: chainBlk,
|
||||
Root: headBlock.BlockRoot,
|
||||
FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
|
||||
Optimistic: true,
|
||||
FinalizedRoots: map[[32]byte]bool{
|
||||
bytesutil.ToBytes32(blkContainers[32].BlockRoot): true,
|
||||
bytesutil.ToBytes32(blkContainers[64].BlockRoot): false,
|
||||
},
|
||||
FinalizedRoots: map[[32]byte]bool{root: true},
|
||||
}
|
||||
bs := &Server{
|
||||
BeaconDB: beaconDB,
|
||||
ChainInfoFetcher: mockChainService,
|
||||
HeadFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
}
|
||||
|
||||
t.Run("true", func(t *testing.T) {
|
||||
blk, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: []byte("32"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, blk.Finalized)
|
||||
})
|
||||
t.Run("false", func(t *testing.T) {
|
||||
blk, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{
|
||||
BlockId: []byte("64"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, blk.Finalized)
|
||||
})
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{BlockId: root[:]})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, resp.Finalized)
|
||||
})
|
||||
t.Run("not finalized", func(t *testing.T) {
|
||||
b := util.NewBeaconBlock()
|
||||
blk, err := blocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
mockChainService := &mock.ChainService{
|
||||
FinalizedRoots: map[[32]byte]bool{root: false},
|
||||
}
|
||||
bs := &Server{
|
||||
FinalizationFetcher: mockChainService,
|
||||
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
|
||||
}
|
||||
|
||||
resp, err := bs.GetBlindedBlockSSZ(ctx, ðpbv1.BlockRequest{BlockId: root[:]})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -882,14 +389,6 @@ func TestServer_SubmitBlindedBlockSSZ_OK(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Bellatrix", func(t *testing.T) {
|
||||
// INFO: This code block can be removed once Bellatrix
|
||||
// fork epoch is set to a value other than math.MaxUint64
|
||||
params.SetupTestConfigCleanup(t)
|
||||
cfg := params.BeaconConfig()
|
||||
cfg.BellatrixForkEpoch = cfg.AltairForkEpoch + 1000
|
||||
cfg.ForkVersionSchedule[bytesutil.ToBytes4(cfg.BellatrixForkVersion)] = cfg.AltairForkEpoch + 1000
|
||||
params.OverrideBeaconConfig(cfg)
|
||||
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
@@ -938,16 +437,6 @@ func TestServer_SubmitBlindedBlockSSZ_OK(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Capella", func(t *testing.T) {
|
||||
t.Skip("This test needs Capella fork version configured properly")
|
||||
|
||||
// INFO: This code block can be removed once Capella
|
||||
// fork epoch is set to a value other than math.MaxUint64
|
||||
params.SetupTestConfigCleanup(t)
|
||||
cfg := params.BeaconConfig()
|
||||
cfg.CapellaForkEpoch = cfg.BellatrixForkEpoch + 1000
|
||||
cfg.ForkVersionSchedule[bytesutil.ToBytes4(cfg.CapellaForkVersion)] = cfg.BellatrixForkEpoch + 1000
|
||||
params.OverrideBeaconConfig(cfg)
|
||||
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/filters"
|
||||
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
@@ -37,23 +38,6 @@ var (
|
||||
errNilBlock = errors.New("nil block")
|
||||
)
|
||||
|
||||
// blockIdParseError represents an error scenario where a block ID could not be parsed.
|
||||
type blockIdParseError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
// newBlockIdParseError creates a new error instance.
|
||||
func newBlockIdParseError(reason error) blockIdParseError {
|
||||
return blockIdParseError{
|
||||
message: errors.Wrapf(reason, "could not parse block ID").Error(),
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the underlying error message.
|
||||
func (e *blockIdParseError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
// 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.
|
||||
// DEPRECATED: GetWeakSubjectivity endpoint will no longer be supported
|
||||
@@ -101,7 +85,7 @@ func (bs *Server) GetBlockHeader(ctx context.Context, req *ethpbv1.BlockRequest)
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockHeader")
|
||||
defer span.End()
|
||||
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
blk, err := bs.Blocker.Block(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -290,7 +274,7 @@ func (bs *Server) GetBlock(ctx context.Context, req *ethpbv1.BlockRequest) (*eth
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetBlock")
|
||||
defer span.End()
|
||||
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
blk, err := bs.Blocker.Block(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -314,7 +298,7 @@ func (bs *Server) GetBlockSSZ(ctx context.Context, req *ethpbv1.BlockRequest) (*
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockSSZ")
|
||||
defer span.End()
|
||||
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
blk, err := bs.Blocker.Block(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -336,7 +320,7 @@ func (bs *Server) GetBlockV2(ctx context.Context, req *ethpbv2.BlockRequestV2) (
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockV2")
|
||||
defer span.End()
|
||||
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
blk, err := bs.Blocker.Block(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -382,14 +366,6 @@ func (bs *Server) GetBlockV2(ctx context.Context, req *ethpbv2.BlockRequestV2) (
|
||||
if !errors.Is(err, blocks.ErrUnsupportedGetter) {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get signed beacon block: %v", err)
|
||||
}
|
||||
result, err = bs.getBlockDeneb(ctx, blk)
|
||||
if result != nil {
|
||||
return result, nil
|
||||
}
|
||||
// ErrUnsupportedGetter means that we have another block type
|
||||
if !errors.Is(err, blocks.ErrUnsupportedGetter) {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get signed beacon block: %v", err)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "Unknown block type %T", blk)
|
||||
}
|
||||
|
||||
@@ -398,7 +374,7 @@ func (bs *Server) GetBlockSSZV2(ctx context.Context, req *ethpbv2.BlockRequestV2
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockSSZV2")
|
||||
defer span.End()
|
||||
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
blk, err := bs.Blocker.Block(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -444,14 +420,6 @@ func (bs *Server) GetBlockSSZV2(ctx context.Context, req *ethpbv2.BlockRequestV2
|
||||
if !errors.Is(err, blocks.ErrUnsupportedGetter) {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get signed beacon block: %v", err)
|
||||
}
|
||||
result, err = bs.getSSZBlockDeneb(ctx, blk)
|
||||
if result != nil {
|
||||
return result, nil
|
||||
}
|
||||
// ErrUnsupportedGetter means that we have another block type
|
||||
if !errors.Is(err, blocks.ErrUnsupportedGetter) {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get signed beacon block: %v", err)
|
||||
}
|
||||
|
||||
return nil, status.Errorf(codes.Internal, "Unknown block type %T", blk)
|
||||
}
|
||||
@@ -548,7 +516,7 @@ func (bs *Server) ListBlockAttestations(ctx context.Context, req *ethpbv1.BlockR
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.ListBlockAttestations")
|
||||
defer span.End()
|
||||
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
blk, err := bs.Blocker.Block(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -575,68 +543,8 @@ func (bs *Server) ListBlockAttestations(ctx context.Context, req *ethpbv1.BlockR
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (bs *Server) blockFromBlockID(ctx context.Context, blockId []byte) (interfaces.ReadOnlySignedBeaconBlock, error) {
|
||||
var err error
|
||||
var blk interfaces.ReadOnlySignedBeaconBlock
|
||||
switch string(blockId) {
|
||||
case "head":
|
||||
blk, err = bs.ChainInfoFetcher.HeadBlock(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not retrieve head block")
|
||||
}
|
||||
case "finalized":
|
||||
finalized := bs.ChainInfoFetcher.FinalizedCheckpt()
|
||||
finalizedRoot := bytesutil.ToBytes32(finalized.Root)
|
||||
blk, err = bs.BeaconDB.Block(ctx, finalizedRoot)
|
||||
if err != nil {
|
||||
return nil, errors.New("could not get finalized block from db")
|
||||
}
|
||||
case "genesis":
|
||||
blk, err = bs.BeaconDB.GenesisBlock(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not retrieve blocks for genesis slot")
|
||||
}
|
||||
default:
|
||||
if len(blockId) == 32 {
|
||||
blk, err = bs.BeaconDB.Block(ctx, bytesutil.ToBytes32(blockId))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not retrieve block")
|
||||
}
|
||||
} else {
|
||||
slot, err := strconv.ParseUint(string(blockId), 10, 64)
|
||||
if err != nil {
|
||||
e := newBlockIdParseError(err)
|
||||
return nil, &e
|
||||
}
|
||||
blks, err := bs.BeaconDB.BlocksBySlot(ctx, primitives.Slot(slot))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not retrieve blocks for slot %d", slot)
|
||||
}
|
||||
_, roots, err := bs.BeaconDB.BlockRootsBySlot(ctx, primitives.Slot(slot))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not retrieve block roots for slot %d", slot)
|
||||
}
|
||||
numBlks := len(blks)
|
||||
if numBlks == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
for i, b := range blks {
|
||||
canonical, err := bs.ChainInfoFetcher.IsCanonical(ctx, roots[i])
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not determine if block root is canonical: %v", err)
|
||||
}
|
||||
if canonical {
|
||||
blk = b
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return blk, nil
|
||||
}
|
||||
|
||||
func handleGetBlockError(blk interfaces.ReadOnlySignedBeaconBlock, err error) error {
|
||||
if invalidBlockIdErr, ok := err.(*blockIdParseError); ok {
|
||||
if invalidBlockIdErr, ok := err.(*lookup.BlockIdParseError); ok {
|
||||
return status.Errorf(codes.InvalidArgument, "Invalid block ID: %v", invalidBlockIdErr)
|
||||
}
|
||||
if err != nil {
|
||||
@@ -833,76 +741,6 @@ func (bs *Server) getBlockCapella(ctx context.Context, blk interfaces.ReadOnlySi
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (bs *Server) getBlockDeneb(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.BlockResponseV2, error) {
|
||||
denebBlk, err := blk.PbDenebBlock()
|
||||
if err != nil {
|
||||
// ErrUnsupportedGetter means that we have another block type
|
||||
if errors.Is(err, blocks.ErrUnsupportedGetter) {
|
||||
if blindedDenebBlk, err := blk.PbBlindedDenebBlock(); err == nil {
|
||||
if blindedDenebBlk == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
signedFullBlock, err := bs.ExecutionPayloadReconstructor.ReconstructFullBlock(ctx, blk)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block")
|
||||
}
|
||||
denebBlk, err = signedFullBlock.PbDenebBlock()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get signed beacon block")
|
||||
}
|
||||
v2Blk, err := migration.V1Alpha1BeaconBlockDenebToV2(denebBlk.Block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not convert beacon block")
|
||||
}
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get block root")
|
||||
}
|
||||
isOptimistic, err := bs.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not check if block is optimistic")
|
||||
}
|
||||
sig := blk.Signature()
|
||||
return ðpbv2.BlockResponseV2{
|
||||
Version: ethpbv2.Version_Deneb,
|
||||
Data: ðpbv2.SignedBeaconBlockContainer{
|
||||
Message: ðpbv2.SignedBeaconBlockContainer_DenebBlock{DenebBlock: v2Blk},
|
||||
Signature: sig[:],
|
||||
},
|
||||
ExecutionOptimistic: isOptimistic,
|
||||
}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if denebBlk == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
v2Blk, err := migration.V1Alpha1BeaconBlockDenebToV2(denebBlk.Block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not convert beacon block")
|
||||
}
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get block root")
|
||||
}
|
||||
isOptimistic, err := bs.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not check if block is optimistic")
|
||||
}
|
||||
sig := blk.Signature()
|
||||
return ðpbv2.BlockResponseV2{
|
||||
Version: ethpbv2.Version_Deneb,
|
||||
Data: ðpbv2.SignedBeaconBlockContainer{
|
||||
Message: ðpbv2.SignedBeaconBlockContainer_DenebBlock{DenebBlock: v2Blk},
|
||||
Signature: sig[:],
|
||||
},
|
||||
ExecutionOptimistic: isOptimistic,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getSSZBlockPhase0(blk interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.SSZContainer, error) {
|
||||
phase0Blk, err := blk.PbPhase0Block()
|
||||
if err != nil {
|
||||
@@ -1098,82 +936,6 @@ func (bs *Server) getSSZBlockCapella(ctx context.Context, blk interfaces.ReadOnl
|
||||
return ðpbv2.SSZContainer{Version: ethpbv2.Version_CAPELLA, ExecutionOptimistic: isOptimistic, Data: sszData}, nil
|
||||
}
|
||||
|
||||
func (bs *Server) getSSZBlockDeneb(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.SSZContainer, error) {
|
||||
denebBlk, err := blk.PbDenebBlock()
|
||||
if err != nil {
|
||||
// ErrUnsupportedGetter means that we have another block type
|
||||
if errors.Is(err, blocks.ErrUnsupportedGetter) {
|
||||
if blindedDenebBlk, err := blk.PbBlindedDenebBlock(); err == nil {
|
||||
if blindedDenebBlk == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
signedFullBlock, err := bs.ExecutionPayloadReconstructor.ReconstructFullBlock(ctx, blk)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block")
|
||||
}
|
||||
denebBlk, err = signedFullBlock.PbDenebBlock()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get signed beacon block")
|
||||
}
|
||||
v2Blk, err := migration.V1Alpha1BeaconBlockDenebToV2(denebBlk.Block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not convert signed beacon block")
|
||||
}
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get block root")
|
||||
}
|
||||
isOptimistic, err := bs.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not check if block is optimistic")
|
||||
}
|
||||
sig := blk.Signature()
|
||||
data := ðpbv2.SignedBeaconBlockDeneb{
|
||||
Message: v2Blk,
|
||||
Signature: sig[:],
|
||||
}
|
||||
sszData, err := data.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
|
||||
}
|
||||
return ðpbv2.SSZContainer{
|
||||
Version: ethpbv2.Version_Deneb,
|
||||
ExecutionOptimistic: isOptimistic,
|
||||
Data: sszData,
|
||||
}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if denebBlk == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
v2Blk, err := migration.V1Alpha1BeaconBlockDenebToV2(denebBlk.Block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not convert signed beacon block")
|
||||
}
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get block root")
|
||||
}
|
||||
isOptimistic, err := bs.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not check if block is optimistic")
|
||||
}
|
||||
sig := blk.Signature()
|
||||
data := ðpbv2.SignedBeaconBlockDeneb{
|
||||
Message: v2Blk,
|
||||
Signature: sig[:],
|
||||
}
|
||||
sszData, err := data.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
|
||||
}
|
||||
return ðpbv2.SSZContainer{Version: ethpbv2.Version_Deneb, ExecutionOptimistic: isOptimistic, Data: sszData}, nil
|
||||
}
|
||||
|
||||
func (bs *Server) submitPhase0Block(ctx context.Context, phase0Blk *ethpbv1.BeaconBlock, sig []byte) error {
|
||||
v1alpha1Blk, err := migration.V1ToV1Alpha1SignedBlock(ðpbv1.SignedBeaconBlock{Block: phase0Blk, Signature: sig})
|
||||
if err != nil {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -104,8 +104,6 @@ func TestGetSpec(t *testing.T) {
|
||||
config.MaxWithdrawalsPerPayload = 74
|
||||
config.MaxBlsToExecutionChanges = 75
|
||||
config.MaxValidatorsPerWithdrawalsSweep = 76
|
||||
config.DenebForkEpoch = 77
|
||||
config.DenebForkVersion = []byte("DenebForkVersion")
|
||||
|
||||
var dbp [4]byte
|
||||
copy(dbp[:], []byte{'0', '0', '0', '1'})
|
||||
@@ -131,9 +129,6 @@ func TestGetSpec(t *testing.T) {
|
||||
var dam [4]byte
|
||||
copy(dam[:], []byte{'1', '0', '0', '0'})
|
||||
config.DomainApplicationMask = dam
|
||||
var dbs [4]byte
|
||||
copy(dbs[:], []byte{'0', '0', '0', '8'})
|
||||
config.DomainBlobSidecar = dbs
|
||||
|
||||
params.OverrideBeaconConfig(config)
|
||||
|
||||
@@ -141,7 +136,7 @@ func TestGetSpec(t *testing.T) {
|
||||
resp, err := server.GetSpec(context.Background(), &emptypb.Empty{})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 108, len(resp.Data))
|
||||
assert.Equal(t, 105, len(resp.Data))
|
||||
for k, v := range resp.Data {
|
||||
switch k {
|
||||
case "CONFIG_NAME":
|
||||
@@ -367,14 +362,8 @@ func TestGetSpec(t *testing.T) {
|
||||
case "REORG_WEIGHT_THRESHOLD":
|
||||
assert.Equal(t, "20", v)
|
||||
case "SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY":
|
||||
case "DENEB_FORK_EPOCH":
|
||||
assert.Equal(t, "77", v)
|
||||
case "DENEB_FORK_VERSION":
|
||||
assert.Equal(t, "0x"+hex.EncodeToString([]byte("DenebForkVersion")), v)
|
||||
case "DOMAIN_BLOB_SIDECAR":
|
||||
assert.Equal(t, "0x30303038", v)
|
||||
default:
|
||||
t.Errorf("Unknown key: %s", k)
|
||||
t.Errorf("Incorrect key: %s", k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ func (bs *Server) SubmitAttesterSlashing(ctx context.Context, req *ethpbv1.Attes
|
||||
return nil, status.Errorf(codes.Internal, "Could not insert attester slashing into pool: %v", err)
|
||||
}
|
||||
if !features.Get().DisableBroadcastSlashings {
|
||||
if err := bs.Broadcaster.Broadcast(ctx, req); err != nil {
|
||||
if err := bs.Broadcaster.Broadcast(ctx, alphaSlashing); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not broadcast slashing object: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -242,7 +242,7 @@ func (bs *Server) SubmitProposerSlashing(ctx context.Context, req *ethpbv1.Propo
|
||||
return nil, status.Errorf(codes.Internal, "Could not insert proposer slashing into pool: %v", err)
|
||||
}
|
||||
if !features.Get().DisableBroadcastSlashings {
|
||||
if err := bs.Broadcaster.Broadcast(ctx, req); err != nil {
|
||||
if err := bs.Broadcaster.Broadcast(ctx, alphaSlashing); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not broadcast slashing object: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,6 +452,9 @@ func TestSubmitAttesterSlashing_Ok(t *testing.T) {
|
||||
require.Equal(t, 1, len(pendingSlashings))
|
||||
assert.DeepEqual(t, migration.V1AttSlashingToV1Alpha1(slashing), pendingSlashings[0])
|
||||
assert.Equal(t, true, broadcaster.BroadcastCalled)
|
||||
require.Equal(t, 1, len(broadcaster.BroadcastMessages))
|
||||
_, ok := broadcaster.BroadcastMessages[0].(*ethpbv1alpha1.AttesterSlashing)
|
||||
assert.Equal(t, true, ok)
|
||||
}
|
||||
|
||||
func TestSubmitAttesterSlashing_AcrossFork(t *testing.T) {
|
||||
@@ -526,6 +529,9 @@ func TestSubmitAttesterSlashing_AcrossFork(t *testing.T) {
|
||||
require.Equal(t, 1, len(pendingSlashings))
|
||||
assert.DeepEqual(t, migration.V1AttSlashingToV1Alpha1(slashing), pendingSlashings[0])
|
||||
assert.Equal(t, true, broadcaster.BroadcastCalled)
|
||||
require.Equal(t, 1, len(broadcaster.BroadcastMessages))
|
||||
_, ok := broadcaster.BroadcastMessages[0].(*ethpbv1alpha1.AttesterSlashing)
|
||||
assert.Equal(t, true, ok)
|
||||
}
|
||||
|
||||
func TestSubmitAttesterSlashing_InvalidSlashing(t *testing.T) {
|
||||
@@ -633,6 +639,9 @@ func TestSubmitProposerSlashing_Ok(t *testing.T) {
|
||||
require.Equal(t, 1, len(pendingSlashings))
|
||||
assert.DeepEqual(t, migration.V1ProposerSlashingToV1Alpha1(slashing), pendingSlashings[0])
|
||||
assert.Equal(t, true, broadcaster.BroadcastCalled)
|
||||
require.Equal(t, 1, len(broadcaster.BroadcastMessages))
|
||||
_, ok := broadcaster.BroadcastMessages[0].(*ethpbv1alpha1.ProposerSlashing)
|
||||
assert.Equal(t, true, ok)
|
||||
}
|
||||
|
||||
func TestSubmitProposerSlashing_AcrossFork(t *testing.T) {
|
||||
@@ -695,6 +704,13 @@ func TestSubmitProposerSlashing_AcrossFork(t *testing.T) {
|
||||
|
||||
_, err = s.SubmitProposerSlashing(ctx, slashing)
|
||||
require.NoError(t, err)
|
||||
pendingSlashings := s.SlashingsPool.PendingProposerSlashings(ctx, bs, true)
|
||||
require.Equal(t, 1, len(pendingSlashings))
|
||||
assert.DeepEqual(t, migration.V1ProposerSlashingToV1Alpha1(slashing), pendingSlashings[0])
|
||||
assert.Equal(t, true, broadcaster.BroadcastCalled)
|
||||
require.Equal(t, 1, len(broadcaster.BroadcastMessages))
|
||||
_, ok := broadcaster.BroadcastMessages[0].(*ethpbv1alpha1.ProposerSlashing)
|
||||
assert.Equal(t, true, ok)
|
||||
}
|
||||
|
||||
func TestSubmitProposerSlashing_InvalidSlashing(t *testing.T) {
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/slashings"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/voluntaryexits"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
||||
v1alpha1validator "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
|
||||
)
|
||||
@@ -34,7 +34,8 @@ type Server struct {
|
||||
SlashingsPool slashings.PoolManager
|
||||
VoluntaryExitsPool voluntaryexits.PoolManager
|
||||
StateGenService stategen.StateManager
|
||||
StateFetcher statefetcher.Fetcher
|
||||
Stater lookup.Stater
|
||||
Blocker lookup.Blocker
|
||||
HeadFetcher blockchain.HeadFetcher
|
||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||
V1Alpha1ValidatorServer *v1alpha1validator.Server
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
@@ -58,20 +58,20 @@ func (bs *Server) GetStateRoot(ctx context.Context, req *ethpb.StateRequest) (*e
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetStateRoot")
|
||||
defer span.End()
|
||||
|
||||
stateRoot, err := bs.StateFetcher.StateRoot(ctx, req.StateId)
|
||||
stateRoot, err := bs.Stater.StateRoot(ctx, req.StateId)
|
||||
if err != nil {
|
||||
if rootNotFoundErr, ok := err.(*statefetcher.StateRootNotFoundError); ok {
|
||||
if rootNotFoundErr, ok := err.(*lookup.StateRootNotFoundError); ok {
|
||||
return nil, status.Errorf(codes.NotFound, "State root not found: %v", rootNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
} else if parseErr, ok := err.(*lookup.StateIdParseError); ok {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "Could not get state root: %v", err)
|
||||
}
|
||||
st, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := bs.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
|
||||
}
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
@@ -95,12 +95,12 @@ func (bs *Server) GetStateFork(ctx context.Context, req *ethpb.StateRequest) (*e
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetStateFork")
|
||||
defer span.End()
|
||||
|
||||
st, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := bs.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
fork := st.Fork()
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
@@ -127,11 +127,11 @@ func (bs *Server) GetFinalityCheckpoints(ctx context.Context, req *ethpb.StateRe
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetFinalityCheckpoints")
|
||||
defer span.End()
|
||||
|
||||
st, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := bs.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
@@ -160,7 +160,7 @@ func (bs *Server) GetRandao(ctx context.Context, req *eth2.RandaoRequest) (*eth2
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetRandao")
|
||||
defer span.End()
|
||||
|
||||
st, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := bs.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
@@ -186,7 +186,7 @@ func (bs *Server) GetRandao(ctx context.Context, req *eth2.RandaoRequest) (*eth2
|
||||
return nil, status.Errorf(codes.Internal, "Could not get randao mix at index %d", idx)
|
||||
}
|
||||
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
@@ -215,14 +215,14 @@ func (bs *Server) stateFromRequest(ctx context.Context, req *stateRequest) (stat
|
||||
err,
|
||||
)
|
||||
}
|
||||
st, err := bs.StateFetcher.State(ctx, []byte(strconv.FormatUint(uint64(slot), 10)))
|
||||
st, err := bs.Stater.State(ctx, []byte(strconv.FormatUint(uint64(slot), 10)))
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
return st, nil
|
||||
}
|
||||
var err error
|
||||
st, err := bs.StateFetcher.State(ctx, req.stateId)
|
||||
st, err := bs.Stater.State(ctx, req.stateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func TestGetStateRoot(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconStateRoot: stateRoot[:],
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
@@ -111,7 +111,7 @@ func TestGetStateRoot(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{Optimistic: true}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconStateRoot: stateRoot[:],
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
@@ -145,7 +145,7 @@ func TestGetStateRoot(t *testing.T) {
|
||||
},
|
||||
}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconStateRoot: stateRoot[:],
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
@@ -179,7 +179,7 @@ func TestGetStateFork(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -209,7 +209,7 @@ func TestGetStateFork(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{Optimistic: true}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -242,7 +242,7 @@ func TestGetStateFork(t *testing.T) {
|
||||
},
|
||||
}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -282,7 +282,7 @@ func TestGetFinalityCheckpoints(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -314,7 +314,7 @@ func TestGetFinalityCheckpoints(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{Optimistic: true}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -347,7 +347,7 @@ func TestGetFinalityCheckpoints(t *testing.T) {
|
||||
},
|
||||
}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -388,7 +388,7 @@ func TestGetRandao(t *testing.T) {
|
||||
db := dbTest.SetupDB(t)
|
||||
chainService := &chainMock.ChainService{}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -413,7 +413,7 @@ func TestGetRandao(t *testing.T) {
|
||||
assert.DeepEqual(t, mixOld, resp.Data.Randao)
|
||||
})
|
||||
t.Run("head state below `EpochsPerHistoricalVector`", func(t *testing.T) {
|
||||
server.StateFetcher = &testutil.MockFetcher{
|
||||
server.Stater = &testutil.MockStater{
|
||||
BeaconState: headSt,
|
||||
}
|
||||
resp, err := server.GetRandao(ctx, ð2.RandaoRequest{StateId: []byte("head")})
|
||||
@@ -441,7 +441,7 @@ func TestGetRandao(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{Optimistic: true}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -473,7 +473,7 @@ func TestGetRandao(t *testing.T) {
|
||||
},
|
||||
}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
|
||||
@@ -91,7 +91,7 @@ func (bs *Server) ListSyncCommittees(ctx context.Context, req *ethpbv2.StateSync
|
||||
return nil, status.Errorf(codes.Internal, "Could not extract sync subcommittees: %v", err)
|
||||
}
|
||||
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ func TestListSyncCommittees(t *testing.T) {
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -213,7 +213,7 @@ func TestListSyncCommittees(t *testing.T) {
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -249,7 +249,7 @@ func TestListSyncCommittees(t *testing.T) {
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -309,7 +309,7 @@ func TestListSyncCommitteesFuture(t *testing.T) {
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
StateFetcher: &futureSyncMockFetcher{
|
||||
Stater: &futureSyncMockFetcher{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
|
||||
@@ -42,7 +42,7 @@ func (bs *Server) GetValidator(ctx context.Context, req *ethpb.StateValidatorReq
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.GetValidator")
|
||||
defer span.End()
|
||||
|
||||
st, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := bs.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func (bs *Server) GetValidator(ctx context.Context, req *ethpb.StateValidatorReq
|
||||
return nil, status.Error(codes.NotFound, "Could not find validator")
|
||||
}
|
||||
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidators
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.ListValidators")
|
||||
defer span.End()
|
||||
|
||||
st, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := bs.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidators
|
||||
return nil, handleValContainerErr(err)
|
||||
}
|
||||
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func (bs *Server) ListValidatorBalances(ctx context.Context, req *ethpb.Validato
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.ListValidatorBalances")
|
||||
defer span.End()
|
||||
|
||||
st, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := bs.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
@@ -155,7 +155,7 @@ func (bs *Server) ListValidatorBalances(ctx context.Context, req *ethpb.Validato
|
||||
}
|
||||
}
|
||||
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
@@ -175,7 +175,7 @@ func (bs *Server) ListCommittees(ctx context.Context, req *ethpb.StateCommittees
|
||||
ctx, span := trace.StartSpan(ctx, "beacon.ListCommittees")
|
||||
defer span.End()
|
||||
|
||||
st, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := bs.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
@@ -220,7 +220,7 @@ func (bs *Server) ListCommittees(ctx context.Context, req *ethpb.StateCommittees
|
||||
}
|
||||
}
|
||||
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
chainMock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
||||
dbTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
|
||||
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
@@ -34,7 +34,7 @@ func TestGetValidator(t *testing.T) {
|
||||
t.Run("Head Get Validator by index", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -54,7 +54,7 @@ func TestGetValidator(t *testing.T) {
|
||||
t.Run("Head Get Validator by pubkey", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -75,7 +75,7 @@ func TestGetValidator(t *testing.T) {
|
||||
|
||||
t.Run("Validator ID required", func(t *testing.T) {
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: &chainMock.ChainService{},
|
||||
@@ -98,7 +98,7 @@ func TestGetValidator(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{Optimistic: true}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -131,7 +131,7 @@ func TestGetValidator(t *testing.T) {
|
||||
},
|
||||
}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -157,7 +157,7 @@ func TestListValidators(t *testing.T) {
|
||||
t.Run("Head List All Validators", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -179,7 +179,7 @@ func TestListValidators(t *testing.T) {
|
||||
t.Run("Head List Validators by index", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -204,7 +204,7 @@ func TestListValidators(t *testing.T) {
|
||||
t.Run("Head List Validators by pubkey", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -233,7 +233,7 @@ func TestListValidators(t *testing.T) {
|
||||
t.Run("Head List Validators by both index and pubkey", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -264,7 +264,7 @@ func TestListValidators(t *testing.T) {
|
||||
t.Run("Unknown public key is ignored", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -287,7 +287,7 @@ func TestListValidators(t *testing.T) {
|
||||
t.Run("Unknown index is ignored", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -317,7 +317,7 @@ func TestListValidators(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{Optimistic: true}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -349,7 +349,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -440,7 +440,7 @@ func TestListValidators_Status(t *testing.T) {
|
||||
t.Run("Head List All ACTIVE Validators", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &statefetcher.StateProvider{
|
||||
Stater: &lookup.BeaconDbStater{
|
||||
ChainInfoFetcher: &chainMock.ChainService{State: st},
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -478,7 +478,7 @@ func TestListValidators_Status(t *testing.T) {
|
||||
t.Run("Head List All ACTIVE_ONGOING Validators", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &statefetcher.StateProvider{
|
||||
Stater: &lookup.BeaconDbStater{
|
||||
ChainInfoFetcher: &chainMock.ChainService{State: st},
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -515,7 +515,7 @@ func TestListValidators_Status(t *testing.T) {
|
||||
t.Run("Head List All EXITED Validators", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &statefetcher.StateProvider{
|
||||
Stater: &lookup.BeaconDbStater{
|
||||
ChainInfoFetcher: &chainMock.ChainService{State: st},
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -551,7 +551,7 @@ func TestListValidators_Status(t *testing.T) {
|
||||
t.Run("Head List All PENDING_INITIALIZED and EXITED_UNSLASHED Validators", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &statefetcher.StateProvider{
|
||||
Stater: &lookup.BeaconDbStater{
|
||||
ChainInfoFetcher: &chainMock.ChainService{State: st},
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -587,7 +587,7 @@ func TestListValidators_Status(t *testing.T) {
|
||||
t.Run("Head List All PENDING and EXITED Validators", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &statefetcher.StateProvider{
|
||||
Stater: &lookup.BeaconDbStater{
|
||||
ChainInfoFetcher: &chainMock.ChainService{State: st},
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -638,7 +638,7 @@ func TestListValidatorBalances(t *testing.T) {
|
||||
t.Run("Head List Validators Balance by index", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -663,7 +663,7 @@ func TestListValidatorBalances(t *testing.T) {
|
||||
t.Run("Head List Validators Balance by pubkey", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -691,7 +691,7 @@ func TestListValidatorBalances(t *testing.T) {
|
||||
t.Run("Head List Validators Balance by both index and pubkey", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -726,7 +726,7 @@ func TestListValidatorBalances(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{Optimistic: true}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -761,7 +761,7 @@ func TestListValidatorBalances(t *testing.T) {
|
||||
},
|
||||
}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -791,7 +791,7 @@ func TestListCommittees(t *testing.T) {
|
||||
t.Run("Head All Committees", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -814,7 +814,7 @@ func TestListCommittees(t *testing.T) {
|
||||
t.Run("Head All Committees of Epoch 10", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -836,7 +836,7 @@ func TestListCommittees(t *testing.T) {
|
||||
t.Run("Head All Committees of Slot 4", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -864,7 +864,7 @@ func TestListCommittees(t *testing.T) {
|
||||
t.Run("Head All Committees of Index 1", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -892,7 +892,7 @@ func TestListCommittees(t *testing.T) {
|
||||
t.Run("Head All Committees of Slot 2, Index 1", func(t *testing.T) {
|
||||
chainService := &chainMock.ChainService{}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -928,7 +928,7 @@ func TestListCommittees(t *testing.T) {
|
||||
|
||||
chainService := &chainMock.ChainService{Optimistic: true}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -961,7 +961,7 @@ func TestListCommittees(t *testing.T) {
|
||||
},
|
||||
}
|
||||
s := Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: st,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
|
||||
@@ -12,7 +12,7 @@ go_library(
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/rpc/eth/helpers:go_default_library",
|
||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/migration:go_default_library",
|
||||
|
||||
@@ -19,7 +19,7 @@ func (ds *Server) GetBeaconStateSSZ(ctx context.Context, req *ethpbv1.StateReque
|
||||
ctx, span := trace.StartSpan(ctx, "debug.GetBeaconStateSSZ")
|
||||
defer span.End()
|
||||
|
||||
state, err := ds.StateFetcher.State(ctx, req.StateId)
|
||||
state, err := ds.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
@@ -37,11 +37,11 @@ func (ds *Server) GetBeaconStateV2(ctx context.Context, req *ethpbv2.BeaconState
|
||||
ctx, span := trace.StartSpan(ctx, "debug.GetBeaconStateV2")
|
||||
defer span.End()
|
||||
|
||||
beaconSt, err := ds.StateFetcher.State(ctx, req.StateId)
|
||||
beaconSt, err := ds.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, ds.OptimisticModeFetcher, ds.StateFetcher, ds.ChainInfoFetcher, ds.BeaconDB)
|
||||
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, ds.OptimisticModeFetcher, ds.Stater, ds.ChainInfoFetcher, ds.BeaconDB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
|
||||
}
|
||||
@@ -104,19 +104,6 @@ func (ds *Server) GetBeaconStateV2(ctx context.Context, req *ethpbv2.BeaconState
|
||||
ExecutionOptimistic: isOptimistic,
|
||||
Finalized: isFinalized,
|
||||
}, nil
|
||||
case version.Deneb:
|
||||
protoState, err := migration.BeaconStateDenebToProto(beaconSt)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not convert state to proto: %v", err)
|
||||
}
|
||||
return ðpbv2.BeaconStateResponseV2{
|
||||
Version: ethpbv2.Version_Deneb,
|
||||
Data: ðpbv2.BeaconStateContainer{
|
||||
State: ðpbv2.BeaconStateContainer_DenebState{DenebState: protoState},
|
||||
},
|
||||
ExecutionOptimistic: isOptimistic,
|
||||
}, nil
|
||||
|
||||
default:
|
||||
return nil, status.Error(codes.Internal, "Unsupported state version")
|
||||
}
|
||||
@@ -127,7 +114,7 @@ func (ds *Server) GetBeaconStateSSZV2(ctx context.Context, req *ethpbv2.BeaconSt
|
||||
ctx, span := trace.StartSpan(ctx, "debug.GetBeaconStateSSZV2")
|
||||
defer span.End()
|
||||
|
||||
st, err := ds.StateFetcher.State(ctx, req.StateId)
|
||||
st, err := ds.Stater.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
@@ -146,8 +133,6 @@ func (ds *Server) GetBeaconStateSSZV2(ctx context.Context, req *ethpbv2.BeaconSt
|
||||
ver = ethpbv2.Version_BELLATRIX
|
||||
case version.Capella:
|
||||
ver = ethpbv2.Version_CAPELLA
|
||||
case version.Deneb:
|
||||
ver = ethpbv2.Version_Deneb
|
||||
default:
|
||||
return nil, status.Error(codes.Internal, "Unsupported state version")
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestGetBeaconStateV2(t *testing.T) {
|
||||
fakeState, err := util.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: &blockchainmock.ChainService{},
|
||||
@@ -46,7 +46,7 @@ func TestGetBeaconStateV2(t *testing.T) {
|
||||
t.Run("Altair", func(t *testing.T) {
|
||||
fakeState, _ := util.DeterministicGenesisStateAltair(t, 1)
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: &blockchainmock.ChainService{},
|
||||
@@ -64,7 +64,7 @@ func TestGetBeaconStateV2(t *testing.T) {
|
||||
t.Run("Bellatrix", func(t *testing.T) {
|
||||
fakeState, _ := util.DeterministicGenesisStateBellatrix(t, 1)
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: &blockchainmock.ChainService{},
|
||||
@@ -82,7 +82,7 @@ func TestGetBeaconStateV2(t *testing.T) {
|
||||
t.Run("Capella", func(t *testing.T) {
|
||||
fakeState, _ := util.DeterministicGenesisStateCapella(t, 1)
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: &blockchainmock.ChainService{},
|
||||
@@ -108,7 +108,7 @@ func TestGetBeaconStateV2(t *testing.T) {
|
||||
|
||||
fakeState, _ := util.DeterministicGenesisStateBellatrix(t, 1)
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: &blockchainmock.ChainService{},
|
||||
@@ -141,7 +141,7 @@ func TestGetBeaconStateV2(t *testing.T) {
|
||||
},
|
||||
}
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
HeadFetcher: chainService,
|
||||
@@ -165,7 +165,7 @@ func TestGetBeaconStateSSZ(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
}
|
||||
@@ -186,7 +186,7 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
}
|
||||
@@ -205,7 +205,7 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
}
|
||||
@@ -224,7 +224,7 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
}
|
||||
@@ -243,7 +243,7 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
server := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
Stater: &testutil.MockStater{
|
||||
BeaconState: fakeState,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ package debug
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
||||
)
|
||||
|
||||
// Server defines a server implementation of the gRPC Beacon Chain service,
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
type Server struct {
|
||||
BeaconDB db.ReadOnlyDatabase
|
||||
HeadFetcher blockchain.HeadFetcher
|
||||
StateFetcher statefetcher.Fetcher
|
||||
Stater lookup.Stater
|
||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||
ForkFetcher blockchain.ForkFetcher
|
||||
ForkchoiceFetcher blockchain.ForkchoiceFetcher
|
||||
|
||||
@@ -261,9 +261,13 @@ func (s *Server) handleStateEvents(
|
||||
// This event stream is intended to be used by builders and relays.
|
||||
// parent_ fields are based on state at N_{current_slot}, while the rest of fields are based on state of N_{current_slot + 1}
|
||||
func (s *Server) streamPayloadAttributes(stream ethpbservice.Events_StreamEventsServer) error {
|
||||
headRoot, err := s.HeadFetcher.HeadRoot(s.Ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get head root")
|
||||
}
|
||||
st, err := s.HeadFetcher.HeadState(s.Ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "could not get head state")
|
||||
}
|
||||
// advance the headstate
|
||||
headState, err := transition.ProcessSlotsIfPossible(s.Ctx, st, s.ChainInfoFetcher.CurrentSlot()+1)
|
||||
@@ -276,11 +280,6 @@ func (s *Server) streamPayloadAttributes(stream ethpbservice.Events_StreamEvents
|
||||
return err
|
||||
}
|
||||
|
||||
headRoot, err := s.HeadFetcher.HeadRoot(s.Ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
headPayload, err := headBlock.Block().Body().Execution()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -13,7 +13,7 @@ go_library(
|
||||
"//api/grpc:go_default_library",
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user