Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion node/core/backing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,7 @@ async fn import_statement<Context>(
// we need to create an entry in the `PerCandidateState` map.
//
// If the relay parent supports prospective parachains, we also need
// to inform the prospective parachains subsystem of the seconded candidate
// to inform the prospective parachains subsystem of the seconded candidate.
// If `ProspectiveParachainsMessage::Second` fails, then we return
// Error::RejectedByProspectiveParachains.
//
Expand Down
69 changes: 35 additions & 34 deletions node/core/prospective-parachains/src/fragment_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,8 @@ impl Scope {
}
}

// We use indices into a flat vector to refer to nodes in the tree.
// Every tree also has an implicit root.
/// We use indices into a flat vector to refer to nodes in the tree.
/// Every tree also has an implicit root.
#[derive(Debug, Clone, Copy, PartialEq)]
enum NodePointer {
Root,
Expand Down Expand Up @@ -618,8 +618,8 @@ impl FragmentTree {
let max_depth = self.scope.max_depth;
let mut depths = bitvec![u16, Msb0; 0; max_depth + 1];

// iterate over all nodes < max_depth where parent head-data matches,
// relay-parent number is <= candidate, and depth < max_depth.
// iterate over all nodes where parent head-data matches,
// relay-parent number is <= candidate, and depth <= max_depth.
let node_pointers = (0..self.nodes.len()).map(NodePointer::Storage);
for parent_pointer in std::iter::once(NodePointer::Root).chain(node_pointers) {
let (modifications, child_depth, earliest_rp) = match parent_pointer {
Expand Down Expand Up @@ -665,46 +665,46 @@ impl FragmentTree {
};

let parent_head_hash = candidate.parent_head_data_hash();
if parent_head_hash == child_constraints.required_parent.hash() {
// We do additional checks for complete candidates.
if let HypotheticalCandidate::Complete {
ref receipt,
ref persisted_validation_data,
} = candidate
{
let prospective_candidate = ProspectiveCandidate {
commitments: Cow::Borrowed(&receipt.commitments),
collator: receipt.descriptor().collator.clone(),
collator_signature: receipt.descriptor().signature.clone(),
persisted_validation_data: persisted_validation_data.as_ref().clone(),
pov_hash: receipt.descriptor().pov_hash,
validation_code_hash: receipt.descriptor().validation_code_hash,
};
if parent_head_hash != child_constraints.required_parent.hash() {
continue
}
Comment on lines +668 to +670
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this check to continue-style to be consistent with above checks (and it's easier to read). Rest of the diff here is due to indentation/formatting.


if Fragment::new(
candidate_relay_parent.clone(),
child_constraints,
prospective_candidate,
)
.is_err()
{
continue
}
}
// We do additional checks for complete candidates.
if let HypotheticalCandidate::Complete { ref receipt, ref persisted_validation_data } =
candidate
{
let prospective_candidate = ProspectiveCandidate {
commitments: Cow::Borrowed(&receipt.commitments),
collator: receipt.descriptor().collator.clone(),
collator_signature: receipt.descriptor().signature.clone(),
persisted_validation_data: persisted_validation_data.as_ref().clone(),
pov_hash: receipt.descriptor().pov_hash,
validation_code_hash: receipt.descriptor().validation_code_hash,
};

// Check that the path only contains backed candidates, if necessary.
if !backed_in_path_only ||
self.path_contains_backed_only_candidates(parent_pointer, candidate_storage)
if Fragment::new(
candidate_relay_parent.clone(),
child_constraints,
prospective_candidate,
)
.is_err()
{
depths.set(child_depth, true);
continue
}
}

// Check that the path only contains backed candidates, if necessary.
if !backed_in_path_only ||
self.path_contains_backed_only_candidates(parent_pointer, candidate_storage)
{
depths.set(child_depth, true);
}
}

depths.iter_ones().collect()
}

/// Select a candidate after the given `required_path` which pass
/// Select a candidate after the given `required_path` which passes
/// the predicate.
///
/// If there are multiple possibilities, this will select the first one.
Expand Down Expand Up @@ -1160,6 +1160,7 @@ mod tests {
assert!(storage.head_data_by_hash(&output_head_hash).is_none());
}

// [`FragmentTree::populate`] should pick up candidates that build on other candidates.
#[test]
fn populate_works_recursively() {
let mut storage = CandidateStorage::new();
Expand Down
2 changes: 1 addition & 1 deletion node/subsystem-types/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ pub enum ChainApiMessage {
/// Request the last finalized block number.
/// This request always succeeds.
FinalizedBlockNumber(ChainApiResponseChannel<BlockNumber>),
/// Request the `k` ancestors block hashes of a block with the given hash.
/// Request the `k` ancestor block hashes of a block with the given hash.
/// The response channel may return a `Vec` of size up to `k`
/// filled with ancestors hashes with the following order:
/// `parent`, `grandparent`, ... up to the hash of genesis block
Expand Down
2 changes: 1 addition & 1 deletion node/subsystem-util/src/backing_implicit_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl View {
///
/// This returns a list of para-ids which are relevant to the leaf,
/// and the allowed relay parents for these paras under this leaf can be
/// queried with [`known_allowed_relay_parents_under`].
/// queried with [`View::known_allowed_relay_parents_under`].
///
/// No-op for known leaves.
pub async fn activate_leaf<Sender>(
Expand Down
25 changes: 13 additions & 12 deletions node/subsystem-util/src/inclusion_emulator/staging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,20 @@
//!
//! ### Pruning Fragment Trees
//!
//! When the relay-chain advances, we want to compare the new constraints
//! of that relay-parent to the roots of the fragment trees we have. There are 3 cases.
//! When the relay-chain advances, we want to compare the new constraints of that relay-parent to
//! the roots of the fragment trees we have. There are 3 cases:
//!
//! 1. The root fragment is still valid under the new constraints. In this case, we do nothing.
//! This is the "prediction still uncertain" case.
//! 2. The root fragment is invalid under the new constraints because it has been subsumed by the relay-chain.
//! in this case, we can discard the root and split & re-root the fragment tree
//! under its descendents and compare to the new constraints again.
//! This is the "prediction came true" case.
//! 3. The root fragment is invalid under the new constraints because a competing parachain block has been included
//! or it would never be accepted for some other reason. In this case we can discard the entire
//! fragment tree.
//! This is the "prediction came false" case.
//! 1. The root fragment is still valid under the new constraints. In this case, we do nothing. This
//! is the "prediction still uncertain" case.
//!
//! 2. The root fragment is invalid under the new constraints because it has been subsumed by the
//! relay-chain. In this case, we can discard the root and split & re-root the fragment tree under
//! its descendents and compare to the new constraints again. This is the "prediction came true"
//! case.
//!
//! 3. The root fragment is invalid under the new constraints because a competing parachain block
//! has been included or it would never be accepted for some other reason. In this case we can
//! discard the entire fragment tree. This is the "prediction came false" case.
//!
//! This is all a bit of a simplification because it assumes that the relay-chain advances without
//! forks and is finalized instantly. In practice, the set of fragment-trees needs to be observable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ reasons. As a result, all validators must have a up to date view of all possible
parachain candidates + backing statements that could be placed on-chain in the
next block.

[This blog
post](https://polkadot.network/blog/polkadot-v1-0-sharding-and-economic-security)
[This blog post](https://polkadot.network/blog/polkadot-v1-0-sharding-and-economic-security)
puts it another way: "Validators who aren't assigned to the parachain still
listen for the attestations [statements] because whichever validator ends up
being the author of the relay-chain block needs to bundle up attested parachain
Expand Down Expand Up @@ -155,11 +154,11 @@ backing subsystem itself.
- Note that requesting is not an implicit acknowledgement, and an explicit
acknowledgement must be sent upon receipt.

## Statement distribution messages
## Messages

### Input
### Incoming

- `ActiveLeavesUpdate`
- `ActiveLeaves`
- Notification of a change in the set of active leaves.
- `StatementDistributionMessage::Share`
- Notification of a locally-originating statement. That is, this statement
Expand All @@ -186,7 +185,7 @@ backing subsystem itself.
- Acknowledgement.
- Handled by `handle_incoming_acknowledgement`

### Output
### Outgoing

- `NetworkBridgeTxMessage::SendValidationMessages`
- Sends a peer all pending messages / acknowledgements / statements for a
Expand All @@ -202,7 +201,7 @@ backing subsystem itself.
- Gets the hypothetical frontier membership of candidates under active leaves'
fragment trees.
- `NetworkBridgeTxMessage::SendRequests`
- Sends requests, initiating request/response protocol.
- Sends requests, initiating the request/response protocol.

## Request/Response

Expand Down