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

Test gas payment with IBC token (backport #3866) #3881

Merged
merged 7 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changelog/unreleased/testing/3866-test-ibc-gas-payment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added test for gas payment with an IBC token.
([\#3866](https://github.com/anoma/namada/pull/3866))
1 change: 1 addition & 0 deletions .github/workflows/scripts/e2e.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"e2e::eth_bridge_tests::everything": 4,
"e2e::ibc_tests::ibc_transfers": 414,
"e2e::ibc_tests::pgf_over_ibc": 415,
"e2e::ibc_tests::fee_payment_with_ibc_token": 357,
"e2e::ibc_tests::ibc_token_inflation": 840,
"e2e::ibc_tests::ibc_rate_limit": 485,
"e2e::ibc_tests::ibc_upgrade_client": 280,
Expand Down
2 changes: 1 addition & 1 deletion crates/apps_lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@ pub mod cmds {
fn def() -> App {
App::new(Self::CMD)
.about(wrap!(
"Query the substorage space of a specific enstablished \
"Query the substorage space of a specific established \
address."
))
.add_args::<args::QueryAccount<args::CliTypes>>()
Expand Down
2 changes: 1 addition & 1 deletion crates/sdk/src/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2265,7 +2265,7 @@ pub async fn build_become_validator(
);
if !tx_args.force {
return Err(Error::Other(
"The given address must be enstablished".to_string(),
"The given address must be established".to_string(),
));
}
};
Expand Down
2 changes: 2 additions & 0 deletions crates/test_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub enum TestWasms {
TxProposalCode,
TxProposalMaspRewards,
TxProposalIbcTokenInflation,
TxProposalTokenGas,
TxReadStorageKey,
TxWriteStorageKey,
VpAlwaysFalse,
Expand Down Expand Up @@ -58,6 +59,7 @@ impl TestWasms {
TestWasms::TxProposalIbcTokenInflation => {
"tx_proposal_ibc_token_inflation.wasm"
}
TestWasms::TxProposalTokenGas => "tx_proposal_token_gas.wasm",
TestWasms::TxReadStorageKey => "tx_read_storage_key.wasm",
TestWasms::TxWriteStorageKey => "tx_write.wasm",
TestWasms::VpAlwaysFalse => "vp_always_false.wasm",
Expand Down
189 changes: 162 additions & 27 deletions crates/tests/src/e2e/ibc_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ use setup::constants::*;
use sha2::{Digest, Sha256};

use crate::e2e::helpers::{
epochs_per_year_from_min_duration, find_address, find_gaia_address,
get_actor_rpc, get_epoch, get_gaia_gov_address,
epoch_sleep, epochs_per_year_from_min_duration, find_address,
find_gaia_address, get_actor_rpc, get_epoch, get_gaia_gov_address,
};
use crate::e2e::ledger_tests::{
start_namada_ledger_node_wait_wasm, write_json_file,
Expand Down Expand Up @@ -234,6 +234,7 @@ fn ibc_transfers() -> Result<()> {
&ibc_denom_on_namada,
50,
ALBERT_KEY,
&[],
)?;
check_balance(&test, AA_VIEWING_KEY, &ibc_denom_on_namada, 50)?;
check_balance(&test, AB_VIEWING_KEY, &ibc_denom_on_namada, 50)?;
Expand Down Expand Up @@ -479,6 +480,7 @@ fn pgf_over_ibc() -> Result<()> {
NAM,
100,
ALBERT_KEY,
&[],
)?;

// Proposal on Namada
Expand All @@ -488,8 +490,7 @@ fn pgf_over_ibc() -> Result<()> {
let mut epoch = get_epoch(&test, &rpc).unwrap();
let delegated = epoch + PIPELINE_LEN;
while epoch < delegated {
sleep(5);
epoch = get_epoch(&test, &rpc).unwrap();
epoch = epoch_sleep(&test, &rpc, 120)?;
}
// funding proposal
let continuous_receiver = find_gaia_address(&test_gaia, GAIA_RELAYER)?;
Expand All @@ -504,16 +505,14 @@ fn pgf_over_ibc() -> Result<()> {
let mut epoch = get_epoch(&test, &rpc).unwrap();
// Vote
while epoch < start_epoch {
sleep(5);
epoch = get_epoch(&test, &rpc).unwrap();
epoch = epoch_sleep(&test, &rpc, 120)?;
}
submit_votes(&test)?;

// wait for the grace
let grace_epoch = start_epoch + 6u64;
while epoch < grace_epoch {
sleep(5);
epoch = get_epoch(&test, &rpc).unwrap();
epoch = epoch_sleep(&test, &rpc, 120)?;
}
wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?;

Expand All @@ -526,6 +525,108 @@ fn pgf_over_ibc() -> Result<()> {
Ok(())
}

// Test fee payment with an ibc token
//
// 1. Submit governance proposal to allow fee payment with the IBC token
// 2. Transfer some IBC tokens from gaia
// 3. Transparent transfer in Namada with ibc token gas payment
#[test]
fn fee_payment_with_ibc_token() -> Result<()> {
const PIPELINE_LEN: u64 = 2;
let update_genesis =
|mut genesis: templates::All<templates::Unvalidated>, base_dir: &_| {
genesis.parameters.parameters.epochs_per_year =
epochs_per_year_from_min_duration(30);
genesis.parameters.ibc_params.default_mint_limit =
Amount::max_signed();
genesis.parameters.gov_params.min_proposal_grace_epochs = 1;
genesis
.parameters
.ibc_params
.default_per_epoch_throughput_limit = Amount::max_signed();
// Artificially increase the gas scale to allow for fee payment with
// the limited ibc tokens available
genesis.parameters.parameters.gas_scale = 10_000_000;
setup::set_validators(1, genesis, base_dir, |_| 0, vec![])
};
let (ledger, gaia, test, test_gaia) = run_namada_gaia(update_genesis)?;
let _bg_ledger = ledger.background();
let _bg_gaia = gaia.background();

// Proposal on Namada
// Delegate some token
delegate_token(&test)?;
let rpc = get_actor_rpc(&test, Who::Validator(0));
let mut epoch = get_epoch(&test, &rpc).unwrap();
let delegated = epoch + PIPELINE_LEN;
while epoch < delegated {
epoch = epoch_sleep(&test, &rpc, 120)?;
}
// ibc gas token proposal on Namada
let start_epoch = propose_gas_token(&test)?;
let mut epoch = get_epoch(&test, &rpc).unwrap();
// Vote
while epoch < start_epoch {
epoch = epoch_sleep(&test, &rpc, 120)?;
}
submit_votes(&test)?;

// Create an IBC channel while waiting the grace epoch
setup_hermes(&test, &test_gaia)?;
let (channel_id_namada, channel_id_gaia) =
create_channel_with_hermes(&test, &test_gaia)?;
let port_id_gaia = "transfer".parse().unwrap();
let port_id_namada = "transfer";
let ibc_token_on_namada =
format!("{port_id_namada}/{channel_id_namada}/{GAIA_COIN}");
// Start relaying
let hermes = run_hermes(&test)?;
let _bg_hermes = hermes.background();

// wait for the grace
let grace_epoch = start_epoch + 4u64;
while epoch < grace_epoch {
epoch = epoch_sleep(&test, &rpc, 120)?;
}

// Transfer 250 samoleans from Gaia to Namada
let namada_receiver = find_address(&test, ALBERT_KEY)?.to_string();
transfer_from_gaia(
&test_gaia,
GAIA_USER,
&namada_receiver,
GAIA_COIN,
250,
&port_id_gaia,
&channel_id_gaia,
None,
None,
)?;
wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test)?;

// Check the token on Namada
check_balance(&test, ALBERT_KEY, &ibc_token_on_namada, 250)?;
check_gaia_balance(&test_gaia, GAIA_USER, GAIA_COIN, 750)?;

// Transparent transfer in Namada paying gas with samoleans
transfer_on_chain(
&test,
"transparent-transfer",
ALBERT,
CHRISTEL,
NAM,
50,
ALBERT_KEY,
&["--gas-token", &ibc_token_on_namada, "--gas-limit", "250"],
)?;
check_balance(&test, ALBERT, NAM, 1_999_950)?;
check_balance(&test, CHRISTEL, NAM, 2_000_050)?;
check_balance(&test, ALBERT_KEY, &ibc_token_on_namada, 0)?;
check_balance(&test, "validator-0", &ibc_token_on_namada, 250)?;

Ok(())
}

/// IBC token inflation test
/// - Propose the inflation of an IBC token received from Gaia
/// - Shielding transfer of the token from Gaia
Expand Down Expand Up @@ -560,20 +661,14 @@ fn ibc_token_inflation() -> Result<()> {
let mut epoch = get_epoch(&test, &rpc).unwrap();
let delegated = epoch + PIPELINE_LEN;
while epoch < delegated {
sleep(10);
#[allow(clippy::disallowed_methods)]
let new_epoch = get_epoch(&test, &rpc).unwrap_or_default();
epoch = new_epoch;
epoch = epoch_sleep(&test, &rpc, 120)?;
}
// inflation proposal on Namada
let start_epoch = propose_inflation(&test)?;
let mut epoch = get_epoch(&test, &rpc).unwrap();
// Vote
while epoch < start_epoch {
sleep(10);
#[allow(clippy::disallowed_methods)]
let new_epoch = get_epoch(&test, &rpc).unwrap_or_default();
epoch = new_epoch;
epoch = epoch_sleep(&test, &rpc, 120)?;
}
submit_votes(&test)?;

Expand All @@ -590,8 +685,7 @@ fn ibc_token_inflation() -> Result<()> {
// wait for the grace
let grace_epoch = start_epoch + 6u64;
while epoch < grace_epoch {
sleep(5);
epoch = get_epoch(&test, &rpc).unwrap();
epoch = epoch_sleep(&test, &rpc, 120)?;
}

// Check the target balance is zero before the inflation
Expand Down Expand Up @@ -622,10 +716,7 @@ fn ibc_token_inflation() -> Result<()> {
let mut epoch = get_epoch(&test, &rpc).unwrap();
let new_epoch = epoch + MASP_EPOCH_MULTIPLIER;
while epoch < new_epoch {
sleep(10);
#[allow(clippy::disallowed_methods)]
let new_epoch = get_epoch(&test, &rpc).unwrap_or_default();
epoch = new_epoch;
epoch = epoch_sleep(&test, &rpc, 120)?;
}

// Check balances
Expand Down Expand Up @@ -726,8 +817,7 @@ fn ibc_rate_limit() -> Result<()> {
let mut epoch = get_epoch(&test, &rpc).unwrap();
let next_epoch = epoch.next();
while epoch <= next_epoch {
sleep(5);
epoch = get_epoch(&test, &rpc).unwrap();
epoch = epoch_sleep(&test, &rpc, 120)?;
}

// Transfer 1 NAM from Namada to Gaia
Expand Down Expand Up @@ -770,8 +860,7 @@ fn ibc_rate_limit() -> Result<()> {
let mut epoch = get_epoch(&test, &rpc).unwrap();
let next_epoch = epoch.next();
while epoch <= next_epoch {
sleep(5);
epoch = get_epoch(&test, &rpc).unwrap();
epoch = epoch_sleep(&test, &rpc, 120)?;
}

// Transfer 1 NAM from Namada to Gaia will succeed in the new epoch
Expand Down Expand Up @@ -1052,10 +1141,11 @@ fn transfer_on_chain(
token: impl AsRef<str>,
amount: u64,
signer: impl AsRef<str>,
extra_args: &[&str],
) -> Result<()> {
let rpc = get_actor_rpc(test, Who::Validator(0));
let amount = amount.to_string();
let tx_args = apply_use_device(vec![
let mut tx_args = apply_use_device(vec![
kind.as_ref(),
"--source",
sender.as_ref(),
Expand All @@ -1070,6 +1160,7 @@ fn transfer_on_chain(
"--node",
&rpc,
]);
tx_args.extend_from_slice(extra_args);
let mut client = run!(test, Bin::Client, tx_args, Some(120))?;
client.exp_string(TX_APPLIED_SUCCESS)?;
client.assert_success();
Expand Down Expand Up @@ -1367,6 +1458,50 @@ fn propose_upgrade_client(
Ok(())
}

fn propose_gas_token(test: &Test) -> Result<Epoch> {
let albert = find_address(test, ALBERT)?;
let rpc = get_actor_rpc(test, Who::Validator(0));
let epoch = get_epoch(test, &rpc)?;
let start_epoch = (epoch.0 + 3) / 3 * 3;
let proposal_json = serde_json::json!({
"proposal": {
"content": {
"title": "IBC token gas",
"authors": "[email protected]",
"discussions-to": "www.github.com/anoma/aip/1",
"created": "2022-03-10T08:54:37Z",
"license": "MIT",
"abstract": "IBC token gas",
"motivation": "IBC token gas",
"details": "IBC token gas",
"requires": "2"
},
"author": albert,
"voting_start_epoch": start_epoch,
"voting_end_epoch": start_epoch + 3_u64,
"activation_epoch": start_epoch + 4_u64,
},
"data": TestWasms::TxProposalTokenGas.read_bytes()
});

let proposal_json_path = test.test_dir.path().join("proposal.json");
write_json_file(proposal_json_path.as_path(), proposal_json);

let submit_proposal_args = apply_use_device(vec![
"init-proposal",
"--data-path",
proposal_json_path.to_str().unwrap(),
"--gas-limit",
"10000000",
"--node",
&rpc,
]);
let mut client = run!(test, Bin::Client, submit_proposal_args, Some(100))?;
client.exp_string(TX_APPLIED_SUCCESS)?;
client.assert_success();
Ok(start_epoch.into())
}

fn wait_for_pass(test: &Test) -> Result<()> {
let args = ["query", "gov", "proposal", "1"];
for _ in 0..10 {
Expand Down
4 changes: 2 additions & 2 deletions crates/tx/src/data/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ impl WrapperTx {
hasher
}

/// Get the [`Amount`] of fees to be paid by the given wrapper. Returns
/// an error if the amount overflows
/// Get the [`DenominatedAmount`] of fees to be paid by the given wrapper.
/// Returns an error if the amount overflows
pub fn get_tx_fee(&self) -> Result<DenominatedAmount, WrapperTxErr> {
self.fee
.amount_per_gas_unit
Expand Down
9 changes: 9 additions & 0 deletions wasm_for_tests/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions wasm_for_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
"tx_proposal_code",
"tx_proposal_ibc_token_inflation",
"tx_proposal_masp_reward",
"tx_proposal_token_gas",
"tx_read_storage_key",
"tx_write",
"vp_always_false",
Expand Down
1 change: 1 addition & 0 deletions wasm_for_tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ wasms += tx_no_op_event
wasms += tx_proposal_code
wasms += tx_proposal_ibc_token_inflation
wasms += tx_proposal_masp_reward
wasms += tx_proposal_token_gas
wasms += tx_read_storage_key
wasms += tx_write
wasms += vp_always_false
Expand Down
Loading
Loading