mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-18 02:31:03 +00:00
Allow parachains to send messages (#274)
* Slots module * Integrate slots * More drafting * Minor updates * Update parachains to use trati * More build fixes * Full code now compiles * Add renew bid function * Implement calculate_winner * Warning remove * Update gitignore * Test framework * Tests * Further testing * More tests, new parameterisation. * Fix and new test * Thread-safe tests * Test off-boarding and a fix. * Test onboarding * Allow late onboarding. * Another test and fix * Avoid println in nostd * Compact representation of paraids * Introduce documentation. * Introduce events. * Additional test and fix * Additional test * Tidy up line lengths. * Remove printlns * Use later substrate utils. * Allow parachains to send messages. * Fix build/test * Make slots work with latest substrate * Update runtime/src/slot_range.rs Co-Authored-By: Robert Habermeier <rphmeier@gmail.com> * Update runtime/src/slots.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Update runtime/src/slots.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Polish logic * Rewind to earlier substrate master * Remove dead code. * Fix build * Update substrate ref to master * Update to new inherent digests API * address grumbles * fix * Fix a warning. * Reworded a comment. * Check that receipt matches expectations * Add test for final checks * Split out queuing logic. * Test final piece of queuing logic * Fix up docs. * More docs fixes
This commit is contained in:
@@ -21,13 +21,12 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use polkadot_primitives::{Block, Hash, BlockId, parachain::CollatorId};
|
||||
use polkadot_primitives::parachain::{Id as ParaId, Collation, Extrinsic, OutgoingMessage};
|
||||
use polkadot_primitives::parachain::{
|
||||
use polkadot_primitives::{Block, Hash, BlockId, parachain::CollatorId, parachain::{
|
||||
ConsolidatedIngress, ConsolidatedIngressRoots, CandidateReceipt, ParachainHost,
|
||||
};
|
||||
Id as ParaId, Collation, Extrinsic, OutgoingMessage, UpwardMessage
|
||||
}};
|
||||
use runtime_primitives::traits::ProvideRuntimeApi;
|
||||
use parachain::{wasm_executor::{self, ExternalitiesError}, MessageRef};
|
||||
use parachain::{wasm_executor::{self, ExternalitiesError}, MessageRef, UpwardMessageRef};
|
||||
use error_chain::bail;
|
||||
|
||||
use futures::prelude::*;
|
||||
@@ -190,6 +189,10 @@ error_chain! {
|
||||
description("Block data is too big."),
|
||||
display("Block data is too big (maximum allowed size: {}, actual size: {})", max_size, size),
|
||||
}
|
||||
UpwardMessagesInvalid(expected: Vec<UpwardMessage>, got: Vec<UpwardMessage>) {
|
||||
description("Parachain validation produced wrong relay-chain messages."),
|
||||
display("Parachain validation produced wrong relay-chain messages (expected: {:?}, got {:?})", expected, got),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,6 +278,7 @@ fn check_extrinsic(
|
||||
struct Externalities {
|
||||
parachain_index: ParaId,
|
||||
outgoing: Vec<OutgoingMessage>,
|
||||
upward: Vec<UpwardMessage>,
|
||||
}
|
||||
|
||||
impl wasm_executor::Externalities for Externalities {
|
||||
@@ -293,14 +297,35 @@ impl wasm_executor::Externalities for Externalities {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn post_upward_message(&mut self, message: UpwardMessageRef)
|
||||
-> Result<(), ExternalitiesError>
|
||||
{
|
||||
// TODO: https://github.com/paritytech/polkadot/issues/92
|
||||
// check per-message and per-byte fees for the parachain.
|
||||
self.upward.push(UpwardMessage {
|
||||
origin: message.origin,
|
||||
data: message.data.to_vec(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Externalities {
|
||||
// Performs final checks of validity, producing the extrinsic data.
|
||||
fn final_checks(
|
||||
self,
|
||||
candidate: &CandidateReceipt,
|
||||
) -> Result<Extrinsic, Error> {
|
||||
if &self.upward != &candidate.upward_messages {
|
||||
bail!(ErrorKind::UpwardMessagesInvalid(
|
||||
candidate.upward_messages.clone(),
|
||||
self.upward.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
check_extrinsic(
|
||||
self.outgoing,
|
||||
&candidate.egress_queue_roots[..],
|
||||
@@ -382,6 +407,7 @@ pub fn validate_collation<P>(
|
||||
let mut ext = Externalities {
|
||||
parachain_index: collation.receipt.parachain_index.clone(),
|
||||
outgoing: Vec::new(),
|
||||
upward: Vec::new(),
|
||||
};
|
||||
|
||||
match wasm_executor::validate_candidate(&validation_code, params, &mut ext) {
|
||||
@@ -403,6 +429,8 @@ pub fn validate_collation<P>(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use parachain::wasm_executor::Externalities as ExternalitiesTrait;
|
||||
use parachain::ParachainDispatchOrigin;
|
||||
use polkadot_primitives::parachain::{Statement::Candidate, CandidateReceipt, HeadData};
|
||||
|
||||
#[test]
|
||||
fn compute_and_check_egress() {
|
||||
@@ -453,9 +481,74 @@ mod tests {
|
||||
let mut ext = Externalities {
|
||||
parachain_index: 5.into(),
|
||||
outgoing: Vec::new(),
|
||||
upward: Vec::new(),
|
||||
};
|
||||
|
||||
assert!(ext.post_message(MessageRef { target: 1.into(), data: &[] }).is_ok());
|
||||
assert!(ext.post_message(MessageRef { target: 5.into(), data: &[] }).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ext_checks_upward_messages() {
|
||||
let ext = || Externalities {
|
||||
parachain_index: 5.into(),
|
||||
outgoing: Vec::new(),
|
||||
upward: vec![
|
||||
UpwardMessage{ data: vec![42], origin: ParachainDispatchOrigin::Parachain },
|
||||
],
|
||||
};
|
||||
let receipt = CandidateReceipt {
|
||||
parachain_index: 5.into(),
|
||||
collator: Default::default(),
|
||||
signature: Default::default(),
|
||||
head_data: HeadData(Vec::new()),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 0,
|
||||
block_data_hash: Default::default(),
|
||||
upward_messages: vec![
|
||||
UpwardMessage{ data: vec![42], origin: ParachainDispatchOrigin::Signed },
|
||||
UpwardMessage{ data: vec![69], origin: ParachainDispatchOrigin::Parachain },
|
||||
],
|
||||
};
|
||||
assert!(ext().final_checks(&receipt).is_err());
|
||||
let receipt = CandidateReceipt {
|
||||
parachain_index: 5.into(),
|
||||
collator: Default::default(),
|
||||
signature: Default::default(),
|
||||
head_data: HeadData(Vec::new()),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 0,
|
||||
block_data_hash: Default::default(),
|
||||
upward_messages: vec![
|
||||
UpwardMessage{ data: vec![42], origin: ParachainDispatchOrigin::Signed },
|
||||
],
|
||||
};
|
||||
assert!(ext().final_checks(&receipt).is_err());
|
||||
let receipt = CandidateReceipt {
|
||||
parachain_index: 5.into(),
|
||||
collator: Default::default(),
|
||||
signature: Default::default(),
|
||||
head_data: HeadData(Vec::new()),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 0,
|
||||
block_data_hash: Default::default(),
|
||||
upward_messages: vec![
|
||||
UpwardMessage{ data: vec![69], origin: ParachainDispatchOrigin::Parachain },
|
||||
],
|
||||
};
|
||||
assert!(ext().final_checks(&receipt).is_err());
|
||||
let receipt = CandidateReceipt {
|
||||
parachain_index: 5.into(),
|
||||
collator: Default::default(),
|
||||
signature: Default::default(),
|
||||
head_data: HeadData(Vec::new()),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 0,
|
||||
block_data_hash: Default::default(),
|
||||
upward_messages: vec![
|
||||
UpwardMessage{ data: vec![42], origin: ParachainDispatchOrigin::Parachain },
|
||||
],
|
||||
};
|
||||
assert!(ext().final_checks(&receipt).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ use polkadot_primitives::parachain::{
|
||||
Collation, PoVBlock,
|
||||
};
|
||||
use primitives::{Pair, ed25519};
|
||||
use runtime_primitives::{traits::{ProvideRuntimeApi, Header as HeaderT}, ApplyError};
|
||||
use runtime_primitives::{traits::{ProvideRuntimeApi, Header as HeaderT, Block as BlockT}, ApplyError};
|
||||
use tokio::runtime::TaskExecutor;
|
||||
use tokio::timer::{Delay, Interval};
|
||||
use transaction_pool::txpool::{Pool, ChainApi as PoolChainApi};
|
||||
@@ -570,7 +570,11 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
type Error = Error;
|
||||
type Create = Either<CreateProposal<C, TxApi>, future::FutureResult<Block, Error>>;
|
||||
|
||||
fn propose(&self, inherent_data: InherentData, max_duration: Duration) -> Self::Create {
|
||||
fn propose(&self,
|
||||
inherent_data: InherentData,
|
||||
_digest: <<Block as BlockT>::Header as HeaderT>::Digest,
|
||||
max_duration: Duration,
|
||||
) -> Self::Create {
|
||||
const ATTEMPT_PROPOSE_EVERY: Duration = Duration::from_millis(100);
|
||||
const SLOT_DURATION_DENOMINATOR: u64 = 3; // wait up to 1/3 of the slot for candidates.
|
||||
|
||||
@@ -712,7 +716,7 @@ impl<C, TxApi> CreateProposal<C, TxApi> where
|
||||
|
||||
let runtime_api = self.client.runtime_api();
|
||||
|
||||
let mut block_builder = BlockBuilder::at_block(&self.parent_id, &*self.client, false)?;
|
||||
let mut block_builder = BlockBuilder::at_block(&self.parent_id, &*self.client, false, Default::default())?;
|
||||
|
||||
{
|
||||
let inherents = runtime_api.inherent_extrinsics(&self.parent_id, inherent_data)?;
|
||||
|
||||
@@ -630,10 +630,10 @@ mod tests {
|
||||
collator: [1; 32].unchecked_into(),
|
||||
signature: Default::default(),
|
||||
head_data: ::polkadot_primitives::parachain::HeadData(vec![1, 2, 3, 4]),
|
||||
balance_uploads: Vec::new(),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 1_000_000,
|
||||
block_data_hash: [2; 32].into(),
|
||||
upward_messages: Vec::new(),
|
||||
};
|
||||
|
||||
let candidate_statement = GenericStatement::Candidate(candidate);
|
||||
@@ -684,10 +684,10 @@ mod tests {
|
||||
collator: [1; 32].unchecked_into(),
|
||||
signature: Default::default(),
|
||||
head_data: ::polkadot_primitives::parachain::HeadData(vec![1, 2, 3, 4]),
|
||||
balance_uploads: Vec::new(),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 1_000_000,
|
||||
block_data_hash: [2; 32].into(),
|
||||
upward_messages: Vec::new(),
|
||||
};
|
||||
|
||||
let candidate_statement = GenericStatement::Candidate(candidate);
|
||||
@@ -717,10 +717,10 @@ mod tests {
|
||||
collator: [1; 32].unchecked_into(),
|
||||
signature: Default::default(),
|
||||
head_data: ::polkadot_primitives::parachain::HeadData(vec![1, 2, 3, 4]),
|
||||
balance_uploads: Vec::new(),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 1_000_000,
|
||||
block_data_hash: [2; 32].into(),
|
||||
upward_messages: Vec::new(),
|
||||
};
|
||||
|
||||
let hash = candidate.hash();
|
||||
@@ -758,10 +758,10 @@ mod tests {
|
||||
collator: [1; 32].unchecked_into(),
|
||||
signature: Default::default(),
|
||||
head_data: ::polkadot_primitives::parachain::HeadData(vec![1, 2, 3, 4]),
|
||||
balance_uploads: Vec::new(),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 1_000_000,
|
||||
block_data_hash: [2; 32].into(),
|
||||
upward_messages: Vec::new(),
|
||||
};
|
||||
|
||||
let hash = candidate.hash();
|
||||
@@ -819,10 +819,10 @@ mod tests {
|
||||
collator: [1; 32].unchecked_into(),
|
||||
signature: Default::default(),
|
||||
head_data: ::polkadot_primitives::parachain::HeadData(vec![1, 2, 3, 4]),
|
||||
balance_uploads: Vec::new(),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 1_000_000,
|
||||
block_data_hash: [2; 32].into(),
|
||||
upward_messages: Vec::new(),
|
||||
};
|
||||
|
||||
let hash = candidate.hash();
|
||||
@@ -884,10 +884,10 @@ mod tests {
|
||||
collator: [1; 32].unchecked_into(),
|
||||
signature: Default::default(),
|
||||
head_data: ::polkadot_primitives::parachain::HeadData(vec![1, 2, 3, 4]),
|
||||
balance_uploads: Vec::new(),
|
||||
egress_queue_roots: Vec::new(),
|
||||
fees: 1_000_000,
|
||||
block_data_hash: [2; 32].into(),
|
||||
upward_messages: Vec::new(),
|
||||
};
|
||||
|
||||
let hash = candidate.hash();
|
||||
|
||||
Reference in New Issue
Block a user