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

runtime-sdk: Add support for (un)delegation receipts #1510

Merged
merged 2 commits into from Sep 26, 2023

Conversation

kostko
Copy link
Member

@kostko kostko commented Sep 23, 2023

This adds support for (un)delegation receipts so contracts can more easily do delegation accounting.

TODO

  • More tests.

@codecov
Copy link

codecov bot commented Sep 23, 2023

Codecov Report

Merging #1510 (1a46fa5) into main (c35d047) will decrease coverage by 0.06%.
The diff coverage is 57.39%.

@@            Coverage Diff             @@
##             main    #1510      +/-   ##
==========================================
- Coverage   60.39%   60.34%   -0.06%     
==========================================
  Files         138      138              
  Lines        9734     9840     +106     
==========================================
+ Hits         5879     5938      +59     
- Misses       3813     3860      +47     
  Partials       42       42              
Files Changed Coverage Δ
runtime-sdk-macros/src/module_derive/mod.rs 100.00% <ø> (ø)
...untime-sdk/src/modules/consensus_accounts/types.rs 60.00% <0.00%> (-40.00%) ⬇️
runtime-sdk/src/modules/consensus_accounts/mod.rs 56.04% <35.61%> (-5.37%) ⬇️
...ime-sdk-macros/src/module_derive/method_handler.rs 92.80% <100.00%> (+0.87%) ⬆️
runtime-sdk/src/modules/consensus/mod.rs 85.71% <100.00%> (+0.25%) ⬆️
...untime-sdk/src/modules/consensus_accounts/state.rs 97.76% <100.00%> (+0.41%) ⬆️

@kostko kostko force-pushed the kostko/feature/consensus-staking-receipts branch from 7b21437 to 409c1cf Compare September 25, 2023 09:38
@kostko kostko force-pushed the kostko/feature/consensus-staking-receipts branch from 409c1cf to 1a46fa5 Compare September 25, 2023 09:39
@kostko kostko marked this pull request as ready for review September 25, 2023 09:39

// Check whether delegate is allowed.
if params.disable_delegate {
return Err(Error::Forbidden);
}
// Make sure receipts can only be requested internally (e.g. via subcalls).
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this required? what's wrong with external receipt storage other than it being weird?

Copy link
Member Author

@kostko kostko Sep 25, 2023

Choose a reason for hiding this comment

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

Nothing wrong beyond what you said, just not very useful.

Comment on lines +481 to +485
let nonce = if store_receipt {
body.receipt // Use receipt identifier as the nonce.
} else {
signer.nonce // Use signer nonce as the nonce.
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let nonce = if store_receipt {
body.receipt // Use receipt identifier as the nonce.
} else {
signer.nonce // Use signer nonce as the nonce.
};
let nonce = store_receipt.then_some(body.receipt).unwrap_or(signer.nonce);

FYI

} else {
signer.nonce // Use signer nonce as the nonce.
};
Self::undelegate(ctx, body.from, nonce, to, body.shares, store_receipt)
Copy link
Contributor

Choose a reason for hiding this comment

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

this is a fair amount of duplicated code. can you split out the common stuff into a function that takes the other functions as input and then does the verification and nonce setup?

Copy link
Member Author

Choose a reason for hiding this comment

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

Duplication between delegate and undelegate you mean?

Copy link
Contributor

@nhynes nhynes left a comment

Choose a reason for hiding this comment

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

looks normal to me

@@ -679,14 +772,35 @@ impl<Accounts: modules::accounts::API, Consensus: modules::consensus::API>
let result: ReclaimEscrowResult = cbor::from_value(result).unwrap();
let debonding_shares = result.debonding_shares.try_into().unwrap();

state::add_undelegation(
let receipt = if context.receipt {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let receipt = if context.receipt {
let receipt = context.receipt.then_some(context.nonce).unwrap_or_default();


delete(pendingUndelegations[receiptId]);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

strictly speaking, for just testing, I would have passed the cbor directly into the contract and have it proxy the subcall instead. would have been a bit clearer what's going on, too.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah thought about that, I just wanted to write some Solidity to see if the API was viable. Any thoughts about the API, does it make sense?

Copy link
Member

Choose a reason for hiding this comment

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

Could use an existing solidity cbor lib? That would make it clearer to show how it would look like in practice. Unless there's too much work incorporating that into the existing unit tests.

Copy link
Member

Choose a reason for hiding this comment

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

I'm in the process of re-working the CBOR stuff (it was an easy fix to support 64bit ints, but need to do better parsing).

I'm happy with the unit test as a starting point and will be submitting a PR for sapphire-paratime repo when the updated sapphire-dev image is available.

Copy link
Member Author

Choose a reason for hiding this comment

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

Could use an existing solidity cbor lib? That would make it clearer to show how it would look like in practice. Unless there's too much work incorporating that into the existing unit tests.

Not easily for these E2E tests, we would need to adapt the pipeline a bit.

@CedarMist
Copy link
Member

CedarMist commented Sep 25, 2023

There's one thing I need to confirm, to make sure I fully understand.

The same receiptId will be used twice for the UndelegateStart & UndelegateDone receipts.

add_undelegation batches them together on a per-epoch basis, so if I call undelegate twice in a row with two sequential receipt IDs, fetching the two undelegateStart tickets will return the same endReceiptId - which will be the receiptId of the first undelegate call.

@kostko
Copy link
Member Author

kostko commented Sep 26, 2023

Yes, note that this is batched per epoch per address the contract is undelegating from.

@kostko kostko merged commit 9e8c6e9 into main Sep 26, 2023
25 of 27 checks passed
@kostko kostko deleted the kostko/feature/consensus-staking-receipts branch September 26, 2023 09:49
github-actions bot added a commit that referenced this pull request Sep 26, 2023
…ostko/feature/consensus-staking-receipts

runtime-sdk: Add support for (un)delegation receipts 9e8c6e9
github-actions bot added a commit that referenced this pull request Sep 26, 2023
…/kostko/feature/consensus-staking-receipts

runtime-sdk: Add support for (un)delegation receipts 9e8c6e9
/// A receipt.
#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct Receipt {
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer splitting this into multiple structs, as it is hard to know which fields are/can be set by different kinds.

Copy link
Member Author

@kostko kostko Sep 26, 2023

Choose a reason for hiding this comment

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

Yeah it is just slightly annoying with the current deserializer if you want to keep a flat struct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants