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

Feat/dapp staking v3 precompiles #1096

Merged
merged 39 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
c6b63a6
Init commit
Dinonard Dec 5, 2023
e317f4d
All legacy calls covered
Dinonard Dec 5, 2023
b675c77
v2 interface first definition
Dinonard Dec 5, 2023
e2dbf48
Rename
Dinonard Dec 5, 2023
4cef3cf
Merge remote-tracking branch 'origin/feat/dapp-staking-v3' into feat/…
Dinonard Dec 5, 2023
f3b0804
Resolve merge errors
Dinonard Dec 5, 2023
13fcfe6
TODO
Dinonard Dec 6, 2023
d1668d6
v2 init implementation
Dinonard Dec 6, 2023
cd66ee7
Prepared mock
Dinonard Dec 6, 2023
777b0a8
todo
Dinonard Dec 8, 2023
58e5500
Migration to v2 utils
Dinonard Dec 14, 2023
5df87ca
More adjustments
Dinonard Dec 14, 2023
791243f
Finish adapting implementation to v2
Dinonard Dec 14, 2023
dac1dd4
Mock & fixes
Dinonard Dec 14, 2023
0ffe023
Primitive smart contract
Dinonard Dec 14, 2023
03ee458
Fix dsv3 test
Dinonard Dec 14, 2023
9e8e81b
Prepare impl & mock
Dinonard Dec 14, 2023
94b480c
Remove redundant code, adjust mock & prepare tests
Dinonard Dec 15, 2023
ff0d6cd
Tests & utils
Dinonard Dec 15, 2023
578d0e2
Test for legacy getters/view functions
Dinonard Dec 15, 2023
4ac2884
More legacy tests
Dinonard Dec 15, 2023
96e7c2b
v1 interface covered with tests
Dinonard Dec 15, 2023
fadf928
Minor refactor, organization, improvements
Dinonard Dec 15, 2023
127a80a
v2 tests
Dinonard Dec 16, 2023
7ce2370
Cleanup TODOs
Dinonard Dec 16, 2023
391a3e8
More tests
Dinonard Dec 16, 2023
c6148b1
Updates
Dinonard Dec 16, 2023
65db544
docs
Dinonard Dec 16, 2023
c8431e5
Merge remote-tracking branch 'origin/feat/dapp-staking-v3' into feat/…
Dinonard Dec 16, 2023
c880ed2
Fixes
Dinonard Dec 16, 2023
6ae4a2a
Merge remote-tracking branch 'origin/master' into feat/dapp-staking-v…
Dinonard Dec 18, 2023
feab9d6
Address review comments
Dinonard Dec 18, 2023
eea2f21
Merge remote-tracking branch 'origin/feat/dapp-staking-v3' into feat/…
Dinonard Dec 18, 2023
c4f0fc2
Merge remote-tracking branch 'origin/feat/dapp-staking-v3' into feat/…
Dinonard Dec 18, 2023
1aaa0be
Adjustments
Dinonard Dec 18, 2023
10f1019
Audit comments
Dinonard Dec 18, 2023
9504670
Fix mock
Dinonard Dec 18, 2023
30ac30d
FMT
Dinonard Dec 18, 2023
547d57f
Review comments
Dinonard Dec 19, 2023
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
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
Loading