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
Show all changes
27 commits
Select commit Hold shift + click to select a range
ab14b90
HRMP: Update the impl guide
pepyakin Oct 28, 2020
c318044
HRMP: Incorporate the channel notifications into the guide
pepyakin Sep 30, 2020
130accb
HRMP: Renaming in the impl guide
pepyakin Oct 28, 2020
e1e4eb0
HRMP: Constrain the maximum number of HRMP messages per candidate
pepyakin Oct 28, 2020
8ef66ec
XCM: Introduce HRMP related message types
pepyakin Sep 30, 2020
196c4a4
HRMP: Data structures and plumbing
pepyakin Sep 14, 2020
71bb7a6
HRMP: Configuration
pepyakin Sep 19, 2020
3dacd77
HRMP: Data layout
pepyakin Oct 6, 2020
6e7979b
HRMP: Acceptance & Enactment
pepyakin Sep 23, 2020
8363874
HRMP: Test base logic
pepyakin Nov 4, 2020
e6a84dc
Update adder collator
pepyakin Nov 2, 2020
19f01ac
HRMP: Runtime API for accessing inbound messages
pepyakin Nov 3, 2020
d61440b
HRMP: Add diagnostic logging in acceptance criteria
pepyakin Nov 3, 2020
71aa0bb
HRMP: Additional tests
pepyakin Nov 4, 2020
f4b03ce
Self-review fixes
pepyakin Nov 5, 2020
0fe6c9a
save test refactorings for the next time
pepyakin Nov 5, 2020
0dce9f8
Missed a return statement.
pepyakin Nov 5, 2020
3555327
a formatting blip
pepyakin Nov 5, 2020
af77075
Add missing logic for appending HRMP digests
pepyakin Nov 5, 2020
1b2368b
Remove the channel contents vectors which became empty
pepyakin Nov 5, 2020
02945d9
Tighten HRMP channel digests invariants.
pepyakin Nov 5, 2020
8448078
Apply suggestions from code review
pepyakin Nov 6, 2020
ee5078f
Remove a note about sorting for channel id
pepyakin Nov 6, 2020
37c1fdd
Add missing rustdocs to the configuration
pepyakin Nov 6, 2020
be1013c
Clarify and update the invariant for HrmpChannelDigests
pepyakin Nov 6, 2020
e546c3c
Make the onboarding invariant less sloppy
pepyakin Nov 6, 2020
9e6e3c2
Make `CandidateCheckContext` use T::BlockNumber for hrmp_watermark
pepyakin Nov 6, 2020
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
HRMP: Data structures and plumbing
  • Loading branch information
pepyakin committed Nov 5, 2020
commit 196c4a4bf247156a8e8b8d25e14b142696cddb34
19 changes: 19 additions & 0 deletions core-primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ pub struct InboundDownwardMessage<BlockNumber = crate::BlockNumber> {
pub msg: DownwardMessage,
}

/// An HRMP message seen from the perspective of a recipient.
#[derive(codec::Encode, codec::Decode, Clone, sp_runtime::RuntimeDebug, PartialEq)]
pub struct InboundHrmpMessage<BlockNumber = crate::BlockNumber> {
/// The block number at which this message was sent.
/// Specifically, it is the block number at which the candidate that sends this message was
/// enacted.
pub sent_at: BlockNumber,
/// The message payload.
pub data: sp_std::vec::Vec<u8>,
}

#[derive(codec::Encode, codec::Decode, Clone, sp_runtime::RuntimeDebug, PartialEq, Eq, Hash)]
pub struct OutboundHrmpMessage<Id> {
/// The para that will get this message in its downward message queue.
pub recipient: Id,
/// The message payload.
pub data: sp_std::vec::Vec<u8>,
}

