mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-21 22:04:44 +00:00
Fix http api tests ci (#7943)
Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com> Co-Authored-By: Michael Sproul <micsproul@gmail.com> Co-Authored-By: Michael Sproul <michael@sigmaprime.io> Co-Authored-By: hopinheimer <knmanas6@gmail.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use beacon_chain::test_utils::test_spec;
|
||||
use beacon_chain::{
|
||||
GossipVerifiedBlock, IntoGossipVerifiedBlock,
|
||||
GossipVerifiedBlock, IntoGossipVerifiedBlock, WhenSlotSkipped,
|
||||
test_utils::{AttestationStrategy, BlockStrategy},
|
||||
};
|
||||
use eth2::reqwest::StatusCode;
|
||||
use eth2::reqwest::{Response, StatusCode};
|
||||
use eth2::types::{BroadcastValidation, PublishBlockRequest};
|
||||
use http_api::test_utils::InteractiveTester;
|
||||
use http_api::{Config, ProvenancedBlock, publish_blinded_block, publish_block, reconstruct_block};
|
||||
@@ -74,7 +74,7 @@ pub async fn gossip_invalid() {
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&PublishBlockRequest::new(block, blobs), validation_level)
|
||||
.await;
|
||||
@@ -85,7 +85,13 @@ pub async fn gossip_invalid() {
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: NotFinalizedDescendant { block_parent_root: 0x0000000000000000000000000000000000000000000000000000000000000000 }".to_string());
|
||||
// Since Deneb, the invalidity of the blobs will be detected prior to the invalidity of the
|
||||
// block.
|
||||
let pre_finalized_block_root = Hash256::zero();
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!("BAD_REQUEST: ParentUnknown {{ parent_root: {pre_finalized_block_root:?} }}"),
|
||||
);
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from a gossip perspective is accepted when using `broadcast_validation=gossip`.
|
||||
@@ -123,15 +129,11 @@ pub async fn gossip_partial_pass() {
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&PublishBlockRequest::new(block, blobs), validation_level)
|
||||
.await;
|
||||
assert!(response.is_err());
|
||||
|
||||
let error_response = response.unwrap_err();
|
||||
|
||||
assert_eq!(error_response.status(), Some(StatusCode::ACCEPTED));
|
||||
assert_eq!(response.unwrap().status(), StatusCode::ACCEPTED);
|
||||
}
|
||||
|
||||
// This test checks that a block that is valid from both a gossip and consensus perspective is accepted when using `broadcast_validation=gossip`.
|
||||
@@ -164,7 +166,7 @@ pub async fn gossip_full_pass() {
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let ((block, blobs), _) = tester.harness.make_block(state_a, slot_b).await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(block.clone(), blobs),
|
||||
@@ -215,7 +217,7 @@ pub async fn gossip_full_pass_ssz() {
|
||||
let (block_contents_tuple, _) = tester.harness.make_block(state_a, slot_b).await;
|
||||
let block_contents = block_contents_tuple.into();
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&block_contents, validation_level)
|
||||
.await;
|
||||
@@ -264,7 +266,7 @@ pub async fn consensus_invalid() {
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&PublishBlockRequest::new(block, blobs), validation_level)
|
||||
.await;
|
||||
@@ -274,7 +276,13 @@ pub async fn consensus_invalid() {
|
||||
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: NotFinalizedDescendant { block_parent_root: 0x0000000000000000000000000000000000000000000000000000000000000000 }".to_string());
|
||||
// Since Deneb, the invalidity of the blobs will be detected prior to the invalidity of the
|
||||
// block.
|
||||
let pre_finalized_block_root = Hash256::zero();
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!("BAD_REQUEST: ParentUnknown {{ parent_root: {pre_finalized_block_root:?} }}"),
|
||||
);
|
||||
}
|
||||
|
||||
/// This test checks that a block that is only valid from a gossip perspective is rejected when using `broadcast_validation=consensus`.
|
||||
@@ -304,13 +312,17 @@ pub async fn consensus_gossip() {
|
||||
let slot_a = Slot::new(num_initial);
|
||||
let slot_b = slot_a + 1;
|
||||
|
||||
let mut correct_state_root = Hash256::ZERO;
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let ((block, blobs), _) = tester
|
||||
.harness
|
||||
.make_block_with_modifier(state_a, slot_b, |b| *b.state_root_mut() = Hash256::zero())
|
||||
.make_block_with_modifier(state_a, slot_b, |b| {
|
||||
*correct_state_root = *b.state_root();
|
||||
*b.state_root_mut() = Hash256::zero()
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&PublishBlockRequest::new(block, blobs), validation_level)
|
||||
.await;
|
||||
@@ -320,7 +332,14 @@ pub async fn consensus_gossip() {
|
||||
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: Invalid block: StateRootMismatch { block: 0x0000000000000000000000000000000000000000000000000000000000000000, local: 0x253405be9aa159bce7b276b8e1d3849c743e673118dfafe8c7d07c203ae0d80d }".to_string());
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!(
|
||||
"BAD_REQUEST: Invalid block: StateRootMismatch {{ block: {}, \
|
||||
local: {correct_state_root:?} }}",
|
||||
Hash256::ZERO
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from both a gossip and consensus perspective, but nonetheless equivocates, is accepted when using `broadcast_validation=consensus`.
|
||||
@@ -424,7 +443,7 @@ pub async fn consensus_full_pass() {
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let ((block, blobs), _) = tester.harness.make_block(state_a, slot_b).await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(block.clone(), blobs),
|
||||
@@ -478,7 +497,7 @@ pub async fn equivocation_invalid() {
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&PublishBlockRequest::new(block, blobs), validation_level)
|
||||
.await;
|
||||
@@ -488,7 +507,13 @@ pub async fn equivocation_invalid() {
|
||||
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: NotFinalizedDescendant { block_parent_root: 0x0000000000000000000000000000000000000000000000000000000000000000 }".to_string());
|
||||
// Since Deneb, the invalidity of the blobs will be detected prior to the invalidity of the
|
||||
// block.
|
||||
let pre_finalized_block_root = Hash256::zero();
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!("BAD_REQUEST: ParentUnknown {{ parent_root: {pre_finalized_block_root:?} }}"),
|
||||
);
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from both a gossip and consensus perspective is rejected when using `broadcast_validation=consensus_and_equivocation`.
|
||||
@@ -554,7 +579,7 @@ pub async fn equivocation_consensus_early_equivocation() {
|
||||
);
|
||||
|
||||
/* submit `block_b` which should induce equivocation */
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(block_b.clone(), blobs_b),
|
||||
@@ -597,14 +622,18 @@ pub async fn equivocation_gossip() {
|
||||
|
||||
let slot_a = Slot::new(num_initial);
|
||||
let slot_b = slot_a + 1;
|
||||
let mut correct_state_root = Hash256::zero();
|
||||
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let ((block, blobs), _) = tester
|
||||
.harness
|
||||
.make_block_with_modifier(state_a, slot_b, |b| *b.state_root_mut() = Hash256::zero())
|
||||
.make_block_with_modifier(state_a, slot_b, |b| {
|
||||
*correct_state_root = *b.state_root();
|
||||
*b.state_root_mut() = Hash256::zero()
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&PublishBlockRequest::new(block, blobs), validation_level)
|
||||
.await;
|
||||
@@ -614,7 +643,13 @@ pub async fn equivocation_gossip() {
|
||||
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: Invalid block: StateRootMismatch { block: 0x0000000000000000000000000000000000000000000000000000000000000000, local: 0x253405be9aa159bce7b276b8e1d3849c743e673118dfafe8c7d07c203ae0d80d }".to_string());
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!(
|
||||
"BAD_REQUEST: Invalid block: StateRootMismatch {{ block: {}, local: {correct_state_root} }}",
|
||||
Hash256::zero()
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from both a gossip and consensus perspective but
|
||||
@@ -725,7 +760,7 @@ pub async fn equivocation_full_pass() {
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let ((block, blobs), _) = tester.harness.make_block(state_a, slot_b).await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(block.clone(), blobs),
|
||||
@@ -770,28 +805,43 @@ pub async fn blinded_gossip_invalid() {
|
||||
|
||||
tester.harness.advance_slot();
|
||||
|
||||
let (block_contents_tuple, _) = tester
|
||||
let (blinded_block, _) = tester
|
||||
.harness
|
||||
.make_block_with_modifier(chain_state_before, slot, |b| {
|
||||
.make_blinded_block_with_modifier(chain_state_before, slot, |b| {
|
||||
*b.state_root_mut() = Hash256::zero();
|
||||
*b.parent_root_mut() = Hash256::zero();
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_contents_tuple.0.clone_as_blinded(), validation_level)
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block, validation_level)
|
||||
.await;
|
||||
assert!(response.is_err());
|
||||
|
||||
let error_response: eth2::Error = response.err().unwrap();
|
||||
|
||||
let pre_finalized_block_root = Hash256::zero();
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: NotFinalizedDescendant { block_parent_root: 0x0000000000000000000000000000000000000000000000000000000000000000 }".to_string());
|
||||
if tester.harness.spec.is_fulu_scheduled() {
|
||||
// XXX: this should be a 400 but is a 500 due to the mock-builder being janky
|
||||
assert_eq!(
|
||||
error_response.status(),
|
||||
Some(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
);
|
||||
} else {
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!("BAD_REQUEST: ParentUnknown {{ parent_root: {pre_finalized_block_root:?} }}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from a gossip perspective is accepted when using `broadcast_validation=gossip`.
|
||||
/// Process a blinded block that is invalid, but valid on gossip.
|
||||
///
|
||||
/// Due to the checks conducted by the "relay" (mock-builder) when `broadcast_to_bn` is set (post
|
||||
/// Fulu), we can't always assert that we get a 202 status for this block -- post Fulu the relay
|
||||
/// detects it as invalid and the BN returns an error.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
pub async fn blinded_gossip_partial_pass() {
|
||||
/* this test targets gossip-level validation */
|
||||
@@ -819,22 +869,27 @@ pub async fn blinded_gossip_partial_pass() {
|
||||
|
||||
tester.harness.advance_slot();
|
||||
|
||||
let (block_contents_tuple, _) = tester
|
||||
let (blinded_block, _) = tester
|
||||
.harness
|
||||
.make_block_with_modifier(chain_state_before, slot, |b| {
|
||||
.make_blinded_block_with_modifier(chain_state_before, slot, |b| {
|
||||
*b.state_root_mut() = Hash256::zero()
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_contents_tuple.0.clone_as_blinded(), validation_level)
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block, validation_level)
|
||||
.await;
|
||||
assert!(response.is_err());
|
||||
|
||||
let error_response = response.unwrap_err();
|
||||
|
||||
assert_eq!(error_response.status(), Some(StatusCode::ACCEPTED));
|
||||
if tester.harness.spec.is_fulu_scheduled() {
|
||||
let error_response = response.unwrap_err();
|
||||
// XXX: this should be a 400 but is a 500 due to the mock-builder being janky
|
||||
assert_eq!(
|
||||
error_response.status(),
|
||||
Some(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
);
|
||||
} else {
|
||||
assert_eq!(response.unwrap().status(), StatusCode::ACCEPTED);
|
||||
}
|
||||
}
|
||||
|
||||
// This test checks that a block that is valid from both a gossip and consensus perspective is accepted when using `broadcast_validation=gossip`.
|
||||
@@ -866,12 +921,13 @@ pub async fn blinded_gossip_full_pass() {
|
||||
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let (blinded_block, _) = tester.harness.make_blinded_block(state_a, slot_b).await;
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block, validation_level)
|
||||
.await;
|
||||
|
||||
assert!(response.is_ok());
|
||||
assert_eq!(response.unwrap().status(), StatusCode::OK);
|
||||
assert!(
|
||||
tester
|
||||
.harness
|
||||
@@ -910,12 +966,13 @@ pub async fn blinded_gossip_full_pass_ssz() {
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let (blinded_block, _) = tester.harness.make_blinded_block(state_a, slot_b).await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2_ssz(&blinded_block, validation_level)
|
||||
.await;
|
||||
|
||||
assert!(response.is_ok());
|
||||
assert_eq!(response.unwrap().status(), StatusCode::OK);
|
||||
assert!(
|
||||
tester
|
||||
.harness
|
||||
@@ -933,7 +990,7 @@ pub async fn blinded_consensus_invalid() {
|
||||
// Validator count needs to be at least 32 or proposer boost gets set to 0 when computing
|
||||
// `validator_count // 32`.
|
||||
let validator_count = 64;
|
||||
let num_initial: u64 = 31;
|
||||
let num_initial: u64 = 256;
|
||||
let tester = InteractiveTester::<E>::new(None, validator_count).await;
|
||||
|
||||
// Create some chain depth.
|
||||
@@ -952,25 +1009,48 @@ pub async fn blinded_consensus_invalid() {
|
||||
|
||||
tester.harness.advance_slot();
|
||||
|
||||
let (block_contents_tuple, _) = tester
|
||||
let finalized_slot = chain_state_before
|
||||
.finalized_checkpoint()
|
||||
.epoch
|
||||
.start_slot(E::slots_per_epoch());
|
||||
assert_ne!(finalized_slot, 0);
|
||||
let pre_finalized_block_root = tester
|
||||
.harness
|
||||
.make_block_with_modifier(chain_state_before, slot, |b| {
|
||||
.chain
|
||||
.block_root_at_slot(finalized_slot - 1, WhenSlotSkipped::Prev)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
let (blinded_block, _) = tester
|
||||
.harness
|
||||
.make_blinded_block_with_modifier(chain_state_before, slot, |b| {
|
||||
*b.state_root_mut() = Hash256::zero();
|
||||
*b.parent_root_mut() = Hash256::zero();
|
||||
*b.parent_root_mut() = pre_finalized_block_root;
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_contents_tuple.0.clone_as_blinded(), validation_level)
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block, validation_level)
|
||||
.await;
|
||||
assert!(response.is_err());
|
||||
|
||||
let error_response: eth2::Error = response.err().unwrap();
|
||||
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: NotFinalizedDescendant { block_parent_root: 0x0000000000000000000000000000000000000000000000000000000000000000 }".to_string());
|
||||
if tester.harness.spec.is_fulu_scheduled() {
|
||||
// XXX: this should be a 400 but is a 500 due to the mock-builder being janky
|
||||
assert_eq!(
|
||||
error_response.status(),
|
||||
Some(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
);
|
||||
} else {
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!("BAD_REQUEST: ParentUnknown {{ parent_root: {pre_finalized_block_root:?} }}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// This test checks that a block that is only valid from a gossip perspective is rejected when using `broadcast_validation=consensus`.
|
||||
@@ -1000,23 +1080,44 @@ pub async fn blinded_consensus_gossip() {
|
||||
let slot_a = Slot::new(num_initial);
|
||||
let slot_b = slot_a + 1;
|
||||
|
||||
let mut correct_state_root = Hash256::zero();
|
||||
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let (block_contents_tuple, _) = tester
|
||||
let (blinded_block, _) = tester
|
||||
.harness
|
||||
.make_block_with_modifier(state_a, slot_b, |b| *b.state_root_mut() = Hash256::zero())
|
||||
.make_blinded_block_with_modifier(state_a, slot_b, |b| {
|
||||
*correct_state_root = *b.state_root();
|
||||
*b.state_root_mut() = Hash256::zero()
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_contents_tuple.0.clone_as_blinded(), validation_level)
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block, validation_level)
|
||||
.await;
|
||||
|
||||
assert!(response.is_err());
|
||||
|
||||
let error_response: eth2::Error = response.err().unwrap();
|
||||
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: Invalid block: StateRootMismatch { block: 0x0000000000000000000000000000000000000000000000000000000000000000, local: 0x253405be9aa159bce7b276b8e1d3849c743e673118dfafe8c7d07c203ae0d80d }".to_string());
|
||||
if tester.harness.spec.is_fulu_scheduled() {
|
||||
// XXX: this should be a 400 but is a 500 due to the mock-builder being janky
|
||||
assert_eq!(
|
||||
error_response.status(),
|
||||
Some(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
);
|
||||
} else {
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!(
|
||||
"BAD_REQUEST: Invalid block: StateRootMismatch {{ block: {}, \
|
||||
local: {correct_state_root} }}",
|
||||
Hash256::ZERO
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from both a gossip and consensus perspective is accepted when using `broadcast_validation=consensus`.
|
||||
@@ -1049,7 +1150,7 @@ pub async fn blinded_consensus_full_pass() {
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let (blinded_block, _) = tester.harness.make_blinded_block(state_a, slot_b).await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block, validation_level)
|
||||
.await;
|
||||
@@ -1073,7 +1174,7 @@ pub async fn blinded_equivocation_invalid() {
|
||||
// Validator count needs to be at least 32 or proposer boost gets set to 0 when computing
|
||||
// `validator_count // 32`.
|
||||
let validator_count = 64;
|
||||
let num_initial: u64 = 31;
|
||||
let num_initial: u64 = 256;
|
||||
let tester = InteractiveTester::<E>::new(None, validator_count).await;
|
||||
|
||||
// Create some chain depth.
|
||||
@@ -1092,25 +1193,47 @@ pub async fn blinded_equivocation_invalid() {
|
||||
|
||||
tester.harness.advance_slot();
|
||||
|
||||
let (block_contents_tuple, _) = tester
|
||||
let finalized_slot = chain_state_before
|
||||
.finalized_checkpoint()
|
||||
.epoch
|
||||
.start_slot(E::slots_per_epoch());
|
||||
assert_ne!(finalized_slot, 0);
|
||||
let pre_finalized_block_root = tester
|
||||
.harness
|
||||
.make_block_with_modifier(chain_state_before, slot, |b| {
|
||||
.chain
|
||||
.block_root_at_slot(finalized_slot - 1, WhenSlotSkipped::Prev)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
let (blinded_block, _) = tester
|
||||
.harness
|
||||
.make_blinded_block_with_modifier(chain_state_before, slot, |b| {
|
||||
*b.state_root_mut() = Hash256::zero();
|
||||
*b.parent_root_mut() = Hash256::zero();
|
||||
*b.parent_root_mut() = pre_finalized_block_root;
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_contents_tuple.0.clone_as_blinded(), validation_level)
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block, validation_level)
|
||||
.await;
|
||||
assert!(response.is_err());
|
||||
|
||||
let error_response: eth2::Error = response.err().unwrap();
|
||||
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: NotFinalizedDescendant { block_parent_root: 0x0000000000000000000000000000000000000000000000000000000000000000 }".to_string());
|
||||
if tester.harness.spec.is_fulu_scheduled() {
|
||||
assert_eq!(
|
||||
error_response.status(),
|
||||
Some(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
);
|
||||
} else {
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!("BAD_REQUEST: ParentUnknown {{ parent_root: {pre_finalized_block_root:?} }}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from both a gossip and consensus perspective is rejected when using `broadcast_validation=consensus_and_equivocation`.
|
||||
@@ -1160,13 +1283,11 @@ pub async fn blinded_equivocation_consensus_early_equivocation() {
|
||||
assert_ne!(block_a.state_root(), block_b.state_root());
|
||||
|
||||
/* submit `block_a` as valid */
|
||||
assert!(
|
||||
tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_a, validation_level)
|
||||
.await
|
||||
.is_ok()
|
||||
);
|
||||
tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_a, validation_level)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(
|
||||
tester
|
||||
.harness
|
||||
@@ -1175,7 +1296,7 @@ pub async fn blinded_equivocation_consensus_early_equivocation() {
|
||||
);
|
||||
|
||||
/* submit `block_b` which should induce equivocation */
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_b, validation_level)
|
||||
.await;
|
||||
@@ -1183,8 +1304,15 @@ pub async fn blinded_equivocation_consensus_early_equivocation() {
|
||||
|
||||
let error_response: eth2::Error = response.err().unwrap();
|
||||
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: Slashable".to_string());
|
||||
if tester.harness.spec.is_fulu_scheduled() {
|
||||
assert_eq!(
|
||||
error_response.status(),
|
||||
Some(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
);
|
||||
} else {
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: Slashable".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
/// This test checks that a block that is only valid from a gossip perspective is rejected when using `broadcast_validation=consensus_and_equivocation`.
|
||||
@@ -1215,24 +1343,41 @@ pub async fn blinded_equivocation_gossip() {
|
||||
let slot_a = Slot::new(num_initial);
|
||||
let slot_b = slot_a + 1;
|
||||
|
||||
let mut correct_state_root = Hash256::zero();
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let (block_contents_tuple, _) = tester
|
||||
let (blinded_block, _) = tester
|
||||
.harness
|
||||
.make_block_with_modifier(state_a, slot_b, |b| *b.state_root_mut() = Hash256::zero())
|
||||
.make_blinded_block_with_modifier(state_a, slot_b, |b| {
|
||||
*correct_state_root = *b.state_root();
|
||||
*b.state_root_mut() = Hash256::zero()
|
||||
})
|
||||
.await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block_contents_tuple.0.clone_as_blinded(), validation_level)
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block, validation_level)
|
||||
.await;
|
||||
assert!(response.is_err());
|
||||
|
||||
assert!(response.is_err());
|
||||
let error_response: eth2::Error = response.err().unwrap();
|
||||
|
||||
/* mandated by Beacon API spec */
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
|
||||
assert_server_message_error(error_response, "BAD_REQUEST: Invalid block: StateRootMismatch { block: 0x0000000000000000000000000000000000000000000000000000000000000000, local: 0x253405be9aa159bce7b276b8e1d3849c743e673118dfafe8c7d07c203ae0d80d }".to_string());
|
||||
if tester.harness.spec.is_fulu_scheduled() {
|
||||
// XXX: this should be a 400 but is a 500 due to the mock-builder being janky
|
||||
assert_eq!(
|
||||
error_response.status(),
|
||||
Some(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
);
|
||||
} else {
|
||||
assert_eq!(error_response.status(), Some(StatusCode::BAD_REQUEST));
|
||||
assert_server_message_error(
|
||||
error_response,
|
||||
format!(
|
||||
"BAD_REQUEST: Invalid block: StateRootMismatch {{ block: {}, local: {correct_state_root} }}",
|
||||
Hash256::zero()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from both a gossip and
|
||||
@@ -1287,54 +1432,58 @@ pub async fn blinded_equivocation_consensus_late_equivocation() {
|
||||
);
|
||||
assert_ne!(block_a.state_root(), block_b.state_root());
|
||||
|
||||
let unblinded_block_a = reconstruct_block(
|
||||
tester.harness.chain.clone(),
|
||||
block_a.canonical_root(),
|
||||
Arc::new(block_a),
|
||||
)
|
||||
.await
|
||||
.expect("failed to reconstruct block")
|
||||
.expect("block expected");
|
||||
// From fulu builders never send back a full payload, hence further checks in this test
|
||||
// are not possible
|
||||
if !tester.harness.spec.is_fulu_scheduled() {
|
||||
let unblinded_block_a = reconstruct_block(
|
||||
tester.harness.chain.clone(),
|
||||
block_a.canonical_root(),
|
||||
Arc::new(block_a),
|
||||
)
|
||||
.await
|
||||
.expect("failed to reconstruct block")
|
||||
.expect("block expected");
|
||||
|
||||
let unblinded_block_b = reconstruct_block(
|
||||
tester.harness.chain.clone(),
|
||||
block_b.canonical_root(),
|
||||
block_b.clone(),
|
||||
)
|
||||
.await
|
||||
.expect("failed to reconstruct block")
|
||||
.expect("block expected");
|
||||
let unblinded_block_b = reconstruct_block(
|
||||
tester.harness.chain.clone(),
|
||||
block_b.canonical_root(),
|
||||
block_b.clone(),
|
||||
)
|
||||
.await
|
||||
.expect("failed to reconstruct block")
|
||||
.expect("block expected");
|
||||
|
||||
let inner_block_a = match unblinded_block_a {
|
||||
ProvenancedBlock::Local(a, _, _) => a,
|
||||
ProvenancedBlock::Builder(a, _, _) => a,
|
||||
};
|
||||
let inner_block_b = match unblinded_block_b {
|
||||
ProvenancedBlock::Local(b, _, _) => b,
|
||||
ProvenancedBlock::Builder(b, _, _) => b,
|
||||
};
|
||||
let inner_block_a = match unblinded_block_a {
|
||||
ProvenancedBlock::Local(a, _, _) => a,
|
||||
ProvenancedBlock::Builder(a, _, _) => a,
|
||||
};
|
||||
let inner_block_b = match unblinded_block_b {
|
||||
ProvenancedBlock::Local(b, _, _) => b,
|
||||
ProvenancedBlock::Builder(b, _, _) => b,
|
||||
};
|
||||
|
||||
let gossip_block_b = GossipVerifiedBlock::new(inner_block_b, &tester.harness.chain);
|
||||
assert!(gossip_block_b.is_ok());
|
||||
let gossip_block_a = GossipVerifiedBlock::new(inner_block_a, &tester.harness.chain);
|
||||
assert!(gossip_block_a.is_err());
|
||||
let gossip_block_b = GossipVerifiedBlock::new(inner_block_b, &tester.harness.chain);
|
||||
assert!(gossip_block_b.is_ok());
|
||||
let gossip_block_a = GossipVerifiedBlock::new(inner_block_a, &tester.harness.chain);
|
||||
assert!(gossip_block_a.is_err());
|
||||
|
||||
let channel = tokio::sync::mpsc::unbounded_channel();
|
||||
let channel = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
let publication_result = publish_blinded_block(
|
||||
block_b,
|
||||
tester.harness.chain,
|
||||
&channel.0,
|
||||
validation_level,
|
||||
StatusCode::ACCEPTED,
|
||||
)
|
||||
.await;
|
||||
let publication_result = publish_blinded_block(
|
||||
block_b,
|
||||
tester.harness.chain,
|
||||
&channel.0,
|
||||
validation_level,
|
||||
StatusCode::ACCEPTED,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(publication_result.is_err());
|
||||
assert!(publication_result.is_err());
|
||||
|
||||
let publication_error: Rejection = publication_result.unwrap_err();
|
||||
let publication_error: Rejection = publication_result.unwrap_err();
|
||||
|
||||
assert!(publication_error.find::<CustomBadRequest>().is_some());
|
||||
assert!(publication_error.find::<CustomBadRequest>().is_some());
|
||||
}
|
||||
}
|
||||
|
||||
/// This test checks that a block that is valid from both a gossip and consensus perspective (and does not equivocate) is accepted when using `broadcast_validation=consensus_and_equivocation`.
|
||||
@@ -1368,7 +1517,7 @@ pub async fn blinded_equivocation_full_pass() {
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let (block, _) = tester.harness.make_blinded_block(state_a, slot_b).await;
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blinded_blocks_v2(&block, validation_level)
|
||||
.await;
|
||||
@@ -1434,7 +1583,7 @@ pub async fn block_seen_on_gossip_without_blobs_or_columns() {
|
||||
);
|
||||
|
||||
// Post the block *and* blobs to the HTTP API.
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(block.clone(), Some(blobs)),
|
||||
@@ -1522,7 +1671,7 @@ pub async fn block_seen_on_gossip_with_some_blobs_or_columns() {
|
||||
);
|
||||
|
||||
// Post the block *and* all blobs to the HTTP API.
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(block.clone(), Some(blobs)),
|
||||
@@ -1597,7 +1746,7 @@ pub async fn blobs_or_columns_seen_on_gossip_without_block() {
|
||||
);
|
||||
|
||||
// Post the block *and* all blobs to the HTTP API.
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(block.clone(), Some((kzg_proofs, blobs))),
|
||||
@@ -1672,7 +1821,7 @@ async fn blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_colu
|
||||
);
|
||||
|
||||
// Post just the block to the HTTP API (blob lists are empty).
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(
|
||||
@@ -1750,7 +1899,7 @@ async fn slashable_blobs_or_columns_seen_on_gossip_cause_failure() {
|
||||
);
|
||||
|
||||
// Post block A *and* all its blobs to the HTTP API.
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(
|
||||
&PublishBlockRequest::new(block_a.clone(), Some((kzg_proofs_a, blobs_a))),
|
||||
@@ -1788,6 +1937,7 @@ pub async fn duplicate_block_status_code() {
|
||||
duplicate_block_status_code,
|
||||
..Config::default()
|
||||
},
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -1812,7 +1962,7 @@ pub async fn duplicate_block_status_code() {
|
||||
|
||||
// Post the block blobs to the HTTP API once.
|
||||
let block_request = PublishBlockRequest::new(block.clone(), Some((kzg_proofs, blobs)));
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
let response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&block_request, validation_level)
|
||||
.await;
|
||||
@@ -1827,7 +1977,7 @@ pub async fn duplicate_block_status_code() {
|
||||
);
|
||||
|
||||
// Post again.
|
||||
let duplicate_response: Result<(), eth2::Error> = tester
|
||||
let duplicate_response: Result<Response, eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&block_request, validation_level)
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user