mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-05-02 03:02:54 -04:00
More Efficient Validation of Proposer Index (#8107)
* metric * make it better * make it better * gaz Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
This commit is contained in:
@@ -47,6 +47,7 @@ var (
|
||||
Help: "Count the number of times a node resyncs.",
|
||||
},
|
||||
)
|
||||
|
||||
arrivalBlockPropagationHistogram = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "block_arrival_latency_milliseconds",
|
||||
|
||||
@@ -136,7 +136,8 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms
|
||||
log.WithError(err).WithField("blockSlot", blk.Block.Slot).Warn("Rejected block")
|
||||
return pubsub.ValidationReject
|
||||
}
|
||||
|
||||
// Record attribute of valid block.
|
||||
span.AddAttributes(trace.Int64Attribute("slotInEpoch", int64(blk.Block.Slot%params.BeaconConfig().SlotsPerEpoch)))
|
||||
msg.ValidatorData = blk // Used in downstream subscriber
|
||||
return pubsub.ValidationAccept
|
||||
}
|
||||
@@ -167,10 +168,26 @@ func (s *Service) validateBeaconBlock(ctx context.Context, blk *ethpb.SignedBeac
|
||||
s.setBadBlock(ctx, blockRoot)
|
||||
return err
|
||||
}
|
||||
|
||||
parentState, err = state.ProcessSlots(ctx, parentState, blk.Block.Slot)
|
||||
if err != nil {
|
||||
return err
|
||||
// There is an epoch lookahead for validator proposals
|
||||
// for the next epoch from the start of our current epoch. We
|
||||
// use the randao mix at the end of the previous epoch as the seed
|
||||
// to determine proposals.
|
||||
// Seed for Next Epoch => Derived From Randao Mix at the end of the Previous Epoch.
|
||||
// Which is why we simply set the slot over here.
|
||||
nextEpoch := helpers.NextEpoch(parentState)
|
||||
expectedEpoch := helpers.SlotToEpoch(blk.Block.Slot)
|
||||
if expectedEpoch <= nextEpoch {
|
||||
err = parentState.SetSlot(blk.Block.Slot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// In the event the block is more than an epoch ahead from its
|
||||
// parent state, we have to advance the state forward.
|
||||
parentState, err = state.ProcessSlots(ctx, parentState, blk.Block.Slot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
idx, err := helpers.BeaconProposerIndex(parentState)
|
||||
if err != nil {
|
||||
|
||||
@@ -244,6 +244,69 @@ func TestValidateBeaconBlockPubSub_ValidProposerSignature(t *testing.T) {
|
||||
assert.NotNil(t, m.ValidatorData, "Decoded message was not set on the message validator data")
|
||||
}
|
||||
|
||||
func TestValidateBeaconBlockPubSub_WithLookahead(t *testing.T) {
|
||||
db, stateSummaryCache := dbtest.SetupDB(t)
|
||||
p := p2ptest.NewTestP2P(t)
|
||||
ctx := context.Background()
|
||||
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
|
||||
parentBlock := testutil.NewBeaconBlock()
|
||||
require.NoError(t, db.SaveBlock(ctx, parentBlock))
|
||||
bRoot, err := parentBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, db.SaveState(ctx, beaconState, bRoot))
|
||||
require.NoError(t, db.SaveStateSummary(ctx, &pb.StateSummary{Root: bRoot[:]}))
|
||||
copied := beaconState.Copy()
|
||||
// The next block is only 1 epoch ahead so as to not induce a new seed.
|
||||
blkSlot := params.BeaconConfig().SlotsPerEpoch * helpers.NextEpoch(copied)
|
||||
copied, err = state.ProcessSlots(context.Background(), copied, blkSlot)
|
||||
require.NoError(t, err)
|
||||
proposerIdx, err := helpers.BeaconProposerIndex(copied)
|
||||
require.NoError(t, err)
|
||||
msg := testutil.NewBeaconBlock()
|
||||
msg.Block.ProposerIndex = proposerIdx
|
||||
msg.Block.Slot = blkSlot
|
||||
msg.Block.ParentRoot = bRoot[:]
|
||||
msg.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, msg.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx])
|
||||
require.NoError(t, err)
|
||||
|
||||
c, err := lru.New(10)
|
||||
require.NoError(t, err)
|
||||
c2, err := lru.New(10)
|
||||
require.NoError(t, err)
|
||||
stateGen := stategen.New(db, stateSummaryCache)
|
||||
chainService := &mock.ChainService{Genesis: time.Unix(time.Now().Unix()-int64(blkSlot*params.BeaconConfig().SecondsPerSlot), 0),
|
||||
State: beaconState,
|
||||
FinalizedCheckPoint: ðpb.Checkpoint{
|
||||
Epoch: 0,
|
||||
}}
|
||||
r := &Service{
|
||||
db: db,
|
||||
p2p: p,
|
||||
initialSync: &mockSync.Sync{IsSyncing: false},
|
||||
chain: chainService,
|
||||
blockNotifier: chainService.BlockNotifier(),
|
||||
seenBlockCache: c,
|
||||
badBlockCache: c2,
|
||||
slotToPendingBlocks: gcache.New(time.Second, 2*time.Second),
|
||||
seenPendingBlocks: make(map[[32]byte]bool),
|
||||
stateSummaryCache: stateSummaryCache,
|
||||
stateGen: stateGen,
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
_, err = p.Encoding().EncodeGossip(buf, msg)
|
||||
require.NoError(t, err)
|
||||
topic := p2p.GossipTypeMapping[reflect.TypeOf(msg)]
|
||||
m := &pubsub.Message{
|
||||
Message: &pubsubpb.Message{
|
||||
Data: buf.Bytes(),
|
||||
Topic: &topic,
|
||||
},
|
||||
}
|
||||
result := r.validateBeaconBlockPubSub(ctx, "", m) == pubsub.ValidationAccept
|
||||
assert.Equal(t, true, result)
|
||||
assert.NotNil(t, m.ValidatorData, "Decoded message was not set on the message validator data")
|
||||
}
|
||||
|
||||
func TestValidateBeaconBlockPubSub_AdvanceEpochsForState(t *testing.T) {
|
||||
db, stateSummaryCache := dbtest.SetupDB(t)
|
||||
p := p2ptest.NewTestP2P(t)
|
||||
|
||||
Reference in New Issue
Block a user