Skip to content

Commit

Permalink
Feat/dapp staking v3 precompiles (#1096)
Browse files Browse the repository at this point in the history
* Init commit

* All legacy calls covered

* v2 interface first definition

* Rename

* Resolve merge errors

* TODO

* v2 init implementation

* Prepared mock

* todo

* Migration to v2 utils

* More adjustments

* Finish adapting implementation to v2

* Mock & fixes

* Primitive smart contract

* Fix dsv3 test

* Prepare impl & mock

* Remove redundant code, adjust mock & prepare tests

* Tests & utils

* Test for legacy getters/view functions

* More legacy tests

* v1 interface covered with tests

* Minor refactor, organization, improvements

* v2 tests

* Cleanup TODOs

* More tests

* Updates

* docs

* Fixes

* Address review comments

* Adjustments

* Audit comments

* Fix mock

* FMT

* Review comments
  • Loading branch information
Dinonard authored Dec 19, 2023
1 parent 38d2b72 commit 808686f
Show file tree
Hide file tree
Showing 26 changed files with 3,291 additions and 126 deletions.
31 changes: 29 additions & 2 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ pallet-evm-precompile-substrate-ecdsa = { path = "./precompiles/substrate-ecdsa"
pallet-evm-precompile-xcm = { path = "./precompiles/xcm", default-features = false }
pallet-evm-precompile-xvm = { path = "./precompiles/xvm", default-features = false }
pallet-evm-precompile-dapps-staking = { path = "./precompiles/dapps-staking", default-features = false }
pallet-evm-precompile-dapp-staking-v3 = { path = "./precompiles/dapp-staking-v3", default-features = false }
pallet-evm-precompile-unified-accounts = { path = "./precompiles/unified-accounts", default-features = false }

pallet-chain-extension-dapps-staking = { path = "./chain-extensions/dapps-staking", default-features = false }
Expand Down
15 changes: 2 additions & 13 deletions pallets/dapp-staking-migration/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ use frame_support::{
weights::Weight,
PalletId,
};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use sp_arithmetic::fixed_point::FixedU64;
use sp_core::H256;
use sp_io::TestExternalities;
use sp_runtime::traits::{BlakeTwo256, IdentityLookup};

use astar_primitives::{
dapp_staking::{CycleConfiguration, StakingRewardHandler},
dapp_staking::{CycleConfiguration, SmartContract, StakingRewardHandler},
testing::Header,
Balance, BlockNumber,
};
Expand Down Expand Up @@ -134,17 +133,7 @@ impl StakingRewardHandler<AccountId> for DummyStakingRewardHandler {
}
}

#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug, TypeInfo, MaxEncodedLen, Hash)]
pub enum MockSmartContract {
Wasm(AccountId),
Other(AccountId),
}

impl Default for MockSmartContract {
fn default() -> Self {
MockSmartContract::Wasm(1)
}
}
pub(crate) type MockSmartContract = SmartContract<AccountId>;

#[cfg(feature = "runtime-benchmarks")]
pub struct BenchmarkHelper<SC, ACC>(sp_std::marker::PhantomData<(SC, ACC)>);
Expand Down
3 changes: 2 additions & 1 deletion pallets/dapp-staking-v3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ be left out of tiers and won't earn **any** reward.
In a special and unlikely case that two or more dApps have the exact same score and satisfy tier entry threshold, but there isn't enough
leftover tier capacity to accomodate them all, this is considered _undefined_ behavior. Some of the dApps will manage to enter the tier, while
others will be left out. There is no strict rule which defines this behavior - instead dApps are encouraged to ensure their tier entry by
having a larger stake than the other dApp(s).
having a larger stake than the other dApp(s). Tehnically, at the moment, the dApp with the lower `dApp Id` will have the advantage over a dApp with
the larger Id.

### Reward Expiry

Expand Down
24 changes: 15 additions & 9 deletions pallets/dapp-staking-v3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use sp_runtime::{
pub use sp_std::vec::Vec;

use astar_primitives::{
dapp_staking::{CycleConfiguration, StakingRewardHandler},
dapp_staking::{CycleConfiguration, SmartContractHandle, StakingRewardHandler},
Balance, BlockNumber,
};

Expand Down Expand Up @@ -118,7 +118,10 @@ pub mod pallet {
>;

/// Describes smart contract in the context required by dApp staking.
type SmartContract: Parameter + Member + MaxEncodedLen;
type SmartContract: Parameter
+ Member
+ MaxEncodedLen
+ SmartContractHandle<Self::AccountId>;

/// Privileged origin for managing dApp staking pallet.
type ManagerOrigin: EnsureOrigin<<Self as frame_system::Config>::RuntimeOrigin>;
Expand Down Expand Up @@ -795,7 +798,7 @@ pub mod pallet {
ledger.subtract_lock_amount(amount_to_unlock);

let current_block = frame_system::Pallet::<T>::block_number();
let unlock_block = current_block.saturating_add(Self::unlock_period());
let unlock_block = current_block.saturating_add(Self::unlocking_period());
ledger
.add_unlocking_chunk(amount_to_unlock, unlock_block)
.map_err(|_| Error::<T>::TooManyUnlockingChunks)?;
Expand Down Expand Up @@ -1137,8 +1140,9 @@ pub mod pallet {
let earliest_staked_era = ledger
.earliest_staked_era()
.ok_or(Error::<T>::InternalClaimStakerError)?;
let era_rewards = EraRewards::<T>::get(Self::era_reward_index(earliest_staked_era))
.ok_or(Error::<T>::NoClaimableRewards)?;
let era_rewards =
EraRewards::<T>::get(Self::era_reward_span_index(earliest_staked_era))
.ok_or(Error::<T>::NoClaimableRewards)?;

// The last era for which we can theoretically claim rewards.
// And indicator if we know the period's ending era.
Expand Down Expand Up @@ -1545,7 +1549,7 @@ pub mod pallet {
}

/// Calculates the `EraRewardSpan` index for the specified era.
pub(crate) fn era_reward_index(era: EraNumber) -> EraNumber {
pub fn era_reward_span_index(era: EraNumber) -> EraNumber {
era.saturating_sub(era % T::EraRewardSpanLength::get())
}

Expand All @@ -1556,7 +1560,7 @@ pub mod pallet {
}

/// Unlocking period expressed in the number of blocks.
pub(crate) fn unlock_period() -> BlockNumber {
pub fn unlocking_period() -> BlockNumber {
T::CycleConfiguration::blocks_per_era().saturating_mul(T::UnlockingPeriod::get().into())
}

Expand Down Expand Up @@ -1655,7 +1659,9 @@ pub mod pallet {
// In case when tier has 1 more free slot, but two dApps with exactly same score satisfy the threshold,
// one of them will be assigned to the tier, and the other one will be assigned to the lower tier, if it exists.
//
// There is no explicit definition of which dApp gets the advantage - it's decided by dApp IDs hash & the unstable sort algorithm.
// In the current implementation, the dApp with the lower dApp Id has the advantage.
// There is no guarantee this will persist in the future, so it's best for dApps to do their
// best to avoid getting themselves into such situations.

// 4. Calculate rewards.
let tier_rewards = tier_config
Expand Down Expand Up @@ -1842,7 +1848,7 @@ pub mod pallet {

CurrentEraInfo::<T>::put(era_info);

let era_span_index = Self::era_reward_index(current_era);
let era_span_index = Self::era_reward_span_index(current_era);
let mut span = EraRewards::<T>::get(&era_span_index).unwrap_or(EraRewardSpan::new());
if let Err(_) = span.push(current_era, era_reward) {
// This must never happen but we log the error just in case.
Expand Down
17 changes: 3 additions & 14 deletions pallets/dapp-staking-v3/src/test/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use frame_support::{
},
weights::Weight,
};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use sp_arithmetic::fixed_point::FixedU64;
use sp_core::H256;
use sp_io::TestExternalities;
Expand All @@ -40,7 +39,7 @@ use sp_runtime::{
};
use sp_std::cell::RefCell;

use astar_primitives::{testing::Header, Balance, BlockNumber};
use astar_primitives::{dapp_staking::SmartContract, testing::Header, Balance, BlockNumber};

pub(crate) type AccountId = u64;

Expand Down Expand Up @@ -146,17 +145,7 @@ impl StakingRewardHandler<AccountId> for DummyStakingRewardHandler {
}
}

#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug, TypeInfo, MaxEncodedLen, Hash)]
pub enum MockSmartContract {
Wasm(AccountId),
Other(AccountId),
}

impl Default for MockSmartContract {
fn default() -> Self {
MockSmartContract::Wasm(1)
}
}
pub(crate) type MockSmartContract = SmartContract<AccountId>;

#[cfg(feature = "runtime-benchmarks")]
pub struct BenchmarkHelper<SC, ACC>(sp_std::marker::PhantomData<(SC, ACC)>);
Expand All @@ -165,7 +154,7 @@ impl crate::BenchmarkHelper<MockSmartContract, AccountId>
for BenchmarkHelper<MockSmartContract, AccountId>
{
fn get_smart_contract(id: u32) -> MockSmartContract {
MockSmartContract::Wasm(id as AccountId)
MockSmartContract::wasm(id as AccountId)
}

fn set_balance(account: &AccountId, amount: Balance) {
Expand Down
6 changes: 3 additions & 3 deletions pallets/dapp-staking-v3/src/test/testing_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,7 @@ pub(crate) fn assert_block_bump(pre_snapshot: &MemorySnapshot) {
}

// 4. Verify era reward
let era_span_index = DappStaking::era_reward_index(pre_protoc_state.era);
let era_span_index = DappStaking::era_reward_span_index(pre_protoc_state.era);
let maybe_pre_era_reward_span = pre_snapshot.era_rewards.get(&era_span_index);
let post_era_reward_span = post_snapshot
.era_rewards
Expand Down Expand Up @@ -1467,10 +1467,10 @@ pub(crate) fn required_number_of_reward_claims(account: AccountId) -> u32 {
};

let era_span_length: EraNumber = <Test as Config>::EraRewardSpanLength::get();
let first = DappStaking::era_reward_index(range.0)
let first = DappStaking::era_reward_span_index(range.0)
.checked_div(era_span_length)
.unwrap();
let second = DappStaking::era_reward_index(range.1)
let second = DappStaking::era_reward_span_index(range.1)
.checked_div(era_span_length)
.unwrap();

Expand Down
Loading

0 comments on commit 808686f

Please sign in to comment.