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

Now denominate the fee amount in wrapper headers. #2245

Merged
merged 9 commits into from
Dec 29, 2023

Conversation

murisi
Copy link
Collaborator

@murisi murisi commented Dec 4, 2023

Describe your changes

Made changes necessary to enable hardware wallets to first correctly display amounts in different tokens and second sign over them. Specifically, the following changes were made:

  • Converted WrapperTx::amount_per_gas_unit from Amount to DenominatedAmount to enable the hardware wallet to display amount with correct precision regardless of the token.
  • Modified the protocol to always align the DenominatedAmount::denom field before extracting the DenominatedAmount::admount field so that hardware wallet users cannot be tricked into signing unrelated amounts.
  • Added checked high level operations (like add, subtract, and multiply) to DenominatedAmount to reduce the potential for arithmetic mistakes when manipulating the significand and denomination.
  • Fixed the redacting of Transfer::amount and Transfer::token for fully shielded transactions. Also fixed the bug where Transfer::amount and its denomination did not correspond to Transfer::token.

The following are known omissions from this PR:

  • Ethereum bridge pool transactions: EthereumBridgePool::amount and EthereumBridgePool::fee_amount should probably be converted from Amount to DenominatedAmount to allow the hardware wallet to display quantities properly, and the protocol should safely convert them back to Amounts.

Indicate on which release or other PRs this topic is based on

Namada v0.27.0

Checklist before merging to draft

  • I have added a changelog
  • Git history is in acceptable state

@murisi murisi force-pushed the murisi/denominated-fee-amount branch from 0e487a1 to bab08c8 Compare December 4, 2023 15:38
@murisi murisi force-pushed the murisi/denominated-fee-amount branch from bab08c8 to fd07f6b Compare December 4, 2023 15:55
@murisi murisi force-pushed the murisi/denominated-fee-amount branch from 95c5f6f to f551e29 Compare December 5, 2023 17:03
@murisi murisi force-pushed the murisi/denominated-fee-amount branch from 3425622 to e8cb0c1 Compare December 6, 2023 07:10
@murisi murisi marked this pull request as ready for review December 6, 2023 08:07
@murisi murisi requested review from grarco, batconjurer and sug0 December 6, 2023 08:25
@@ -544,15 +544,15 @@ pub async fn wrap_tx<'a, N: Namada<'a>>(
let target = namada_core::types::masp::TransferTarget::Address(
fee_payer_address.clone(),
);
let fee_amount = DenominatedAmount {
let fee_amount = DenominatedAmount::new(
Copy link
Collaborator

Choose a reason for hiding this comment

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

This variable is only used to feed the next call to gen_shielded_transfer. This second function though, takes a DenominatedAmount but only ever uses the amount field of it. I was wondering if we could maybe change the signature of gen_shielded_transfer to take an Amount instead

grarco
grarco previously approved these changes Dec 6, 2023
Copy link
Collaborator

@grarco grarco left a comment

Choose a reason for hiding this comment

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

Left a minor comment but looks good from my side!

batconjurer
batconjurer previously approved these changes Dec 7, 2023
@@ -491,7 +491,7 @@ pub struct EthBridgeParams {
impl TokenBalances {
pub fn get(&self, pk: common::PublicKey) -> Option<token::Amount> {
let pk = StringEncoded { raw: pk };
self.0.get(&pk).map(|amt| amt.amount)
self.0.get(&pk).map(|amt| amt.amount())
Copy link
Collaborator

Choose a reason for hiding this comment

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

oh what a world of pain. you modified genesis code haha. let's hope the conflicts with #2186 won't be too gnarly

Comment on lines 421 to 423
self.increase_precision(denom)
.map_err(storage_api::Error::new)
.map(|x| x.amount)
Copy link
Collaborator

Choose a reason for hiding this comment

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

self.scale(...) since you have this method available

Comment on lines +436 to +441
/// Checked multiplication. Returns `None` on overflow.
pub fn checked_mul(&self, rhs: DenominatedAmount) -> Option<Self> {
let amount = self.amount.checked_mul(rhs.amount)?;
let denom = self.denom.0.checked_add(rhs.denom.0)?.into();
Some(Self { amount, denom })
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

add unit tests for this

Comment on lines +443 to +456
/// Checked subtraction. Returns `None` on overflow.
pub fn checked_sub(&self, mut rhs: DenominatedAmount) -> Option<Self> {
let mut lhs = *self;
if lhs.denom < rhs.denom {
lhs = lhs.increase_precision(rhs.denom).ok()?;
} else {
rhs = rhs.increase_precision(lhs.denom).ok()?;
}
let amount = lhs.amount.checked_sub(rhs.amount)?;
Some(Self {
amount,
denom: lhs.denom,
})
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

add unit tests for this

Comment on lines +458 to +471
/// Checked addition. Returns `None` on overflow.
pub fn checked_add(&self, mut rhs: DenominatedAmount) -> Option<Self> {
let mut lhs = *self;
if lhs.denom < rhs.denom {
lhs = lhs.increase_precision(rhs.denom).ok()?;
} else {
rhs = rhs.increase_precision(lhs.denom).ok()?;
}
let amount = lhs.amount.checked_add(rhs.amount)?;
Some(Self {
amount,
denom: lhs.denom,
})
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

add unit tests for this

}

impl DenominatedAmount {
/// Make a new denominated amount
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would rework the docstr here to make it a bit more clear that what we're returning is amount * 10^denom

}

impl DenominatedAmount {
/// Make a new denominated amount
pub fn new(amount: Amount, denom: Denomination) -> Self {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
pub fn new(amount: Amount, denom: Denomination) -> Self {
pub const fn new(amount: Amount, denom: Denomination) -> Self {

Comment on lines 473 to 476
/// Returns the significand of this number
pub fn amount(&self) -> Amount {
self.amount
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

this method might be a bit confusing, since it doesn't specify that the returned amount is not multiplied by the denomination. maybe mention this in the docstr.

also, I think this can become a const fn

}

/// Returns the denomination of this number
pub fn denom(&self) -> Denomination {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
pub fn denom(&self) -> Denomination {
pub const fn denom(&self) -> Denomination {

Comment on lines +140 to +141
let amount =
token::DenominatedAmount::new(transfer_amount, 0u8.into()).to_string();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wouldn't bother touching the eth bridge e2e tests, honestly. they're still disabled

@murisi murisi force-pushed the murisi/denominated-fee-amount branch from a9ff48e to 8b28d27 Compare December 7, 2023 13:55
@anoma anoma deleted a comment from leotese Dec 8, 2023
@brentstone brentstone merged commit a723d00 into main Dec 29, 2023
12 of 14 checks passed
@brentstone brentstone deleted the murisi/denominated-fee-amount branch December 29, 2023 19:37
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.

5 participants