Merge remote-tracking branch 'origin/deneb-free-blobs' into tree-states

This commit is contained in:
Michael Sproul
2023-09-29 16:34:29 +10:00
253 changed files with 21791 additions and 3122 deletions

View File

@@ -62,8 +62,8 @@ struct ApiTester {
harness: Arc<BeaconChainHarness<EphemeralHarnessType<E>>>,
chain: Arc<BeaconChain<EphemeralHarnessType<E>>>,
client: BeaconNodeHttpClient,
next_block: SignedBeaconBlock<E>,
reorg_block: SignedBeaconBlock<E>,
next_block: SignedBlockContents<E>,
reorg_block: SignedBlockContents<E>,
attestations: Vec<Attestation<E>>,
contribution_and_proofs: Vec<SignedContributionAndProof<E>>,
attester_slashing: AttesterSlashing<E>,
@@ -171,11 +171,13 @@ impl ApiTester {
let (next_block, _next_state) = harness
.make_block(head.beacon_state.clone(), harness.chain.slot().unwrap())
.await;
let next_block = SignedBlockContents::from(next_block);
// `make_block` adds random graffiti, so this will produce an alternate block
let (reorg_block, _reorg_state) = harness
.make_block(head.beacon_state.clone(), harness.chain.slot().unwrap() + 1)
.await;
let reorg_block = SignedBlockContents::from(reorg_block);
let head_state_root = head.beacon_state_root();
let attestations = harness
@@ -314,11 +316,13 @@ impl ApiTester {
let (next_block, _next_state) = harness
.make_block(head.beacon_state.clone(), harness.chain.slot().unwrap())
.await;
let next_block = SignedBlockContents::from(next_block);
// `make_block` adds random graffiti, so this will produce an alternate block
let (reorg_block, _reorg_state) = harness
.make_block(head.beacon_state.clone(), harness.chain.slot().unwrap())
.await;
let reorg_block = SignedBlockContents::from(reorg_block);
let head_state_root = head.beacon_state_root();
let attestations = harness
@@ -1256,9 +1260,9 @@ impl ApiTester {
}
pub async fn test_post_beacon_blocks_valid(mut self) -> Self {
let next_block = &self.next_block;
let next_block = self.next_block.clone();
self.client.post_beacon_blocks(next_block).await.unwrap();
self.client.post_beacon_blocks(&next_block).await.unwrap();
assert!(
self.network_rx.network_recv.recv().await.is_some(),
@@ -1297,7 +1301,11 @@ impl ApiTester {
.await
.0;
assert!(self.client.post_beacon_blocks(&block).await.is_err());
assert!(self
.client
.post_beacon_blocks(&SignedBlockContents::from(block))
.await
.is_err());
assert!(
self.network_rx.network_recv.recv().await.is_some(),
@@ -1320,7 +1328,11 @@ impl ApiTester {
.await
.0;
assert!(self.client.post_beacon_blocks_ssz(&block).await.is_err());
assert!(self
.client
.post_beacon_blocks_ssz(&SignedBlockContents::from(block))
.await
.is_err());
assert!(
self.network_rx.network_recv.recv().await.is_some(),
@@ -1331,48 +1343,56 @@ impl ApiTester {
}
pub async fn test_post_beacon_blocks_duplicate(self) -> Self {
let block = self
let block_contents = self
.harness
.make_block(
self.harness.get_current_state(),
self.harness.get_current_slot(),
)
.await
.0;
.0
.into();
assert!(self.client.post_beacon_blocks(&block).await.is_ok());
assert!(self
.client
.post_beacon_blocks(&block_contents)
.await
.is_ok());
let blinded_block = block.clone_as_blinded();
let blinded_block_contents = block_contents.clone_as_blinded();
// Test all the POST methods in sequence, they should all behave the same.
let responses = vec![
self.client.post_beacon_blocks(&block).await.unwrap_err(),
self.client
.post_beacon_blocks_v2(&block, None)
.post_beacon_blocks(&block_contents)
.await
.unwrap_err(),
self.client
.post_beacon_blocks_ssz(&block)
.post_beacon_blocks_v2(&block_contents, None)
.await
.unwrap_err(),
self.client
.post_beacon_blocks_v2_ssz(&block, None)
.post_beacon_blocks_ssz(&block_contents)
.await
.unwrap_err(),
self.client
.post_beacon_blinded_blocks(&blinded_block)
.post_beacon_blocks_v2_ssz(&block_contents, None)
.await
.unwrap_err(),
self.client
.post_beacon_blinded_blocks_v2(&blinded_block, None)
.post_beacon_blinded_blocks(&blinded_block_contents)
.await
.unwrap_err(),
self.client
.post_beacon_blinded_blocks_ssz(&blinded_block)
.post_beacon_blinded_blocks_v2(&blinded_block_contents, None)
.await
.unwrap_err(),
self.client
.post_beacon_blinded_blocks_v2_ssz(&blinded_block, None)
.post_beacon_blinded_blocks_ssz(&blinded_block_contents)
.await
.unwrap_err(),
self.client
.post_beacon_blinded_blocks_v2_ssz(&blinded_block_contents, None)
.await
.unwrap_err(),
];
@@ -1798,9 +1818,9 @@ impl ApiTester {
pub async fn test_get_config_spec(self) -> Self {
let result = self
.client
.get_config_spec::<ConfigAndPresetCapella>()
.get_config_spec::<ConfigAndPresetDeneb>()
.await
.map(|res| ConfigAndPreset::Capella(res.data))
.map(|res| ConfigAndPreset::Deneb(res.data))
.unwrap();
let expected = ConfigAndPreset::from_chain_spec::<E>(&self.chain.spec, None);
@@ -2499,11 +2519,18 @@ impl ApiTester {
.get_validator_blocks::<E, FullPayload<E>>(slot, &randao_reveal, None)
.await
.unwrap()
.data;
.data
.deconstruct()
.0;
let signed_block = block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
let signed_block_contents =
SignedBlockContents::try_from(signed_block.clone()).unwrap();
self.client.post_beacon_blocks(&signed_block).await.unwrap();
self.client
.post_beacon_blocks(&signed_block_contents)
.await
.unwrap();
assert_eq!(self.chain.head_beacon_block().as_ref(), &signed_block);
@@ -2558,18 +2585,22 @@ impl ApiTester {
.unwrap()
.expect("block bytes");
let block =
BeaconBlock::<E, FullPayload<E>>::from_ssz_bytes(&block_bytes, &self.chain.spec)
.expect("block bytes can be decoded");
let block_contents =
BlockContents::<E, FullPayload<E>>::from_ssz_bytes(&block_bytes, &self.chain.spec)
.expect("block contents bytes can be decoded");
let signed_block = block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
let signed_block_contents =
block_contents.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
self.client
.post_beacon_blocks_ssz(&signed_block)
.post_beacon_blocks_ssz(&signed_block_contents)
.await
.unwrap();
assert_eq!(self.chain.head_beacon_block().as_ref(), &signed_block);
assert_eq!(
self.chain.head_beacon_block().as_ref(),
signed_block_contents.signed_block()
);
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
}
@@ -2591,7 +2622,9 @@ impl ApiTester {
)
.await
.unwrap()
.data;
.data
.deconstruct()
.0;
assert_eq!(block.slot(), slot);
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
}
@@ -2705,14 +2738,16 @@ impl ApiTester {
.unwrap()
.data;
let signed_block = block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
let signed_block_contents =
block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
self.client
.post_beacon_blinded_blocks(&signed_block)
.post_beacon_blinded_blocks(&signed_block_contents)
.await
.unwrap();
// This converts the generic `Payload` to a concrete type for comparison.
let signed_block = signed_block_contents.deconstruct().0;
let head_block = SignedBeaconBlock::from(signed_block.clone());
assert_eq!(head_block, signed_block);
@@ -2758,24 +2793,29 @@ impl ApiTester {
sk.sign(message).into()
};
let block_bytes = self
let block_contents_bytes = self
.client
.get_validator_blinded_blocks_ssz::<E, Payload>(slot, &randao_reveal, None)
.await
.unwrap()
.expect("block bytes");
let block = BeaconBlock::<E, Payload>::from_ssz_bytes(&block_bytes, &self.chain.spec)
.expect("block bytes can be decoded");
let block_contents = BlockContents::<E, Payload>::from_ssz_bytes(
&block_contents_bytes,
&self.chain.spec,
)
.expect("block contents bytes can be decoded");
let signed_block = block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
let signed_block_contents =
block_contents.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
self.client
.post_beacon_blinded_blocks_ssz(&signed_block)
.post_beacon_blinded_blocks_ssz(&signed_block_contents)
.await
.unwrap();
// This converts the generic `Payload` to a concrete type for comparison.
let signed_block = signed_block_contents.deconstruct().0;
let head_block = SignedBeaconBlock::from(signed_block.clone());
assert_eq!(head_block, signed_block);
@@ -2789,7 +2829,7 @@ impl ApiTester {
for _ in 0..E::slots_per_epoch() {
let slot = self.chain.slot().unwrap();
let block = self
let block_contents = self
.client
.get_validator_blinded_blocks_modular::<E, Payload>(
slot,
@@ -2800,7 +2840,7 @@ impl ApiTester {
.await
.unwrap()
.data;
assert_eq!(block.slot(), slot);
assert_eq!(block_contents.block().slot(), slot);
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
}
@@ -3336,6 +3376,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3376,6 +3417,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3418,6 +3460,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3466,6 +3509,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3513,6 +3557,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3559,6 +3604,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3604,6 +3650,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3636,6 +3683,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3673,6 +3721,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3716,6 +3765,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3745,6 +3795,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3794,6 +3845,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3833,6 +3885,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3876,6 +3929,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3916,6 +3970,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3952,6 +4007,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -3988,6 +4044,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -4024,6 +4081,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -4050,19 +4108,6 @@ impl ApiTester {
)));
let slot = self.chain.slot().unwrap();
let propose_state = self
.harness
.chain
.state_at_slot(slot, StateSkipConfig::WithoutStateRoots)
.unwrap();
let withdrawals = get_expected_withdrawals(&propose_state, &self.chain.spec).unwrap();
let withdrawals_root = withdrawals.tree_hash_root();
// Set withdrawals root for builder
self.mock_builder
.as_ref()
.unwrap()
.add_operation(Operation::WithdrawalsRoot(withdrawals_root));
let epoch = self.chain.epoch().unwrap();
let (_, randao_reveal) = self.get_test_randao(slot, epoch).await;
@@ -4072,6 +4117,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -4088,6 +4134,42 @@ impl ApiTester {
self
}
pub async fn test_builder_works_post_deneb(self) -> Self {
// Ensure builder payload is chosen
self.mock_builder
.as_ref()
.unwrap()
.add_operation(Operation::Value(Uint256::from(
DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI + 1,
)));
let slot = self.chain.slot().unwrap();
let epoch = self.chain.epoch().unwrap();
let (_, randao_reveal) = self.get_test_randao(slot, epoch).await;
let block_contents = self
.client
.get_validator_blinded_blocks::<E, BlindedPayload<E>>(slot, &randao_reveal, None)
.await
.unwrap()
.data;
let (block, maybe_sidecars) = block_contents.deconstruct();
// Response should contain blob sidecars
assert!(maybe_sidecars.is_some());
// The builder's payload should've been chosen, so this cache should not be populated
let payload: BlindedPayload<E> = block.body().execution_payload().unwrap().into();
assert!(self
.chain
.execution_layer
.as_ref()
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_none());
self
}
pub async fn test_lighthouse_rejects_invalid_withdrawals_root(self) -> Self {
// Ensure builder payload *would be* chosen
self.mock_builder
@@ -4112,6 +4194,7 @@ impl ApiTester {
.await
.unwrap()
.data
.block()
.body()
.execution_payload()
.unwrap()
@@ -4367,12 +4450,12 @@ impl ApiTester {
// Submit the next block, which is on an epoch boundary, so this will produce a finalized
// checkpoint event, head event, and block event
let block_root = self.next_block.canonical_root();
let block_root = self.next_block.signed_block().canonical_root();
// current_duty_dependent_root = block root because this is the first slot of the epoch
let current_duty_dependent_root = self.chain.head_beacon_block_root();
let current_slot = self.chain.slot().unwrap();
let next_slot = self.next_block.slot();
let next_slot = self.next_block.signed_block().slot();
let finalization_distance = E::slots_per_epoch() * 2;
let expected_block = EventKind::Block(SseBlock {
@@ -4384,7 +4467,7 @@ impl ApiTester {
let expected_head = EventKind::Head(SseHead {
block: block_root,
slot: next_slot,
state: self.next_block.state_root(),
state: self.next_block.signed_block().state_root(),
current_duty_dependent_root,
previous_duty_dependent_root: self
.chain
@@ -4433,13 +4516,17 @@ impl ApiTester {
.unwrap();
let expected_reorg = EventKind::ChainReorg(SseChainReorg {
slot: self.reorg_block.slot(),
slot: self.reorg_block.signed_block().slot(),
depth: 1,
old_head_block: self.next_block.canonical_root(),
old_head_state: self.next_block.state_root(),
new_head_block: self.reorg_block.canonical_root(),
new_head_state: self.reorg_block.state_root(),
epoch: self.next_block.slot().epoch(E::slots_per_epoch()),
old_head_block: self.next_block.signed_block().canonical_root(),
old_head_state: self.next_block.signed_block().state_root(),
new_head_block: self.reorg_block.signed_block().canonical_root(),
new_head_state: self.reorg_block.signed_block().state_root(),
epoch: self
.next_block
.signed_block()
.slot()
.epoch(E::slots_per_epoch()),
execution_optimistic: false,
});
@@ -4569,8 +4656,8 @@ impl ApiTester {
.await
.unwrap();
let block_root = self.next_block.canonical_root();
let next_slot = self.next_block.slot();
let block_root = self.next_block.signed_block().canonical_root();
let next_slot = self.next_block.signed_block().slot();
let expected_block = EventKind::Block(SseBlock {
block: block_root,
@@ -4581,7 +4668,7 @@ impl ApiTester {
let expected_head = EventKind::Head(SseHead {
block: block_root,
slot: next_slot,
state: self.next_block.state_root(),
state: self.next_block.signed_block().state_root(),
current_duty_dependent_root: self.chain.genesis_block_root,
previous_duty_dependent_root: self.chain.genesis_block_root,
epoch_transition: false,
@@ -5284,6 +5371,26 @@ async fn builder_works_post_capella() {
.await;
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn builder_works_post_deneb() {
let mut config = ApiTesterConfig {
builder_threshold: Some(0),
retain_historic_states: false,
spec: E::default_spec(),
};
config.spec.altair_fork_epoch = Some(Epoch::new(0));
config.spec.bellatrix_fork_epoch = Some(Epoch::new(0));
config.spec.capella_fork_epoch = Some(Epoch::new(0));
config.spec.deneb_fork_epoch = Some(Epoch::new(0));
ApiTester::new_from_config(config)
.await
.test_post_validator_register_validator()
.await
.test_builder_works_post_deneb()
.await;
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn post_validator_liveness_epoch() {
ApiTester::new()