Skip to content

Commit

Permalink
Mock/tests, type fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Dinonard committed Sep 21, 2023
1 parent 6600a4e commit c9fd237
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 7 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

12 changes: 9 additions & 3 deletions pallets/dynamic-evm-base-fee/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ scale-info = { workspace = true }
# Substrate
frame-support = { workspace = true }
frame-system = { workspace = true }
pallet-transaction-payment = { workspace = true }
sp-core = { workspace = true }
sp-runtime = { workspace = true }
pallet-transaction-payment = { workspace = true }

# Frontier
fp-evm = { workspace = true }

[dev-dependencies]
pallet-balances = { workspace = true }
pallet-timestamp = { workspace = true }

[features]
default = ["std"]
std = [
Expand All @@ -32,12 +36,14 @@ std = [
"frame-system/std",
"sp-core/std",
"sp-runtime/std",
"pallet-transaction-payment/std",
"pallet-transaction-payment/std",
"pallet-balances/std",
"pallet-timestamp/std",
# Frontier
"fp-evm/std",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-transaction-payment/try-runtime",
"pallet-transaction-payment/try-runtime",
]
28 changes: 24 additions & 4 deletions pallets/dynamic-evm-base-fee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@
// You should have received a copy of the GNU General Public License
// along with Astar. If not, see <http://www.gnu.org/licenses/>.

//! TODO: Rustdoc!!!
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::{traits::Get, weights::Weight};
use sp_core::U256;
use sp_runtime::{traits::UniqueSaturatedInto, Perquintill};
use sp_runtime::{traits::UniqueSaturatedInto, FixedPointNumber, FixedU128, Perquintill};

pub use self::pallet::*;

#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;

#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
Expand All @@ -45,7 +52,7 @@ pub mod pallet {
/// Maximum value 'base fee per gas' can be adjusted to. This is a defensive measure to prevent the fee from being too high.
type MaxBaseFeePerGas: Get<U256>;
/// Getter for the fee adjustment factor used in 'base fee per gas' formula. This is expected to change in-between the blocks (doesn't have to though).
type AdjustmentFactor: Get<u128>;
type AdjustmentFactor: Get<FixedU128>;
/// The so-called `weight_factor` in the 'base fee per gas' formula.
type WeightFactor: Get<u128>;
/// Ratio limit on how much the 'base fee per gas' can change in-between two blocks.
Expand Down Expand Up @@ -87,10 +94,16 @@ pub mod pallet {
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event {
/// New `base fee per gas` value has been forced-set.
/// New `base fee per gas` value has been force-set.
NewBaseFeePerGas { fee: U256 },
}

#[pallet::error]
pub enum Error<T> {
/// Specified value is outside of the allowed range.
ValueOutOfBounds,
}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(_: T::BlockNumber) -> Weight {
Expand All @@ -115,14 +128,16 @@ pub mod pallet {

// TODO: maybe add a DB entry to check until when should we apply max step adjustment?
// Once 'equilibrium' is reached, it's safe to just follow the formula without limit updates.
// Or we could abuse the sudo for this.

// Lower & upper limit between which the new base fee per gas should be clamped.
let lower_limit = T::MinBaseFeePerGas::get().max(old_bfpg.saturating_sub(max_step));
let upper_limit = T::MaxBaseFeePerGas::get().min(old_bfpg.saturating_add(max_step));

// Calculate ideal new 'base_fee_per_gas' according to the formula
let ideal_new_bfpg = T::AdjustmentFactor::get()
.saturating_mul(T::WeightFactor::get())
// Weight factor should be multiplied first since it's a larger number, to avoid precision loss.
.saturating_mul_int(T::WeightFactor::get())
.saturating_mul(25)
.saturating_div(98974);

Expand All @@ -138,6 +153,11 @@ pub mod pallet {
#[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())]
pub fn set_base_fee_per_gas(origin: OriginFor<T>, fee: U256) -> DispatchResult {
ensure_root(origin)?;
ensure!(
fee >= T::MinBaseFeePerGas::get() && fee <= T::MaxBaseFeePerGas::get(),
Error::<T>::ValueOutOfBounds
);

BaseFeePerGas::<T>::put(fee);
Self::deposit_event(Event::NewBaseFeePerGas { fee });
Ok(())
Expand Down
167 changes: 167 additions & 0 deletions pallets/dynamic-evm-base-fee/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Astar is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Astar. If not, see <http://www.gnu.org/licenses/>.

#![cfg(test)]

use super::*;
use crate as pallet_dynamic_evm_base_fee;

use frame_support::{
construct_runtime, parameter_types,
sp_io::TestExternalities,
storage,
traits::{ConstU128, ConstU32, ConstU64},
weights::Weight,
};
use parity_scale_codec::Encode;
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup, One},
FixedU128, Perquintill,
};

pub(crate) type AccountId = u128;
pub(crate) type BlockNumber = u64;
pub(crate) type Balance = u128;

parameter_types! {
pub BlockWeights: frame_system::limits::BlockWeights =
frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, 0));
}

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

impl pallet_balances::Config for TestRuntime {
type MaxLocks = ConstU32<4>;
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
type Balance = Balance;
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ConstU128<2>;
type AccountStore = System;
type WeightInfo = ();
type HoldIdentifier = ();
type FreezeIdentifier = ();
type MaxHolds = ConstU32<0>;
type MaxFreezes = ConstU32<0>;
}

impl pallet_timestamp::Config for TestRuntime {
type Moment = u64;
type OnTimestampSet = ();
type MinimumPeriod = ConstU64<3>;
type WeightInfo = ();
}

parameter_types! {
pub WeightPerGas: Weight = Weight::from_parts(1, 0);
pub DefaultBaseFeePerGas: U256 = U256::from(1_500_000_000_000_u128);
pub MinBaseFeePerGas: U256 = U256::from(800_000_000_000_u128);
pub MaxBaseFeePerGas: U256 = U256::from(80_000_000_000_000_u128);
pub StepLimitRation: Perquintill = Perquintill::from_rational(30_u128, 1_000_000);
}

impl pallet_dynamic_evm_base_fee::Config for TestRuntime {
type RuntimeEvent = RuntimeEvent;
type DefaultBaseFeePerGas = DefaultBaseFeePerGas;
type MinBaseFeePerGas = MinBaseFeePerGas;
type MaxBaseFeePerGas = MaxBaseFeePerGas;
type AdjustmentFactor = GetAdjustmentFactor;
type WeightFactor = ConstU128<30_000_000_000_000_000>;
type StepLimitRatio = StepLimitRation;
}

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

construct_runtime!(
pub struct TestRuntime
where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system,
Timestamp: pallet_timestamp,
Balances: pallet_balances,
DynamicEvmBaseFee: pallet_dynamic_evm_base_fee,
}
);

const ADJUSTMENT_FACTOR: &[u8] = b":adj_factor_evm";

/// Helper method to set the adjustment factor used by the pallet.
pub fn set_adjustment_factor(factor: FixedU128) {
storage::unhashed::put_raw(&ADJUSTMENT_FACTOR, &factor.encode());
}

/// Helper function to get the adjustment factor used by the pallet.
/// In case it's unset, it returns 0.
pub fn get_adjustment_factor() -> FixedU128 {
storage::unhashed::get::<FixedU128>(&ADJUSTMENT_FACTOR).unwrap_or_default()
}

pub struct GetAdjustmentFactor;
impl Get<FixedU128> for GetAdjustmentFactor {
fn get() -> FixedU128 {
get_adjustment_factor()
}
}

pub struct ExtBuilder;
impl ExtBuilder {
pub fn build() -> TestExternalities {
let storage = frame_system::GenesisConfig::default()
.build_storage::<TestRuntime>()
.unwrap();

let mut ext = TestExternalities::from(storage);
ext.execute_with(|| {
set_adjustment_factor(FixedU128::one());
System::set_block_number(1);
});
ext
}
}
91 changes: 91 additions & 0 deletions pallets/dynamic-evm-base-fee/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Astar is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Astar. If not, see <http://www.gnu.org/licenses/>.

#![cfg(test)]

use super::*;
use mock::*;

use frame_support::{assert_noop, assert_ok};
use sp_runtime::traits::BadOrigin;

#[test]
fn set_base_fee_per_gas_works() {
ExtBuilder::build().execute_with(|| {
// sanity check
assert_eq!(
BaseFeePerGas::<TestRuntime>::get(),
<TestRuntime as pallet::Config>::DefaultBaseFeePerGas::get()
);

// Ensure we can change the bfpg value via root
for new_base_fee_per_gas in [
<TestRuntime as pallet::Config>::MinBaseFeePerGas::get(),
<TestRuntime as pallet::Config>::MaxBaseFeePerGas::get(),
] {
assert_ok!(DynamicEvmBaseFee::set_base_fee_per_gas(
RuntimeOrigin::root(),
new_base_fee_per_gas
));
System::assert_last_event(mock::RuntimeEvent::DynamicEvmBaseFee(
Event::NewBaseFeePerGas {
fee: new_base_fee_per_gas,
},
));
assert_eq!(BaseFeePerGas::<TestRuntime>::get(), new_base_fee_per_gas);
}
});
}

#[test]
fn set_base_fee_per_gas_value_out_of_bounds_fails() {
ExtBuilder::build().execute_with(|| {
// Out of bound values
let too_small_base_fee_per_gas =
<TestRuntime as pallet::Config>::MinBaseFeePerGas::get() - 1;
let too_big_base_fee_per_gas = <TestRuntime as pallet::Config>::MaxBaseFeePerGas::get() + 1;

assert_noop!(
DynamicEvmBaseFee::set_base_fee_per_gas(
RuntimeOrigin::root(),
too_small_base_fee_per_gas
),
Error::<TestRuntime>::ValueOutOfBounds
);
assert_noop!(
DynamicEvmBaseFee::set_base_fee_per_gas(
RuntimeOrigin::root(),
too_big_base_fee_per_gas
),
Error::<TestRuntime>::ValueOutOfBounds
);
});
}

#[test]
fn set_base_fee_per_gas_non_root_fails() {
ExtBuilder::build().execute_with(|| {
assert_noop!(
DynamicEvmBaseFee::set_base_fee_per_gas(
RuntimeOrigin::signed(1),
<TestRuntime as pallet::Config>::MinBaseFeePerGas::get()
),
BadOrigin
);
});
}

0 comments on commit c9fd237

Please sign in to comment.