Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pallet for mock-skip blocks on runtimes #487

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ members = [
"runtime/integration-tests",
"chain-extensions/token",
"chain-extensions/price",
"chain-extensions/common",
"chain-extensions/common", "pallets/pallet-mock-skip-blocks",
]

# need this because of bifrost farming dependency in runtime
Expand Down
2 changes: 2 additions & 0 deletions node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,5 @@ try-runtime = [
"pendulum-runtime/try-runtime",
"try-runtime-cli/try-runtime"
]

instant-seal = ["foucoco-runtime/instant-seal"]
27 changes: 27 additions & 0 deletions pallets/pallet-mock-skip-blocks/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "pallet-mock-skip-blocks"
version = "0.1.0"
edition = "2021"

[features]
default = ["std"]
std = [
"frame-system/std",
"frame-support/std",
]

instant-seal = []

[dependencies]
# hex-literal = { version = "0.3.4", optional = true }
codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive", "max-encoded-len"] }
scale-info = { version = "2.2.0", default-features = false, features = ["derive"] }
serde = { version = "1.0.130", default-features = false, features = ["derive"], optional = true }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }

[dev-dependencies]
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
124 changes: 124 additions & 0 deletions pallets/pallet-mock-skip-blocks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#![cfg_attr(not(feature = "std"), no_std)]

// #[cfg(not(feature = "instant-seal"))]
// pub use dummy as pallet;

pub use pallet::*;

// #[cfg(not(feature = "instant-seal"))]
// #[frame_support::pallet]
// pub mod dummy {
// use frame_support::pallet_prelude::*;
//
// #[pallet::pallet]
// pub struct Pallet<T>(_);
//
// #[pallet::event]
// #[pallet::generate_deposit(pub(super) fn deposit_event)]
// pub enum Event<T: Config> {
// /// Dummy event
// DummyEvent,
// }
//
// #[pallet::config]
// pub trait Config: frame_system::Config {
// /// Overarching event type
// type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
// }
//
// #[pallet::call]
// impl<T: Config> Pallet<T> {}
// }

//#[cfg(feature = "instant-seal")]
#[cfg(test)]
mod mock;

//#[cfg(feature = "instant-seal")]
#[cfg(test)]
mod tests;

//#[cfg(feature = "instant-seal")]
#[frame_support::pallet]
pub mod pallet {
use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
use frame_system::pallet_prelude::*;

#[pallet::pallet]
pub struct Pallet<T>(PhantomData<T>);

#[pallet::error]
pub enum Error<T> {
InvalidBlockNumber,
}

//const ENCODED_KEY: &[u8] = &hex_literal::hex!("0x26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac");

const ENCODED_KEY: &[u8] = &[
0x26, 0xaa, 0x39, 0x4e, 0xea, 0x56, 0x30, 0xe0, 0x7c, 0x48, 0xae, 0x0c,
0x95, 0x58, 0xce, 0xf7, 0x02, 0xa5, 0xc1, 0xb1, 0x9a, 0xb7, 0xa0, 0x4f,
0x53, 0x6c, 0x51, 0x9a, 0xca, 0x49, 0x83, 0xac,
];

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Desired block number stored
DesiredBlockStored { n: BlockNumberFor<T> },
/// Desired block number set
BlockSet { n: BlockNumberFor<T> },
/// Original block number restored
BlockReverted { n: BlockNumberFor<T> },
}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(n: T::BlockNumber) -> Weight {
let desired_block_number = DesiredBlockNumber::<T>::get();
OriginalBlockNumber::<T>::put(n);
//frame_system::Pallet::<T>::set_block_number(desired_block_number);
sp_io::storage::set(ENCODED_KEY, &*desired_block_number.encode());
Self::deposit_event(Event::<T>::BlockSet { n: desired_block_number });
Weight::from_ref_time(0)
}

fn on_finalize(_: T::BlockNumber) {
let original_block_number = OriginalBlockNumber::<T>::get();
//frame_system::Pallet::<T>::set_block_number(original_block_number);
sp_io::storage::set(ENCODED_KEY, &*original_block_number.encode());
Self::deposit_event(Event::<T>::BlockReverted { n: original_block_number });
}
}

#[pallet::storage]
pub type DesiredBlockNumber<T: Config> = StorageValue<_, T::BlockNumber, ValueQuery>;

#[pallet::storage]
pub type OriginalBlockNumber<T: Config> = StorageValue<_, T::BlockNumber, ValueQuery>;

