Skip to content

Commit

Permalink
Merge pull request #266 from PlasmNetwork/issue/255
Browse files Browse the repository at this point in the history
change claim specification
  • Loading branch information
t8m8 authored Feb 5, 2021
2 parents b5be83b + c44b123 commit 5d5d606
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 137 deletions.
125 changes: 40 additions & 85 deletions frame/dapps-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,6 @@ decl_storage! {
/// The already untreated era is EraIndex.
pub UntreatedEra get(fn untreated_era): EraIndex;

// The untreated era for each nominator
pub NominatorsUntreatedEra get(fn nominators_untreated_era):
map hasher(twox_64_concat) T::AccountId => EraIndex;

// The untreated era for each contract
pub ContractsUntreatedEra get(fn contracts_untreated_era):
map hasher(twox_64_concat) T::AccountId => EraIndex;
Expand Down Expand Up @@ -308,11 +304,6 @@ decl_storage! {
pub ErasTotalStake get(fn eras_total_stake):
map hasher(twox_64_concat) EraIndex => BalanceOf<T>;

/// The total amounts of staking for each nominators
ErasNominateTotals get(fn eras_nominate_totals):
double_map hasher(twox_64_concat) EraIndex, hasher(twox_64_concat) T::AccountId
=> BalanceOf<T>;

/// The total amounts of staking for pairs of nominator and contract
pub TotalStakes get(fn total_stakes):
double_map hasher(twox_64_concat) T::AccountId, hasher(twox_64_concat) T::AccountId
Expand Down Expand Up @@ -805,15 +796,17 @@ decl_module! {
}
}

/// rewards are claimed by the nominator.
/// rewards are claimed by the contract.
///
/// era must be in the range `[current_era - history_depth; active_era)`.
///
/// The dispatch origin for this call must be _Signed_ by the stash, not the controller.
/// TODO: weight
#[weight = 1_000]
fn claim_for_nominator(origin, era: EraIndex) {
let nominator = ensure_signed(origin)?;
fn claim(origin, contract: <T::Lookup as StaticLookup>::Source, era: EraIndex) {
ensure_signed(origin)?;

let contract = T::Lookup::lookup(contract)?;
if !T::ContractFinder::is_exists_contract(&contract) {
Err(Error::<T>::NotOperatedContracts)?
}

// check if era is valid
if let Some(active_era) = T::EraFinder::active() {
Expand All @@ -827,26 +820,15 @@ decl_module! {
}
}

let mut untreated_era = Self::nominators_untreated_era(&nominator);
let mut untreated_era = Self::contracts_untreated_era(&contract);
if era == untreated_era {
Err("the nominator already rewarded")?
Err("the contract is already rewarded")?
}
while era > untreated_era {
Self::propagate_nominate_totals(&nominator, &untreated_era, &(untreated_era + 1));
Self::propagate_eras_staking_points_total(&contract, &untreated_era, &(untreated_era + 1));
untreated_era += 1;
}
<NominatorsUntreatedEra<T>>::insert(&nominator, untreated_era);

for (contract, _) in <ErasStakingPoints<T>>::iter_prefix(&era) {
let mut untreated_era = Self::contracts_untreated_era(&contract);
if era != untreated_era {
while era > untreated_era {
Self::propagate_eras_staking_points_total(&contract, &untreated_era, &(untreated_era + 1));
untreated_era += 1;
}
<ContractsUntreatedEra<T>>::insert(&contract, untreated_era);
}
}
<ContractsUntreatedEra<T>>::insert(&contract, untreated_era);

let rewards = match T::ForDappsEraReward::get(&era) {
Some(rewards) => rewards,
Expand All @@ -856,43 +838,23 @@ decl_module! {
}
};

let actual_rewarded = Self::reward_nominator(&era, rewards, &nominator);
// deposit event to total validator rewards
Self::deposit_event(RawEvent::TotalDappsRewards(era, actual_rewarded));
}

/// rewards are claimed by the operator.
///
/// era must be in the range [current_era - history_depth; active_era).
///
/// The dispatch origin for this call must be _Signed_ by the stash, not the controller
/// TODO: weight
#[weight = 1_000]
fn claim_for_operator(origin, era: EraIndex) {
let operator = ensure_signed(origin)?;
let mut actual_rewarded = BalanceOf::<T>::zero();

// check if era is valid
if let Some(active_era) = T::EraFinder::active() {
if era >= active_era.index {
Err("cannot claim yet")?
}
}
if let Some(current_era) = T::EraFinder::current() {
if era < current_era.saturating_sub(T::HistoryDepthFinder::get()) {
Err("the era is expired")?
}
// rewards for the operator
if let Some(operator) = T::ContractFinder::operator(&contract) {
actual_rewarded += Self::reward_operator(&era, rewards, &operator, &contract);
}

let rewards = match T::ForDappsEraReward::get(&era) {
Some(rewards) => rewards,
None => {
frame_support::print("Error: start_session_index must be set for current_era");
BalanceOf::<T>::zero()
// rewards for nominators
let each_points = (era.saturating_sub(T::HistoryDepthFinder::get())..=era)
.map(|era| Self::eras_staking_points(&era, &contract));
for points in each_points {
for (nominator, _) in points.individual {
actual_rewarded += Self::reward_nominator(&era, rewards, &nominator, &contract);
}
};
}

let actual_rewarded = Self::reward_operator(&era, rewards, &operator);
// deposit event to total validator rewards
// deposit event to total rewards
Self::deposit_event(RawEvent::TotalDappsRewards(era, actual_rewarded));
}
}
Expand Down Expand Up @@ -945,20 +907,11 @@ impl<T: Trait> Module<T> {
}
}

fn propagate_nominate_totals(nominator: &T::AccountId, src_era: &EraIndex, dst_era: &EraIndex) {
if <ErasNominateTotals<T>>::contains_key(src_era, nominator) {
let untreated_nootate_total = <ErasNominateTotals<T>>::get(src_era, nominator);

<ErasNominateTotals<T>>::mutate(dst_era, nominator, |total| {
*total += untreated_nootate_total;
})
}
}

fn reward_nominator(
era: &EraIndex,
max_payout: BalanceOf<T>,
nominator: &T::AccountId,
contract: &T::AccountId,
) -> BalanceOf<T> {
let mut total_imbalance = <PositiveImbalanceOf<T>>::zero();
let (_, nominators_reward) =
Expand All @@ -968,9 +921,13 @@ impl<T: Trait> Module<T> {

let mut nominate_values: Vec<_> = Vec::new();

// collect target points
let mut each_points: Vec<_> = Vec::new();
for e in era.saturating_sub(T::HistoryDepthFinder::get())..=*era {
for (contract, points) in <ErasStakingPoints<T>>::iter_prefix(&e) {
for (c, points) in <ErasStakingPoints<T>>::iter_prefix(&e) {
if c != *contract {
continue;
}
if Self::is_rewardable(&contract, &e) {
each_points.push((
Self::eras_staking_points(era, contract).total,
Expand All @@ -980,15 +937,17 @@ impl<T: Trait> Module<T> {
}
}

// summarize nominated values
let mut nominate_total = BalanceOf::<T>::zero();
for (total, individual) in each_points {
for (account, value) in individual {
if account == *nominator {
nominate_total += value;
nominate_values.push((total, value));
}
}
}

let nominate_total = Self::eras_nominate_totals(era, nominator);
let reward = T::ComputeRewardsForDapps::compute_reward_for_nominator(
nominate_total,
total_staked,
Expand All @@ -1012,6 +971,7 @@ impl<T: Trait> Module<T> {
era: &EraIndex,
max_payout: BalanceOf<T>,
operator: &T::AccountId,
contract: &T::AccountId,
) -> BalanceOf<T> {
let mut total_imbalance = <PositiveImbalanceOf<T>>::zero();
let (operators_reward, _) =
Expand All @@ -1021,7 +981,10 @@ impl<T: Trait> Module<T> {

let mut stakes = BalanceOf::<T>::zero();
for e in era.saturating_sub(T::HistoryDepthFinder::get())..=*era {
for (contract, _) in <ErasStakingPoints<T>>::iter_prefix(&e) {
for (c, _) in <ErasStakingPoints<T>>::iter_prefix(&e) {
if c != *contract {
continue;
}
if let Some(o) = T::ContractFinder::operator(&contract) {
if o == *operator && Self::is_rewardable(&contract, &e) {
stakes += Self::eras_staking_points(era, contract).total;
Expand Down Expand Up @@ -1120,10 +1083,6 @@ impl<T: Trait> Module<T> {
<ErasStakingPoints<T>>::insert(&next_era, &contract, points);
}

<ErasNominateTotals<T>>::mutate(&next_era, stash, |total| {
*total += value.clone();
});

<ErasTotalStake<T>>::mutate(&next_era, |total| {
*total += value.clone();
});
Expand All @@ -1143,10 +1102,6 @@ impl<T: Trait> Module<T> {
(*points).individual.remove(stash);
});

<ErasNominateTotals<T>>::mutate(&era, stash, |total| {
*total = total.saturating_sub(value.clone());
});

<ErasTotalStake<T>>::mutate(&era, |total| {
*total = total.saturating_sub(value.clone());
});
Expand All @@ -1171,12 +1126,12 @@ impl<T: Trait> Module<T> {
if current_era < *era {
return;
}
let mut untreated_era = Self::contracts_untreated_era(&contract);
let mut untreated_era = Self::contract_votes_untreated_era(&contract);
while *era > untreated_era {
Self::propagate_eras_votes(&contract, &untreated_era, &(untreated_era + 1));
untreated_era += 1;
}
<ContractsUntreatedEra<T>>::insert(&contract, untreated_era);
<ContractVotesUntreatedEra<T>>::insert(&contract, untreated_era);
}

// convert Vote into VoteCounts
Expand Down
62 changes: 54 additions & 8 deletions frame/dapps-staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ pub const VALIDATOR_A: u64 = 5;
pub const VALIDATOR_B: u64 = 6;
pub const OPERATOR_A: u64 = 9;
pub const OPERATOR_B: u64 = 10;
pub const OPERATOR_C: u64 = 11;
pub const OPERATED_CONTRACT_A: u64 = 19;
pub const OPERATED_CONTRACT_B: u64 = 20;
pub const OPERATED_CONTRACT_C: u64 = 21;
pub const BOB_CONTRACT: u64 = 12;

impl_outer_origin! {
Expand Down Expand Up @@ -362,19 +364,27 @@ pub const CODE_RETURN_FROM_START_FN: &str = r#"
)
"#;

pub const CODE_RETURN_FROM_START_FN_B: &str = CODE_RETURN_FROM_START_FN;

pub fn valid_instatiate() {
let (wasm, code_hash) = compile_module::<Test>(CODE_RETURN_FROM_START_FN).unwrap();

let (wasm_b, code_hash_b) = compile_module::<Test>(CODE_RETURN_FROM_START_FN_B).unwrap();

// prepare
let _ = Balances::deposit_creating(&OPERATOR_A, 1_000_000);
assert_ok!(Contracts::put_code(Origin::signed(OPERATOR_A), wasm));
assert_ok!(Contracts::put_code(
Origin::signed(OPERATOR_A),
wasm.clone()
));

let _ = Balances::deposit_creating(&OPERATOR_B, 1_000_000);
assert_ok!(Contracts::put_code(Origin::signed(OPERATOR_B), wasm_b));
assert_ok!(Contracts::put_code(
Origin::signed(OPERATOR_B),
wasm.clone()
));

let _ = Balances::deposit_creating(&OPERATOR_C, 1_000_000);
assert_ok!(Contracts::put_code(
Origin::signed(OPERATOR_C),
wasm.clone()
));

let test_params = parameters::StakingParameters {
can_be_nominated: true,
Expand All @@ -396,7 +406,15 @@ pub fn valid_instatiate() {
Origin::signed(OPERATOR_B),
100,
Gas::max_value(),
code_hash_b.into(),
code_hash.into(),
vec![],
test_params.clone(),
);
let _ = Operator::instantiate(
Origin::signed(OPERATOR_C),
100,
Gas::max_value(),
code_hash.into(),
vec![],
test_params.clone(),
);
Expand All @@ -408,6 +426,9 @@ pub fn valid_instatiate() {
assert!(pallet_contracts::ContractInfoOf::<Test>::contains_key(
OPERATED_CONTRACT_B
));
assert!(pallet_contracts::ContractInfoOf::<Test>::contains_key(
OPERATED_CONTRACT_C
));

// checks mapping operator and contract
// OPERATOR_A operates a only OPERATED_CONTRACT_A contract.
Expand All @@ -423,6 +444,13 @@ pub fn valid_instatiate() {
assert_eq!(tree.len(), 1);
assert!(tree.contains(&OPERATED_CONTRACT_B));

// checks mapping operator and contract
// OPERATOR_C operates a only OPERATED_CONTRACT_C contract.
assert!(pallet_contract_operator::OperatorHasContracts::<Test>::contains_key(OPERATOR_C));
let tree = pallet_contract_operator::OperatorHasContracts::<Test>::get(&OPERATOR_C);
assert_eq!(tree.len(), 1);
assert!(tree.contains(&OPERATED_CONTRACT_C));

// OPERATED_CONTRACT_A contract is operated by OPERATOR_A.
assert!(
pallet_contract_operator::ContractHasOperator::<Test>::contains_key(OPERATED_CONTRACT_A)
Expand All @@ -441,6 +469,15 @@ pub fn valid_instatiate() {
Some(OPERATOR_B)
);

// OPERATED_CONTRACT_C contract is operated by OPERATOR_C.
assert!(
pallet_contract_operator::ContractHasOperator::<Test>::contains_key(OPERATED_CONTRACT_C)
);
assert_eq!(
pallet_contract_operator::ContractHasOperator::<Test>::get(&OPERATED_CONTRACT_C),
Some(OPERATOR_C)
);

// OPERATED_CONTRACT's contract Parameters is same test_params.
assert!(
pallet_contract_operator::ContractParameters::<Test>::contains_key(OPERATED_CONTRACT_A)
Expand All @@ -456,7 +493,16 @@ pub fn valid_instatiate() {
);
assert_eq!(
pallet_contract_operator::ContractParameters::<Test>::get(&OPERATED_CONTRACT_B),
Some(test_params)
Some(test_params.clone())
);

// OPERATED_CONTRACT_C's contract Parameters is same test_params.
assert!(
pallet_contract_operator::ContractParameters::<Test>::contains_key(OPERATED_CONTRACT_C)
);
assert_eq!(
pallet_contract_operator::ContractParameters::<Test>::get(&OPERATED_CONTRACT_C),
Some(test_params.clone())
);
}

Expand Down
Loading

0 comments on commit 5d5d606

Please sign in to comment.