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

Remove tight coupling to parachain system #43

Merged
merged 15 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from 14 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
18 changes: 10 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ sp-io = { git = "https://github.com/paritytech/substrate", default-features = fa
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false }
pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false }
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false, optional = true }
cumulus-pallet-parachain-system = { git = "https://github.com/purestake/cumulus", default-features = false, branch = "nimbus-polkadot-v0.9.9" }
cumulus-primitives-core = { git = "https://github.com/purestake/cumulus", default-features = false, branch = "nimbus-polkadot-v0.9.9" }
cumulus-primitives-parachain-inherent = { git = "https://github.com/purestake/cumulus", default-features = false, branch = "nimbus-polkadot-v0.9.9" }
ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend", "alloc"], optional = true }
sp-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.9", optional = true }

# These cumulus dependencies to be removed with https://github.com/PureStake/crowdloan-rewards/pull/44
cumulus-primitives-core = { git = "https://github.com/purestake/cumulus", branch = "nimbus-polkadot-v0.9.9", optional = true }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cumulus-primitives-core = { git = "https://github.com/purestake/cumulus", branch = "nimbus-polkadot-v0.9.9", optional = true }
cumulus-primitives-core = { git = "https://github.com/purestake/cumulus", branch = "nimbus-polkadot-v0.9.9", optional = true, default-features=false }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if they are optional, as benchmarking is compiled without std, we should add default-features = false in all of them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. CI should also catch this for us.

cumulus-pallet-parachain-system = { git = "https://github.com/purestake/cumulus", branch = "nimbus-polkadot-v0.9.9", optional = true }
cumulus-primitives-parachain-inherent = { git = "https://github.com/purestake/cumulus", branch = "nimbus-polkadot-v0.9.9", optional = true }

[dev-dependencies]
cumulus-test-relay-sproof-builder = { git = "https://github.com/purestake/cumulus", default-features = false, branch = "nimbus-polkadot-v0.9.9" }
cumulus-test-relay-sproof-builder = { git = "https://github.com/purestake/cumulus", branch = "nimbus-polkadot-v0.9.9" }

[features]
default = ["std"]
Expand All @@ -43,12 +45,12 @@ std = [
"log/std",
"sp-std/std",
"sp-io/std",
"cumulus-pallet-parachain-system/std",
JoshOrndorff marked this conversation as resolved.
Show resolved Hide resolved
"cumulus-primitives-core/std",
"cumulus-primitives-parachain-inherent/std",
]
runtime-benchmarks = [
"frame-benchmarking",
"sp-trie",
"ed25519-dalek"
"ed25519-dalek",
"cumulus-primitives-core",
"cumulus-pallet-parachain-system",
"cumulus-primitives-parachain-inherent",
]
19 changes: 13 additions & 6 deletions src/benchmarks.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg(feature = "runtime-benchmarks")]

use crate::{BalanceOf, Call, Config, Pallet};
use crate::{BalanceOf, Call, Pallet};
use cumulus_pallet_parachain_system::Pallet as RelayPallet;
use cumulus_primitives_core::{
relay_chain::{v1::HeadData, BlockNumber as RelayChainBlockNumber},
Expand Down Expand Up @@ -39,9 +39,14 @@ const MOCK_PROOF_HASH: [u8; 32] = [
243, 146, 7, 202, 245, 129, 165, 70, 72, 184, 130, 141,
];

// These benchmarks only work with a Runtime that uses cumulus's RelayChainBlockNumberProvider.
// This will improve once https://github.com/PureStake/crowdloan-rewards/pull/44 lands
pub trait Config: crate::Config + cumulus_pallet_parachain_system::Config {}
impl<T: crate::Config + cumulus_pallet_parachain_system::Config> Config for T {}

/// Default balance amount is minimum contribution
fn default_balance<T: Config>() -> BalanceOf<T> {
<<T as Config>::MinimumReward as Get<BalanceOf<T>>>::get()
T::MinimumReward::get()
}

/// Create a funded user.
Expand Down Expand Up @@ -135,8 +140,10 @@ fn insert_contributors<T: Config>(
}

/// Create a Contributor.
fn close_initialization<T: Config>(end_relay: RelayChainBlockNumber) -> Result<(), &'static str> {
Pallet::<T>::complete_initialization(RawOrigin::Root.into(), end_relay)?;
fn close_initialization<T: Config>(
end_vesting_block: T::VestingBlockNumber,
) -> Result<(), &'static str> {
Pallet::<T>::complete_initialization(RawOrigin::Root.into(), end_vesting_block)?;
Ok(())
}

