mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-18 22:49:34 +00:00
Impl 5302
This commit is contained in:
@@ -144,9 +144,17 @@ impl<T: BeaconChainTypes> GossipVerifiedPayloadBid<T> {
|
||||
let fork_choice = ctx.canonical_head.fork_choice_read_lock();
|
||||
|
||||
// TODO(gloas) reprocess bids whose parent_block_root becomes known & canonical after a reorg?
|
||||
if !fork_choice.contains_block(&bid_parent_block_root) {
|
||||
return Err(PayloadBidError::ParentBlockRootUnknown {
|
||||
let parent_block = fork_choice.get_block(&bid_parent_block_root).ok_or(
|
||||
PayloadBidError::ParentBlockRootUnknown {
|
||||
parent_block_root: bid_parent_block_root,
|
||||
},
|
||||
)?;
|
||||
|
||||
// [REJECT] The bid is for a higher slot than its parent block.
|
||||
if bid_slot <= parent_block.slot {
|
||||
return Err(PayloadBidError::BidNotDescendantOfParent {
|
||||
bid_slot,
|
||||
parent_slot: parent_block.slot,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ pub enum PayloadBidError {
|
||||
},
|
||||
/// The bids slot is not the current slot or the next slot.
|
||||
InvalidBidSlot { bid_slot: Slot },
|
||||
/// The bid's slot is not greater than the slot of its parent block.
|
||||
BidNotDescendantOfParent { bid_slot: Slot, parent_slot: Slot },
|
||||
/// The slot clock cannot be read.
|
||||
UnableToReadSlot,
|
||||
/// No proposer preferences for the current slot.
|
||||
|
||||
@@ -310,7 +310,7 @@ fn builder_already_seen_for_slot() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let bid = make_signed_bid(slot, 42, Address::ZERO, 30_000_000, 100, Hash256::ZERO);
|
||||
@@ -336,7 +336,7 @@ fn bid_value_below_cached() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let high_bid = GossipVerifiedPayloadBid {
|
||||
@@ -384,7 +384,7 @@ fn fee_recipient_mismatch() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::repeat_byte(0xaa), 30_000_000);
|
||||
|
||||
let bid = make_signed_bid(
|
||||
@@ -406,7 +406,7 @@ fn gas_limit_mismatch() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let bid = make_signed_bid(
|
||||
@@ -428,7 +428,7 @@ fn execution_payment_nonzero() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let bid = Arc::new(SignedExecutionPayloadBid {
|
||||
@@ -455,7 +455,7 @@ fn unknown_builder_index() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
// Use a builder_index that doesn't exist in the registry.
|
||||
@@ -483,7 +483,7 @@ fn inactive_builder() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let bid = make_signed_bid(
|
||||
@@ -508,7 +508,7 @@ fn builder_cant_cover_bid() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
// Builder index 0 exists but bid value far exceeds their balance.
|
||||
@@ -534,7 +534,7 @@ fn parent_block_root_unknown() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
// Parent block root not in fork choice.
|
||||
@@ -556,7 +556,9 @@ fn parent_block_root_not_canonical() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
// The non-canonical fork block is at slot 1, so use slot 2 to satisfy the `bid.slot > parent
|
||||
// block slot` rule and exercise the bid descendant from parent check specifically.
|
||||
let slot = Slot::new(2);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let fork_root = ctx.insert_non_canonical_block();
|
||||
@@ -570,6 +572,36 @@ fn parent_block_root_not_canonical() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bid_slot_not_after_parent() {
|
||||
if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
|
||||
return;
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
// The genesis (parent) block is at slot 0, so a bid at slot 0 is not for a higher slot than
|
||||
// its parent and must be rejected (per consensus-specs #5302).
|
||||
let slot = Slot::new(0);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let bid = make_signed_bid(
|
||||
slot,
|
||||
0,
|
||||
Address::ZERO,
|
||||
30_000_000,
|
||||
0,
|
||||
ctx.genesis_block_root,
|
||||
);
|
||||
let result = GossipVerifiedPayloadBid::new(bid, &gossip);
|
||||
assert!(
|
||||
matches!(
|
||||
result,
|
||||
Err(PayloadBidError::BidNotDescendantOfParent { .. })
|
||||
),
|
||||
"expected BidNotDescendantOfParent, got: {result:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_blob_kzg_commitments() {
|
||||
if !fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
|
||||
@@ -577,7 +609,7 @@ fn invalid_blob_kzg_commitments() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let max_blobs = ctx
|
||||
@@ -614,7 +646,7 @@ fn bad_signature() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
// All checks pass but signature is empty/invalid.
|
||||
@@ -643,7 +675,7 @@ fn valid_bid() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let bid = ctx.sign_bid(ExecutionPayloadBid {
|
||||
@@ -670,7 +702,7 @@ fn two_builders_coexist_in_cache() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
let bid_0 = ctx.sign_bid(ExecutionPayloadBid {
|
||||
@@ -725,7 +757,7 @@ fn bid_equal_to_cached_value_rejected() {
|
||||
}
|
||||
let ctx = TestContext::new();
|
||||
let gossip = ctx.gossip_ctx();
|
||||
let slot = Slot::new(0);
|
||||
let slot = Slot::new(1);
|
||||
seed_preferences(&ctx, slot, Address::ZERO, 30_000_000);
|
||||
|
||||
// Seed a cached bid with value 100.
|
||||
|
||||
Reference in New Issue
Block a user