Skip to content

Commit

Permalink
Merge branch 'master' into alexaggh/fix_busy_waiting_statement_distri…
Browse files Browse the repository at this point in the history
…bution
  • Loading branch information
alexggh authored Apr 18, 2024
2 parents a64bf77 + 91d4a20 commit 6871b51
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 28 deletions.
3 changes: 1 addition & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ workflow:
- if: $CI_COMMIT_BRANCH

variables:
# CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE]
CI_IMAGE: "docker.io/paritytech/ci-unified:bullseye-1.77.0-2024-04-10-v20240408"
CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE]
# BUILDAH_IMAGE is defined in group variables
BUILDAH_COMMAND: "buildah --storage-driver overlay2"
RELENG_SCRIPTS_BRANCH: "master"
Expand Down
6 changes: 3 additions & 3 deletions polkadot/node/core/chain-selection/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ async fn handle_active_leaf(

// Extract all reversion logs from a header in ascending order.
//
// Ignores logs with number >= the block header number.
// Ignores logs with number > the block header number.
fn extract_reversion_logs(header: &Header) -> Vec<BlockNumber> {
let number = header.number;
let mut logs = header
Expand All @@ -639,14 +639,14 @@ fn extract_reversion_logs(header: &Header) -> Vec<BlockNumber> {

None
},
Ok(Some(ConsensusLog::Revert(b))) if b < number => Some(b),
Ok(Some(ConsensusLog::Revert(b))) if b <= number => Some(b),
Ok(Some(ConsensusLog::Revert(b))) => {
gum::warn!(
target: LOG_TARGET,
revert_target = b,
block_number = number,
block_hash = ?header.hash(),
"Block issued invalid revert digest targeting itself or future"
"Block issued invalid revert digest targeting future"
);

None
Expand Down
43 changes: 39 additions & 4 deletions polkadot/node/core/chain-selection/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -966,19 +966,54 @@ fn ancestor_of_unviable_is_not_leaf_if_has_children() {
}

#[test]
fn self_and_future_reversions_are_ignored() {
fn self_reversions_are_not_ignored() {
test_harness(|backend, _, mut virtual_overseer| async move {
let finalized_number = 0;
let finalized_hash = Hash::repeat_byte(0);

// F <- A1 <- A2 <- A3.
//
// A3 reverts itself and future blocks. ignored.
// A3 reverts itself

let (_, chain_a) =
construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| {
if h.number == 3 {
add_reversions(h, vec![3])
}
});

let a2_hash = chain_a.iter().rev().nth(1).unwrap().0.hash();

import_blocks_into(
&mut virtual_overseer,
&backend,
Some((finalized_number, finalized_hash)),
chain_a.clone(),
)
.await;

assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h));
assert_leaves(&backend, vec![a2_hash]);
assert_leaves_query(&mut virtual_overseer, vec![a2_hash]).await;

virtual_overseer
});
}

#[test]
fn future_reversions_are_ignored() {
test_harness(|backend, _, mut virtual_overseer| async move {
let finalized_number = 0;
let finalized_hash = Hash::repeat_byte(0);

// F <- A1 <- A2 <- A3.
//
// A3 reverts future blocks. ignored.

let (a3_hash, chain_a) =
construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| {
if h.number == 3 {
add_reversions(h, vec![3, 4, 100])
add_reversions(h, vec![4, 100])
}
});

Expand Down Expand Up @@ -1006,7 +1041,7 @@ fn revert_finalized_is_ignored() {

// F <- A1 <- A2 <- A3.
//
// A3 reverts itself and future blocks. ignored.
// A3 reverts finalized F and its ancestors. ignored.

let (a3_hash, chain_a) =
construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| {
Expand Down
42 changes: 23 additions & 19 deletions polkadot/node/core/chain-selection/src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ fn propagate_viability_update(
Ok(())
}

/// Imports a new block and applies any reversions to ancestors.
/// Imports a new block and applies any reversions to ancestors or the block itself.
pub(crate) fn import_block(
backend: &mut OverlayedBackend<impl Backend>,
block_hash: Hash,
Expand All @@ -246,25 +246,29 @@ pub(crate) fn import_block(
weight: BlockWeight,
stagnant_at: Timestamp,
) -> Result<(), Error> {
add_block(backend, block_hash, block_number, parent_hash, weight, stagnant_at)?;
apply_ancestor_reversions(backend, block_hash, block_number, reversion_logs)?;
let block_entry =
add_block(backend, block_hash, block_number, parent_hash, weight, stagnant_at)?;
apply_reversions(backend, block_entry, reversion_logs)?;

Ok(())
}

// Load the given ancestor's block entry, in descending order from the `block_hash`.
// The ancestor_number must be at least one block less than the `block_number`.
// The ancestor_number must be not higher than the `block_entry`'s.
//
// The returned entry will be `None` if the range is invalid or any block in the path had
// no entry present. If any block entry was missing, it can safely be assumed to
// be finalized.
fn load_ancestor(
backend: &mut OverlayedBackend<impl Backend>,
block_hash: Hash,
block_number: BlockNumber,
block_entry: &BlockEntry,
ancestor_number: BlockNumber,
) -> Result<Option<BlockEntry>, Error> {
if block_number <= ancestor_number {
let block_hash = block_entry.block_hash;
let block_number = block_entry.block_number;
if block_number == ancestor_number {
return Ok(Some(block_entry.clone()))
} else if block_number < ancestor_number {
return Ok(None)
}

Expand Down Expand Up @@ -300,15 +304,15 @@ fn add_block(
parent_hash: Hash,
weight: BlockWeight,
stagnant_at: Timestamp,
) -> Result<(), Error> {
) -> Result<BlockEntry, Error> {
let mut leaves = backend.load_leaves()?;
let parent_entry = backend.load_block_entry(&parent_hash)?;

let inherited_viability =
parent_entry.as_ref().and_then(|parent| parent.non_viable_ancestor_for_child());

// 1. Add the block to the DB assuming it's not reverted.
backend.write_block_entry(BlockEntry {
let block_entry = BlockEntry {
block_hash,
block_number,
parent_hash,
Expand All @@ -319,7 +323,8 @@ fn add_block(
approval: Approval::Unapproved,
},
weight,
});
};
backend.write_block_entry(block_entry.clone());

// 2. Update leaves if inherited viability is fine.
if inherited_viability.is_none() {
Expand All @@ -344,26 +349,25 @@ fn add_block(
stagnant_at_list.push(block_hash);
backend.write_stagnant_at(stagnant_at, stagnant_at_list);

Ok(())
Ok(block_entry)
}

/// Assuming that a block is already imported, accepts the number of the block
/// as well as a list of reversions triggered by the block in ascending order.
fn apply_ancestor_reversions(
fn apply_reversions(
backend: &mut OverlayedBackend<impl Backend>,
block_hash: Hash,
block_number: BlockNumber,
block_entry: BlockEntry,
reversions: Vec<BlockNumber>,
) -> Result<(), Error> {
// Note: since revert numbers are in ascending order, the expensive propagation
// of unviability is only heavy on the first log.
for revert_number in reversions {
let maybe_block_entry = load_ancestor(backend, block_hash, block_number, revert_number)?;
if let Some(block_entry) = &maybe_block_entry {
let maybe_block_entry = load_ancestor(backend, &block_entry, revert_number)?;
if let Some(entry) = &maybe_block_entry {
gum::trace!(
target: LOG_TARGET,
?revert_number,
revert_hash = ?block_entry.block_hash,
revert_hash = ?entry.block_hash,
"Block marked as reverted via scraped on-chain reversions"
);
}
Expand All @@ -372,8 +376,8 @@ fn apply_ancestor_reversions(
maybe_block_entry,
None,
revert_number,
Some(block_hash),
Some(block_number),
Some(block_entry.block_hash),
Some(block_entry.block_number),
)?;
}

Expand Down

0 comments on commit 6871b51

Please sign in to comment.