Expand All @@ -154,7 +161,7 @@ fn create_sig<T: Config>(signed_account: T::AccountId) -> (AccountId32, MultiSig
}

fn max_batch_contributors<T: Config>() -> u32 {
<<T as Config>::MaxInitContributors as Get<u32>>::get()
T::MaxInitContributors::get()
}

// This is our current number of contributors
Expand Down Expand Up @@ -206,7 +213,7 @@ benchmarks! {
RelayPallet::<T>::on_finalize(T::BlockNumber::one());
Pallet::<T>::on_finalize(T::BlockNumber::one());

}: _(RawOrigin::Root, 10u32)
}: _(RawOrigin::Root, 10u32.into())
verify {
assert!(Pallet::<T>::initialized());
}
Expand Down
75 changes: 36 additions & 39 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ pub mod weights;
pub mod pallet {

use crate::weights::WeightInfo;
use cumulus_primitives_core::relay_chain;
use frame_support::traits::WithdrawReasons;
use frame_support::{
dispatch::fmt::Debug,
pallet_prelude::*,
traits::{Currency, ExistenceRequirement::AllowDeath},
PalletId,
};
use frame_system::pallet_prelude::*;
use sp_core::crypto::AccountId32;
use sp_runtime::traits::{AccountIdConversion, Saturating, Verify};
use sp_runtime::traits::{
AccountIdConversion, AtLeast32BitUnsigned, BlockNumberProvider, Saturating, Verify,
};
use sp_runtime::{MultiSignature, Perbill};
use sp_std::vec;
use sp_std::vec::Vec;
Expand All @@ -95,11 +95,9 @@ pub mod pallet {

pub const PALLET_ID: PalletId = PalletId(*b"Crowdloa");

pub struct RelayChainBeacon<T>(PhantomData<T>);

/// Configuration trait of this pallet.
#[pallet::config]
pub trait Config: cumulus_pallet_parachain_system::Config + frame_system::Config {
pub trait Config: frame_system::Config {
/// The overarching event type
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
/// Checker for the reward vec, is it initalized already?
Expand All @@ -114,18 +112,19 @@ pub mod pallet {
type MinimumReward: Get<BalanceOf<Self>>;
/// The currency in which the rewards will be paid (probably the parachain native currency)
type RewardCurrency: Currency<Self::AccountId>;
// TODO What trait bounds do I need here? I think concretely we would
// be using MultiSigner? Or maybe MultiAccount? I copied these from frame_system
/// The AccountId type contributors used on the relay chain.
type RelayChainAccountId: Parameter
+ Member
+ MaybeSerializeDeserialize
+ Ord
+ Default
+ Debug
//TODO these AccountId32 bounds feel a little extraneous. I wonder if we can remove them.
JoshOrndorff marked this conversation as resolved.
Show resolved Hide resolved
+ Into<AccountId32>
+ From<AccountId32>;

/// The type that will be used to track vesting progress
type VestingBlockNumber: AtLeast32BitUnsigned + Parameter + Default + Into<BalanceOf<Self>>;

/// The notion of time that will be used for vesting. Probably
/// either the relay chain or sovereign chain block number.
type VestingBlockProvider: BlockNumberProvider<BlockNumber = Self::VestingBlockNumber>;

type WeightInfo: WeightInfo;
}

Expand All @@ -143,16 +142,13 @@ pub mod pallet {
pub contributed_relay_addresses: Vec<T::RelayChainAccountId>,
}

// This hook is in charge of initializing the relay chain height at the first block of the parachain
// This hook is in charge of initializing the vesting height at the first block of the parachain
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_finalize(n: <T as frame_system::Config>::BlockNumber) {
// In the first block of the parachain we need to introduce the relay block related info
// In the first block of the parachain we need to introduce the vesting block related info
if n == 1u32.into() {
let slot = cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
.expect("validation data was set in parachain system inherent")
.relay_parent_number;
<InitRelayBlock<T>>::put(slot);
<InitVestingBlock<T>>::put(T::VestingBlockProvider::current_block_number());
}
}
}
Expand Down Expand Up @@ -259,21 +255,19 @@ pub mod pallet {
Error::<T>::RewardsAlreadyClaimed
);

// Vesting is done in relation with the relay chain slot
let now = cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
.expect("validation data was set in parachain system inherent")
.relay_parent_number;
// Get the current block used for vesting purposes
let now = T::VestingBlockProvider::current_block_number();

// Substract the first payment from the vested amount
let first_paid = T::InitializationPayment::get() * info.total_reward;

// To calculate how much could the user have claimed already
let payable_period = now.saturating_sub(<InitRelayBlock<T>>::get());
let payable_period = now.saturating_sub(<InitVestingBlock<T>>::get());

// How much should the contributor have already claimed by this block?
// By multiplying first we allow the conversion to integer done with the biggest number
let period = EndRelayBlock::<T>::get() - InitRelayBlock::<T>::get();
let should_have_claimed = if period == 0 {
let period = EndVestingBlock::<T>::get() - InitVestingBlock::<T>::get();
let should_have_claimed = if period == 0u32.into() {
// Pallet is configured with a zero vesting period.
info.total_reward - first_paid
} else {
Expand Down Expand Up @@ -337,12 +331,12 @@ pub mod pallet {

/// This extrinsic completes the initialization if some checks are fullfiled. These checks are:
/// -The reward contribution money matches the crowdloan pot
/// -The end relay block is higher than the init relay block
/// -The end vesting block is higher than the init vesting block
/// -The initialization has not complete yet
#[pallet::weight(T::WeightInfo::complete_initialization())]
pub fn complete_initialization(
origin: OriginFor<T>,
lease_ending_block: relay_chain::BlockNumber,
lease_ending_block: T::VestingBlockNumber,
) -> DispatchResultWithPostInfo {
ensure_root(origin)?;

Expand All @@ -354,9 +348,10 @@ pub mod pallet {
Error::<T>::RewardVecAlreadyInitialized
);

// This ensures the lease ending block is bigger than the init relay block
// This ensures the end vesting block (when all funds are fully vested)
// is bigger than the init vesting block
ensure!(
lease_ending_block > InitRelayBlock::<T>::get(),
lease_ending_block > InitVestingBlock::<T>::get(),
Error::<T>::VestingPeriodNonValid
);

Expand All @@ -380,7 +375,7 @@ pub mod pallet {
.expect("Shouldnt fail, as the fund should be enough to burn and nothing is locked");
drop(imbalance);

EndRelayBlock::<T>::put(lease_ending_block);
EndVestingBlock::<T>::put(lease_ending_block);

<Initialized<T>>::put(true);

Expand Down Expand Up @@ -440,7 +435,7 @@ pub mod pallet {
}

if *reward < T::MinimumReward::get() {
// Dont fail as this is supposed to be called with batch calls and we
// Don't fail as this is supposed to be called with batch calls and we
// dont want to stall the rest of the contributions
Self::deposit_event(Event::InitializedAccountWithNotEnoughContribution(
relay_account.clone(),
Expand Down Expand Up @@ -468,7 +463,7 @@ pub mod pallet {
0u32.into()
};

// We need to calculate the vesting based on the relay block number
// Calculate the reward info to store after the initial payment has been made.
let mut reward_info = RewardInfo {
total_reward: *reward,
claimed_reward: initial_payment,
Expand Down Expand Up @@ -599,14 +594,16 @@ pub mod pallet {
pub type Initialized<T: Config> = StorageValue<_, bool, ValueQuery, T::Initialized>;

#[pallet::storage]
#[pallet::getter(fn init_relay_block)]
/// Relay block height at the initialization of the pallet
type InitRelayBlock<T: Config> = StorageValue<_, relay_chain::BlockNumber, ValueQuery>;
#[pallet::storage_prefix = "InitRelayBlock"]
#[pallet::getter(fn init_vesting_block)]
/// Vesting block height at the initialization of the pallet
type InitVestingBlock<T: Config> = StorageValue<_, T::VestingBlockNumber, ValueQuery>;
JoshOrndorff marked this conversation as resolved.
Show resolved Hide resolved

#[pallet::storage]
#[pallet::getter(fn end_relay_block)]
/// Relay block height at which vesting will be complete and all rewards fully vested.
type EndRelayBlock<T: Config> = StorageValue<_, relay_chain::BlockNumber, ValueQuery>;
#[pallet::storage_prefix = "EndRelayBlock"]
#[pallet::getter(fn end_vesting_block)]
/// Vesting block height at the initialization of the pallet
type EndVestingBlock<T: Config> = StorageValue<_, T::VestingBlockNumber, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn init_reward_amount)]
Expand Down
3 changes: 3 additions & 0 deletions src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ impl Config for Test {
type MinimumReward = TestMinimumReward;
type RewardCurrency = Balances;
type RelayChainAccountId = [u8; 32];
type VestingBlockNumber = RelayChainBlockNumber;
type VestingBlockProvider =
cumulus_pallet_parachain_system::RelaychainBlockNumberProvider<Self>;
type WeightInfo = ();
}

Expand Down
Loading