Unverified Commit d729d4a1 authored by Andronik Ordian's avatar Andronik Ordian Committed by GitHub
Browse files

approval-distribution: send all messages on unify (#3179)

* approval-distribution: send all messages on unify

* update the guide
parent b7b25c4b
Pipeline #140768 passed with stages
in 37 minutes and 19 seconds
......@@ -146,8 +146,6 @@ enum LocalSource {
No,
}
type BlockDepth = usize;
/// Information about candidates in the context of a particular block they are included in.
/// In other words, multiple `CandidateEntry`s may exist for the same candidate,
/// if it is included by multiple blocks - this is likely the case when there are forks.
......@@ -968,7 +966,7 @@ impl State {
) {
metrics.on_unify_with_peer();
let _timer = metrics.time_unify_with_peer();
let mut to_send: Vec<(BlockDepth, Hash)> = Vec::new();
let mut to_send: Vec<Hash> = Vec::new();
let view_finalized_number = view.finalized_number;
for head in view.into_iter() {
......@@ -996,7 +994,7 @@ impl State {
block = entry.parent_hash.clone();
Some(interesting_block)
});
to_send.extend(interesting_blocks.enumerate());
to_send.extend(interesting_blocks);
}
// step 6.
// send all assignments and approvals for all candidates in those blocks to the peer
......@@ -1012,16 +1010,13 @@ impl State {
entries: &HashMap<Hash, BlockEntry>,
ctx: &mut impl SubsystemContext<Message = ApprovalDistributionMessage>,
peer_id: PeerId,
blocks: Vec<(BlockDepth, Hash)>,
blocks: Vec<Hash>,
) {
// we will propagate only local assignment/approvals after a certain depth
const DEPTH_THRESHOLD: usize = 5;
let mut assignments = Vec::new();
let mut approvals = Vec::new();
let num_blocks = blocks.len();
for (depth, block) in blocks.into_iter() {
for block in blocks.into_iter() {
let entry = match entries.get(&block) {
Some(entry) => entry,
None => continue, // should be unreachable
......@@ -1036,10 +1031,7 @@ impl State {
for (candidate_index, candidate_entry) in entry.candidates.iter().enumerate() {
let candidate_index = candidate_index as u32;
for (validator_index, (approval_state, is_local)) in candidate_entry.approvals.iter() {
if depth >= DEPTH_THRESHOLD && !matches!(is_local, LocalSource::Yes) {
continue;
}
for (validator_index, (approval_state, _is_local)) in candidate_entry.approvals.iter() {
match approval_state {
ApprovalState::Assigned(cert) => {
assignments.push((
......
......@@ -247,8 +247,6 @@ For each block in the view:
2. Load the `BlockEntry` for the block. If the block is unknown, or the number is less than or equal to the view's finalized number go to step 6.
3. Inspect the `known_by` set of the `BlockEntry`. If the peer is already present, go to step 6.
4. Add the peer to `known_by` with a cloned version of `block_entry.knowledge`. and add the hash of the block to `fresh_blocks`.
5. Return to step 2 with the ancestor of the block, keeping track of the block depth (+1).
5. Return to step 2 with the ancestor of the block.
6. For each block in `fresh_blocks`, send all assignments and approvals for all candidates in those blocks to the peer if the block depth threshold is not reached, otherwise, send only assignments and approvals origination with the local source.
The reason we only send our local assignments and approvals when a certain block depth is reached when unifying with a peer is to avoid DoS attacks. It also helps when a node starts with a large difference between finalized and the highest block.
6. For each block in `fresh_blocks`, send all assignments and approvals for all candidates in those blocks to the peer.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment