......@@ -7,17 +7,31 @@ source "$FRAMEWORK_PATH/utils/zombienet.sh"
rococo_dir=$1
westend_dir=$2
__relayer_pid=$3
__finality_relayer_pid=$3
__parachains_relayer_pid=$4
__messages_relayer_pid=$5
logs_dir=$TEST_DIR/logs
helper_script="${BASH_SOURCE%/*}/helper.sh"
relayer_log=$logs_dir/relayer.log
echo -e "Starting rococo-westend relayer. Logs available at: $relayer_log\n"
start_background_process "$helper_script run-relay" $relayer_log relayer_pid
# start finality relayer
finality_relayer_log=$logs_dir/relayer_finality.log
echo -e "Starting rococo-westend finality relayer. Logs available at: $finality_relayer_log\n"
start_background_process "$helper_script run-finality-relay" $finality_relayer_log finality_relayer_pid
# start parachains relayer
parachains_relayer_log=$logs_dir/relayer_parachains.log
echo -e "Starting rococo-westend parachains relayer. Logs available at: $parachains_relayer_log\n"
start_background_process "$helper_script run-parachains-relay" $parachains_relayer_log parachains_relayer_pid
# start messages relayer
messages_relayer_log=$logs_dir/relayer_messages.log
echo -e "Starting rococo-westend messages relayer. Logs available at: $messages_relayer_log\n"
start_background_process "$helper_script run-messages-relay" $messages_relayer_log messages_relayer_pid
run_zndsl ${BASH_SOURCE%/*}/rococo.zndsl $rococo_dir
run_zndsl ${BASH_SOURCE%/*}/westend.zndsl $westend_dir
eval $__relayer_pid="'$relayer_pid'"
eval $__finality_relayer_pid="'$finality_relayer_pid'"
eval $__parachains_relayer_pid="'$parachains_relayer_pid'"
eval $__messages_relayer_pid="'$messages_relayer_pid'"
......@@ -10,33 +10,23 @@ async function run(nodeName, networkInfo, args) {
// start listening to new blocks
let totalGrandpaHeaders = 0;
let initialParachainHeaderImported = false;
let totalParachainHeaders = 0;
api.rpc.chain.subscribeNewHeads(async function (header) {
const apiAtParent = await api.at(header.parentHash);
const apiAtCurrent = await api.at(header.hash);
const currentEvents = await apiAtCurrent.query.system.events();
totalGrandpaHeaders += await utils.ensureOnlyMandatoryGrandpaHeadersImported(
bridgedChain,
apiAtParent,
apiAtCurrent,
currentEvents,
);
initialParachainHeaderImported = await utils.ensureOnlyInitialParachainHeaderImported(
bridgedChain,
apiAtParent,
apiAtCurrent,
currentEvents,
);
totalGrandpaHeaders += await utils.countGrandpaHeaderImports(bridgedChain, currentEvents);
totalParachainHeaders += await utils.countParachainHeaderImports(bridgedChain, currentEvents);
});
// wait given time
await new Promise(resolve => setTimeout(resolve, exitAfterSeconds * 1000));
// if we haven't seen any new GRANDPA or parachain headers => fail
if (totalGrandpaHeaders == 0) {
// if we haven't seen many (>1) new GRANDPA or parachain headers => fail
if (totalGrandpaHeaders <= 1) {
throw new Error("No bridged relay chain headers imported");
}
if (!initialParachainHeaderImported) {
if (totalParachainHeaders <= 1) {
throw new Error("No bridged parachain headers imported");
}
}
......
async function run(nodeName, networkInfo, args) {
const {wsUri, userDefinedTypes} = networkInfo.nodesByName[nodeName];
const api = await zombie.connect(wsUri, userDefinedTypes);
const accountAddress = args[0];
const accountData = await api.query.system.account(accountAddress);
const accountBalance = accountData.data['free'];
console.log("Balance of " + accountAddress + ": " + accountBalance);
return accountBalance;
}
module.exports = {run}
......@@ -3,10 +3,10 @@ Network: {{ENV_PATH}}/bridge_hub_westend_local_network.toml
Creds: config
# send 5 ROC to //Alice from Rococo AH to Westend AH
asset-hub-westend-collator1: run {{ENV_PATH}}/helper.sh with "reserve-transfer-assets-from-asset-hub-rococo-local 5000000000000" within 120 seconds
asset-hub-westend-collator1: run {{ENV_PATH}}/helper.sh with "auto-log reserve-transfer-assets-from-asset-hub-rococo-local 5000000000000" within 120 seconds
# check that //Alice received at least 4.8 ROC on Westend AH
asset-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/wrapped-assets-balance.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,4800000000000,Rococo" within 600 seconds
# check that the relayer //Charlie is rewarded by Westend AH
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/relayer-rewards.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y,0x00000002,0x6268726F,ThisChain,0" within 30 seconds
# relayer //Ferdie is rewarded for delivering messages from Rococo BH
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/relayer-rewards.js with "5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw,0x00000002,0x6268726F,ThisChain,0" within 300 seconds
Description: Finality and parachain relays should have the constant balance, because their transactions are free
Network: {{ENV_PATH}}/bridge_hub_rococo_local_network.toml
Creds: config
# local chain spec gives `1u64 << 60` tokens to every endowed account: if it'll ever
# change, it'd need to be fixed here as well
# //Charlie only submits free and mandatory relay chain headers, so the balance should stay the same
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y" return is 1152921504606846976 within 30 seconds
# //Dave only submits free parachain headers, so the balance should stay the same
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy" return is 1152921504606846976 within 30 seconds
......@@ -18,8 +18,14 @@ ensure_process_file $env_pid $TEST_DIR/westend.env 300
westend_dir=`cat $TEST_DIR/westend.env`
echo
run_zndsl ${BASH_SOURCE%/*}/roc-relayer-balance-does-not-change.zndsl $rococo_dir
run_zndsl ${BASH_SOURCE%/*}/wnd-relayer-balance-does-not-change.zndsl $westend_dir
run_zndsl ${BASH_SOURCE%/*}/roc-reaches-westend.zndsl $westend_dir
run_zndsl ${BASH_SOURCE%/*}/wnd-reaches-rococo.zndsl $rococo_dir
run_zndsl ${BASH_SOURCE%/*}/wroc-reaches-rococo.zndsl $rococo_dir
run_zndsl ${BASH_SOURCE%/*}/wwnd-reaches-westend.zndsl $westend_dir
run_zndsl ${BASH_SOURCE%/*}/roc-relayer-balance-does-not-change.zndsl $rococo_dir
run_zndsl ${BASH_SOURCE%/*}/wnd-relayer-balance-does-not-change.zndsl $westend_dir
......@@ -3,10 +3,10 @@ Network: {{ENV_PATH}}/bridge_hub_rococo_local_network.toml
Creds: config
# send 5 WND to //Alice from Westend AH to Rococo AH
asset-hub-rococo-collator1: run {{ENV_PATH}}/helper.sh with "reserve-transfer-assets-from-asset-hub-westend-local 5000000000000" within 120 seconds
asset-hub-rococo-collator1: run {{ENV_PATH}}/helper.sh with "auto-log reserve-transfer-assets-from-asset-hub-westend-local 5000000000000" within 120 seconds
# check that //Alice received at least 4.8 WND on Rococo AH
asset-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/wrapped-assets-balance.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,4800000000000,Westend" within 600 seconds
# check that the relayer //Charlie is rewarded by Rococo AH
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/relayer-rewards.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y,0x00000002,0x62687764,ThisChain,0" within 30 seconds
# relayer //Eve is rewarded for delivering messages from Westend BH
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/relayer-rewards.js with "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL,0x00000002,0x62687764,ThisChain,0" within 300 seconds
Description: Finality and parachain relays should have the constant balance, because their transactions are free
Network: {{ENV_PATH}}/bridge_hub_westend_local_network.toml
Creds: config
# local chain spec gives `1u64 << 60` tokens to every endowed account: if it'll ever
# change, it'd need to be fixed here as well
# //Charlie only submits free and mandatory relay chain headers, so the balance should stay the same
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y" return is 1152921504606846976 within 30 seconds
# //Dave only submits free parachain headers, so the balance should stay the same
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy" return is 1152921504606846976 within 30 seconds
Description: While relayer is idle, we only sync free Rococo (and a single Rococo BH) headers to Westend BH.
Network: {{ENV_PATH}}/bridge_hub_westend_local_network.toml
Creds: config
# local chain spec gives `1u64 << 60` tokens to every endowed account: if it'll ever
# change, it'd need to be fixed here as well
# //Charlie only submits free and mandatory relay chain headers, so the balance should stay the same
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y" return is 1152921504606846976 within 30 seconds
# //Dave only submits free parachain headers, so the balance should stay the same
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy" return is 1152921504606846976 within 30 seconds
# ensure that we have synced multiple relay and parachain headers while idle. This includes both
# headers that were generated while relay was offline and those in the next 100 seconds while script is active.
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/multiple-headers-synced.js with "300,rococo-at-westend" within 600 seconds
# //Charlie only submits free and mandatory relay chain headers, so the balance should stay the same
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y" return is 1152921504606846976 within 30 seconds
# //Dave only submits free parachain headers, so the balance should stay the same
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy" return is 1152921504606846976 within 30 seconds
......@@ -22,7 +22,7 @@ echo
# which is expected to be 60 seconds for the test environment.
echo -e "Sleeping 90s before starting relayer ...\n"
sleep 90
${BASH_SOURCE%/*}/../../environments/rococo-westend/start_relayer.sh $rococo_dir $westend_dir relayer_pid
${BASH_SOURCE%/*}/../../environments/rococo-westend/start_relayer.sh $rococo_dir $westend_dir finality_relayer_pid parachains_relayer_pid messages_relayer_pid
run_zndsl ${BASH_SOURCE%/*}/rococo-to-westend.zndsl $westend_dir
run_zndsl ${BASH_SOURCE%/*}/westend-to-rococo.zndsl $rococo_dir
......
Description: While relayer is idle, we only sync free Westend (and a single Westend BH) headers to Rococo BH.
Network: {{ENV_PATH}}/bridge_hub_rococo_local_network.toml
Creds: config
# local chain spec gives `1u64 << 60` tokens to every endowed account: if it'll ever
# change, it'd need to be fixed here as well
# //Charlie has inital balance
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y" return is 1152921504606846976 within 30 seconds
# //Dave has inital balance
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy" return is 1152921504606846976 within 30 seconds
# ensure that we have synced multiple relay and parachain headers while idle. This includes both
# headers that were generated while relay was offline and those in the next 100 seconds while script is active.
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/multiple-headers-synced.js with "300,westend-at-rococo" within 600 seconds
# //Charlie only submits free and mandatory relay chain headers, so the balance should stay the same
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y" return is 1152921504606846976 within 30 seconds
# //Dave only submits free parachain headers, so the balance should stay the same
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-asset-balance.js with "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy" return is 1152921504606846976 within 30 seconds
Description: While relayer is idle, we only sync mandatory Rococo (and a single Rococo BH) headers to Westend BH.
Network: {{ENV_PATH}}/bridge_hub_westend_local_network.toml
Creds: config
# ensure that relayer is only syncing mandatory headers while idle. This includes both headers that were
# generated while relay was offline and those in the next 100 seconds while script is active.
bridge-hub-westend-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/only-mandatory-headers-synced-when-idle.js with "300,rococo-at-westend" within 600 seconds
Description: While relayer is idle, we only sync mandatory Westend (and a single Westend BH) headers to Rococo BH.
Network: {{ENV_PATH}}/bridge_hub_rococo_local_network.toml
Creds: config
# ensure that relayer is only syncing mandatory headers while idle. This includes both headers that were
# generated while relay was offline and those in the next 100 seconds while script is active.
bridge-hub-rococo-collator1: js-script {{FRAMEWORK_PATH}}/js-helpers/only-mandatory-headers-synced-when-idle.js with "300,westend-at-rococo" within 600 seconds
......@@ -312,6 +312,9 @@ fn build_polkadot_full_node(
overseer_message_channel_capacity_override: None,
malus_finality_delay: None,
hwbench,
execute_workers_max_num: None,
prepare_workers_hard_max_num: None,
prepare_workers_soft_max_num: None,
},
)?;
......
......@@ -27,6 +27,7 @@ sp-staking = { path = "../../../substrate/primitives/staking", default-features
frame-support = { path = "../../../substrate/frame/support", default-features = false }
frame-system = { path = "../../../substrate/frame/system", default-features = false }
pallet-authorship = { path = "../../../substrate/frame/authorship", default-features = false }
pallet-balances = { path = "../../../substrate/frame/balances", default-features = false }
pallet-session = { path = "../../../substrate/frame/session", default-features = false }
frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true }
......@@ -38,7 +39,6 @@ sp-tracing = { path = "../../../substrate/primitives/tracing" }
sp-runtime = { path = "../../../substrate/primitives/runtime" }
pallet-timestamp = { path = "../../../substrate/frame/timestamp" }
sp-consensus-aura = { path = "../../../substrate/primitives/consensus/aura" }
pallet-balances = { path = "../../../substrate/frame/balances" }
pallet-aura = { path = "../../../substrate/frame/aura" }
[features]
......@@ -59,6 +59,7 @@ std = [
"frame-system/std",
"log/std",
"pallet-authorship/std",
"pallet-balances/std",
"pallet-session/std",
"rand/std",
"scale-info/std",
......
......@@ -121,7 +121,7 @@ pub mod pallet {
use sp_std::vec::Vec;
/// The in-code storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);
type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as SystemConfig>::AccountId>>::Balance;
......
......@@ -17,9 +17,107 @@
//! A module that is responsible for migration of storage for Collator Selection.
use super::*;
use frame_support::traits::OnRuntimeUpgrade;
use frame_support::traits::{OnRuntimeUpgrade, UncheckedOnRuntimeUpgrade};
use log;
/// Migrate to v2. Should have been part of <https://github.com/paritytech/polkadot-sdk/pull/1340>.
pub mod v2 {
use super::*;
use frame_support::{
pallet_prelude::*,
storage_alias,
traits::{Currency, ReservableCurrency},
};
use sp_runtime::traits::{Saturating, Zero};
#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;
/// [`UncheckedMigrationToV2`] wrapped in a
/// [`VersionedMigration`](frame_support::migrations::VersionedMigration), ensuring the
/// migration is only performed when on-chain version is 1.
pub type MigrationToV2<T> = frame_support::migrations::VersionedMigration<
1,
2,
UncheckedMigrationToV2<T>,
Pallet<T>,
<T as frame_system::Config>::DbWeight,
>;
#[storage_alias]
pub type Candidates<T: Config> = StorageValue<
Pallet<T>,
BoundedVec<CandidateInfo<<T as frame_system::Config>::AccountId, <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance>, <T as Config>::MaxCandidates>,
ValueQuery,
>;
/// Migrate to V2.
pub struct UncheckedMigrationToV2<T>(sp_std::marker::PhantomData<T>);
impl<T: Config + pallet_balances::Config> UncheckedOnRuntimeUpgrade for UncheckedMigrationToV2<T> {
fn on_runtime_upgrade() -> Weight {
let mut weight = Weight::zero();
let mut count: u64 = 0;
// candidates who exist under the old `Candidates` key
let candidates = Candidates::<T>::take();
// New candidates who have registered since the upgrade. Under normal circumstances,
// this should not exist because the migration should be applied when the upgrade
// happens. But in Polkadot/Kusama we messed this up, and people registered under
// `CandidateList` while their funds were locked in `Candidates`.
let new_candidate_list = CandidateList::<T>::get();
if new_candidate_list.len().is_zero() {
// The new list is empty, so this is essentially being applied correctly. We just
// put the candidates into the new storage item.
CandidateList::<T>::put(&candidates);
// 1 write for the new list
weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 1));
} else {
// Oops, the runtime upgraded without the migration. There are new candidates in
// `CandidateList`. So, let's just refund the old ones and assume they have already
// started participating in the new system.
for candidate in candidates {
let err = T::Currency::unreserve(&candidate.who, candidate.deposit);
if err > Zero::zero() {
log::error!(
target: LOG_TARGET,
"{:?} balance was unable to be unreserved from {:?}",
err, &candidate.who,
);
}
count.saturating_inc();
}
weight.saturating_accrue(
<<T as pallet_balances::Config>::WeightInfo as pallet_balances::WeightInfo>::force_unreserve().saturating_mul(count.into()),
);
}
log::info!(
target: LOG_TARGET,
"Unreserved locked bond of {} candidates, upgraded storage to version 2",
count,
);
weight.saturating_accrue(T::DbWeight::get().reads_writes(3, 2));
weight
}
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::DispatchError> {
let number_of_candidates = Candidates::<T>::get().to_vec().len();
Ok((number_of_candidates as u32).encode())
}
#[cfg(feature = "try-runtime")]
fn post_upgrade(_number_of_candidates: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
let new_number_of_candidates = Candidates::<T>::get().to_vec().len();
assert_eq!(
new_number_of_candidates, 0 as usize,
"after migration, the candidates map should be empty"
);
Ok(())
}
}
}
/// Version 1 Migration
/// This migration ensures that any existing `Invulnerables` storage lists are sorted.
pub mod v1 {
......@@ -90,3 +188,136 @@ pub mod v1 {
}
}
}
#[cfg(all(feature = "try-runtime", test))]
mod tests {
use super::*;
use crate::{
migration::v2::Candidates,
mock::{new_test_ext, Balances, Test},
};
use frame_support::{
traits::{Currency, ReservableCurrency, StorageVersion},
BoundedVec,
};
use sp_runtime::traits::ConstU32;
#[test]
fn migrate_to_v2_with_new_candidates() {
new_test_ext().execute_with(|| {
let storage_version = StorageVersion::new(1);
storage_version.put::<Pallet<Test>>();
let one = 1u64;
let two = 2u64;
let three = 3u64;
let deposit = 10u64;
// Set balance to 100
Balances::make_free_balance_be(&one, 100u64);
Balances::make_free_balance_be(&two, 100u64);
Balances::make_free_balance_be(&three, 100u64);
// Reservations: 10 for the "old" candidacy and 10 for the "new"
Balances::reserve(&one, 10u64).unwrap(); // old
Balances::reserve(&two, 20u64).unwrap(); // old + new
Balances::reserve(&three, 10u64).unwrap(); // new
// Candidate info
let candidate_one = CandidateInfo { who: one, deposit };
let candidate_two = CandidateInfo { who: two, deposit };
let candidate_three = CandidateInfo { who: three, deposit };
// Storage lists
let bounded_candidates =
BoundedVec::<CandidateInfo<u64, u64>, ConstU32<20>>::try_from(vec![
candidate_one.clone(),
candidate_two.clone(),
])
.expect("it works");
let bounded_candidate_list =
BoundedVec::<CandidateInfo<u64, u64>, ConstU32<20>>::try_from(vec![
candidate_two.clone(),
candidate_three.clone(),
])
.expect("it works");
// Set storage
Candidates::<Test>::put(bounded_candidates);
CandidateList::<Test>::put(bounded_candidate_list.clone());
// Sanity check
assert_eq!(Balances::free_balance(one), 90);
assert_eq!(Balances::free_balance(two), 80);
assert_eq!(Balances::free_balance(three), 90);
// Run migration
v2::MigrationToV2::<Test>::on_runtime_upgrade();
let new_storage_version = StorageVersion::get::<Pallet<Test>>();
assert_eq!(new_storage_version, 2);
// 10 should have been unreserved from the old candidacy
assert_eq!(Balances::free_balance(one), 100);
assert_eq!(Balances::free_balance(two), 90);
assert_eq!(Balances::free_balance(three), 90);
// The storage item should be gone
assert!(Candidates::<Test>::get().is_empty());
// The new storage item should be preserved
assert_eq!(CandidateList::<Test>::get(), bounded_candidate_list);
});
}
#[test]
fn migrate_to_v2_without_new_candidates() {
new_test_ext().execute_with(|| {
let storage_version = StorageVersion::new(1);
storage_version.put::<Pallet<Test>>();
let one = 1u64;
let two = 2u64;
let deposit = 10u64;
// Set balance to 100
Balances::make_free_balance_be(&one, 100u64);
Balances::make_free_balance_be(&two, 100u64);
// Reservations
Balances::reserve(&one, 10u64).unwrap(); // old
Balances::reserve(&two, 10u64).unwrap(); // old
// Candidate info
let candidate_one = CandidateInfo { who: one, deposit };
let candidate_two = CandidateInfo { who: two, deposit };
// Storage lists
let bounded_candidates =
BoundedVec::<CandidateInfo<u64, u64>, ConstU32<20>>::try_from(vec![
candidate_one.clone(),
candidate_two.clone(),
])
.expect("it works");
// Set storage
Candidates::<Test>::put(bounded_candidates.clone());
// Sanity check
assert_eq!(Balances::free_balance(one), 90);
assert_eq!(Balances::free_balance(two), 90);
// Run migration
v2::MigrationToV2::<Test>::on_runtime_upgrade();
let new_storage_version = StorageVersion::get::<Pallet<Test>>();
assert_eq!(new_storage_version, 2);
// Nothing changes deposit-wise
assert_eq!(Balances::free_balance(one), 90);
assert_eq!(Balances::free_balance(two), 90);
// The storage item should be gone
assert!(Candidates::<Test>::get().is_empty());
// The new storage item should have the info now
assert_eq!(CandidateList::<Test>::get(), bounded_candidates);
});
}
}
......@@ -916,7 +916,8 @@ impl<T: Config> SendXcm for Pallet<T> {
let price = T::PriceForSiblingDelivery::price_for_delivery(id, &xcm);
let versioned_xcm = T::VersionWrapper::wrap_version(&d, xcm)
.map_err(|()| SendError::DestinationUnsupported)?;
validate_xcm_nesting(&versioned_xcm)
versioned_xcm
.validate_xcm_nesting()
.map_err(|()| SendError::ExceedsMaxMessageSize)?;
Ok(((id, versioned_xcm), price))
......@@ -932,10 +933,6 @@ impl<T: Config> SendXcm for Pallet<T> {
fn deliver((id, xcm): (ParaId, VersionedXcm<()>)) -> Result<XcmHash, SendError> {
let hash = xcm.using_encoded(sp_io::hashing::blake2_256);
defensive_assert!(
validate_xcm_nesting(&xcm).is_ok(),
"Tickets are valid prior to delivery by trait XCM; qed"
);
match Self::send_fragment(id, XcmpMessageFormat::ConcatenatedVersionedXcm, xcm) {
Ok(_) => {
......@@ -950,16 +947,6 @@ impl<T: Config> SendXcm for Pallet<T> {
}
}
/// Checks that the XCM is decodable with `MAX_XCM_DECODE_DEPTH`.
///
/// Note that this uses the limit of the sender - not the receiver. It it best effort.
pub(crate) fn validate_xcm_nesting(xcm: &VersionedXcm<()>) -> Result<(), ()> {
xcm.using_encoded(|mut enc| {
VersionedXcm::<()>::decode_all_with_depth_limit(MAX_XCM_DECODE_DEPTH, &mut enc).map(|_| ())
})
.map_err(|_| ())
}
impl<T: Config> FeeTracker for Pallet<T> {
type Id = ParaId;
......
......@@ -11,6 +11,7 @@ publish = false
workspace = true
[dependencies]
# Substrate
sp-core = { path = "../../../../../../../substrate/primitives/core", default-features = false }
sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false }
......
......@@ -360,7 +360,7 @@ macro_rules! impl_send_transact_helpers_for_relay_chain {
recipient: $crate::impls::ParaId,
call: $crate::impls::DoubleEncoded<()>
) {
use $crate::impls::{bx, Chain, RelayChain, Encode};
use $crate::impls::{bx, Chain, RelayChain};
<Self as $crate::impls::TestExt>::execute_with(|| {
let root_origin = <Self as Chain>::RuntimeOrigin::root();
......@@ -368,10 +368,10 @@ macro_rules! impl_send_transact_helpers_for_relay_chain {
let xcm = $crate::impls::xcm_transact_unpaid_execution(call, $crate::impls::OriginKind::Superuser);
// Send XCM `Transact`
$crate::impls::assert_ok!(<Self as [<$chain RelayPallet>]>::XcmPallet::send_blob(
$crate::impls::assert_ok!(<Self as [<$chain RelayPallet>]>::XcmPallet::send(
root_origin,
bx!(destination.into()),
xcm.encode().try_into().unwrap(),
bx!(xcm),
));
Self::assert_xcm_pallet_sent();
});
......