mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 05:21:08 +00:00
Update Cumulus for Parachains V1 (#224)
* Start with something * Whatever * Update * MOARE * Make cumulus-network compile and tests work * Update more and fixes * More stuff * More fixes * Make collator build * Make test almost work * Remove contracts runtime * More test work * Make service compile * Fix test-service * Fix test client * More fixes * Fix collator test * Fix network tests (again) * Make everything compile, finally * Fix tests * Update to latest masters * Remove ignore * Switch to different branch in polkadot for now * Update reference * Make it compile with latest changes * Update collator/src/lib.rs Co-authored-by: Robert Habermeier <rphmeier@gmail.com> * Update to latest upstream * Update to latest master * Fix test Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
@@ -19,24 +19,22 @@
|
||||
use frame_executive::ExecuteBlock;
|
||||
use sp_runtime::traits::{Block as BlockT, HashFor, Header as HeaderT};
|
||||
|
||||
use sp_std::{boxed::Box, vec::Vec, collections::btree_map::BTreeMap, ops::Bound};
|
||||
use sp_std::{boxed::Box, collections::btree_map::BTreeMap, ops::Bound, vec::Vec};
|
||||
use sp_trie::{delta_trie_root, read_trie_value, Layout, MemoryDB, StorageProof};
|
||||
|
||||
use hash_db::{HashDB, EMPTY_PREFIX};
|
||||
|
||||
use trie_db::{TrieDB, TrieDBIterator, Trie, TrieError};
|
||||
use trie_db::{Trie, TrieDB, TrieDBIterator};
|
||||
|
||||
use parachain::primitives::{HeadData, ValidationCode, ValidationParams, ValidationResult};
|
||||
|
||||
use codec::{Decode, Encode, EncodeAppend};
|
||||
|
||||
use cumulus_primitives::{
|
||||
validation_function_params::ValidationFunctionParams,
|
||||
well_known_keys::{
|
||||
NEW_VALIDATION_CODE, PROCESSED_DOWNWARD_MESSAGES, UPWARD_MESSAGES,
|
||||
VALIDATION_FUNCTION_PARAMS,
|
||||
NEW_VALIDATION_CODE, PROCESSED_DOWNWARD_MESSAGES, UPWARD_MESSAGES, VALIDATION_DATA,
|
||||
},
|
||||
GenericUpwardMessage,
|
||||
GenericUpwardMessage, ValidationData,
|
||||
};
|
||||
|
||||
/// Stores the global [`Storage`] instance.
|
||||
@@ -117,16 +115,13 @@ pub fn validate_block<B: BlockT, E: ExecuteBlock<B>>(params: ValidationParams) -
|
||||
let block = B::new(block_data.header, block_data.extrinsics);
|
||||
assert!(
|
||||
parent_head.hash() == *block.header().parent_hash(),
|
||||
"Invalid parent hash"
|
||||
"Invalid parent hash",
|
||||
);
|
||||
|
||||
// make a copy for later use
|
||||
let validation_function_params = (¶ms).into();
|
||||
|
||||
let storage_inner = WitnessStorage::<B>::new(
|
||||
block_data.storage_proof,
|
||||
parent_head.state_root().clone(),
|
||||
validation_function_params,
|
||||
params,
|
||||
)
|
||||
.expect("Witness data and storage root always match; qed");
|
||||
|
||||
@@ -153,9 +148,6 @@ pub fn validate_block<B: BlockT, E: ExecuteBlock<B>>(params: ValidationParams) -
|
||||
// its scheduled upgrade so we can validate that block number later.
|
||||
let new_validation_code =
|
||||
with_storage(|storage| storage.modified(NEW_VALIDATION_CODE)).map(ValidationCode);
|
||||
if new_validation_code.is_some() && validation_function_params.code_upgrade_allowed.is_none() {
|
||||
panic!("Attempt to upgrade validation function when not permitted!");
|
||||
}
|
||||
|
||||
// Extract potential upward messages from the storage.
|
||||
let upward_messages = match with_storage(|storage| storage.modified(UPWARD_MESSAGES)) {
|
||||
@@ -183,7 +175,7 @@ struct WitnessStorage<B: BlockT> {
|
||||
witness_data: MemoryDB<HashFor<B>>,
|
||||
overlay: BTreeMap<Vec<u8>, Option<Vec<u8>>>,
|
||||
storage_root: B::Hash,
|
||||
params: ValidationFunctionParams,
|
||||
validation_params: ValidationParams,
|
||||
}
|
||||
|
||||
impl<B: BlockT> WitnessStorage<B> {
|
||||
@@ -193,9 +185,9 @@ impl<B: BlockT> WitnessStorage<B> {
|
||||
fn new(
|
||||
storage_proof: StorageProof,
|
||||
storage_root: B::Hash,
|
||||
params: ValidationFunctionParams,
|
||||
validation_params: ValidationParams,
|
||||
) -> Result<Self, &'static str> {
|
||||
let mut db = storage_proof.into_memory_db();
|
||||
let db = storage_proof.into_memory_db();
|
||||
|
||||
if !HashDB::contains(&db, &storage_root, EMPTY_PREFIX) {
|
||||
return Err("Witness data does not contain given storage root.");
|
||||
@@ -205,7 +197,7 @@ impl<B: BlockT> WitnessStorage<B> {
|
||||
witness_data: db,
|
||||
overlay: Default::default(),
|
||||
storage_root,
|
||||
params,
|
||||
validation_params,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -238,41 +230,50 @@ impl<B: BlockT> WitnessStorage<B> {
|
||||
/// Find the next storage key after the given `key` in the overlay.
|
||||
fn overlay_next_key(&self, key: &[u8]) -> Option<(&[u8], Option<&[u8]>)> {
|
||||
let range = (Bound::Excluded(key), Bound::Unbounded);
|
||||
self.overlay.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v.as_deref()))
|
||||
self.overlay
|
||||
.range::<[u8], _>(range)
|
||||
.next()
|
||||
.map(|(k, v)| (&k[..], v.as_deref()))
|
||||
}
|
||||
|
||||
/// Checks that the encoded `ValidationData` in `data` is correct.
|
||||
///
|
||||
/// Should be removed with: https://github.com/paritytech/cumulus/issues/217
|
||||
fn check_validation_data(&self, mut data: &[u8]) {
|
||||
let validation_data = ValidationData::decode(&mut data).expect("Invalid `ValidationData`");
|
||||
|
||||
assert_eq!(
|
||||
self.validation_params.parent_head,
|
||||
validation_data.persisted.parent_head
|
||||
);
|
||||
assert_eq!(
|
||||
self.validation_params.relay_chain_height,
|
||||
validation_data.persisted.block_number
|
||||
);
|
||||
assert_eq!(
|
||||
self.validation_params.hrmp_mqc_heads,
|
||||
validation_data.persisted.hrmp_mqc_heads
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT> Storage for WitnessStorage<B> {
|
||||
fn modified(&self, key: &[u8]) -> Option<Vec<u8>> {
|
||||
match key {
|
||||
VALIDATION_FUNCTION_PARAMS => Some(self.params.encode()),
|
||||
key => self
|
||||
.overlay
|
||||
.get(key)
|
||||
.cloned()
|
||||
.unwrap_or(None),
|
||||
}
|
||||
self.overlay.get(key).cloned().unwrap_or(None)
|
||||
}
|
||||
|
||||
fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
|
||||
match key {
|
||||
VALIDATION_FUNCTION_PARAMS => Some(self.params.encode()),
|
||||
key => self
|
||||
.overlay
|
||||
.get(key)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| {
|
||||
read_trie_value::<Layout<HashFor<B>>, _>(
|
||||
&self.witness_data,
|
||||
&self.storage_root,
|
||||
key,
|
||||
)
|
||||
.expect("Reading key from trie.")
|
||||
})
|
||||
}
|
||||
self.overlay.get(key).cloned().unwrap_or_else(|| {
|
||||
read_trie_value::<Layout<HashFor<B>>, _>(&self.witness_data, &self.storage_root, key)
|
||||
.expect("Reading key from trie.")
|
||||
})
|
||||
}
|
||||
|
||||
fn insert(&mut self, key: &[u8], value: &[u8]) {
|
||||
if key == VALIDATION_DATA {
|
||||
self.check_validation_data(value);
|
||||
}
|
||||
|
||||
self.overlay.insert(key.to_vec(), Some(value.to_vec()));
|
||||
}
|
||||
|
||||
@@ -339,13 +340,17 @@ impl<B: BlockT> Storage for WitnessStorage<B> {
|
||||
let next_overlay_key = self.overlay_next_key(key);
|
||||
|
||||
match (next_trie_key, next_overlay_key) {
|
||||
(Some(backend_key), Some(overlay_key)) if &backend_key[..] < overlay_key.0 => Some(backend_key),
|
||||
(Some(backend_key), Some(overlay_key)) if &backend_key[..] < overlay_key.0 => {
|
||||
Some(backend_key)
|
||||
}
|
||||
(backend_key, None) => backend_key,
|
||||
(_, Some(overlay_key)) => if overlay_key.1.is_some() {
|
||||
Some(overlay_key.0.to_vec())
|
||||
} else {
|
||||
self.next_key(&overlay_key.0)
|
||||
},
|
||||
(_, Some(overlay_key)) => {
|
||||
if overlay_key.1.is_some() {
|
||||
Some(overlay_key.0.to_vec())
|
||||
} else {
|
||||
self.next_key(&overlay_key.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,13 @@
|
||||
|
||||
use crate::ParachainBlockData;
|
||||
|
||||
use cumulus_primitives::{PersistedValidationData, ValidationData};
|
||||
use cumulus_test_client::{
|
||||
generate_block_inherents,
|
||||
runtime::{Block, Hash, Header, UncheckedExtrinsic, WASM_BINARY},
|
||||
transfer, Client, DefaultTestClientBuilderExt, LongestChain, TestClientBuilder,
|
||||
TestClientBuilderExt,
|
||||
};
|
||||
use parachain::primitives::{BlockData, HeadData, ValidationParams, ValidationResult};
|
||||
use sc_block_builder::BlockBuilderProvider;
|
||||
use sc_executor::{
|
||||
@@ -30,12 +37,6 @@ use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header as HeaderT},
|
||||
};
|
||||
use test_client::{
|
||||
generate_block_inherents,
|
||||
runtime::{Block, Hash, Header, UncheckedExtrinsic, WASM_BINARY},
|
||||
transfer, Client, DefaultTestClientBuilderExt, LongestChain, TestClientBuilder,
|
||||
TestClientBuilderExt,
|
||||
};
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
@@ -48,10 +49,9 @@ fn call_validate_block(
|
||||
let params = ValidationParams {
|
||||
block_data: BlockData(block_data.encode()),
|
||||
parent_head: HeadData(parent_head.encode()),
|
||||
code_upgrade_allowed: None,
|
||||
max_code_size: 1024,
|
||||
max_head_data_size: 1024,
|
||||
relay_chain_height: 1,
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
}
|
||||
.encode();
|
||||
|
||||
@@ -86,15 +86,26 @@ fn create_test_client() -> (Client, LongestChain) {
|
||||
fn build_block_with_proof(
|
||||
client: &Client,
|
||||
extra_extrinsics: Vec<UncheckedExtrinsic>,
|
||||
parent_head: Header,
|
||||
) -> (Block, sp_trie::StorageProof) {
|
||||
let block_id = BlockId::Hash(client.info().best_hash);
|
||||
let mut builder = client
|
||||
.new_block_at(&block_id, Default::default(), true)
|
||||
.expect("Initializes new block");
|
||||
|
||||
generate_block_inherents(client)
|
||||
.into_iter()
|
||||
.for_each(|e| builder.push(e).expect("Pushes an inherent"));
|
||||
generate_block_inherents(
|
||||
client,
|
||||
Some(ValidationData {
|
||||
persisted: PersistedValidationData {
|
||||
block_number: 1,
|
||||
parent_head: parent_head.encode().into(),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
)
|
||||
.into_iter()
|
||||
.for_each(|e| builder.push(e).expect("Pushes an inherent"));
|
||||
|
||||
extra_extrinsics
|
||||
.into_iter()
|
||||
@@ -112,9 +123,11 @@ fn build_block_with_proof(
|
||||
|
||||
#[test]
|
||||
fn validate_block_no_extra_extrinsics() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let (client, longest_chain) = create_test_client();
|
||||
let parent_head = longest_chain.best_chain().expect("Best block exists");
|
||||
let (block, witness_data) = build_block_with_proof(&client, vec![]);
|
||||
let (block, witness_data) = build_block_with_proof(&client, vec![], parent_head.clone());
|
||||
let (header, extrinsics) = block.deconstruct();
|
||||
|
||||
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness_data);
|
||||
@@ -125,6 +138,8 @@ fn validate_block_no_extra_extrinsics() {
|
||||
|
||||
#[test]
|
||||
fn validate_block_with_extra_extrinsics() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let (client, longest_chain) = create_test_client();
|
||||
let parent_head = longest_chain.best_chain().expect("Best block exists");
|
||||
let extra_extrinsics = vec![
|
||||
@@ -133,7 +148,8 @@ fn validate_block_with_extra_extrinsics() {
|
||||
transfer(&client, Charlie, Alice, 500),
|
||||
];
|
||||
|
||||
let (block, witness_data) = build_block_with_proof(&client, extra_extrinsics);
|
||||
let (block, witness_data) =
|
||||
build_block_with_proof(&client, extra_extrinsics, parent_head.clone());
|
||||
let (header, extrinsics) = block.deconstruct();
|
||||
|
||||
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness_data);
|
||||
@@ -145,9 +161,11 @@ fn validate_block_with_extra_extrinsics() {
|
||||
#[test]
|
||||
#[should_panic(expected = "Calls `validate_block`: Other(\"Trap: Trap { kind: Unreachable }\")")]
|
||||
fn validate_block_invalid_parent_hash() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let (client, longest_chain) = create_test_client();
|
||||
let parent_head = longest_chain.best_chain().expect("Best block exists");
|
||||
let (block, witness_data) = build_block_with_proof(&client, vec![]);
|
||||
let (block, witness_data) = build_block_with_proof(&client, vec![], parent_head.clone());
|
||||
let (mut header, extrinsics) = block.deconstruct();
|
||||
header.set_parent_hash(Hash::from_low_u64_be(1));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user