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
Conversation
Codecov Report
@@ 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
|
7b21437
to
409c1cf
Compare
409c1cf
to
1a46fa5
Compare
|
||
// 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). |
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 is this required? what's wrong with external receipt storage other than it being weird?
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.
Nothing wrong beyond what you said, just not very useful.
let nonce = if store_receipt { | ||
body.receipt // Use receipt identifier as the nonce. | ||
} else { | ||
signer.nonce // Use signer nonce as the nonce. | ||
}; |
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.
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) |
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.
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?
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.
Duplication between delegate and undelegate you mean?
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.
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 { |
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.
let receipt = if context.receipt { | |
let receipt = context.receipt.then_some(context.nonce).unwrap_or_default(); |
|
||
delete(pendingUndelegations[receiptId]); | ||
} | ||
} |
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.
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.
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.
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?
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.
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.
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'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.
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.
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.
There's one thing I need to confirm, to make sure I fully understand. The same
|
Yes, note that this is batched per epoch per address the contract is undelegating from. |
…ostko/feature/consensus-staking-receipts runtime-sdk: Add support for (un)delegation receipts 9e8c6e9
…/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 { |
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 prefer splitting this into multiple structs, as it is hard to know which fields are/can be set by different kinds.
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.
Yeah it is just slightly annoying with the current deserializer if you want to keep a flat struct.
This adds support for (un)delegation receipts so contracts can more easily do delegation accounting.
TODO