mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-11 06:18:05 -05:00
Compare commits
1 Commits
filter-cha
...
test-nilaw
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dadb11e37c |
10
WORKSPACE
10
WORKSPACE
@@ -223,7 +223,7 @@ filegroup(
|
||||
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
|
||||
)
|
||||
|
||||
consensus_spec_version = "v1.4.0-beta.6"
|
||||
consensus_spec_version = "v1.4.0-beta.5"
|
||||
|
||||
bls_test_version = "v0.1.1"
|
||||
|
||||
@@ -239,7 +239,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "7dc467d7be97525c88a1d3683665c1354cc86297fd62009e7cf5000905b25652",
|
||||
sha256 = "9017ffff84d64a7c4c9e6ff9f421f9479f71d3b463b738f54e02158dbb4f50f0",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -255,7 +255,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "e163011254b6ce100205fb779ba660faedc9bc9f7bb4408c25746a7aa5e8d8bc",
|
||||
sha256 = "f08711682553fe7c9362f1400ed8c56b2fa9576df08581fcad4c508ba8ad4788",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -271,7 +271,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "b73c81b6386053a2141f6f43b457489668621c7013f740ed93edf9ac0e34f091",
|
||||
sha256 = "7ea3189e3879f2ac62467cbf2945c00b6c94d30cdefb2d645c630b1018c50e10",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -286,7 +286,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "47726c527512d03ef3e706a8e7f8d5db6a5f2153351db0470dab780f6a87c4dd",
|
||||
sha256 = "4119992a2efc79e5cb2bdc07ed08c0b1fa32332cbd0d88e6467f34938df97026",
|
||||
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
|
||||
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -7,6 +7,4 @@ const (
|
||||
ConsensusBlockValueHeader = "Eth-Consensus-Block-Value"
|
||||
JsonMediaType = "application/json"
|
||||
OctetStreamMediaType = "application/octet-stream"
|
||||
EventStreamMediaType = "text/event-stream"
|
||||
KeepAlive = "keep-alive"
|
||||
)
|
||||
|
||||
@@ -6,7 +6,6 @@ go_library(
|
||||
"chain_info.go",
|
||||
"chain_info_forkchoice.go",
|
||||
"currently_syncing_block.go",
|
||||
"defragment.go",
|
||||
"error.go",
|
||||
"execution_engine.go",
|
||||
"forkchoice_update_execution.go",
|
||||
|
||||
@@ -556,18 +556,3 @@ func (s *Service) RecentBlockSlot(root [32]byte) (primitives.Slot, error) {
|
||||
defer s.cfg.ForkChoiceStore.RUnlock()
|
||||
return s.cfg.ForkChoiceStore.Slot(root)
|
||||
}
|
||||
|
||||
// inRegularSync applies the following heuristics to decide if the node is in
|
||||
// regular sync mode vs init sync mode using only forkchoice.
|
||||
// It checks that the highest received block is behind the current time by at least 2 epochs
|
||||
// and that it was imported at least one epoch late if both of these
|
||||
// tests pass then the node is in init sync. The caller of this function MUST
|
||||
// have a lock on forkchoice
|
||||
func (s *Service) inRegularSync() bool {
|
||||
currentSlot := s.CurrentSlot()
|
||||
fc := s.cfg.ForkChoiceStore
|
||||
if currentSlot-fc.HighestReceivedBlockSlot() < 2*params.BeaconConfig().SlotsPerEpoch {
|
||||
return true
|
||||
}
|
||||
return fc.HighestReceivedBlockDelay() < params.BeaconConfig().SlotsPerEpoch
|
||||
}
|
||||
|
||||
@@ -593,26 +593,3 @@ func TestService_IsFinalized(t *testing.T) {
|
||||
require.Equal(t, true, c.IsFinalized(ctx, br))
|
||||
require.Equal(t, false, c.IsFinalized(ctx, [32]byte{'c'}))
|
||||
}
|
||||
|
||||
func TestService_inRegularSync(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
c := &Service{cfg: &config{ForkChoiceStore: doublylinkedtree.New()}, head: &head{root: [32]byte{'b'}}}
|
||||
ojc := ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
ofc := ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
st, blkRoot, err := prepareForkchoiceState(ctx, 100, [32]byte{'a'}, [32]byte{}, params.BeaconConfig().ZeroHash, ojc, ofc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.cfg.ForkChoiceStore.InsertNode(ctx, st, blkRoot))
|
||||
require.Equal(t, false, c.inRegularSync())
|
||||
c.SetGenesisTime(time.Now().Add(time.Second * time.Duration(-1*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot))))
|
||||
st, blkRoot, err = prepareForkchoiceState(ctx, 128, [32]byte{'b'}, [32]byte{'a'}, params.BeaconConfig().ZeroHash, ojc, ofc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.cfg.ForkChoiceStore.InsertNode(ctx, st, blkRoot))
|
||||
require.Equal(t, false, c.inRegularSync())
|
||||
|
||||
c.SetGenesisTime(time.Now().Add(time.Second * time.Duration(-5*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot))))
|
||||
require.Equal(t, true, c.inRegularSync())
|
||||
|
||||
c.SetGenesisTime(time.Now().Add(time.Second * time.Duration(-1*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot))))
|
||||
c.cfg.ForkChoiceStore.SetGenesisTime(uint64(time.Now().Unix()))
|
||||
require.Equal(t, true, c.inRegularSync())
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package blockchain
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/time"
|
||||
)
|
||||
|
||||
var stateDefragmentationTime = promauto.NewSummary(prometheus.SummaryOpts{
|
||||
Name: "head_state_defragmentation_milliseconds",
|
||||
Help: "Milliseconds it takes to defragment the head state",
|
||||
})
|
||||
|
||||
// This method defragments our state, so that any specific fields which have
|
||||
// a higher number of fragmented indexes are reallocated to a new separate slice for
|
||||
// that field.
|
||||
func (s *Service) defragmentState(st state.BeaconState) {
|
||||
if !features.Get().EnableExperimentalState {
|
||||
return
|
||||
}
|
||||
startTime := time.Now()
|
||||
st.Defragment()
|
||||
elapsedTime := time.Since(startTime)
|
||||
stateDefragmentationTime.Observe(float64(elapsedTime.Milliseconds()))
|
||||
}
|
||||
@@ -67,9 +67,7 @@ func (s *Service) postBlockProcess(cfg *postBlockProcessConfig) error {
|
||||
startTime := time.Now()
|
||||
fcuArgs := &fcuConfig{}
|
||||
|
||||
if s.inRegularSync() {
|
||||
defer s.handleSecondFCUCall(cfg, fcuArgs)
|
||||
}
|
||||
defer s.handleSecondFCUCall(cfg, fcuArgs)
|
||||
defer s.sendLightClientFeeds(cfg)
|
||||
defer s.sendStateFeedOnBlock(cfg)
|
||||
defer reportProcessingTime(startTime)
|
||||
@@ -582,15 +580,10 @@ func (s *Service) lateBlockTasks(ctx context.Context) {
|
||||
if s.CurrentSlot() == s.HeadSlot() {
|
||||
return
|
||||
}
|
||||
s.cfg.ForkChoiceStore.RLock()
|
||||
defer s.cfg.ForkChoiceStore.RUnlock()
|
||||
// return early if we are in init sync
|
||||
if !s.inRegularSync() {
|
||||
return
|
||||
}
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.MissedSlot,
|
||||
})
|
||||
|
||||
s.headLock.RLock()
|
||||
headRoot := s.headRoot()
|
||||
headState := s.headState(ctx)
|
||||
@@ -605,22 +598,18 @@ func (s *Service) lateBlockTasks(ctx context.Context) {
|
||||
if err := transition.UpdateNextSlotCache(ctx, lastRoot, lastState); err != nil {
|
||||
log.WithError(err).Debug("could not update next slot state cache")
|
||||
}
|
||||
// handleEpochBoundary requires a forkchoice lock to obtain the target root.
|
||||
s.cfg.ForkChoiceStore.RLock()
|
||||
if err := s.handleEpochBoundary(ctx, currentSlot, headState, headRoot[:]); err != nil {
|
||||
log.WithError(err).Error("lateBlockTasks: could not update epoch boundary caches")
|
||||
}
|
||||
s.cfg.ForkChoiceStore.RUnlock()
|
||||
// return early if we already started building a block for the current
|
||||
// head root
|
||||
_, has := s.cfg.PayloadIDCache.PayloadID(s.CurrentSlot()+1, headRoot)
|
||||
if has {
|
||||
return
|
||||
}
|
||||
|
||||
attribute := s.getPayloadAttribute(ctx, headState, s.CurrentSlot()+1, headRoot[:])
|
||||
// return early if we are not proposing next slot
|
||||
if attribute.IsEmpty() {
|
||||
return
|
||||
}
|
||||
|
||||
s.headLock.RLock()
|
||||
headBlock, err := s.headBlock()
|
||||
if err != nil {
|
||||
@@ -631,12 +620,18 @@ func (s *Service) lateBlockTasks(ctx context.Context) {
|
||||
s.headLock.RUnlock()
|
||||
|
||||
fcuArgs := &fcuConfig{
|
||||
headState: headState,
|
||||
headRoot: headRoot,
|
||||
headBlock: headBlock,
|
||||
attributes: attribute,
|
||||
headState: headState,
|
||||
headRoot: headRoot,
|
||||
headBlock: headBlock,
|
||||
}
|
||||
fcuArgs.attributes = s.getPayloadAttribute(ctx, headState, s.CurrentSlot()+1, headRoot[:])
|
||||
// return early if we are not proposing next slot
|
||||
if fcuArgs.attributes.IsEmpty() {
|
||||
return
|
||||
}
|
||||
s.cfg.ForkChoiceStore.RLock()
|
||||
_, err = s.notifyForkchoiceUpdate(ctx, fcuArgs)
|
||||
s.cfg.ForkChoiceStore.RUnlock()
|
||||
if err != nil {
|
||||
log.WithError(err).Debug("could not perform late block tasks: failed to update forkchoice with engine")
|
||||
}
|
||||
|
||||
@@ -37,9 +37,6 @@ func (s *Service) getFCUArgs(cfg *postBlockProcessConfig, fcuArgs *fcuConfig) er
|
||||
if err := s.getFCUArgsEarlyBlock(cfg, fcuArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
if !s.inRegularSync() {
|
||||
return nil
|
||||
}
|
||||
slot := cfg.signed.Block().Slot()
|
||||
if slots.WithinVotingWindow(uint64(s.genesisTime.Unix()), slot) {
|
||||
return nil
|
||||
|
||||
@@ -150,9 +150,7 @@ func (s *Service) UpdateHead(ctx context.Context, proposingSlot primitives.Slot)
|
||||
headBlock: headBlock,
|
||||
proposingSlot: proposingSlot,
|
||||
}
|
||||
if s.inRegularSync() {
|
||||
fcuArgs.attributes = s.getPayloadAttribute(ctx, headState, proposingSlot, newHeadRoot[:])
|
||||
}
|
||||
fcuArgs.attributes = s.getPayloadAttribute(ctx, headState, proposingSlot, newHeadRoot[:])
|
||||
if fcuArgs.attributes != nil && s.shouldOverrideFCU(newHeadRoot, proposingSlot) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -123,9 +123,6 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.ReadOnlySig
|
||||
}
|
||||
daWaitedTime := time.Since(daStartTime)
|
||||
|
||||
// Defragment the state before continuing block processing.
|
||||
s.defragmentState(postState)
|
||||
|
||||
// The rest of block processing takes a lock on forkchoice.
|
||||
s.cfg.ForkChoiceStore.Lock()
|
||||
defer s.cfg.ForkChoiceStore.Unlock()
|
||||
|
||||
@@ -15,12 +15,11 @@ import (
|
||||
|
||||
// AttDelta contains rewards and penalties for a single attestation.
|
||||
type AttDelta struct {
|
||||
HeadReward uint64
|
||||
SourceReward uint64
|
||||
SourcePenalty uint64
|
||||
TargetReward uint64
|
||||
TargetPenalty uint64
|
||||
InactivityPenalty uint64
|
||||
HeadReward uint64
|
||||
SourceReward uint64
|
||||
SourcePenalty uint64
|
||||
TargetReward uint64
|
||||
TargetPenalty uint64
|
||||
}
|
||||
|
||||
// InitializePrecomputeValidators precomputes individual validator for its attested balances and the total sum of validators attested balances of the epoch.
|
||||
@@ -252,7 +251,7 @@ func ProcessRewardsAndPenaltiesPrecompute(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
balances[i] = helpers.DecreaseBalanceWithVal(balances[i], delta.SourcePenalty+delta.TargetPenalty+delta.InactivityPenalty)
|
||||
balances[i] = helpers.DecreaseBalanceWithVal(balances[i], delta.SourcePenalty+delta.TargetPenalty)
|
||||
|
||||
vals[i].AfterEpochTransitionBalance = balances[i]
|
||||
}
|
||||
@@ -352,7 +351,7 @@ func attestationDelta(
|
||||
if err != nil {
|
||||
return &AttDelta{}, err
|
||||
}
|
||||
attDelta.InactivityPenalty = n / inactivityDenominator
|
||||
attDelta.TargetPenalty += n / inactivityDenominator
|
||||
}
|
||||
|
||||
return attDelta, nil
|
||||
|
||||
@@ -220,7 +220,7 @@ func TestAttestationsDelta(t *testing.T) {
|
||||
penalties := make([]uint64, len(deltas))
|
||||
for i, d := range deltas {
|
||||
rewards[i] = d.HeadReward + d.SourceReward + d.TargetReward
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty + d.InactivityPenalty
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty
|
||||
}
|
||||
|
||||
// Reward amount should increase as validator index increases due to setup.
|
||||
@@ -258,7 +258,7 @@ func TestAttestationsDeltaBellatrix(t *testing.T) {
|
||||
penalties := make([]uint64, len(deltas))
|
||||
for i, d := range deltas {
|
||||
rewards[i] = d.HeadReward + d.SourceReward + d.TargetReward
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty + d.InactivityPenalty
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty
|
||||
}
|
||||
|
||||
// Reward amount should increase as validator index increases due to setup.
|
||||
@@ -306,7 +306,7 @@ func TestProcessRewardsAndPenaltiesPrecompute_Ok(t *testing.T) {
|
||||
penalties := make([]uint64, len(deltas))
|
||||
for i, d := range deltas {
|
||||
rewards[i] = d.HeadReward + d.SourceReward + d.TargetReward
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty + d.InactivityPenalty
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty
|
||||
}
|
||||
for i := range rewards {
|
||||
wanted[i] += rewards[i]
|
||||
|
||||
@@ -57,10 +57,6 @@ func UpgradeToDeneb(state state.BeaconState) (state.BeaconState, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
historicalRoots, err := state.HistoricalRoots()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := ðpb.BeaconStateDeneb{
|
||||
GenesisTime: state.GenesisTime(),
|
||||
@@ -74,7 +70,7 @@ func UpgradeToDeneb(state state.BeaconState) (state.BeaconState, error) {
|
||||
LatestBlockHeader: state.LatestBlockHeader(),
|
||||
BlockRoots: state.BlockRoots(),
|
||||
StateRoots: state.StateRoots(),
|
||||
HistoricalRoots: historicalRoots,
|
||||
HistoricalRoots: [][]byte{},
|
||||
Eth1Data: state.Eth1Data(),
|
||||
Eth1DataVotes: state.Eth1DataVotes(),
|
||||
Eth1DepositIndex: state.Eth1DepositIndex(),
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
|
||||
func TestUpgradeToDeneb(t *testing.T) {
|
||||
st, _ := util.DeterministicGenesisStateCapella(t, params.BeaconConfig().MaxValidatorsPerCommittee)
|
||||
require.NoError(t, st.SetHistoricalRoots([][]byte{{1}}))
|
||||
preForkState := st.Copy()
|
||||
mSt, err := deneb.UpgradeToDeneb(st)
|
||||
require.NoError(t, err)
|
||||
@@ -47,12 +46,6 @@ func TestUpgradeToDeneb(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.DeepSSZEqual(t, make([]uint64, numValidators), s)
|
||||
|
||||
hr1, err := preForkState.HistoricalRoots()
|
||||
require.NoError(t, err)
|
||||
hr2, err := mSt.HistoricalRoots()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, hr1, hr2)
|
||||
|
||||
f := mSt.Fork()
|
||||
require.DeepSSZEqual(t, ðpb.Fork{
|
||||
PreviousVersion: st.Fork().CurrentVersion,
|
||||
|
||||
@@ -156,7 +156,7 @@ func (bs *BlobStorage) Save(sidecar blocks.VerifiedROBlob) error {
|
||||
}
|
||||
partialMoved = true
|
||||
blobsWrittenCounter.Inc()
|
||||
blobSaveLatency.Observe(float64(time.Since(startTime).Milliseconds()))
|
||||
blobSaveLatency.Observe(time.Since(startTime).Seconds())
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ func (bs *BlobStorage) Get(root [32]byte, idx uint64) (blocks.VerifiedROBlob, er
|
||||
return blocks.VerifiedROBlob{}, err
|
||||
}
|
||||
defer func() {
|
||||
blobFetchLatency.Observe(float64(time.Since(startTime).Milliseconds()))
|
||||
blobFetchLatency.Observe(time.Since(startTime).Seconds())
|
||||
}()
|
||||
return verification.BlobSidecarNoop(ro)
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
blobBuckets = []float64{3, 5, 7, 9, 11, 13}
|
||||
blobBuckets = []float64{0.00003, 0.00005, 0.00007, 0.00009, 0.00011, 0.00013, 0.00015}
|
||||
blobSaveLatency = promauto.NewHistogram(prometheus.HistogramOpts{
|
||||
Name: "blob_storage_save_latency",
|
||||
Help: "Latency of BlobSidecar storage save operations in milliseconds",
|
||||
Help: "Latency of BlobSidecar storage save operations in seconds",
|
||||
Buckets: blobBuckets,
|
||||
})
|
||||
blobFetchLatency = promauto.NewHistogram(prometheus.HistogramOpts{
|
||||
Name: "blob_storage_get_latency",
|
||||
Help: "Latency of BlobSidecar storage get operations in milliseconds",
|
||||
Help: "Latency of BlobSidecar storage get operations in seconds",
|
||||
Buckets: blobBuckets,
|
||||
})
|
||||
blobsPrunedCounter = promauto.NewCounter(prometheus.CounterOpts{
|
||||
|
||||
@@ -2,4 +2,4 @@ package execution
|
||||
|
||||
import "github.com/sirupsen/logrus"
|
||||
|
||||
var log = logrus.WithField("prefix", "execution")
|
||||
var log = logrus.WithField("prefix", "powchain")
|
||||
|
||||
@@ -77,6 +77,5 @@ go_test(
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -89,25 +89,17 @@ func (n *Node) updateBestDescendant(ctx context.Context, justifiedEpoch, finaliz
|
||||
return nil
|
||||
}
|
||||
|
||||
// getVotingSource returns the voting source if we were to make an FFG vote for this node in the currentEpoch
|
||||
func (n *Node) getVotingSource(currentEpoch primitives.Epoch) primitives.Epoch {
|
||||
// If the block is from a past epoch, then return the unrealized justified epoch
|
||||
if slots.ToEpoch(n.slot) < currentEpoch {
|
||||
return n.unrealizedJustifiedEpoch
|
||||
}
|
||||
// Otherwise return the justified epoch
|
||||
return n.justifiedEpoch
|
||||
}
|
||||
|
||||
// viableForHead returns true if the node is viable to head.
|
||||
// Any node with different finalized or justified epoch than
|
||||
// the ones in fork choice store should not be viable to head.
|
||||
func (n *Node) viableForHead(justifiedEpoch, currentEpoch primitives.Epoch) bool {
|
||||
if justifiedEpoch == 0 {
|
||||
return true
|
||||
justified := justifiedEpoch == n.justifiedEpoch || justifiedEpoch == 0
|
||||
if !justified && justifiedEpoch+1 == currentEpoch {
|
||||
if n.unrealizedJustifiedEpoch+1 >= currentEpoch && n.justifiedEpoch+2 >= currentEpoch {
|
||||
justified = true
|
||||
}
|
||||
}
|
||||
votingSource := n.getVotingSource(currentEpoch)
|
||||
return votingSource == justifiedEpoch || votingSource+2 >= currentEpoch
|
||||
return justified
|
||||
}
|
||||
|
||||
func (n *Node) leadsToViableHead(justifiedEpoch, currentEpoch primitives.Epoch) bool {
|
||||
|
||||
@@ -144,15 +144,9 @@ func TestNode_ViableForHead(t *testing.T) {
|
||||
}{
|
||||
{&Node{}, 0, true},
|
||||
{&Node{}, 1, false},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1, unrealizedJustifiedEpoch: 1}, 1, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1, unrealizedJustifiedEpoch: 1}, 2, false},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1, unrealizedJustifiedEpoch: 2}, 2, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1, unrealizedJustifiedEpoch: 2}, 3, false},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1, unrealizedJustifiedEpoch: 3}, 3, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 2, unrealizedJustifiedEpoch: 3}, 3, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 2, unrealizedJustifiedEpoch: 2}, 4, false},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 2, unrealizedJustifiedEpoch: 3}, 4, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 3, unrealizedJustifiedEpoch: 4}, 4, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1}, 1, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1}, 2, false},
|
||||
{&Node{finalizedEpoch: 3, justifiedEpoch: 4}, 4, true},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
got := tc.n.viableForHead(tc.justifiedEpoch, 5)
|
||||
|
||||
@@ -240,20 +240,6 @@ func (f *ForkChoice) HighestReceivedBlockSlot() primitives.Slot {
|
||||
return f.store.highestReceivedNode.slot
|
||||
}
|
||||
|
||||
// HighestReceivedBlockSlotDelay returns the number of slots that the highest
|
||||
// received block was late when receiving it
|
||||
func (f *ForkChoice) HighestReceivedBlockDelay() primitives.Slot {
|
||||
n := f.store.highestReceivedNode
|
||||
if n == nil {
|
||||
return 0
|
||||
}
|
||||
secs, err := slots.SecondsSinceSlotStart(n.slot, f.store.genesisTime, n.timestamp)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return primitives.Slot(secs / params.BeaconConfig().SecondsPerSlot)
|
||||
}
|
||||
|
||||
// ReceivedBlocksLastEpoch returns the number of blocks received in the last epoch
|
||||
func (f *ForkChoice) ReceivedBlocksLastEpoch() (uint64, error) {
|
||||
count := uint64(0)
|
||||
|
||||
@@ -333,29 +333,26 @@ func TestForkChoice_ReceivedBlocksLastEpoch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), count)
|
||||
require.Equal(t, primitives.Slot(1), f.HighestReceivedBlockSlot())
|
||||
require.Equal(t, primitives.Slot(0), f.HighestReceivedBlockDelay())
|
||||
|
||||
// 64
|
||||
// Received block last epoch is 1
|
||||
_, err = s.insert(context.Background(), 64, [32]byte{'A'}, b, b, 1, 1)
|
||||
require.NoError(t, err)
|
||||
s.genesisTime = uint64(time.Now().Add(time.Duration((-64*int64(params.BeaconConfig().SecondsPerSlot))-1) * time.Second).Unix())
|
||||
s.genesisTime = uint64(time.Now().Add(time.Duration(-64*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second).Unix())
|
||||
count, err = f.ReceivedBlocksLastEpoch()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), count)
|
||||
require.Equal(t, primitives.Slot(64), f.HighestReceivedBlockSlot())
|
||||
require.Equal(t, primitives.Slot(0), f.HighestReceivedBlockDelay())
|
||||
|
||||
// 64 65
|
||||
// Received block last epoch is 2
|
||||
_, err = s.insert(context.Background(), 65, [32]byte{'B'}, b, b, 1, 1)
|
||||
require.NoError(t, err)
|
||||
s.genesisTime = uint64(time.Now().Add(time.Duration(-66*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second).Unix())
|
||||
s.genesisTime = uint64(time.Now().Add(time.Duration(-65*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second).Unix())
|
||||
count, err = f.ReceivedBlocksLastEpoch()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), count)
|
||||
require.Equal(t, primitives.Slot(65), f.HighestReceivedBlockSlot())
|
||||
require.Equal(t, primitives.Slot(1), f.HighestReceivedBlockDelay())
|
||||
|
||||
// 64 65 66
|
||||
// Received block last epoch is 3
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
)
|
||||
|
||||
func TestStore_SetUnrealizedEpochs(t *testing.T) {
|
||||
@@ -64,14 +63,14 @@ func TestStore_UpdateUnrealizedCheckpoints(t *testing.T) {
|
||||
func TestStore_LongFork(t *testing.T) {
|
||||
f := setup(1, 1)
|
||||
ctx := context.Background()
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, 75, [32]byte{'a'}, params.BeaconConfig().ZeroHash, [32]byte{'A'}, 1, 1)
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, 100, [32]byte{'a'}, params.BeaconConfig().ZeroHash, [32]byte{'A'}, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 80, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'B'}, 1, 1)
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 101, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'B'}, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
require.NoError(t, f.store.setUnrealizedJustifiedEpoch([32]byte{'b'}, 2))
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 95, [32]byte{'c'}, [32]byte{'b'}, [32]byte{'C'}, 1, 1)
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 102, [32]byte{'c'}, [32]byte{'b'}, [32]byte{'C'}, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
require.NoError(t, f.store.setUnrealizedJustifiedEpoch([32]byte{'c'}, 2))
|
||||
@@ -79,28 +78,27 @@ func TestStore_LongFork(t *testing.T) {
|
||||
// Add an attestation to c, it is head
|
||||
f.ProcessAttestation(ctx, []uint64{0}, [32]byte{'c'}, 1)
|
||||
f.justifiedBalances = []uint64{100}
|
||||
c := f.store.nodeByRoot[[32]byte{'c'}]
|
||||
require.Equal(t, primitives.Epoch(2), slots.ToEpoch(c.slot))
|
||||
driftGenesisTime(f, c.slot, 0)
|
||||
headRoot, err := f.Head(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{'c'}, headRoot)
|
||||
|
||||
// c remains the head even if a block d with higher realized justification is seen
|
||||
// D is head even though its weight is lower.
|
||||
ha := [32]byte{'a'}
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 103, [32]byte{'d'}, [32]byte{'b'}, [32]byte{'D'}, 2, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
require.NoError(t, f.UpdateJustifiedCheckpoint(ctx, &forkchoicetypes.Checkpoint{Epoch: 2, Root: ha}))
|
||||
d := f.store.nodeByRoot[[32]byte{'d'}]
|
||||
require.Equal(t, primitives.Epoch(3), slots.ToEpoch(d.slot))
|
||||
driftGenesisTime(f, d.slot, 0)
|
||||
require.Equal(t, true, d.viableForHead(f.store.justifiedCheckpoint.Epoch, slots.ToEpoch(d.slot)))
|
||||
headRoot, err = f.Head(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{'d'}, headRoot)
|
||||
require.Equal(t, uint64(0), f.store.nodeByRoot[[32]byte{'d'}].weight)
|
||||
require.Equal(t, uint64(100), f.store.nodeByRoot[[32]byte{'c'}].weight)
|
||||
|
||||
// Update unrealized justification, c becomes head
|
||||
require.NoError(t, f.updateUnrealizedCheckpoints(ctx))
|
||||
headRoot, err = f.Head(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{'c'}, headRoot)
|
||||
require.Equal(t, uint64(0), f.store.nodeByRoot[[32]byte{'d'}].weight)
|
||||
require.Equal(t, uint64(100), f.store.nodeByRoot[[32]byte{'c'}].weight)
|
||||
}
|
||||
|
||||
// Epoch 1 Epoch 2 Epoch 3
|
||||
|
||||
@@ -64,7 +64,6 @@ type FastGetter interface {
|
||||
FinalizedPayloadBlockHash() [32]byte
|
||||
HasNode([32]byte) bool
|
||||
HighestReceivedBlockSlot() primitives.Slot
|
||||
HighestReceivedBlockDelay() primitives.Slot
|
||||
IsCanonical(root [32]byte) bool
|
||||
IsOptimistic(root [32]byte) (bool, error)
|
||||
IsViableForCheckpoint(*forkchoicetypes.Checkpoint) (bool, error)
|
||||
|
||||
@@ -114,13 +114,6 @@ func (ro *ROForkChoice) HighestReceivedBlockSlot() primitives.Slot {
|
||||
return ro.getter.HighestReceivedBlockSlot()
|
||||
}
|
||||
|
||||
// HighestReceivedBlockDelay delegates to the underlying forkchoice call, under a lock.
|
||||
func (ro *ROForkChoice) HighestReceivedBlockDelay() primitives.Slot {
|
||||
ro.l.RLock()
|
||||
defer ro.l.RUnlock()
|
||||
return ro.getter.HighestReceivedBlockDelay()
|
||||
}
|
||||
|
||||
// ReceivedBlocksLastEpoch delegates to the underlying forkchoice call, under a lock.
|
||||
func (ro *ROForkChoice) ReceivedBlocksLastEpoch() (uint64, error) {
|
||||
ro.l.RLock()
|
||||
|
||||
@@ -29,7 +29,6 @@ const (
|
||||
unrealizedJustifiedPayloadBlockHashCalled
|
||||
nodeCountCalled
|
||||
highestReceivedBlockSlotCalled
|
||||
highestReceivedBlockDelayCalled
|
||||
receivedBlocksLastEpochCalled
|
||||
weightCalled
|
||||
isOptimisticCalled
|
||||
@@ -114,11 +113,6 @@ func TestROLocking(t *testing.T) {
|
||||
call: highestReceivedBlockSlotCalled,
|
||||
cb: func(g FastGetter) { g.HighestReceivedBlockSlot() },
|
||||
},
|
||||
{
|
||||
name: "highestReceivedBlockDelayCalled",
|
||||
call: highestReceivedBlockDelayCalled,
|
||||
cb: func(g FastGetter) { g.HighestReceivedBlockDelay() },
|
||||
},
|
||||
{
|
||||
name: "receivedBlocksLastEpochCalled",
|
||||
call: receivedBlocksLastEpochCalled,
|
||||
@@ -251,11 +245,6 @@ func (ro *mockROForkchoice) HighestReceivedBlockSlot() primitives.Slot {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (ro *mockROForkchoice) HighestReceivedBlockDelay() primitives.Slot {
|
||||
ro.calls = append(ro.calls, highestReceivedBlockDelayCalled)
|
||||
return 0
|
||||
}
|
||||
|
||||
func (ro *mockROForkchoice) ReceivedBlocksLastEpoch() (uint64, error) {
|
||||
ro.calls = append(ro.calls, receivedBlocksLastEpochCalled)
|
||||
return 0, nil
|
||||
|
||||
@@ -6,7 +6,6 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/gateway",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//api:go_default_library",
|
||||
"//api/gateway:go_default_library",
|
||||
"//cmd/beacon-chain/flags:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
|
||||
@@ -2,7 +2,6 @@ package gateway
|
||||
|
||||
import (
|
||||
gwruntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/prysmaticlabs/prysm/v4/api"
|
||||
"github.com/prysmaticlabs/prysm/v4/api/gateway"
|
||||
"github.com/prysmaticlabs/prysm/v4/cmd/beacon-chain/flags"
|
||||
ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -41,7 +40,7 @@ func DefaultConfig(enableDebugRPCEndpoints bool, httpModules string) MuxConfig {
|
||||
},
|
||||
}),
|
||||
gwruntime.WithMarshalerOption(
|
||||
api.EventStreamMediaType, &gwruntime.EventSourceJSONPb{},
|
||||
"text/event-stream", &gwruntime.EventSourceJSONPb{},
|
||||
),
|
||||
)
|
||||
v1AlphaPbHandler = &gateway.PbMux{
|
||||
|
||||
@@ -42,7 +42,7 @@ func (s *Service) prepareForkChoiceAtts() {
|
||||
switch slotInterval.Interval {
|
||||
case 0:
|
||||
duration := time.Since(t)
|
||||
log.WithField("Duration", duration).Debug("Aggregated unaggregated attestations")
|
||||
log.WithField("Duration", duration).Debug("aggregated unaggregated attestations")
|
||||
batchForkChoiceAttsT1.Observe(float64(duration.Milliseconds()))
|
||||
case 1:
|
||||
batchForkChoiceAttsT2.Observe(float64(time.Since(t).Milliseconds()))
|
||||
|
||||
@@ -38,7 +38,6 @@ go_library(
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_grpc//codes:go_default_library",
|
||||
"@org_golang_x_sync//errgroup:go_default_library",
|
||||
],
|
||||
|
||||
@@ -11,15 +11,14 @@ import (
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
HeadFetcher blockchain.HeadFetcher
|
||||
FinalizedFetcher blockchain.FinalizationFetcher
|
||||
GenesisTimeFetcher blockchain.TimeFetcher
|
||||
SyncChecker sync.Checker
|
||||
Broadcaster p2p.Broadcaster
|
||||
SyncCommitteePool synccommittee.Pool
|
||||
OperationNotifier opfeed.Notifier
|
||||
AttestationCache *cache.AttestationCache
|
||||
StateGen stategen.StateManager
|
||||
P2P p2p.Broadcaster
|
||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||
HeadFetcher blockchain.HeadFetcher
|
||||
FinalizedFetcher blockchain.FinalizationFetcher
|
||||
GenesisTimeFetcher blockchain.TimeFetcher
|
||||
SyncChecker sync.Checker
|
||||
Broadcaster p2p.Broadcaster
|
||||
SyncCommitteePool synccommittee.Pool
|
||||
OperationNotifier opfeed.Notifier
|
||||
AttestationCache *cache.AttestationCache
|
||||
StateGen stategen.StateManager
|
||||
P2P p2p.Broadcaster
|
||||
}
|
||||
|
||||
@@ -29,12 +29,9 @@ import (
|
||||
prysmTime "github.com/prysmaticlabs/prysm/v4/time"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
var errOptimisticMode = errors.New("the node is currently optimistic and cannot serve validators")
|
||||
|
||||
// AggregateBroadcastFailedError represents an error scenario where
|
||||
// broadcasting an aggregate selection proof failed.
|
||||
type AggregateBroadcastFailedError struct {
|
||||
@@ -59,9 +56,6 @@ func (s *Service) ComputeValidatorPerformance(
|
||||
ctx context.Context,
|
||||
req *ethpb.ValidatorPerformanceRequest,
|
||||
) (*ethpb.ValidatorPerformanceResponse, *RpcError) {
|
||||
ctx, span := trace.StartSpan(ctx, "coreService.ComputeValidatorPerformance")
|
||||
defer span.End()
|
||||
|
||||
if s.SyncChecker.Syncing() {
|
||||
return nil, &RpcError{Reason: Unavailable, Err: errors.New("Syncing to latest head, not ready to respond")}
|
||||
}
|
||||
@@ -217,9 +211,6 @@ func (s *Service) SubmitSignedContributionAndProof(
|
||||
ctx context.Context,
|
||||
req *ethpb.SignedContributionAndProof,
|
||||
) *RpcError {
|
||||
ctx, span := trace.StartSpan(ctx, "coreService.SubmitSignedContributionAndProof")
|
||||
defer span.End()
|
||||
|
||||
errs, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
// Broadcasting and saving contribution into the pool in parallel. As one fail should not affect another.
|
||||
@@ -252,9 +243,6 @@ func (s *Service) SubmitSignedAggregateSelectionProof(
|
||||
ctx context.Context,
|
||||
req *ethpb.SignedAggregateSubmitRequest,
|
||||
) *RpcError {
|
||||
ctx, span := trace.StartSpan(ctx, "coreService.SubmitSignedAggregateSelectionProof")
|
||||
defer span.End()
|
||||
|
||||
if req.SignedAggregateAndProof == nil || req.SignedAggregateAndProof.Message == nil ||
|
||||
req.SignedAggregateAndProof.Message.Aggregate == nil || req.SignedAggregateAndProof.Message.Aggregate.Data == nil {
|
||||
return &RpcError{Err: errors.New("signed aggregate request can't be nil"), Reason: BadRequest}
|
||||
@@ -327,9 +315,6 @@ func (s *Service) AggregatedSigAndAggregationBits(
|
||||
func (s *Service) GetAttestationData(
|
||||
ctx context.Context, req *ethpb.AttestationDataRequest,
|
||||
) (*ethpb.AttestationData, *RpcError) {
|
||||
ctx, span := trace.StartSpan(ctx, "coreService.GetAttestationData")
|
||||
defer span.End()
|
||||
|
||||
if req.Slot != s.GenesisTimeFetcher.CurrentSlot() {
|
||||
return nil, &RpcError{Reason: BadRequest, Err: errors.Errorf("invalid request: slot %d is not the current slot %d", req.Slot, s.GenesisTimeFetcher.CurrentSlot())}
|
||||
}
|
||||
@@ -383,14 +368,6 @@ func (s *Service) GetAttestationData(
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// cache miss, we need to check for optimistic status before proceeding
|
||||
optimistic, err := s.OptimisticModeFetcher.IsOptimistic(ctx)
|
||||
if err != nil {
|
||||
return nil, &RpcError{Reason: Internal, Err: err}
|
||||
}
|
||||
if optimistic {
|
||||
return nil, &RpcError{Reason: Unavailable, Err: errOptimisticMode}
|
||||
}
|
||||
|
||||
headRoot, err := s.HeadFetcher.HeadRoot(ctx)
|
||||
if err != nil {
|
||||
@@ -435,9 +412,6 @@ func (s *Service) GetAttestationData(
|
||||
// SubmitSyncMessage submits the sync committee message to the network.
|
||||
// It also saves the sync committee message into the pending pool for block inclusion.
|
||||
func (s *Service) SubmitSyncMessage(ctx context.Context, msg *ethpb.SyncCommitteeMessage) *RpcError {
|
||||
ctx, span := trace.StartSpan(ctx, "coreService.SubmitSyncMessage")
|
||||
defer span.End()
|
||||
|
||||
errs, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
headSyncCommitteeIndices, err := s.HeadFetcher.HeadSyncCommitteeIndices(ctx, msg.ValidatorIndex, msg.Slot)
|
||||
|
||||
@@ -62,7 +62,7 @@ func (s *Server) GetBlock(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if httputil.RespondWithSsz(r) {
|
||||
if httputil.SszRequested(r) {
|
||||
s.getBlockSSZ(ctx, w, blk)
|
||||
} else {
|
||||
s.getBlock(ctx, w, blk)
|
||||
@@ -105,7 +105,7 @@ func (s *Server) GetBlockV2(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if httputil.RespondWithSsz(r) {
|
||||
if httputil.SszRequested(r) {
|
||||
s.getBlockSSZV2(ctx, w, blk)
|
||||
} else {
|
||||
s.getBlockV2(ctx, w, blk)
|
||||
@@ -205,7 +205,7 @@ func (s *Server) GetBlindedBlock(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if httputil.RespondWithSsz(r) {
|
||||
if httputil.SszRequested(r) {
|
||||
s.getBlindedBlockSSZ(ctx, w, blk)
|
||||
} else {
|
||||
s.getBlindedBlock(ctx, w, blk)
|
||||
@@ -953,7 +953,8 @@ func (s *Server) PublishBlindedBlock(w http.ResponseWriter, r *http.Request) {
|
||||
if shared.IsSyncing(r.Context(), w, s.SyncChecker, s.HeadFetcher, s.TimeFetcher, s.OptimisticModeFetcher) {
|
||||
return
|
||||
}
|
||||
if httputil.IsRequestSsz(r) {
|
||||
isSSZ := httputil.SszRequested(r)
|
||||
if isSSZ {
|
||||
s.publishBlindedBlockSSZ(ctx, w, r, false)
|
||||
} else {
|
||||
s.publishBlindedBlock(ctx, w, r, false)
|
||||
@@ -977,7 +978,8 @@ func (s *Server) PublishBlindedBlockV2(w http.ResponseWriter, r *http.Request) {
|
||||
if shared.IsSyncing(r.Context(), w, s.SyncChecker, s.HeadFetcher, s.TimeFetcher, s.OptimisticModeFetcher) {
|
||||
return
|
||||
}
|
||||
if httputil.IsRequestSsz(r) {
|
||||
isSSZ := httputil.SszRequested(r)
|
||||
if isSSZ {
|
||||
s.publishBlindedBlockSSZ(ctx, w, r, true)
|
||||
} else {
|
||||
s.publishBlindedBlock(ctx, w, r, true)
|
||||
@@ -1248,7 +1250,8 @@ func (s *Server) PublishBlock(w http.ResponseWriter, r *http.Request) {
|
||||
if shared.IsSyncing(r.Context(), w, s.SyncChecker, s.HeadFetcher, s.TimeFetcher, s.OptimisticModeFetcher) {
|
||||
return
|
||||
}
|
||||
if httputil.IsRequestSsz(r) {
|
||||
isSSZ := httputil.SszRequested(r)
|
||||
if isSSZ {
|
||||
s.publishBlockSSZ(ctx, w, r, false)
|
||||
} else {
|
||||
s.publishBlock(ctx, w, r, false)
|
||||
@@ -1270,7 +1273,8 @@ func (s *Server) PublishBlockV2(w http.ResponseWriter, r *http.Request) {
|
||||
if shared.IsSyncing(r.Context(), w, s.SyncChecker, s.HeadFetcher, s.TimeFetcher, s.OptimisticModeFetcher) {
|
||||
return
|
||||
}
|
||||
if httputil.IsRequestSsz(r) {
|
||||
isSSZ := httputil.SszRequested(r)
|
||||
if isSSZ {
|
||||
s.publishBlockSSZ(ctx, w, r, true)
|
||||
} else {
|
||||
s.publishBlock(ctx, w, r, true)
|
||||
|
||||
@@ -1169,7 +1169,7 @@ func TestPublishBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetPhase0().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1199,7 +1199,7 @@ func TestPublishBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetAltair().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Altair))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1224,7 +1224,7 @@ func TestPublishBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Bellatrix))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1250,7 +1250,7 @@ func TestPublishBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetCapella().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Capella))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1276,7 +1276,7 @@ func TestPublishBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetDeneb().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Deneb))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1296,7 +1296,7 @@ func TestPublishBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Bellatrix))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1317,7 +1317,7 @@ func TestPublishBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Capella))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1335,7 +1335,7 @@ func TestPublishBlockSSZ(t *testing.T) {
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte("foo")))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
server.PublishBlock(writer, request)
|
||||
@@ -1531,7 +1531,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetPhase0().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1561,7 +1561,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetAltair().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Altair))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1587,7 +1587,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Bellatrix))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1613,7 +1613,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedCapella().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Capella))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1639,7 +1639,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedDeneb().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Deneb))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1672,7 +1672,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Capella))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1690,7 +1690,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte("foo")))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
server.PublishBlindedBlock(writer, request)
|
||||
@@ -1899,7 +1899,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetPhase0().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1929,7 +1929,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetAltair().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Altair))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1954,7 +1954,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Bellatrix))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -1980,7 +1980,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetCapella().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Capella))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2006,7 +2006,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetDeneb().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Deneb))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2026,7 +2026,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Bellatrix))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2047,7 +2047,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Capella))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2061,7 +2061,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte(rpctesting.CapellaBlock)))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
server.PublishBlockV2(writer, request)
|
||||
@@ -2078,7 +2078,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte("foo")))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
server.PublishBlockV2(writer, request)
|
||||
@@ -2286,7 +2286,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetPhase0().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2316,7 +2316,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetAltair().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Altair))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2342,7 +2342,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Bellatrix))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2368,7 +2368,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedCapella().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Capella))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2394,7 +2394,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedDeneb().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Deneb))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2427,7 +2427,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
|
||||
ssz, err := genericBlock.GetBlindedBellatrix().MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(ssz))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
request.Header.Set(api.VersionHeader, version.String(version.Capella))
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
@@ -2441,7 +2441,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte(rpctesting.BlindedCapellaBlock)))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
server.PublishBlockV2(writer, request)
|
||||
@@ -2458,7 +2458,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte("foo")))
|
||||
request.Header.Set("Content-Type", api.OctetStreamMediaType)
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
server.PublishBlindedBlockV2(writer, request)
|
||||
|
||||
@@ -46,7 +46,8 @@ func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
|
||||
for i := range verifiedBlobs {
|
||||
sidecars = append(sidecars, verifiedBlobs[i].BlobSidecar)
|
||||
}
|
||||
if httputil.RespondWithSsz(r) {
|
||||
ssz := httputil.SszRequested(r)
|
||||
if ssz {
|
||||
sidecarResp := ð.BlobSidecars{
|
||||
Sidecars: sidecars,
|
||||
}
|
||||
|
||||
@@ -12,5 +12,5 @@ type Sidecar struct {
|
||||
SignedBeaconBlockHeader *shared.SignedBeaconBlockHeader `json:"signed_block_header"`
|
||||
KzgCommitment string `json:"kzg_commitment"`
|
||||
KzgProof string `json:"kzg_proof"`
|
||||
CommitmentInclusionProof []string `json:"kzg_commitment_inclusion_proof"`
|
||||
CommitmentInclusionProof []string `json:"commitment_inclusion_proof"`
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func (s *Server) GetBeaconStateV2(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if httputil.RespondWithSsz(r) {
|
||||
if httputil.SszRequested(r) {
|
||||
s.getBeaconStateSSZV2(ctx, w, []byte(stateId))
|
||||
} else {
|
||||
s.getBeaconStateV2(ctx, w, []byte(stateId))
|
||||
|
||||
@@ -8,9 +8,8 @@ go_library(
|
||||
"structs.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/events",
|
||||
visibility = ["//visibility:public"],
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//api:go_default_library",
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/core/feed:go_default_library",
|
||||
"//beacon-chain/core/feed/operation:go_default_library",
|
||||
@@ -19,7 +18,6 @@ go_library(
|
||||
"//beacon-chain/core/time:go_default_library",
|
||||
"//beacon-chain/core/transition:go_default_library",
|
||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
|
||||
@@ -5,10 +5,11 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
time2 "time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/api"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/operation"
|
||||
@@ -17,14 +18,11 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/network/httputil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -116,24 +114,16 @@ func (s *Server) StreamEvents(w http.ResponseWriter, r *http.Request) {
|
||||
defer stateSub.Unsubscribe()
|
||||
|
||||
// Set up SSE response headers
|
||||
w.Header().Set("Content-Type", api.EventStreamMediaType)
|
||||
w.Header().Set("Connection", api.KeepAlive)
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
|
||||
// Handle each event received and context cancellation.
|
||||
// We send a keepalive dummy message immediately to prevent clients
|
||||
// stalling while waiting for the first response chunk.
|
||||
// After that we send a keepalive dummy message every SECONDS_PER_SLOT
|
||||
// to prevent anyone (e.g. proxy servers) from closing connections.
|
||||
sendKeepalive(w, flusher)
|
||||
keepaliveTicker := time2.NewTicker(time2.Duration(params.BeaconConfig().SecondsPerSlot) * time2.Second)
|
||||
for {
|
||||
select {
|
||||
case event := <-opsChan:
|
||||
handleBlockOperationEvents(w, flusher, topicsMap, event)
|
||||
case event := <-stateChan:
|
||||
s.handleStateEvents(ctx, w, flusher, topicsMap, event)
|
||||
case <-keepaliveTicker.C:
|
||||
sendKeepalive(w, flusher)
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
@@ -515,10 +505,6 @@ func send(w http.ResponseWriter, flusher http.Flusher, name string, data interfa
|
||||
write(w, flusher, "event: %s\ndata: %s\n\n", name, string(j))
|
||||
}
|
||||
|
||||
func sendKeepalive(w http.ResponseWriter, flusher http.Flusher) {
|
||||
write(w, flusher, ":\n\n")
|
||||
}
|
||||
|
||||
func write(w http.ResponseWriter, flusher http.Flusher, format string, a ...any) {
|
||||
_, err := fmt.Fprintf(w, format, a...)
|
||||
if err != nil {
|
||||
|
||||
@@ -375,9 +375,7 @@ func TestStreamEvents_OperationsEvents(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
const operationsResult = `:
|
||||
|
||||
event: attestation
|
||||
const operationsResult = `event: attestation
|
||||
data: {"aggregation_bits":"0x00","data":{"slot":"0","index":"0","beacon_block_root":"0x0000000000000000000000000000000000000000000000000000000000000000","source":{"epoch":"0","root":"0x0000000000000000000000000000000000000000000000000000000000000000"},"target":{"epoch":"0","root":"0x0000000000000000000000000000000000000000000000000000000000000000"}},"signature":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
|
||||
|
||||
event: attestation
|
||||
@@ -403,9 +401,7 @@ data: {"signed_header_1":{"message":{"slot":"0","proposer_index":"0","parent_roo
|
||||
|
||||
`
|
||||
|
||||
const stateResult = `:
|
||||
|
||||
event: head
|
||||
const stateResult = `event: head
|
||||
data: {"slot":"0","block":"0x0000000000000000000000000000000000000000000000000000000000000000","state":"0x0000000000000000000000000000000000000000000000000000000000000000","epoch_transition":true,"execution_optimistic":false,"previous_duty_dependent_root":"0x0000000000000000000000000000000000000000000000000000000000000000","current_duty_dependent_root":"0x0000000000000000000000000000000000000000000000000000000000000000"}
|
||||
|
||||
event: finalized_checkpoint
|
||||
@@ -419,23 +415,17 @@ data: {"slot":"0","block":"0xeade62f0457b2fdf48e7d3fc4b60736688286be7c7a3ac4c9a1
|
||||
|
||||
`
|
||||
|
||||
const payloadAttributesBellatrixResult = `:
|
||||
|
||||
event: payload_attributes
|
||||
const payloadAttributesBellatrixResult = `event: payload_attributes
|
||||
data: {"version":"bellatrix","data":{"proposer_index":"0","proposal_slot":"1","parent_block_number":"0","parent_block_root":"0x0000000000000000000000000000000000000000000000000000000000000000","parent_block_hash":"0x0000000000000000000000000000000000000000000000000000000000000000","payload_attributes":{"timestamp":"12","prev_randao":"0x0000000000000000000000000000000000000000000000000000000000000000","suggested_fee_recipient":"0x0000000000000000000000000000000000000000"}}}
|
||||
|
||||
`
|
||||
|
||||
const payloadAttributesCapellaResult = `:
|
||||
|
||||
event: payload_attributes
|
||||
const payloadAttributesCapellaResult = `event: payload_attributes
|
||||
data: {"version":"capella","data":{"proposer_index":"0","proposal_slot":"1","parent_block_number":"0","parent_block_root":"0x0000000000000000000000000000000000000000000000000000000000000000","parent_block_hash":"0x0000000000000000000000000000000000000000000000000000000000000000","payload_attributes":{"timestamp":"12","prev_randao":"0x0000000000000000000000000000000000000000000000000000000000000000","suggested_fee_recipient":"0x0000000000000000000000000000000000000000","withdrawals":[]}}}
|
||||
|
||||
`
|
||||
|
||||
const payloadAttributesDenebResult = `:
|
||||
|
||||
event: payload_attributes
|
||||
const payloadAttributesDenebResult = `event: payload_attributes
|
||||
data: {"version":"deneb","data":{"proposer_index":"0","proposal_slot":"1","parent_block_number":"0","parent_block_root":"0x0000000000000000000000000000000000000000000000000000000000000000","parent_block_hash":"0x0000000000000000000000000000000000000000000000000000000000000000","payload_attributes":{"timestamp":"12","prev_randao":"0x0000000000000000000000000000000000000000000000000000000000000000","suggested_fee_recipient":"0x0000000000000000000000000000000000000000","withdrawals":[],"parent_beacon_block_root":"0xbef96cb938fd48b2403d3e662664325abb0102ed12737cbb80d717520e50cf4a"}}}
|
||||
|
||||
`
|
||||
|
||||
@@ -62,6 +62,7 @@ func (s *Server) BlockRewards(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// AttestationRewards retrieves attestation reward info for validators specified by array of public keys or validator index.
|
||||
// If no array is provided, return reward info for every validator.
|
||||
// TODO: Inclusion delay
|
||||
func (s *Server) AttestationRewards(w http.ResponseWriter, r *http.Request) {
|
||||
st, ok := s.attRewardsState(w, r)
|
||||
if !ok {
|
||||
@@ -276,10 +277,7 @@ func idealAttRewards(
|
||||
IsPrevEpochTargetAttester: true,
|
||||
IsPrevEpochHeadAttester: true,
|
||||
})
|
||||
idealRewards = append(idealRewards, IdealAttestationReward{
|
||||
EffectiveBalance: strconv.FormatUint(effectiveBalance, 10),
|
||||
Inactivity: strconv.FormatUint(0, 10),
|
||||
})
|
||||
idealRewards = append(idealRewards, IdealAttestationReward{EffectiveBalance: strconv.FormatUint(effectiveBalance, 10)})
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -301,11 +299,6 @@ func idealAttRewards(
|
||||
} else {
|
||||
idealRewards[i].Target = strconv.FormatUint(d.TargetReward, 10)
|
||||
}
|
||||
if d.InactivityPenalty > 0 {
|
||||
idealRewards[i].Inactivity = fmt.Sprintf("-%s", strconv.FormatUint(d.InactivityPenalty, 10))
|
||||
} else {
|
||||
idealRewards[i].Inactivity = strconv.FormatUint(d.InactivityPenalty, 10)
|
||||
}
|
||||
}
|
||||
return idealRewards, true
|
||||
}
|
||||
@@ -338,11 +331,6 @@ func totalAttRewards(
|
||||
} else {
|
||||
totalRewards[i].Target = strconv.FormatUint(d.TargetReward, 10)
|
||||
}
|
||||
if d.InactivityPenalty > 0 {
|
||||
totalRewards[i].Inactivity = fmt.Sprintf("-%s", strconv.FormatUint(d.InactivityPenalty, 10))
|
||||
} else {
|
||||
totalRewards[i].Inactivity = strconv.FormatUint(d.InactivityPenalty, 10)
|
||||
}
|
||||
}
|
||||
return totalRewards, true
|
||||
}
|
||||
|
||||
@@ -396,7 +396,7 @@ func TestAttestationRewards(t *testing.T) {
|
||||
FinalizationFetcher: mockChainService,
|
||||
}
|
||||
|
||||
t.Run("ideal rewards", func(t *testing.T) {
|
||||
t.Run("ok - ideal rewards", func(t *testing.T) {
|
||||
url := "http://only.the.epoch.number.at.the.end.is.important/1"
|
||||
request := httptest.NewRequest("POST", url, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
@@ -419,7 +419,7 @@ func TestAttestationRewards(t *testing.T) {
|
||||
}
|
||||
assert.Equal(t, uint64(20756849), sum)
|
||||
})
|
||||
t.Run("filtered vals", func(t *testing.T) {
|
||||
t.Run("ok - filtered vals", func(t *testing.T) {
|
||||
url := "http://only.the.epoch.number.at.the.end.is.important/1"
|
||||
var body bytes.Buffer
|
||||
pubkey := fmt.Sprintf("%#x", secretKeys[10].PublicKey().Marshal())
|
||||
@@ -448,7 +448,7 @@ func TestAttestationRewards(t *testing.T) {
|
||||
}
|
||||
assert.Equal(t, uint64(794265), sum)
|
||||
})
|
||||
t.Run("all vals", func(t *testing.T) {
|
||||
t.Run("ok - all vals", func(t *testing.T) {
|
||||
url := "http://only.the.epoch.number.at.the.end.is.important/1"
|
||||
request := httptest.NewRequest("POST", url, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
@@ -471,12 +471,36 @@ func TestAttestationRewards(t *testing.T) {
|
||||
}
|
||||
assert.Equal(t, uint64(54221955), sum)
|
||||
})
|
||||
t.Run("penalty", func(t *testing.T) {
|
||||
st := st.Copy()
|
||||
validators := st.Validators()
|
||||
t.Run("ok - penalty", func(t *testing.T) {
|
||||
st, err := util.NewBeaconStateCapella()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, st.SetSlot(params.BeaconConfig().SlotsPerEpoch*3-1))
|
||||
validators := make([]*eth.Validator, 0, valCount)
|
||||
balances := make([]uint64, 0, valCount)
|
||||
for i := 0; i < valCount; i++ {
|
||||
blsKey, err := bls.RandKey()
|
||||
require.NoError(t, err)
|
||||
validators = append(validators, ð.Validator{
|
||||
PublicKey: blsKey.PublicKey().Marshal(),
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance / 64 * uint64(i),
|
||||
})
|
||||
balances = append(balances, params.BeaconConfig().MaxEffectiveBalance/64*uint64(i))
|
||||
}
|
||||
validators[63].Slashed = true
|
||||
require.NoError(t, st.SetValidators(validators))
|
||||
require.NoError(t, st.SetBalances(balances))
|
||||
require.NoError(t, st.SetInactivityScores(make([]uint64, len(validators))))
|
||||
participation := make([]byte, len(validators))
|
||||
for i := range participation {
|
||||
participation[i] = 0b111
|
||||
}
|
||||
require.NoError(t, st.SetCurrentParticipationBits(participation))
|
||||
require.NoError(t, st.SetPreviousParticipationBits(participation))
|
||||
|
||||
currentSlot := params.BeaconConfig().SlotsPerEpoch * 3
|
||||
mockChainService := &mock.ChainService{Optimistic: true, Slot: ¤tSlot}
|
||||
s := &Server{
|
||||
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
|
||||
params.BeaconConfig().SlotsPerEpoch*3 - 1: st,
|
||||
@@ -501,44 +525,8 @@ func TestAttestationRewards(t *testing.T) {
|
||||
resp := &AttestationRewardsResponse{}
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||
assert.Equal(t, "0", resp.Data.TotalRewards[0].Head)
|
||||
assert.Equal(t, "-439299", resp.Data.TotalRewards[0].Source)
|
||||
assert.Equal(t, "-815841", resp.Data.TotalRewards[0].Target)
|
||||
assert.Equal(t, "0", resp.Data.TotalRewards[0].Inactivity)
|
||||
})
|
||||
t.Run("inactivity", func(t *testing.T) {
|
||||
st := st.Copy()
|
||||
validators := st.Validators()
|
||||
validators[63].Slashed = true
|
||||
require.NoError(t, st.SetValidators(validators))
|
||||
inactivityScores, err := st.InactivityScores()
|
||||
require.NoError(t, err)
|
||||
inactivityScores[63] = 10
|
||||
require.NoError(t, st.SetInactivityScores(inactivityScores))
|
||||
|
||||
s := &Server{
|
||||
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
|
||||
params.BeaconConfig().SlotsPerEpoch*3 - 1: st,
|
||||
}},
|
||||
TimeFetcher: mockChainService,
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
}
|
||||
|
||||
url := "http://only.the.epoch.number.at.the.end.is.important/1"
|
||||
var body bytes.Buffer
|
||||
valIds, err := json.Marshal([]string{"63"})
|
||||
require.NoError(t, err)
|
||||
_, err = body.Write(valIds)
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest("POST", url, &body)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
|
||||
s.AttestationRewards(writer, request)
|
||||
assert.Equal(t, http.StatusOK, writer.Code)
|
||||
resp := &AttestationRewardsResponse{}
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||
assert.Equal(t, "-4768", resp.Data.TotalRewards[0].Inactivity)
|
||||
assert.Equal(t, "-432270", resp.Data.TotalRewards[0].Source)
|
||||
assert.Equal(t, "-802788", resp.Data.TotalRewards[0].Target)
|
||||
})
|
||||
t.Run("invalid validator index/pubkey", func(t *testing.T) {
|
||||
url := "http://only.the.epoch.number.at.the.end.is.important/1"
|
||||
|
||||
@@ -31,7 +31,6 @@ type IdealAttestationReward struct {
|
||||
Head string `json:"head"`
|
||||
Target string `json:"target"`
|
||||
Source string `json:"source"`
|
||||
Inactivity string `json:"inactivity"`
|
||||
}
|
||||
|
||||
type TotalAttestationReward struct {
|
||||
@@ -39,7 +38,7 @@ type TotalAttestationReward struct {
|
||||
Head string `json:"head"`
|
||||
Target string `json:"target"`
|
||||
Source string `json:"source"`
|
||||
Inactivity string `json:"inactivity"`
|
||||
InclusionDelay string `json:"inclusion_delay"`
|
||||
}
|
||||
|
||||
type SyncCommitteeRewardsResponse struct {
|
||||
|
||||
@@ -388,6 +388,10 @@ func (s *Server) GetAttestationData(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if isOptimistic, err := shared.IsOptimistic(ctx, w, s.OptimisticModeFetcher); isOptimistic || err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, slot, ok := shared.UintFromQuery(w, r, "slot", true)
|
||||
if !ok {
|
||||
return
|
||||
|
||||
@@ -201,7 +201,7 @@ func (s *Server) ProduceBlockV3(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *Server) produceBlockV3(ctx context.Context, w http.ResponseWriter, r *http.Request, v1alpha1req *eth.BlockRequest, requiredType blockType) {
|
||||
isSSZ := httputil.RespondWithSsz(r)
|
||||
isSSZ := httputil.SszRequested(r)
|
||||
v1alpha1resp, err := s.V1Alpha1Server.GetBeaconBlock(ctx, v1alpha1req)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
|
||||
|
||||
@@ -831,11 +831,10 @@ func TestGetAttestationData(t *testing.T) {
|
||||
TimeFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
CoreService: &core.Service{
|
||||
HeadFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
OptimisticModeFetcher: chain,
|
||||
HeadFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -915,11 +914,10 @@ func TestGetAttestationData(t *testing.T) {
|
||||
TimeFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
CoreService: &core.Service{
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
GenesisTimeFetcher: chain,
|
||||
HeadFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
GenesisTimeFetcher: chain,
|
||||
HeadFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -961,9 +959,8 @@ func TestGetAttestationData(t *testing.T) {
|
||||
TimeFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
CoreService: &core.Service{
|
||||
GenesisTimeFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1020,11 +1017,10 @@ func TestGetAttestationData(t *testing.T) {
|
||||
TimeFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
CoreService: &core.Service{
|
||||
HeadFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
StateGen: stategen.New(db, doublylinkedtree.New()),
|
||||
FinalizedFetcher: chain,
|
||||
HeadFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
StateGen: stategen.New(db, doublylinkedtree.New()),
|
||||
FinalizedFetcher: chain,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1069,11 +1065,10 @@ func TestGetAttestationData(t *testing.T) {
|
||||
TimeFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
CoreService: &core.Service{
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
OptimisticModeFetcher: chain,
|
||||
HeadFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
HeadFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1156,11 +1151,10 @@ func TestGetAttestationData(t *testing.T) {
|
||||
TimeFetcher: chain,
|
||||
OptimisticModeFetcher: chain,
|
||||
CoreService: &core.Service{
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
OptimisticModeFetcher: chain,
|
||||
HeadFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
HeadFetcher: chain,
|
||||
GenesisTimeFetcher: chain,
|
||||
FinalizedFetcher: chain,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ go_library(
|
||||
"//beacon-chain/builder:go_default_library",
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/cache/depositcache:go_default_library",
|
||||
"//beacon-chain/core/altair:go_default_library",
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/feed:go_default_library",
|
||||
"//beacon-chain/core/feed/block:go_default_library",
|
||||
@@ -65,6 +66,7 @@ go_library(
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/payload-attribute:go_default_library",
|
||||
@@ -89,13 +91,13 @@ go_library(
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_golang_protobuf//ptypes/empty",
|
||||
"@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_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_bazel_rules_go//proto/wkt:empty_go_proto",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_grpc//codes:go_default_library",
|
||||
"@org_golang_google_grpc//status:go_default_library",
|
||||
@@ -139,7 +141,6 @@ common_deps = [
|
||||
"//beacon-chain/sync/initial-sync/testing:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
|
||||
@@ -31,6 +31,12 @@ func (vs *Server) GetAttestationData(ctx context.Context, req *ethpb.Attestation
|
||||
if vs.SyncChecker.Syncing() {
|
||||
return nil, status.Errorf(codes.Unavailable, "Syncing to latest head, not ready to respond")
|
||||
}
|
||||
|
||||
// An optimistic validator MUST NOT participate in attestation. (i.e., sign across the DOMAIN_BEACON_ATTESTER, DOMAIN_SELECTION_PROOF or DOMAIN_AGGREGATE_AND_PROOF domains).
|
||||
if err := vs.optimisticStatus(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := vs.CoreService.GetAttestationData(ctx, req)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(core.ErrorReasonToGRPC(err.Reason), "Could not get attestation data: %v", err.Err)
|
||||
|
||||
@@ -61,11 +61,10 @@ func TestAttestationDataAtSlot_HandlesFarAwayJustifiedEpoch(t *testing.T) {
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
TimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
CoreService: &core.Service{
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
HeadFetcher: &mock.ChainService{TargetRoot: blockRoot, Root: blockRoot[:]},
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
HeadFetcher: &mock.ChainService{TargetRoot: blockRoot, Root: blockRoot[:]},
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -116,9 +116,8 @@ func TestGetAttestationData_OK(t *testing.T) {
|
||||
GenesisTimeFetcher: &mock.ChainService{
|
||||
Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second),
|
||||
},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -177,8 +176,7 @@ func BenchmarkGetAttestationDataConcurrent(b *testing.B) {
|
||||
GenesisTimeFetcher: &mock.ChainService{
|
||||
Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second),
|
||||
},
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -224,10 +222,9 @@ func TestGetAttestationData_Optimistic(t *testing.T) {
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: true},
|
||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
||||
CoreService: &core.Service{
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
||||
HeadFetcher: &mock.ChainService{},
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: true},
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
||||
HeadFetcher: &mock.ChainService{},
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
},
|
||||
}
|
||||
_, err := as.GetAttestationData(context.Background(), ðpb.AttestationDataRequest{})
|
||||
@@ -243,11 +240,10 @@ func TestGetAttestationData_Optimistic(t *testing.T) {
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
TimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
||||
CoreService: &core.Service{
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
||||
HeadFetcher: &mock.ChainService{Optimistic: false, State: beaconState},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: ðpb.Checkpoint{}},
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now()},
|
||||
HeadFetcher: &mock.ChainService{Optimistic: false, State: beaconState},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: ðpb.Checkpoint{}},
|
||||
},
|
||||
}
|
||||
_, err = as.GetAttestationData(context.Background(), ðpb.AttestationDataRequest{})
|
||||
@@ -264,8 +260,7 @@ func TestServer_GetAttestationData_InvalidRequestSlot(t *testing.T) {
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
TimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
CoreService: &core.Service{
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -306,11 +301,10 @@ func TestServer_GetAttestationData_RequestSlotIsDifferentThanCurrentSlot(t *test
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
TimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
CoreService: &core.Service{
|
||||
HeadFetcher: &mock.ChainService{TargetRoot: blockRoot2, Root: blockRoot[:]},
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
StateGen: stategen.New(db, doublylinkedtree.New()),
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
HeadFetcher: &mock.ChainService{TargetRoot: blockRoot2, Root: blockRoot[:]},
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
StateGen: stategen.New(db, doublylinkedtree.New()),
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
},
|
||||
}
|
||||
util.SaveBlock(t, ctx, db, block)
|
||||
@@ -352,9 +346,8 @@ func TestGetAttestationData_SucceedsInFirstEpoch(t *testing.T) {
|
||||
HeadFetcher: &mock.ChainService{
|
||||
TargetRoot: targetRoot, Root: blockRoot[:],
|
||||
},
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
OptimisticModeFetcher: &mock.ChainService{Optimistic: false},
|
||||
GenesisTimeFetcher: &mock.ChainService{Genesis: prysmTime.Now().Add(time.Duration(-1*offset) * time.Second)},
|
||||
FinalizedFetcher: &mock.ChainService{CurrentJustifiedCheckPoint: justifiedCheckpoint},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -359,17 +359,16 @@ func (s *Service) Start() {
|
||||
})
|
||||
|
||||
coreService := &core.Service{
|
||||
HeadFetcher: s.cfg.HeadFetcher,
|
||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
||||
SyncChecker: s.cfg.SyncService,
|
||||
Broadcaster: s.cfg.Broadcaster,
|
||||
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
|
||||
OperationNotifier: s.cfg.OperationNotifier,
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
StateGen: s.cfg.StateGen,
|
||||
P2P: s.cfg.Broadcaster,
|
||||
FinalizedFetcher: s.cfg.FinalizationFetcher,
|
||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||
HeadFetcher: s.cfg.HeadFetcher,
|
||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
||||
SyncChecker: s.cfg.SyncService,
|
||||
Broadcaster: s.cfg.Broadcaster,
|
||||
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
|
||||
OperationNotifier: s.cfg.OperationNotifier,
|
||||
AttestationCache: cache.NewAttestationCache(),
|
||||
StateGen: s.cfg.StateGen,
|
||||
P2P: s.cfg.Broadcaster,
|
||||
FinalizedFetcher: s.cfg.FinalizationFetcher,
|
||||
}
|
||||
|
||||
validatorServer := &validatorv1alpha1.Server{
|
||||
|
||||
@@ -22,7 +22,6 @@ type BeaconState interface {
|
||||
WriteOnlyBeaconState
|
||||
Copy() BeaconState
|
||||
CopyAllTries()
|
||||
Defragment()
|
||||
HashTreeRoot(ctx context.Context) ([32]byte, error)
|
||||
Prover
|
||||
json.Marshaler
|
||||
|
||||
@@ -123,55 +123,6 @@ func NewMultiValueValidators(vals []*ethpb.Validator) *MultiValueValidators {
|
||||
return mv
|
||||
}
|
||||
|
||||
// Defragment checks whether each individual multi-value field in our state is fragmented
|
||||
// and if it is, it will 'reset' the field to create a new multivalue object.
|
||||
func (b *BeaconState) Defragment() {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
if b.blockRootsMultiValue != nil && b.blockRootsMultiValue.IsFragmented() {
|
||||
initialMVslice := b.blockRootsMultiValue
|
||||
b.blockRootsMultiValue = b.blockRootsMultiValue.Reset(b)
|
||||
initialMVslice.Detach(b)
|
||||
multiValueCountGauge.WithLabelValues(types.BlockRoots.String()).Inc()
|
||||
runtime.SetFinalizer(b.blockRootsMultiValue, blockRootsFinalizer)
|
||||
}
|
||||
if b.stateRootsMultiValue != nil && b.stateRootsMultiValue.IsFragmented() {
|
||||
initialMVslice := b.stateRootsMultiValue
|
||||
b.stateRootsMultiValue = b.stateRootsMultiValue.Reset(b)
|
||||
initialMVslice.Detach(b)
|
||||
multiValueCountGauge.WithLabelValues(types.StateRoots.String()).Inc()
|
||||
runtime.SetFinalizer(b.stateRootsMultiValue, stateRootsFinalizer)
|
||||
}
|
||||
if b.randaoMixesMultiValue != nil && b.randaoMixesMultiValue.IsFragmented() {
|
||||
initialMVslice := b.randaoMixesMultiValue
|
||||
b.randaoMixesMultiValue = b.randaoMixesMultiValue.Reset(b)
|
||||
initialMVslice.Detach(b)
|
||||
multiValueCountGauge.WithLabelValues(types.RandaoMixes.String()).Inc()
|
||||
runtime.SetFinalizer(b.randaoMixesMultiValue, randaoMixesFinalizer)
|
||||
}
|
||||
if b.balancesMultiValue != nil && b.balancesMultiValue.IsFragmented() {
|
||||
initialMVslice := b.balancesMultiValue
|
||||
b.balancesMultiValue = b.balancesMultiValue.Reset(b)
|
||||
initialMVslice.Detach(b)
|
||||
multiValueCountGauge.WithLabelValues(types.Balances.String()).Inc()
|
||||
runtime.SetFinalizer(b.balancesMultiValue, balancesFinalizer)
|
||||
}
|
||||
if b.validatorsMultiValue != nil && b.validatorsMultiValue.IsFragmented() {
|
||||
initialMVslice := b.validatorsMultiValue
|
||||
b.validatorsMultiValue = b.validatorsMultiValue.Reset(b)
|
||||
initialMVslice.Detach(b)
|
||||
multiValueCountGauge.WithLabelValues(types.Validators.String()).Inc()
|
||||
runtime.SetFinalizer(b.validatorsMultiValue, validatorsFinalizer)
|
||||
}
|
||||
if b.inactivityScoresMultiValue != nil && b.inactivityScoresMultiValue.IsFragmented() {
|
||||
initialMVslice := b.inactivityScoresMultiValue
|
||||
b.inactivityScoresMultiValue = b.inactivityScoresMultiValue.Reset(b)
|
||||
initialMVslice.Detach(b)
|
||||
multiValueCountGauge.WithLabelValues(types.InactivityScores.String()).Inc()
|
||||
runtime.SetFinalizer(b.inactivityScoresMultiValue, inactivityScoresFinalizer)
|
||||
}
|
||||
}
|
||||
|
||||
func randaoMixesFinalizer(m *MultiValueRandaoMixes) {
|
||||
multiValueCountGauge.WithLabelValues(types.RandaoMixes.String()).Dec()
|
||||
}
|
||||
|
||||
@@ -606,7 +606,7 @@ func TestBlocksFetcher_WaitForBandwidth(t *testing.T) {
|
||||
p1.Connect(p2)
|
||||
require.Equal(t, 1, len(p1.BHost.Network().Peers()), "Expected peers to be connected")
|
||||
req := ðpb.BeaconBlocksByRangeRequest{
|
||||
Count: 64,
|
||||
Count: 64,
|
||||
}
|
||||
|
||||
topic := p2pm.RPCBlocksByRangeTopicV1
|
||||
|
||||
@@ -79,6 +79,13 @@ func (s *Service) processPendingAtts(ctx context.Context) error {
|
||||
seen := s.seenPendingBlocks[bRoot]
|
||||
s.pendingQueueLock.RUnlock()
|
||||
if !seen {
|
||||
// Pending attestation's missing block has not arrived yet.
|
||||
log.WithFields(logrus.Fields{
|
||||
"currentSlot": s.cfg.clock.CurrentSlot(),
|
||||
"attSlot": attestations[0].Message.Aggregate.Data.Slot,
|
||||
"attCount": len(attestations),
|
||||
"blockRoot": hex.EncodeToString(bytesutil.Trunc(bRoot[:])),
|
||||
}).Debug("Requesting block for pending attestation")
|
||||
pendingRoots = append(pendingRoots, bRoot)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func TestProcessPendingAtts_NoBlockRequestBlock(t *testing.T) {
|
||||
a := ðpb.AggregateAttestationAndProof{Aggregate: ðpb.Attestation{Data: ðpb.AttestationData{Target: ðpb.Checkpoint{Root: make([]byte, 32)}}}}
|
||||
r.blkRootToPendingAtts[[32]byte{'A'}] = []*ethpb.SignedAggregateAttestationAndProof{{Message: a}}
|
||||
require.NoError(t, r.processPendingAtts(context.Background()))
|
||||
require.LogsContain(t, hook, "Requesting block by root")
|
||||
require.LogsContain(t, hook, "Requesting block for pending attestation")
|
||||
}
|
||||
|
||||
func TestProcessPendingAtts_HasBlockSaveUnAggregatedAtt(t *testing.T) {
|
||||
|
||||
@@ -126,6 +126,7 @@ func (s *Service) processPendingBlocks(ctx context.Context) error {
|
||||
// Request parent block if not in the pending queue and not in the database.
|
||||
isParentBlockInDB := s.cfg.beaconDB.HasBlock(ctx, parentRoot)
|
||||
if !inPendingQueue && !isParentBlockInDB && s.hasPeer() {
|
||||
log.WithFields(logrus.Fields{"currentSlot": b.Block().Slot(), "parentRoot": hex.EncodeToString(parentRoot[:])}).Debug("Requesting parent block")
|
||||
parentRoots = append(parentRoots, parentRoot)
|
||||
continue
|
||||
}
|
||||
@@ -282,8 +283,6 @@ func (s *Service) sendBatchRootRequest(ctx context.Context, roots [][32]byte, ra
|
||||
r := roots[i]
|
||||
if s.seenPendingBlocks[r] || s.cfg.chain.BlockBeingSynced(r) {
|
||||
roots = append(roots[:i], roots[i+1:]...)
|
||||
} else {
|
||||
log.WithField("blockRoot", fmt.Sprintf("%#x", r)).Debug("Requesting block by root")
|
||||
}
|
||||
}
|
||||
s.pendingQueueLock.RUnlock()
|
||||
|
||||
@@ -31,12 +31,11 @@ func DefaultDataDir() string {
|
||||
// Try to place the data folder in the user's home dir
|
||||
home := file.HomeDir()
|
||||
if home != "" {
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
if runtime.GOOS == "darwin" {
|
||||
return filepath.Join(home, "Library", "Eth2")
|
||||
case "windows":
|
||||
} else if runtime.GOOS == "windows" {
|
||||
return filepath.Join(home, "AppData", "Local", "Eth2")
|
||||
default:
|
||||
} else {
|
||||
return filepath.Join(home, ".eth2")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ type StdInPasswordReader struct {
|
||||
}
|
||||
|
||||
// ReadPassword reads a password from stdin.
|
||||
func (StdInPasswordReader) ReadPassword() (string, error) {
|
||||
func (_ StdInPasswordReader) ReadPassword() (string, error) {
|
||||
pwd, err := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||
return string(pwd), err
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ load("//tools:prysm_image.bzl", "prysm_image_upload")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"log.go",
|
||||
"main.go",
|
||||
"usage.go",
|
||||
],
|
||||
@@ -29,7 +30,6 @@ go_library(
|
||||
"//runtime/version:go_default_library",
|
||||
"//validator/node:go_default_library",
|
||||
"@com_github_joonix_log//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
],
|
||||
|
||||
5
cmd/validator/log.go
Normal file
5
cmd/validator/log.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package main
|
||||
|
||||
import "github.com/sirupsen/logrus"
|
||||
|
||||
var log = logrus.WithField("prefix", "main")
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
runtimeDebug "runtime/debug"
|
||||
|
||||
joonix "github.com/joonix/log"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/cmd"
|
||||
accountcommands "github.com/prysmaticlabs/prysm/v4/cmd/validator/accounts"
|
||||
dbcommands "github.com/prysmaticlabs/prysm/v4/cmd/validator/db"
|
||||
@@ -32,10 +31,8 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var log = logrus.WithField("prefix", "main")
|
||||
|
||||
func startNode(ctx *cli.Context) error {
|
||||
// Verify if ToS is accepted.
|
||||
// verify if ToS accepted
|
||||
if err := tos.VerifyTosAcceptedOrPrompt(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -144,8 +141,6 @@ func main() {
|
||||
return err
|
||||
}
|
||||
|
||||
logFileName := ctx.String(cmd.LogFileName.Name)
|
||||
|
||||
format := ctx.String(cmd.LogFormat.Name)
|
||||
switch format {
|
||||
case "text":
|
||||
@@ -153,8 +148,8 @@ func main() {
|
||||
formatter.TimestampFormat = "2006-01-02 15:04:05"
|
||||
formatter.FullTimestamp = true
|
||||
// If persistent log files are written - we disable the log messages coloring because
|
||||
// the colors are ANSI codes and seen as gibberish in the log files.
|
||||
formatter.DisableColors = logFileName != ""
|
||||
// the colors are ANSI codes and seen as Gibberish in the log files.
|
||||
formatter.DisableColors = ctx.String(cmd.LogFileName.Name) != ""
|
||||
logrus.SetFormatter(formatter)
|
||||
case "fluentd":
|
||||
f := joonix.NewFormatter()
|
||||
@@ -172,6 +167,7 @@ func main() {
|
||||
return fmt.Errorf("unknown log format %s", format)
|
||||
}
|
||||
|
||||
logFileName := ctx.String(cmd.LogFileName.Name)
|
||||
if logFileName != "" {
|
||||
if err := logs.ConfigurePersistentLogging(logFileName); err != nil {
|
||||
log.WithError(err).Error("Failed to configuring logging to disk.")
|
||||
@@ -186,9 +182,8 @@ func main() {
|
||||
}
|
||||
|
||||
if err := debug.Setup(ctx); err != nil {
|
||||
return errors.Wrap(err, "failed to setup debug")
|
||||
return err
|
||||
}
|
||||
|
||||
return cmd.ValidateNoArgs(ctx)
|
||||
},
|
||||
After: func(ctx *cli.Context) error {
|
||||
|
||||
@@ -29,7 +29,7 @@ Examples of when not to use a feature flag:
|
||||
Once it has been decided that you should use a feature flag. Follow these steps to safely
|
||||
releasing your feature. In general, try to create a single PR for each step of this process.
|
||||
|
||||
1. Add your feature flag to `shared/featureconfig/flags.go`, use the flag to toggle a boolean in the
|
||||
1. Add your feature flag to shared/featureconfig/flags.go, use the flag to toggle a boolean in the
|
||||
feature config in shared/featureconfig/config.go. It is a good idea to use the `enable` prefix for
|
||||
your flag since you're going to invert the flag in a later step. i.e you will use `disable` prefix
|
||||
later. For example, `--enable-my-feature`. Additionally, [create a feature flag tracking issue](https://github.com/prysmaticlabs/prysm/issues/new?template=feature_flag.md)
|
||||
@@ -48,7 +48,7 @@ func someExistingMethod(ctx context.Context) error {
|
||||
3. Add the flag to the end to end tests. This set of flags can also be found in shared/featureconfig/flags.go.
|
||||
4. Test the functionality locally and safely in production. Once you have enough confidence that
|
||||
your new function works and is safe to release then move onto the next step.
|
||||
5. Move your existing flag to the deprecated section of `shared/featureconfig/flags.go`. It is
|
||||
5. Move your existing flag to the deprecated section of shared/featureconfig/flags.go. It is
|
||||
important NOT to delete your existing flag outright. Deleting a flag can be extremely frustrating
|
||||
to users as it may break their existing workflow! Marking a flag as deprecated gives users time to
|
||||
adjust their start scripts and workflow. Add another feature flag to represent the inverse of your
|
||||
|
||||
@@ -96,10 +96,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Amount of references beyond which a multivalue object is considered
|
||||
// fragmented.
|
||||
const fragmentationLimit = 50000
|
||||
|
||||
// Id is an object identifier.
|
||||
type Id = uint64
|
||||
|
||||
@@ -428,58 +424,6 @@ func (s *Slice[V]) MultiValueStatistics() MultiValueStatistics {
|
||||
return stats
|
||||
}
|
||||
|
||||
// IsFragmented checks if our mutlivalue object is fragmented (individual references held).
|
||||
// If the number of references is higher than our threshold we return true.
|
||||
func (s *Slice[V]) IsFragmented() bool {
|
||||
stats := s.MultiValueStatistics()
|
||||
return stats.TotalIndividualElemReferences+stats.TotalAppendedElemReferences >= fragmentationLimit
|
||||
}
|
||||
|
||||
// Reset builds a new multivalue object with respect to the
|
||||
// provided object's id. The base slice will be based on this
|
||||
// particular id.
|
||||
func (s *Slice[V]) Reset(obj Identifiable) *Slice[V] {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
||||
l, ok := s.cachedLengths[obj.Id()]
|
||||
if !ok {
|
||||
l = len(s.sharedItems)
|
||||
}
|
||||
|
||||
items := make([]V, l)
|
||||
copy(items, s.sharedItems)
|
||||
for i, ind := range s.individualItems {
|
||||
for _, v := range ind.Values {
|
||||
_, found := containsId(v.ids, obj.Id())
|
||||
if found {
|
||||
items[i] = v.val
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index := len(s.sharedItems)
|
||||
for _, app := range s.appendedItems {
|
||||
found := true
|
||||
for _, v := range app.Values {
|
||||
_, found = containsId(v.ids, obj.Id())
|
||||
if found {
|
||||
items[index] = v.val
|
||||
index++
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
reset := &Slice[V]{}
|
||||
reset.Init(items)
|
||||
return reset
|
||||
}
|
||||
|
||||
func (s *Slice[V]) fillOriginalItems(obj Identifiable, items *[]V) {
|
||||
for i, item := range s.sharedItems {
|
||||
ind, ok := s.individualItems[uint64(i)]
|
||||
|
||||
@@ -326,156 +326,6 @@ func TestDetach(t *testing.T) {
|
||||
assert.Equal(t, false, ok)
|
||||
}
|
||||
|
||||
func TestReset(t *testing.T) {
|
||||
s := setup()
|
||||
obj := &testObject{id: 2}
|
||||
|
||||
reset := s.Reset(obj)
|
||||
|
||||
assert.Equal(t, 8, len(reset.sharedItems))
|
||||
assert.Equal(t, 123, reset.sharedItems[0])
|
||||
assert.Equal(t, 2, reset.sharedItems[1])
|
||||
assert.Equal(t, 3, reset.sharedItems[2])
|
||||
assert.Equal(t, 123, reset.sharedItems[3])
|
||||
assert.Equal(t, 2, reset.sharedItems[4])
|
||||
assert.Equal(t, 2, reset.sharedItems[5])
|
||||
assert.Equal(t, 3, reset.sharedItems[6])
|
||||
assert.Equal(t, 2, reset.sharedItems[7])
|
||||
assert.Equal(t, 0, len(reset.individualItems))
|
||||
assert.Equal(t, 0, len(reset.appendedItems))
|
||||
}
|
||||
|
||||
func TestFragmentation_IndividualReferences(t *testing.T) {
|
||||
s := &Slice[int]{}
|
||||
s.Init([]int{123, 123, 123, 123, 123})
|
||||
s.individualItems[1] = &MultiValueItem[int]{
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 1,
|
||||
ids: []uint64{1},
|
||||
},
|
||||
{
|
||||
val: 2,
|
||||
ids: []uint64{2},
|
||||
},
|
||||
},
|
||||
}
|
||||
s.individualItems[2] = &MultiValueItem[int]{
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 3,
|
||||
ids: []uint64{1, 2},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
numOfRefs := fragmentationLimit / 2
|
||||
for i := 3; i < numOfRefs; i++ {
|
||||
obj := &testObject{id: uint64(i)}
|
||||
s.Copy(&testObject{id: 1}, obj)
|
||||
}
|
||||
|
||||
assert.Equal(t, false, s.IsFragmented())
|
||||
|
||||
// Add more references to hit fragmentation limit. Id 1
|
||||
// has 2 references above.
|
||||
for i := numOfRefs; i < numOfRefs+3; i++ {
|
||||
obj := &testObject{id: uint64(i)}
|
||||
s.Copy(&testObject{id: 1}, obj)
|
||||
}
|
||||
assert.Equal(t, true, s.IsFragmented())
|
||||
}
|
||||
|
||||
func TestFragmentation_AppendedReferences(t *testing.T) {
|
||||
s := &Slice[int]{}
|
||||
s.Init([]int{123, 123, 123, 123, 123})
|
||||
s.appendedItems = []*MultiValueItem[int]{
|
||||
{
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 1,
|
||||
ids: []uint64{1},
|
||||
},
|
||||
{
|
||||
val: 2,
|
||||
ids: []uint64{2},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 3,
|
||||
ids: []uint64{1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
s.cachedLengths[1] = 7
|
||||
s.cachedLengths[2] = 8
|
||||
|
||||
numOfRefs := fragmentationLimit / 2
|
||||
for i := 3; i < numOfRefs; i++ {
|
||||
obj := &testObject{id: uint64(i)}
|
||||
s.Copy(&testObject{id: 1}, obj)
|
||||
}
|
||||
|
||||
assert.Equal(t, false, s.IsFragmented())
|
||||
|
||||
// Add more references to hit fragmentation limit. Id 1
|
||||
// has 2 references above.
|
||||
for i := numOfRefs; i < numOfRefs+3; i++ {
|
||||
obj := &testObject{id: uint64(i)}
|
||||
s.Copy(&testObject{id: 1}, obj)
|
||||
}
|
||||
assert.Equal(t, true, s.IsFragmented())
|
||||
}
|
||||
|
||||
func TestFragmentation_IndividualAndAppendedReferences(t *testing.T) {
|
||||
s := &Slice[int]{}
|
||||
s.Init([]int{123, 123, 123, 123, 123})
|
||||
s.individualItems[2] = &MultiValueItem[int]{
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 3,
|
||||
ids: []uint64{1, 2},
|
||||
},
|
||||
},
|
||||
}
|
||||
s.appendedItems = []*MultiValueItem[int]{
|
||||
{
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 1,
|
||||
ids: []uint64{1},
|
||||
},
|
||||
{
|
||||
val: 2,
|
||||
ids: []uint64{2},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
s.cachedLengths[1] = 7
|
||||
s.cachedLengths[2] = 8
|
||||
|
||||
numOfRefs := fragmentationLimit / 2
|
||||
for i := 3; i < numOfRefs; i++ {
|
||||
obj := &testObject{id: uint64(i)}
|
||||
s.Copy(&testObject{id: 1}, obj)
|
||||
}
|
||||
|
||||
assert.Equal(t, false, s.IsFragmented())
|
||||
|
||||
// Add more references to hit fragmentation limit. Id 1
|
||||
// has 2 references above.
|
||||
for i := numOfRefs; i < numOfRefs+3; i++ {
|
||||
obj := &testObject{id: uint64(i)}
|
||||
s.Copy(&testObject{id: 1}, obj)
|
||||
}
|
||||
assert.Equal(t, true, s.IsFragmented())
|
||||
}
|
||||
|
||||
// Share the slice between 2 objects.
|
||||
// Index 0: Shared value
|
||||
// Index 1: Different individual value
|
||||
|
||||
4
deps.bzl
4
deps.bzl
@@ -3617,8 +3617,8 @@ def prysm_deps():
|
||||
"gazelle:exclude tools.go",
|
||||
],
|
||||
importpath = "github.com/quic-go/quic-go",
|
||||
sum = "h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s=",
|
||||
version = "v0.39.4",
|
||||
sum = "h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg=",
|
||||
version = "v0.39.3",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_quic_go_webtransport_go",
|
||||
|
||||
@@ -49,23 +49,6 @@ func FromState(marshaled []byte) (*VersionedUnmarshaler, error) {
|
||||
return FromForkVersion(cv)
|
||||
}
|
||||
|
||||
// FromBlock uses the known size of an offset and signature to determine the slot of a block without unmarshalling it.
|
||||
// The slot is used to determine the version along with the respective config.
|
||||
func FromBlock(marshaled []byte) (*VersionedUnmarshaler, error) {
|
||||
slot, err := slotFromBlock(marshaled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copiedCfg := params.BeaconConfig().Copy()
|
||||
epoch := slots.ToEpoch(slot)
|
||||
fs := forks.NewOrderedSchedule(copiedCfg)
|
||||
ver, err := fs.VersionForEpoch(epoch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return FromForkVersion(ver)
|
||||
}
|
||||
|
||||
var ErrForkNotFound = errors.New("version found in fork schedule but can't be matched to a named fork")
|
||||
|
||||
// FromForkVersion uses a lookup table to resolve a Version (from a beacon node api for instance, or obtained by peeking at
|
||||
@@ -179,7 +162,7 @@ var errBlockForkMismatch = errors.New("fork or config detected in unmarshaler is
|
||||
|
||||
// UnmarshalBeaconBlock uses internal knowledge in the VersionedUnmarshaler to pick the right concrete ReadOnlySignedBeaconBlock type,
|
||||
// then Unmarshal()s the type and returns an instance of block.ReadOnlySignedBeaconBlock if successful.
|
||||
func (cf *VersionedUnmarshaler) UnmarshalBeaconBlock(marshaled []byte) (interfaces.SignedBeaconBlock, error) {
|
||||
func (cf *VersionedUnmarshaler) UnmarshalBeaconBlock(marshaled []byte) (interfaces.ReadOnlySignedBeaconBlock, error) {
|
||||
slot, err := slotFromBlock(marshaled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -214,7 +197,7 @@ func (cf *VersionedUnmarshaler) UnmarshalBeaconBlock(marshaled []byte) (interfac
|
||||
// UnmarshalBlindedBeaconBlock uses internal knowledge in the VersionedUnmarshaler to pick the right concrete blinded ReadOnlySignedBeaconBlock type,
|
||||
// then Unmarshal()s the type and returns an instance of block.ReadOnlySignedBeaconBlock if successful.
|
||||
// For Phase0 and Altair it works exactly line UnmarshalBeaconBlock.
|
||||
func (cf *VersionedUnmarshaler) UnmarshalBlindedBeaconBlock(marshaled []byte) (interfaces.SignedBeaconBlock, error) {
|
||||
func (cf *VersionedUnmarshaler) UnmarshalBlindedBeaconBlock(marshaled []byte) (interfaces.ReadOnlySignedBeaconBlock, error) {
|
||||
slot, err := slotFromBlock(marshaled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -204,97 +204,6 @@ func TestUnmarshalState(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectAndUnmarshalBlock(t *testing.T) {
|
||||
undo := util.HackDenebMaxuint(t)
|
||||
defer undo()
|
||||
altairS, err := slots.EpochStart(params.BeaconConfig().AltairForkEpoch)
|
||||
require.NoError(t, err)
|
||||
bellaS, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch)
|
||||
require.NoError(t, err)
|
||||
capellaS, err := slots.EpochStart(params.BeaconConfig().CapellaForkEpoch)
|
||||
require.NoError(t, err)
|
||||
denebS, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch)
|
||||
require.NoError(t, err)
|
||||
cases := []struct {
|
||||
b func(*testing.T, primitives.Slot) interfaces.ReadOnlySignedBeaconBlock
|
||||
name string
|
||||
slot primitives.Slot
|
||||
errExists bool
|
||||
}{
|
||||
{
|
||||
name: "genesis - slot 0",
|
||||
b: signedTestBlockGenesis,
|
||||
},
|
||||
{
|
||||
name: "last slot of phase 0",
|
||||
b: signedTestBlockGenesis,
|
||||
slot: altairS - 1,
|
||||
},
|
||||
{
|
||||
name: "first slot of altair",
|
||||
b: signedTestBlockAltair,
|
||||
slot: altairS,
|
||||
},
|
||||
{
|
||||
name: "last slot of altair",
|
||||
b: signedTestBlockAltair,
|
||||
slot: bellaS - 1,
|
||||
},
|
||||
{
|
||||
name: "first slot of bellatrix",
|
||||
b: signedTestBlockBellatrix,
|
||||
slot: bellaS,
|
||||
},
|
||||
{
|
||||
name: "first slot of capella",
|
||||
b: signedTestBlockCapella,
|
||||
slot: capellaS,
|
||||
},
|
||||
{
|
||||
name: "last slot of capella",
|
||||
b: signedTestBlockCapella,
|
||||
slot: denebS - 1,
|
||||
},
|
||||
{
|
||||
name: "first slot of deneb",
|
||||
b: signedTestBlockDeneb,
|
||||
slot: denebS,
|
||||
},
|
||||
{
|
||||
name: "bellatrix block in altair slot",
|
||||
b: signedTestBlockBellatrix,
|
||||
slot: bellaS - 1,
|
||||
errExists: true,
|
||||
},
|
||||
{
|
||||
name: "genesis block in altair slot",
|
||||
b: signedTestBlockGenesis,
|
||||
slot: bellaS - 1,
|
||||
errExists: true,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
b := c.b(t, c.slot)
|
||||
marshaled, err := b.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
cf, err := FromBlock(marshaled)
|
||||
require.NoError(t, err)
|
||||
bcf, err := cf.UnmarshalBeaconBlock(marshaled)
|
||||
if c.errExists {
|
||||
require.NotNil(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
expected, err := b.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
actual, err := bcf.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalBlock(t *testing.T) {
|
||||
undo := util.HackDenebMaxuint(t)
|
||||
defer undo()
|
||||
|
||||
2
go.mod
2
go.mod
@@ -213,7 +213,7 @@ require (
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
|
||||
github.com/quic-go/quic-go v0.39.4 // indirect
|
||||
github.com/quic-go/quic-go v0.39.3 // indirect
|
||||
github.com/quic-go/webtransport-go v0.6.0 // indirect
|
||||
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1117,8 +1117,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s=
|
||||
github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
|
||||
github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg=
|
||||
github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
|
||||
github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY=
|
||||
github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc=
|
||||
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
||||
|
||||
@@ -22,6 +22,5 @@ go_test(
|
||||
deps = [
|
||||
"//api:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
// match a number with optional decimals
|
||||
var priorityRegex = regexp.MustCompile(`q=(\d+(?:\.\d+)?)`)
|
||||
|
||||
// RespondWithSsz takes a http request and checks to see if it should be requesting a ssz response.
|
||||
func RespondWithSsz(req *http.Request) bool {
|
||||
// SszRequested takes a http request and checks to see if it should be requesting a ssz response.
|
||||
func SszRequested(req *http.Request) bool {
|
||||
accept := req.Header.Values("Accept")
|
||||
if len(accept) == 0 {
|
||||
return false
|
||||
@@ -51,8 +51,3 @@ func RespondWithSsz(req *http.Request) bool {
|
||||
|
||||
return currentType == api.OctetStreamMediaType
|
||||
}
|
||||
|
||||
// IsRequestSsz checks if the request object should be interpreted as ssz
|
||||
func IsRequestSsz(req *http.Request) bool {
|
||||
return req.Header.Get("Content-Type") == api.OctetStreamMediaType
|
||||
}
|
||||
|
||||
@@ -1,123 +1,88 @@
|
||||
package httputil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/api"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
func TestRespondWithSsz(t *testing.T) {
|
||||
func TestSSZRequested(t *testing.T) {
|
||||
t.Run("ssz_requested", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{api.OctetStreamMediaType}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, true, result)
|
||||
})
|
||||
|
||||
t.Run("ssz_content_type_first", func(t *testing.T) {
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{fmt.Sprintf("%s,%s", api.OctetStreamMediaType, api.JsonMediaType)}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, true, result)
|
||||
})
|
||||
|
||||
t.Run("ssz_content_type_preferred_1", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{fmt.Sprintf("%s;q=0.9,%s", api.JsonMediaType, api.OctetStreamMediaType)}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, true, result)
|
||||
})
|
||||
|
||||
t.Run("ssz_content_type_preferred_2", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{fmt.Sprintf("%s;q=0.95,%s;q=0.9", api.OctetStreamMediaType, api.JsonMediaType)}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, true, result)
|
||||
})
|
||||
|
||||
t.Run("other_content_type_preferred", func(t *testing.T) {
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{fmt.Sprintf("%s,%s;q=0.9", api.JsonMediaType, api.OctetStreamMediaType)}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
|
||||
t.Run("other_params", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{fmt.Sprintf("%s,%s;q=0.9,otherparam=xyz", api.JsonMediaType, api.OctetStreamMediaType)}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
|
||||
t.Run("no_header", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
result := RespondWithSsz(request)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
|
||||
t.Run("empty_header", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
|
||||
t.Run("empty_header_value", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{""}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
|
||||
t.Run("other_content_type", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{"application/other"}
|
||||
result := RespondWithSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
|
||||
t.Run("garbage", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodGet, "http://foo.example", nil)
|
||||
request := httptest.NewRequest("GET", "http://foo.example", nil)
|
||||
request.Header["Accept"] = []string{"This is Sparta!!!"}
|
||||
result := RespondWithSsz(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsRequestSsz(t *testing.T) {
|
||||
t.Run("ssz Post happy path", func(t *testing.T) {
|
||||
var body bytes.Buffer
|
||||
_, err := body.WriteString("something")
|
||||
require.NoError(t, err)
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", &body)
|
||||
request.Header["Content-Type"] = []string{api.OctetStreamMediaType}
|
||||
result := IsRequestSsz(request)
|
||||
assert.Equal(t, true, result)
|
||||
})
|
||||
|
||||
t.Run("ssz Post missing header", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", nil)
|
||||
result := IsRequestSsz(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
|
||||
t.Run("ssz Post wrong content type", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", nil)
|
||||
request.Header["Content-Type"] = []string{"application/other"}
|
||||
result := IsRequestSsz(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
|
||||
t.Run("ssz Post json content type", func(t *testing.T) {
|
||||
request := httptest.NewRequest(http.MethodPost, "http://foo.example", nil)
|
||||
request.Header["Content-Type"] = []string{api.JsonMediaType}
|
||||
result := IsRequestSsz(request)
|
||||
result := SszRequested(request)
|
||||
assert.Equal(t, false, result)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -103,12 +103,7 @@ func WarnIfPlatformNotSupported(ctx context.Context) {
|
||||
return
|
||||
}
|
||||
if !supported {
|
||||
log.Warn(`This platform is not supported. The following platforms are supported:
|
||||
- Linux/AMD64
|
||||
- Linux/ARM64
|
||||
- Mac OS X/AMD64 (from 10.14+)
|
||||
- Mac OS X/ARM64 (from 12.5+)
|
||||
- Windows/AMD64`,
|
||||
)
|
||||
log.Warn("This platform is not supported. The following platforms are supported: Linux/AMD64," +
|
||||
" Linux/ARM64, Mac OS X/AMD64 (10.14+ only), and Windows/AMD64")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ type ServiceRegistry struct {
|
||||
serviceTypes []reflect.Type // keep an ordered slice of registered service types.
|
||||
}
|
||||
|
||||
// NewServiceRegistry starts a registry instance for convenience.
|
||||
// NewServiceRegistry starts a registry instance for convenience
|
||||
func NewServiceRegistry() *ServiceRegistry {
|
||||
return &ServiceRegistry{
|
||||
services: make(map[reflect.Type]Service),
|
||||
|
||||
@@ -35,13 +35,11 @@ var (
|
||||
log = logrus.WithField("prefix", "tos")
|
||||
)
|
||||
|
||||
// VerifyTosAcceptedOrPrompt checks if Tos was accepted before or asks to accept.
|
||||
// VerifyTosAcceptedOrPrompt check if Tos was accepted before or asks to accept.
|
||||
func VerifyTosAcceptedOrPrompt(ctx *cli.Context) error {
|
||||
tosFilePath := filepath.Join(ctx.String(cmd.DataDirFlag.Name), acceptTosFilename)
|
||||
if file.Exists(tosFilePath) {
|
||||
if file.Exists(filepath.Join(ctx.String(cmd.DataDirFlag.Name), acceptTosFilename)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ctx.Bool(cmd.AcceptTosFlag.Name) {
|
||||
saveTosAccepted(ctx)
|
||||
return nil
|
||||
@@ -51,7 +49,6 @@ func VerifyTosAcceptedOrPrompt(ctx *cli.Context) error {
|
||||
if err != nil {
|
||||
return errors.New(acceptTosPromptErrText)
|
||||
}
|
||||
|
||||
if !strings.EqualFold(input, "accept") {
|
||||
return errors.New("you have to accept Terms and Conditions in order to continue")
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) {
|
||||
penalties := make([]uint64, len(deltas))
|
||||
for i, d := range deltas {
|
||||
rewards[i] = d.HeadReward + d.SourceReward + d.TargetReward
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty + d.InactivityPenalty
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty
|
||||
}
|
||||
|
||||
totalSpecTestRewards := make([]uint64, len(rewards))
|
||||
|
||||
@@ -87,7 +87,7 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) {
|
||||
penalties := make([]uint64, len(deltas))
|
||||
for i, d := range deltas {
|
||||
rewards[i] = d.HeadReward + d.SourceReward + d.TargetReward
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty + d.InactivityPenalty
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty
|
||||
}
|
||||
|
||||
totalSpecTestRewards := make([]uint64, len(rewards))
|
||||
|
||||
@@ -87,7 +87,7 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) {
|
||||
penalties := make([]uint64, len(deltas))
|
||||
for i, d := range deltas {
|
||||
rewards[i] = d.HeadReward + d.SourceReward + d.TargetReward
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty + d.InactivityPenalty
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty
|
||||
}
|
||||
|
||||
totalSpecTestRewards := make([]uint64, len(rewards))
|
||||
|
||||
@@ -79,7 +79,7 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) {
|
||||
penalties := make([]uint64, len(deltas))
|
||||
for i, d := range deltas {
|
||||
rewards[i] = d.HeadReward + d.SourceReward + d.TargetReward
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty + d.InactivityPenalty
|
||||
penalties[i] = d.SourcePenalty + d.TargetPenalty
|
||||
}
|
||||
|
||||
totalSpecTestRewards := make([]uint64, len(rewards))
|
||||
|
||||
14
testing/validator-mock/node_client_mock.go
generated
14
testing/validator-mock/node_client_mock.go
generated
@@ -81,20 +81,6 @@ func (mr *MockNodeClientMockRecorder) GetVersion(arg0, arg1 interface{}) *gomock
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersion", reflect.TypeOf((*MockNodeClient)(nil).GetVersion), arg0, arg1)
|
||||
}
|
||||
|
||||
// IsHealthy mocks base method.
|
||||
func (m *MockNodeClient) IsHealthy(arg0 context.Context) bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IsHealthy", arg0)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IsHealthy indicates an expected call of IsHealthy.
|
||||
func (mr *MockNodeClientMockRecorder) IsHealthy(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsHealthy", reflect.TypeOf((*MockNodeClient)(nil).IsHealthy), arg0)
|
||||
}
|
||||
|
||||
// ListPeers mocks base method.
|
||||
func (m *MockNodeClient) ListPeers(arg0 context.Context, arg1 *emptypb.Empty) (*eth.Peers, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
28
testing/validator-mock/validator_client_mock.go
generated
28
testing/validator-mock/validator_client_mock.go
generated
@@ -67,20 +67,6 @@ func (mr *MockValidatorClientMockRecorder) DomainData(arg0, arg1 interface{}) *g
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DomainData", reflect.TypeOf((*MockValidatorClient)(nil).DomainData), arg0, arg1)
|
||||
}
|
||||
|
||||
// EventStreamIsRunning mocks base method.
|
||||
func (m *MockValidatorClient) EventStreamIsRunning() bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EventStreamIsRunning")
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// EventStreamIsRunning indicates an expected call of EventStreamIsRunning.
|
||||
func (mr *MockValidatorClientMockRecorder) EventStreamIsRunning() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventStreamIsRunning", reflect.TypeOf((*MockValidatorClient)(nil).EventStreamIsRunning))
|
||||
}
|
||||
|
||||
// GetAttestationData mocks base method.
|
||||
func (m *MockValidatorClient) GetAttestationData(arg0 context.Context, arg1 *eth.AttestationDataRequest) (*eth.AttestationData, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -261,20 +247,6 @@ func (mr *MockValidatorClientMockRecorder) ProposeExit(arg0, arg1 interface{}) *
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProposeExit", reflect.TypeOf((*MockValidatorClient)(nil).ProposeExit), arg0, arg1)
|
||||
}
|
||||
|
||||
// StartEventStream mocks base method.
|
||||
func (m *MockValidatorClient) StartEventStream(arg0 context.Context) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "StartEventStream", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// StartEventStream indicates an expected call of StartEventStream.
|
||||
func (mr *MockValidatorClientMockRecorder) StartEventStream(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartEventStream", reflect.TypeOf((*MockValidatorClient)(nil).StartEventStream), arg0)
|
||||
}
|
||||
|
||||
// StreamSlots mocks base method.
|
||||
func (m *MockValidatorClient) StreamSlots(arg0 context.Context, arg1 *eth.StreamSlotsRequest) (eth.BeaconNodeValidator_StreamSlotsClient, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -185,7 +185,7 @@ func (h *handler) httpHandler(w http.ResponseWriter, _ *http.Request) {
|
||||
write(w, []byte("Node ID: "+n.ID().String()+"\n"))
|
||||
write(w, []byte("IP: "+n.IP().String()+"\n"))
|
||||
write(w, []byte(fmt.Sprintf("UDP Port: %d", n.UDP())+"\n"))
|
||||
write(w, []byte(fmt.Sprintf("TCP Port: %d", n.TCP())+"\n\n"))
|
||||
write(w, []byte(fmt.Sprintf("TCP Port: %d", n.UDP())+"\n\n"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,17 +9,13 @@ go_library(
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//beacon-chain/core/transition:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//encoding/ssz/detect:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//encoding/ssz/equality:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/logging/logrus-prefixed-formatter:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_kr_pretty//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
|
||||
@@ -11,14 +11,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/kr/pretty"
|
||||
"github.com/pkg/errors"
|
||||
fssz "github.com/prysmaticlabs/fastssz"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
"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/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/ssz/detect"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/ssz/equality"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
prefixed "github.com/prysmaticlabs/prysm/v4/runtime/logging/logrus-prefixed-formatter"
|
||||
@@ -32,7 +28,6 @@ func main() {
|
||||
var blockPath string
|
||||
var preStatePath string
|
||||
var expectedPostStatePath string
|
||||
var network string
|
||||
var sszPath string
|
||||
var sszType string
|
||||
|
||||
@@ -162,36 +157,8 @@ func main() {
|
||||
Usage: "Path to expected post state file(ssz)",
|
||||
Destination: &expectedPostStatePath,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "network",
|
||||
Usage: "Network to run the state transition in",
|
||||
Destination: &network,
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if network != "" {
|
||||
switch network {
|
||||
case params.PraterName:
|
||||
if err := params.SetActive(params.PraterConfig()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
case params.GoerliName:
|
||||
if err := params.SetActive(params.PraterConfig()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
case params.SepoliaName:
|
||||
if err := params.SetActive(params.SepoliaConfig()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
case params.HoleskyName:
|
||||
if err := params.SetActive(params.HoleskyConfig()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
default:
|
||||
log.Fatalf("Unknown network provided: %s", network)
|
||||
}
|
||||
}
|
||||
|
||||
if blockPath == "" {
|
||||
log.Info("Block path not provided for state transition. " +
|
||||
"Please provide path")
|
||||
@@ -205,11 +172,11 @@ func main() {
|
||||
}
|
||||
blockPath = text
|
||||
}
|
||||
block, err := detectBlock(blockPath)
|
||||
if err != nil {
|
||||
block := ðpb.SignedBeaconBlock{}
|
||||
if err := dataFetcher(blockPath, block); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
blkRoot, err := block.Block().HashTreeRoot()
|
||||
blkRoot, err := block.Block.HashTreeRoot()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -226,7 +193,11 @@ func main() {
|
||||
}
|
||||
preStatePath = text
|
||||
}
|
||||
stateObj, err := detectState(preStatePath)
|
||||
preState := ðpb.BeaconState{}
|
||||
if err := dataFetcher(preStatePath, preState); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
stateObj, err := state_native.InitializeFromProtoPhase0(preState)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -235,14 +206,18 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
"blockSlot": fmt.Sprintf("%d", block.Block().Slot()),
|
||||
"blockSlot": fmt.Sprintf("%d", block.Block.Slot),
|
||||
"preStateSlot": fmt.Sprintf("%d", stateObj.Slot()),
|
||||
}).Infof(
|
||||
"Performing state transition with a block root of %#x and pre state root of %#x",
|
||||
blkRoot,
|
||||
preStateRoot,
|
||||
)
|
||||
postState, err := transition.ExecuteStateTransition(context.Background(), stateObj, block)
|
||||
wsb, err := blocks.NewSignedBeaconBlock(block)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
postState, err := transition.ExecuteStateTransition(context.Background(), stateObj, wsb)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -254,12 +229,12 @@ func main() {
|
||||
|
||||
// Diff the state if a post state is provided.
|
||||
if expectedPostStatePath != "" {
|
||||
expectedState, err := detectState(expectedPostStatePath)
|
||||
if err != nil {
|
||||
expectedState := ðpb.BeaconState{}
|
||||
if err := dataFetcher(expectedPostStatePath, expectedState); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if !equality.DeepEqual(expectedState.ToProtoUnsafe(), postState.ToProtoUnsafe()) {
|
||||
diff, _ := messagediff.PrettyDiff(expectedState.ToProtoUnsafe(), postState.ToProtoUnsafe())
|
||||
if !equality.DeepEqual(expectedState, postState.ToProtoUnsafe()) {
|
||||
diff, _ := messagediff.PrettyDiff(expectedState, postState.ToProtoUnsafe())
|
||||
log.Errorf("Derived state differs from provided post state: %s", diff)
|
||||
}
|
||||
}
|
||||
@@ -282,34 +257,6 @@ func dataFetcher(fPath string, data fssz.Unmarshaler) error {
|
||||
return data.UnmarshalSSZ(rawFile)
|
||||
}
|
||||
|
||||
func detectState(fPath string) (state.BeaconState, error) {
|
||||
rawFile, err := os.ReadFile(fPath) // #nosec G304
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vu, err := detect.FromState(rawFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error detecting state from file")
|
||||
}
|
||||
s, err := vu.UnmarshalBeaconState(rawFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error unmarshalling state")
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func detectBlock(fPath string) (interfaces.SignedBeaconBlock, error) {
|
||||
rawFile, err := os.ReadFile(fPath) // #nosec G304
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vu, err := detect.FromBlock(rawFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return vu.UnmarshalBeaconBlock(rawFile)
|
||||
}
|
||||
|
||||
func prettyPrint(sszPath string, data fssz.Unmarshaler) {
|
||||
if err := dataFetcher(sszPath, data); err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
@@ -23,7 +23,7 @@ type Wallet interface {
|
||||
// Read methods for important wallet and accounts-related files.
|
||||
ReadFileAtPath(ctx context.Context, filePath string, fileName string) ([]byte, error)
|
||||
// Write methods to persist important wallet and accounts-related files to disk.
|
||||
WriteFileAtPath(ctx context.Context, pathName string, fileName string, data []byte) (bool, error)
|
||||
WriteFileAtPath(ctx context.Context, pathName string, fileName string, data []byte) error
|
||||
// Method for initializing a new keymanager.
|
||||
InitializeKeymanager(ctx context.Context, cfg InitKeymanagerConfig) (keymanager.IKeymanager, error)
|
||||
}
|
||||
|
||||
@@ -55,19 +55,19 @@ func (w *Wallet) Password() string {
|
||||
}
|
||||
|
||||
// WriteFileAtPath --
|
||||
func (w *Wallet) WriteFileAtPath(_ context.Context, pathName, fileName string, data []byte) (bool, error) {
|
||||
func (w *Wallet) WriteFileAtPath(_ context.Context, pathName, fileName string, data []byte) error {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
if w.HasWriteFileError {
|
||||
// reset the flag to not contaminate other tests
|
||||
w.HasWriteFileError = false
|
||||
return false, errors.New("could not write keystore file for accounts")
|
||||
return errors.New("could not write keystore file for accounts")
|
||||
}
|
||||
if w.Files[pathName] == nil {
|
||||
w.Files[pathName] = make(map[string][]byte)
|
||||
}
|
||||
w.Files[pathName][fileName] = data
|
||||
return true, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadFileAtPath --
|
||||
@@ -212,15 +212,3 @@ func (m *Validator) SetProposerSettings(_ context.Context, settings *validatorse
|
||||
m.proposerSettings = settings
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Validator) StartEventStream(_ context.Context) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (_ *Validator) EventStreamIsRunning() bool {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (_ *Validator) NodeIsHealthy(ctx context.Context) bool {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -366,27 +366,26 @@ func (w *Wallet) InitializeKeymanager(ctx context.Context, cfg iface.InitKeymana
|
||||
}
|
||||
|
||||
// WriteFileAtPath within the wallet directory given the desired path, filename, and raw data.
|
||||
func (w *Wallet) WriteFileAtPath(_ context.Context, filePath, fileName string, data []byte) (bool /* exited previously */, error) {
|
||||
func (w *Wallet) WriteFileAtPath(_ context.Context, filePath, fileName string, data []byte) error {
|
||||
accountPath := filepath.Join(w.accountsPath, filePath)
|
||||
hasDir, err := file.HasDir(accountPath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
if !hasDir {
|
||||
if err := file.MkdirAll(accountPath); err != nil {
|
||||
return false, errors.Wrapf(err, "could not create path: %s", accountPath)
|
||||
return errors.Wrapf(err, "could not create path: %s", accountPath)
|
||||
}
|
||||
}
|
||||
fullPath := filepath.Join(accountPath, fileName)
|
||||
existedPreviously := file.Exists(fullPath)
|
||||
if err := file.WriteFile(fullPath, data); err != nil {
|
||||
return false, errors.Wrapf(err, "could not write %s", filePath)
|
||||
return errors.Wrapf(err, "could not write %s", filePath)
|
||||
}
|
||||
log.WithFields(logrus.Fields{
|
||||
"path": fullPath,
|
||||
"fileName": fileName,
|
||||
}).Debug("Wrote new file at path")
|
||||
return existedPreviously, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadFileAtPath within the wallet directory given the desired path and filename.
|
||||
|
||||
@@ -32,8 +32,7 @@ func (acm *CLIManager) WalletCreate(ctx context.Context) (*wallet.Wallet, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = w.WriteFileAtPath(ctx, local.AccountsPath, local.AccountsKeystoreFileName, encodedAccounts)
|
||||
if err != nil {
|
||||
if err = w.WriteFileAtPath(ctx, local.AccountsPath, local.AccountsKeystoreFileName, encodedAccounts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.WithField("--wallet-dir", acm.walletDir).Info(
|
||||
|
||||
@@ -32,7 +32,6 @@ go_library(
|
||||
"//beacon-chain/core/altair:go_default_library",
|
||||
"//beacon-chain/core/signing:go_default_library",
|
||||
"//cache/lru:go_default_library",
|
||||
"//cmd:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
|
||||
@@ -15,7 +15,6 @@ go_library(
|
||||
"domain_data.go",
|
||||
"doppelganger.go",
|
||||
"duties.go",
|
||||
"event_handler.go",
|
||||
"genesis.go",
|
||||
"get_beacon_block.go",
|
||||
"index.go",
|
||||
@@ -44,7 +43,6 @@ go_library(
|
||||
"//beacon-chain/core/signing:go_default_library",
|
||||
"//beacon-chain/rpc/eth/beacon:go_default_library",
|
||||
"//beacon-chain/rpc/eth/config:go_default_library",
|
||||
"//beacon-chain/rpc/eth/events:go_default_library",
|
||||
"//beacon-chain/rpc/eth/node:go_default_library",
|
||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||
"//beacon-chain/rpc/eth/validator:go_default_library",
|
||||
@@ -85,7 +83,6 @@ go_test(
|
||||
"domain_data_test.go",
|
||||
"doppelganger_test.go",
|
||||
"duties_test.go",
|
||||
"event_handler_test.go",
|
||||
"genesis_test.go",
|
||||
"get_beacon_block_test.go",
|
||||
"index_test.go",
|
||||
@@ -142,7 +139,6 @@ go_test(
|
||||
"@com_github_golang_mock//gomock:go_default_library",
|
||||
"@com_github_golang_protobuf//ptypes/empty",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
],
|
||||
|
||||
@@ -98,10 +98,6 @@ func (c *beaconApiNodeClient) ListPeers(ctx context.Context, in *empty.Empty) (*
|
||||
panic("beaconApiNodeClient.ListPeers is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiNodeClientWithFallback.")
|
||||
}
|
||||
|
||||
func (c *beaconApiNodeClient) IsHealthy(ctx context.Context) bool {
|
||||
return c.jsonRestHandler.Get(ctx, "/eth/v1/node/health", nil) == nil
|
||||
}
|
||||
|
||||
func NewNodeClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient iface.NodeClient) iface.NodeClient {
|
||||
return &beaconApiNodeClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
|
||||
@@ -13,26 +13,17 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/iface"
|
||||
)
|
||||
|
||||
type ValidatorClientOpt func(*beaconApiValidatorClient)
|
||||
|
||||
func WithEventHandler(h *EventHandler) ValidatorClientOpt {
|
||||
return func(c *beaconApiValidatorClient) {
|
||||
c.eventHandler = h
|
||||
}
|
||||
}
|
||||
|
||||
type beaconApiValidatorClient struct {
|
||||
genesisProvider GenesisProvider
|
||||
dutiesProvider dutiesProvider
|
||||
stateValidatorsProvider StateValidatorsProvider
|
||||
jsonRestHandler JsonRestHandler
|
||||
eventHandler *EventHandler
|
||||
beaconBlockConverter BeaconBlockConverter
|
||||
prysmBeaconChainCLient iface.PrysmBeaconChainClient
|
||||
}
|
||||
|
||||
func NewBeaconApiValidatorClient(jsonRestHandler JsonRestHandler, opts ...ValidatorClientOpt) iface.ValidatorClient {
|
||||
c := &beaconApiValidatorClient{
|
||||
func NewBeaconApiValidatorClient(jsonRestHandler JsonRestHandler) iface.ValidatorClient {
|
||||
return &beaconApiValidatorClient{
|
||||
genesisProvider: beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler},
|
||||
dutiesProvider: beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler},
|
||||
stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler},
|
||||
@@ -43,10 +34,6 @@ func NewBeaconApiValidatorClient(jsonRestHandler JsonRestHandler, opts ...Valida
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
},
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(c)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) GetDuties(ctx context.Context, in *ethpb.DutiesRequest) (*ethpb.DutiesResponse, error) {
|
||||
@@ -162,16 +149,3 @@ func (c *beaconApiValidatorClient) WaitForActivation(ctx context.Context, in *et
|
||||
func (c *beaconApiValidatorClient) WaitForChainStart(ctx context.Context, _ *empty.Empty) (*ethpb.ChainStartResponse, error) {
|
||||
return c.waitForChainStart(ctx)
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) StartEventStream(ctx context.Context) error {
|
||||
if c.eventHandler != nil {
|
||||
if err := c.eventHandler.get(ctx, []string{"head"}); err != nil {
|
||||
return errors.Wrapf(err, "could not invoke event handler")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) EventStreamIsRunning() bool {
|
||||
return c.eventHandler.running
|
||||
}
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
package beacon_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/api"
|
||||
)
|
||||
|
||||
// Currently set to the first power of 2 bigger than the size of the `head` event
|
||||
// which is 446 bytes
|
||||
const eventByteLimit = 512
|
||||
|
||||
// EventHandler is responsible for subscribing to the Beacon API events endpoint
|
||||
// and dispatching received events to subscribers.
|
||||
type EventHandler struct {
|
||||
httpClient *http.Client
|
||||
host string
|
||||
running bool
|
||||
subs []eventSub
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
type eventSub struct {
|
||||
name string
|
||||
ch chan<- event
|
||||
}
|
||||
|
||||
type event struct {
|
||||
eventType string
|
||||
data string
|
||||
}
|
||||
|
||||
// NewEventHandler returns a new handler.
|
||||
func NewEventHandler(httpClient *http.Client, host string) *EventHandler {
|
||||
return &EventHandler{
|
||||
httpClient: httpClient,
|
||||
host: host,
|
||||
running: false,
|
||||
subs: make([]eventSub, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *EventHandler) subscribe(sub eventSub) {
|
||||
h.Lock()
|
||||
h.subs = append(h.subs, sub)
|
||||
h.Unlock()
|
||||
}
|
||||
|
||||
func (h *EventHandler) get(ctx context.Context, topics []string) error {
|
||||
if len(topics) == 0 {
|
||||
return errors.New("no topics provided")
|
||||
}
|
||||
if h.running {
|
||||
log.Warn("Event listener is already running, ignoring function call")
|
||||
}
|
||||
|
||||
go func() {
|
||||
h.running = true
|
||||
defer func() { h.running = false }()
|
||||
|
||||
allTopics := strings.Join(topics, ",")
|
||||
log.Info("Starting listening to Beacon API events on topics: " + allTopics)
|
||||
url := h.host + "/eth/v1/events?topics=" + allTopics
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to create HTTP request")
|
||||
return
|
||||
}
|
||||
req.Header.Set("Accept", api.EventStreamMediaType)
|
||||
req.Header.Set("Connection", api.KeepAlive)
|
||||
resp, err := h.httpClient.Do(req)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to perform HTTP request")
|
||||
return
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if closeErr := resp.Body.Close(); closeErr != nil {
|
||||
log.WithError(closeErr).Error("Failed to close events response body")
|
||||
}
|
||||
}()
|
||||
|
||||
// We signal an EOF error in a special way. When we get this error while reading the response body,
|
||||
// there might still be an event received in the body that we should handle.
|
||||
eof := false
|
||||
for {
|
||||
if ctx.Err() != nil {
|
||||
log.WithError(ctx.Err()).Error("Stopping listening to Beacon API events")
|
||||
return
|
||||
}
|
||||
|
||||
rawData := make([]byte, eventByteLimit)
|
||||
_, err = resp.Body.Read(rawData)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "EOF") {
|
||||
log.Error("Received EOF while reading events response body. Stopping listening to Beacon API events")
|
||||
eof = true
|
||||
} else {
|
||||
log.WithError(err).Error("Stopping listening to Beacon API events")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
e := strings.Split(string(rawData), "\n")
|
||||
// We expect that the event format will contain event type and data separated with a newline
|
||||
if len(e) < 2 {
|
||||
// We reached EOF and there is no event to send
|
||||
if eof {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
for _, sub := range h.subs {
|
||||
select {
|
||||
case sub.ch <- event{eventType: e[0], data: e[1]}:
|
||||
// Event sent successfully.
|
||||
default:
|
||||
log.Warn("Subscriber '" + sub.name + "' not ready to receive events")
|
||||
}
|
||||
}
|
||||
// We reached EOF and sent the last event
|
||||
if eof {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package beacon_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
logtest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
func TestEventHandler(t *testing.T) {
|
||||
logHook := logtest.NewGlobal()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/eth/v1/events", func(w http.ResponseWriter, r *http.Request) {
|
||||
flusher, ok := w.(http.Flusher)
|
||||
require.Equal(t, true, ok)
|
||||
_, err := fmt.Fprint(w, "head\ndata\n\n")
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
})
|
||||
server := httptest.NewServer(mux)
|
||||
defer server.Close()
|
||||
|
||||
handler := NewEventHandler(http.DefaultClient, server.URL)
|
||||
ch1 := make(chan event, 1)
|
||||
sub1 := eventSub{ch: ch1}
|
||||
ch2 := make(chan event, 1)
|
||||
sub2 := eventSub{ch: ch2}
|
||||
ch3 := make(chan event, 1)
|
||||
sub3 := eventSub{name: "sub3", ch: ch3}
|
||||
// fill up the channel so that it can't receive more events
|
||||
ch3 <- event{}
|
||||
handler.subscribe(sub1)
|
||||
handler.subscribe(sub2)
|
||||
handler.subscribe(sub3)
|
||||
|
||||
require.NoError(t, handler.get(context.Background(), []string{"head"}))
|
||||
// make sure the goroutine inside handler.get is invoked
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
e := <-ch1
|
||||
assert.Equal(t, "head", e.eventType)
|
||||
assert.Equal(t, "data", e.data)
|
||||
e = <-ch2
|
||||
assert.Equal(t, "head", e.eventType)
|
||||
assert.Equal(t, "data", e.data)
|
||||
|
||||
assert.LogsContain(t, logHook, "Subscriber 'sub3' not ready to receive events")
|
||||
}
|
||||
@@ -45,6 +45,10 @@ func (c beaconApiValidatorClient) waitForChainStart(ctx context.Context) (*ethpb
|
||||
return nil, errors.Wrapf(err, "failed to parse genesis time: %s", genesis.GenesisTime)
|
||||
}
|
||||
|
||||
chainStartResponse := ðpb.ChainStartResponse{}
|
||||
chainStartResponse.Started = true
|
||||
chainStartResponse.GenesisTime = genesisTime
|
||||
|
||||
if !validRoot(genesis.GenesisValidatorsRoot) {
|
||||
return nil, errors.Errorf("invalid genesis validators root: %s", genesis.GenesisValidatorsRoot)
|
||||
}
|
||||
@@ -53,12 +57,7 @@ func (c beaconApiValidatorClient) waitForChainStart(ctx context.Context) (*ethpb
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode genesis validators root")
|
||||
}
|
||||
|
||||
chainStartResponse := ðpb.ChainStartResponse{
|
||||
Started: true,
|
||||
GenesisTime: genesisTime,
|
||||
GenesisValidatorsRoot: genesisValidatorRoot,
|
||||
}
|
||||
chainStartResponse.GenesisValidatorsRoot = genesisValidatorRoot
|
||||
|
||||
return chainStartResponse, nil
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/api"
|
||||
@@ -26,6 +25,10 @@ type BeaconApiJsonRestHandler struct {
|
||||
// Get sends a GET request and decodes the response body as a JSON object into the passed in object.
|
||||
// If an HTTP error is returned, the body is decoded as a DefaultJsonError JSON object and returned as the first return value.
|
||||
func (c BeaconApiJsonRestHandler) Get(ctx context.Context, endpoint string, resp interface{}) error {
|
||||
if resp == nil {
|
||||
return errors.New("resp is nil")
|
||||
}
|
||||
|
||||
url := c.Host + endpoint
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
@@ -89,16 +92,14 @@ func decodeResp(httpResp *http.Response, resp interface{}) error {
|
||||
}
|
||||
|
||||
if httpResp.Header.Get("Content-Type") != api.JsonMediaType {
|
||||
// 2XX codes are a success
|
||||
if strings.HasPrefix(httpResp.Status, "2") {
|
||||
if httpResp.StatusCode == http.StatusOK {
|
||||
return nil
|
||||
}
|
||||
return &httputil.DefaultJsonError{Code: httpResp.StatusCode, Message: string(body)}
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(bytes.NewBuffer(body))
|
||||
// non-2XX codes are a failure
|
||||
if !strings.HasPrefix(httpResp.Status, "2") {
|
||||
if httpResp.StatusCode != http.StatusOK {
|
||||
errorJson := &httputil.DefaultJsonError{}
|
||||
if err = decoder.Decode(errorJson); err != nil {
|
||||
return errors.Wrapf(err, "failed to decode response body into error json for %s", httpResp.Request.URL)
|
||||
|
||||
@@ -103,29 +103,17 @@ func Test_decodeResp(t *testing.T) {
|
||||
t.Run("200 non-JSON", func(t *testing.T) {
|
||||
body := bytes.Buffer{}
|
||||
r := &http.Response{
|
||||
Status: "200",
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.OctetStreamMediaType}},
|
||||
}
|
||||
require.NoError(t, decodeResp(r, nil))
|
||||
})
|
||||
t.Run("204 non-JSON", func(t *testing.T) {
|
||||
body := bytes.Buffer{}
|
||||
r := &http.Response{
|
||||
Status: "204",
|
||||
StatusCode: http.StatusNoContent,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.OctetStreamMediaType}},
|
||||
}
|
||||
require.NoError(t, decodeResp(r, nil))
|
||||
})
|
||||
t.Run("500 non-JSON", func(t *testing.T) {
|
||||
t.Run("non-200 non-JSON", func(t *testing.T) {
|
||||
body := bytes.Buffer{}
|
||||
_, err := body.WriteString("foo")
|
||||
require.NoError(t, err)
|
||||
r := &http.Response{
|
||||
Status: "500",
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.OctetStreamMediaType}},
|
||||
@@ -142,7 +130,6 @@ func Test_decodeResp(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
body.Write(b)
|
||||
r := &http.Response{
|
||||
Status: "200",
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
|
||||
@@ -154,30 +141,18 @@ func Test_decodeResp(t *testing.T) {
|
||||
t.Run("200 JSON without resp", func(t *testing.T) {
|
||||
body := bytes.Buffer{}
|
||||
r := &http.Response{
|
||||
Status: "200",
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
|
||||
}
|
||||
require.NoError(t, decodeResp(r, nil))
|
||||
})
|
||||
t.Run("204 JSON", func(t *testing.T) {
|
||||
body := bytes.Buffer{}
|
||||
r := &http.Response{
|
||||
Status: "204",
|
||||
StatusCode: http.StatusNoContent,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
|
||||
}
|
||||
require.NoError(t, decodeResp(r, nil))
|
||||
})
|
||||
t.Run("500 JSON", func(t *testing.T) {
|
||||
t.Run("non-200 JSON", func(t *testing.T) {
|
||||
body := bytes.Buffer{}
|
||||
b, err := json.Marshal(&httputil.DefaultJsonError{Code: http.StatusInternalServerError, Message: "error"})
|
||||
require.NoError(t, err)
|
||||
body.Write(b)
|
||||
r := &http.Response{
|
||||
Status: "500",
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
|
||||
@@ -193,7 +168,6 @@ func Test_decodeResp(t *testing.T) {
|
||||
_, err := body.WriteString("foo")
|
||||
require.NoError(t, err)
|
||||
r := &http.Response{
|
||||
Status: "200",
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
|
||||
@@ -203,12 +177,11 @@ func Test_decodeResp(t *testing.T) {
|
||||
err = decodeResp(r, resp)
|
||||
assert.ErrorContains(t, "failed to decode response body into json", err)
|
||||
})
|
||||
t.Run("500 JSON cannot decode", func(t *testing.T) {
|
||||
t.Run("non-200 JSON cannot decode", func(t *testing.T) {
|
||||
body := bytes.Buffer{}
|
||||
_, err := body.WriteString("foo")
|
||||
require.NoError(t, err)
|
||||
r := &http.Response{
|
||||
Status: "500",
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Body: io.NopCloser(&body),
|
||||
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
|
||||
|
||||
@@ -4,12 +4,10 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/events"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -28,8 +26,8 @@ type streamSlotsClient struct {
|
||||
ctx context.Context
|
||||
beaconApiClient beaconApiValidatorClient
|
||||
streamSlotsRequest *ethpb.StreamSlotsRequest
|
||||
prevBlockSlot primitives.Slot
|
||||
pingDelay time.Duration
|
||||
ch chan event
|
||||
}
|
||||
|
||||
type streamBlocksAltairClient struct {
|
||||
@@ -48,14 +46,11 @@ type headSignedBeaconBlockResult struct {
|
||||
}
|
||||
|
||||
func (c beaconApiValidatorClient) streamSlots(ctx context.Context, in *ethpb.StreamSlotsRequest, pingDelay time.Duration) ethpb.BeaconNodeValidator_StreamSlotsClient {
|
||||
ch := make(chan event, 1)
|
||||
c.eventHandler.subscribe(eventSub{name: "stream slots", ch: ch})
|
||||
return &streamSlotsClient{
|
||||
ctx: ctx,
|
||||
beaconApiClient: c,
|
||||
streamSlotsRequest: in,
|
||||
pingDelay: pingDelay,
|
||||
ch: ch,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,27 +64,28 @@ func (c beaconApiValidatorClient) streamBlocks(ctx context.Context, in *ethpb.St
|
||||
}
|
||||
|
||||
func (c *streamSlotsClient) Recv() (*ethpb.StreamSlotsResponse, error) {
|
||||
for {
|
||||
result, err := c.beaconApiClient.getHeadSignedBeaconBlock(c.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get latest signed block")
|
||||
}
|
||||
|
||||
// We keep querying the beacon chain for the latest block until we receive a new slot
|
||||
for (c.streamSlotsRequest.VerifiedOnly && result.executionOptimistic) || c.prevBlockSlot == result.slot {
|
||||
select {
|
||||
case rawEvent := <-c.ch:
|
||||
if rawEvent.eventType != events.HeadTopic {
|
||||
continue
|
||||
}
|
||||
e := &events.HeadEvent{}
|
||||
if err := json.Unmarshal([]byte(rawEvent.data), e); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal head event into JSON")
|
||||
}
|
||||
uintSlot, err := strconv.ParseUint(e.Slot, 10, 64)
|
||||
case <-time.After(c.pingDelay):
|
||||
result, err = c.beaconApiClient.getHeadSignedBeaconBlock(c.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse slot")
|
||||
return nil, errors.Wrap(err, "failed to get latest signed block")
|
||||
}
|
||||
return ðpb.StreamSlotsResponse{
|
||||
Slot: primitives.Slot(uintSlot),
|
||||
}, nil
|
||||
case <-c.ctx.Done():
|
||||
return nil, errors.New("context canceled")
|
||||
}
|
||||
}
|
||||
|
||||
c.prevBlockSlot = result.slot
|
||||
return ðpb.StreamSlotsResponse{
|
||||
Slot: result.slot,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *streamBlocksAltairClient) Recv() (*ethpb.StreamBlocksResponse, error) {
|
||||
|
||||
@@ -29,10 +29,6 @@ func (c *grpcNodeClient) ListPeers(ctx context.Context, in *empty.Empty) (*ethpb
|
||||
return c.nodeClient.ListPeers(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcNodeClient) IsHealthy(context.Context) bool {
|
||||
panic("function not supported for gRPC client")
|
||||
}
|
||||
|
||||
func NewNodeClient(cc grpc.ClientConnInterface) iface.NodeClient {
|
||||
return &grpcNodeClient{ethpb.NewNodeClient(cc)}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user