Skip to content

Commit

Permalink
Merge branch 'tiago/bridge-pool-fees' (#1795)
Browse files Browse the repository at this point in the history
* origin/tiago/bridge-pool-fees:
  Changelog for #1795
  Fix the denomination of Bridge pool gas fees
  Add `DenominatedAmount::is_zero`
  Fix docstring
  Make Bridge pool gas payer CLI arg optional
  Standardize Bridge pool transfer CLI args
  Update CLI args for Bridge pool transfers
  Test paying Bridge pool gas fees in ERC20 tokens
  Arbitrary gas fees in Ethereum events `init_balances`
  Fix bug in `determine_escrow_checks` and document corner cases
  Add misc Bridge pool VP tests
  Fix test_minting_wnam() unit test
  Validate different gas fee tokens in Bridge pool VP
  Check correct gas fee token in Bridge pool transfers
  Fix compilation errors from prev commit
  Add token addr field to Bridge pool gas fees
  Move `check_balance_changes` to Bridge pool VP module
  • Loading branch information
Fraccaman committed Sep 6, 2023
2 parents 51fb52f + 968f1a6 commit e8f96ae
Show file tree
Hide file tree
Showing 15 changed files with 659 additions and 338 deletions.
2 changes: 2 additions & 0 deletions .changelog/unreleased/features/1795-bridge-pool-fees.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Allow Bridge pool transfer fees to be paid in arbitrary token types (except
NUTs) ([\#1795](https://github.com/anoma/namada/pull/1795))
57 changes: 37 additions & 20 deletions apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2484,6 +2484,22 @@ pub mod args {
);
pub const BLOCK_HEIGHT: Arg<BlockHeight> = arg("block-height");
pub const BLOCK_HEIGHT_OPT: ArgOpt<BlockHeight> = arg_opt("height");
pub const BRIDGE_POOL_GAS_AMOUNT: ArgDefault<token::DenominatedAmount> =
arg_default(
"pool-gas-amount",
DefaultFn(|| token::DenominatedAmount {
amount: token::Amount::default(),
denom: NATIVE_MAX_DECIMAL_PLACES.into(),
}),
);
pub const BRIDGE_POOL_GAS_PAYER: ArgOpt<WalletAddress> =
arg_opt("pool-gas-payer");
pub const BRIDGE_POOL_GAS_TOKEN: ArgDefaultFromCtx<WalletAddress> =
arg_default_from_ctx(
"pool-gas-token",
DefaultFn(|| "NAM".parse().unwrap()),
);
pub const BRIDGE_POOL_TARGET: Arg<EthAddress> = arg("target");
pub const BROADCAST_ONLY: ArgFlag = flag("broadcast-only");
pub const CHAIN_ID: Arg<ChainId> = arg("chain-id");
pub const CHAIN_ID_OPT: ArgOpt<ChainId> = CHAIN_ID.opt();
Expand Down Expand Up @@ -2515,7 +2531,7 @@ pub mod args {
pub const ETH_GAS: ArgOpt<u64> = arg_opt("eth-gas");
pub const ETH_GAS_PRICE: ArgOpt<u64> = arg_opt("eth-gas-price");
pub const ETH_ADDRESS: Arg<EthAddress> = arg("ethereum-address");
pub const ETH_ADDRESS_OPT: ArgOpt<EthAddress> = arg_opt("ethereum-address");
pub const ETH_ADDRESS_OPT: ArgOpt<EthAddress> = ETH_ADDRESS.opt();
pub const ETH_RPC_ENDPOINT: ArgDefault<String> = arg_default(
"eth-rpc-endpoint",
DefaultFn(|| "http://localhost:8545".into()),
Expand All @@ -2532,7 +2548,6 @@ pub mod args {
arg_default("gas-limit", DefaultFn(|| GasLimit::from(20_000)));
pub const FEE_TOKEN: ArgDefaultFromCtx<WalletAddress> =
arg_default_from_ctx("gas-token", DefaultFn(|| "NAM".parse().unwrap()));
pub const BRIDGE_GAS_PAYER: Arg<WalletAddress> = arg("bridge-gas-payer");
pub const GENESIS_PATH: Arg<PathBuf> = arg("genesis-path");
pub const GENESIS_VALIDATOR: ArgOpt<String> =
arg("genesis-validator").opt();
Expand Down Expand Up @@ -2846,7 +2861,8 @@ pub mod args {
sender: ctx.get(&self.sender),
amount: self.amount,
fee_amount: self.fee_amount,
fee_payer: ctx.get(&self.fee_payer),
fee_payer: self.fee_payer.map(|fee_payer| ctx.get(&fee_payer)),
fee_token: ctx.get(&self.fee_token),
code_path: self.code_path,
}
}
Expand All @@ -2856,15 +2872,13 @@ pub mod args {
fn parse(matches: &ArgMatches) -> Self {
let tx = Tx::parse(matches);
let asset = ERC20.parse(matches);
let recipient = ETH_ADDRESS.parse(matches);
let sender = ADDRESS.parse(matches);
let recipient = BRIDGE_POOL_TARGET.parse(matches);
let sender = SOURCE.parse(matches);
let amount = InputAmount::Unvalidated(AMOUNT.parse(matches));
let fee_amount = FEE_AMOUNT_OPT
.parse(matches)
.map_or_else(token::Amount::default, |denom_amount| {
denom_amount.amount
});
let fee_payer = BRIDGE_GAS_PAYER.parse(matches);
let fee_amount =
InputAmount::Unvalidated(BRIDGE_POOL_GAS_AMOUNT.parse(matches));
let fee_payer = BRIDGE_POOL_GAS_PAYER.parse(matches);
let fee_token = BRIDGE_POOL_GAS_TOKEN.parse(matches);
let code_path = PathBuf::from(TX_BRIDGE_POOL_WASM);
let nut = NUT.parse(matches);
Self {
Expand All @@ -2875,6 +2889,7 @@ pub mod args {
amount,
fee_amount,
fee_payer,
fee_token,
code_path,
nut,
}
Expand All @@ -2888,27 +2903,29 @@ pub mod args {
.help("The Ethereum address of the ERC20 token."),
)
.arg(
ETH_ADDRESS
BRIDGE_POOL_TARGET
.def()
.help("The Ethereum address receiving the tokens."),
)
.arg(
ADDRESS
.def()
.help("The Namada address sending the tokens."),
SOURCE.def().help("The Namada address sending the tokens."),
)
.arg(
AMOUNT.def().help(
"The amount of tokens being sent across the bridge.",
),
)
.arg(FEE_AMOUNT_OPT.def().help(
"The amount of NAM you wish to pay to have this transfer \
.arg(BRIDGE_POOL_GAS_AMOUNT.def().help(
"The amount of gas you wish to pay to have this transfer \
relayed to Ethereum.",
))
.arg(BRIDGE_GAS_PAYER.def().help(
"The Namada address of the account paying the fee for the \
Ethereum transaction.",
.arg(BRIDGE_POOL_GAS_PAYER.def().help(
"The Namada address of the account paying the gas. By \
default, it is the same as the source.",
))
.arg(BRIDGE_POOL_GAS_TOKEN.def().help(
"The token for paying the Bridge pool gas fees. Defaults \
to NAM.",
))
.arg(NUT.def().help(
"Add Non Usable Tokens (NUTs) to the Bridge pool. These \
Expand Down
3 changes: 2 additions & 1 deletion apps/src/lib/node/ledger/shell/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1745,6 +1745,7 @@ mod test_finalize_block {
///
/// Sets the validity of the transfer on Ethereum's side.
fn test_bp_nonce_is_incremented_aux(valid_transfer: bool) {
use crate::node::ledger::shell::address::nam;
test_bp(|shell: &mut TestShell| {
let asset = EthAddress([0xff; 20]);
let receiver = EthAddress([0xaa; 20]);
Expand All @@ -1769,7 +1770,6 @@ mod test_finalize_block {
}
// add bertha's gas fees the pool
{
use crate::node::ledger::shell::address::nam;
let amt: Amount = 999_999_u64.into();
let pool_balance_key = token::balance_key(
&nam(),
Expand All @@ -1795,6 +1795,7 @@ mod test_finalize_block {
sender: bertha.clone(),
},
gas_fee: GasFee {
token: nam(),
amount: 10u64.into(),
payer: bertha.clone(),
},
Expand Down
18 changes: 18 additions & 0 deletions core/src/ledger/eth_bridge/storage/bridge_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ mod test_bridge_pool_tree {
use proptest::prelude::*;

use super::*;
use crate::types::address::nam;
use crate::types::eth_bridge_pool::{
GasFee, TransferToEthereum, TransferToEthereumKind,
};
Expand All @@ -441,6 +442,7 @@ mod test_bridge_pool_tree {
amount: 1.into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -468,6 +470,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -496,6 +499,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -534,6 +538,7 @@ mod test_bridge_pool_tree {
amount: 1.into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -562,6 +567,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -593,6 +599,7 @@ mod test_bridge_pool_tree {
amount: 1u64.into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand All @@ -617,6 +624,7 @@ mod test_bridge_pool_tree {
amount: 1u64.into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -653,6 +661,7 @@ mod test_bridge_pool_tree {
amount: 1.into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand All @@ -672,6 +681,7 @@ mod test_bridge_pool_tree {
amount: 1u64.into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -704,6 +714,7 @@ mod test_bridge_pool_tree {
amount: 0.into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -733,6 +744,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -763,6 +775,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -793,6 +806,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -821,6 +835,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -849,6 +864,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -877,6 +893,7 @@ mod test_bridge_pool_tree {
amount: (i as u64).into(),
},
gas_fee: GasFee {
token: nam(),
amount: 0.into(),
payer: bertha_address(),
},
Expand Down Expand Up @@ -909,6 +926,7 @@ mod test_bridge_pool_tree {
amount: Default::default(),
},
gas_fee: GasFee {
token: nam(),
amount: Default::default(),
payer: bertha_address(),
},
Expand Down
23 changes: 14 additions & 9 deletions core/src/types/eth_bridge_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ pub struct PendingTransferAppendix<'transfer> {
pub kind: Cow<'transfer, TransferToEthereumKind>,
/// The sender of the transfer.
pub sender: Cow<'transfer, Address>,
/// The amount of gas fees (in NAM)
/// paid by the user sending this transfer
/// The amount of gas fees paid by the user
/// sending this transfer.
pub gas_fee: Cow<'transfer, GasFee>,
}

Expand Down Expand Up @@ -158,10 +158,10 @@ pub struct TransferToEthereum {
BorshSchema,
)]
pub struct PendingTransfer {
/// The message to send to Ethereum to
/// Transfer to Ethereum data.
pub transfer: TransferToEthereum,
/// The amount of gas fees (in NAM)
/// paid by the user sending this transfer
/// Amount of gas fees paid by the user
/// sending the transfer.
pub gas_fee: GasFee,
}

Expand Down Expand Up @@ -267,9 +267,9 @@ impl From<&PendingTransfer> for Key {
}
}

/// The amount of NAM to be payed to the relayer of
/// a transfer across the Ethereum Bridge to compensate
/// for Ethereum gas fees.
/// The amount of fees to be payed, in Namada, to the relayer
/// of a transfer across the Ethereum Bridge, compensating
/// for Ethereum gas costs.
#[derive(
Debug,
Clone,
Expand All @@ -285,15 +285,19 @@ impl From<&PendingTransfer> for Key {
BorshSchema,
)]
pub struct GasFee {
/// The amount of fees (in NAM)
/// The amount of fees.
pub amount: Amount,
/// The account of fee payer.
pub payer: Address,
/// The address of the fungible token to draw
/// gas fees from.
pub token: Address,
}

#[cfg(test)]
mod test_eth_bridge_pool_types {
use super::*;
use crate::types::address::nam;
use crate::types::address::testing::established_address_1;

/// Test that [`PendingTransfer`] and [`TransferToEthereum`]
Expand All @@ -309,6 +313,7 @@ mod test_eth_bridge_pool_types {
sender: established_address_1(),
},
gas_fee: GasFee {
token: nam(),
amount: 10u64.into(),
payer: established_address_1(),
},
Expand Down
6 changes: 6 additions & 0 deletions core/src/types/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,12 @@ impl DenominatedAmount {
}
}

/// Check if the inner [`Amount`] is zero.
#[inline]
pub fn is_zero(&self) -> bool {
self.amount.is_zero()
}

/// A precise string representation. The number of
/// decimal places in this string gives the denomination.
/// This not true of the string produced by the `Display`
Expand Down
Loading

0 comments on commit e8f96ae

Please sign in to comment.