#[pallet::config]
pub trait Config: frame_system::Config {
/// Overarching event type
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight((0, Pays::No))]
pub fn set_block_number(
origin: OriginFor<T>,
block_number: T::BlockNumber,
) -> DispatchResult {
ensure_root(origin)?;

let current_block_number = frame_system::Pallet::<T>::block_number();
ensure!(block_number >= current_block_number, Error::<T>::InvalidBlockNumber);

DesiredBlockNumber::<T>::put(block_number);
Self::deposit_event(Event::<T>::DesiredBlockStored { n: block_number });

Ok(())
}
}
}
83 changes: 83 additions & 0 deletions pallets/pallet-mock-skip-blocks/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use crate::{self as pallet_mock_skip_blocks, Config};
use frame_support::{parameter_types, traits::Everything};
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
};

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;

// Configure a mock runtime to test the pallet.
frame_support::construct_runtime!(
pub enum Test where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
MockSkipBlocks: pallet_mock_skip_blocks::{Pallet, Storage, Call, Event<T>},
}
);

pub type AccountId = u64;
pub type BlockNumber = u64;
pub type Index = u64;

parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const SS58Prefix: u8 = 42;
}

pub type TestEvent = RuntimeEvent;

impl frame_system::Config for Test {
type BaseCallFilter = Everything;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type Index = Index;
type BlockNumber = BlockNumber;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type RuntimeEvent = TestEvent;
type BlockHashCount = BlockHashCount;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = SS58Prefix;
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

impl Config for Test {
type RuntimeEvent = RuntimeEvent;
}

pub struct ExtBuilder;

impl ExtBuilder {
pub fn build() -> sp_io::TestExternalities {
let storage = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
sp_io::TestExternalities::from(storage)
}
}

pub fn run_test<T>(test: T)
where
T: FnOnce(),
{
ExtBuilder::build().execute_with(|| {
System::set_block_number(1);
test();
});
}
54 changes: 54 additions & 0 deletions pallets/pallet-mock-skip-blocks/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#![cfg(test)]
use crate::{mock::*, Error};
use frame_support::{assert_noop, assert_ok, traits::Hooks};

#[test]
fn sets_and_reverts_block_number_success() {
run_test(|| {
// Initial block number
assert_eq!(System::block_number(), 1);

// Set desired block number
let desired_block_number = 95;
assert_ok!(crate::Pallet::<Test>::set_block_number(
RuntimeOrigin::root(),
desired_block_number
));

// Simulate block production
System::on_initialize(1);
crate::Pallet::<Test>::on_initialize(1);
assert_eq!(System::block_number(), desired_block_number);

crate::Pallet::<Test>::on_finalize(1);
System::on_finalize(1);
assert_eq!(System::block_number(), 1);

// Advance to the next block
System::set_block_number(2);
System::on_initialize(2);
crate::Pallet::<Test>::on_initialize(2);
assert_eq!(System::block_number(), desired_block_number);

crate::Pallet::<Test>::on_finalize(2);
System::on_finalize(2);
assert_eq!(System::block_number(), 2);
});
}

#[test]
fn setting_block_number_to_less_than_current_fails() {
run_test(|| {
// Initial block number
assert_eq!(System::block_number(), 1);

// Attempt to set desired block number to a value less than the current block number
assert_noop!(
crate::Pallet::<Test>::set_block_number(RuntimeOrigin::root(), 0),
Error::<Test>::InvalidBlockNumber
);

// Block number should remain unchanged
assert_eq!(System::block_number(), 1);
});
}
5 changes: 5 additions & 0 deletions runtime/foucoco/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ parachain-staking = { path = "../../pallets/parachain-staking", default-features
orml-currencies-allowance-extension = { path = "../../pallets/orml-currencies-allowance-extension", default-features = false }
orml-tokens-management-extension = { path = "../../pallets/orml-tokens-management-extension", default-features = false }
treasury-buyout-extension = { path = "../../pallets/treasury-buyout-extension", default-features = false }
pallet-mock-skip-blocks = { path = "../../pallets/pallet-mock-skip-blocks", default-features = false }

# DIA
dia-oracle = { git = "https://github.com/pendulum-chain/oracle-pallet", default-features = false, branch = "polkadot-v0.9.42" }
Expand Down Expand Up @@ -338,3 +339,7 @@ try-runtime = [
"bifrost-farming/try-runtime",
"zenlink-protocol/try-runtime",
]

instant-seal = [
"pallet-mock-skip-blocks/instant-seal",
]
Loading
Loading