Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Block packet size limit #6398

Merged
merged 5 commits into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions client/network/src/block_requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ pub enum Event<B: Block> {
#[derive(Debug, Clone)]
pub struct Config {
max_block_data_response: u32,
max_block_body_bytes: usize,
max_request_len: usize,
max_response_len: usize,
inactivity_timeout: Duration,
Expand All @@ -137,6 +138,7 @@ impl Config {
pub fn new(id: &ProtocolId) -> Self {
let mut c = Config {
max_block_data_response: 128,
max_block_body_bytes: 8 * 1024 * 1024,
max_request_len: 1024 * 1024,
max_response_len: 16 * 1024 * 1024,
inactivity_timeout: Duration::from_secs(15),
Expand Down Expand Up @@ -171,6 +173,15 @@ impl Config {
self
}

/// Set the maximum total bytes of block bodies that are send in the response.
/// Note that at least one block is always sent regardless of the limit.
/// This should be lower than the value specified in `set_max_response_len`
/// accounting for headers, justifications and encoding overhead.
pub fn set_max_block_body_bytes(&mut self, v: usize) -> &mut Self {
self.max_block_body_bytes = v;
self
}

/// Set protocol to use for upgrade negotiation.
pub fn set_protocol(&mut self, id: &ProtocolId) -> &mut Self {
let mut v = Vec::new();
Expand Down Expand Up @@ -385,8 +396,11 @@ where

let mut blocks = Vec::new();
let mut block_id = from_block_id;
let mut total_size = 0;
while let Some(header) = self.chain.header(block_id).unwrap_or(None) {
if blocks.len() >= max_blocks as usize {
if blocks.len() >= max_blocks as usize
|| (blocks.len() >= 1 && total_size > self.config.max_block_body_bytes)
{
break
}

Expand All @@ -400,28 +414,35 @@ where
};
let is_empty_justification = justification.as_ref().map(|j| j.is_empty()).unwrap_or(false);

let body = if get_body {
match self.chain.block_body(&BlockId::Hash(hash))? {
Some(mut extrinsics) => extrinsics.iter_mut()
.map(|extrinsic| extrinsic.encode())
.collect(),
None => {
log::trace!(target: "sync", "Missing data for block request.");
break;
}
}
} else {
Vec::new()
};

let block_data = schema::v1::BlockData {
hash: hash.encode(),
header: if get_header {
header.encode()
} else {
Vec::new()
},
body: if get_body {
self.chain.block_body(&BlockId::Hash(hash))?
.unwrap_or_default()
.iter_mut()
.map(|extrinsic| extrinsic.encode())
.collect()
} else {
Vec::new()
},
body,
receipt: Vec::new(),
message_queue: Vec::new(),
justification: justification.unwrap_or_default(),
is_empty_justification,
};

total_size += block_data.body.len();
blocks.push(block_data);

match direction {
Expand Down
7 changes: 6 additions & 1 deletion client/network/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ pub(crate) const MIN_VERSION: u32 = 3;

// Maximum allowed entries in `BlockResponse`
const MAX_BLOCK_DATA_RESPONSE: u32 = 128;
// Maximum total bytes allowed for block bodies in `BlockResponse`
const MAX_BODIES_BYTES: usize = 8 * 1024 * 1024;

/// When light node connects to the full node and the full node is behind light node
/// for at least `LIGHT_MAXIMAL_BLOCKS_DIFFERENCE` blocks, we consider it not useful
/// and disconnect to free connection slot.
Expand Down Expand Up @@ -756,8 +759,9 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
let get_justification = request
.fields
.contains(message::BlockAttributes::JUSTIFICATION);
let mut total_size = 0;
while let Some(header) = self.context_data.chain.header(id).unwrap_or(None) {
if blocks.len() >= max {
if blocks.len() >= max || (blocks.len() >= 1 && total_size > MAX_BODIES_BYTES) {
break;
}
let number = *header.number();
Expand Down Expand Up @@ -788,6 +792,7 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
trace!(target: "sync", "Missing data for block request.");
break;
}
total_size += block_data.body.as_ref().map_or(0, |b| b.len());
blocks.push(block_data);
match request.direction {
message::Direction::Ascending => id = BlockId::Number(number + One::one()),
Expand Down