Skip to content

Commit

Permalink
Enable async backing on moonriver (#2776)
Browse files Browse the repository at this point in the history
Co-authored-by: Rodrigo Quelhas <[email protected]>
Co-authored-by: Ahmad Kaouk <[email protected]>
  • Loading branch information
3 people authored May 16, 2024
1 parent 26a88a5 commit ae2c682
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 32 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions runtime/moonriver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ parachains-common = { workspace = true }
async-backing-primitives = { workspace = true }
moonkit-xcm-primitives = { workspace = true }
nimbus-primitives = { workspace = true }
pallet-async-backing = { workspace = true }
pallet-author-inherent = { workspace = true }
pallet-author-slot-filter = { workspace = true }
pallet-relay-storage-roots = { workspace = true }
Expand Down Expand Up @@ -221,6 +222,7 @@ std = [
"orml-xtokens/std",
"pallet-asset-manager/std",
"pallet-assets/std",
"pallet-async-backing/std",
"pallet-author-inherent/std",
"pallet-author-mapping/std",
"pallet-author-slot-filter/std",
Expand Down Expand Up @@ -409,6 +411,7 @@ try-runtime = [
"pallet-identity/try-runtime",
"orml-xtokens/try-runtime",
"pallet-assets/try-runtime",
"pallet-async-backing/try-runtime",
"pallet-xcm-transactor/try-runtime",
"pallet-proxy-genesis-companion/try-runtime",
"pallet-moonbeam-orbiters/try-runtime",
Expand Down
51 changes: 36 additions & 15 deletions runtime/moonriver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ use sp_version::RuntimeVersion;

use nimbus_primitives::CanAuthor;

mod precompiles;
pub use precompiles::{
MoonriverPrecompiles, PrecompileName, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX,
};
Expand All @@ -116,6 +115,9 @@ pub mod asset_config;
pub mod governance;
pub mod xcm_config;

mod migrations;
mod precompiles;

pub use governance::councils::*;

/// MOVR, the native token, uses 18 decimals of precision.
Expand Down Expand Up @@ -148,7 +150,7 @@ pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_
.saturating_div(2)
.set_proof_size(relay_chain::MAX_POV_SIZE as u64);

pub const MILLISECS_PER_BLOCK: u64 = 12000;
pub const MILLISECS_PER_BLOCK: u64 = 6_000;
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
pub const HOURS: BlockNumber = MINUTES * 60;
pub const DAYS: BlockNumber = HOURS * 24;
Expand Down Expand Up @@ -701,6 +703,19 @@ parameter_types! {
pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
}

/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included
/// into the relay chain.
const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
/// How many parachain blocks are processed by the relay chain per parent. Limits the
/// number of blocks authored per slot.
const BLOCK_PROCESSING_VELOCITY: u32 = 1;

type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
Runtime,
BLOCK_PROCESSING_VELOCITY,
UNINCLUDED_SEGMENT_CAPACITY,
>;

impl cumulus_pallet_parachain_system::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type OnSystemEvent = ();
Expand Down Expand Up @@ -770,13 +785,11 @@ impl pallet_parachain_staking::OnInactiveCollator<Runtime> for OnInactiveCollato
type MonetaryGovernanceOrigin =
EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;

/// TODO:
/// Temporary type that we should replace by RelayChainSlotProvider once async backing is enabled.
pub struct StakingRoundSlotProvider;
impl Get<Slot> for StakingRoundSlotProvider {
pub struct RelayChainSlotProvider;
impl Get<Slot> for RelayChainSlotProvider {
fn get() -> Slot {
let block_number: u64 = frame_system::pallet::Pallet::<Runtime>::block_number().into();
Slot::from(block_number)
let slot_info = pallet_async_backing::pallet::Pallet::<Runtime>::slot_info();
slot_info.unwrap_or_default().0
}
}

Expand Down Expand Up @@ -817,7 +830,7 @@ impl pallet_parachain_staking::Config for Runtime {
type PayoutCollatorReward = PayoutCollatorOrOrbiterReward;
type OnInactiveCollator = OnInactiveCollator;
type OnNewRound = OnNewRound;
type SlotProvider = StakingRoundSlotProvider;
type SlotProvider = RelayChainSlotProvider;
type WeightInfo = moonbeam_weights::pallet_parachain_staking::WeightInfo<Runtime>;
type MaxCandidates = ConstU32<200>;
type SlotDuration = ConstU64<12_000>;
Expand All @@ -839,6 +852,12 @@ impl pallet_author_slot_filter::Config for Runtime {
type WeightInfo = moonbeam_weights::pallet_author_slot_filter::WeightInfo<Runtime>;
}

impl pallet_async_backing::Config for Runtime {
type AllowMultipleBlocksPerSlot = ConstBool<true>;
type GetAndVerifySlot = pallet_async_backing::RelaySlot;
type ExpectedBlockTime = ConstU64<6000>;
}

parameter_types! {
pub const InitializationPayment: Perbill = Perbill::from_percent(30);
pub const RelaySignaturesThreshold: Perbill = Perbill::from_percent(100);
Expand Down Expand Up @@ -1106,7 +1125,10 @@ impl pallet_proxy::Config for Runtime {

impl pallet_migrations::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type MigrationsList = (moonbeam_runtime_common::migrations::CommonMigrations<Runtime>,);
type MigrationsList = (
moonbeam_runtime_common::migrations::CommonMigrations<Runtime>,
migrations::MoonriverMigrations,
);
type XcmExecutionManager = XcmExecutionManager;
}

Expand Down Expand Up @@ -1350,6 +1372,7 @@ construct_runtime! {
AuthorFilter: pallet_author_slot_filter::{Pallet, Call, Storage, Event, Config<T>} = 22,
AuthorMapping: pallet_author_mapping::{Pallet, Call, Config<T>, Storage, Event<T>} = 23,
MoonbeamOrbiters: pallet_moonbeam_orbiters::{Pallet, Call, Storage, Event<T>} = 24,
AsyncBacking: pallet_async_backing::{Pallet, Storage} = 25,

// Handy utilities.
Utility: pallet_utility::{Pallet, Call, Event} = 30,
Expand Down Expand Up @@ -1574,12 +1597,10 @@ moonbeam_runtime_common::impl_runtime_apis_plus_common! {

impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
fn can_build_upon(
_included_hash: <Block as BlockT>::Hash,
_slot: async_backing_primitives::Slot,
included_hash: <Block as BlockT>::Hash,
slot: async_backing_primitives::Slot,
) -> bool {
// This runtime API can be called only when asynchronous backing is enabled client-side
// We return false here to force the client to not use async backing in moonriver.
false
ConsensusHook::can_build_upon(included_hash, slot)
}
}
}
Expand Down
43 changes: 43 additions & 0 deletions runtime/moonriver/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2024 Moonbeam Foundation Inc.
// This file is part of Moonbeam.

// Moonbeam 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.

// Moonbeam 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 Moonbeam. If not, see <http://www.gnu.org/licenses/>.

//! # Moonriver specific Migrations

use crate::Runtime;
use frame_support::{traits::OnRuntimeUpgrade, weights::Weight};
use pallet_migrations::{GetMigrations, Migration};
use pallet_parachain_staking::migrations::MultiplyRoundLenBy2;
use sp_std::{prelude::*, vec};

pub struct MoonriverMigrations;

impl GetMigrations for MoonriverMigrations {
fn get_migrations() -> Vec<Box<dyn Migration>> {
vec![Box::new(PalletStakingMultiplyRoundLenBy2)]
}
}

// This migration should only be applied to runtimes with async backing enabled
pub struct PalletStakingMultiplyRoundLenBy2;
impl Migration for PalletStakingMultiplyRoundLenBy2 {
fn friendly_name(&self) -> &str {
"MM_MultiplyRoundLenBy2"
}

fn migrate(&self, _available_weight: Weight) -> Weight {
MultiplyRoundLenBy2::<Runtime>::on_runtime_upgrade()
}
}
17 changes: 13 additions & 4 deletions runtime/moonriver/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ pub use moonriver_runtime::{
asset_config::AssetRegistrarMetadata,
currency::{GIGAWEI, MOVR, SUPPLY_FACTOR, WEI},
xcm_config::AssetType,
AccountId, AssetId, AssetManager, AuthorInherent, Balance, Balances, CrowdloanRewards,
Ethereum, Executive, Header, InflationInfo, ParachainStaking, Range, Runtime, RuntimeCall,
RuntimeEvent, System, TransactionConverter, TransactionPaymentAsGasPrice, UncheckedExtrinsic,
HOURS, WEEKS,
AccountId, AssetId, AssetManager, AsyncBacking, AuthorInherent, Balance, Balances,
CrowdloanRewards, Ethereum, Executive, Header, InflationInfo, ParachainStaking, Range, Runtime,
RuntimeCall, RuntimeEvent, System, TransactionConverter, TransactionPaymentAsGasPrice,
UncheckedExtrinsic, HOURS, WEEKS,
};
use nimbus_primitives::{NimbusId, NIMBUS_ENGINE_ID};
use sp_consensus_slots::Slot;
use sp_core::{Encode, H160};
use sp_runtime::{traits::Dispatchable, BuildStorage, Digest, DigestItem, Perbill, Percent};

Expand Down Expand Up @@ -378,3 +379,11 @@ pub fn ethereum_transaction(raw_hex_tx: &str) -> pallet_ethereum::Transaction {
assert!(transaction.is_ok());
transaction.unwrap()
}

pub(crate) fn increase_last_relay_slot_number(amount: u64) {
let last_relay_slot = u64::from(AsyncBacking::slot_info().unwrap_or_default().0);
frame_support::storage::unhashed::put(
&frame_support::storage::storage_prefix(b"AsyncBacking", b"SlotInfo"),
&((Slot::from(last_relay_slot + amount), 0)),
);
}
34 changes: 21 additions & 13 deletions runtime/moonriver/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,25 +616,27 @@ fn reward_block_authors() {
)])
.build()
.execute_with(|| {
set_parachain_inherent_data();
for x in 2..1199 {
run_to_block(x, Some(NimbusId::from_slice(&ALICE_NIMBUS).unwrap()));
}
increase_last_relay_slot_number(1);

// Just before round 3
run_to_block(2399, Some(NimbusId::from_slice(&ALICE_NIMBUS).unwrap()));

// no rewards doled out yet
assert_eq!(
Balances::usable_balance(AccountId::from(ALICE)),
10_100 * MOVR,
);
assert_eq!(Balances::usable_balance(AccountId::from(BOB)), 9500 * MOVR,);
run_to_block(1201, Some(NimbusId::from_slice(&ALICE_NIMBUS).unwrap()));
run_to_block(2401, Some(NimbusId::from_slice(&ALICE_NIMBUS).unwrap()));

// rewards minted and distributed
assert_eq!(
Balances::usable_balance(AccountId::from(ALICE)),
11547666666208000000000,
10101206388888506666666,
);
assert_eq!(
Balances::usable_balance(AccountId::from(BOB)),
9557333332588000000000,
9500047777777156666667,
);
});
}
Expand All @@ -660,12 +662,13 @@ fn reward_block_authors_with_parachain_bond_reserved() {
)])
.build()
.execute_with(|| {
set_parachain_inherent_data();
increase_last_relay_slot_number(1);
assert_ok!(ParachainStaking::set_parachain_bond_account(
root_origin(),
AccountId::from(CHARLIE),
),);

// Stop just before round 2
run_to_block(1199, Some(NimbusId::from_slice(&ALICE_NIMBUS).unwrap()));

// no collator rewards doled out yet
Expand All @@ -675,26 +678,31 @@ fn reward_block_authors_with_parachain_bond_reserved() {
);
assert_eq!(Balances::usable_balance(AccountId::from(BOB)), 9500 * MOVR,);

// Go to round 2
run_to_block(1201, Some(NimbusId::from_slice(&ALICE_NIMBUS).unwrap()));

// 30% reserved for parachain bond
assert_eq!(
Balances::usable_balance(AccountId::from(CHARLIE)),
452515000000000000000,
1376262500000000000,
);

run_to_block(1201, Some(NimbusId::from_slice(&ALICE_NIMBUS).unwrap()));
// Go to round 3
run_to_block(2401, Some(NimbusId::from_slice(&ALICE_NIMBUS).unwrap()));

// rewards minted and distributed
assert_eq!(
Balances::usable_balance(AccountId::from(ALICE)),
11117700475903800000000,
10100848083729919833333,
);
assert_eq!(
Balances::usable_balance(AccountId::from(BOB)),
9535834523343675000000,
9500029862102786395833,
);
// 30% reserved for parachain bond again
assert_eq!(
Balances::usable_balance(AccountId::from(CHARLIE)),
910802725000000000000,
1376262500000000000,
);
});
}
Expand Down

0 comments on commit ae2c682

Please sign in to comment.