/// V1 primitives.
pub mod v1 {
pub use super::*;
Expand Down
4 changes: 4 additions & 0 deletions node/collation-generation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,12 @@ async fn handle_new_activations<Context: SubsystemContext>(

let commitments = CandidateCommitments {
upward_messages: collation.upward_messages,
horizontal_messages: collation.horizontal_messages,
new_validation_code: collation.new_validation_code,
head_data: collation.head_data,
erasure_root,
processed_downward_messages: collation.processed_downward_messages,
hrmp_watermark: collation.hrmp_watermark,
};

let ccr = CandidateReceipt {
Expand Down Expand Up @@ -382,12 +384,14 @@ mod tests {
fn test_collation() -> Collation {
Collation {
upward_messages: Default::default(),
horizontal_messages: Default::default(),
new_validation_code: Default::default(),
head_data: Default::default(),
proof_of_validity: PoV {
block_data: BlockData(Vec::new()),
},
processed_downward_messages: Default::default(),
hrmp_watermark: Default::default(),
}
}

Expand Down
10 changes: 10 additions & 0 deletions node/core/backing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,10 +717,12 @@ impl CandidateBackingJob {

let commitments = CandidateCommitments {
upward_messages: outputs.upward_messages,
horizontal_messages: outputs.horizontal_messages,
erasure_root,
new_validation_code: outputs.new_validation_code,
head_data: outputs.head_data,
processed_downward_messages: outputs.processed_downward_messages,
hrmp_watermark: outputs.hrmp_watermark,
};

let res = match with_commitments(commitments) {
Expand Down Expand Up @@ -1200,9 +1202,11 @@ mod tests {
tx.send(Ok(
ValidationResult::Valid(ValidationOutputs {
head_data: expected_head_data.clone(),
horizontal_messages: Vec::new(),
upward_messages: Vec::new(),
new_validation_code: None,
processed_downward_messages: 0,
hrmp_watermark: 0,
}, test_state.validation_data.persisted),
)).unwrap();
}
Expand Down Expand Up @@ -1328,8 +1332,10 @@ mod tests {
ValidationResult::Valid(ValidationOutputs {
head_data: expected_head_data.clone(),
upward_messages: Vec::new(),
horizontal_messages: Vec::new(),
new_validation_code: None,
processed_downward_messages: 0,
hrmp_watermark: 0,
}, test_state.validation_data.persisted),
)).unwrap();
}
Expand Down Expand Up @@ -1477,8 +1483,10 @@ mod tests {
ValidationResult::Valid(ValidationOutputs {
head_data: expected_head_data.clone(),
upward_messages: Vec::new(),
horizontal_messages: Vec::new(),
new_validation_code: None,
processed_downward_messages: 0,
hrmp_watermark: 0,
}, test_state.validation_data.persisted),
)).unwrap();
}
Expand Down Expand Up @@ -1660,8 +1668,10 @@ mod tests {
ValidationResult::Valid(ValidationOutputs {
head_data: expected_head_data.clone(),
upward_messages: Vec::new(),
horizontal_messages: Vec::new(),
new_validation_code: None,
processed_downward_messages: 0,
hrmp_watermark: 0,
}, test_state.validation_data.persisted),
)).unwrap();
}
Expand Down
6 changes: 6 additions & 0 deletions node/core/candidate-validation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,10 @@ fn validate_candidate_exhaustive<B: ValidationBackend, S: SpawnNamed + 'static>(
let outputs = ValidationOutputs {
head_data: res.head_data,
upward_messages: res.upward_messages,
horizontal_messages: res.horizontal_messages,
new_validation_code: res.new_validation_code,
processed_downward_messages: res.processed_downward_messages,
hrmp_watermark: res.hrmp_watermark,
};
Ok(ValidationResult::Valid(outputs, persisted_validation_data))
}
Expand Down Expand Up @@ -833,7 +835,9 @@ mod tests {
head_data: HeadData(vec![1, 1, 1]),
new_validation_code: Some(vec![2, 2, 2].into()),
upward_messages: Vec::new(),
horizontal_messages: Vec::new(),
processed_downward_messages: 0,
hrmp_watermark: 0,
};

