Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Closed
Changes from 1 commit
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
62184b4
BEGIN ASYNC candidate-backing CHANGES
rphmeier Apr 28, 2022
821ed42
rename & document modes
rphmeier Apr 29, 2022
1fc4928
answer prospective validation data requests
rphmeier May 18, 2022
39f2076
GetMinimumRelayParents request is now plural
rphmeier May 19, 2022
80af4be
implement an implicit view utility for backing subsystems
rphmeier May 19, 2022
7c58f7a
implicit-view: get allowed relay parents
rphmeier May 23, 2022
fbcedac
refactorings and improvements to implicit view
rphmeier May 23, 2022
126ed91
add some TODOs for tests
rphmeier May 23, 2022
a5994a7
split implicit view updates into 2 functions
rphmeier May 25, 2022
8944760
backing: define State to prepare for functional refactor
rphmeier May 25, 2022
c34d0e6
add some docs
rphmeier May 25, 2022
20cd422
backing: implement bones of new leaf activation logic
rphmeier May 25, 2022
2b7d883
backing: create per-relay-parent-states
rphmeier May 25, 2022
923b28a
use new handle_active_leaves_update
rphmeier May 25, 2022
b9280d1
begin extracting logic from CandidateBackingJob
rphmeier May 27, 2022
967156e
mostly extract statement import from job logic
rphmeier May 27, 2022
b25acb7
handle statement imports outside of job logic
rphmeier May 27, 2022
df95962
do some TODO planning for prospective parachains integration
rphmeier May 27, 2022
458d24d
finish rewriting backing subsystem in functional style
rphmeier May 27, 2022
22a9d5e
add prospective parachains mode to relay parent entries
rphmeier May 27, 2022
fc0c4e4
fmt
rphmeier May 27, 2022
a4df277
add a RejectedByProspectiveParachains error
rphmeier May 27, 2022
2f202d0
notify prospective parachains of seconded and backed candidates
rphmeier May 28, 2022
910b997
always validate candidates exhaustively in backing.
rphmeier May 28, 2022
19d7a43
return persisted_validation_data from validation
rphmeier May 28, 2022
7f24629
handle rejections by prospective parachains
rphmeier May 28, 2022
22ead26
implement seconding sanity check
rphmeier May 28, 2022
6738ee9
invoke validate_and_second
rphmeier May 28, 2022
c54e1ca
Alter statement table to allow multiple seconded messages per validator
rphmeier May 28, 2022
e855b6c
refactor backing to have statements carry PVD
rphmeier May 30, 2022
eb0ee29
clean up all warnings
rphmeier May 30, 2022
d80c190
Add tests for implicit view
slumber May 31, 2022
21a381b
fix per_relay_parent pruning in backing
rphmeier May 31, 2022
47a9832
BEGIN STATEMENT DISTRIBUTION WORK
rphmeier May 31, 2022
b8f5282
mostly make network bridge amenable to vstaging
rphmeier May 31, 2022
843cb7b
network-bridge: fully adapt to vstaging
rphmeier May 31, 2022
89cf386
add some TODOs for tests
rphmeier May 31, 2022
a320e44
fix fallout in bitfield-distribution
rphmeier May 31, 2022
3cc56d1
add some test TODOs
rphmeier May 31, 2022
00f410d
fix fallout in gossip-support
rphmeier May 31, 2022
1a60a0c
fmt
rphmeier May 31, 2022
6f16adf
collator-protocol: fix message fallout
rphmeier May 31, 2022
7e46d8a
collator-protocol: load PVD from runtime
rphmeier May 31, 2022
86007fb
make things compile
rphmeier Jun 2, 2022
faf00f6
fmt
rphmeier Jun 2, 2022
f43c8f6
begin extracting view logic to separate module
rphmeier Jun 2, 2022
759e1d1
create deeper submodule and add per-peer knowledge
rphmeier Jun 2, 2022
51ca0ef
add ProspectiveParachainsMessage to statement-distribution
rphmeier Jun 2, 2022
778627b
make recv_runtime public
rphmeier Jun 2, 2022
df6f7c0
add ChainApiMessage to outgoing of statement-dist
rphmeier Jun 2, 2022
9af0013
begin new handle_active_leaves_update
rphmeier Jun 2, 2022
ce6e3d8
instantiate relay-parent-info without prospective data
rphmeier Jun 2, 2022
5bdb0ec
add staging-network feature to protocol
rphmeier Jun 5, 2022
8c9158a
rename to network-protocol staging
rphmeier Jun 5, 2022
dc6ee0d
refactor view to better accomodate both protcools
rphmeier Jun 5, 2022
a45cb24
begin fleshing out with_prospective
rphmeier Jun 5, 2022
d5e8e88
extract some tests to without_prospective; comment the rest
rphmeier Jun 5, 2022
3a095e6
begin high-level View API
rphmeier Jun 5, 2022
406d87d
fmt
rphmeier Jun 5, 2022
5c8e048
Merge branch 'rh-async-backing-feature' into rh-async-backing-integra…
slumber Jun 22, 2022
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
Prev Previous commit
Next Next commit
notify prospective parachains of seconded and backed candidates
  • Loading branch information
