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

claim_staking_rewards extrinsic #2080

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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
21 changes: 21 additions & 0 deletions common/primitives/src/capacity.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::msa::MessageSourceId;
use frame_support::traits::tokens::Balance;
use scale_info::TypeInfo;
use sp_core::{Decode, Encode, MaxEncodedLen, RuntimeDebug};
use sp_runtime::DispatchError;

/// The type of a Reward Era
Expand Down Expand Up @@ -55,3 +57,22 @@ pub trait Replenishable {
/// Checks if an account can be replenished.
fn can_replenish(msa_id: MessageSourceId) -> bool;
}

/// Result of checking a Boost History item to see if it's eligible for a reward.
#[derive(
Copy, Clone, Default, Encode, Eq, Decode, RuntimeDebug, MaxEncodedLen, PartialEq, TypeInfo,
)]
#[scale_info(skip_type_params(T))]
pub struct UnclaimedRewardInfo<Balance, BlockNumber> {
/// The Reward Era for which this reward was earned
pub reward_era: RewardEra,
/// When this reward expires, i.e. can no longer be claimed
pub expires_at_block: BlockNumber,
/// The total staked in this era as of the current block
pub staked_amount: Balance,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It makes sense to have the amount they staked in each Reward Info.

/// The amount staked in this era that is eligible for rewards. Does not count additional amounts
/// staked in this era.
pub eligible_amount: Balance,
/// The amount in token of the reward (only if it can be calculated using only on chain data)
pub earned_amount: Balance,
}
17 changes: 13 additions & 4 deletions e2e/capacity/change_staking_target.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { getFundingSource } from '../scaffolding/funding';
import {
createKeys, createMsaAndProvider,
stakeToProvider,
CENTS, DOLLARS, createAndFundKeypair, createProviderKeysAndId
} from "../scaffolding/helpers";
CENTS, DOLLARS, createAndFundKeypair, createProviderKeysAndId, getNonce,
} from '../scaffolding/helpers';
import { KeyringPair } from '@polkadot/keyring/types';

const fundingSource = getFundingSource('capacity-replenishment');

Expand Down Expand Up @@ -39,9 +40,17 @@ describe("Capacity: change_staking_target", function() {
await assert.rejects(call.signAndSend(),
(err) => {
assert. strictEqual(err?.name, 'InvalidTarget', `expected InvalidTarget, got ${err?.name}`);
// // {name: "InvalidTarget"}
// assert. strictEqual(err?.message, `Wrong value: expected`);
return true;
});
});

it("foo", async function(){
const fundedKeys: KeyringPair = await createAndFundKeypair(fundingSource, 100_000_000n);
const receiverKeys: KeyringPair = await createAndFundKeypair(fundingSource);
const accountPKey = fundedKeys.publicKey;
const nonce = await getNonce(fundedKeys);

const transferCalls = ExtrinsicHelper.api.tx.balances.transferKeepAlive(receiverKeys.publicKey, 100n);
transferCalls.signAndSend(fundedKeys);
});
});
49 changes: 35 additions & 14 deletions pallets/capacity/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,23 @@ fn fill_unlock_chunks<T: Config>(caller: &T::AccountId, count: u32) {
UnstakeUnlocks::<T>::set(caller, Some(unlocking));
}

fn fill_reward_pool_chunks<T: Config>() {
let chunk_len = T::RewardPoolChunkLength::get();
let chunks = T::ProviderBoostHistoryLimit::get() / (chunk_len);
for i in 0..chunks {
let mut new_chunk = RewardPoolHistoryChunk::<T>::new();
for j in 0..chunk_len {
let era = (i + 1) * (j + 1);
assert_ok!(new_chunk.try_insert(era.into(), (1000u32 * era).into()));
}
ProviderBoostRewardPools::<T>::set(i, Some(new_chunk));
fn fill_reward_pool_chunks<T: Config>(current_era: RewardEra) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The previous version of this function, while it worked for the provider_boost benchmark, did not correctly fill up the reward_pool_chunks, so it caused an EraOutOfRange error in the claim_staking_reward benchmark.

let history_limit: RewardEra = <T as Config>::ProviderBoostHistoryLimit::get();
let starting_era: RewardEra = current_era - history_limit - 1u32;
for era in starting_era..current_era {
Capacity::<T>::update_provider_boost_reward_pool(era, 10_000u32.into());
}
}

fn fill_boost_history<T: Config>(
caller: &T::AccountId,
amount: BalanceOf<T>,
current_era: RewardEra,
) {
let max_history: RewardEra = <T as Config>::ProviderBoostHistoryLimit::get().into();
let starting_era = current_era - max_history - 1u32;
for i in starting_era..current_era {
assert_ok!(Capacity::<T>::upsert_boost_history(caller.into(), i, amount, true));
}
}

Expand Down Expand Up @@ -152,7 +159,7 @@ benchmarks! {

let current_era: RewardEra = (history_limit + 1u32).into();
CurrentEraInfo::<T>::set(RewardEraInfo{ era_index: current_era, started_at });
fill_reward_pool_chunks::<T>();
fill_reward_pool_chunks::<T>(current_era);
}: {
Capacity::<T>::start_new_reward_era_if_needed(current_block);
} verify {
Expand Down Expand Up @@ -232,12 +239,26 @@ benchmarks! {

}: _ (RawOrigin::Signed(caller.clone()), target, boost_amount)
verify {
assert!(StakingAccountLedger::<T>::contains_key(&caller));
assert!(StakingTargetLedger::<T>::contains_key(&caller, target));
assert!(CapacityLedger::<T>::contains_key(target));
assert_last_event::<T>(Event::<T>::ProviderBoosted {account: caller, amount: boost_amount, target, capacity}.into());
}

// TODO: vary the boost_history to get better weight estimates.
claim_staking_rewards {
let caller: T::AccountId = create_funded_account::<T>("account", SEED, 5u32);
let from_msa = 33;
let from_msa_amount: BalanceOf<T> = T::MinimumStakingAmount::get().saturating_add(31u32.into());
setup_provider_stake::<T>(&caller, &from_msa, from_msa_amount, false);
frame_system::Pallet::<T>::set_block_number(1002u32.into());
let current_era: RewardEra = 100u32;
set_era_and_reward_pool_at_block::<T>(current_era, 1001u32.into(), 1_000u32.into());
fill_reward_pool_chunks::<T>(current_era);
fill_boost_history::<T>(&caller, 1000u32.into(), current_era);
}: _ (RawOrigin::Signed(caller.clone()))
verify {
let expected_amount: BalanceOf<T> = 293u32.into();
assert_last_event::<T>(Event::<T>::ProviderBoostRewardClaimed {account: caller.clone(), reward_amount: expected_amount}.into());
}

impl_benchmark_test_suite!(Capacity,
tests::mock::new_test_ext(),
tests::mock::Test);
Expand Down
Loading