Reduce size of futures in HTTP API to prevent stack overflows (#5104)
* Box::pin a few big futures * Arc the blocks early in publication * Fix more tests
This commit is contained in:
parent
02d1f36090
commit
a403138ed0
@ -722,7 +722,7 @@ impl<T: BeaconChainTypes> IntoGossipVerifiedBlockContents<T> for PublishBlockReq
|
|||||||
Ok::<_, BlockContentsError<T::EthSpec>>(gossip_verified_blobs)
|
Ok::<_, BlockContentsError<T::EthSpec>>(gossip_verified_blobs)
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
let gossip_verified_block = GossipVerifiedBlock::new(Arc::new(block), chain)?;
|
let gossip_verified_block = GossipVerifiedBlock::new(block, chain)?;
|
||||||
|
|
||||||
Ok((gossip_verified_block, gossip_verified_blobs))
|
Ok((gossip_verified_block, gossip_verified_blobs))
|
||||||
}
|
}
|
||||||
|
@ -952,7 +952,7 @@ mod test {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let availability_pending_block = AvailabilityPendingExecutedBlock {
|
let availability_pending_block = AvailabilityPendingExecutedBlock {
|
||||||
block: Arc::new(block),
|
block,
|
||||||
import_data,
|
import_data,
|
||||||
payload_verification_outcome,
|
payload_verification_outcome,
|
||||||
};
|
};
|
||||||
|
@ -822,7 +822,7 @@ where
|
|||||||
slot: Slot,
|
slot: Slot,
|
||||||
) -> (SignedBlindedBeaconBlock<E>, BeaconState<E>) {
|
) -> (SignedBlindedBeaconBlock<E>, BeaconState<E>) {
|
||||||
let (unblinded, new_state) = self.make_block(state, slot).await;
|
let (unblinded, new_state) = self.make_block(state, slot).await;
|
||||||
(unblinded.0.into(), new_state)
|
((*unblinded.0).clone().into(), new_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a newly created block, signed by the proposer for the given slot.
|
/// Returns a newly created block, signed by the proposer for the given slot.
|
||||||
@ -866,14 +866,14 @@ where
|
|||||||
panic!("Should always be a full payload response");
|
panic!("Should always be a full payload response");
|
||||||
};
|
};
|
||||||
|
|
||||||
let signed_block = block_response.block.sign(
|
let signed_block = Arc::new(block_response.block.sign(
|
||||||
&self.validator_keypairs[proposer_index].sk,
|
&self.validator_keypairs[proposer_index].sk,
|
||||||
&block_response.state.fork(),
|
&block_response.state.fork(),
|
||||||
block_response.state.genesis_validators_root(),
|
block_response.state.genesis_validators_root(),
|
||||||
&self.spec,
|
&self.spec,
|
||||||
);
|
));
|
||||||
|
|
||||||
let block_contents: SignedBlockContentsTuple<E> = match &signed_block {
|
let block_contents: SignedBlockContentsTuple<E> = match *signed_block {
|
||||||
SignedBeaconBlock::Base(_)
|
SignedBeaconBlock::Base(_)
|
||||||
| SignedBeaconBlock::Altair(_)
|
| SignedBeaconBlock::Altair(_)
|
||||||
| SignedBeaconBlock::Merge(_)
|
| SignedBeaconBlock::Merge(_)
|
||||||
@ -928,14 +928,14 @@ where
|
|||||||
panic!("Should always be a full payload response");
|
panic!("Should always be a full payload response");
|
||||||
};
|
};
|
||||||
|
|
||||||
let signed_block = block_response.block.sign(
|
let signed_block = Arc::new(block_response.block.sign(
|
||||||
&self.validator_keypairs[proposer_index].sk,
|
&self.validator_keypairs[proposer_index].sk,
|
||||||
&block_response.state.fork(),
|
&block_response.state.fork(),
|
||||||
block_response.state.genesis_validators_root(),
|
block_response.state.genesis_validators_root(),
|
||||||
&self.spec,
|
&self.spec,
|
||||||
);
|
));
|
||||||
|
|
||||||
let block_contents: SignedBlockContentsTuple<E> = match &signed_block {
|
let block_contents: SignedBlockContentsTuple<E> = match *signed_block {
|
||||||
SignedBeaconBlock::Base(_)
|
SignedBeaconBlock::Base(_)
|
||||||
| SignedBeaconBlock::Altair(_)
|
| SignedBeaconBlock::Altair(_)
|
||||||
| SignedBeaconBlock::Merge(_)
|
| SignedBeaconBlock::Merge(_)
|
||||||
@ -1742,7 +1742,7 @@ where
|
|||||||
|
|
||||||
let ((block, blobs), state) = self.make_block_return_pre_state(state, slot).await;
|
let ((block, blobs), state) = self.make_block_return_pre_state(state, slot).await;
|
||||||
|
|
||||||
let (mut block, _) = block.deconstruct();
|
let (mut block, _) = (*block).clone().deconstruct();
|
||||||
|
|
||||||
block_modifier(&mut block);
|
block_modifier(&mut block);
|
||||||
|
|
||||||
@ -1754,7 +1754,7 @@ where
|
|||||||
state.genesis_validators_root(),
|
state.genesis_validators_root(),
|
||||||
&self.spec,
|
&self.spec,
|
||||||
);
|
);
|
||||||
((signed_block, blobs), state)
|
((Arc::new(signed_block), blobs), state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn make_blob_with_modifier(
|
pub async fn make_blob_with_modifier(
|
||||||
@ -1768,7 +1768,7 @@ where
|
|||||||
|
|
||||||
let ((block, mut blobs), state) = self.make_block_return_pre_state(state, slot).await;
|
let ((block, mut blobs), state) = self.make_block_return_pre_state(state, slot).await;
|
||||||
|
|
||||||
let (block, _) = block.deconstruct();
|
let (block, _) = (*block).clone().deconstruct();
|
||||||
|
|
||||||
blob_modifier(&mut blobs.as_mut().unwrap().1);
|
blob_modifier(&mut blobs.as_mut().unwrap().1);
|
||||||
|
|
||||||
@ -1780,7 +1780,7 @@ where
|
|||||||
state.genesis_validators_root(),
|
state.genesis_validators_root(),
|
||||||
&self.spec,
|
&self.spec,
|
||||||
);
|
);
|
||||||
((signed_block, blobs), state)
|
((Arc::new(signed_block), blobs), state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_deposits<'a>(
|
pub fn make_deposits<'a>(
|
||||||
@ -1873,7 +1873,7 @@ where
|
|||||||
.chain
|
.chain
|
||||||
.process_block(
|
.process_block(
|
||||||
block_root,
|
block_root,
|
||||||
RpcBlock::new(Some(block_root), Arc::new(block), sidecars).unwrap(),
|
RpcBlock::new(Some(block_root), block, sidecars).unwrap(),
|
||||||
NotifyExecutionLayer::Yes,
|
NotifyExecutionLayer::Yes,
|
||||||
|| Ok(()),
|
|| Ok(()),
|
||||||
)
|
)
|
||||||
@ -1899,7 +1899,7 @@ where
|
|||||||
.chain
|
.chain
|
||||||
.process_block(
|
.process_block(
|
||||||
block_root,
|
block_root,
|
||||||
RpcBlock::new(Some(block_root), Arc::new(block), sidecars).unwrap(),
|
RpcBlock::new(Some(block_root), block, sidecars).unwrap(),
|
||||||
NotifyExecutionLayer::Yes,
|
NotifyExecutionLayer::Yes,
|
||||||
|| Ok(()),
|
|| Ok(()),
|
||||||
)
|
)
|
||||||
|
@ -1142,11 +1142,7 @@ async fn verify_block_for_gossip_slashing_detection() {
|
|||||||
let ((block1, blobs1), _) = harness.make_block(state.clone(), Slot::new(1)).await;
|
let ((block1, blobs1), _) = harness.make_block(state.clone(), Slot::new(1)).await;
|
||||||
let ((block2, _blobs2), _) = harness.make_block(state, Slot::new(1)).await;
|
let ((block2, _blobs2), _) = harness.make_block(state, Slot::new(1)).await;
|
||||||
|
|
||||||
let verified_block = harness
|
let verified_block = harness.chain.verify_block_for_gossip(block1).await.unwrap();
|
||||||
.chain
|
|
||||||
.verify_block_for_gossip(Arc::new(block1))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if let Some((kzg_proofs, blobs)) = blobs1 {
|
if let Some((kzg_proofs, blobs)) = blobs1 {
|
||||||
let sidecars =
|
let sidecars =
|
||||||
@ -1174,12 +1170,7 @@ async fn verify_block_for_gossip_slashing_detection() {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
unwrap_err(
|
unwrap_err(harness.chain.verify_block_for_gossip(block2).await);
|
||||||
harness
|
|
||||||
.chain
|
|
||||||
.verify_block_for_gossip(Arc::new(block2))
|
|
||||||
.await,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Slasher should have been handed the two conflicting blocks and crafted a slashing.
|
// Slasher should have been handed the two conflicting blocks and crafted a slashing.
|
||||||
slasher.process_queued(Epoch::new(0)).unwrap();
|
slasher.process_queued(Epoch::new(0)).unwrap();
|
||||||
@ -1198,11 +1189,7 @@ async fn verify_block_for_gossip_doppelganger_detection() {
|
|||||||
let state = harness.get_current_state();
|
let state = harness.get_current_state();
|
||||||
let ((block, _), _) = harness.make_block(state.clone(), Slot::new(1)).await;
|
let ((block, _), _) = harness.make_block(state.clone(), Slot::new(1)).await;
|
||||||
|
|
||||||
let verified_block = harness
|
let verified_block = harness.chain.verify_block_for_gossip(block).await.unwrap();
|
||||||
.chain
|
|
||||||
.verify_block_for_gossip(Arc::new(block))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let attestations = verified_block.block.message().body().attestations().clone();
|
let attestations = verified_block.block.message().body().attestations().clone();
|
||||||
harness
|
harness
|
||||||
.chain
|
.chain
|
||||||
@ -1564,7 +1551,6 @@ async fn import_duplicate_block_unrealized_justification() {
|
|||||||
let slot = harness.get_current_slot();
|
let slot = harness.get_current_slot();
|
||||||
let (block_contents, _) = harness.make_block(state.clone(), slot).await;
|
let (block_contents, _) = harness.make_block(state.clone(), slot).await;
|
||||||
let (block, _) = block_contents;
|
let (block, _) = block_contents;
|
||||||
let block = Arc::new(block);
|
|
||||||
let block_root = block.canonical_root();
|
let block_root = block.canonical_root();
|
||||||
|
|
||||||
// Create two verified variants of the block, representing the same block being processed in
|
// Create two verified variants of the block, representing the same block being processed in
|
||||||
|
@ -319,7 +319,7 @@ impl InvalidPayloadRig {
|
|||||||
.get_full_block(&block_root)
|
.get_full_block(&block_root)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
block,
|
*block,
|
||||||
"block from db must match block imported"
|
"block from db must match block imported"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -700,7 +700,7 @@ async fn invalidates_all_descendants() {
|
|||||||
.chain
|
.chain
|
||||||
.process_block(
|
.process_block(
|
||||||
fork_block.canonical_root(),
|
fork_block.canonical_root(),
|
||||||
Arc::new(fork_block),
|
fork_block,
|
||||||
NotifyExecutionLayer::Yes,
|
NotifyExecutionLayer::Yes,
|
||||||
|| Ok(()),
|
|| Ok(()),
|
||||||
)
|
)
|
||||||
@ -800,7 +800,7 @@ async fn switches_heads() {
|
|||||||
.chain
|
.chain
|
||||||
.process_block(
|
.process_block(
|
||||||
fork_block.canonical_root(),
|
fork_block.canonical_root(),
|
||||||
Arc::new(fork_block),
|
fork_block,
|
||||||
NotifyExecutionLayer::Yes,
|
NotifyExecutionLayer::Yes,
|
||||||
|| Ok(()),
|
|| Ok(()),
|
||||||
)
|
)
|
||||||
@ -1044,8 +1044,7 @@ async fn invalid_parent() {
|
|||||||
// Produce another block atop the parent, but don't import yet.
|
// Produce another block atop the parent, but don't import yet.
|
||||||
let slot = parent_block.slot() + 1;
|
let slot = parent_block.slot() + 1;
|
||||||
rig.harness.set_current_slot(slot);
|
rig.harness.set_current_slot(slot);
|
||||||
let (block_tuple, state) = rig.harness.make_block(parent_state, slot).await;
|
let ((block, _), state) = rig.harness.make_block(parent_state, slot).await;
|
||||||
let block = Arc::new(block_tuple.0);
|
|
||||||
let block_root = block.canonical_root();
|
let block_root = block.canonical_root();
|
||||||
assert_eq!(block.parent_root(), parent_root);
|
assert_eq!(block.parent_root(), parent_root);
|
||||||
|
|
||||||
@ -1865,7 +1864,7 @@ impl InvalidHeadSetup {
|
|||||||
.state_at_slot(slot - 1, StateSkipConfig::WithStateRoots)
|
.state_at_slot(slot - 1, StateSkipConfig::WithStateRoots)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (fork_block_tuple, _) = rig.harness.make_block(parent_state, slot).await;
|
let (fork_block_tuple, _) = rig.harness.make_block(parent_state, slot).await;
|
||||||
opt_fork_block = Some(Arc::new(fork_block_tuple.0));
|
opt_fork_block = Some(fork_block_tuple.0);
|
||||||
} else {
|
} else {
|
||||||
// Skipped slot.
|
// Skipped slot.
|
||||||
};
|
};
|
||||||
|
@ -2268,17 +2268,17 @@ async fn garbage_collect_temp_states_from_failed_block() {
|
|||||||
let block_slot = Slot::new(2 * slots_per_epoch);
|
let block_slot = Slot::new(2 * slots_per_epoch);
|
||||||
let ((signed_block, _), state) = harness.make_block(genesis_state, block_slot).await;
|
let ((signed_block, _), state) = harness.make_block(genesis_state, block_slot).await;
|
||||||
|
|
||||||
let (mut block, _) = signed_block.deconstruct();
|
let (mut block, _) = (*signed_block).clone().deconstruct();
|
||||||
|
|
||||||
// Mutate the block to make it invalid, and re-sign it.
|
// Mutate the block to make it invalid, and re-sign it.
|
||||||
*block.state_root_mut() = Hash256::repeat_byte(0xff);
|
*block.state_root_mut() = Hash256::repeat_byte(0xff);
|
||||||
let proposer_index = block.proposer_index() as usize;
|
let proposer_index = block.proposer_index() as usize;
|
||||||
let block = block.sign(
|
let block = Arc::new(block.sign(
|
||||||
&harness.validator_keypairs[proposer_index].sk,
|
&harness.validator_keypairs[proposer_index].sk,
|
||||||
&state.fork(),
|
&state.fork(),
|
||||||
state.genesis_validators_root(),
|
state.genesis_validators_root(),
|
||||||
&harness.spec,
|
&harness.spec,
|
||||||
);
|
));
|
||||||
|
|
||||||
// The block should be rejected, but should store a bunch of temporary states.
|
// The block should be rejected, but should store a bunch of temporary states.
|
||||||
harness.set_current_slot(block_slot);
|
harness.set_current_slot(block_slot);
|
||||||
@ -2677,7 +2677,7 @@ async fn process_blocks_and_attestations_for_unaligned_checkpoint() {
|
|||||||
.chain
|
.chain
|
||||||
.process_block(
|
.process_block(
|
||||||
invalid_fork_block.canonical_root(),
|
invalid_fork_block.canonical_root(),
|
||||||
Arc::new(invalid_fork_block.clone()),
|
invalid_fork_block.clone(),
|
||||||
NotifyExecutionLayer::Yes,
|
NotifyExecutionLayer::Yes,
|
||||||
|| Ok(()),
|
|| Ok(()),
|
||||||
)
|
)
|
||||||
@ -2690,7 +2690,7 @@ async fn process_blocks_and_attestations_for_unaligned_checkpoint() {
|
|||||||
.chain
|
.chain
|
||||||
.process_block(
|
.process_block(
|
||||||
valid_fork_block.canonical_root(),
|
valid_fork_block.canonical_root(),
|
||||||
Arc::new(valid_fork_block.clone()),
|
valid_fork_block.clone(),
|
||||||
NotifyExecutionLayer::Yes,
|
NotifyExecutionLayer::Yes,
|
||||||
|| Ok(()),
|
|| Ok(()),
|
||||||
)
|
)
|
||||||
|
@ -1410,7 +1410,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and(network_tx_filter.clone())
|
.and(network_tx_filter.clone())
|
||||||
.and(log_filter.clone())
|
.and(log_filter.clone())
|
||||||
.then(
|
.then(
|
||||||
move |block_contents: SignedBlindedBeaconBlock<T::EthSpec>,
|
move |block_contents: Arc<SignedBlindedBeaconBlock<T::EthSpec>>,
|
||||||
task_spawner: TaskSpawner<T::EthSpec>,
|
task_spawner: TaskSpawner<T::EthSpec>,
|
||||||
chain: Arc<BeaconChain<T>>,
|
chain: Arc<BeaconChain<T>>,
|
||||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||||
@ -1450,6 +1450,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
&block_bytes,
|
&block_bytes,
|
||||||
&chain.spec,
|
&chain.spec,
|
||||||
)
|
)
|
||||||
|
.map(Arc::new)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
warp_utils::reject::custom_bad_request(format!("invalid SSZ: {e:?}"))
|
warp_utils::reject::custom_bad_request(format!("invalid SSZ: {e:?}"))
|
||||||
})?;
|
})?;
|
||||||
@ -1478,7 +1479,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and(log_filter.clone())
|
.and(log_filter.clone())
|
||||||
.then(
|
.then(
|
||||||
move |validation_level: api_types::BroadcastValidationQuery,
|
move |validation_level: api_types::BroadcastValidationQuery,
|
||||||
blinded_block: SignedBlindedBeaconBlock<T::EthSpec>,
|
blinded_block: Arc<SignedBlindedBeaconBlock<T::EthSpec>>,
|
||||||
task_spawner: TaskSpawner<T::EthSpec>,
|
task_spawner: TaskSpawner<T::EthSpec>,
|
||||||
chain: Arc<BeaconChain<T>>,
|
chain: Arc<BeaconChain<T>>,
|
||||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||||
@ -1519,6 +1520,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
&block_bytes,
|
&block_bytes,
|
||||||
&chain.spec,
|
&chain.spec,
|
||||||
)
|
)
|
||||||
|
.map(Arc::new)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
warp_utils::reject::custom_bad_request(format!("invalid SSZ: {e:?}"))
|
warp_utils::reject::custom_bad_request(format!("invalid SSZ: {e:?}"))
|
||||||
})?;
|
})?;
|
||||||
|
@ -194,7 +194,7 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
|||||||
|
|
||||||
if let Some(gossip_verified_blobs) = gossip_verified_blobs {
|
if let Some(gossip_verified_blobs) = gossip_verified_blobs {
|
||||||
for blob in gossip_verified_blobs {
|
for blob in gossip_verified_blobs {
|
||||||
if let Err(e) = chain.process_gossip_blob(blob).await {
|
if let Err(e) = Box::pin(chain.process_gossip_blob(blob)).await {
|
||||||
let msg = format!("Invalid blob: {e}");
|
let msg = format!("Invalid blob: {e}");
|
||||||
return if let BroadcastValidation::Gossip = validation_level {
|
return if let BroadcastValidation::Gossip = validation_level {
|
||||||
Err(warp_utils::reject::broadcast_without_import(msg))
|
Err(warp_utils::reject::broadcast_without_import(msg))
|
||||||
@ -210,14 +210,13 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match chain
|
match Box::pin(chain.process_block(
|
||||||
.process_block(
|
block_root,
|
||||||
block_root,
|
gossip_verified_block,
|
||||||
gossip_verified_block,
|
NotifyExecutionLayer::Yes,
|
||||||
NotifyExecutionLayer::Yes,
|
publish_fn,
|
||||||
publish_fn,
|
))
|
||||||
)
|
.await
|
||||||
.await
|
|
||||||
{
|
{
|
||||||
Ok(AvailabilityProcessingStatus::Imported(root)) => {
|
Ok(AvailabilityProcessingStatus::Imported(root)) => {
|
||||||
info!(
|
info!(
|
||||||
@ -291,7 +290,7 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
|||||||
/// Handles a request from the HTTP API for blinded blocks. This converts blinded blocks into full
|
/// Handles a request from the HTTP API for blinded blocks. This converts blinded blocks into full
|
||||||
/// blocks before publishing.
|
/// blocks before publishing.
|
||||||
pub async fn publish_blinded_block<T: BeaconChainTypes>(
|
pub async fn publish_blinded_block<T: BeaconChainTypes>(
|
||||||
blinded_block: SignedBlindedBeaconBlock<T::EthSpec>,
|
blinded_block: Arc<SignedBlindedBeaconBlock<T::EthSpec>>,
|
||||||
chain: Arc<BeaconChain<T>>,
|
chain: Arc<BeaconChain<T>>,
|
||||||
network_tx: &UnboundedSender<NetworkMessage<T::EthSpec>>,
|
network_tx: &UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
@ -319,7 +318,7 @@ pub async fn publish_blinded_block<T: BeaconChainTypes>(
|
|||||||
pub async fn reconstruct_block<T: BeaconChainTypes>(
|
pub async fn reconstruct_block<T: BeaconChainTypes>(
|
||||||
chain: Arc<BeaconChain<T>>,
|
chain: Arc<BeaconChain<T>>,
|
||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
block: SignedBlindedBeaconBlock<T::EthSpec>,
|
block: Arc<SignedBlindedBeaconBlock<T::EthSpec>>,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
) -> Result<ProvenancedBlock<T, PublishBlockRequest<T::EthSpec>>, Rejection> {
|
) -> Result<ProvenancedBlock<T, PublishBlockRequest<T::EthSpec>>, Rejection> {
|
||||||
let full_payload_opt = if let Ok(payload_header) = block.message().body().execution_payload() {
|
let full_payload_opt = if let Ok(payload_header) = block.message().body().execution_payload() {
|
||||||
@ -380,6 +379,10 @@ pub async fn reconstruct_block<T: BeaconChainTypes>(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Perf: cloning the block here to unblind it is a little sub-optimal. This is considered an
|
||||||
|
// acceptable tradeoff to avoid passing blocks around on the stack (unarced), which blows up
|
||||||
|
// the size of futures.
|
||||||
|
let block = (*block).clone();
|
||||||
match full_payload_opt {
|
match full_payload_opt {
|
||||||
// A block without a payload is pre-merge and we consider it locally
|
// A block without a payload is pre-merge and we consider it locally
|
||||||
// built.
|
// built.
|
||||||
|
@ -3,7 +3,7 @@ use beacon_chain::{
|
|||||||
GossipVerifiedBlock, IntoGossipVerifiedBlockContents,
|
GossipVerifiedBlock, IntoGossipVerifiedBlockContents,
|
||||||
};
|
};
|
||||||
use eth2::reqwest::StatusCode;
|
use eth2::reqwest::StatusCode;
|
||||||
use eth2::types::{BroadcastValidation, PublishBlockRequest, SignedBeaconBlock};
|
use eth2::types::{BroadcastValidation, PublishBlockRequest};
|
||||||
use http_api::test_utils::InteractiveTester;
|
use http_api::test_utils::InteractiveTester;
|
||||||
use http_api::{publish_blinded_block, publish_block, reconstruct_block, ProvenancedBlock};
|
use http_api::{publish_blinded_block, publish_block, reconstruct_block, ProvenancedBlock};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -63,7 +63,7 @@ pub async fn gossip_invalid() {
|
|||||||
|
|
||||||
tester.harness.advance_slot();
|
tester.harness.advance_slot();
|
||||||
|
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) = tester
|
let ((block, blobs), _) = tester
|
||||||
.harness
|
.harness
|
||||||
.make_block_with_modifier(chain_state_before, slot, |b| {
|
.make_block_with_modifier(chain_state_before, slot, |b| {
|
||||||
*b.state_root_mut() = Hash256::zero();
|
*b.state_root_mut() = Hash256::zero();
|
||||||
@ -115,7 +115,7 @@ pub async fn gossip_partial_pass() {
|
|||||||
|
|
||||||
tester.harness.advance_slot();
|
tester.harness.advance_slot();
|
||||||
|
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) = tester
|
let ((block, blobs), _) = tester
|
||||||
.harness
|
.harness
|
||||||
.make_block_with_modifier(chain_state_before, slot, |b| {
|
.make_block_with_modifier(chain_state_before, slot, |b| {
|
||||||
*b.state_root_mut() = Hash256::random()
|
*b.state_root_mut() = Hash256::random()
|
||||||
@ -161,8 +161,7 @@ pub async fn gossip_full_pass() {
|
|||||||
let slot_b = slot_a + 1;
|
let slot_b = slot_a + 1;
|
||||||
|
|
||||||
let state_a = tester.harness.get_current_state();
|
let state_a = tester.harness.get_current_state();
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) =
|
let ((block, blobs), _) = tester.harness.make_block(state_a, slot_b).await;
|
||||||
tester.harness.make_block(state_a, slot_b).await;
|
|
||||||
|
|
||||||
let response: Result<(), eth2::Error> = tester
|
let response: Result<(), eth2::Error> = tester
|
||||||
.client
|
.client
|
||||||
@ -252,7 +251,7 @@ pub async fn consensus_invalid() {
|
|||||||
|
|
||||||
tester.harness.advance_slot();
|
tester.harness.advance_slot();
|
||||||
|
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) = tester
|
let ((block, blobs), _) = tester
|
||||||
.harness
|
.harness
|
||||||
.make_block_with_modifier(chain_state_before, slot, |b| {
|
.make_block_with_modifier(chain_state_before, slot, |b| {
|
||||||
*b.state_root_mut() = Hash256::zero();
|
*b.state_root_mut() = Hash256::zero();
|
||||||
@ -304,7 +303,7 @@ pub async fn consensus_gossip() {
|
|||||||
let slot_b = slot_a + 1;
|
let slot_b = slot_a + 1;
|
||||||
|
|
||||||
let state_a = tester.harness.get_current_state();
|
let state_a = tester.harness.get_current_state();
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) = tester
|
let ((block, blobs), _) = tester
|
||||||
.harness
|
.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| *b.state_root_mut() = Hash256::zero())
|
||||||
.await;
|
.await;
|
||||||
@ -418,8 +417,7 @@ pub async fn consensus_full_pass() {
|
|||||||
let slot_b = slot_a + 1;
|
let slot_b = slot_a + 1;
|
||||||
|
|
||||||
let state_a = tester.harness.get_current_state();
|
let state_a = tester.harness.get_current_state();
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) =
|
let ((block, blobs), _) = tester.harness.make_block(state_a, slot_b).await;
|
||||||
tester.harness.make_block(state_a, slot_b).await;
|
|
||||||
|
|
||||||
let response: Result<(), eth2::Error> = tester
|
let response: Result<(), eth2::Error> = tester
|
||||||
.client
|
.client
|
||||||
@ -465,7 +463,7 @@ pub async fn equivocation_invalid() {
|
|||||||
|
|
||||||
tester.harness.advance_slot();
|
tester.harness.advance_slot();
|
||||||
|
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) = tester
|
let ((block, blobs), _) = tester
|
||||||
.harness
|
.harness
|
||||||
.make_block_with_modifier(chain_state_before, slot, |b| {
|
.make_block_with_modifier(chain_state_before, slot, |b| {
|
||||||
*b.state_root_mut() = Hash256::zero();
|
*b.state_root_mut() = Hash256::zero();
|
||||||
@ -518,10 +516,9 @@ pub async fn equivocation_consensus_early_equivocation() {
|
|||||||
let slot_b = slot_a + 1;
|
let slot_b = slot_a + 1;
|
||||||
|
|
||||||
let state_a = tester.harness.get_current_state();
|
let state_a = tester.harness.get_current_state();
|
||||||
let ((block_a, blobs_a), state_after_a): ((SignedBeaconBlock<E>, _), _) =
|
let ((block_a, blobs_a), state_after_a) =
|
||||||
tester.harness.make_block(state_a.clone(), slot_b).await;
|
tester.harness.make_block(state_a.clone(), slot_b).await;
|
||||||
let ((block_b, blobs_b), state_after_b): ((SignedBeaconBlock<E>, _), _) =
|
let ((block_b, blobs_b), state_after_b) = tester.harness.make_block(state_a, slot_b).await;
|
||||||
tester.harness.make_block(state_a, slot_b).await;
|
|
||||||
|
|
||||||
/* check for `make_block` curios */
|
/* check for `make_block` curios */
|
||||||
assert_eq!(block_a.state_root(), state_after_a.tree_hash_root());
|
assert_eq!(block_a.state_root(), state_after_a.tree_hash_root());
|
||||||
@ -590,7 +587,7 @@ pub async fn equivocation_gossip() {
|
|||||||
let slot_b = slot_a + 1;
|
let slot_b = slot_a + 1;
|
||||||
|
|
||||||
let state_a = tester.harness.get_current_state();
|
let state_a = tester.harness.get_current_state();
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) = tester
|
let ((block, blobs), _) = tester
|
||||||
.harness
|
.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| *b.state_root_mut() = Hash256::zero())
|
||||||
.await;
|
.await;
|
||||||
@ -645,10 +642,9 @@ pub async fn equivocation_consensus_late_equivocation() {
|
|||||||
let slot_b = slot_a + 1;
|
let slot_b = slot_a + 1;
|
||||||
|
|
||||||
let state_a = tester.harness.get_current_state();
|
let state_a = tester.harness.get_current_state();
|
||||||
let ((block_a, blobs_a), state_after_a): ((SignedBeaconBlock<E>, _), _) =
|
let ((block_a, blobs_a), state_after_a) =
|
||||||
tester.harness.make_block(state_a.clone(), slot_b).await;
|
tester.harness.make_block(state_a.clone(), slot_b).await;
|
||||||
let ((block_b, blobs_b), state_after_b): ((SignedBeaconBlock<E>, _), _) =
|
let ((block_b, blobs_b), state_after_b) = tester.harness.make_block(state_a, slot_b).await;
|
||||||
tester.harness.make_block(state_a, slot_b).await;
|
|
||||||
|
|
||||||
/* check for `make_block` curios */
|
/* check for `make_block` curios */
|
||||||
assert_eq!(block_a.state_root(), state_after_a.tree_hash_root());
|
assert_eq!(block_a.state_root(), state_after_a.tree_hash_root());
|
||||||
@ -716,8 +712,7 @@ pub async fn equivocation_full_pass() {
|
|||||||
let slot_b = slot_a + 1;
|
let slot_b = slot_a + 1;
|
||||||
|
|
||||||
let state_a = tester.harness.get_current_state();
|
let state_a = tester.harness.get_current_state();
|
||||||
let ((block, blobs), _): ((SignedBeaconBlock<E>, _), _) =
|
let ((block, blobs), _) = tester.harness.make_block(state_a, slot_b).await;
|
||||||
tester.harness.make_block(state_a, slot_b).await;
|
|
||||||
|
|
||||||
let response: Result<(), eth2::Error> = tester
|
let response: Result<(), eth2::Error> = tester
|
||||||
.client
|
.client
|
||||||
@ -1269,6 +1264,7 @@ pub async fn blinded_equivocation_consensus_late_equivocation() {
|
|||||||
.make_blinded_block(state_a.clone(), slot_b)
|
.make_blinded_block(state_a.clone(), slot_b)
|
||||||
.await;
|
.await;
|
||||||
let (block_b, state_after_b) = tester.harness.make_blinded_block(state_a, slot_b).await;
|
let (block_b, state_after_b) = tester.harness.make_blinded_block(state_a, slot_b).await;
|
||||||
|
let block_b = Arc::new(block_b);
|
||||||
|
|
||||||
/* check for `make_blinded_block` curios */
|
/* check for `make_blinded_block` curios */
|
||||||
assert_eq!(block_a.state_root(), state_after_a.tree_hash_root());
|
assert_eq!(block_a.state_root(), state_after_a.tree_hash_root());
|
||||||
@ -1278,7 +1274,7 @@ pub async fn blinded_equivocation_consensus_late_equivocation() {
|
|||||||
let unblinded_block_a = reconstruct_block(
|
let unblinded_block_a = reconstruct_block(
|
||||||
tester.harness.chain.clone(),
|
tester.harness.chain.clone(),
|
||||||
block_a.canonical_root(),
|
block_a.canonical_root(),
|
||||||
block_a,
|
Arc::new(block_a),
|
||||||
test_logger.clone(),
|
test_logger.clone(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -1301,15 +1297,11 @@ pub async fn blinded_equivocation_consensus_late_equivocation() {
|
|||||||
ProvenancedBlock::Builder(b, _) => b,
|
ProvenancedBlock::Builder(b, _) => b,
|
||||||
};
|
};
|
||||||
|
|
||||||
let gossip_block_b = GossipVerifiedBlock::new(
|
let gossip_block_b =
|
||||||
Arc::new(inner_block_b.clone().deconstruct().0),
|
GossipVerifiedBlock::new(inner_block_b.clone().deconstruct().0, &tester.harness.chain);
|
||||||
&tester.harness.chain,
|
|
||||||
);
|
|
||||||
assert!(gossip_block_b.is_ok());
|
assert!(gossip_block_b.is_ok());
|
||||||
let gossip_block_a = GossipVerifiedBlock::new(
|
let gossip_block_a =
|
||||||
Arc::new(inner_block_a.clone().deconstruct().0),
|
GossipVerifiedBlock::new(inner_block_a.clone().deconstruct().0, &tester.harness.chain);
|
||||||
&tester.harness.chain,
|
|
||||||
);
|
|
||||||
assert!(gossip_block_a.is_err());
|
assert!(gossip_block_a.is_err());
|
||||||
|
|
||||||
let channel = tokio::sync::mpsc::unbounded_channel();
|
let channel = tokio::sync::mpsc::unbounded_channel();
|
||||||
|
@ -632,7 +632,7 @@ pub async fn proposer_boost_re_org_test(
|
|||||||
panic!("Should not be a blinded block");
|
panic!("Should not be a blinded block");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let block_c = harness.sign_beacon_block(unsigned_block_c, &state_b);
|
let block_c = Arc::new(harness.sign_beacon_block(unsigned_block_c, &state_b));
|
||||||
|
|
||||||
if should_re_org {
|
if should_re_org {
|
||||||
// Block C should build on A.
|
// Block C should build on A.
|
||||||
|
@ -2597,7 +2597,7 @@ impl ApiTester {
|
|||||||
|
|
||||||
let signed_block = block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
|
let signed_block = block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
|
||||||
let signed_block_contents =
|
let signed_block_contents =
|
||||||
PublishBlockRequest::try_from(signed_block.clone()).unwrap();
|
PublishBlockRequest::try_from(Arc::new(signed_block.clone())).unwrap();
|
||||||
|
|
||||||
self.client
|
self.client
|
||||||
.post_beacon_blocks(&signed_block_contents)
|
.post_beacon_blocks(&signed_block_contents)
|
||||||
@ -2670,8 +2670,8 @@ impl ApiTester {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.chain.head_beacon_block().as_ref(),
|
self.chain.head_beacon_block(),
|
||||||
signed_block_contents.signed_block()
|
*signed_block_contents.signed_block()
|
||||||
);
|
);
|
||||||
|
|
||||||
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
||||||
@ -2763,8 +2763,8 @@ impl ApiTester {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.chain.head_beacon_block().as_ref(),
|
self.chain.head_beacon_block(),
|
||||||
signed_block_contents.signed_block()
|
*signed_block_contents.signed_block()
|
||||||
);
|
);
|
||||||
|
|
||||||
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
||||||
@ -2994,7 +2994,7 @@ impl ApiTester {
|
|||||||
.data;
|
.data;
|
||||||
|
|
||||||
let signed_block = signed_block_contents.signed_block();
|
let signed_block = signed_block_contents.signed_block();
|
||||||
assert_eq!(&head_block, signed_block);
|
assert_eq!(head_block, **signed_block);
|
||||||
|
|
||||||
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ impl TestRig {
|
|||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
chain,
|
chain,
|
||||||
next_block: Arc::new(block),
|
next_block: block,
|
||||||
next_blobs: blob_sidecars,
|
next_blobs: blob_sidecars,
|
||||||
attestations,
|
attestations,
|
||||||
next_block_attestations,
|
next_block_attestations,
|
||||||
|
@ -15,6 +15,7 @@ use ssz_derive::{Decode, Encode};
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::str::{from_utf8, FromStr};
|
use std::str::{from_utf8, FromStr};
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use types::beacon_block_body::KzgCommitments;
|
use types::beacon_block_body::KzgCommitments;
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
@ -1479,10 +1480,10 @@ mod tests {
|
|||||||
type E = MainnetEthSpec;
|
type E = MainnetEthSpec;
|
||||||
let spec = ForkName::Capella.make_genesis_spec(E::default_spec());
|
let spec = ForkName::Capella.make_genesis_spec(E::default_spec());
|
||||||
|
|
||||||
let block: PublishBlockRequest<E> = SignedBeaconBlock::from_block(
|
let block: PublishBlockRequest<E> = Arc::new(SignedBeaconBlock::from_block(
|
||||||
BeaconBlock::<E>::Capella(BeaconBlockCapella::empty(&spec)),
|
BeaconBlock::<E>::Capella(BeaconBlockCapella::empty(&spec)),
|
||||||
Signature::empty(),
|
Signature::empty(),
|
||||||
)
|
))
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("should convert into signed block contents");
|
.expect("should convert into signed block contents");
|
||||||
|
|
||||||
@ -1503,7 +1504,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let blobs = BlobsList::<E>::from(vec![Blob::<E>::default()]);
|
let blobs = BlobsList::<E>::from(vec![Blob::<E>::default()]);
|
||||||
let kzg_proofs = KzgProofs::<E>::from(vec![KzgProof::empty()]);
|
let kzg_proofs = KzgProofs::<E>::from(vec![KzgProof::empty()]);
|
||||||
let signed_block_contents = PublishBlockRequest::new(block, Some((kzg_proofs, blobs)));
|
let signed_block_contents =
|
||||||
|
PublishBlockRequest::new(Arc::new(block), Some((kzg_proofs, blobs)));
|
||||||
|
|
||||||
let decoded: PublishBlockRequest<E> = PublishBlockRequest::from_ssz_bytes(
|
let decoded: PublishBlockRequest<E> = PublishBlockRequest::from_ssz_bytes(
|
||||||
&signed_block_contents.as_ssz_bytes(),
|
&signed_block_contents.as_ssz_bytes(),
|
||||||
@ -1644,7 +1646,7 @@ impl<T: EthSpec> FullBlockContents<T> {
|
|||||||
) -> PublishBlockRequest<T> {
|
) -> PublishBlockRequest<T> {
|
||||||
let (block, maybe_blobs) = self.deconstruct();
|
let (block, maybe_blobs) = self.deconstruct();
|
||||||
let signed_block = block.sign(secret_key, fork, genesis_validators_root, spec);
|
let signed_block = block.sign(secret_key, fork, genesis_validators_root, spec);
|
||||||
PublishBlockRequest::new(signed_block, maybe_blobs)
|
PublishBlockRequest::new(Arc::new(signed_block), maybe_blobs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1675,7 +1677,10 @@ impl<T: EthSpec> Into<BeaconBlock<T>> for FullBlockContents<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SignedBlockContentsTuple<T> = (SignedBeaconBlock<T>, Option<(KzgProofs<T>, BlobsList<T>)>);
|
pub type SignedBlockContentsTuple<T> = (
|
||||||
|
Arc<SignedBeaconBlock<T>>,
|
||||||
|
Option<(KzgProofs<T>, BlobsList<T>)>,
|
||||||
|
);
|
||||||
|
|
||||||
fn parse_required_header<T>(
|
fn parse_required_header<T>(
|
||||||
headers: &HeaderMap,
|
headers: &HeaderMap,
|
||||||
@ -1730,12 +1735,12 @@ impl TryFrom<&HeaderMap> for ProduceBlockV3Metadata {
|
|||||||
#[ssz(enum_behaviour = "transparent")]
|
#[ssz(enum_behaviour = "transparent")]
|
||||||
pub enum PublishBlockRequest<T: EthSpec> {
|
pub enum PublishBlockRequest<T: EthSpec> {
|
||||||
BlockContents(SignedBlockContents<T>),
|
BlockContents(SignedBlockContents<T>),
|
||||||
Block(SignedBeaconBlock<T>),
|
Block(Arc<SignedBeaconBlock<T>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> PublishBlockRequest<T> {
|
impl<T: EthSpec> PublishBlockRequest<T> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
block: SignedBeaconBlock<T>,
|
block: Arc<SignedBeaconBlock<T>>,
|
||||||
blob_items: Option<(KzgProofs<T>, BlobsList<T>)>,
|
blob_items: Option<(KzgProofs<T>, BlobsList<T>)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
match blob_items {
|
match blob_items {
|
||||||
@ -1753,7 +1758,7 @@ impl<T: EthSpec> PublishBlockRequest<T> {
|
|||||||
match fork_name {
|
match fork_name {
|
||||||
ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {
|
ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {
|
||||||
SignedBeaconBlock::from_ssz_bytes_for_fork(bytes, fork_name)
|
SignedBeaconBlock::from_ssz_bytes_for_fork(bytes, fork_name)
|
||||||
.map(|block| PublishBlockRequest::Block(block))
|
.map(|block| PublishBlockRequest::Block(Arc::new(block)))
|
||||||
}
|
}
|
||||||
ForkName::Deneb => {
|
ForkName::Deneb => {
|
||||||
let mut builder = ssz::SszDecoderBuilder::new(bytes);
|
let mut builder = ssz::SszDecoderBuilder::new(bytes);
|
||||||
@ -1767,12 +1772,15 @@ impl<T: EthSpec> PublishBlockRequest<T> {
|
|||||||
})?;
|
})?;
|
||||||
let kzg_proofs = decoder.decode_next()?;
|
let kzg_proofs = decoder.decode_next()?;
|
||||||
let blobs = decoder.decode_next()?;
|
let blobs = decoder.decode_next()?;
|
||||||
Ok(PublishBlockRequest::new(block, Some((kzg_proofs, blobs))))
|
Ok(PublishBlockRequest::new(
|
||||||
|
Arc::new(block),
|
||||||
|
Some((kzg_proofs, blobs)),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signed_block(&self) -> &SignedBeaconBlock<T> {
|
pub fn signed_block(&self) -> &Arc<SignedBeaconBlock<T>> {
|
||||||
match self {
|
match self {
|
||||||
PublishBlockRequest::BlockContents(block_and_sidecars) => {
|
PublishBlockRequest::BlockContents(block_and_sidecars) => {
|
||||||
&block_and_sidecars.signed_block
|
&block_and_sidecars.signed_block
|
||||||
@ -1802,14 +1810,14 @@ pub fn into_full_block_and_blobs<T: EthSpec>(
|
|||||||
let signed_block = blinded_block
|
let signed_block = blinded_block
|
||||||
.try_into_full_block(None)
|
.try_into_full_block(None)
|
||||||
.ok_or("Failed to build full block with payload".to_string())?;
|
.ok_or("Failed to build full block with payload".to_string())?;
|
||||||
Ok(PublishBlockRequest::new(signed_block, None))
|
Ok(PublishBlockRequest::new(Arc::new(signed_block), None))
|
||||||
}
|
}
|
||||||
// This variant implies a pre-deneb block
|
// This variant implies a pre-deneb block
|
||||||
Some(FullPayloadContents::Payload(execution_payload)) => {
|
Some(FullPayloadContents::Payload(execution_payload)) => {
|
||||||
let signed_block = blinded_block
|
let signed_block = blinded_block
|
||||||
.try_into_full_block(Some(execution_payload))
|
.try_into_full_block(Some(execution_payload))
|
||||||
.ok_or("Failed to build full block with payload".to_string())?;
|
.ok_or("Failed to build full block with payload".to_string())?;
|
||||||
Ok(PublishBlockRequest::new(signed_block, None))
|
Ok(PublishBlockRequest::new(Arc::new(signed_block), None))
|
||||||
}
|
}
|
||||||
// This variant implies a post-deneb block
|
// This variant implies a post-deneb block
|
||||||
Some(FullPayloadContents::PayloadAndBlobs(payload_and_blobs)) => {
|
Some(FullPayloadContents::PayloadAndBlobs(payload_and_blobs)) => {
|
||||||
@ -1818,7 +1826,7 @@ pub fn into_full_block_and_blobs<T: EthSpec>(
|
|||||||
.ok_or("Failed to build full block with payload".to_string())?;
|
.ok_or("Failed to build full block with payload".to_string())?;
|
||||||
|
|
||||||
Ok(PublishBlockRequest::new(
|
Ok(PublishBlockRequest::new(
|
||||||
signed_block,
|
Arc::new(signed_block),
|
||||||
Some((
|
Some((
|
||||||
payload_and_blobs.blobs_bundle.proofs,
|
payload_and_blobs.blobs_bundle.proofs,
|
||||||
payload_and_blobs.blobs_bundle.blobs,
|
payload_and_blobs.blobs_bundle.blobs,
|
||||||
@ -1828,10 +1836,10 @@ pub fn into_full_block_and_blobs<T: EthSpec>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> TryFrom<SignedBeaconBlock<T>> for PublishBlockRequest<T> {
|
impl<T: EthSpec> TryFrom<Arc<SignedBeaconBlock<T>>> for PublishBlockRequest<T> {
|
||||||
type Error = &'static str;
|
type Error = &'static str;
|
||||||
fn try_from(block: SignedBeaconBlock<T>) -> Result<Self, Self::Error> {
|
fn try_from(block: Arc<SignedBeaconBlock<T>>) -> Result<Self, Self::Error> {
|
||||||
match block {
|
match *block {
|
||||||
SignedBeaconBlock::Base(_)
|
SignedBeaconBlock::Base(_)
|
||||||
| SignedBeaconBlock::Altair(_)
|
| SignedBeaconBlock::Altair(_)
|
||||||
| SignedBeaconBlock::Merge(_)
|
| SignedBeaconBlock::Merge(_)
|
||||||
@ -1852,7 +1860,7 @@ impl<T: EthSpec> From<SignedBlockContentsTuple<T>> for PublishBlockRequest<T> {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize, Encode)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Encode)]
|
||||||
#[serde(bound = "T: EthSpec")]
|
#[serde(bound = "T: EthSpec")]
|
||||||
pub struct SignedBlockContents<T: EthSpec> {
|
pub struct SignedBlockContents<T: EthSpec> {
|
||||||
pub signed_block: SignedBeaconBlock<T>,
|
pub signed_block: Arc<SignedBeaconBlock<T>>,
|
||||||
pub kzg_proofs: KzgProofs<T>,
|
pub kzg_proofs: KzgProofs<T>,
|
||||||
#[serde(with = "ssz_types::serde_utils::list_of_hex_fixed_vec")]
|
#[serde(with = "ssz_types::serde_utils::list_of_hex_fixed_vec")]
|
||||||
pub blobs: BlobsList<T>,
|
pub blobs: BlobsList<T>,
|
||||||
|
@ -323,8 +323,9 @@ impl ForkChoiceTest {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let slot = self.harness.get_current_slot();
|
let slot = self.harness.get_current_slot();
|
||||||
let (mut block_tuple, mut state) = self.harness.make_block(state, slot).await;
|
let ((block_arc, _block_blobs), mut state) = self.harness.make_block(state, slot).await;
|
||||||
func(&mut block_tuple.0, &mut state);
|
let mut block = (*block_arc).clone();
|
||||||
|
func(&mut block, &mut state);
|
||||||
let current_slot = self.harness.get_current_slot();
|
let current_slot = self.harness.get_current_slot();
|
||||||
self.harness
|
self.harness
|
||||||
.chain
|
.chain
|
||||||
@ -332,8 +333,8 @@ impl ForkChoiceTest {
|
|||||||
.fork_choice_write_lock()
|
.fork_choice_write_lock()
|
||||||
.on_block(
|
.on_block(
|
||||||
current_slot,
|
current_slot,
|
||||||
block_tuple.0.message(),
|
block.message(),
|
||||||
block_tuple.0.canonical_root(),
|
block.canonical_root(),
|
||||||
Duration::from_secs(0),
|
Duration::from_secs(0),
|
||||||
&state,
|
&state,
|
||||||
PayloadVerificationStatus::Verified,
|
PayloadVerificationStatus::Verified,
|
||||||
@ -366,8 +367,9 @@ impl ForkChoiceTest {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let slot = self.harness.get_current_slot();
|
let slot = self.harness.get_current_slot();
|
||||||
let (mut block_tuple, mut state) = self.harness.make_block(state, slot).await;
|
let ((block_arc, _block_blobs), mut state) = self.harness.make_block(state, slot).await;
|
||||||
mutation_func(&mut block_tuple.0, &mut state);
|
let mut block = (*block_arc).clone();
|
||||||
|
mutation_func(&mut block, &mut state);
|
||||||
let current_slot = self.harness.get_current_slot();
|
let current_slot = self.harness.get_current_slot();
|
||||||
let err = self
|
let err = self
|
||||||
.harness
|
.harness
|
||||||
@ -376,8 +378,8 @@ impl ForkChoiceTest {
|
|||||||
.fork_choice_write_lock()
|
.fork_choice_write_lock()
|
||||||
.on_block(
|
.on_block(
|
||||||
current_slot,
|
current_slot,
|
||||||
block_tuple.0.message(),
|
block.message(),
|
||||||
block_tuple.0.canonical_root(),
|
block.canonical_root(),
|
||||||
Duration::from_secs(0),
|
Duration::from_secs(0),
|
||||||
&state,
|
&state,
|
||||||
PayloadVerificationStatus::Verified,
|
PayloadVerificationStatus::Verified,
|
||||||
|
@ -90,7 +90,7 @@ async fn invalid_block_header_state_slot() {
|
|||||||
let slot = state.slot() + Slot::new(1);
|
let slot = state.slot() + Slot::new(1);
|
||||||
|
|
||||||
let ((signed_block, _), mut state) = harness.make_block_return_pre_state(state, slot).await;
|
let ((signed_block, _), mut state) = harness.make_block_return_pre_state(state, slot).await;
|
||||||
let (mut block, signature) = signed_block.deconstruct();
|
let (mut block, signature) = (*signed_block).clone().deconstruct();
|
||||||
*block.slot_mut() = slot + Slot::new(1);
|
*block.slot_mut() = slot + Slot::new(1);
|
||||||
|
|
||||||
let mut ctxt = ConsensusContext::new(block.slot());
|
let mut ctxt = ConsensusContext::new(block.slot());
|
||||||
@ -123,7 +123,7 @@ async fn invalid_parent_block_root() {
|
|||||||
let ((signed_block, _), mut state) = harness
|
let ((signed_block, _), mut state) = harness
|
||||||
.make_block_return_pre_state(state, slot + Slot::new(1))
|
.make_block_return_pre_state(state, slot + Slot::new(1))
|
||||||
.await;
|
.await;
|
||||||
let (mut block, signature) = signed_block.deconstruct();
|
let (mut block, signature) = (*signed_block).clone().deconstruct();
|
||||||
*block.parent_root_mut() = Hash256::from([0xAA; 32]);
|
*block.parent_root_mut() = Hash256::from([0xAA; 32]);
|
||||||
|
|
||||||
let mut ctxt = ConsensusContext::new(block.slot());
|
let mut ctxt = ConsensusContext::new(block.slot());
|
||||||
@ -158,7 +158,7 @@ async fn invalid_block_signature() {
|
|||||||
let ((signed_block, _), mut state) = harness
|
let ((signed_block, _), mut state) = harness
|
||||||
.make_block_return_pre_state(state, slot + Slot::new(1))
|
.make_block_return_pre_state(state, slot + Slot::new(1))
|
||||||
.await;
|
.await;
|
||||||
let (block, _) = signed_block.deconstruct();
|
let (block, _) = (*signed_block).clone().deconstruct();
|
||||||
|
|
||||||
let mut ctxt = ConsensusContext::new(block.slot());
|
let mut ctxt = ConsensusContext::new(block.slot());
|
||||||
let result = per_block_processing(
|
let result = per_block_processing(
|
||||||
|
@ -57,7 +57,7 @@ impl ExitTest {
|
|||||||
block_modifier(&harness, block);
|
block_modifier(&harness, block);
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
(signed_block.0, state)
|
((*signed_block.0).clone(), state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(
|
fn process(
|
||||||
|
@ -450,12 +450,13 @@ impl<T: SlotClock + 'static, E: EthSpec> BlockService<T, E> {
|
|||||||
self.validator_store
|
self.validator_store
|
||||||
.sign_block(*validator_pubkey, block, slot)
|
.sign_block(*validator_pubkey, block, slot)
|
||||||
.await
|
.await
|
||||||
.map(|b| SignedBlock::Full(PublishBlockRequest::new(b, maybe_blobs)))
|
.map(|b| SignedBlock::Full(PublishBlockRequest::new(Arc::new(b), maybe_blobs)))
|
||||||
}
|
}
|
||||||
UnsignedBlock::Blinded(block) => self
|
UnsignedBlock::Blinded(block) => self
|
||||||
.validator_store
|
.validator_store
|
||||||
.sign_block(*validator_pubkey, block, slot)
|
.sign_block(*validator_pubkey, block, slot)
|
||||||
.await
|
.await
|
||||||
|
.map(Arc::new)
|
||||||
.map(SignedBlock::Blinded),
|
.map(SignedBlock::Blinded),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -870,7 +871,7 @@ impl<E: EthSpec> UnsignedBlock<E> {
|
|||||||
|
|
||||||
pub enum SignedBlock<E: EthSpec> {
|
pub enum SignedBlock<E: EthSpec> {
|
||||||
Full(PublishBlockRequest<E>),
|
Full(PublishBlockRequest<E>),
|
||||||
Blinded(SignedBlindedBeaconBlock<E>),
|
Blinded(Arc<SignedBlindedBeaconBlock<E>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> SignedBlock<E> {
|
impl<E: EthSpec> SignedBlock<E> {
|
||||||
|
Loading…
Reference in New Issue
Block a user