mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 11:01:01 +00:00
migrate eth PoA pallet to frame v2 (#1091)
This commit is contained in:
committed by
Bastian Köcher
parent
239790fc72
commit
92b3a69126
@@ -22,10 +22,10 @@ use crate::test_utils::{
|
||||
};
|
||||
|
||||
use bp_eth_poa::{compute_merkle_root, U256};
|
||||
use frame_benchmarking::benchmarks_instance;
|
||||
use frame_benchmarking::benchmarks_instance_pallet;
|
||||
use frame_system::RawOrigin;
|
||||
|
||||
benchmarks_instance! {
|
||||
benchmarks_instance_pallet! {
|
||||
// Benchmark `import_unsigned_header` extrinsic with the best possible conditions:
|
||||
// * Parent header is finalized.
|
||||
// * New header doesn't require receipts.
|
||||
@@ -153,7 +153,7 @@ benchmarks_instance! {
|
||||
let validators = validators(num_validators);
|
||||
|
||||
// Want to prune eligible blocks between [0, n)
|
||||
BlocksToPrune::<I>::put(PruningRange {
|
||||
BlocksToPrune::<T, I>::put(PruningRange {
|
||||
oldest_unpruned_block: 0,
|
||||
oldest_block_to_keep: n as u64,
|
||||
});
|
||||
@@ -172,8 +172,8 @@ benchmarks_instance! {
|
||||
let storage = BridgeStorage::<T, I>::new();
|
||||
let max_pruned: u64 = (n - 1) as _;
|
||||
assert_eq!(storage.best_block().0.number, (n + 1) as u64);
|
||||
assert!(HeadersByNumber::<I>::get(&0).is_none());
|
||||
assert!(HeadersByNumber::<I>::get(&max_pruned).is_none());
|
||||
assert!(HeadersByNumber::<T, I>::get(&0).is_none());
|
||||
assert!(HeadersByNumber::<T, I>::get(&max_pruned).is_none());
|
||||
}
|
||||
|
||||
// The goal of this bench is to import a block which contains a transaction receipt. The receipt
|
||||
@@ -216,7 +216,7 @@ benchmarks_instance! {
|
||||
}
|
||||
}
|
||||
|
||||
fn initialize_bench<T: Config<I>, I: Instance>(num_validators: usize) -> AuraHeader {
|
||||
fn initialize_bench<T: Config<I>, I: 'static>(num_validators: usize) -> AuraHeader {
|
||||
// Initialize storage with some initial header
|
||||
let initial_header = build_genesis_header(&validator(0));
|
||||
let initial_difficulty = initial_header.difficulty;
|
||||
|
||||
@@ -284,7 +284,6 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::mock::{insert_header, run_test, validator, validators_addresses, HeaderBuilder, TestRuntime};
|
||||
use crate::{BridgeStorage, FinalityCache, HeaderToImport};
|
||||
use frame_support::StorageMap;
|
||||
|
||||
const TOTAL_VALIDATORS: usize = 5;
|
||||
|
||||
|
||||
@@ -176,9 +176,7 @@ mod tests {
|
||||
validators_change_receipt, HeaderBuilder, KeepSomeHeadersBehindBest, TestRuntime, GAS_LIMIT,
|
||||
};
|
||||
use crate::validators::ValidatorsSource;
|
||||
use crate::DefaultInstance;
|
||||
use crate::{BlocksToPrune, BridgeStorage, Headers, PruningRange};
|
||||
use frame_support::{StorageMap, StorageValue};
|
||||
use secp256k1::SecretKey;
|
||||
|
||||
const TOTAL_VALIDATORS: usize = 3;
|
||||
@@ -367,7 +365,7 @@ mod tests {
|
||||
step += 3;
|
||||
}
|
||||
assert_eq!(
|
||||
BlocksToPrune::<DefaultInstance>::get(),
|
||||
BlocksToPrune::<TestRuntime, ()>::get(),
|
||||
PruningRange {
|
||||
oldest_unpruned_block: 11,
|
||||
oldest_block_to_keep: 14,
|
||||
@@ -394,7 +392,7 @@ mod tests {
|
||||
.unwrap();
|
||||
assert_eq!(finalized_blocks, expected_blocks);
|
||||
assert_eq!(
|
||||
BlocksToPrune::<DefaultInstance>::get(),
|
||||
BlocksToPrune::<TestRuntime, ()>::get(),
|
||||
PruningRange {
|
||||
oldest_unpruned_block: 15,
|
||||
oldest_block_to_keep: 15,
|
||||
|
||||
+232
-181
@@ -21,14 +21,8 @@
|
||||
use crate::finality::{CachedFinalityVotes, FinalityVotes};
|
||||
use bp_eth_poa::{Address, AuraHeader, HeaderId, RawTransaction, RawTransactionReceipt, Receipt, H256, U256};
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::{decl_module, decl_storage, traits::Get};
|
||||
use sp_runtime::{
|
||||
transaction_validity::{
|
||||
InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource, TransactionValidity,
|
||||
UnknownTransaction, ValidTransaction,
|
||||
},
|
||||
RuntimeDebug,
|
||||
};
|
||||
use frame_support::traits::Get;
|
||||
use sp_runtime::RuntimeDebug;
|
||||
use sp_std::{cmp::Ord, collections::btree_map::BTreeMap, prelude::*};
|
||||
|
||||
pub use validators::{ValidatorsConfiguration, ValidatorsSource};
|
||||
@@ -369,34 +363,53 @@ impl<AccountId> OnHeadersSubmitted<AccountId> for () {
|
||||
fn on_valid_headers_finalized(_submitter: AccountId, _finalized: u64) {}
|
||||
}
|
||||
|
||||
/// The module configuration trait.
|
||||
pub trait Config<I = DefaultInstance>: frame_system::Config {
|
||||
/// Aura configuration.
|
||||
type AuraConfiguration: Get<AuraConfiguration>;
|
||||
/// Validators configuration.
|
||||
type ValidatorsConfiguration: Get<validators::ValidatorsConfiguration>;
|
||||
pub use pallet::*;
|
||||
|
||||
/// Interval (in blocks) for for finality votes caching.
|
||||
/// If None, cache is disabled.
|
||||
///
|
||||
/// Ideally, this should either be None (when we are sure that there won't
|
||||
/// be any significant finalization delays), or something that is bit larger
|
||||
/// than average finalization delay.
|
||||
type FinalityVotesCachingInterval: Get<Option<u64>>;
|
||||
/// Headers pruning strategy.
|
||||
type PruningStrategy: PruningStrategy;
|
||||
/// Header timestamp verification against current on-chain time.
|
||||
type ChainTime: ChainTime;
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_system::pallet_prelude::*;
|
||||
|
||||
/// Handler for headers submission result.
|
||||
type OnHeadersSubmitted: OnHeadersSubmitted<Self::AccountId>;
|
||||
}
|
||||
#[pallet::config]
|
||||
pub trait Config<I: 'static = ()>: frame_system::Config {
|
||||
/// Aura configuration.
|
||||
type AuraConfiguration: Get<AuraConfiguration>;
|
||||
/// Validators configuration.
|
||||
type ValidatorsConfiguration: Get<validators::ValidatorsConfiguration>;
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Config<I>, I: Instance = DefaultInstance> for enum Call where origin: T::Origin {
|
||||
/// Interval (in blocks) for for finality votes caching.
|
||||
/// If None, cache is disabled.
|
||||
///
|
||||
/// Ideally, this should either be None (when we are sure that there won't
|
||||
/// be any significant finalization delays), or something that is bit larger
|
||||
/// than average finalization delay.
|
||||
type FinalityVotesCachingInterval: Get<Option<u64>>;
|
||||
/// Headers pruning strategy.
|
||||
type PruningStrategy: PruningStrategy;
|
||||
/// Header timestamp verification against current on-chain time.
|
||||
type ChainTime: ChainTime;
|
||||
|
||||
/// Handler for headers submission result.
|
||||
type OnHeadersSubmitted: OnHeadersSubmitted<Self::AccountId>;
|
||||
}
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(super) trait Store)]
|
||||
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
/// Import single Aura header. Requires transaction to be **UNSIGNED**.
|
||||
#[weight = 0] // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78)
|
||||
pub fn import_unsigned_header(origin, header: AuraHeader, receipts: Option<Vec<Receipt>>) {
|
||||
#[pallet::weight(0)] // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78)
|
||||
pub fn import_unsigned_header(
|
||||
origin: OriginFor<T>,
|
||||
header: AuraHeader,
|
||||
receipts: Option<Vec<Receipt>>,
|
||||
) -> DispatchResult {
|
||||
frame_system::ensure_none(origin)?;
|
||||
|
||||
import::import_header(
|
||||
@@ -408,7 +421,10 @@ decl_module! {
|
||||
header,
|
||||
&T::ChainTime::default(),
|
||||
receipts,
|
||||
).map_err(|e| e.msg())?;
|
||||
)
|
||||
.map_err(|e| e.msg())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Import Aura chain headers in a single **SIGNED** transaction.
|
||||
@@ -417,8 +433,11 @@ decl_module! {
|
||||
///
|
||||
/// This should be used with caution - passing too many headers could lead to
|
||||
/// enormous block production/import time.
|
||||
#[weight = 0] // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78)
|
||||
pub fn import_signed_headers(origin, headers_with_receipts: Vec<(AuraHeader, Option<Vec<Receipt>>)>) {
|
||||
#[pallet::weight(0)] // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78)
|
||||
pub fn import_signed_headers(
|
||||
origin: OriginFor<T>,
|
||||
headers_with_receipts: Vec<(AuraHeader, Option<Vec<Receipt>>)>,
|
||||
) -> DispatchResult {
|
||||
let submitter = frame_system::ensure_signed(origin)?;
|
||||
let mut finalized_headers = BTreeMap::new();
|
||||
let import_result = import::import_headers(
|
||||
@@ -435,77 +454,147 @@ decl_module! {
|
||||
// if we have finalized some headers, we will reward their submitters even
|
||||
// if current submitter has provided some invalid headers
|
||||
for (f_submitter, f_count) in finalized_headers {
|
||||
T::OnHeadersSubmitted::on_valid_headers_finalized(
|
||||
f_submitter,
|
||||
f_count,
|
||||
);
|
||||
T::OnHeadersSubmitted::on_valid_headers_finalized(f_submitter, f_count);
|
||||
}
|
||||
|
||||
// now track/penalize current submitter for providing new headers
|
||||
match import_result {
|
||||
Ok((useful, useless)) =>
|
||||
T::OnHeadersSubmitted::on_valid_headers_submitted(submitter, useful, useless),
|
||||
Ok((useful, useless)) => T::OnHeadersSubmitted::on_valid_headers_submitted(submitter, useful, useless),
|
||||
Err(error) => {
|
||||
// even though we may have accept some headers, we do not want to reward someone
|
||||
// who provides invalid headers
|
||||
T::OnHeadersSubmitted::on_invalid_headers_submitted(submitter);
|
||||
return Err(error.msg().into());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::validate_unsigned]
|
||||
impl<T: Config<I>, I: 'static> ValidateUnsigned for Pallet<T, I> {
|
||||
type Call = Call<T, I>;
|
||||
|
||||
fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
|
||||
match *call {
|
||||
Self::Call::import_unsigned_header(ref header, ref receipts) => {
|
||||
let accept_result = verification::accept_aura_header_into_pool(
|
||||
&BridgeStorage::<T, I>::new(),
|
||||
&T::AuraConfiguration::get(),
|
||||
&T::ValidatorsConfiguration::get(),
|
||||
&pool_configuration(),
|
||||
header,
|
||||
&T::ChainTime::default(),
|
||||
receipts.as_ref(),
|
||||
);
|
||||
|
||||
match accept_result {
|
||||
Ok((requires, provides)) => Ok(ValidTransaction {
|
||||
priority: TransactionPriority::max_value(),
|
||||
requires,
|
||||
provides,
|
||||
longevity: TransactionLongevity::max_value(),
|
||||
propagate: true,
|
||||
}),
|
||||
// UnsignedTooFarInTheFuture is the special error code used to limit
|
||||
// number of transactions in the pool - we do not want to ban transaction
|
||||
// in this case (see verification.rs for details)
|
||||
Err(error::Error::UnsignedTooFarInTheFuture) => {
|
||||
UnknownTransaction::Custom(error::Error::UnsignedTooFarInTheFuture.code()).into()
|
||||
}
|
||||
Err(error) => InvalidTransaction::Custom(error.code()).into(),
|
||||
}
|
||||
}
|
||||
_ => InvalidTransaction::Call.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
trait Store for Pallet<T: Config<I>, I: Instance = DefaultInstance> as Bridge {
|
||||
/// Best known block.
|
||||
BestBlock: (HeaderId, U256);
|
||||
/// Best finalized block.
|
||||
FinalizedBlock: HeaderId;
|
||||
/// Range of blocks that we want to prune.
|
||||
BlocksToPrune: PruningRange;
|
||||
/// Map of imported headers by hash.
|
||||
Headers: map hasher(identity) H256 => Option<StoredHeader<T::AccountId>>;
|
||||
/// Map of imported header hashes by number.
|
||||
HeadersByNumber: map hasher(blake2_128_concat) u64 => Option<Vec<H256>>;
|
||||
/// Map of cached finality data by header hash.
|
||||
FinalityCache: map hasher(identity) H256 => Option<FinalityVotes<T::AccountId>>;
|
||||
/// The ID of next validator set.
|
||||
NextValidatorsSetId: u64;
|
||||
/// Map of validators sets by their id.
|
||||
ValidatorsSets: map hasher(twox_64_concat) u64 => Option<ValidatorsSet>;
|
||||
/// Validators sets reference count. Each header that is authored by this set increases
|
||||
/// the reference count. When we prune this header, we decrease the reference count.
|
||||
/// When it reaches zero, we are free to prune validator set as well.
|
||||
ValidatorsSetsRc: map hasher(twox_64_concat) u64 => Option<u64>;
|
||||
/// Map of validators set changes scheduled by given header.
|
||||
ScheduledChanges: map hasher(identity) H256 => Option<AuraScheduledChange>;
|
||||
/// Best known block.
|
||||
#[pallet::storage]
|
||||
pub(super) type BestBlock<T: Config<I>, I: 'static = ()> = StorageValue<_, (HeaderId, U256), ValueQuery>;
|
||||
|
||||
/// Best finalized block.
|
||||
#[pallet::storage]
|
||||
pub(super) type FinalizedBlock<T: Config<I>, I: 'static = ()> = StorageValue<_, HeaderId, ValueQuery>;
|
||||
|
||||
/// Range of blocks that we want to prune.
|
||||
#[pallet::storage]
|
||||
pub(super) type BlocksToPrune<T: Config<I>, I: 'static = ()> = StorageValue<_, PruningRange, ValueQuery>;
|
||||
|
||||
/// Map of imported headers by hash.
|
||||
#[pallet::storage]
|
||||
pub(super) type Headers<T: Config<I>, I: 'static = ()> = StorageMap<_, Identity, H256, StoredHeader<T::AccountId>>;
|
||||
|
||||
/// Map of imported header hashes by number.
|
||||
#[pallet::storage]
|
||||
pub(super) type HeadersByNumber<T: Config<I>, I: 'static = ()> = StorageMap<_, Blake2_128Concat, u64, Vec<H256>>;
|
||||
|
||||
/// Map of cached finality data by header hash.
|
||||
#[pallet::storage]
|
||||
pub(super) type FinalityCache<T: Config<I>, I: 'static = ()> =
|
||||
StorageMap<_, Identity, H256, FinalityVotes<T::AccountId>>;
|
||||
|
||||
/// The ID of next validator set.
|
||||
#[pallet::storage]
|
||||
pub(super) type NextValidatorsSetId<T: Config<I>, I: 'static = ()> = StorageValue<_, u64, ValueQuery>;
|
||||
|
||||
/// Map of validators sets by their id.
|
||||
#[pallet::storage]
|
||||
pub(super) type ValidatorsSets<T: Config<I>, I: 'static = ()> = StorageMap<_, Twox64Concat, u64, ValidatorsSet>;
|
||||
|
||||
/// Validators sets reference count. Each header that is authored by this set increases
|
||||
/// the reference count. When we prune this header, we decrease the reference count.
|
||||
/// When it reaches zero, we are free to prune validator set as well.
|
||||
#[pallet::storage]
|
||||
pub(super) type ValidatorsSetsRc<T: Config<I>, I: 'static = ()> = StorageMap<_, Twox64Concat, u64, u64>;
|
||||
|
||||
/// Map of validators set changes scheduled by given header.
|
||||
#[pallet::storage]
|
||||
pub(super) type ScheduledChanges<T: Config<I>, I: 'static = ()> =
|
||||
StorageMap<_, Identity, H256, AuraScheduledChange>;
|
||||
|
||||
#[pallet::genesis_config]
|
||||
pub struct GenesisConfig {
|
||||
/// PoA header to start with.
|
||||
pub initial_header: AuraHeader,
|
||||
/// Initial PoA chain difficulty.
|
||||
pub initial_difficulty: U256,
|
||||
/// Initial PoA validators set.
|
||||
pub initial_validators: Vec<Address>,
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(initial_header): AuraHeader;
|
||||
config(initial_difficulty): U256;
|
||||
config(initial_validators): Vec<Address>;
|
||||
build(|config| {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Default for GenesisConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
initial_header: Default::default(),
|
||||
initial_difficulty: Default::default(),
|
||||
initial_validators: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::genesis_build]
|
||||
impl<T: Config<I>, I: 'static> GenesisBuild<T, I> for GenesisConfig {
|
||||
fn build(&self) {
|
||||
// the initial blocks should be selected so that:
|
||||
// 1) it doesn't signal validators changes;
|
||||
// 2) there are no scheduled validators changes from previous blocks;
|
||||
// 3) (implied) all direct children of initial block are authored by the same validators set.
|
||||
|
||||
assert!(
|
||||
!config.initial_validators.is_empty(),
|
||||
!self.initial_validators.is_empty(),
|
||||
"Initial validators set can't be empty",
|
||||
);
|
||||
|
||||
initialize_storage::<T, I>(
|
||||
&config.initial_header,
|
||||
config.initial_difficulty,
|
||||
&config.initial_validators,
|
||||
);
|
||||
})
|
||||
initialize_storage::<T, I>(&self.initial_header, self.initial_difficulty, &self.initial_validators);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: Instance> Pallet<T, I> {
|
||||
impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
/// Returns number and hash of the best block known to the bridge module.
|
||||
/// The caller should only submit `import_header` transaction that makes
|
||||
/// (or leads to making) other header the best one.
|
||||
@@ -542,49 +631,11 @@ impl<T: Config<I>, I: Instance> Pallet<T, I> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: Instance> frame_support::unsigned::ValidateUnsigned for Pallet<T, I> {
|
||||
type Call = Call<T, I>;
|
||||
|
||||
fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
|
||||
match *call {
|
||||
Self::Call::import_unsigned_header(ref header, ref receipts) => {
|
||||
let accept_result = verification::accept_aura_header_into_pool(
|
||||
&BridgeStorage::<T, I>::new(),
|
||||
&T::AuraConfiguration::get(),
|
||||
&T::ValidatorsConfiguration::get(),
|
||||
&pool_configuration(),
|
||||
header,
|
||||
&T::ChainTime::default(),
|
||||
receipts.as_ref(),
|
||||
);
|
||||
|
||||
match accept_result {
|
||||
Ok((requires, provides)) => Ok(ValidTransaction {
|
||||
priority: TransactionPriority::max_value(),
|
||||
requires,
|
||||
provides,
|
||||
longevity: TransactionLongevity::max_value(),
|
||||
propagate: true,
|
||||
}),
|
||||
// UnsignedTooFarInTheFuture is the special error code used to limit
|
||||
// number of transactions in the pool - we do not want to ban transaction
|
||||
// in this case (see verification.rs for details)
|
||||
Err(error::Error::UnsignedTooFarInTheFuture) => {
|
||||
UnknownTransaction::Custom(error::Error::UnsignedTooFarInTheFuture.code()).into()
|
||||
}
|
||||
Err(error) => InvalidTransaction::Custom(error.code()).into(),
|
||||
}
|
||||
}
|
||||
_ => InvalidTransaction::Call.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Runtime bridge storage.
|
||||
#[derive(Default)]
|
||||
pub struct BridgeStorage<T, I = DefaultInstance>(sp_std::marker::PhantomData<(T, I)>);
|
||||
pub struct BridgeStorage<T, I: 'static = ()>(sp_std::marker::PhantomData<(T, I)>);
|
||||
|
||||
impl<T: Config<I>, I: Instance> BridgeStorage<T, I> {
|
||||
impl<T: Config<I>, I: 'static> BridgeStorage<T, I> {
|
||||
/// Create new BridgeStorage.
|
||||
pub fn new() -> Self {
|
||||
BridgeStorage(sp_std::marker::PhantomData::<(T, I)>::default())
|
||||
@@ -592,7 +643,7 @@ impl<T: Config<I>, I: Instance> BridgeStorage<T, I> {
|
||||
|
||||
/// Prune old blocks.
|
||||
fn prune_blocks(&self, mut max_blocks_to_prune: u64, finalized_number: u64, prune_end: u64) {
|
||||
let pruning_range = BlocksToPrune::<I>::get();
|
||||
let pruning_range = BlocksToPrune::<T, I>::get();
|
||||
let mut new_pruning_range = pruning_range.clone();
|
||||
|
||||
// update oldest block we want to keep
|
||||
@@ -611,7 +662,7 @@ impl<T: Config<I>, I: Instance> BridgeStorage<T, I> {
|
||||
}
|
||||
|
||||
// read hashes of blocks with given number and try to prune these blocks
|
||||
let blocks_at_number = HeadersByNumber::<I>::take(number);
|
||||
let blocks_at_number = HeadersByNumber::<T, I>::take(number);
|
||||
if let Some(mut blocks_at_number) = blocks_at_number {
|
||||
self.prune_blocks_by_hashes(
|
||||
&mut max_blocks_to_prune,
|
||||
@@ -622,7 +673,7 @@ impl<T: Config<I>, I: Instance> BridgeStorage<T, I> {
|
||||
|
||||
// if we haven't pruned all blocks, remember unpruned
|
||||
if !blocks_at_number.is_empty() {
|
||||
HeadersByNumber::<I>::insert(number, blocks_at_number);
|
||||
HeadersByNumber::<T, I>::insert(number, blocks_at_number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -638,7 +689,7 @@ impl<T: Config<I>, I: Instance> BridgeStorage<T, I> {
|
||||
|
||||
// update pruning range in storage
|
||||
if pruning_range != new_pruning_range {
|
||||
BlocksToPrune::<I>::put(new_pruning_range);
|
||||
BlocksToPrune::<T, I>::put(new_pruning_range);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,7 +702,7 @@ impl<T: Config<I>, I: Instance> BridgeStorage<T, I> {
|
||||
blocks_at_number: &mut Vec<H256>,
|
||||
) {
|
||||
// ensure that unfinalized headers we want to prune do not have scheduled changes
|
||||
if number > finalized_number && blocks_at_number.iter().any(ScheduledChanges::<I>::contains_key) {
|
||||
if number > finalized_number && blocks_at_number.iter().any(ScheduledChanges::<T, I>::contains_key) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -665,10 +716,10 @@ impl<T: Config<I>, I: Instance> BridgeStorage<T, I> {
|
||||
hash,
|
||||
);
|
||||
|
||||
ScheduledChanges::<I>::remove(hash);
|
||||
ScheduledChanges::<T, I>::remove(hash);
|
||||
FinalityCache::<T, I>::remove(hash);
|
||||
if let Some(header) = header {
|
||||
ValidatorsSetsRc::<I>::mutate(header.next_validators_set_id, |rc| match *rc {
|
||||
ValidatorsSetsRc::<T, I>::mutate(header.next_validators_set_id, |rc| match *rc {
|
||||
Some(rc) if rc > 1 => Some(rc - 1),
|
||||
_ => None,
|
||||
});
|
||||
@@ -683,15 +734,15 @@ impl<T: Config<I>, I: Instance> BridgeStorage<T, I> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
impl<T: Config<I>, I: 'static> Storage for BridgeStorage<T, I> {
|
||||
type Submitter = T::AccountId;
|
||||
|
||||
fn best_block(&self) -> (HeaderId, U256) {
|
||||
BestBlock::<I>::get()
|
||||
BestBlock::<T, I>::get()
|
||||
}
|
||||
|
||||
fn finalized_block(&self) -> HeaderId {
|
||||
FinalizedBlock::<I>::get()
|
||||
FinalizedBlock::<T, I>::get()
|
||||
}
|
||||
|
||||
fn header(&self, hash: &H256) -> Option<(AuraHeader, Option<Self::Submitter>)> {
|
||||
@@ -750,9 +801,9 @@ impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
parent_hash: &H256,
|
||||
) -> Option<ImportContext<Self::Submitter>> {
|
||||
Headers::<T, I>::get(parent_hash).map(|parent_header| {
|
||||
let validators_set = ValidatorsSets::<I>::get(parent_header.next_validators_set_id)
|
||||
let validators_set = ValidatorsSets::<T, I>::get(parent_header.next_validators_set_id)
|
||||
.expect("validators set is only pruned when last ref is pruned; there is a ref; qed");
|
||||
let parent_scheduled_change = ScheduledChanges::<I>::get(parent_hash);
|
||||
let parent_scheduled_change = ScheduledChanges::<T, I>::get(parent_hash);
|
||||
ImportContext {
|
||||
submitter,
|
||||
parent_hash: *parent_hash,
|
||||
@@ -767,15 +818,15 @@ impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
}
|
||||
|
||||
fn scheduled_change(&self, hash: &H256) -> Option<AuraScheduledChange> {
|
||||
ScheduledChanges::<I>::get(hash)
|
||||
ScheduledChanges::<T, I>::get(hash)
|
||||
}
|
||||
|
||||
fn insert_header(&mut self, header: HeaderToImport<Self::Submitter>) {
|
||||
if header.is_best {
|
||||
BestBlock::<I>::put((header.id, header.total_difficulty));
|
||||
BestBlock::<T, I>::put((header.id, header.total_difficulty));
|
||||
}
|
||||
if let Some(scheduled_change) = header.scheduled_change {
|
||||
ScheduledChanges::<I>::insert(
|
||||
ScheduledChanges::<T, I>::insert(
|
||||
&header.id.hash,
|
||||
AuraScheduledChange {
|
||||
validators: scheduled_change,
|
||||
@@ -785,12 +836,12 @@ impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
}
|
||||
let next_validators_set_id = match header.enacted_change {
|
||||
Some(enacted_change) => {
|
||||
let next_validators_set_id = NextValidatorsSetId::<I>::mutate(|set_id| {
|
||||
let next_validators_set_id = NextValidatorsSetId::<T, I>::mutate(|set_id| {
|
||||
let next_set_id = *set_id;
|
||||
*set_id += 1;
|
||||
next_set_id
|
||||
});
|
||||
ValidatorsSets::<I>::insert(
|
||||
ValidatorsSets::<T, I>::insert(
|
||||
next_validators_set_id,
|
||||
ValidatorsSet {
|
||||
validators: enacted_change.validators,
|
||||
@@ -798,11 +849,11 @@ impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
signal_block: enacted_change.signal_block,
|
||||
},
|
||||
);
|
||||
ValidatorsSetsRc::<I>::insert(next_validators_set_id, 1);
|
||||
ValidatorsSetsRc::<T, I>::insert(next_validators_set_id, 1);
|
||||
next_validators_set_id
|
||||
}
|
||||
None => {
|
||||
ValidatorsSetsRc::<I>::mutate(header.context.validators_set_id, |rc| {
|
||||
ValidatorsSetsRc::<T, I>::mutate(header.context.validators_set_id, |rc| {
|
||||
*rc = Some(rc.map(|rc| rc + 1).unwrap_or(1));
|
||||
*rc
|
||||
});
|
||||
@@ -826,7 +877,7 @@ impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
);
|
||||
|
||||
let last_signal_block = header.context.last_signal_block();
|
||||
HeadersByNumber::<I>::append(header.id.number, header.id.hash);
|
||||
HeadersByNumber::<T, I>::append(header.id.number, header.id.hash);
|
||||
Headers::<T, I>::insert(
|
||||
&header.id.hash,
|
||||
StoredHeader {
|
||||
@@ -844,7 +895,7 @@ impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
let finalized_number = finalized
|
||||
.as_ref()
|
||||
.map(|f| f.number)
|
||||
.unwrap_or_else(|| FinalizedBlock::<I>::get().number);
|
||||
.unwrap_or_else(|| FinalizedBlock::<T, I>::get().number);
|
||||
if let Some(finalized) = finalized {
|
||||
log::trace!(
|
||||
target: "runtime",
|
||||
@@ -853,7 +904,7 @@ impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
finalized.hash,
|
||||
);
|
||||
|
||||
FinalizedBlock::<I>::put(finalized);
|
||||
FinalizedBlock::<T, I>::put(finalized);
|
||||
}
|
||||
|
||||
// and now prune headers if we need to
|
||||
@@ -863,7 +914,7 @@ impl<T: Config<I>, I: Instance> Storage for BridgeStorage<T, I> {
|
||||
|
||||
/// Initialize storage.
|
||||
#[cfg(any(feature = "std", feature = "runtime-benchmarks"))]
|
||||
pub(crate) fn initialize_storage<T: Config<I>, I: Instance>(
|
||||
pub(crate) fn initialize_storage<T: Config<I>, I: 'static>(
|
||||
initial_header: &AuraHeader,
|
||||
initial_difficulty: U256,
|
||||
initial_validators: &[Address],
|
||||
@@ -880,13 +931,13 @@ pub(crate) fn initialize_storage<T: Config<I>, I: Instance>(
|
||||
number: initial_header.number,
|
||||
hash: initial_hash,
|
||||
};
|
||||
BestBlock::<I>::put((initial_id, initial_difficulty));
|
||||
FinalizedBlock::<I>::put(initial_id);
|
||||
BlocksToPrune::<I>::put(PruningRange {
|
||||
BestBlock::<T, I>::put((initial_id, initial_difficulty));
|
||||
FinalizedBlock::<T, I>::put(initial_id);
|
||||
BlocksToPrune::<T, I>::put(PruningRange {
|
||||
oldest_unpruned_block: initial_header.number,
|
||||
oldest_block_to_keep: initial_header.number,
|
||||
});
|
||||
HeadersByNumber::<I>::insert(initial_header.number, vec![initial_hash]);
|
||||
HeadersByNumber::<T, I>::insert(initial_header.number, vec![initial_hash]);
|
||||
Headers::<T, I>::insert(
|
||||
initial_hash,
|
||||
StoredHeader {
|
||||
@@ -897,8 +948,8 @@ pub(crate) fn initialize_storage<T: Config<I>, I: Instance>(
|
||||
last_signal_block: None,
|
||||
},
|
||||
);
|
||||
NextValidatorsSetId::<I>::put(1);
|
||||
ValidatorsSets::<I>::insert(
|
||||
NextValidatorsSetId::<T, I>::put(1);
|
||||
ValidatorsSets::<T, I>::insert(
|
||||
0,
|
||||
ValidatorsSet {
|
||||
validators: initial_validators.to_vec(),
|
||||
@@ -906,7 +957,7 @@ pub(crate) fn initialize_storage<T: Config<I>, I: Instance>(
|
||||
enact_block: initial_id,
|
||||
},
|
||||
);
|
||||
ValidatorsSetsRc::<I>::insert(0, 1);
|
||||
ValidatorsSetsRc::<T, I>::insert(0, 1);
|
||||
}
|
||||
|
||||
/// Verify that transaction is included into given finalized block.
|
||||
@@ -1112,7 +1163,7 @@ pub(crate) mod tests {
|
||||
);
|
||||
|
||||
if i == 7 && j == 1 {
|
||||
ScheduledChanges::<DefaultInstance>::insert(
|
||||
ScheduledChanges::<TestRuntime, ()>::insert(
|
||||
hash,
|
||||
AuraScheduledChange {
|
||||
validators: validators_addresses(5),
|
||||
@@ -1121,7 +1172,7 @@ pub(crate) mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
HeadersByNumber::<DefaultInstance>::insert(i, headers_by_number);
|
||||
HeadersByNumber::<TestRuntime, ()>::insert(i, headers_by_number);
|
||||
}
|
||||
|
||||
f(BridgeStorage::new())
|
||||
@@ -1131,16 +1182,16 @@ pub(crate) mod tests {
|
||||
#[test]
|
||||
fn blocks_are_not_pruned_if_range_is_empty() {
|
||||
with_headers_to_prune(|storage| {
|
||||
BlocksToPrune::<DefaultInstance>::put(PruningRange {
|
||||
BlocksToPrune::<TestRuntime, ()>::put(PruningRange {
|
||||
oldest_unpruned_block: 5,
|
||||
oldest_block_to_keep: 5,
|
||||
});
|
||||
|
||||
// try to prune blocks [5; 10)
|
||||
storage.prune_blocks(0xFFFF, 10, 5);
|
||||
assert_eq!(HeadersByNumber::<DefaultInstance>::get(&5).unwrap().len(), 5);
|
||||
assert_eq!(HeadersByNumber::<TestRuntime, ()>::get(&5).unwrap().len(), 5);
|
||||
assert_eq!(
|
||||
BlocksToPrune::<DefaultInstance>::get(),
|
||||
BlocksToPrune::<TestRuntime, ()>::get(),
|
||||
PruningRange {
|
||||
oldest_unpruned_block: 5,
|
||||
oldest_block_to_keep: 5,
|
||||
@@ -1152,7 +1203,7 @@ pub(crate) mod tests {
|
||||
#[test]
|
||||
fn blocks_to_prune_never_shrinks_from_the_end() {
|
||||
with_headers_to_prune(|storage| {
|
||||
BlocksToPrune::<DefaultInstance>::put(PruningRange {
|
||||
BlocksToPrune::<TestRuntime, ()>::put(PruningRange {
|
||||
oldest_unpruned_block: 0,
|
||||
oldest_block_to_keep: 5,
|
||||
});
|
||||
@@ -1160,7 +1211,7 @@ pub(crate) mod tests {
|
||||
// try to prune blocks [5; 10)
|
||||
storage.prune_blocks(0xFFFF, 10, 3);
|
||||
assert_eq!(
|
||||
BlocksToPrune::<DefaultInstance>::get(),
|
||||
BlocksToPrune::<TestRuntime, ()>::get(),
|
||||
PruningRange {
|
||||
oldest_unpruned_block: 5,
|
||||
oldest_block_to_keep: 5,
|
||||
@@ -1174,12 +1225,12 @@ pub(crate) mod tests {
|
||||
with_headers_to_prune(|storage| {
|
||||
// try to prune blocks [0; 10)
|
||||
storage.prune_blocks(0, 10, 10);
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&0).is_some());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&1).is_some());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&2).is_some());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&3).is_some());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&0).is_some());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&1).is_some());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&2).is_some());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&3).is_some());
|
||||
assert_eq!(
|
||||
BlocksToPrune::<DefaultInstance>::get(),
|
||||
BlocksToPrune::<TestRuntime, ()>::get(),
|
||||
PruningRange {
|
||||
oldest_unpruned_block: 0,
|
||||
oldest_block_to_keep: 10,
|
||||
@@ -1194,13 +1245,13 @@ pub(crate) mod tests {
|
||||
// try to prune blocks [0; 10)
|
||||
storage.prune_blocks(7, 10, 10);
|
||||
// 1 headers with number = 0 is pruned (1 total)
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&0).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&0).is_none());
|
||||
// 5 headers with number = 1 are pruned (6 total)
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&1).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&1).is_none());
|
||||
// 1 header with number = 2 are pruned (7 total)
|
||||
assert_eq!(HeadersByNumber::<DefaultInstance>::get(&2).unwrap().len(), 4);
|
||||
assert_eq!(HeadersByNumber::<TestRuntime, ()>::get(&2).unwrap().len(), 4);
|
||||
assert_eq!(
|
||||
BlocksToPrune::<DefaultInstance>::get(),
|
||||
BlocksToPrune::<TestRuntime, ()>::get(),
|
||||
PruningRange {
|
||||
oldest_unpruned_block: 2,
|
||||
oldest_block_to_keep: 10,
|
||||
@@ -1210,13 +1261,13 @@ pub(crate) mod tests {
|
||||
// try to prune blocks [2; 10)
|
||||
storage.prune_blocks(11, 10, 10);
|
||||
// 4 headers with number = 2 are pruned (4 total)
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&2).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&2).is_none());
|
||||
// 5 headers with number = 3 are pruned (9 total)
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&3).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&3).is_none());
|
||||
// 2 headers with number = 4 are pruned (11 total)
|
||||
assert_eq!(HeadersByNumber::<DefaultInstance>::get(&4).unwrap().len(), 3);
|
||||
assert_eq!(HeadersByNumber::<TestRuntime, ()>::get(&4).unwrap().len(), 3);
|
||||
assert_eq!(
|
||||
BlocksToPrune::<DefaultInstance>::get(),
|
||||
BlocksToPrune::<TestRuntime, ()>::get(),
|
||||
PruningRange {
|
||||
oldest_unpruned_block: 4,
|
||||
oldest_block_to_keep: 10,
|
||||
@@ -1233,16 +1284,16 @@ pub(crate) mod tests {
|
||||
// and one of blocks#7 has scheduled change
|
||||
// => we won't prune any block#7 at all
|
||||
storage.prune_blocks(0xFFFF, 5, 10);
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&0).is_none());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&1).is_none());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&2).is_none());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&3).is_none());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&4).is_none());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&5).is_none());
|
||||
assert!(HeadersByNumber::<DefaultInstance>::get(&6).is_none());
|
||||
assert_eq!(HeadersByNumber::<DefaultInstance>::get(&7).unwrap().len(), 5);
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&0).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&1).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&2).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&3).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&4).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&5).is_none());
|
||||
assert!(HeadersByNumber::<TestRuntime, ()>::get(&6).is_none());
|
||||
assert_eq!(HeadersByNumber::<TestRuntime, ()>::get(&7).unwrap().len(), 5);
|
||||
assert_eq!(
|
||||
BlocksToPrune::<DefaultInstance>::get(),
|
||||
BlocksToPrune::<TestRuntime, ()>::get(),
|
||||
PruningRange {
|
||||
oldest_unpruned_block: 7,
|
||||
oldest_block_to_keep: 10,
|
||||
@@ -1272,7 +1323,7 @@ pub(crate) mod tests {
|
||||
assert!(FinalityCache::<TestRuntime>::get(&header_with_entry_hash).is_some());
|
||||
|
||||
// when we later prune this header, cache entry is removed
|
||||
BlocksToPrune::<DefaultInstance>::put(PruningRange {
|
||||
BlocksToPrune::<TestRuntime, ()>::put(PruningRange {
|
||||
oldest_unpruned_block: interval - 1,
|
||||
oldest_block_to_keep: interval - 1,
|
||||
});
|
||||
@@ -1359,7 +1410,7 @@ pub(crate) mod tests {
|
||||
insert_header(&mut storage, header1s);
|
||||
|
||||
// header1 is finalized
|
||||
FinalizedBlock::<DefaultInstance>::put(header1_id);
|
||||
FinalizedBlock::<TestRuntime, ()>::put(header1_id);
|
||||
|
||||
// trying to get finality votes when importing header2 -> header1 succeeds
|
||||
assert!(
|
||||
|
||||
@@ -23,7 +23,7 @@ pub use bp_eth_poa::signatures::secret_to_address;
|
||||
use crate::validators::{ValidatorsConfiguration, ValidatorsSource};
|
||||
use crate::{AuraConfiguration, ChainTime, Config, GenesisConfig as CrateGenesisConfig, PruningStrategy};
|
||||
use bp_eth_poa::{Address, AuraHeader, H256, U256};
|
||||
use frame_support::{parameter_types, weights::Weight};
|
||||
use frame_support::{parameter_types, traits::GenesisBuild, weights::Weight};
|
||||
use secp256k1::SecretKey;
|
||||
use sp_runtime::{
|
||||
testing::Header as SubstrateHeader,
|
||||
@@ -146,13 +146,12 @@ pub fn run_test_with_genesis<T>(
|
||||
) -> T {
|
||||
let validators = validators(total_validators);
|
||||
let addresses = validators_addresses(total_validators);
|
||||
sp_io::TestExternalities::new(
|
||||
CrateGenesisConfig {
|
||||
sp_io::TestExternalities::from(
|
||||
GenesisBuild::<TestRuntime>::build_storage(&CrateGenesisConfig {
|
||||
initial_header: genesis.clone(),
|
||||
initial_difficulty: 0.into(),
|
||||
initial_validators: addresses.clone(),
|
||||
}
|
||||
.build_storage::<TestRuntime, crate::DefaultInstance>()
|
||||
})
|
||||
.unwrap(),
|
||||
)
|
||||
.execute_with(|| {
|
||||
|
||||
@@ -63,30 +63,28 @@ impl HeaderBuilder {
|
||||
/// Creates default header on top of test parent with given hash.
|
||||
#[cfg(test)]
|
||||
pub fn with_parent_hash(parent_hash: H256) -> Self {
|
||||
Self::with_parent_hash_on_runtime::<crate::mock::TestRuntime, crate::DefaultInstance>(parent_hash)
|
||||
Self::with_parent_hash_on_runtime::<crate::mock::TestRuntime, ()>(parent_hash)
|
||||
}
|
||||
|
||||
/// Creates default header on top of test parent with given number. First parent is selected.
|
||||
#[cfg(test)]
|
||||
pub fn with_parent_number(parent_number: u64) -> Self {
|
||||
Self::with_parent_number_on_runtime::<crate::mock::TestRuntime, crate::DefaultInstance>(parent_number)
|
||||
Self::with_parent_number_on_runtime::<crate::mock::TestRuntime, ()>(parent_number)
|
||||
}
|
||||
|
||||
/// Creates default header on top of parent with given hash.
|
||||
pub fn with_parent_hash_on_runtime<T: Config<I>, I: crate::Instance>(parent_hash: H256) -> Self {
|
||||
pub fn with_parent_hash_on_runtime<T: Config<I>, I: 'static>(parent_hash: H256) -> Self {
|
||||
use crate::Headers;
|
||||
use frame_support::StorageMap;
|
||||
|
||||
let parent_header = Headers::<T, I>::get(&parent_hash).unwrap().header;
|
||||
Self::with_parent(&parent_header)
|
||||
}
|
||||
|
||||
/// Creates default header on top of parent with given number. First parent is selected.
|
||||
pub fn with_parent_number_on_runtime<T: Config<I>, I: crate::Instance>(parent_number: u64) -> Self {
|
||||
pub fn with_parent_number_on_runtime<T: Config<I>, I: 'static>(parent_number: u64) -> Self {
|
||||
use crate::HeadersByNumber;
|
||||
use frame_support::StorageMap;
|
||||
|
||||
let parent_hash = HeadersByNumber::<I>::get(parent_number).unwrap()[0];
|
||||
let parent_hash = HeadersByNumber::<T, I>::get(parent_number).unwrap()[0];
|
||||
Self::with_parent_hash_on_runtime::<T, I>(parent_hash)
|
||||
}
|
||||
|
||||
|
||||
@@ -276,10 +276,8 @@ impl ValidatorsSource {
|
||||
pub(crate) mod tests {
|
||||
use super::*;
|
||||
use crate::mock::{run_test, validators_addresses, validators_change_receipt, TestRuntime};
|
||||
use crate::DefaultInstance;
|
||||
use crate::{AuraScheduledChange, BridgeStorage, Headers, ScheduledChanges, StoredHeader};
|
||||
use bp_eth_poa::compute_merkle_root;
|
||||
use frame_support::StorageMap;
|
||||
|
||||
const TOTAL_VALIDATORS: usize = 3;
|
||||
|
||||
@@ -438,7 +436,7 @@ pub(crate) mod tests {
|
||||
};
|
||||
Headers::<TestRuntime>::insert(id100.hash, header100);
|
||||
if let Some(scheduled_at) = scheduled_at {
|
||||
ScheduledChanges::<DefaultInstance>::insert(scheduled_at.hash, scheduled_change);
|
||||
ScheduledChanges::<TestRuntime, ()>::insert(scheduled_at.hash, scheduled_change);
|
||||
}
|
||||
|
||||
validators.finalize_validators_change(&storage, &finalized_blocks)
|
||||
|
||||
@@ -375,13 +375,11 @@ mod tests {
|
||||
validators_change_receipt, AccountId, ConstChainTime, HeaderBuilder, TestRuntime, GAS_LIMIT,
|
||||
};
|
||||
use crate::validators::ValidatorsSource;
|
||||
use crate::DefaultInstance;
|
||||
use crate::{
|
||||
pool_configuration, BridgeStorage, FinalizedBlock, Headers, HeadersByNumber, NextValidatorsSetId,
|
||||
ScheduledChanges, ValidatorsSet, ValidatorsSets,
|
||||
};
|
||||
use bp_eth_poa::{compute_merkle_root, rlp_encode, TransactionOutcome, H520, U256};
|
||||
use frame_support::{StorageMap, StorageValue};
|
||||
use hex_literal::hex;
|
||||
use secp256k1::SecretKey;
|
||||
use sp_runtime::transaction_validity::TransactionTag;
|
||||
@@ -418,7 +416,7 @@ mod tests {
|
||||
let block3 = HeaderBuilder::with_parent_number(2).sign_by_set(&validators);
|
||||
insert_header(&mut storage, block3);
|
||||
|
||||
FinalizedBlock::<DefaultInstance>::put(block2_id);
|
||||
FinalizedBlock::<TestRuntime, ()>::put(block2_id);
|
||||
|
||||
let validators_config =
|
||||
ValidatorsConfiguration::Single(ValidatorsSource::Contract(Default::default(), Vec::new()));
|
||||
@@ -436,21 +434,21 @@ mod tests {
|
||||
}
|
||||
|
||||
fn change_validators_set_at(number: u64, finalized_set: Vec<Address>, signalled_set: Option<Vec<Address>>) {
|
||||
let set_id = NextValidatorsSetId::<DefaultInstance>::get();
|
||||
NextValidatorsSetId::<DefaultInstance>::put(set_id + 1);
|
||||
ValidatorsSets::<DefaultInstance>::insert(
|
||||
let set_id = NextValidatorsSetId::<TestRuntime, ()>::get();
|
||||
NextValidatorsSetId::<TestRuntime, ()>::put(set_id + 1);
|
||||
ValidatorsSets::<TestRuntime, ()>::insert(
|
||||
set_id,
|
||||
ValidatorsSet {
|
||||
validators: finalized_set,
|
||||
signal_block: None,
|
||||
enact_block: HeaderId {
|
||||
number: 0,
|
||||
hash: HeadersByNumber::<DefaultInstance>::get(&0).unwrap()[0],
|
||||
hash: HeadersByNumber::<TestRuntime, ()>::get(&0).unwrap()[0],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
let header_hash = HeadersByNumber::<DefaultInstance>::get(&number).unwrap()[0];
|
||||
let header_hash = HeadersByNumber::<TestRuntime, ()>::get(&number).unwrap()[0];
|
||||
let mut header = Headers::<TestRuntime>::get(&header_hash).unwrap();
|
||||
header.next_validators_set_id = set_id;
|
||||
if let Some(signalled_set) = signalled_set {
|
||||
@@ -458,7 +456,7 @@ mod tests {
|
||||
number: header.header.number - 1,
|
||||
hash: header.header.parent_hash,
|
||||
});
|
||||
ScheduledChanges::<DefaultInstance>::insert(
|
||||
ScheduledChanges::<TestRuntime, ()>::insert(
|
||||
header.header.parent_hash,
|
||||
AuraScheduledChange {
|
||||
validators: signalled_set,
|
||||
|
||||
Reference in New Issue
Block a user