-
Notifications
You must be signed in to change notification settings - Fork 0
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
Testing 01 #1
base: polkadot-v0.9.37
Are you sure you want to change the base?
Testing 01 #1
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work!
I've left you some comments, and I'd like to hear your thoughts and opinion about them.
#[pallet::storage] | ||
pub type RewardDelegate<T: Config> = StorageDoubleMap< | ||
_, | ||
Twox64Concat, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you choose Twox64Concat
and not e.g. Blake2_128Concat
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about performance when I choose it. But giving it a second view since the user can kind of
arbitrarily choose the account ID that will be used as index It should be changed to Blake2_128Concat.
T::Currency::resolve_creating(&staker, reward_imbalance); | ||
Self::update_staker_info(&staker, &contract_id, staker_info); | ||
Self::deposit_event(Event::<T>::Reward(staker, contract_id, era, staker_reward)); | ||
if let Some(delegate) = RewardDelegate::<T>::get(&staker, &contract_id) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be solved in a more optimal way, in relationship to weight?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the delegation or not of the rewards are restricted by the restaking being set or not, I think a read to storage could be avoid in those cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that's true.
You also read in the value few lines above, so it would be more optimal to just reuse that.
// reward to the delegate | ||
T::Currency::resolve_creating(&delegate, reward_imbalance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when restaking is used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I changed should_restake_reward function to take into consideration if there is a delegate account, restaking will not be performed unless delegate account is not set, and in that case the reward will go to the staker.
// Ensure the staker does not have reward destination set to StakeBalance | ||
let ledger = Self::ledger(&staker); | ||
ensure!( | ||
ledger.reward_destination != RewardDestination::StakeBalance, | ||
Error::<T>::RewardDestinationStakeBalance | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if reward destination is changed later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will make no difference, because restaking and delegation now depends on delegate account being set or not. I though about creating a new reward destination so to make it more clear, but as it is implemented now, the rewards destinations are associated to the ledger, so are associated to an account. And for the delegation logic something smart contract specific was needed. I still think that is a possibility worth exploring.
) -> bool { | ||
reward_destination == RewardDestination::StakeBalance | ||
&& dapp_state == DAppState::Registered | ||
&& latest_staked_value > Zero::zero() | ||
&& delegate_account.is_none() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems a bit misleading to read from storage that staker has set reward destination to restake, but restake doesn't happen when claiming the reward.
What is your opinion on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, in the case when freebalance reward destination is set, the same happens. I mean, a read from storage is perfomed and no restaking is done. But I agree that the whole restaking logic could be done better, It doesn´t feel right that almost all claim_staker logic depends on "should restake" conditionals. But I would need to give it more time to think about a alternative implementation.
// Check there is a delegate account | ||
let delegate_account = RewardDelegate::<TestRuntime>::get(&claimer, &contract_id); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case this is Some(account)
, would the function still work as expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of Some(account) the rewards will go to freebalance destination. I´m missing a test to make sure this case will not create unexpected behaviour since current test doesn´t account for that.
@@ -575,17 +579,156 @@ pub(crate) fn assert_claim_staker(claimer: AccountId, contract_id: &MockSmartCon | |||
); | |||
} | |||
|
|||
pub(crate) fn assert_claim_staker_with_delegate(claimer: AccountId, delegated_account: AccountId, contract_id: &MockSmartContract<AccountId>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good that you added such function!
Perhaps it would be better to keep it a single asset_claim_staker
though?
Right now you've introduced the second public function for the same thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I should be simplified. I did it this way because I wanted to control the changes so to compare to the previous function. But It should be changed, also to avoid code duplication.
let init_state_claim_era = MemorySnapshot::all(claim_era, contract_id, claimer); | ||
let init_state_current_era = MemorySnapshot::all(current_era, contract_id, claimer); | ||
|
||
let init_state_delegate_claim_era = MemorySnapshot::all(claim_era, contract_id, delegated_account); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would there be benefit of adding delegate to the memory snapshot struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, It would simplify the testing code. So not to make the delegating logic testing different from the other functions.
init_state_claim_era.contract_info, | ||
final_state_claim_era.contract_info | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a lot of duplicated code 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
/// Only staker or current delegate account can delegate reward | ||
NotAuthorizedToDelegate, | ||
/// Reward is already delegated to the account | ||
AlreadyDelegated, | ||
/// Can not set reward delegate if rewards are set to be re staked | ||
RewardDestinationStakeBalance, | ||
/// There is no reward delegate set | ||
NoDelegateSet, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested these out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I should have added a test for each event or error possible.
Task One: Reward Beneficiary Delegation