Skip to content

Commit

Permalink
Fix #2617 (#2703)
Browse files Browse the repository at this point in the history
Fix #2617 

The code that this PR touches was completely wrong, and probably got lost in an earlier refactoring.
  • Loading branch information
tomaka authored Sep 1, 2022
1 parent db871a2 commit 1be7f8c
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 16 deletions.
68 changes: 52 additions & 16 deletions bin/light-base/src/sync_service/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,22 +644,58 @@ pub(super) async fn start_parachain<TPlat: Platform>(
let _ = send_back.send(super::SubscribeAll {
finalized_block_scale_encoded_header: finalized_parahead.clone(),
finalized_block_runtime: None,
non_finalized_blocks_ancestry_order: async_tree.input_iter_unordered().filter_map(|block| {
// `async_op_user_data` is `Some` only if this block has
// already been reported on the output. In order to
// maintain consistency, only these blocks should be
// reported.
let parahead = block.async_op_user_data?.as_ref().unwrap();
let parent_hash = async_tree.parent(block.id)
.map(|idx| header::hash_from_scale_encoded_header(&async_tree.block_async_user_data(idx).unwrap().as_ref().unwrap()))
.unwrap_or_else(|| header::hash_from_scale_encoded_header(&finalized_parahead));

Some(super::BlockNotification {
is_new_best: block.is_output_best,
scale_encoded_header: parahead.clone(),
parent_hash,
})
}).collect(),
non_finalized_blocks_ancestry_order: {
let mut list = HashMap::<_, super::BlockNotification, _>::with_capacity_and_hasher(async_tree.num_input_non_finalized_blocks(), fnv::FnvBuildHasher::default());

for relay_block in async_tree.input_iter_unordered() {
let parablock = match relay_block.async_op_user_data {
Some(b) => b.as_ref().unwrap(),
None => continue,
};

let parablock_hash = header::hash_from_scale_encoded_header(&parablock);

match list.entry(parablock_hash) {
hashbrown::hash_map::Entry::Occupied(entry) => {
if relay_block.is_output_best {
entry.into_mut().is_new_best = true;
}
}
hashbrown::hash_map::Entry::Vacant(entry) => {
let parent_hash = async_tree
.ancestors(relay_block.id)
.find_map(|idx| {
let hash = header::hash_from_scale_encoded_header(&async_tree.block_async_user_data(idx).unwrap().as_ref().unwrap());
if hash != parablock_hash {
Some(hash)
} else {
None
}
})
.or_else(|| {
let finalized_parahash = header::hash_from_scale_encoded_header(&finalized_parahead);
if finalized_parahash != parablock_hash {
Some(finalized_parahash)
} else {
None
}
});

// `parent_hash` is `None` if the parablock is
// the same as the finalized parablock.
if let Some(parent_hash) = parent_hash {
entry.insert(super::BlockNotification {
is_new_best: relay_block.is_output_best,
scale_encoded_header: parablock.clone(),
parent_hash,
});
}
}
}
}

list.into_iter().map(|(_, v)| v).collect()
},
new_blocks,
});
} else {
Expand Down
1 change: 1 addition & 0 deletions bin/wasm-node/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Fixed

- Fix occasional panic when connecting to a parachain with forks and/or missed slots. ([#2703](https://github.com/paritytech/smoldot/pull/2703))
- Fix parachain initialization unnecessarily waiting for its corresponding relay chain initialization to be finished. ([#2705](https://github.com/paritytech/smoldot/pull/2705))

## 0.6.31 - 2022-08-30
Expand Down
11 changes: 11 additions & 0 deletions src/chain/async_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,17 @@ where
self.non_finalized_blocks.parent(node)
}

/// Returns the ancestors of the given node. The iterator stops when it reaches the finalized
/// block. The iterator is empty if the parent of the node is the finalized block.
///
/// # Panic
///
/// Panics if the [`NodeIndex`] is invalid.
///
pub fn ancestors(&'_ self, node: NodeIndex) -> impl Iterator<Item = NodeIndex> + '_ {
self.non_finalized_blocks.ancestors(node)
}

/// Returns the list of children that have the given node as parent.
///
/// # Panic
Expand Down
11 changes: 11 additions & 0 deletions src/chain/fork_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,17 @@ impl<T> ForkTree<T> {
}
}

/// Returns the ancestors of the given node. The iterator is empty if the node doesn't have
/// any parent.
///
/// # Panic
///
/// Panics if the [`NodeIndex`] is invalid.
///
pub fn ancestors(&'_ self, node: NodeIndex) -> impl Iterator<Item = NodeIndex> + '_ {
iter::successors(Some(node), move |n| self.nodes[n.0].parent.map(NodeIndex)).skip(1)
}

/// Returns the parent of the given node. Returns `None` if the node doesn't have any parent.
///
/// # Panic
Expand Down

0 comments on commit 1be7f8c

Please sign in to comment.