-
Notifications
You must be signed in to change notification settings - Fork 956
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
Murisi+grarco/multi tx masp vp rebased #3186
Conversation
… sapling bundle anymore
…oves unchecked operation.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3186 +/- ##
==========================================
- Coverage 59.40% 59.32% -0.09%
==========================================
Files 298 298
Lines 92326 92435 +109
==========================================
- Hits 54849 54839 -10
- Misses 37477 37596 +119 ☔ View full report in Codecov by Sentry. |
90d004a
to
67ec3be
Compare
89a2e63
to
0380f7c
Compare
let epoched_asset_type = | ||
encode_asset_type(token.clone(), *denom, *digit, Some(epoch)) | ||
.wrap_err("unable to create asset type")?; | ||
if conversion_state.assets.contains_key(&epoched_asset_type) { |
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.
shouldn't this check also be present in the function below?
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 check is here to prevent an unepoched asset from entering the shielded pool in the case where its underlying token address is participating in the shielded rewards program. But it is possible for an unepoched asset to enter the shielded pool and then later have its underlying token address participate in the shielded pool. In this case we need to allow users to withdraw these assets even though their epoched equivalents are in the conversion state. This was my reasoning for why this check is not repeated in the context of the transparent output. But please let me know if I'm missing something!
0ea6215
to
06f4da1
Compare
fd5e418
to
3938cde
Compare
3938cde
to
29f0c60
Compare
29f0c60
to
7531eed
Compare
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.
mostly code quality related comments
impl From<Uint> for SignedAmount { | ||
fn from(lo: Uint) -> Self { | ||
let mut arr = [0u64; Self::N_WORDS]; | ||
arr[..4].copy_from_slice(&lo.0); | ||
Self(SignedAmountInt(arr)) | ||
} | ||
} | ||
|
||
impl From<Amount> for SignedAmount { | ||
fn from(lo: Amount) -> Self { | ||
let mut arr = [0u64; Self::N_WORDS]; | ||
arr[..4].copy_from_slice(&lo.raw_amount().0); | ||
Self(SignedAmountInt(arr)) | ||
} | ||
} |
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.
add some unit tests to check these conversions hold
impl TryInto<Amount> for SignedAmount { | ||
type Error = std::io::Error; | ||
|
||
fn try_into(self) -> Result<Amount, Self::Error> { | ||
if self.0.0[Self::N_WORDS - 1] == 0 { | ||
Ok(Amount::from_uint( | ||
Uint([self.0.0[0], self.0.0[1], self.0.0[2], self.0.0[3]]), | ||
0, | ||
) | ||
.unwrap()) | ||
} else { | ||
Err(std::io::Error::new( | ||
std::io::ErrorKind::InvalidInput, | ||
"Integer overflow when casting to Amount", | ||
)) | ||
} | ||
} | ||
} |
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.
add a conversion test with failures included
construct_uint! { | ||
#[derive( | ||
BorshSerialize, | ||
BorshDeserialize, | ||
BorshSchema, | ||
)] | ||
|
||
struct SignedAmountInt(5); | ||
} | ||
|
||
/// A positive or negative amount | ||
#[derive( | ||
Copy, | ||
Clone, | ||
Eq, | ||
PartialEq, | ||
BorshSerialize, | ||
BorshDeserialize, | ||
BorshSchema, | ||
Default, | ||
)] | ||
pub struct SignedAmount(SignedAmountInt); |
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.
btw, I think we can replace I256
with this type, renaming it to something like I320
. as it stands, signed arithmetic in core/src/uint.rs
is prone to loss of precision.
I would move this to core
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.
Thanks. I've renamed SignedAmount
to I320
and moved it into the core
file core/src/uint.rs
in #3264. Probably we can replace usage of I256
with I320
in a separate PR.
// Ensure that every account for which balance has gone down has | ||
// authorized this transaction | ||
for (addr, pre) in changed_balances.pre { | ||
if changed_balances.post[&addr] < pre && addr != masp_address_hash { |
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 this check be done only if the balances decrease more than implied by the Transaction
? As in, if we expect a balance to go down by 10 but we see a decrease of 15 we request a signature since this means that something else happened in parallel to the masp tx that we cannot verify in here. Otherwise, if the decrease matches (or is less than) the exepected value of Transaction
we don't require/verify the signature. Could this also apply to validate_transparent_input
?
This (if correct) could lead to less signatures needed on the transaction and less verifications.
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 think you have a point here, though I'll have to think about the details some more. I'll try and sketch this change in a separate PR.
Describe your changes
Tried to increase the readability, strength, and generality of the MASP validity predicate whilst decreasing its verbosity. The changes are as follows:
Transaction
inputs and outputs that exceed pre-balances and post-balances respectively are no longer allowed.AssetType
decoding in one place before starting to check the transparent bundlesTransaction
s and unrelatedTransfer
s touching the same addresses/tokensTransaction
s and the balancing transaction are sufficiently authorized; prevents malleabilityWhat would still need to be handled/fixed if this code turns out to be relevant:
Transaction
to Bertha is embeddable inside aTransfer
to Christel only if Bertha has signed the entire transaction (in addition to the usual MASP checks).Indicate on which release or other PRs this topic is based on
Namada 0.34.0
anoma/masp#79
Checklist before merging to
draft