mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 23:31:07 +00:00
Cap the warp sync proof by size, not by fragments (#8578)
* Cap the warp sync proof by size, not by fragments * Add a final debug assert * Check size after
This commit is contained in:
@@ -66,7 +66,7 @@ pub fn generate_request_response_config(protocol_id: ProtocolId) -> RequestRespo
|
||||
RequestResponseConfig {
|
||||
name: generate_protocol_name(protocol_id).into(),
|
||||
max_request_size: 32,
|
||||
max_response_size: 16 * 1024 * 1024,
|
||||
max_response_size: proof::MAX_WARP_SYNC_PROOF_SIZE as u64,
|
||||
request_timeout: Duration::from_secs(10),
|
||||
inbound_queue: None,
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ use sp_runtime::{
|
||||
|
||||
use crate::HandleRequestError;
|
||||
|
||||
/// The maximum number of authority set change proofs to include in a single warp sync proof.
|
||||
const MAX_CHANGES_PER_WARP_SYNC_PROOF: usize = 256;
|
||||
/// The maximum size in bytes of the `WarpSyncProof`.
|
||||
pub(super) const MAX_WARP_SYNC_PROOF_SIZE: usize = 16 * 1024 * 1024;
|
||||
|
||||
/// A proof of an authority set change.
|
||||
#[derive(Decode, Encode)]
|
||||
@@ -53,7 +53,7 @@ pub struct WarpSyncProof<Block: BlockT> {
|
||||
impl<Block: BlockT> WarpSyncProof<Block> {
|
||||
/// Generates a warp sync proof starting at the given block. It will generate authority set
|
||||
/// change proofs for all changes that happened from `begin` until the current authority set
|
||||
/// (capped by MAX_CHANGES_PER_WARP_SYNC_PROOF).
|
||||
/// (capped by MAX_WARP_SYNC_PROOF_SIZE).
|
||||
pub fn generate<Backend>(
|
||||
backend: &Backend,
|
||||
begin: Block::Hash,
|
||||
@@ -88,14 +88,10 @@ impl<Block: BlockT> WarpSyncProof<Block> {
|
||||
}
|
||||
|
||||
let mut proofs = Vec::new();
|
||||
let mut proofs_encoded_len = 0;
|
||||
let mut proof_limit_reached = false;
|
||||
|
||||
for (_, last_block) in set_changes.iter_from(begin_number) {
|
||||
if proofs.len() >= MAX_CHANGES_PER_WARP_SYNC_PROOF {
|
||||
proof_limit_reached = true;
|
||||
break;
|
||||
}
|
||||
|
||||
let header = blockchain.header(BlockId::Number(*last_block))?.expect(
|
||||
"header number comes from previously applied set changes; must exist in db; qed.",
|
||||
);
|
||||
@@ -120,10 +116,22 @@ impl<Block: BlockT> WarpSyncProof<Block> {
|
||||
|
||||
let justification = GrandpaJustification::<Block>::decode(&mut &justification[..])?;
|
||||
|
||||
proofs.push(WarpSyncFragment {
|
||||
let proof = WarpSyncFragment {
|
||||
header: header.clone(),
|
||||
justification,
|
||||
});
|
||||
};
|
||||
let proof_size = proof.encoded_size();
|
||||
|
||||
// Check for the limit. We remove some bytes from the maximum size, because we're only
|
||||
// counting the size of the `WarpSyncFragment`s. The extra margin is here to leave
|
||||
// room for rest of the data (the size of the `Vec` and the boolean).
|
||||
if proofs_encoded_len + proof_size >= MAX_WARP_SYNC_PROOF_SIZE - 50 {
|
||||
proof_limit_reached = true;
|
||||
break;
|
||||
}
|
||||
|
||||
proofs_encoded_len += proof_size;
|
||||
proofs.push(proof);
|
||||
}
|
||||
|
||||
let is_finished = if proof_limit_reached {
|
||||
@@ -156,10 +164,12 @@ impl<Block: BlockT> WarpSyncProof<Block> {
|
||||
true
|
||||
};
|
||||
|
||||
Ok(WarpSyncProof {
|
||||
let final_outcome = WarpSyncProof {
|
||||
proofs,
|
||||
is_finished,
|
||||
})
|
||||
};
|
||||
debug_assert!(final_outcome.encoded_size() <= MAX_WARP_SYNC_PROOF_SIZE);
|
||||
Ok(final_outcome)
|
||||
}
|
||||
|
||||
/// Verifies the warp sync proof starting at the given set id and with the given authorities.
|
||||
|
||||
Reference in New Issue
Block a user