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

Commit

Permalink
Onchain scraper in dispute-coordinator will scrape `SCRAPED_FINALIZ…
Browse files Browse the repository at this point in the history
…ED_BLOCKS_COUNT` blocks before finality (#7013)

* Onchain scraper in `dispute-coordinator` will scrape `SCRAPED_FINALIZED_BLOCKS_COUNT` blocks before finality

The purpose is to make the availability of a `CandidateReceipt` for finalized candidates more likely.

For details see:  #7009

* Fix off by one error

* Replace `SCRAPED_FINALIZED_BLOCKS_COUNT` with `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION`
  • Loading branch information
tdimitrov authored Apr 7, 2023
1 parent 173a5a3 commit 7b6ea48
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
21 changes: 14 additions & 7 deletions node/core/dispute-coordinator/src/scraping/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ impl Inclusions {
/// `process_active_leaves_update` any scraped votes.
///
/// Scraped candidates are available `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION` more blocks
/// after finalization as a precaution not to prune them prematurely.
/// after finalization as a precaution not to prune them prematurely. Besides the newly scraped
/// candidates `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION` finalized blocks are parsed as
/// another precaution to have their `CandidateReceipts` available in case a dispute is raised on
/// them,
pub struct ChainScraper {
/// All candidates we have seen included, which not yet have been finalized.
included_candidates: candidates::ScrapedCandidates,
Expand Down Expand Up @@ -228,9 +231,10 @@ impl ChainScraper {
None => return Ok(ScrapedUpdates::new()),
};

// Fetch ancestry up to last finalized block.
// Fetch ancestry up to `SCRAPED_FINALIZED_BLOCKS_COUNT` blocks beyond
// the last finalized one
let ancestors = self
.get_unfinalized_block_ancestors(sender, activated.hash, activated.number)
.get_relevant_block_ancestors(sender, activated.hash, activated.number)
.await?;

// Ancestors block numbers are consecutive in the descending order.
Expand Down Expand Up @@ -330,10 +334,11 @@ impl ChainScraper {
}

/// Returns ancestors of `head` in the descending order, stopping
/// either at the block present in cache or at the last finalized block.
/// either at the block present in cache or at `SCRAPED_FINALIZED_BLOCKS_COUNT -1` blocks after
/// the last finalized one (called `target_ancestor`).
///
/// Both `head` and the latest finalized block are **not** included in the result.
async fn get_unfinalized_block_ancestors<Sender>(
/// Both `head` and the `target_ancestor` blocks are **not** included in the result.
async fn get_relevant_block_ancestors<Sender>(
&mut self,
sender: &mut Sender,
mut head: Hash,
Expand All @@ -342,7 +347,9 @@ impl ChainScraper {
where
Sender: overseer::DisputeCoordinatorSenderTrait,
{
let target_ancestor = get_finalized_block_number(sender).await?;
let target_ancestor = get_finalized_block_number(sender)
.await?
.saturating_sub(DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION);

let mut ancestors = Vec::new();

Expand Down
3 changes: 2 additions & 1 deletion node/core/dispute-coordinator/src/scraping/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@ fn scraper_requests_candidates_of_non_finalized_ancestors() {
&mut virtual_overseer,
&chain,
finalized_block_number,
BLOCKS_TO_SKIP - finalized_block_number as usize, // Expect the provider not to go past finalized block.
BLOCKS_TO_SKIP -
(finalized_block_number - DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION) as usize, // Expect the provider not to go past finalized block.
get_backed_and_included_candidate_events,
);
join(process_active_leaves_update(ctx.sender(), &mut ordering, next_update), overseer_fut)
Expand Down
8 changes: 7 additions & 1 deletion node/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub const VALIDATION_CODE_BOMB_LIMIT: usize = (MAX_CODE_SIZE * 4u32) as usize;
pub const POV_BOMB_LIMIT: usize = (MAX_POV_SIZE * 4u32) as usize;

/// How many blocks after finalization an information about backed/included candidate should be
/// kept.
/// pre-loaded (when scraoing onchain votes) and kept locally (when pruning).
///
/// We don't want to remove scraped candidates on finalization because we want to
/// be sure that disputes will conclude on abandoned forks.
Expand All @@ -74,6 +74,12 @@ pub const POV_BOMB_LIMIT: usize = (MAX_POV_SIZE * 4u32) as usize;
/// better one gets finalized the entries for the bad fork will be pruned and we
/// might never participate in a dispute for it.
///
/// Why pre-load finalized blocks? I dispute might be raised against finalized candidate. In most
/// of the cases it will conclude valid (otherwise we are in big trouble) but never the less the
/// node must participate. It's possible to see a vote for such dispute onchain before we have it
/// imported by `dispute-distribution`. In this case we won't have `CandidateReceipt` and the import
/// will fail unless we keep them preloaded.
///
/// This value should consider the timeout we allow for participation in approval-voting. In
/// particular, the following condition should hold:
///
Expand Down

0 comments on commit 7b6ea48

Please sign in to comment.