Skip to content
Merged
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
34 changes: 27 additions & 7 deletions runtime/moonbase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use frame_support::{

#[cfg(feature = "std")]
pub use fp_evm::GenesisAccount;
use frame_system::{EnsureRoot, EnsureSigned};
use frame_system::{limits::BlockWeights, EnsureRoot, EnsureSigned};
pub use moonbeam_core_primitives::{
AccountId, AccountIndex, Address, AssetId, Balance, BlockNumber, DigestItem, Hash, Header,
Index, Signature,
Expand Down Expand Up @@ -191,13 +191,33 @@ pub fn native_version() -> NativeVersion {
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
const NORMAL_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT * 3 / 4;
// Here we assume Ethereum's base fee of 21000 gas and convert to weight, but we
// subtract roughly the cost of a balance transfer from it (about 1/3 the cost)
// and some cost to account for per-byte-fee.
// TODO: we should use benchmarking's overhead feature to measure this
pub const EXTRINSIC_BASE_WEIGHT: Weight = 10000 * WEIGHT_PER_GAS;

pub struct RuntimeBlockWeights;
impl Get<BlockWeights> for RuntimeBlockWeights {
fn get() -> BlockWeights {
BlockWeights::builder()
.for_class(DispatchClass::Normal, |weights| {
weights.base_extrinsic = EXTRINSIC_BASE_WEIGHT;
weights.max_total = NORMAL_WEIGHT.into();
})
.for_class(DispatchClass::Operational, |weights| {
weights.max_total = MAXIMUM_BLOCK_WEIGHT.into();
weights.reserved = (MAXIMUM_BLOCK_WEIGHT - NORMAL_WEIGHT).into();
})
.avg_block_initialization(Perbill::from_percent(10))
.build()
.expect("Provided BlockWeight definitions are valid, qed")
}
}

parameter_types! {
pub const Version: RuntimeVersion = VERSION;
/// We allow for one half second of compute with a 6 second average block time.
/// These values are dictated by Polkadot for the parachain.
pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights
::with_sensible_defaults(MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO);
/// We allow for 5 MB blocks.
pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
Expand Down Expand Up @@ -227,7 +247,7 @@ impl frame_system::Config for Runtime {
/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
type BlockHashCount = ConstU32<256>;
/// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok.
type BlockWeights = BlockWeights;
type BlockWeights = RuntimeBlockWeights;
/// Maximum size of all encoded transactions (in bytes) that are allowed in one block.
type BlockLength = BlockLength;
/// Runtime version.
Expand Down Expand Up @@ -442,7 +462,7 @@ impl pallet_evm::Config for Runtime {
}

parameter_types! {
pub MaximumSchedulerWeight: Weight = NORMAL_DISPATCH_RATIO * BlockWeights::get().max_block;
pub MaximumSchedulerWeight: Weight = NORMAL_DISPATCH_RATIO * RuntimeBlockWeights::get().max_block;
}

impl pallet_scheduler::Config for Runtime {
Expand Down
37 changes: 31 additions & 6 deletions runtime/moonbase/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ use frame_support::{
};
use moonbase_runtime::{
asset_config::AssetRegistrarMetadata, asset_config::LocalAssetInstance, get,
xcm_config::AssetType, AccountId, AssetId, AssetManager, Assets, Balances, BaseFee,
BlockWeights, Call, CrowdloanRewards, Event, LocalAssets, ParachainStaking, PolkadotXcm,
Precompiles, Runtime, System, XTokens, XcmTransactor, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX,
LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX,
xcm_config::AssetType, AccountId, AssetId, AssetManager, Assets, Balances, BaseFee, Call,
CrowdloanRewards, Event, LocalAssets, ParachainStaking, PolkadotXcm, Precompiles, Runtime,
RuntimeBlockWeights, System, TransactionPayment, XTokens, XcmTransactor,
FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX,
};
use precompile_utils::testing::MockHandle;

Expand Down Expand Up @@ -1999,9 +1999,11 @@ fn length_fee_is_sensible() {

#[test]
fn multiplier_can_grow_from_zero() {
use frame_support::traits::Get;

let minimum_multiplier = moonbase_runtime::MinimumMultiplier::get();
let target = moonbase_runtime::TargetBlockFullness::get()
* BlockWeights::get()
* RuntimeBlockWeights::get()
.get(DispatchClass::Normal)
.max_total
.unwrap();
Expand All @@ -2021,11 +2023,13 @@ fn multiplier_can_grow_from_zero() {
#[test]
#[ignore] // test runs for a very long time
fn multiplier_growth_simulator() {
use frame_support::traits::Get;

// assume the multiplier is initially set to its minimum. We update it with values twice the
//target (target is 25%, thus 50%) and we see at which point it reaches 1.
let mut multiplier = moonbase_runtime::MinimumMultiplier::get();
let block_weight = moonbase_runtime::TargetBlockFullness::get()
* BlockWeights::get()
* RuntimeBlockWeights::get()
.get(DispatchClass::Normal)
.max_total
.unwrap()
Expand Down Expand Up @@ -2602,6 +2606,27 @@ fn base_fee_should_default_to_associate_type_value() {
});
}

#[test]
fn substrate_based_fees_zero_txn_costs_only_base_extrinsic() {
use frame_support::weights::{DispatchInfo, Pays};
use moonbase_runtime::{currency, EXTRINSIC_BASE_WEIGHT};

ExtBuilder::default().build().execute_with(|| {
let size_bytes = 0;
let tip = 0;
let dispatch_info = DispatchInfo {
weight: 0,
class: DispatchClass::Normal,
pays_fee: Pays::Yes,
};

assert_eq!(
TransactionPayment::compute_fee(size_bytes, &dispatch_info, tip),
EXTRINSIC_BASE_WEIGHT as u128 * currency::WEIGHT_FEE,
);
});
}

#[test]
fn evm_revert_substrate_events() {
ExtBuilder::default()
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/test-author/test-author-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ describeDevMoonbeam("Author Mapping - Fail to reassociate alice", (context) => {
//check state
expect(
(await context.polkadotApi.query.system.account(baltathar.address)).data.free.toBigInt()
).to.eq(1208925819590952822705800n);
).to.eq(1208925819582767722705800n);
expect(
(await context.polkadotApi.query.system.account(baltathar.address)).data.reserved.toBigInt()
).to.eq(0n);
Expand Down
4 changes: 2 additions & 2 deletions tests/tests/test-eth-tx/test-eth-tx-size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ describeDevMoonbeam("Ethereum Transaction - Large Transaction", (context) => {
};

// TODO: I'm not sure where this 2000 came from...
const max_size = Math.floor((EXTRINSIC_GAS_LIMIT - 21000) / 16 - 2000);
const max_size = Math.floor((EXTRINSIC_GAS_LIMIT - 21000) / 16) - 2000;

it("should accept txns up to known size", async function () {
expect(max_size).to.equal(808971); // our max Ethereum TXN size in bytes
expect(max_size).to.equal(808562); // our max Ethereum TXN size in bytes

const tx = await generateLargeTxn(max_size);
const { result } = await context.createBlock(tx);
Expand Down
4 changes: 2 additions & 2 deletions tests/tests/test-fees/test-length-fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describeDevMoonbeam(
(context) => {
it("should have low balance transfer fees", async () => {
const fee = await testBalanceTransfer(context);
expect(fee).to.equal(12772901520875n);
expect(fee).to.equal(20958001520875n);
});
},
"Legacy",
Expand All @@ -22,7 +22,7 @@ describeDevMoonbeam(
(context) => {
it("should have expensive runtime-upgrade fees", async () => {
const fee = await testRuntimeUpgrade(context);
expect(fee).to.equal(9226793130623667008n);
expect(fee).to.equal(9226801315723667008n);
});
},
"Legacy",
Expand Down
38 changes: 23 additions & 15 deletions tests/tests/test-staking/test-staking-locks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,13 +447,12 @@ describeDevMoonbeam("Staking - Locks - bottom delegator removed", (context) => {
before("setup candidate & delegations", async function () {
this.timeout(20000);

// Create the delegators to fill the lists
additionalDelegators = new Array(
const maxDelegations =
context.polkadotApi.consts.parachainStaking.maxTopDelegationsPerCandidate.toNumber() +
context.polkadotApi.consts.parachainStaking.maxBottomDelegationsPerCandidate.toNumber()
)
.fill(0)
.map(() => generateKeyringPair());
context.polkadotApi.consts.parachainStaking.maxBottomDelegationsPerCandidate.toNumber();

// Create the delegators to fill the lists
additionalDelegators = new Array(maxDelegations).fill(0).map(() => generateKeyringPair());

await expectOk(
context.createBlock(
Expand Down Expand Up @@ -482,20 +481,29 @@ describeDevMoonbeam("Staking - Locks - bottom delegator removed", (context) => {
`Unexpected number of locks: ${locks.map((l) => l.id.toHuman().toString()).join(` - `)}`
);

await expectOk(
context.createBlock(
[...additionalDelegators].map((account, i) =>
context.polkadotApi.tx.parachainStaking
.delegate(alith.address, MIN_GLMR_DELEGATOR + GLMR, i + 1, 1)
.signAsync(account)
)
)
const txns = await [...additionalDelegators].map((account, i) =>
context.polkadotApi.tx.parachainStaking
.delegate(alith.address, MIN_GLMR_DELEGATOR + GLMR, i + 1, 1)
.signAsync(account)
);

// this can no longer fit in one block
const batchSize = 100;
for (let i = 0; i < txns.length; i += batchSize) {
await expectOk(context.createBlock(txns.slice(i, i + batchSize)));
}

const alithCandidateInfo = (
(await context.polkadotApi.query.parachainStaking.candidateInfo(alith.address)) as any
).unwrap();
expect(alithCandidateInfo.delegationCount.toNumber()).to.equal(additionalDelegators.length);

const newLocks = await context.polkadotApi.query.balances.locks(randomAccount.address);
expect(newLocks.length).to.be.equal(
0,
"Lock should have been removed after getting removed from bottom delegations"
`Unexpected number of locks: ${newLocks
.map((l) => `${l.id.toHuman().toString()}: ${l.amount.toHuman().toString()}`)
.join(` - `)}`
);
});
});
Expand Down
4 changes: 2 additions & 2 deletions tests/util/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export const BLOCK_TX_LIMIT = GAS_PER_SECOND * 0.5;

// Current implementation is limiting block transactions to 75% of the block gas limit
export const BLOCK_TX_GAS_LIMIT = BLOCK_TX_LIMIT * 0.75;
// 86_298_000 Weight per extrinsics
export const EXTRINSIC_BASE_COST = Math.ceil(86_298_000 / GAS_PER_WEIGHT);
// 400_000_000 Weight per extrinsics
export const EXTRINSIC_BASE_COST = 250_000_000 / GAS_PER_WEIGHT;

// Maximum extrinsic weight is taken from the max allowed transaction weight per block,
// minus the block initialization (10%) and minus the extrinsic base cost.
Expand Down