mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 12:11:02 +00:00
Add events to the bridge parachains pallet (#1568)
* add events to the bridge parachains pallet * clippy + spellcheck * fix compilation * untracked is not a word?
This commit is contained in:
committed by
Bastian Köcher
parent
95c30c780c
commit
653ff6ef0d
@@ -540,6 +540,7 @@ parameter_types! {
|
|||||||
pub type WithRialtoParachainsInstance = ();
|
pub type WithRialtoParachainsInstance = ();
|
||||||
|
|
||||||
impl pallet_bridge_parachains::Config<WithRialtoParachainsInstance> for Runtime {
|
impl pallet_bridge_parachains::Config<WithRialtoParachainsInstance> for Runtime {
|
||||||
|
type Event = Event;
|
||||||
type WeightInfo = pallet_bridge_parachains::weights::MillauWeight<Runtime>;
|
type WeightInfo = pallet_bridge_parachains::weights::MillauWeight<Runtime>;
|
||||||
type BridgesGrandpaPalletInstance = RialtoGrandpaInstance;
|
type BridgesGrandpaPalletInstance = RialtoGrandpaInstance;
|
||||||
type ParasPalletName = RialtoParasPalletName;
|
type ParasPalletName = RialtoParasPalletName;
|
||||||
@@ -551,6 +552,7 @@ impl pallet_bridge_parachains::Config<WithRialtoParachainsInstance> for Runtime
|
|||||||
pub type WithWestendParachainsInstance = pallet_bridge_parachains::Instance1;
|
pub type WithWestendParachainsInstance = pallet_bridge_parachains::Instance1;
|
||||||
|
|
||||||
impl pallet_bridge_parachains::Config<WithWestendParachainsInstance> for Runtime {
|
impl pallet_bridge_parachains::Config<WithWestendParachainsInstance> for Runtime {
|
||||||
|
type Event = Event;
|
||||||
type WeightInfo = pallet_bridge_parachains::weights::MillauWeight<Runtime>;
|
type WeightInfo = pallet_bridge_parachains::weights::MillauWeight<Runtime>;
|
||||||
type BridgesGrandpaPalletInstance = WestendGrandpaInstance;
|
type BridgesGrandpaPalletInstance = WestendGrandpaInstance;
|
||||||
type ParasPalletName = WestendParasPalletName;
|
type ParasPalletName = WestendParasPalletName;
|
||||||
@@ -592,10 +594,10 @@ construct_runtime!(
|
|||||||
|
|
||||||
// Westend bridge modules.
|
// Westend bridge modules.
|
||||||
BridgeWestendGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Config<T>, Storage},
|
BridgeWestendGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Config<T>, Storage},
|
||||||
BridgeWestendParachains: pallet_bridge_parachains::<Instance1>::{Pallet, Call, Storage},
|
BridgeWestendParachains: pallet_bridge_parachains::<Instance1>::{Pallet, Call, Storage, Event<T>},
|
||||||
|
|
||||||
// RialtoParachain bridge modules.
|
// RialtoParachain bridge modules.
|
||||||
BridgeRialtoParachains: pallet_bridge_parachains::{Pallet, Call, Storage},
|
BridgeRialtoParachains: pallet_bridge_parachains::{Pallet, Call, Storage, Event<T>},
|
||||||
BridgeRialtoParachainMessages: pallet_bridge_messages::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>},
|
BridgeRialtoParachainMessages: pallet_bridge_messages::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>},
|
||||||
|
|
||||||
// Pallet for sending XCM.
|
// Pallet for sending XCM.
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
use crate::{Config, Pallet, RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
use crate::{Config, Pallet, RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||||
use bp_runtime::FilterCall;
|
use bp_runtime::FilterCall;
|
||||||
use frame_support::{dispatch::CallableCallFor, traits::IsSubType};
|
use frame_support::{dispatch::CallableCallFor, traits::IsSubType};
|
||||||
use sp_runtime::transaction_validity::{TransactionValidity, ValidTransaction};
|
use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction};
|
||||||
|
|
||||||
/// Validate parachain heads in order to avoid "mining" transactions that provide
|
/// Validate parachain heads in order to avoid "mining" transactions that provide
|
||||||
/// outdated bridged parachain heads. Without this validation, even honest relayers
|
/// outdated bridged parachain heads. Without this validation, even honest relayers
|
||||||
@@ -57,13 +57,19 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
let maybe_stored_best_head = crate::ParasInfo::<T, I>::get(parachain);
|
let maybe_stored_best_head = crate::ParasInfo::<T, I>::get(parachain);
|
||||||
Self::validate_updated_parachain_head(
|
let is_valid = Self::validate_updated_parachain_head(
|
||||||
parachain,
|
parachain,
|
||||||
&maybe_stored_best_head,
|
&maybe_stored_best_head,
|
||||||
updated_at_relay_block_number,
|
updated_at_relay_block_number,
|
||||||
parachain_head_hash,
|
parachain_head_hash,
|
||||||
"Rejecting obsolete parachain-head transaction",
|
"Rejecting obsolete parachain-head transaction",
|
||||||
)
|
);
|
||||||
|
|
||||||
|
if is_valid {
|
||||||
|
Ok(ValidTransaction::default())
|
||||||
|
} else {
|
||||||
|
InvalidTransaction::Stale.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,27 @@ pub mod pallet {
|
|||||||
/// Weight info of the given parachains pallet.
|
/// Weight info of the given parachains pallet.
|
||||||
pub type WeightInfoOf<T, I> = <T as Config<I>>::WeightInfo;
|
pub type WeightInfoOf<T, I> = <T as Config<I>>::WeightInfo;
|
||||||
|
|
||||||
|
#[pallet::event]
|
||||||
|
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||||
|
pub enum Event<T: Config<I>, I: 'static = ()> {
|
||||||
|
/// The caller has provided head of parachain that the pallet is not configured to track.
|
||||||
|
UntrackedParachainRejected { parachain: ParaId },
|
||||||
|
/// The caller has declared that he has provided given parachain head, but it is missing
|
||||||
|
/// from the storage proof.
|
||||||
|
MissingParachainHead { parachain: ParaId },
|
||||||
|
/// The caller has provided parachain head hash that is not matching the hash read from the
|
||||||
|
/// storage proof.
|
||||||
|
IncorrectParachainHeadHash {
|
||||||
|
parachain: ParaId,
|
||||||
|
parachain_head_hash: ParaHash,
|
||||||
|
actual_parachain_head_hash: ParaHash,
|
||||||
|
},
|
||||||
|
/// The caller has provided obsolete parachain head, which is already known to the pallet.
|
||||||
|
RejectedObsoleteParachainHead { parachain: ParaId, parachain_head_hash: ParaHash },
|
||||||
|
/// Parachain head has been updated.
|
||||||
|
UpdatedParachainHead { parachain: ParaId, parachain_head_hash: ParaHash },
|
||||||
|
}
|
||||||
|
|
||||||
#[pallet::error]
|
#[pallet::error]
|
||||||
pub enum Error<T, I = ()> {
|
pub enum Error<T, I = ()> {
|
||||||
/// Relay chain block hash is unknown to us.
|
/// Relay chain block hash is unknown to us.
|
||||||
@@ -100,6 +121,8 @@ pub mod pallet {
|
|||||||
pub trait Config<I: 'static = ()>:
|
pub trait Config<I: 'static = ()>:
|
||||||
pallet_bridge_grandpa::Config<Self::BridgesGrandpaPalletInstance>
|
pallet_bridge_grandpa::Config<Self::BridgesGrandpaPalletInstance>
|
||||||
{
|
{
|
||||||
|
/// The overarching event type.
|
||||||
|
type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;
|
||||||
/// Benchmarks results from runtime we're plugged into.
|
/// Benchmarks results from runtime we're plugged into.
|
||||||
type WeightInfo: WeightInfoExt;
|
type WeightInfo: WeightInfoExt;
|
||||||
|
|
||||||
@@ -248,6 +271,7 @@ pub mod pallet {
|
|||||||
"The head of parachain {:?} has been provided, but it is not tracked by the pallet",
|
"The head of parachain {:?} has been provided, but it is not tracked by the pallet",
|
||||||
parachain,
|
parachain,
|
||||||
);
|
);
|
||||||
|
Self::deposit_event(Event::UntrackedParachainRejected { parachain });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +288,7 @@ pub mod pallet {
|
|||||||
"Looks like it has been deregistered from the source relay chain"
|
"Looks like it has been deregistered from the source relay chain"
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
Self::deposit_event(Event::MissingParachainHead { parachain });
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -273,6 +298,7 @@ pub mod pallet {
|
|||||||
parachain,
|
parachain,
|
||||||
e,
|
e,
|
||||||
);
|
);
|
||||||
|
Self::deposit_event(Event::MissingParachainHead { parachain });
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -288,6 +314,11 @@ pub mod pallet {
|
|||||||
parachain_head_hash,
|
parachain_head_hash,
|
||||||
actual_parachain_head_hash,
|
actual_parachain_head_hash,
|
||||||
);
|
);
|
||||||
|
Self::deposit_event(Event::IncorrectParachainHeadHash {
|
||||||
|
parachain,
|
||||||
|
parachain_head_hash,
|
||||||
|
actual_parachain_head_hash,
|
||||||
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,16 +418,20 @@ pub mod pallet {
|
|||||||
|
|
||||||
/// Check if para head has been already updated at better relay chain block.
|
/// Check if para head has been already updated at better relay chain block.
|
||||||
/// Without this check, we may import heads in random order.
|
/// Without this check, we may import heads in random order.
|
||||||
|
///
|
||||||
|
/// Returns `true` if the pallet is ready to import given parachain head.
|
||||||
|
/// Returns `false` if the pallet already knows the same or better parachain head.
|
||||||
|
#[must_use]
|
||||||
pub fn validate_updated_parachain_head(
|
pub fn validate_updated_parachain_head(
|
||||||
parachain: ParaId,
|
parachain: ParaId,
|
||||||
maybe_stored_best_head: &Option<ParaInfo>,
|
maybe_stored_best_head: &Option<ParaInfo>,
|
||||||
updated_at_relay_block_number: RelayBlockNumber,
|
updated_at_relay_block_number: RelayBlockNumber,
|
||||||
updated_head_hash: ParaHash,
|
updated_head_hash: ParaHash,
|
||||||
err_log_prefix: &str,
|
err_log_prefix: &str,
|
||||||
) -> TransactionValidity {
|
) -> bool {
|
||||||
let stored_best_head = match maybe_stored_best_head {
|
let stored_best_head = match maybe_stored_best_head {
|
||||||
Some(stored_best_head) => stored_best_head,
|
Some(stored_best_head) => stored_best_head,
|
||||||
None => return Ok(ValidTransaction::default()),
|
None => return true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if stored_best_head.best_head_hash.at_relay_block_number >=
|
if stored_best_head.best_head_hash.at_relay_block_number >=
|
||||||
@@ -410,7 +445,7 @@ pub mod pallet {
|
|||||||
stored_best_head.best_head_hash.at_relay_block_number,
|
stored_best_head.best_head_hash.at_relay_block_number,
|
||||||
updated_at_relay_block_number
|
updated_at_relay_block_number
|
||||||
);
|
);
|
||||||
return InvalidTransaction::Stale.into()
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if stored_best_head.best_head_hash.head_hash == updated_head_hash {
|
if stored_best_head.best_head_hash.head_hash == updated_head_hash {
|
||||||
@@ -423,10 +458,10 @@ pub mod pallet {
|
|||||||
stored_best_head.best_head_hash.at_relay_block_number,
|
stored_best_head.best_head_hash.at_relay_block_number,
|
||||||
updated_at_relay_block_number
|
updated_at_relay_block_number
|
||||||
);
|
);
|
||||||
return InvalidTransaction::Stale.into()
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ValidTransaction::default())
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to update parachain head.
|
/// Try to update parachain head.
|
||||||
@@ -439,14 +474,20 @@ pub mod pallet {
|
|||||||
) -> Result<UpdateParachainHeadArtifacts, ()> {
|
) -> Result<UpdateParachainHeadArtifacts, ()> {
|
||||||
// check if head has been already updated at better relay chain block. Without this
|
// check if head has been already updated at better relay chain block. Without this
|
||||||
// check, we may import heads in random order
|
// check, we may import heads in random order
|
||||||
Self::validate_updated_parachain_head(
|
let is_valid = Self::validate_updated_parachain_head(
|
||||||
parachain,
|
parachain,
|
||||||
&stored_best_head,
|
&stored_best_head,
|
||||||
updated_at_relay_block_number,
|
updated_at_relay_block_number,
|
||||||
updated_head_hash,
|
updated_head_hash,
|
||||||
"The parachain head can't be updated",
|
"The parachain head can't be updated",
|
||||||
)
|
);
|
||||||
.map_err(|_| ())?;
|
if !is_valid {
|
||||||
|
Self::deposit_event(Event::RejectedObsoleteParachainHead {
|
||||||
|
parachain,
|
||||||
|
parachain_head_hash: updated_head_hash,
|
||||||
|
});
|
||||||
|
return Err(())
|
||||||
|
}
|
||||||
let next_imported_hash_position = stored_best_head
|
let next_imported_hash_position = stored_best_head
|
||||||
.map_or(0, |stored_best_head| stored_best_head.next_imported_hash_position);
|
.map_or(0, |stored_best_head| stored_best_head.next_imported_hash_position);
|
||||||
|
|
||||||
@@ -485,6 +526,10 @@ pub mod pallet {
|
|||||||
);
|
);
|
||||||
ImportedParaHeads::<T, I>::remove(parachain, head_hash_to_prune);
|
ImportedParaHeads::<T, I>::remove(parachain, head_hash_to_prune);
|
||||||
}
|
}
|
||||||
|
Self::deposit_event(Event::UpdatedParachainHead {
|
||||||
|
parachain,
|
||||||
|
parachain_head_hash: updated_head_hash,
|
||||||
|
});
|
||||||
|
|
||||||
Ok(UpdateParachainHeadArtifacts { best_head: updated_best_para_head, prune_happened })
|
Ok(UpdateParachainHeadArtifacts { best_head: updated_best_para_head, prune_happened })
|
||||||
}
|
}
|
||||||
@@ -526,7 +571,8 @@ pub mod pallet {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::mock::{
|
use crate::mock::{
|
||||||
run_test, test_relay_header, Origin, TestRuntime, PARAS_PALLET_NAME, UNTRACKED_PARACHAIN_ID,
|
run_test, test_relay_header, Event as TestEvent, Origin, TestRuntime, PARAS_PALLET_NAME,
|
||||||
|
UNTRACKED_PARACHAIN_ID,
|
||||||
};
|
};
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
|
|
||||||
@@ -545,6 +591,7 @@ mod tests {
|
|||||||
traits::{Get, OnInitialize},
|
traits::{Get, OnInitialize},
|
||||||
weights::Weight,
|
weights::Weight,
|
||||||
};
|
};
|
||||||
|
use frame_system::{EventRecord, Pallet as System, Phase};
|
||||||
use sp_runtime::DispatchError;
|
use sp_runtime::DispatchError;
|
||||||
use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, Recorder, TrieMut};
|
use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, Recorder, TrieMut};
|
||||||
|
|
||||||
@@ -733,6 +780,28 @@ mod tests {
|
|||||||
ImportedParaHeads::<TestRuntime>::get(ParaId(3), head_hash(3, 10)),
|
ImportedParaHeads::<TestRuntime>::get(ParaId(3), head_hash(3, 10)),
|
||||||
Some(head_data(3, 10))
|
Some(head_data(3, 10))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: initial_best_head(1).best_head_hash.head_hash,
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(3),
|
||||||
|
parachain_head_hash: head_data(3, 10).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,6 +833,17 @@ mod tests {
|
|||||||
ImportedParaHeads::<TestRuntime>::get(ParaId(1), head_data(1, 10).hash()),
|
ImportedParaHeads::<TestRuntime>::get(ParaId(1), head_data(1, 10).hash()),
|
||||||
None
|
None
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: head_data(1, 5).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
|
||||||
// import head#10 of parachain#1 at relay block #1
|
// import head#10 of parachain#1 at relay block #1
|
||||||
proceed(1, state_root_10);
|
proceed(1, state_root_10);
|
||||||
@@ -786,6 +866,27 @@ mod tests {
|
|||||||
ImportedParaHeads::<TestRuntime>::get(ParaId(1), head_data(1, 10).hash()),
|
ImportedParaHeads::<TestRuntime>::get(ParaId(1), head_data(1, 10).hash()),
|
||||||
Some(head_data(1, 10))
|
Some(head_data(1, 10))
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: head_data(1, 5).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: head_data(1, 10).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -834,6 +935,34 @@ mod tests {
|
|||||||
next_imported_hash_position: 1,
|
next_imported_hash_position: 1,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: head_data(1, 5).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UntrackedParachainRejected {
|
||||||
|
parachain: ParaId(UNTRACKED_PARACHAIN_ID),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(2),
|
||||||
|
parachain_head_hash: head_data(1, 5).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -846,12 +975,44 @@ mod tests {
|
|||||||
initialize(state_root);
|
initialize(state_root);
|
||||||
assert_ok!(import_parachain_1_head(0, state_root, parachains.clone(), proof.clone()));
|
assert_ok!(import_parachain_1_head(0, state_root, parachains.clone(), proof.clone()));
|
||||||
assert_eq!(ParasInfo::<TestRuntime>::get(ParaId(1)), Some(initial_best_head(1)));
|
assert_eq!(ParasInfo::<TestRuntime>::get(ParaId(1)), Some(initial_best_head(1)));
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: initial_best_head(1).best_head_hash.head_hash,
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
|
||||||
// try to import head#0 of parachain#1 at relay block#1
|
// try to import head#0 of parachain#1 at relay block#1
|
||||||
// => call succeeds, but nothing is changed
|
// => call succeeds, but nothing is changed
|
||||||
proceed(1, state_root);
|
proceed(1, state_root);
|
||||||
assert_ok!(import_parachain_1_head(1, state_root, parachains, proof));
|
assert_ok!(import_parachain_1_head(1, state_root, parachains, proof));
|
||||||
assert_eq!(ParasInfo::<TestRuntime>::get(ParaId(1)), Some(initial_best_head(1)));
|
assert_eq!(ParasInfo::<TestRuntime>::get(ParaId(1)), Some(initial_best_head(1)));
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: initial_best_head(1).best_head_hash.head_hash,
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::RejectedObsoleteParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: initial_best_head(1).best_head_hash.head_hash,
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,6 +1039,17 @@ mod tests {
|
|||||||
next_imported_hash_position: 1,
|
next_imported_hash_position: 1,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: head_data(1, 10).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
|
||||||
// now try to import head#5 at relay block#0
|
// now try to import head#5 at relay block#0
|
||||||
// => nothing is changed, because better head has already been imported
|
// => nothing is changed, because better head has already been imported
|
||||||
@@ -892,6 +1064,27 @@ mod tests {
|
|||||||
next_imported_hash_position: 1,
|
next_imported_hash_position: 1,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::UpdatedParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: head_data(1, 10).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::RejectedObsoleteParachainHead {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: head_data(1, 5).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1047,5 +1240,57 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ignores_parachain_head_if_it_is_missing_from_storage_proof() {
|
||||||
|
let (state_root, proof, _) = prepare_parachain_heads_proof(vec![(1, head_data(1, 0))]);
|
||||||
|
let parachains = vec![(ParaId(2), Default::default())];
|
||||||
|
run_test(|| {
|
||||||
|
initialize(state_root);
|
||||||
|
assert_ok!(Pallet::<TestRuntime>::submit_parachain_heads(
|
||||||
|
Origin::signed(1),
|
||||||
|
(0, test_relay_header(0, state_root).hash()),
|
||||||
|
parachains,
|
||||||
|
proof,
|
||||||
|
));
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::MissingParachainHead {
|
||||||
|
parachain: ParaId(2),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ignores_parachain_head_if_parachain_head_hash_is_wrong() {
|
||||||
|
let (state_root, proof, _) = prepare_parachain_heads_proof(vec![(1, head_data(1, 0))]);
|
||||||
|
let parachains = vec![(ParaId(1), head_data(1, 10).hash())];
|
||||||
|
run_test(|| {
|
||||||
|
initialize(state_root);
|
||||||
|
assert_ok!(Pallet::<TestRuntime>::submit_parachain_heads(
|
||||||
|
Origin::signed(1),
|
||||||
|
(0, test_relay_header(0, state_root).hash()),
|
||||||
|
parachains,
|
||||||
|
proof,
|
||||||
|
));
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::Parachains(Event::IncorrectParachainHeadHash {
|
||||||
|
parachain: ParaId(1),
|
||||||
|
parachain_head_hash: head_data(1, 10).hash(),
|
||||||
|
actual_parachain_head_hash: head_data(1, 0).hash(),
|
||||||
|
}),
|
||||||
|
topics: vec![],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
generate_owned_bridge_module_tests!(BasicOperatingMode::Normal, BasicOperatingMode::Halted);
|
generate_owned_bridge_module_tests!(BasicOperatingMode::Normal, BasicOperatingMode::Halted);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ construct_runtime! {
|
|||||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
||||||
Grandpa1: pallet_bridge_grandpa::<Instance1>::{Pallet},
|
Grandpa1: pallet_bridge_grandpa::<Instance1>::{Pallet},
|
||||||
Grandpa2: pallet_bridge_grandpa::<Instance2>::{Pallet},
|
Grandpa2: pallet_bridge_grandpa::<Instance2>::{Pallet},
|
||||||
Parachains: pallet_bridge_parachains::{Call, Pallet},
|
Parachains: pallet_bridge_parachains::{Call, Pallet, Event<T>},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ impl frame_system::Config for TestRuntime {
|
|||||||
type AccountId = AccountId;
|
type AccountId = AccountId;
|
||||||
type Lookup = IdentityLookup<Self::AccountId>;
|
type Lookup = IdentityLookup<Self::AccountId>;
|
||||||
type Header = Header;
|
type Header = Header;
|
||||||
type Event = ();
|
type Event = Event;
|
||||||
type BlockHashCount = BlockHashCount;
|
type BlockHashCount = BlockHashCount;
|
||||||
type Version = ();
|
type Version = ();
|
||||||
type PalletInfo = PalletInfo;
|
type PalletInfo = PalletInfo;
|
||||||
@@ -112,6 +112,7 @@ parameter_types! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl pallet_bridge_parachains::Config for TestRuntime {
|
impl pallet_bridge_parachains::Config for TestRuntime {
|
||||||
|
type Event = Event;
|
||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
type BridgesGrandpaPalletInstance = pallet_bridge_grandpa::Instance1;
|
type BridgesGrandpaPalletInstance = pallet_bridge_grandpa::Instance1;
|
||||||
type ParasPalletName = ParasPalletName;
|
type ParasPalletName = ParasPalletName;
|
||||||
@@ -166,7 +167,11 @@ impl Chain for OtherBridgedChain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_test<T>(test: impl FnOnce() -> T) -> T {
|
pub fn run_test<T>(test: impl FnOnce() -> T) -> T {
|
||||||
sp_io::TestExternalities::new(Default::default()).execute_with(test)
|
sp_io::TestExternalities::new(Default::default()).execute_with(|| {
|
||||||
|
System::set_block_number(1);
|
||||||
|
System::reset_events();
|
||||||
|
test()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_relay_header(
|
pub fn test_relay_header(
|
||||||
|
|||||||
Reference in New Issue
Block a user