let v = validate_candidate_exhaustive::<MockValidationBackend, _>(
Expand All @@ -848,7 +852,9 @@ mod tests {
assert_matches!(v, ValidationResult::Valid(outputs, used_validation_data) => {
assert_eq!(outputs.head_data, HeadData(vec![1, 1, 1]));
assert_eq!(outputs.upward_messages, Vec::<UpwardMessage>::new());
assert_eq!(outputs.horizontal_messages, Vec::new());
assert_eq!(outputs.new_validation_code, Some(vec![2, 2, 2].into()));
assert_eq!(outputs.hrmp_watermark, 0);
assert_eq!(used_validation_data, validation_data);
});
}
Expand Down
8 changes: 6 additions & 2 deletions node/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use polkadot_primitives::v1::{
Hash, CommittedCandidateReceipt, CandidateReceipt, CompactStatement,
EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId,
UpwardMessage, ValidationCode, PersistedValidationData, ValidationData,
HeadData, PoV, CollatorPair, Id as ParaId, ValidationOutputs, CandidateHash,
HeadData, PoV, CollatorPair, Id as ParaId, OutboundHrmpMessage, ValidationOutputs, CandidateHash,
};
use polkadot_statement_table::{
generic::{
Expand Down Expand Up @@ -252,9 +252,11 @@ impl std::convert::TryFrom<FromTableMisbehavior> for MisbehaviorReport {
/// - does not contain the erasure root; that's computed at the Polkadot level, not at Cumulus
/// - contains a proof of validity.
#[derive(Clone, Encode, Decode)]
pub struct Collation {
pub struct Collation<BlockNumber = polkadot_primitives::v1::BlockNumber> {
/// Messages destined to be interpreted by the Relay chain itself.
pub upward_messages: Vec<UpwardMessage>,
/// The horizontal messages sent by the parachain.
pub horizontal_messages: Vec<OutboundHrmpMessage<ParaId>>,
/// New validation code.
pub new_validation_code: Option<ValidationCode>,
/// The head-data produced as a result of execution.
Expand All @@ -263,6 +265,8 @@ pub struct Collation {
pub proof_of_validity: PoV,
/// The number of messages processed from the DMQ.
pub processed_downward_messages: u32,
/// The mark which specifies the block number up to which all inbound HRMP messages are processed.
pub hrmp_watermark: BlockNumber,
}

/// Configuration for the collation generator
Expand Down
18 changes: 16 additions & 2 deletions parachain/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use serde::{Serialize, Deserialize};
#[cfg(feature = "std")]
use sp_core::bytes;

use polkadot_core_primitives::Hash;
use polkadot_core_primitives::{Hash, OutboundHrmpMessage};

/// Block number type used by the relay chain.
pub use polkadot_core_primitives::BlockNumber as RelayChainBlockNumber;
Expand Down Expand Up @@ -186,6 +186,16 @@ impl<T: Encode + Decode + Default> AccountIdConversion<T> for Id {
}
}

/// A type that uniquely identifies an HRMP channel. An HRMP channel is unidirectional
#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Hash))]
pub struct HrmpChannelId {
/// The para that acts as the sender in this channel.
pub sender: Id,
/// The para that acts as the recipient in this channel.
pub recipient: Id,
}

/// A message from a parachain to its Relay Chain.
pub type UpwardMessage = Vec<u8>;

Expand All @@ -212,7 +222,7 @@ pub struct ValidationParams {
}

/// The result of parachain validation.
// TODO: egress and balance uploads (https://github.com/paritytech/polkadot/issues/220)
// TODO: balance uploads (https://github.com/paritytech/polkadot/issues/220)
#[derive(PartialEq, Eq, Encode)]
#[cfg_attr(feature = "std", derive(Debug, Decode))]
pub struct ValidationResult {
Expand All @@ -222,8 +232,12 @@ pub struct ValidationResult {
pub new_validation_code: Option<ValidationCode>,
/// Upward messages send by the Parachain.
pub upward_messages: Vec<UpwardMessage>,
/// Outbound horizontal messages sent by the parachain.
pub horizontal_messages: Vec<OutboundHrmpMessage<Id>>,
/// Number of downward messages that were processed by the Parachain.
///
/// It is expected that the Parachain processes them from first to last.
pub processed_downward_messages: u32,
/// The mark which specifies the block number up to which all inbound HRMP messages are processed.
pub hrmp_watermark: RelayChainBlockNumber,
}
7 changes: 5 additions & 2 deletions parachain/test-parachains/adder/src/wasm_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
//! WASM validation for adder parachain.

use crate::{HeadData, BlockData};
use core::{intrinsics, panic};
use core::panic;
use sp_std::vec::Vec;
use parachain::primitives::{ValidationResult, HeadData as GenericHeadData};
use codec::{Encode, Decode};

#[no_mangle]
pub extern fn validate_block(params: *const u8, len: usize) -> u64 {
pub extern "C" fn validate_block(params: *const u8, len: usize) -> u64 {
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be preferred to have platform independent integer width length for len, since this is exported.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess, this won't harm, but note that this code is for wasm only and we assume that it's 32 bits only.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's just a beartrap in the woods, soon to be forgotten of its existence, and somebody will step into it eventually - it might not be a 🐻

Copy link
Contributor Author

Choose a reason for hiding this comment

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

let params = unsafe { parachain::load_params(params, len) };
let parent_head = HeadData::decode(&mut &params.parent_head.0[..])
.expect("invalid parent head format.");
Expand All @@ -38,7 +39,9 @@ pub extern fn validate_block(params: *const u8, len: usize) -> u64 {
head_data: GenericHeadData(new_head.encode()),
new_validation_code: None,
upward_messages: sp_std::vec::Vec::new(),
horizontal_messages: sp_std::vec::Vec::new(),
processed_downward_messages: 0,
hrmp_watermark: params.relay_chain_height,
}
)
}
18 changes: 13 additions & 5 deletions primitives/src/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT};

// Export some core primitives.
pub use polkadot_core_primitives::v1::{
BlockNumber, Moment, Signature, AccountPublic, AccountId, AccountIndex,
ChainId, Hash, Nonce, Balance, Header, Block, BlockId, UncheckedExtrinsic,
Remark, DownwardMessage, InboundDownwardMessage, CandidateHash,
BlockNumber, Moment, Signature, AccountPublic, AccountId, AccountIndex, ChainId, Hash, Nonce,
Balance, Header, Block, BlockId, UncheckedExtrinsic, Remark, DownwardMessage,
InboundDownwardMessage, CandidateHash, InboundHrmpMessage, OutboundHrmpMessage,
};

// Export some polkadot-parachain primitives
pub use polkadot_parachain::primitives::{
Id, LOWEST_USER_ID, UpwardMessage, HeadData, BlockData, ValidationCode,
Id, LOWEST_USER_ID, HrmpChannelId, UpwardMessage, HeadData, BlockData, ValidationCode,
};

// Export some basic parachain primitives from v0.
Expand Down Expand Up @@ -317,18 +317,24 @@ pub struct ValidationOutputs {
pub head_data: HeadData,
/// Upward messages to the relay chain.
pub upward_messages: Vec<UpwardMessage>,
/// The horizontal messages sent by the parachain.
pub horizontal_messages: Vec<OutboundHrmpMessage<Id>>,
/// The new validation code submitted by the execution, if any.
pub new_validation_code: Option<ValidationCode>,
/// The number of messages processed from the DMQ.
pub processed_downward_messages: u32,
/// The mark which specifies the block number up to which all inbound HRMP messages are processed.
pub hrmp_watermark: BlockNumber,
}

/// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Default, Hash))]
pub struct CandidateCommitments {
pub struct CandidateCommitments<N = BlockNumber> {
/// Messages destined to be interpreted by the Relay chain itself.
pub upward_messages: Vec<UpwardMessage>,
/// Horizontal messages sent by the parachain.
pub horizontal_messages: Vec<OutboundHrmpMessage<Id>>,
/// The root of a block's erasure encoding Merkle tree.
pub erasure_root: Hash,
/// New validation code.
Expand All @@ -337,6 +343,8 @@ pub struct CandidateCommitments {
pub head_data: HeadData,
/// The number of messages processed from the DMQ.
pub processed_downward_messages: u32,
/// The mark which specifies the block number up to which all inbound HRMP messages are processed.
pub hrmp_watermark: N,
}

impl CandidateCommitments {
Expand Down