rphmeier committed May 28, 2022
commit 2f202d01c9dc490f8883c403682dcaab6ec19f6f
137 changes: 114 additions & 23 deletions node/core/backing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ where
}

struct PerRelayParentState {
mode: ProspectiveParachainsMode,
prospective_parachains_mode: ProspectiveParachainsMode,
/// The hash of the relay parent on top of which this job is doing it's work.
parent: Hash,
/// The session index this corresponds to.
Expand Down Expand Up @@ -1040,7 +1040,7 @@ async fn construct_per_relay_parent_state<Context>(
let assignment = assignment.map(|(a, _required_collator)| a);

Ok(Some(PerRelayParentState {
mode,
prospective_parachains_mode: mode,
parent,
session_index,
assignment,
Expand Down Expand Up @@ -1086,19 +1086,32 @@ async fn handle_validated_candidate_command<Context>(
});

// TODO [now]: if we get an Error::RejectedByProspectiveParachains,
// then the statement has not been distributed. In this case,
// we should expunge the candidate from the rp_state,
// then the statement has not been distributed. We need to handle this case

// TODO [now]: get this from changing `BackgroundValidationResult`.
let persisted_validation_data = unimplemented!();
if let Some(stmt) = sign_import_and_distribute_statement(
ctx,
rp_state,
&mut state.per_candidate,
statement,
persisted_validation_data,
state.keystore.clone(),
metrics,
)
.await?
{
// TODO [now]: note the candidate as seconded in the
// per-candidate state.
match state.per_candidate.get_mut(&candidate_hash) {
None => {
gum::warn!(
target: LOG_TARGET,
?candidate_hash,
"Missing `per_candidate` for seconded candidate.",
);
}
Some(p) => { p.seconded_locally = true }
}
// TODO [now]: update seconded depths in active leaves.
rp_state.issued_statements.insert(candidate_hash);

metrics.on_candidate_seconded();
Expand Down Expand Up @@ -1129,7 +1142,9 @@ async fn handle_validated_candidate_command<Context>(
sign_import_and_distribute_statement(
ctx,
rp_state,
&mut state.per_candidate,
statement,
None, // only needed when seconding.
state.keystore.clone(),
metrics,
)
Expand Down Expand Up @@ -1251,11 +1266,21 @@ async fn dispatch_new_statement_to_dispute_coordinator<Context>(
}

/// Import a statement into the statement table and return the summary of the import.
///
/// This will fail with `Error::RejectedByProspectiveParachains` if the message type
/// is seconded, the candidate is fresh,
/// and any of the following are true:
/// 1. There is no `PersistedValidationData` attached.
/// 2. Prospective parachains are enabled for the relay parent and the prospective parachains
/// subsystem returned an empty `FragmentTreeMembership`
/// i.e. did not recognize the candidate as being applicable to any of the active leaves.
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
async fn import_statement<Context>(
ctx: &mut Context,
rp_state: &mut PerRelayParentState,
per_candidate: &mut HashMap<CandidateHash, PerCandidateState>,
statement: &SignedFullStatement,
persisted_validation_data: Option<PersistedValidationData>,
) -> Result<Option<TableSummary>, Error> {
gum::debug!(
target: LOG_TARGET,
Expand All @@ -1266,6 +1291,65 @@ async fn import_statement<Context>(

let candidate_hash = statement.payload().candidate_hash();

// If this is a new candidate (statement is 'seconded' and candidate is unknown),
// 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
// If `ProspectiveParachainsMessage::Second` fails, then we return
// Error::RejectedByProspectiveParachains.
//
// Persisted Validation Data should be available - it may already be available
// if this is a candidate we are seconding.
//
// We should also not accept any candidates which have no valid depths under any of
// our active leaves.
if let Statement::Seconded(candidate) = statement.payload() {
if !per_candidate.contains_key(&candidate_hash) {
let pvd = match persisted_validation_data {
None => return Err(Error::RejectedByProspectiveParachains),
Some(pvd) => pvd,
};

per_candidate.insert(
candidate_hash,
PerCandidateState {
persisted_validation_data: pvd.clone(),
// This is set after importing when seconding locally.
seconded_locally: false,
para_id: candidate.descriptor().para_id,
relay_parent: candidate.descriptor().relay_parent,
},
);

if rp_state.prospective_parachains_mode.is_enabled() {
let (tx, rx) = oneshot::channel();
ctx.send_message(ProspectiveParachainsMessage::CandidateSeconded(
candidate.descriptor().para_id,
candidate.clone(),
pvd,
tx,
)).await;

match rx.await {
Err(oneshot::Canceled) => {
gum::warn!(
target: LOG_TARGET,
"Could not reach the Prospective Parachains subsystem."
);

return Err(Error::RejectedByProspectiveParachains);
}
Ok(membership) => {
if membership.is_empty() {
return Err(Error::RejectedByProspectiveParachains);
}
}
}
}
}
}

if let Err(ValidatorIndexOutOfBounds) =
dispatch_new_statement_to_dispute_coordinator(ctx, rp_state, candidate_hash, &statement)
.await
Expand Down Expand Up @@ -1293,31 +1377,26 @@ async fn import_statement<Context>(
.as_ref()
.and_then(|s| rp_state.table.attested_candidate(&s.candidate, &rp_state.table_context))
{
// TODO [now]
//
// If this is a new candidate, 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
// If `ProspectiveParachainsMessage::Second` fails, then we expunge the
// statement from the table and return an error, which should be handled
// to avoid distribution of the statement.

let candidate_hash = attested.candidate.hash();
// `HashSet::insert` returns true if the thing wasn't in there already.
if rp_state.backed.insert(candidate_hash) {
if let Some(backed) = table_attested_to_backed(attested, &rp_state.table_context) {
let para_id = backed.candidate.descriptor.para_id;
gum::debug!(
target: LOG_TARGET,
candidate_hash = ?candidate_hash,
relay_parent = ?rp_state.parent,
para_id = %backed.candidate.descriptor.para_id,
%para_id,
"Candidate backed",
);

// TODO [now]: inform the prospective parachains subsystem
// Inform the prospective parachains subsystem
// that the candidate is now backed.
if rp_state.prospective_parachains_mode.is_enabled() {
ctx.send_message(ProspectiveParachainsMessage::CandidateBacked(
para_id,
candidate_hash,
)).await;
}

// The provisioner waits on candidate-backing, which means
// that we need to send unbounded messages to avoid cycles.
Expand Down Expand Up @@ -1360,16 +1439,22 @@ fn issue_new_misbehaviors<Context>(
}
}

/// Sign, import, and distribute a statement.
///
/// If the statement is a `Seconded` statement, the `persisted_validation_data`
/// must be `Some`.
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
async fn sign_import_and_distribute_statement<Context>(
ctx: &mut Context,
rp_state: &mut PerRelayParentState,
per_candidate: &mut HashMap<CandidateHash, PerCandidateState>,
statement: Statement,
persisted_validation_data: Option<PersistedValidationData>,
keystore: SyncCryptoStorePtr,
metrics: &Metrics,
) -> Result<Option<SignedFullStatement>, Error> {
if let Some(signed_statement) = sign_statement(&*rp_state, statement, keystore, metrics).await {
import_statement(ctx, rp_state, &signed_statement).await?;
import_statement(ctx, rp_state, per_candidate, &signed_statement, persisted_validation_data).await?;

// TODO [now]: if we get an Error::RejectedByProspectiveParachains,
// we _do not_ distribute - it has been expunged.
Expand Down Expand Up @@ -1471,12 +1556,16 @@ async fn kick_off_validation_work<Context>(
}

/// Import the statement and kick off validation work if it is a part of our assignment.
///
/// If the statement type is `Seconded`, the `persisted_validation_data` must be
/// `Some`.
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
async fn maybe_validate_and_import<Context>(
ctx: &mut Context,
state: &mut State,
relay_parent: Hash,
statement: SignedFullStatement,
persisted_validation_data: Option<PersistedValidationData>,
metrics: &Metrics,
) -> Result<(), Error> {
let rp_state = match state.per_relay_parent.get_mut(&relay_parent) {
Expand All @@ -1494,7 +1583,7 @@ async fn maybe_validate_and_import<Context>(

// TODO [now]: if we get an Error::RejectedByProspectiveParachains,
// we will do nothing.
if let Some(summary) = import_statement(ctx, rp_state, &statement).await? {
if let Some(summary) = import_statement(ctx, rp_state, &mut state.per_candidate, &statement, persisted_validation_data).await? {
// import_statement already takes care of communicating with the
// prospective parachains subsystem. At this point, the candidate
// has already been accepted into the fragment trees.
Expand Down Expand Up @@ -1652,7 +1741,9 @@ async fn handle_statement_message<Context>(
) -> Result<(), Error> {
let _timer = metrics.time_process_statement();

match maybe_validate_and_import(ctx, state, relay_parent, statement, metrics).await {
// TODO [now]: get this from the message.
let persisted_validation_data: Option<PersistedValidationData> = unimplemented!();
match maybe_validate_and_import(ctx, state, relay_parent, statement, persisted_validation_data, metrics).await {
Err(Error::ValidationFailed(_)) => Ok(()),
Err(e) => Err(e),
Ok(()) => Ok(()),
Expand Down