mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 03:31:10 +00:00
Downward Message Processing implementation (#1859)
* DMP: data structures and plumbing * DMP: Implement DMP logic in the router module DMP: Integrate DMP parts into the inclusion module * DMP: Introduce the max size limit for the size of a downward message * DMP: Runtime API for accessing inbound messages * OCD Small clean ups * DMP: fix the naming of the error * DMP: add caution about a non-existent recipient
This commit is contained in:
@@ -277,6 +277,7 @@ async fn handle_new_activations<Context: SubsystemContext>(
|
||||
new_validation_code: collation.new_validation_code,
|
||||
head_data: collation.head_data,
|
||||
erasure_root,
|
||||
processed_downward_messages: collation.processed_downward_messages,
|
||||
};
|
||||
|
||||
let ccr = CandidateReceipt {
|
||||
@@ -387,6 +388,7 @@ mod tests {
|
||||
proof_of_validity: PoV {
|
||||
block_data: BlockData(Vec::new()),
|
||||
},
|
||||
processed_downward_messages: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ impl Default for TestState {
|
||||
parent_head: HeadData(vec![7, 8, 9]),
|
||||
block_number: 5,
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
};
|
||||
|
||||
let pruning_config = PruningConfig {
|
||||
|
||||
@@ -682,6 +682,7 @@ impl CandidateBackingJob {
|
||||
erasure_root,
|
||||
new_validation_code: outputs.new_validation_code,
|
||||
head_data: outputs.head_data,
|
||||
processed_downward_messages: outputs.processed_downward_messages,
|
||||
};
|
||||
|
||||
let res = match with_commitments(commitments) {
|
||||
@@ -977,12 +978,14 @@ mod tests {
|
||||
parent_head: HeadData(vec![7, 8, 9]),
|
||||
block_number: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
},
|
||||
transient: TransientValidationData {
|
||||
max_code_size: 1000,
|
||||
max_head_data_size: 1000,
|
||||
balance: Default::default(),
|
||||
code_upgrade_allowed: None,
|
||||
dmq_length: 0,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1159,6 +1162,7 @@ mod tests {
|
||||
upward_messages: Vec::new(),
|
||||
fees: Default::default(),
|
||||
new_validation_code: None,
|
||||
processed_downward_messages: 0,
|
||||
}, test_state.validation_data.persisted),
|
||||
)).unwrap();
|
||||
}
|
||||
@@ -1278,6 +1282,7 @@ mod tests {
|
||||
upward_messages: Vec::new(),
|
||||
fees: Default::default(),
|
||||
new_validation_code: None,
|
||||
processed_downward_messages: 0,
|
||||
}, test_state.validation_data.persisted),
|
||||
)).unwrap();
|
||||
}
|
||||
@@ -1416,6 +1421,7 @@ mod tests {
|
||||
upward_messages: Vec::new(),
|
||||
fees: Default::default(),
|
||||
new_validation_code: None,
|
||||
processed_downward_messages: 0,
|
||||
}, test_state.validation_data.persisted),
|
||||
)).unwrap();
|
||||
}
|
||||
@@ -1571,6 +1577,7 @@ mod tests {
|
||||
upward_messages: Vec::new(),
|
||||
fees: Default::default(),
|
||||
new_validation_code: None,
|
||||
processed_downward_messages: 0,
|
||||
}, test_state.validation_data.persisted),
|
||||
)).unwrap();
|
||||
}
|
||||
|
||||
@@ -494,11 +494,13 @@ mod tests {
|
||||
upward_messages: Vec::new(),
|
||||
fees: 0,
|
||||
new_validation_code: None,
|
||||
processed_downward_messages: 0,
|
||||
},
|
||||
PersistedValidationData {
|
||||
parent_head: HeadData(parent_head_data),
|
||||
block_number: 123,
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -468,6 +468,7 @@ fn validate_candidate_exhaustive<B: ValidationBackend, S: SpawnNamed + 'static>(
|
||||
parent_head: persisted_validation_data.parent_head.clone(),
|
||||
block_data: pov.block_data.clone(),
|
||||
relay_chain_height: persisted_validation_data.block_number,
|
||||
dmq_mqc_head: persisted_validation_data.dmq_mqc_head,
|
||||
hrmp_mqc_heads: persisted_validation_data.hrmp_mqc_heads.clone(),
|
||||
};
|
||||
|
||||
@@ -491,6 +492,7 @@ fn validate_candidate_exhaustive<B: ValidationBackend, S: SpawnNamed + 'static>(
|
||||
upward_messages: res.upward_messages,
|
||||
fees: 0,
|
||||
new_validation_code: res.new_validation_code,
|
||||
processed_downward_messages: res.processed_downward_messages,
|
||||
};
|
||||
Ok(ValidationResult::Valid(outputs, persisted_validation_data))
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@ fn make_runtime_api_request<Client>(
|
||||
query!(candidate_pending_availability(para), sender),
|
||||
Request::CandidateEvents(sender) => query!(candidate_events(), sender),
|
||||
Request::ValidatorDiscovery(ids, sender) => query!(validator_discovery(ids), sender),
|
||||
Request::DmqContents(id, sender) => query!(dmq_contents(id), sender),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +177,7 @@ mod tests {
|
||||
use polkadot_primitives::v1::{
|
||||
ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, PersistedValidationData,
|
||||
Id as ParaId, OccupiedCoreAssumption, ValidationData, SessionIndex, ValidationCode,
|
||||
CommittedCandidateReceipt, CandidateEvent, AuthorityDiscoveryId,
|
||||
CommittedCandidateReceipt, CandidateEvent, AuthorityDiscoveryId, InboundDownwardMessage,
|
||||
};
|
||||
use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||
use sp_core::testing::TaskExecutor;
|
||||
@@ -195,6 +196,7 @@ mod tests {
|
||||
validation_outputs_results: HashMap<ParaId, bool>,
|
||||
candidate_pending_availability: HashMap<ParaId, CommittedCandidateReceipt>,
|
||||
candidate_events: Vec<CandidateEvent>,
|
||||
dmq_contents: HashMap<ParaId, Vec<InboundDownwardMessage>>,
|
||||
}
|
||||
|
||||
impl ProvideRuntimeApi<Block> for MockRuntimeApi {
|
||||
@@ -283,6 +285,13 @@ mod tests {
|
||||
fn validator_discovery(ids: Vec<ValidatorId>) -> Vec<Option<AuthorityDiscoveryId>> {
|
||||
vec![None; ids.len()]
|
||||
}
|
||||
|
||||
fn dmq_contents(
|
||||
&self,
|
||||
recipient: ParaId,
|
||||
) -> Vec<polkadot_primitives::v1::InboundDownwardMessage> {
|
||||
self.dmq_contents.get(&recipient).map(|q| q.clone()).unwrap_or_default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,4 +628,54 @@ mod tests {
|
||||
|
||||
futures::executor::block_on(future::join(subsystem_task, test_task));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn requests_dmq_contents() {
|
||||
let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new());
|
||||
let mut runtime_api = MockRuntimeApi::default();
|
||||
let relay_parent = [1; 32].into();
|
||||
let para_a = 5.into();
|
||||
let para_b = 6.into();
|
||||
|
||||
runtime_api.dmq_contents.insert(para_a, vec![]);
|
||||
runtime_api.dmq_contents.insert(
|
||||
para_b,
|
||||
vec![InboundDownwardMessage {
|
||||
sent_at: 228,
|
||||
msg: b"Novus Ordo Seclorum".to_vec(),
|
||||
}],
|
||||
);
|
||||
|
||||
let subsystem = RuntimeApiSubsystem::new(runtime_api.clone(), Metrics(None));
|
||||
let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap());
|
||||
let test_task = async move {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
ctx_handle
|
||||
.send(FromOverseer::Communication {
|
||||
msg: RuntimeApiMessage::Request(relay_parent, Request::DmqContents(para_a, tx)),
|
||||
})
|
||||
.await;
|
||||
assert_eq!(rx.await.unwrap().unwrap(), vec![]);
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
ctx_handle
|
||||
.send(FromOverseer::Communication {
|
||||
msg: RuntimeApiMessage::Request(relay_parent, Request::DmqContents(para_b, tx)),
|
||||
})
|
||||
.await;
|
||||
assert_eq!(
|
||||
rx.await.unwrap().unwrap(),
|
||||
vec![InboundDownwardMessage {
|
||||
sent_at: 228,
|
||||
msg: b"Novus Ordo Seclorum".to_vec(),
|
||||
}]
|
||||
);
|
||||
|
||||
ctx_handle
|
||||
.send(FromOverseer::Signal(OverseerSignal::Conclude))
|
||||
.await;
|
||||
};
|
||||
futures::executor::block_on(future::join(subsystem_task, test_task));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -217,6 +217,7 @@ impl Default for TestState {
|
||||
parent_head: HeadData(vec![7, 8, 9]),
|
||||
block_number: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
};
|
||||
|
||||
let validator_index = Some((validators.len() - 1) as ValidatorIndex);
|
||||
|
||||
@@ -263,6 +263,8 @@ pub struct Collation {
|
||||
pub head_data: HeadData,
|
||||
/// Proof to verify the state transition of the parachain.
|
||||
pub proof_of_validity: PoV,
|
||||
/// The number of messages processed from the DMQ.
|
||||
pub processed_downward_messages: u32,
|
||||
}
|
||||
|
||||
/// Configuration for the collation generator
|
||||
|
||||
@@ -37,7 +37,7 @@ use polkadot_primitives::v1::{
|
||||
GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption,
|
||||
PersistedValidationData, PoV, SessionIndex, SignedAvailabilityBitfield,
|
||||
ValidationCode, ValidatorId, ValidationData,
|
||||
ValidatorIndex, ValidatorSignature,
|
||||
ValidatorIndex, ValidatorSignature, InboundDownwardMessage,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -419,7 +419,11 @@ pub enum RuntimeApiRequest {
|
||||
/// Get the validation code for a para, taking the given `OccupiedCoreAssumption`, which
|
||||
/// will inform on how the validation data should be computed if the para currently
|
||||
/// occupies a core.
|
||||
ValidationCode(ParaId, OccupiedCoreAssumption, RuntimeApiSender<Option<ValidationCode>>),
|
||||
ValidationCode(
|
||||
ParaId,
|
||||
OccupiedCoreAssumption,
|
||||
RuntimeApiSender<Option<ValidationCode>>,
|
||||
),
|
||||
/// Get a the candidate pending availability for a particular parachain by parachain / core index
|
||||
CandidatePendingAvailability(ParaId, RuntimeApiSender<Option<CommittedCandidateReceipt>>),
|
||||
/// Get all events concerning candidates (backing, inclusion, time-out) in the parent of
|
||||
@@ -429,7 +433,15 @@ pub enum RuntimeApiRequest {
|
||||
/// Currently this request is limited to validators in the current session.
|
||||
///
|
||||
/// Returns `None` for validators not found in the current session.
|
||||
ValidatorDiscovery(Vec<ValidatorId>, RuntimeApiSender<Vec<Option<AuthorityDiscoveryId>>>),
|
||||
ValidatorDiscovery(
|
||||
Vec<ValidatorId>,
|
||||
RuntimeApiSender<Vec<Option<AuthorityDiscoveryId>>>,
|
||||
),
|
||||
/// Get all the pending inbound messages in the downward message queue for a para.
|
||||
DmqContents(
|
||||
ParaId,
|
||||
RuntimeApiSender<Vec<InboundDownwardMessage<BlockNumber>>>,
|
||||
),
|
||||
}
|
||||
|
||||
/// A message to the Runtime API subsystem.
|
||||
|
||||
Reference in New Issue
Block a user