-
Notifications
You must be signed in to change notification settings - Fork 986
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
Conversation
0e487a1
to
bab08c8
Compare
bab08c8
to
fd07f6b
Compare
…d checked arithmetic operations to DenominatedAmount to catch mistakes.
95c5f6f
to
f551e29
Compare
…pe is attached. Integration tests now work.
3425622
to
e8cb0c1
Compare
@@ -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( |
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 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
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.
Left a minor comment but looks good from my side!
81d5123
to
a9ff48e
Compare
@@ -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()) |
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.
oh what a world of pain. you modified genesis code haha. let's hope the conflicts with #2186 won't be too gnarly
core/src/types/token.rs
Outdated
self.increase_precision(denom) | ||
.map_err(storage_api::Error::new) | ||
.map(|x| x.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.
self.scale(...)
since you have this method available
/// 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 }) | ||
} |
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 unit tests for this
/// 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, | ||
}) | ||
} |
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 unit tests for this
/// 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, | ||
}) | ||
} |
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 unit tests for this
core/src/types/token.rs
Outdated
} | ||
|
||
impl DenominatedAmount { | ||
/// Make a new denominated 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.
I would rework the docstr here to make it a bit more clear that what we're returning is amount * 10^denom
core/src/types/token.rs
Outdated
} | ||
|
||
impl DenominatedAmount { | ||
/// Make a new denominated amount | ||
pub fn new(amount: Amount, denom: Denomination) -> Self { |
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.
pub fn new(amount: Amount, denom: Denomination) -> Self { | |
pub const fn new(amount: Amount, denom: Denomination) -> Self { |
core/src/types/token.rs
Outdated
/// Returns the significand of this number | ||
pub fn amount(&self) -> Amount { | ||
self.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.
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
core/src/types/token.rs
Outdated
} | ||
|
||
/// Returns the denomination of this number | ||
pub fn denom(&self) -> Denomination { |
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.
pub fn denom(&self) -> Denomination { | |
pub const fn denom(&self) -> Denomination { |
let amount = | ||
token::DenominatedAmount::new(transfer_amount, 0u8.into()).to_string(); |
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 wouldn't bother touching the eth bridge e2e tests, honestly. they're still disabled
a9ff48e
to
8b28d27
Compare
…pdate steward commission, and redelegate.
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:
WrapperTx::amount_per_gas_unit
fromAmount
toDenominatedAmount
to enable the hardware wallet to display amount with correct precision regardless of the token.DenominatedAmount::denom
field before extracting theDenominatedAmount::admount
field so that hardware wallet users cannot be tricked into signing unrelated amounts.DenominatedAmount
to reduce the potential for arithmetic mistakes when manipulating the significand and denomination.Transfer::amount
andTransfer::token
for fully shielded transactions. Also fixed the bug whereTransfer::amount
and its denomination did not correspond toTransfer::token
.The following are known omissions from this PR:
EthereumBridgePool::amount
andEthereumBridgePool::fee_amount
should probably be converted fromAmount
toDenominatedAmount
to allow the hardware wallet to display quantities properly, and the protocol should safely convert them back toAmount
s.Indicate on which release or other PRs this topic is based on
Namada v0.27.0
Checklist before merging to
draft