mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-18 23:25:40 +00:00
Use a BoundedVec in ValidationResult (#6603)
* Use a `BoundedVec` in `ValidationResult` > Use a `BoundedVec` for `upward_messages` and `horizontal_messages` in order to > limit the number of individual messages/memory allocations right at decoding > time. The reason for this is that the `ValidationResult` may contain a code > upgrade (including a full PVF binary), so the total size limit can't be set > too low and this limit will still allow several millions of upward messages, > which will (due to the memory allocator overhead) already have a > non-negligible memory footprint in decoded form. * List all fields when hashing so we don't miss one * Define types for `BoundedVec`s of messages * Fix test compile errors * Depend on `bounded-collections` 0.1.4 (fixes allocation issue) * Fix compilation issue * Derive `Hash` instead of manual `impl` * Avoid use of unwrap
This commit is contained in:
Generated
+5
-2
@@ -662,9 +662,9 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bounded-collections"
|
name = "bounded-collections"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de2aff4807e40f478132150d80b031f2461d88f061851afcab537d7600c24120"
|
checksum = "a071c348a5ef6da1d3a87166b408170b46002382b1dda83992b5c2208cefb370"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
@@ -7162,6 +7162,7 @@ dependencies = [
|
|||||||
"sp-core",
|
"sp-core",
|
||||||
"sp-keystore",
|
"sp-keystore",
|
||||||
"sp-maybe-compressed-blob",
|
"sp-maybe-compressed-blob",
|
||||||
|
"sp-runtime",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
@@ -7286,6 +7287,7 @@ dependencies = [
|
|||||||
name = "polkadot-parachain"
|
name = "polkadot-parachain"
|
||||||
version = "0.9.37"
|
version = "0.9.37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bounded-collections",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"frame-support",
|
"frame-support",
|
||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
@@ -7576,6 +7578,7 @@ dependencies = [
|
|||||||
"pallet-timestamp",
|
"pallet-timestamp",
|
||||||
"pallet-vesting",
|
"pallet-vesting",
|
||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
|
"polkadot-parachain",
|
||||||
"polkadot-primitives",
|
"polkadot-primitives",
|
||||||
"polkadot-primitives-test-helpers",
|
"polkadot-primitives-test-helpers",
|
||||||
"polkadot-runtime-metrics",
|
"polkadot-runtime-metrics",
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ mod handle_new_activations {
|
|||||||
|
|
||||||
fn test_collation() -> Collation {
|
fn test_collation() -> Collation {
|
||||||
Collation {
|
Collation {
|
||||||
upward_messages: vec![],
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: vec![],
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
head_data: dummy_head_data(),
|
head_data: dummy_head_data(),
|
||||||
proof_of_validity: MaybeCompressedPoV::Raw(PoV { block_data: BlockData(Vec::new()) }),
|
proof_of_validity: MaybeCompressedPoV::Raw(PoV { block_data: BlockData(Vec::new()) }),
|
||||||
|
|||||||
@@ -202,8 +202,8 @@ impl TestCandidateBuilder {
|
|||||||
},
|
},
|
||||||
commitments: CandidateCommitments {
|
commitments: CandidateCommitments {
|
||||||
head_data: self.head_data,
|
head_data: self.head_data,
|
||||||
upward_messages: vec![],
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: vec![],
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0_u32,
|
hrmp_watermark: 0_u32,
|
||||||
@@ -311,8 +311,8 @@ fn backing_second_works() {
|
|||||||
tx.send(Ok(
|
tx.send(Ok(
|
||||||
ValidationResult::Valid(CandidateCommitments {
|
ValidationResult::Valid(CandidateCommitments {
|
||||||
head_data: expected_head_data.clone(),
|
head_data: expected_head_data.clone(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
@@ -457,8 +457,8 @@ fn backing_works() {
|
|||||||
tx.send(Ok(
|
tx.send(Ok(
|
||||||
ValidationResult::Valid(CandidateCommitments {
|
ValidationResult::Valid(CandidateCommitments {
|
||||||
head_data: expected_head_data.clone(),
|
head_data: expected_head_data.clone(),
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
@@ -781,8 +781,8 @@ fn backing_misbehavior_works() {
|
|||||||
tx.send(Ok(
|
tx.send(Ok(
|
||||||
ValidationResult::Valid(CandidateCommitments {
|
ValidationResult::Valid(CandidateCommitments {
|
||||||
head_data: expected_head_data.clone(),
|
head_data: expected_head_data.clone(),
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
@@ -954,8 +954,8 @@ fn backing_dont_second_invalid() {
|
|||||||
tx.send(Ok(
|
tx.send(Ok(
|
||||||
ValidationResult::Valid(CandidateCommitments {
|
ValidationResult::Valid(CandidateCommitments {
|
||||||
head_data: expected_head_data.clone(),
|
head_data: expected_head_data.clone(),
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
|
|||||||
@@ -446,8 +446,8 @@ fn candidate_validation_ok_is_ok() {
|
|||||||
let validation_result = WasmValidationResult {
|
let validation_result = WasmValidationResult {
|
||||||
head_data,
|
head_data,
|
||||||
new_validation_code: Some(vec![2, 2, 2].into()),
|
new_validation_code: Some(vec![2, 2, 2].into()),
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
};
|
};
|
||||||
@@ -573,8 +573,8 @@ fn candidate_validation_one_ambiguous_error_is_valid() {
|
|||||||
let validation_result = WasmValidationResult {
|
let validation_result = WasmValidationResult {
|
||||||
head_data,
|
head_data,
|
||||||
new_validation_code: Some(vec![2, 2, 2].into()),
|
new_validation_code: Some(vec![2, 2, 2].into()),
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
};
|
};
|
||||||
@@ -751,8 +751,8 @@ fn candidate_validation_commitment_hash_mismatch_is_invalid() {
|
|||||||
let validation_result = WasmValidationResult {
|
let validation_result = WasmValidationResult {
|
||||||
head_data,
|
head_data,
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 12345,
|
hrmp_watermark: 12345,
|
||||||
};
|
};
|
||||||
@@ -854,8 +854,8 @@ fn compressed_code_works() {
|
|||||||
let validation_result = WasmValidationResult {
|
let validation_result = WasmValidationResult {
|
||||||
head_data,
|
head_data,
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
};
|
};
|
||||||
@@ -918,8 +918,8 @@ fn code_decompression_failure_is_error() {
|
|||||||
let validation_result = WasmValidationResult {
|
let validation_result = WasmValidationResult {
|
||||||
head_data,
|
head_data,
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
};
|
};
|
||||||
@@ -971,8 +971,8 @@ fn pov_decompression_failure_is_invalid() {
|
|||||||
let validation_result = WasmValidationResult {
|
let validation_result = WasmValidationResult {
|
||||||
head_data,
|
head_data,
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0,
|
hrmp_watermark: 0,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -163,8 +163,8 @@ pub fn create_fake_candidate_commitments(
|
|||||||
persisted_validation_data: &PersistedValidationData,
|
persisted_validation_data: &PersistedValidationData,
|
||||||
) -> CandidateCommitments {
|
) -> CandidateCommitments {
|
||||||
CandidateCommitments {
|
CandidateCommitments {
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
head_data: persisted_validation_data.parent_head.clone(),
|
head_data: persisted_validation_data.parent_head.clone(),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ sp-consensus-vrf = { git = "https://github.com/paritytech/substrate", branch = "
|
|||||||
sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
polkadot-parachain = { path = "../../parachain", default-features = false }
|
polkadot-parachain = { path = "../../parachain", default-features = false }
|
||||||
schnorrkel = "0.9.1"
|
schnorrkel = "0.9.1"
|
||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
|||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
BlakeTwo256, BlockNumber, CandidateCommitments, CandidateHash, CollatorPair,
|
BlakeTwo256, BlockNumber, CandidateCommitments, CandidateHash, CollatorPair,
|
||||||
CommittedCandidateReceipt, CompactStatement, EncodeAs, Hash, HashT, HeadData, Id as ParaId,
|
CommittedCandidateReceipt, CompactStatement, EncodeAs, Hash, HashT, HeadData, Id as ParaId,
|
||||||
OutboundHrmpMessage, PersistedValidationData, SessionIndex, Signed, UncheckedSigned,
|
PersistedValidationData, SessionIndex, Signed, UncheckedSigned, ValidationCode, ValidatorIndex,
|
||||||
UpwardMessage, ValidationCode, ValidatorIndex, MAX_CODE_SIZE, MAX_POV_SIZE,
|
MAX_CODE_SIZE, MAX_POV_SIZE,
|
||||||
};
|
};
|
||||||
pub use sp_consensus_babe::{
|
pub use sp_consensus_babe::{
|
||||||
AllowedSlots as BabeAllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch,
|
AllowedSlots as BabeAllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use polkadot_parachain::primitives::BlockData;
|
pub use polkadot_parachain::primitives::{BlockData, HorizontalMessages, UpwardMessages};
|
||||||
|
|
||||||
pub mod approval;
|
pub mod approval;
|
||||||
|
|
||||||
@@ -312,9 +312,9 @@ impl MaybeCompressedPoV {
|
|||||||
#[cfg(not(target_os = "unknown"))]
|
#[cfg(not(target_os = "unknown"))]
|
||||||
pub struct Collation<BlockNumber = polkadot_primitives::BlockNumber> {
|
pub struct Collation<BlockNumber = polkadot_primitives::BlockNumber> {
|
||||||
/// Messages destined to be interpreted by the Relay chain itself.
|
/// Messages destined to be interpreted by the Relay chain itself.
|
||||||
pub upward_messages: Vec<UpwardMessage>,
|
pub upward_messages: UpwardMessages,
|
||||||
/// The horizontal messages sent by the parachain.
|
/// The horizontal messages sent by the parachain.
|
||||||
pub horizontal_messages: Vec<OutboundHrmpMessage<ParaId>>,
|
pub horizontal_messages: HorizontalMessages,
|
||||||
/// New validation code.
|
/// New validation code.
|
||||||
pub new_validation_code: Option<ValidationCode>,
|
pub new_validation_code: Option<ValidationCode>,
|
||||||
/// The head-data produced as a result of execution.
|
/// The head-data produced as a result of execution.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ sp-core = { git = "https://github.com/paritytech/substrate", branch = "master",
|
|||||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
polkadot-core-primitives = { path = "../core-primitives", default-features = false }
|
polkadot-core-primitives = { path = "../core-primitives", default-features = false }
|
||||||
derive_more = "0.99.11"
|
derive_more = "0.99.11"
|
||||||
|
bounded-collections = { version = "0.1.5", default-features = false }
|
||||||
|
|
||||||
# all optional crates.
|
# all optional crates.
|
||||||
serde = { version = "1.0.137", default-features = false, features = [ "derive" ], optional = true }
|
serde = { version = "1.0.137", default-features = false, features = [ "derive" ], optional = true }
|
||||||
@@ -25,6 +26,7 @@ serde = { version = "1.0.137", default-features = false, features = [ "derive" ]
|
|||||||
default = ["std"]
|
default = ["std"]
|
||||||
wasm-api = []
|
wasm-api = []
|
||||||
std = [
|
std = [
|
||||||
|
"bounded-collections/std",
|
||||||
"parity-scale-codec/std",
|
"parity-scale-codec/std",
|
||||||
"scale-info/std",
|
"scale-info/std",
|
||||||
"serde/std",
|
"serde/std",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
use sp_std::vec::Vec;
|
use sp_std::vec::Vec;
|
||||||
|
|
||||||
|
use bounded_collections::{BoundedVec, ConstU32};
|
||||||
use frame_support::weights::Weight;
|
use frame_support::weights::Weight;
|
||||||
use parity_scale_codec::{CompactAs, Decode, Encode, MaxEncodedLen};
|
use parity_scale_codec::{CompactAs, Decode, Encode, MaxEncodedLen};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
@@ -361,6 +362,22 @@ pub struct ValidationParams {
|
|||||||
pub relay_parent_storage_root: Hash,
|
pub relay_parent_storage_root: Hash,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Maximum number of HRMP messages allowed per candidate.
|
||||||
|
///
|
||||||
|
/// We also use this as a generous limit, which still prevents possible memory exhaustion, from
|
||||||
|
/// malicious parachains that may otherwise return a huge amount of messages in `ValidationResult`.
|
||||||
|
pub const MAX_HORIZONTAL_MESSAGE_NUM: u32 = 16 * 1024;
|
||||||
|
/// Maximum number of UMP messages allowed per candidate.
|
||||||
|
///
|
||||||
|
/// We also use this as a generous limit, which still prevents possible memory exhaustion, from
|
||||||
|
/// malicious parachains that may otherwise return a huge amount of messages in `ValidationResult`.
|
||||||
|
pub const MAX_UPWARD_MESSAGE_NUM: u32 = 16 * 1024;
|
||||||
|
|
||||||
|
pub type UpwardMessages = BoundedVec<UpwardMessage, ConstU32<MAX_UPWARD_MESSAGE_NUM>>;
|
||||||
|
|
||||||
|
pub type HorizontalMessages =
|
||||||
|
BoundedVec<OutboundHrmpMessage<Id>, ConstU32<MAX_HORIZONTAL_MESSAGE_NUM>>;
|
||||||
|
|
||||||
/// The result of parachain validation.
|
/// The result of parachain validation.
|
||||||
// TODO: balance uploads (https://github.com/paritytech/polkadot/issues/220)
|
// TODO: balance uploads (https://github.com/paritytech/polkadot/issues/220)
|
||||||
#[derive(PartialEq, Eq, Clone, Encode)]
|
#[derive(PartialEq, Eq, Clone, Encode)]
|
||||||
@@ -371,9 +388,9 @@ pub struct ValidationResult {
|
|||||||
/// An update to the validation code that should be scheduled in the relay chain.
|
/// An update to the validation code that should be scheduled in the relay chain.
|
||||||
pub new_validation_code: Option<ValidationCode>,
|
pub new_validation_code: Option<ValidationCode>,
|
||||||
/// Upward messages send by the Parachain.
|
/// Upward messages send by the Parachain.
|
||||||
pub upward_messages: Vec<UpwardMessage>,
|
pub upward_messages: UpwardMessages,
|
||||||
/// Outbound horizontal messages sent by the parachain.
|
/// Outbound horizontal messages sent by the parachain.
|
||||||
pub horizontal_messages: Vec<OutboundHrmpMessage<Id>>,
|
pub horizontal_messages: HorizontalMessages,
|
||||||
/// Number of downward messages that were processed by the Parachain.
|
/// Number of downward messages that were processed by the Parachain.
|
||||||
///
|
///
|
||||||
/// It is expected that the Parachain processes them from first to last.
|
/// It is expected that the Parachain processes them from first to last.
|
||||||
|
|||||||
@@ -172,8 +172,8 @@ impl Collator {
|
|||||||
let pov = PoV { block_data: block_data.encode().into() };
|
let pov = PoV { block_data: block_data.encode().into() };
|
||||||
|
|
||||||
let collation = Collation {
|
let collation = Collation {
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
head_data: head_data.encode().into(),
|
head_data: head_data.encode().into(),
|
||||||
proof_of_validity: MaybeCompressedPoV::Raw(pov.clone()),
|
proof_of_validity: MaybeCompressedPoV::Raw(pov.clone()),
|
||||||
|
|||||||
@@ -37,8 +37,10 @@ pub extern "C" fn validate_block(params: *const u8, len: usize) -> u64 {
|
|||||||
parachain::write_result(&ValidationResult {
|
parachain::write_result(&ValidationResult {
|
||||||
head_data: GenericHeadData(new_head.encode()),
|
head_data: GenericHeadData(new_head.encode()),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
upward_messages: sp_std::vec::Vec::new(),
|
upward_messages: sp_std::vec::Vec::new().try_into().expect("empty vec fits into bounds"),
|
||||||
horizontal_messages: sp_std::vec::Vec::new(),
|
horizontal_messages: sp_std::vec::Vec::new()
|
||||||
|
.try_into()
|
||||||
|
.expect("empty vec fits into bounds"),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: params.relay_parent_number,
|
hrmp_watermark: params.relay_parent_number,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -247,8 +247,8 @@ impl Collator {
|
|||||||
let pov = PoV { block_data: block_data.encode().into() };
|
let pov = PoV { block_data: block_data.encode().into() };
|
||||||
|
|
||||||
let collation = Collation {
|
let collation = Collation {
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
head_data: head_data.encode().into(),
|
head_data: head_data.encode().into(),
|
||||||
proof_of_validity: MaybeCompressedPoV::Raw(pov.clone()),
|
proof_of_validity: MaybeCompressedPoV::Raw(pov.clone()),
|
||||||
|
|||||||
@@ -37,8 +37,10 @@ pub extern "C" fn validate_block(params: *const u8, len: usize) -> u64 {
|
|||||||
parachain::write_result(&ValidationResult {
|
parachain::write_result(&ValidationResult {
|
||||||
head_data: GenericHeadData(new_head.encode()),
|
head_data: GenericHeadData(new_head.encode()),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
upward_messages: sp_std::vec::Vec::new(),
|
upward_messages: sp_std::vec::Vec::new().try_into().expect("empty vec fits within bounds"),
|
||||||
horizontal_messages: sp_std::vec::Vec::new(),
|
horizontal_messages: sp_std::vec::Vec::new()
|
||||||
|
.try_into()
|
||||||
|
.expect("empty vec fits within bounds"),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: params.relay_parent_number,
|
hrmp_watermark: params.relay_parent_number,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ pub use polkadot_core_primitives::v2::{
|
|||||||
|
|
||||||
// Export some polkadot-parachain primitives
|
// Export some polkadot-parachain primitives
|
||||||
pub use polkadot_parachain::primitives::{
|
pub use polkadot_parachain::primitives::{
|
||||||
HeadData, HrmpChannelId, Id, UpwardMessage, ValidationCode, ValidationCodeHash,
|
HeadData, HorizontalMessages, HrmpChannelId, Id, UpwardMessage, UpwardMessages, ValidationCode,
|
||||||
LOWEST_PUBLIC_ID, LOWEST_USER_ID,
|
ValidationCodeHash, LOWEST_PUBLIC_ID, LOWEST_USER_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@@ -593,12 +593,12 @@ impl<H: Encode, N: Encode> PersistedValidationData<H, N> {
|
|||||||
|
|
||||||
/// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation.
|
/// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation.
|
||||||
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
|
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
|
||||||
#[cfg_attr(feature = "std", derive(Hash, Default))]
|
#[cfg_attr(feature = "std", derive(Default, Hash))]
|
||||||
pub struct CandidateCommitments<N = BlockNumber> {
|
pub struct CandidateCommitments<N = BlockNumber> {
|
||||||
/// Messages destined to be interpreted by the Relay chain itself.
|
/// Messages destined to be interpreted by the Relay chain itself.
|
||||||
pub upward_messages: Vec<UpwardMessage>,
|
pub upward_messages: UpwardMessages,
|
||||||
/// Horizontal messages sent by the parachain.
|
/// Horizontal messages sent by the parachain.
|
||||||
pub horizontal_messages: Vec<OutboundHrmpMessage<Id>>,
|
pub horizontal_messages: HorizontalMessages,
|
||||||
/// New validation code.
|
/// New validation code.
|
||||||
pub new_validation_code: Option<ValidationCode>,
|
pub new_validation_code: Option<ValidationCode>,
|
||||||
/// The head-data produced as a result of execution.
|
/// The head-data produced as a result of execution.
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ pub fn dummy_candidate_receipt_bad_sig(
|
|||||||
pub fn dummy_candidate_commitments(head_data: impl Into<Option<HeadData>>) -> CandidateCommitments {
|
pub fn dummy_candidate_commitments(head_data: impl Into<Option<HeadData>>) -> CandidateCommitments {
|
||||||
CandidateCommitments {
|
CandidateCommitments {
|
||||||
head_data: head_data.into().unwrap_or(dummy_head_data()),
|
head_data: head_data.into().unwrap_or(dummy_head_data()),
|
||||||
upward_messages: vec![],
|
upward_messages: vec![].try_into().expect("empty vec fits within bounds"),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
horizontal_messages: vec![],
|
horizontal_messages: vec![].try_into().expect("empty vec fits within bounds"),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
hrmp_watermark: 0_u32,
|
hrmp_watermark: 0_u32,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ primitives = { package = "polkadot-primitives", path = "../../primitives", defau
|
|||||||
rand = { version = "0.8.5", default-features = false }
|
rand = { version = "0.8.5", default-features = false }
|
||||||
rand_chacha = { version = "0.3.1", default-features = false }
|
rand_chacha = { version = "0.3.1", default-features = false }
|
||||||
static_assertions = { version = "1.1.0", optional = true }
|
static_assertions = { version = "1.1.0", optional = true }
|
||||||
|
polkadot-parachain = { path = "../../parachain", default-features = false }
|
||||||
polkadot-runtime-metrics = { path = "../metrics", default-features = false}
|
polkadot-runtime-metrics = { path = "../metrics", default-features = false}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -292,8 +292,8 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
|
|||||||
availability_votes,
|
availability_votes,
|
||||||
);
|
);
|
||||||
let commitments = CandidateCommitments::<u32> {
|
let commitments = CandidateCommitments::<u32> {
|
||||||
upward_messages: vec![],
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: vec![],
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: None,
|
new_validation_code: None,
|
||||||
head_data: Self::mock_head_data(),
|
head_data: Self::mock_head_data(),
|
||||||
processed_downward_messages: 0,
|
processed_downward_messages: 0,
|
||||||
@@ -535,8 +535,8 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
|
|||||||
validation_code_hash,
|
validation_code_hash,
|
||||||
},
|
},
|
||||||
commitments: CandidateCommitments::<u32> {
|
commitments: CandidateCommitments::<u32> {
|
||||||
upward_messages: Vec::new(),
|
upward_messages: Default::default(),
|
||||||
horizontal_messages: Vec::new(),
|
horizontal_messages: Default::default(),
|
||||||
new_validation_code: includes_code_upgrade
|
new_validation_code: includes_code_upgrade
|
||||||
.map(|v| ValidationCode(vec![42u8; v as usize])),
|
.map(|v| ValidationCode(vec![42u8; v as usize])),
|
||||||
head_data,
|
head_data,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ use crate::shared;
|
|||||||
use frame_support::{pallet_prelude::*, weights::constants::WEIGHT_REF_TIME_PER_MILLIS};
|
use frame_support::{pallet_prelude::*, weights::constants::WEIGHT_REF_TIME_PER_MILLIS};
|
||||||
use frame_system::pallet_prelude::*;
|
use frame_system::pallet_prelude::*;
|
||||||
use parity_scale_codec::{Decode, Encode};
|
use parity_scale_codec::{Decode, Encode};
|
||||||
|
use polkadot_parachain::primitives::{MAX_HORIZONTAL_MESSAGE_NUM, MAX_UPWARD_MESSAGE_NUM};
|
||||||
use primitives::{Balance, SessionIndex, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MAX_POV_SIZE};
|
use primitives::{Balance, SessionIndex, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MAX_POV_SIZE};
|
||||||
use sp_runtime::traits::Zero;
|
use sp_runtime::traits::Zero;
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
@@ -322,8 +323,12 @@ pub enum InconsistentError<BlockNumber> {
|
|||||||
},
|
},
|
||||||
/// `validation_upgrade_delay` is less than or equal 1.
|
/// `validation_upgrade_delay` is less than or equal 1.
|
||||||
ValidationUpgradeDelayIsTooLow { validation_upgrade_delay: BlockNumber },
|
ValidationUpgradeDelayIsTooLow { validation_upgrade_delay: BlockNumber },
|
||||||
/// Maximum UMP message size (`MAX_UPWARD_MESSAGE_SIZE_BOUND`) exceeded.
|
/// Maximum UMP message size ([`MAX_UPWARD_MESSAGE_SIZE_BOUND`]) exceeded.
|
||||||
MaxUpwardMessageSizeExceeded { max_message_size: u32 },
|
MaxUpwardMessageSizeExceeded { max_message_size: u32 },
|
||||||
|
/// Maximum HRMP message num ([`MAX_HORIZONTAL_MESSAGE_NUM`]) exceeded.
|
||||||
|
MaxHorizontalMessageNumExceeded { max_message_num: u32 },
|
||||||
|
/// Maximum UMP message num ([`MAX_UPWARD_MESSAGE_NUM`]) exceeded.
|
||||||
|
MaxUpwardMessageNumExceeded { max_message_num: u32 },
|
||||||
/// Maximum number of HRMP outbound channels exceeded.
|
/// Maximum number of HRMP outbound channels exceeded.
|
||||||
MaxHrmpOutboundChannelsExceeded,
|
MaxHrmpOutboundChannelsExceeded,
|
||||||
/// Maximum number of HRMP inbound channels exceeded.
|
/// Maximum number of HRMP inbound channels exceeded.
|
||||||
@@ -396,6 +401,18 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.hrmp_max_message_num_per_candidate > MAX_HORIZONTAL_MESSAGE_NUM {
|
||||||
|
return Err(MaxHorizontalMessageNumExceeded {
|
||||||
|
max_message_num: self.hrmp_max_message_num_per_candidate,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.max_upward_message_num_per_candidate > MAX_UPWARD_MESSAGE_NUM {
|
||||||
|
return Err(MaxUpwardMessageNumExceeded {
|
||||||
|
max_message_num: self.max_upward_message_num_per_candidate,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if self.hrmp_max_parachain_outbound_channels > crate::hrmp::HRMP_MAX_OUTBOUND_CHANNELS_BOUND
|
if self.hrmp_max_parachain_outbound_channels > crate::hrmp::HRMP_MAX_OUTBOUND_CHANNELS_BOUND
|
||||||
{
|
{
|
||||||
return Err(MaxHrmpOutboundChannelsExceeded)
|
return Err(MaxHrmpOutboundChannelsExceeded)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use crate::{
|
|||||||
use frame_support::{pallet_prelude::*, traits::ReservableCurrency};
|
use frame_support::{pallet_prelude::*, traits::ReservableCurrency};
|
||||||
use frame_system::pallet_prelude::*;
|
use frame_system::pallet_prelude::*;
|
||||||
use parity_scale_codec::{Decode, Encode};
|
use parity_scale_codec::{Decode, Encode};
|
||||||
|
use polkadot_parachain::primitives::HorizontalMessages;
|
||||||
use primitives::{
|
use primitives::{
|
||||||
Balance, Hash, HrmpChannelId, Id as ParaId, InboundHrmpMessage, OutboundHrmpMessage,
|
Balance, Hash, HrmpChannelId, Id as ParaId, InboundHrmpMessage, OutboundHrmpMessage,
|
||||||
SessionIndex,
|
SessionIndex,
|
||||||
@@ -1057,10 +1058,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
/// Process the outbound HRMP messages by putting them into the appropriate recipient queues.
|
/// Process the outbound HRMP messages by putting them into the appropriate recipient queues.
|
||||||
///
|
///
|
||||||
/// Returns the amount of weight consumed.
|
/// Returns the amount of weight consumed.
|
||||||
pub(crate) fn queue_outbound_hrmp(
|
pub(crate) fn queue_outbound_hrmp(sender: ParaId, out_hrmp_msgs: HorizontalMessages) -> Weight {
|
||||||
sender: ParaId,
|
|
||||||
out_hrmp_msgs: Vec<OutboundHrmpMessage<ParaId>>,
|
|
||||||
) -> Weight {
|
|
||||||
let mut weight = Weight::zero();
|
let mut weight = Weight::zero();
|
||||||
let now = <frame_system::Pallet<T>>::block_number();
|
let now = <frame_system::Pallet<T>>::block_number();
|
||||||
|
|
||||||
|
|||||||
@@ -278,8 +278,10 @@ fn send_recv_messages() {
|
|||||||
// A sends a message to B
|
// A sends a message to B
|
||||||
run_to_block(6, Some(vec![6]));
|
run_to_block(6, Some(vec![6]));
|
||||||
assert!(channel_exists(para_a, para_b));
|
assert!(channel_exists(para_a, para_b));
|
||||||
let msgs =
|
let msgs: HorizontalMessages =
|
||||||
vec![OutboundHrmpMessage { recipient: para_b, data: b"this is an emergency".to_vec() }];
|
vec![OutboundHrmpMessage { recipient: para_b, data: b"this is an emergency".to_vec() }]
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
let config = Configuration::config();
|
let config = Configuration::config();
|
||||||
assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok());
|
assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok());
|
||||||
let _ = Hrmp::queue_outbound_hrmp(para_a, msgs);
|
let _ = Hrmp::queue_outbound_hrmp(para_a, msgs);
|
||||||
@@ -313,13 +315,17 @@ fn hrmp_mqc_head_fixture() {
|
|||||||
run_to_block(3, Some(vec![3]));
|
run_to_block(3, Some(vec![3]));
|
||||||
let _ = Hrmp::queue_outbound_hrmp(
|
let _ = Hrmp::queue_outbound_hrmp(
|
||||||
para_a,
|
para_a,
|
||||||
vec![OutboundHrmpMessage { recipient: para_b, data: vec![1, 2, 3] }],
|
vec![OutboundHrmpMessage { recipient: para_b, data: vec![1, 2, 3] }]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
run_to_block(4, None);
|
run_to_block(4, None);
|
||||||
let _ = Hrmp::queue_outbound_hrmp(
|
let _ = Hrmp::queue_outbound_hrmp(
|
||||||
para_a,
|
para_a,
|
||||||
vec![OutboundHrmpMessage { recipient: para_b, data: vec![4, 5, 6] }],
|
vec![OutboundHrmpMessage { recipient: para_b, data: vec![4, 5, 6] }]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -381,7 +387,10 @@ fn check_sent_messages() {
|
|||||||
run_to_block(6, Some(vec![6]));
|
run_to_block(6, Some(vec![6]));
|
||||||
assert!(Paras::is_valid_para(para_a));
|
assert!(Paras::is_valid_para(para_a));
|
||||||
|
|
||||||
let msgs = vec![OutboundHrmpMessage { recipient: para_b, data: b"knock".to_vec() }];
|
let msgs: HorizontalMessages =
|
||||||
|
vec![OutboundHrmpMessage { recipient: para_b, data: b"knock".to_vec() }]
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
let config = Configuration::config();
|
let config = Configuration::config();
|
||||||
assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok());
|
assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok());
|
||||||
let _ = Hrmp::queue_outbound_hrmp(para_a, msgs.clone());
|
let _ = Hrmp::queue_outbound_hrmp(para_a, msgs.clone());
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use frame_support::{pallet_prelude::*, traits::EnsureOrigin};
|
use frame_support::{pallet_prelude::*, traits::EnsureOrigin};
|
||||||
use frame_system::pallet_prelude::*;
|
use frame_system::pallet_prelude::*;
|
||||||
|
use polkadot_parachain::primitives::UpwardMessages;
|
||||||
use primitives::{Id as ParaId, UpwardMessage};
|
use primitives::{Id as ParaId, UpwardMessage};
|
||||||
use sp_std::{collections::btree_map::BTreeMap, fmt, marker::PhantomData, mem, prelude::*};
|
use sp_std::{collections::btree_map::BTreeMap, fmt, marker::PhantomData, mem, prelude::*};
|
||||||
use xcm::latest::Outcome;
|
use xcm::latest::Outcome;
|
||||||
@@ -28,7 +29,7 @@ pub use pallet::*;
|
|||||||
|
|
||||||
/// Maximum value that `config.max_upward_message_size` can be set to
|
/// Maximum value that `config.max_upward_message_size` can be set to
|
||||||
///
|
///
|
||||||
/// This is used for benchmarking sanely bounding relevant storate items. It is expected from the `configurations`
|
/// This is used for benchmarking sanely bounding relevant storage items. It is expected from the `configurations`
|
||||||
/// pallet to check these values before setting.
|
/// pallet to check these values before setting.
|
||||||
pub const MAX_UPWARD_MESSAGE_SIZE_BOUND: u32 = 50 * 1024;
|
pub const MAX_UPWARD_MESSAGE_SIZE_BOUND: u32 = 50 * 1024;
|
||||||
/// Maximum amount of overweight messages that can exist in the queue at any given time.
|
/// Maximum amount of overweight messages that can exist in the queue at any given time.
|
||||||
@@ -470,10 +471,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enqueues `upward_messages` from a `para`'s accepted candidate block.
|
/// Enqueues `upward_messages` from a `para`'s accepted candidate block.
|
||||||
pub(crate) fn receive_upward_messages(
|
pub(crate) fn receive_upward_messages(para: ParaId, upward_messages: UpwardMessages) -> Weight {
|
||||||
para: ParaId,
|
|
||||||
upward_messages: Vec<UpwardMessage>,
|
|
||||||
) -> Weight {
|
|
||||||
let mut weight = Weight::zero();
|
let mut weight = Weight::zero();
|
||||||
|
|
||||||
if !upward_messages.is_empty() {
|
if !upward_messages.is_empty() {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ fn queue_upward_msg<T: Config>(
|
|||||||
msg: UpwardMessage,
|
msg: UpwardMessage,
|
||||||
) {
|
) {
|
||||||
let len = msg.len() as u32;
|
let len = msg.len() as u32;
|
||||||
let msgs = vec![msg];
|
let msgs: UpwardMessages = vec![msg].try_into().unwrap();
|
||||||
Ump::<T>::check_upward_messages(host_conf, para, &msgs).unwrap();
|
Ump::<T>::check_upward_messages(host_conf, para, &msgs).unwrap();
|
||||||
let _ = Ump::<T>::receive_upward_messages(para, msgs);
|
let _ = Ump::<T>::receive_upward_messages(para, msgs);
|
||||||
assert_last_event_type::<T>(Event::UpwardMessagesReceived(para, 1, len).into());
|
assert_last_event_type::<T>(Event::UpwardMessagesReceived(para, 1, len).into());
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ fn default_genesis_config() -> MockGenesisConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn queue_upward_msg(para: ParaId, msg: UpwardMessage) {
|
fn queue_upward_msg(para: ParaId, msg: UpwardMessage) {
|
||||||
let msgs = vec![msg];
|
let msgs: UpwardMessages = vec![msg].try_into().unwrap();
|
||||||
assert!(Ump::check_upward_messages(&Configuration::config(), para, &msgs).is_ok());
|
assert!(Ump::check_upward_messages(&Configuration::config(), para, &msgs).is_ok());
|
||||||
let _ = Ump::receive_upward_messages(para, msgs);
|
let _ = Ump::receive_upward_messages(para, msgs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ authors.workspace = true
|
|||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bounded-collections = { version = "0.1.4", default-features = false }
|
bounded-collections = { version = "0.1.5", default-features = false }
|
||||||
derivative = { version = "2.2.0", default-features = false, features = [ "use_core" ] }
|
derivative = { version = "2.2.0", default-features = false, features = [ "use_core" ] }
|
||||||
impl-trait-for-tuples = "0.2.2"
|
impl-trait-for-tuples = "0.2.2"
|
||||||
log = { version = "0.4.17", default-features = false }
|
log = { version = "0.4.17", default-features = false }
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ version.workspace = true
|
|||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bounded-collections = { version = "0.1.4", default-features = false }
|
bounded-collections = { version = "0.1.5", default-features = false }
|
||||||
codec = { package = "parity-scale-codec", version = "3.3.0", default-features = false, features = ["derive"] }
|
codec = { package = "parity-scale-codec", version = "3.3.0", default-features = false, features = ["derive"] }
|
||||||
scale-info = { version = "2.1.2", default-features = false, features = ["derive"] }
|
scale-info = { version = "2.1.2", default-features = false, features = ["derive"] }
|
||||||
serde = { version = "1.0.137", optional = true, features = ["derive"] }
|
serde = { version = "1.0.137", optional = true, features = ["derive"] }
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ fn pallet_query_should_work() {
|
|||||||
let expected_msg = Xcm::<()>(vec![QueryResponse {
|
let expected_msg = Xcm::<()>(vec![QueryResponse {
|
||||||
query_id: 1,
|
query_id: 1,
|
||||||
max_weight: Weight::from_parts(50, 50),
|
max_weight: Weight::from_parts(50, 50),
|
||||||
response: Response::PalletsInfo(vec![].try_into().unwrap()),
|
response: Response::PalletsInfo(Default::default()),
|
||||||
querier: Some(Here.into()),
|
querier: Some(Here.into()),
|
||||||
}]);
|
}]);
|
||||||
let expected_hash = fake_message_hash(&expected_msg);
|
let expected_hash = fake_message_hash(&expected_msg);
|
||||||
|
|||||||
Reference in New Issue
Block a user