diff --git a/.changelog/unreleased/features/582-native-token-param.md b/.changelog/unreleased/features/582-native-token-param.md new file mode 100644 index 00000000000..10dbb27503f --- /dev/null +++ b/.changelog/unreleased/features/582-native-token-param.md @@ -0,0 +1,2 @@ +- Allow to set the native token via genesis configuration. + ([#582](https://github.com/anoma/namada/pull/582)) \ No newline at end of file diff --git a/.changelog/unreleased/miscellaneous/632-xan-to-nam.md b/.changelog/unreleased/miscellaneous/632-xan-to-nam.md new file mode 100644 index 00000000000..8f9f2c155c8 --- /dev/null +++ b/.changelog/unreleased/miscellaneous/632-xan-to-nam.md @@ -0,0 +1,2 @@ +- Renamed native token from XAN to NAM + ([#632](https://github.com/anoma/namada/pull/632)) \ No newline at end of file diff --git a/apps/src/lib/cli.rs b/apps/src/lib/cli.rs index 8e4c7f78c94..d64a5fbf8ac 100644 --- a/apps/src/lib/cli.rs +++ b/apps/src/lib/cli.rs @@ -1296,7 +1296,7 @@ pub mod args { const FEE_AMOUNT: ArgDefault = arg_default("fee-amount", DefaultFn(|| token::Amount::from(0))); const FEE_TOKEN: ArgDefaultFromCtx = - arg_default_from_ctx("fee-token", DefaultFn(|| "XAN".into())); + arg_default_from_ctx("fee-token", DefaultFn(|| "NAM".into())); const FORCE: ArgFlag = flag("force"); const DONT_PREFETCH_WASM: ArgFlag = flag("dont-prefetch-wasm"); const GAS_LIMIT: ArgDefault = diff --git a/apps/src/lib/cli/context.rs b/apps/src/lib/cli/context.rs index fc6db9633b2..36a8d667536 100644 --- a/apps/src/lib/cli/context.rs +++ b/apps/src/lib/cli/context.rs @@ -47,6 +47,8 @@ pub struct Context { pub global_config: GlobalConfig, /// The ledger configuration for a specific chain ID pub config: Config, + /// Native token's address + pub native_token: Address, } impl Context { @@ -66,10 +68,12 @@ impl Context { let genesis_file_path = global_args .base_dir .join(format!("{}.toml", global_config.default_chain_id.as_str())); - let wallet = Wallet::load_or_new_from_genesis( - &chain_dir, - genesis_config::open_genesis_config(&genesis_file_path)?, - ); + let genesis = genesis_config::read_genesis_config(&genesis_file_path); + let native_token = genesis.native_token; + let default_genesis = + genesis_config::open_genesis_config(genesis_file_path)?; + let wallet = + Wallet::load_or_new_from_genesis(&chain_dir, default_genesis); // If the WASM dir specified, put it in the config match global_args.wasm_dir.as_ref() { @@ -88,6 +92,7 @@ impl Context { wallet, global_config, config, + native_token, }) } diff --git a/apps/src/lib/client/tx.rs b/apps/src/lib/client/tx.rs index e749a681c6f..af884bd916f 100644 --- a/apps/src/lib/client/tx.rs +++ b/apps/src/lib/client/tx.rs @@ -11,7 +11,7 @@ use itertools::Either::*; use namada::ledger::governance::storage as gov_storage; use namada::ledger::pos::{BondId, Bonds, Unbonds}; use namada::proto::Tx; -use namada::types::address::{xan as m1t, Address}; +use namada::types::address::Address; use namada::types::governance::{ OfflineProposal, OfflineVote, Proposal, ProposalVote, }; @@ -23,7 +23,7 @@ use namada::types::transaction::governance::{ }; use namada::types::transaction::nft::{CreateNft, MintNft}; use namada::types::transaction::{pos, InitAccount, InitValidator, UpdateVp}; -use namada::types::{address, storage, token}; +use namada::types::{storage, token}; use namada::{ledger, vm}; use super::rpc; @@ -639,9 +639,13 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) { safe_exit(1) }; - let balance = rpc::get_token_balance(&client, &m1t(), &proposal.author) - .await - .unwrap_or_default(); + let balance = rpc::get_token_balance( + &client, + &ctx.native_token, + &proposal.author, + ) + .await + .unwrap_or_default(); if balance < token::Amount::from(governance_parameters.min_proposal_fund) { @@ -911,7 +915,7 @@ pub async fn submit_bond(ctx: Context, args: args::Bond) { // Check bond's source (source for delegation or validator for self-bonds) // balance let bond_source = source.as_ref().unwrap_or(&validator); - let balance_key = token::balance_key(&address::xan(), bond_source); + let balance_key = token::balance_key(&ctx.native_token, bond_source); let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); match rpc::query_storage_value::(&client, &balance_key).await { diff --git a/apps/src/lib/client/utils.rs b/apps/src/lib/client/utils.rs index 88487267924..e1f865d5d75 100644 --- a/apps/src/lib/client/utils.rs +++ b/apps/src/lib/client/utils.rs @@ -612,18 +612,16 @@ pub fn init_network( }) } - if let Some(token) = &mut config.token { - token.iter_mut().for_each(|(name, config)| { - if config.address.is_none() { - let address = address::gen_established_address("token"); - config.address = Some(address.to_string()); - wallet.add_address(name.clone(), address); - } - if config.vp.is_none() { - config.vp = Some("vp_token".to_string()); - } - }) - } + config.token.iter_mut().for_each(|(name, config)| { + if config.address.is_none() { + let address = address::gen_established_address("token"); + config.address = Some(address.to_string()); + wallet.add_address(name.clone(), address); + } + if config.vp.is_none() { + config.vp = Some("vp_token".to_string()); + } + }); if let Some(implicit) = &mut config.implicit { implicit.iter_mut().for_each(|(name, config)| { diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs index 9425e3b0194..ac7ed4032bc 100644 --- a/apps/src/lib/config/genesis.rs +++ b/apps/src/lib/config/genesis.rs @@ -104,10 +104,13 @@ pub mod genesis_config { pub struct GenesisConfig { // Genesis timestamp pub genesis_time: Rfc3339String, + // Name of the native token - this must one of the tokens included in + // the `token` field + pub native_token: String, // Initial validator set pub validator: HashMap, // Token accounts present at genesis - pub token: Option>, + pub token: HashMap, // Established accounts present at genesis pub established: Option>, // Implicit accounts present at genesis @@ -479,32 +482,53 @@ pub mod genesis_config { } pub fn load_genesis_config(config: GenesisConfig) -> Genesis { - let wasms = config.wasm; - let validators: HashMap = config - .validator - .iter() - .map(|(name, cfg)| (name.clone(), load_validator(cfg, &wasms))) - .collect(); - let established_accounts: HashMap = config - .established - .unwrap_or_default() + let GenesisConfig { + genesis_time, + native_token, + validator, + token, + established, + implicit, + parameters, + pos_params, + gov_params, + wasm, + } = config; + + let native_token = Address::decode( + token + .get(&native_token) + .expect( + "Native token's alias must be present in the declared \ + tokens", + ) + .address + .as_ref() + .expect("Missing native token address"), + ) + .expect("Invalid address"); + + let validators: HashMap = validator .iter() - .map(|(name, cfg)| (name.clone(), load_established(cfg, &wasms))) + .map(|(name, cfg)| (name.clone(), load_validator(cfg, &wasm))) .collect(); - let implicit_accounts: HashMap = config - .implicit + let established_accounts: HashMap = + established + .unwrap_or_default() + .iter() + .map(|(name, cfg)| (name.clone(), load_established(cfg, &wasm))) + .collect(); + let implicit_accounts: HashMap = implicit .unwrap_or_default() .iter() .map(|(name, cfg)| (name.clone(), load_implicit(cfg))) .collect(); - let token_accounts = config - .token - .unwrap_or_default() + let token_accounts = token .iter() .map(|(_name, cfg)| { load_token( cfg, - &wasms, + &wasm, &validators, &established_accounts, &implicit_accounts, @@ -514,53 +538,66 @@ pub mod genesis_config { let parameters = Parameters { epoch_duration: EpochDuration { - min_num_of_blocks: config.parameters.min_num_of_blocks, + min_num_of_blocks: parameters.min_num_of_blocks, min_duration: namada::types::time::Duration::seconds( - config.parameters.min_duration, + parameters.min_duration, ) .into(), }, max_expected_time_per_block: namada::types::time::Duration::seconds( - config.parameters.max_expected_time_per_block, + parameters.max_expected_time_per_block, ) .into(), - vp_whitelist: config.parameters.vp_whitelist.unwrap_or_default(), - tx_whitelist: config.parameters.tx_whitelist.unwrap_or_default(), + vp_whitelist: parameters.vp_whitelist.unwrap_or_default(), + tx_whitelist: parameters.tx_whitelist.unwrap_or_default(), }; + let GovernanceParamsConfig { + min_proposal_fund, + max_proposal_code_size, + min_proposal_period, + max_proposal_content_size, + min_proposal_grace_epochs, + max_proposal_period, + } = gov_params; let gov_params = GovParams { - min_proposal_fund: config.gov_params.min_proposal_fund, - max_proposal_code_size: config.gov_params.max_proposal_code_size, - min_proposal_period: config.gov_params.min_proposal_period, - max_proposal_period: config.gov_params.max_proposal_period, - max_proposal_content_size: config - .gov_params - .max_proposal_content_size, - min_proposal_grace_epochs: config - .gov_params - .min_proposal_grace_epochs, + min_proposal_fund, + max_proposal_code_size, + min_proposal_period, + max_proposal_content_size, + min_proposal_grace_epochs, + max_proposal_period, }; + let PosParamsConfig { + max_validator_slots, + pipeline_len, + unbonding_len, + votes_per_token, + block_proposer_reward, + block_vote_reward, + duplicate_vote_slash_rate, + light_client_attack_slash_rate, + } = pos_params; let pos_params = PosParams { - max_validator_slots: config.pos_params.max_validator_slots, - pipeline_len: config.pos_params.pipeline_len, - unbonding_len: config.pos_params.unbonding_len, - votes_per_token: BasisPoints::new( - config.pos_params.votes_per_token, - ), - block_proposer_reward: config.pos_params.block_proposer_reward, - block_vote_reward: config.pos_params.block_vote_reward, + max_validator_slots, + pipeline_len, + unbonding_len, + votes_per_token: BasisPoints::new(votes_per_token), + block_proposer_reward, + block_vote_reward, duplicate_vote_slash_rate: BasisPoints::new( - config.pos_params.duplicate_vote_slash_rate, + duplicate_vote_slash_rate, ), light_client_attack_slash_rate: BasisPoints::new( - config.pos_params.light_client_attack_slash_rate, + light_client_attack_slash_rate, ), }; let mut genesis = Genesis { - genesis_time: config.genesis_time.try_into().unwrap(), + genesis_time: genesis_time.try_into().unwrap(), + native_token, validators: validators.into_values().collect(), token_accounts, established_accounts: established_accounts.into_values().collect(), @@ -608,6 +645,7 @@ pub mod genesis_config { #[borsh_init(init)] pub struct Genesis { pub genesis_time: DateTimeUtc, + pub native_token: Address, pub validators: Vec, pub token_accounts: Vec, pub established_accounts: Vec, @@ -839,6 +877,7 @@ pub fn genesis() -> Genesis { parameters, pos_params: PosParams::default(), gov_params: GovParams::default(), + native_token: address::nam(), } } diff --git a/apps/src/lib/node/ledger/mod.rs b/apps/src/lib/node/ledger/mod.rs index dc0dfc184c8..2f09d02db99 100644 --- a/apps/src/lib/node/ledger/mod.rs +++ b/apps/src/lib/node/ledger/mod.rs @@ -30,6 +30,7 @@ use crate::config::TendermintMode; use crate::facade::tendermint_proto::abci::CheckTxType; use crate::facade::tower_abci::{response, split, Server}; use crate::node::ledger::broadcaster::Broadcaster; +use crate::node::ledger::config::genesis; use crate::node::ledger::shell::{Error, MempoolTxType, Shell}; use crate::node::ledger::shims::abcipp_shim::AbcippShim; use crate::node::ledger::shims::abcipp_shim_types::shim::{Request, Response}; @@ -423,6 +424,10 @@ fn start_abci_broadcaster_shell( // Construct our ABCI application. let tendermint_mode = config.tendermint.tendermint_mode.clone(); let ledger_address = config.shell.ledger_address; + #[cfg(not(feature = "dev"))] + let genesis = genesis::genesis(&config.shell.base_dir, &config.chain_id); + #[cfg(feature = "dev")] + let genesis = genesis::genesis(); let (shell, abci_service) = AbcippShim::new( config, wasm_dir, @@ -430,6 +435,7 @@ fn start_abci_broadcaster_shell( &db_cache, vp_wasm_compilation_cache, tx_wasm_compilation_cache, + genesis.native_token, ); // Channel for signalling shut down to ABCI server diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index 2080b8d23de..a3e429477f3 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -321,7 +321,6 @@ where /// are covered by the e2e tests. #[cfg(test)] mod test_finalize_block { - use namada::types::address::xan; use namada::types::storage::Epoch; use namada::types::transaction::{EncryptionKey, Fee}; @@ -349,7 +348,7 @@ mod test_finalize_block { let wrapper = WrapperTx::new( Fee { amount: i.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -420,7 +419,7 @@ mod test_finalize_block { let wrapper = WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -472,7 +471,7 @@ mod test_finalize_block { let wrapper = WrapperTx { fee: Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, pk: keypair.ref_to(), epoch: Epoch(0), @@ -538,7 +537,7 @@ mod test_finalize_block { let wrapper_tx = WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -569,7 +568,7 @@ mod test_finalize_block { let wrapper_tx = WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), diff --git a/apps/src/lib/node/ledger/shell/governance.rs b/apps/src/lib/node/ledger/shell/governance.rs index 979c3c0df15..90fd22f04b1 100644 --- a/apps/src/lib/node/ledger/shell/governance.rs +++ b/apps/src/lib/node/ledger/shell/governance.rs @@ -6,7 +6,7 @@ use namada::ledger::governance::vp::ADDRESS as gov_address; use namada::ledger::slash_fund::ADDRESS as slash_fund_address; use namada::ledger::storage::types::encode; use namada::ledger::storage::{DBIter, StorageHasher, DB}; -use namada::types::address::{xan as m1t, Address}; +use namada::types::address::Address; use namada::types::governance::TallyResult; use namada::types::storage::Epoch; use namada::types::token; @@ -176,10 +176,14 @@ where } }; + let native_token = shell.storage.native_token.clone(); // transfer proposal locked funds - shell - .storage - .transfer(&m1t(), funds, &gov_address, &transfer_address); + shell.storage.transfer( + &native_token, + funds, + &gov_address, + &transfer_address, + ); } Ok(proposals_result) diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index 8cb6842c50f..f29b824efdd 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -222,7 +222,7 @@ where // Account balance (tokens no staked in PoS) self.storage .write( - &token::balance_key(&address::xan(), addr), + &token::balance_key(&self.storage.native_token, addr), validator .non_staked_balance .try_to_vec() diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index 28167d4ebac..186eb87726c 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -32,6 +32,7 @@ use namada::ledger::storage::{ }; use namada::ledger::{ibc, pos}; use namada::proto::{self, Tx}; +use namada::types::address::Address; use namada::types::chain::ChainId; use namada::types::key::*; use namada::types::storage::{BlockHeight, Key}; @@ -231,6 +232,7 @@ where db_cache: Option<&D::Cache>, vp_wasm_compilation_cache: u64, tx_wasm_compilation_cache: u64, + native_token: Address, ) -> Self { let chain_id = config.chain_id; let db_path = config.shell.db_dir(&chain_id); @@ -241,7 +243,8 @@ where .expect("Creating directory for Anoma should not fail"); } // load last state from storage - let mut storage = Storage::open(db_path, chain_id.clone(), db_cache); + let mut storage = + Storage::open(db_path, chain_id.clone(), native_token, db_cache); storage .load_last_state() .map_err(|e| { @@ -641,7 +644,7 @@ mod test_utils { use namada::ledger::storage::mockdb::MockDB; use namada::ledger::storage::{BlockStateWrite, MerkleTree, Sha256Hasher}; - use namada::types::address::{xan, EstablishedAddressGen}; + use namada::types::address::EstablishedAddressGen; use namada::types::chain::ChainId; use namada::types::hash::Hash; use namada::types::key::*; @@ -739,6 +742,7 @@ mod test_utils { None, vp_wasm_compilation_cache, tx_wasm_compilation_cache, + address::nam(), ), }, receiver, @@ -840,6 +844,7 @@ mod test_utils { let (sender, _) = tokio::sync::mpsc::unbounded_channel(); let vp_wasm_compilation_cache = 50 * 1024 * 1024; // 50 kiB let tx_wasm_compilation_cache = 50 * 1024 * 1024; // 50 kiB + let native_token = address::nam(); let mut shell = Shell::::new( config::Ledger::new( base_dir.clone(), @@ -851,6 +856,7 @@ mod test_utils { None, vp_wasm_compilation_cache, tx_wasm_compilation_cache, + native_token.clone(), ); let keypair = gen_keypair(); // enqueue a wrapper tx @@ -861,7 +867,7 @@ mod test_utils { let wrapper = WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: native_token, }, &keypair, Epoch(0), @@ -909,6 +915,7 @@ mod test_utils { None, vp_wasm_compilation_cache, tx_wasm_compilation_cache, + address::nam(), ); assert!(!shell.storage.tx_queue.is_empty()); } diff --git a/apps/src/lib/node/ledger/shell/prepare_proposal.rs b/apps/src/lib/node/ledger/shell/prepare_proposal.rs index c41f2c20837..9338ecc4820 100644 --- a/apps/src/lib/node/ledger/shell/prepare_proposal.rs +++ b/apps/src/lib/node/ledger/shell/prepare_proposal.rs @@ -140,7 +140,6 @@ pub(super) mod record { #[cfg(test)] mod test_prepare_proposal { use borsh::BorshSerialize; - use namada::types::address::xan; use namada::types::storage::Epoch; use namada::types::transaction::{Fee, WrapperTx}; @@ -189,7 +188,7 @@ mod test_prepare_proposal { WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -244,7 +243,7 @@ mod test_prepare_proposal { let wrapper_tx = WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), diff --git a/apps/src/lib/node/ledger/shell/process_proposal.rs b/apps/src/lib/node/ledger/shell/process_proposal.rs index 5572e00495d..83cef2cb6a9 100644 --- a/apps/src/lib/node/ledger/shell/process_proposal.rs +++ b/apps/src/lib/node/ledger/shell/process_proposal.rs @@ -189,7 +189,6 @@ where mod test_process_proposal { use borsh::BorshDeserialize; use namada::proto::SignedTxData; - use namada::types::address::xan; use namada::types::hash::Hash; use namada::types::key::*; use namada::types::storage::Epoch; @@ -217,7 +216,7 @@ mod test_process_proposal { let wrapper = WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -264,7 +263,7 @@ mod test_process_proposal { let mut wrapper = WrapperTx::new( Fee { amount: 100.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -346,7 +345,7 @@ mod test_process_proposal { let wrapper = WrapperTx::new( Fee { amount: 1.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -399,7 +398,7 @@ mod test_process_proposal { let wrapper = WrapperTx::new( Fee { amount: Amount::whole(1_000_100), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -447,7 +446,7 @@ mod test_process_proposal { let wrapper = WrapperTx::new( Fee { amount: i.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -511,7 +510,7 @@ mod test_process_proposal { let wrapper = WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -570,7 +569,7 @@ mod test_process_proposal { let mut wrapper = WrapperTx::new( Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, &keypair, Epoch(0), @@ -623,7 +622,7 @@ mod test_process_proposal { let wrapper = WrapperTx { fee: Fee { amount: 0.into(), - token: xan(), + token: shell.storage.native_token.clone(), }, pk: keypair.ref_to(), epoch: Epoch(0), diff --git a/apps/src/lib/node/ledger/shims/abcipp_shim.rs b/apps/src/lib/node/ledger/shims/abcipp_shim.rs index e919610f8e0..76fbd34d246 100644 --- a/apps/src/lib/node/ledger/shims/abcipp_shim.rs +++ b/apps/src/lib/node/ledger/shims/abcipp_shim.rs @@ -5,6 +5,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use futures::future::FutureExt; +use namada::types::address::Address; #[cfg(not(feature = "abcipp"))] use namada::types::hash::Hash; #[cfg(not(feature = "abcipp"))] @@ -50,6 +51,7 @@ impl AbcippShim { db_cache: &rocksdb::Cache, vp_wasm_compilation_cache: u64, tx_wasm_compilation_cache: u64, + native_token: Address, ) -> (Self, AbciService) { // We can use an unbounded channel here, because tower-abci limits the // the number of requests that can come in @@ -63,6 +65,7 @@ impl AbcippShim { Some(db_cache), vp_wasm_compilation_cache, tx_wasm_compilation_cache, + native_token, ), #[cfg(not(feature = "abcipp"))] begin_block_request: None, diff --git a/apps/src/lib/node/ledger/storage/mod.rs b/apps/src/lib/node/ledger/storage/mod.rs index 2876236bca8..2209b8500d7 100644 --- a/apps/src/lib/node/ledger/storage/mod.rs +++ b/apps/src/lib/node/ledger/storage/mod.rs @@ -51,6 +51,7 @@ fn new_blake2b() -> Blake2b { #[cfg(test)] mod tests { use namada::ledger::storage::types; + use namada::types::address; use namada::types::chain::ChainId; use namada::types::storage::{BlockHash, BlockHeight, Key}; use tempfile::TempDir; @@ -61,8 +62,12 @@ mod tests { fn test_crud_value() { let db_path = TempDir::new().expect("Unable to create a temporary DB directory"); - let mut storage = - PersistentStorage::open(db_path.path(), ChainId::default(), None); + let mut storage = PersistentStorage::open( + db_path.path(), + ChainId::default(), + address::nam(), + None, + ); let key = Key::parse("key").expect("cannot parse the key string"); let value: u64 = 1; let value_bytes = types::encode(&value); @@ -104,8 +109,12 @@ mod tests { fn test_commit_block() { let db_path = TempDir::new().expect("Unable to create a temporary DB directory"); - let mut storage = - PersistentStorage::open(db_path.path(), ChainId::default(), None); + let mut storage = PersistentStorage::open( + db_path.path(), + ChainId::default(), + address::nam(), + None, + ); storage .begin_block(BlockHash::default(), BlockHeight(100)) .expect("begin_block failed"); @@ -126,8 +135,12 @@ mod tests { drop(storage); // load the last state - let mut storage = - PersistentStorage::open(db_path.path(), ChainId::default(), None); + let mut storage = PersistentStorage::open( + db_path.path(), + ChainId::default(), + address::nam(), + None, + ); storage .load_last_state() .expect("loading the last state failed"); @@ -145,8 +158,12 @@ mod tests { fn test_iter() { let db_path = TempDir::new().expect("Unable to create a temporary DB directory"); - let mut storage = - PersistentStorage::open(db_path.path(), ChainId::default(), None); + let mut storage = PersistentStorage::open( + db_path.path(), + ChainId::default(), + address::nam(), + None, + ); storage .begin_block(BlockHash::default(), BlockHeight(100)) .expect("begin_block failed"); @@ -185,8 +202,12 @@ mod tests { fn test_validity_predicate() { let db_path = TempDir::new().expect("Unable to create a temporary DB directory"); - let mut storage = - PersistentStorage::open(db_path.path(), ChainId::default(), None); + let mut storage = PersistentStorage::open( + db_path.path(), + ChainId::default(), + address::nam(), + None, + ); storage .begin_block(BlockHash::default(), BlockHeight(100)) .expect("begin_block failed"); diff --git a/apps/src/lib/wallet/defaults.rs b/apps/src/lib/wallet/defaults.rs index ad519d64dea..03d6c06ca2a 100644 --- a/apps/src/lib/wallet/defaults.rs +++ b/apps/src/lib/wallet/defaults.rs @@ -33,16 +33,14 @@ pub fn addresses_from_genesis(genesis: GenesisConfig) -> Vec<(Alias, Address)> { }); addresses.extend(validator_addresses); // Genesis tokens - if let Some(accounts) = genesis.token { - let token_addresses = accounts.into_iter().map(|(alias, token)| { - // The address must be set in the genesis config file - ( - alias.into(), - Address::decode(token.address.unwrap()).unwrap(), - ) - }); - addresses.extend(token_addresses); - } + let token_addresses = genesis.token.into_iter().map(|(alias, token)| { + // The address must be set in the genesis config file + ( + alias.into(), + Address::decode(token.address.unwrap()).unwrap(), + ) + }); + addresses.extend(token_addresses); // Genesis established accounts if let Some(accounts) = genesis.established { let est_addresses = accounts.into_iter().map(|(alias, established)| { diff --git a/documentation/dev/src/explore/design/actors.md b/documentation/dev/src/explore/design/actors.md index 88e26f3d640..6172505adb8 100644 --- a/documentation/dev/src/explore/design/actors.md +++ b/documentation/dev/src/explore/design/actors.md @@ -1,6 +1,6 @@ # Actors and Incentives -Namada consists of various actors fulfilling various roles in the network. They are all incentivized to act for the good of the network. The native Namada token `XAN` is used to settle transaction fees and pay for the incentives in Namada. +Namada consists of various actors fulfilling various roles in the network. They are all incentivized to act for the good of the network. The native Namada token `NAM` is used to settle transaction fees and pay for the incentives in Namada. ## Fees associated with a transaction @@ -9,7 +9,7 @@ Users of Namada can - transfer private assets they hold to other users and - barter assets with other users. -Each transaction may be associated with the following fees, paid in `XAN`: +Each transaction may be associated with the following fees, paid in `NAM`: - **Execution fees** to compensate for computing, storage and memory costs, charges at 2 stages: - **initial fee (init_f)**: charged before the transaction is settled diff --git a/documentation/dev/src/explore/design/ledger/pos-integration.md b/documentation/dev/src/explore/design/ledger/pos-integration.md index d441e5ddcac..dda5abc7489 100644 --- a/documentation/dev/src/explore/design/ledger/pos-integration.md +++ b/documentation/dev/src/explore/design/ledger/pos-integration.md @@ -27,7 +27,7 @@ All [the data relevant to the PoS system](https://specs.namada.net/economics/pro - `validator/{validator_address}/address_raw_hash` (required): raw hash of validator's address associated with the address is used for look-up of validator address from a raw hash - TBA (e.g. alias, website, description, delegation commission rate, etc.) -Only XAN tokens can be staked in bonds. The tokens being staked (bonds and unbonds amounts) are kept in the PoS account under `{xan_address}/balance/{pos_address}` until they are withdrawn. +Only NAM tokens can be staked in bonds. The tokens being staked (bonds and unbonds amounts) are kept in the PoS account under `{nam_address}/balance/{pos_address}` until they are withdrawn. ## Initialization @@ -39,7 +39,7 @@ Staking rewards for validators are rewarded in Tendermint's method `BeginBlock` To a validator who proposed a block (`block.header.proposer_address`), the system rewards tokens based on the `block_proposer_reward` PoS parameter and each validator that voted on a block (`block.last_commit_info.validator` who `signed_last_block`) receives `block_vote_reward`. -All the fees that are charged in a transaction execution (DKG transaction wrapper fee and transactions applied in a block) are transferred into a fee pool, which is another special account controlled by the PoS module. Note that the fee pool account may contain tokens other than the staking token XAN. +All the fees that are charged in a transaction execution (DKG transaction wrapper fee and transactions applied in a block) are transferred into a fee pool, which is another special account controlled by the PoS module. Note that the fee pool account may contain tokens other than the staking token NAM. - TODO describe the fee pool, related to , and diff --git a/documentation/dev/src/explore/design/ledger/vp.md b/documentation/dev/src/explore/design/ledger/vp.md index 7cf939f331c..46eb28e5713 100644 --- a/documentation/dev/src/explore/design/ledger/vp.md +++ b/documentation/dev/src/explore/design/ledger/vp.md @@ -39,9 +39,9 @@ The Proof-of-Stake slash pool is a simple account with a native VP which can rec The [fungible token VP](https://github.com/anoma/anoma/tree/master/wasm/wasm_source) allows to associate accounts balances of a specific token under its account. -For illustration, users `Albert` and `Bertha` might hold some amount of token with the address `XAN`. Their balances would be stored in the `XAN`'s storage sub-space under the storage keys `@XAN/balance/@Albert` and `@XAN/balance/@Bertha`, respectively. When `Albert` or `Bertha` attempt to transact with their `XAN` tokens, its validity predicate would be triggered to check: +For illustration, users `Albert` and `Bertha` might hold some amount of token with the address `NAM`. Their balances would be stored in the `NAM`'s storage sub-space under the storage keys `@NAM/balance/@Albert` and `@NAM/balance/@Bertha`, respectively. When `Albert` or `Bertha` attempt to transact with their `NAM` tokens, its validity predicate would be triggered to check: -- the total supply of `XAN` token is preserved (i.e. inputs = outputs) +- the total supply of `NAM` token is preserved (i.e. inputs = outputs) - the senders (users whose balance has been deducted) are checked that their validity predicate has also been triggered Note that the fungible token VP doesn't need to know whether any of involved users accepted or rejected the transaction, because if any of the involved users rejects it, the whole transaction will be rejected. diff --git a/documentation/dev/src/specs/ledger/default-transactions.md b/documentation/dev/src/specs/ledger/default-transactions.md index 78ed5b2098e..fb254f0cd3b 100644 --- a/documentation/dev/src/specs/ledger/default-transactions.md +++ b/documentation/dev/src/specs/ledger/default-transactions.md @@ -36,13 +36,13 @@ Attach [UpdateVp](../encoding.md#updatevp) to the `data`. ### tx_bond -Self-bond `amount` of XAN token from `validator` (without `source`) or delegate to `validator` from `source`. +Self-bond `amount` of NAM token from `validator` (without `source`) or delegate to `validator` from `source`. Attach [Bond](../encoding.md#bond) to the `data`. ### tx_unbond -Unbond self-bonded `amount` of XAN token from the `validator` (without `source`) or unbond delegation from the `source` to the `validator`. +Unbond self-bonded `amount` of NAM token from the `validator` (without `source`) or unbond delegation from the `source` to the `validator`. Attach [Bond](../encoding.md#bond) to the `data`. diff --git a/genesis/dev.toml b/genesis/dev.toml index 29a4b4d7917..c14390bdff8 100644 --- a/genesis/dev.toml +++ b/genesis/dev.toml @@ -1,5 +1,6 @@ # Example genesis with dev settings. genesis_time = "2021-09-30:10:00.00Z" +native_token = "NAM" # A genesis validator with alias "validator". [validator.validator] @@ -26,10 +27,10 @@ net_address = "127.0.0.1:26656" # Some tokens present at genesis. -[token.xan] +[token.NAM] address = "atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5" vp = "vp_token" -[token.xan.balances] +[token.NAM.balances] # In token balances, we can use: # 1. An address any account a1qyqzsqqqqqcyvvf5xcu5vd6rg4z5233hg9pn23pjgdryzdjy8pz52wzxxscnvvjxx3rryvzz8y5p6mtz = 1000000 @@ -42,28 +43,28 @@ bertha = 1000000 "bertha.public_key" = 100 "validator.public_key" = 100 -[token.btc] +[token.BTC] address = "atest1v4ehgw36xdzryve5gsc52veeg5cnsv2yx5eygvp38qcrvd29xy6rys6p8yc5xvp4xfpy2v694wgwcp" vp = "vp_token" -[token.btc.balances] +[token.BTC.balances] atest1v4ehgw368ycryv2z8qcnxv3cxgmrgvjpxs6yg333gym5vv2zxepnj334g4rryvj9xucrgve4x3xvr4 = 1000000 atest1v4ehgw36x3qng3jzggu5yvpsxgcngv2xgguy2dpkgvu5x33kx3pr2w2zgep5xwfkxscrxs2pj8075p = 1000000 atest1v4ehgw36xvcyyvejgvenxs34g3zygv3jxqunjd6rxyeyys3sxy6rwvfkx4qnj33hg9qnvse4lsfctw = 1000000 a1qyqzsqqqqqcyvvf5xcu5vd6rg4z5233hg9pn23pjgdryzdjy8pz52wzxxscnvvjxx3rryvzz8y5p6mtz = 1000000 -[token.eth] +[token.ETH] address = "atest1v4ehgw36xqmr2d3nx3ryvd2xxgmrq33j8qcns33sxezrgv6zxdzrydjrxveygd2yxumrsdpsf9jc2p" vp = "vp_token" -[token.eth.balances] +[token.ETH.balances] atest1v4ehgw368ycryv2z8qcnxv3cxgmrgvjpxs6yg333gym5vv2zxepnj334g4rryvj9xucrgve4x3xvr4 = 1000000 atest1v4ehgw36x3qng3jzggu5yvpsxgcngv2xgguy2dpkgvu5x33kx3pr2w2zgep5xwfkxscrxs2pj8075p = 1000000 atest1v4ehgw36xvcyyvejgvenxs34g3zygv3jxqunjd6rxyeyys3sxy6rwvfkx4qnj33hg9qnvse4lsfctw = 1000000 a1qyqzsqqqqqcyvvf5xcu5vd6rg4z5233hg9pn23pjgdryzdjy8pz52wzxxscnvvjxx3rryvzz8y5p6mtz = 1000000 -[token.dot] +[token.DOT] address = "atest1v4ehgw36gg6nvs2zgfpyxsfjgc65yv6pxy6nwwfsxgungdzrggeyzv35gveyxsjyxymyz335hur2jn" vp = "vp_token" -[token.dot.balances] +[token.DOT.balances] atest1v4ehgw368ycryv2z8qcnxv3cxgmrgvjpxs6yg333gym5vv2zxepnj334g4rryvj9xucrgve4x3xvr4 = 1000000 atest1v4ehgw36x3qng3jzggu5yvpsxgcngv2xgguy2dpkgvu5x33kx3pr2w2zgep5xwfkxscrxs2pj8075p = 1000000 atest1v4ehgw36xvcyyvejgvenxs34g3zygv3jxqunjd6rxyeyys3sxy6rwvfkx4qnj33hg9qnvse4lsfctw = 1000000 @@ -168,7 +169,7 @@ light_client_attack_slash_rate = 500 # Governance parameters. [gov_params] -# minimum amount of xan token to lock +# minimum amount of NAM token to lock min_proposal_fund = 500 # proposal code size in bytes max_proposal_code_size = 300000 diff --git a/genesis/e2e-tests-single-node.toml b/genesis/e2e-tests-single-node.toml index 0e3a6d3fc86..fa7e6141634 100644 --- a/genesis/e2e-tests-single-node.toml +++ b/genesis/e2e-tests-single-node.toml @@ -3,9 +3,10 @@ # - User accounts same as the ones in "dev" build (Albert, Bertha, Christel) genesis_time = "2021-09-30T10:00:00Z" +native_token = "NAM" [validator.validator-0] -# Validator's staked XAN at genesis. +# Validator's staked NAM at genesis. tokens = 200000 # Amount of the validator's genesis token balance which is not staked. non_staked_balance = 1000000000000 @@ -20,10 +21,10 @@ net_address = "127.0.0.1:27656" # Some tokens present at genesis. -[token.XAN] +[token.NAM] address = "atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5" vp = "vp_token" -[token.XAN.balances] +[token.NAM.balances] Albert = 1000000 "Albert.public_key" = 100 Bertha = 1000000 @@ -168,7 +169,7 @@ light_client_attack_slash_rate = 500 # Governance parameters. [gov_params] -# minimum amount of xan token to lock +# minimum amount of nam token to lock min_proposal_fund = 500 # proposal code size in bytes max_proposal_code_size = 300000 diff --git a/proof_of_stake/src/lib.rs b/proof_of_stake/src/lib.rs index 7676ee7d2e4..66a026e6f3e 100644 --- a/proof_of_stake/src/lib.rs +++ b/proof_of_stake/src/lib.rs @@ -101,9 +101,7 @@ pub trait PosReadOnly { const POS_ADDRESS: Self::Address; /// Address of the staking token - /// TODO: this should be `const`, but in the ledger `address::xan` is not a - /// `const fn` - fn staking_token_address() -> Self::Address; + fn staking_token_address(&self) -> Self::Address; /// Read PoS parameters. fn read_pos_params(&self) -> Result; @@ -375,7 +373,7 @@ pub trait PosActions: PosReadOnly { // Transfer the bonded tokens from the source to PoS self.transfer( - &Self::staking_token_address(), + &self.staking_token_address(), amount, source, &Self::POS_ADDRESS, @@ -505,7 +503,7 @@ pub trait PosActions: PosReadOnly { // Transfer the tokens from PoS back to the source self.transfer( - &Self::staking_token_address(), + &self.staking_token_address(), withdrawn, &Self::POS_ADDRESS, source, @@ -577,9 +575,7 @@ pub trait PosBase { /// Address of the PoS account const POS_ADDRESS: Self::Address; /// Address of the staking token - /// TODO: this should be `const`, but in the ledger `address::xan` is not a - /// `const fn` - fn staking_token_address() -> Self::Address; + fn staking_token_address(&self) -> Self::Address; /// Address of the slash pool, into which slashed tokens are transferred. const POS_SLASH_POOL_ADDRESS: Self::Address; @@ -759,7 +755,7 @@ pub trait PosBase { self.write_total_voting_power(&total_voting_power); // Credit the bonded tokens to the PoS account self.credit_tokens( - &Self::staking_token_address(), + &self.staking_token_address(), &Self::POS_ADDRESS, total_bonded_balance, ); @@ -934,7 +930,7 @@ pub trait PosBase { self.write_total_voting_power(&total_voting_power); // Transfer the slashed tokens to the PoS slash pool self.transfer( - &Self::staking_token_address(), + &self.staking_token_address(), slashed_amount, &Self::POS_ADDRESS, &Self::POS_SLASH_POOL_ADDRESS, diff --git a/shared/src/ledger/governance/mod.rs b/shared/src/ledger/governance/mod.rs index 72aa7fb3ced..38e9ed86fce 100644 --- a/shared/src/ledger/governance/mod.rs +++ b/shared/src/ledger/governance/mod.rs @@ -15,9 +15,10 @@ use std::collections::BTreeSet; pub use vp::Result; use self::storage as gov_storage; +use super::storage_api::StorageRead; use crate::ledger::native_vp::{Ctx, NativeVp}; use crate::ledger::storage::{self as ledger_storage, StorageHasher}; -use crate::types::address::{xan as m1t, Address, InternalAddress}; +use crate::types::address::{Address, InternalAddress}; use crate::types::storage::Key; use crate::types::token as token_storage; use crate::vm::WasmCacheAccess; @@ -55,10 +56,11 @@ where return Ok(false); }; + let native_token = self.ctx.pre().get_native_token()?; let result = keys_changed.iter().all(|key| { let proposal_id = gov_storage::get_proposal_id(key); - let key_type: KeyType = key.into(); + let key_type: KeyType = get_key_type(key, &native_token); match (key_type, proposal_id) { (KeyType::VOTE(validate), Some(proposal_id)) => { validate(&self.ctx, proposal_id, key, verifiers) @@ -206,41 +208,42 @@ where UNKNOWN(fn() -> bool), } -impl<'a, DB, H, CA> From<&Key> for KeyType<'a, DB, H, CA> +fn get_key_type<'a, DB, H, CA>( + value: &Key, + native_token: &Address, +) -> KeyType<'a, DB, H, CA> where DB: 'static + ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter>, H: 'static + StorageHasher, CA: 'static + WasmCacheAccess, { - fn from(value: &Key) -> Self { - if gov_storage::is_vote_key(value) { - KeyType::VOTE(vp::validate_vote_key) - } else if gov_storage::is_content_key(value) { - KeyType::CONTENT(vp::validate_content_key) - } else if gov_storage::is_proposal_code_key(value) { - KeyType::PROPOSAL_CODE(vp::validate_proposal_code_key) - } else if gov_storage::is_grace_epoch_key(value) { - KeyType::GRACE_EPOCH(vp::validate_grace_epoch_key) - } else if gov_storage::is_start_epoch_key(value) { - KeyType::START_EPOCH(vp::validate_start_epoch_key) - } else if gov_storage::is_commit_proposal_key(value) { - KeyType::PROPOSAL_COMMIT(vp::validate_commit_key) - } else if gov_storage::is_end_epoch_key(value) { - KeyType::END_EPOCH(vp::validate_end_epoch_key) - } else if gov_storage::is_balance_key(value) { - KeyType::FUNDS(vp::validate_funds_key) - } else if gov_storage::is_author_key(value) { - KeyType::AUTHOR(vp::validate_author_key) - } else if gov_storage::is_counter_key(value) { - KeyType::COUNTER(vp::validate_counter_key) - } else if gov_storage::is_parameter_key(value) { - KeyType::PARAMETER(vp::validate_parameter_key) - } else if token_storage::is_balance_key(&m1t(), value).is_some() { - KeyType::BALANCE(vp::validate_balance_key) - } else if gov_storage::is_governance_key(value) { - KeyType::UNKNOWN_GOVERNANCE(vp::validate_unknown_governance_key) - } else { - KeyType::UNKNOWN(vp::validate_unknown_key) - } + if gov_storage::is_vote_key(value) { + KeyType::VOTE(vp::validate_vote_key) + } else if gov_storage::is_content_key(value) { + KeyType::CONTENT(vp::validate_content_key) + } else if gov_storage::is_proposal_code_key(value) { + KeyType::PROPOSAL_CODE(vp::validate_proposal_code_key) + } else if gov_storage::is_grace_epoch_key(value) { + KeyType::GRACE_EPOCH(vp::validate_grace_epoch_key) + } else if gov_storage::is_start_epoch_key(value) { + KeyType::START_EPOCH(vp::validate_start_epoch_key) + } else if gov_storage::is_commit_proposal_key(value) { + KeyType::PROPOSAL_COMMIT(vp::validate_commit_key) + } else if gov_storage::is_end_epoch_key(value) { + KeyType::END_EPOCH(vp::validate_end_epoch_key) + } else if gov_storage::is_balance_key(value) { + KeyType::FUNDS(vp::validate_funds_key) + } else if gov_storage::is_author_key(value) { + KeyType::AUTHOR(vp::validate_author_key) + } else if gov_storage::is_counter_key(value) { + KeyType::COUNTER(vp::validate_counter_key) + } else if gov_storage::is_parameter_key(value) { + KeyType::PARAMETER(vp::validate_parameter_key) + } else if token_storage::is_balance_key(native_token, value).is_some() { + KeyType::BALANCE(vp::validate_balance_key) + } else if gov_storage::is_governance_key(value) { + KeyType::UNKNOWN_GOVERNANCE(vp::validate_unknown_governance_key) + } else { + KeyType::UNKNOWN(vp::validate_unknown_key) } } diff --git a/shared/src/ledger/governance/vp.rs b/shared/src/ledger/governance/vp.rs index 7537cd5f012..0d78fa1bf54 100644 --- a/shared/src/ledger/governance/vp.rs +++ b/shared/src/ledger/governance/vp.rs @@ -7,8 +7,9 @@ use super::storage as gov_storage; use crate::ledger::native_vp::{self, Ctx}; use crate::ledger::pos::{self as pos_storage, BondId, Bonds}; use crate::ledger::storage::{self as ledger_storage, StorageHasher}; +use crate::ledger::storage_api::StorageRead; use crate::ledger::vp_env::VpEnv; -use crate::types::address::{xan as m1t, Address, InternalAddress}; +use crate::types::address::{Address, InternalAddress}; use crate::types::storage::{Epoch, Key}; use crate::types::token; use crate::vm::WasmCacheAccess; @@ -53,7 +54,12 @@ where H: 'static + StorageHasher, CA: 'static + WasmCacheAccess, { - let balance_key = token::balance_key(&m1t(), &ADDRESS); + let balance_key = token::balance_key( + &ctx.pre() + .get_native_token() + .expect("Native token must be available"), + &ADDRESS, + ); let min_funds_parameter_key = gov_storage::get_min_proposal_fund_key(); let min_funds_parameter: Option = read(ctx, &min_funds_parameter_key, ReadType::PRE).ok(); @@ -164,7 +170,12 @@ where CA: 'static + WasmCacheAccess, { let funds_key = gov_storage::get_funds_key(proposal_id); - let balance_key = token::balance_key(&m1t(), &ADDRESS); + let balance_key = token::balance_key( + &ctx.pre() + .get_native_token() + .expect("Native token must be available"), + &ADDRESS, + ); let min_funds_parameter_key = gov_storage::get_min_proposal_fund_key(); let min_funds_parameter: Option = read(ctx, &min_funds_parameter_key, ReadType::PRE).ok(); @@ -534,19 +545,13 @@ where #[derive(Error, Debug)] pub enum Error { #[error("Native VP error: {0}")] - NativeVpError(native_vp::Error), + NativeVpError(#[from] native_vp::Error), #[error("Native VP error deserialization: {0}")] NativeVpDeserializationError(std::io::Error), #[error("Native VP error non-existing key: {0}")] NativeVpNonExistingKeyError(String), } -impl From for Error { - fn from(err: native_vp::Error) -> Self { - Self::NativeVpError(err) - } -} - /// Check if a vote is from a delegator pub fn is_delegator( context: &Ctx, diff --git a/shared/src/ledger/ibc/vp/mod.rs b/shared/src/ledger/ibc/vp/mod.rs index b5dec0293c6..6ff04180bba 100644 --- a/shared/src/ledger/ibc/vp/mod.rs +++ b/shared/src/ledger/ibc/vp/mod.rs @@ -1463,7 +1463,7 @@ mod tests { source_port: get_port_id(), source_channel: get_channel_id(), token: Some(Coin { - denom: "XAN".to_string(), + denom: "NAM".to_string(), amount: 100u64.to_string(), }), sender: Signer::new("sender"), @@ -1722,7 +1722,7 @@ mod tests { source_port: get_port_id(), source_channel: get_channel_id(), token: Some(Coin { - denom: "XAN".to_string(), + denom: "NAM".to_string(), amount: 100u64.to_string(), }), sender: Signer::new("sender"), diff --git a/shared/src/ledger/native_vp.rs b/shared/src/ledger/native_vp.rs index 2b7d41e7950..e4ef2ce651e 100644 --- a/shared/src/ledger/native_vp.rs +++ b/shared/src/ledger/native_vp.rs @@ -228,6 +228,10 @@ where fn get_block_epoch(&self) -> Result { self.ctx.get_block_epoch() } + + fn get_native_token(&self) -> Result { + self.ctx.get_native_token() + } } impl<'view, 'a, DB, H, CA> StorageRead<'view> @@ -309,6 +313,10 @@ where fn get_block_epoch(&self) -> Result { self.ctx.get_block_epoch() } + + fn get_native_token(&self) -> Result { + Ok(self.ctx.storage.native_token.clone()) + } } impl<'view, 'a: 'view, DB, H, CA> VpEnv<'view> for Ctx<'a, DB, H, CA> @@ -379,6 +387,14 @@ where .into_storage_result() } + fn get_native_token(&'view self) -> Result { + vp_env::get_native_token( + &mut *self.gas_meter.borrow_mut(), + self.storage, + ) + .into_storage_result() + } + fn iter_prefix( &'view self, prefix: &Key, diff --git a/shared/src/ledger/pos/mod.rs b/shared/src/ledger/pos/mod.rs index 3b498727df3..1c8742c4f63 100644 --- a/shared/src/ledger/pos/mod.rs +++ b/shared/src/ledger/pos/mod.rs @@ -15,7 +15,7 @@ pub use vp::PosVP; use super::storage_api; use crate::ledger::storage::{self as ledger_storage, Storage, StorageHasher}; -use crate::types::address::{self, Address, InternalAddress}; +use crate::types::address::{Address, InternalAddress}; use crate::types::storage::Epoch; use crate::types::{key, token}; @@ -26,11 +26,6 @@ pub const ADDRESS: Address = Address::Internal(InternalAddress::PoS); pub const SLASH_POOL_ADDRESS: Address = Address::Internal(InternalAddress::PosSlashPool); -/// Address of the staking token (XAN) -pub fn staking_token_address() -> Address { - address::xan() -} - /// Initialize storage in the genesis block. pub fn init_genesis_storage<'a, DB, H>( storage: &mut Storage, @@ -157,8 +152,8 @@ mod macros { const POS_ADDRESS: Self::Address = $crate::ledger::pos::ADDRESS; - fn staking_token_address() -> Self::Address { - $crate::ledger::pos::staking_token_address() + fn staking_token_address(&self) -> Self::Address { + self.get_native_token().expect("Native token must be available") } fn read_pos_params(&self) -> std::result::Result { diff --git a/shared/src/ledger/pos/storage.rs b/shared/src/ledger/pos/storage.rs index 366ce489b50..8d65dba1fcd 100644 --- a/shared/src/ledger/pos/storage.rs +++ b/shared/src/ledger/pos/storage.rs @@ -379,8 +379,8 @@ where const POS_ADDRESS: Self::Address = super::ADDRESS; const POS_SLASH_POOL_ADDRESS: Self::Address = super::SLASH_POOL_ADDRESS; - fn staking_token_address() -> Self::Address { - super::staking_token_address() + fn staking_token_address(&self) -> Self::Address { + self.native_token.clone() } fn read_pos_params(&self) -> PosParams { diff --git a/shared/src/ledger/pos/vp.rs b/shared/src/ledger/pos/vp.rs index 60264e49260..a293044db0c 100644 --- a/shared/src/ledger/pos/vp.rs +++ b/shared/src/ledger/pos/vp.rs @@ -19,12 +19,12 @@ use super::{ bond_key, is_bond_key, is_params_key, is_total_voting_power_key, is_unbond_key, is_validator_set_key, is_validator_staking_reward_address_key, is_validator_total_deltas_key, - is_validator_voting_power_key, params_key, staking_token_address, - total_voting_power_key, unbond_key, validator_consensus_key_key, - validator_set_key, validator_slashes_key, - validator_staking_reward_address_key, validator_state_key, - validator_total_deltas_key, validator_voting_power_key, BondId, Bonds, - Unbonds, ValidatorConsensusKeys, ValidatorSets, ValidatorTotalDeltas, + is_validator_voting_power_key, params_key, total_voting_power_key, + unbond_key, validator_consensus_key_key, validator_set_key, + validator_slashes_key, validator_staking_reward_address_key, + validator_state_key, validator_total_deltas_key, + validator_voting_power_key, BondId, Bonds, Unbonds, ValidatorConsensusKeys, + ValidatorSets, ValidatorTotalDeltas, }; use crate::impl_pos_read_only; use crate::ledger::governance::vp::is_proposal_accepted; @@ -122,6 +122,7 @@ where let addr = Address::Internal(Self::ADDR); let mut changes: Vec> = vec![]; let current_epoch = self.ctx.pre().get_block_epoch()?; + let staking_token_address = self.ctx.pre().get_native_token()?; for key in keys_changed { if is_params_key(key) { @@ -214,7 +215,7 @@ where data: Data { pre, post }, }); } else if let Some(owner) = - token::is_balance_key(&staking_token_address(), key) + token::is_balance_key(&staking_token_address, key) { if owner != &addr { continue; diff --git a/shared/src/ledger/slash_fund/mod.rs b/shared/src/ledger/slash_fund/mod.rs index 0d452af2e5f..26044444fec 100644 --- a/shared/src/ledger/slash_fund/mod.rs +++ b/shared/src/ledger/slash_fund/mod.rs @@ -10,9 +10,10 @@ use thiserror::Error; use self::storage as slash_fund_storage; use super::governance::vp::is_proposal_accepted; +use super::storage_api::StorageRead; use crate::ledger::native_vp::{self, Ctx, NativeVp}; use crate::ledger::storage::{self as ledger_storage, StorageHasher}; -use crate::types::address::{xan as nam, Address, InternalAddress}; +use crate::types::address::{Address, InternalAddress}; use crate::types::storage::Key; use crate::types::token; use crate::vm::WasmCacheAccess; @@ -24,7 +25,7 @@ pub const ADDRESS: Address = Address::Internal(InternalAddress::SlashFund); #[derive(Error, Debug)] pub enum Error { #[error("Native VP error: {0}")] - NativeVpError(native_vp::Error), + NativeVpError(#[from] native_vp::Error), } /// SlashFund functions result @@ -57,8 +58,9 @@ where keys_changed: &BTreeSet, _verifiers: &BTreeSet
, ) -> Result { + let native_token = self.ctx.pre().get_native_token()?; let result = keys_changed.iter().all(|key| { - let key_type: KeyType = key.into(); + let key_type: KeyType = get_key_type(key, &native_token); match key_type { KeyType::BALANCE(addr) => { if addr.ne(&ADDRESS) { @@ -90,17 +92,15 @@ enum KeyType { UNKNOWN, } -impl From<&Key> for KeyType { - fn from(value: &Key) -> Self { - if slash_fund_storage::is_slash_fund_key(value) { - KeyType::UNKNOWN_SLASH_FUND - } else if token::is_any_token_balance_key(value).is_some() { - match token::is_balance_key(&nam(), value) { - Some(addr) => KeyType::BALANCE(addr.clone()), - None => KeyType::UNKNOWN, - } - } else { - KeyType::UNKNOWN +fn get_key_type(value: &Key, native_token: &Address) -> KeyType { + if slash_fund_storage::is_slash_fund_key(value) { + KeyType::UNKNOWN_SLASH_FUND + } else if token::is_any_token_balance_key(value).is_some() { + match token::is_balance_key(native_token, value) { + Some(addr) => KeyType::BALANCE(addr.clone()), + None => KeyType::UNKNOWN, } + } else { + KeyType::UNKNOWN } } diff --git a/shared/src/ledger/storage/mod.rs b/shared/src/ledger/storage/mod.rs index 16c3ecf1803..44751fa5a60 100644 --- a/shared/src/ledger/storage/mod.rs +++ b/shared/src/ledger/storage/mod.rs @@ -52,6 +52,9 @@ where pub db: D, /// The ID of the chain pub chain_id: ChainId, + /// The address of the native token - this is not stored in DB, but read + /// from genesis + pub native_token: Address, /// The storage for the current (yet to be committed) block pub block: BlockStorage, /// The latest block header @@ -279,6 +282,7 @@ where pub fn open( db_path: impl AsRef, chain_id: ChainId, + native_token: Address, cache: Option<&D::Cache>, ) -> Self { let block = BlockStorage { @@ -302,6 +306,7 @@ where ), #[cfg(feature = "ferveo-tpke")] tx_queue: TxQueue::default(), + native_token, } } @@ -789,6 +794,12 @@ where ) -> std::result::Result { Ok(self.block.epoch) } + + fn get_native_token( + &self, + ) -> std::result::Result { + Ok(self.native_token.clone()) + } } impl StorageWrite for Storage @@ -879,6 +890,7 @@ pub mod testing { use super::mockdb::MockDB; use super::*; use crate::ledger::storage::traits::Sha256Hasher; + use crate::types::address; /// Storage with a mock DB for testing pub type TestStorage = Storage; @@ -907,6 +919,7 @@ pub mod testing { ), #[cfg(feature = "ferveo-tpke")] tx_queue: TxQueue::default(), + native_token: address::nam(), } } } diff --git a/shared/src/ledger/storage_api/mod.rs b/shared/src/ledger/storage_api/mod.rs index b806f35801c..fbef8742ac8 100644 --- a/shared/src/ledger/storage_api/mod.rs +++ b/shared/src/ledger/storage_api/mod.rs @@ -8,6 +8,7 @@ pub mod validation; use borsh::{BorshDeserialize, BorshSerialize}; pub use error::{CustomError, Error, OptionExt, Result, ResultExt}; +use crate::types::address::Address; use crate::types::storage::{self, BlockHash, BlockHeight, Epoch}; /// Common storage read interface @@ -96,6 +97,9 @@ pub trait StorageRead<'iter> { /// Getting the block epoch. The epoch is that of the block to which the /// current transaction is being applied. fn get_block_epoch(&self) -> Result; + + /// Get the native token address + fn get_native_token(&self) -> Result
; } /// Common storage write interface diff --git a/shared/src/ledger/vp_env.rs b/shared/src/ledger/vp_env.rs index 3f1b22ddc65..fab888b9a39 100644 --- a/shared/src/ledger/vp_env.rs +++ b/shared/src/ledger/vp_env.rs @@ -13,6 +13,7 @@ use crate::ledger::gas::VpGasMeter; use crate::ledger::storage::write_log::WriteLog; use crate::ledger::storage::{self, write_log, Storage, StorageHasher}; use crate::proto::Tx; +use crate::types::address::Address; use crate::types::hash::Hash; use crate::types::key::common; use crate::types::storage::{BlockHash, BlockHeight, Epoch, Key}; @@ -65,6 +66,9 @@ pub trait VpEnv<'view> { /// current transaction is being applied. fn get_block_epoch(&'view self) -> Result; + /// Get the address of the native token. + fn get_native_token(&'view self) -> Result; + /// Storage prefix iterator, ordered by storage keys. It will try to get an /// iterator from the storage. fn iter_prefix( @@ -434,6 +438,19 @@ where Ok(epoch) } +/// Getting the chain ID. +pub fn get_native_token( + gas_meter: &mut VpGasMeter, + storage: &Storage, +) -> EnvResult
+where + DB: storage::DB + for<'iter> storage::DBIter<'iter>, + H: StorageHasher, +{ + add_gas(gas_meter, MIN_STORAGE_GAS)?; + Ok(storage.native_token.clone()) +} + /// Storage prefix iterator, ordered by storage keys. It will try to get an /// iterator from the storage. pub fn iter_prefix<'a, DB, H>( diff --git a/shared/src/types/address.rs b/shared/src/types/address.rs index 6f047730fed..57a9f299cfa 100644 --- a/shared/src/types/address.rs +++ b/shared/src/types/address.rs @@ -488,7 +488,7 @@ impl Display for InternalAddress { } /// Temporary helper for testing -pub fn xan() -> Address { +pub fn nam() -> Address { Address::decode("atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5").expect("The token address decoding shouldn't fail") } @@ -526,7 +526,7 @@ pub fn kartoffel() -> Address { /// informal currency codes. pub fn tokens() -> HashMap { vec![ - (xan(), "XAN"), + (nam(), "NAM"), (btc(), "BTC"), (eth(), "ETH"), (dot(), "DOT"), diff --git a/shared/src/types/transaction/mod.rs b/shared/src/types/transaction/mod.rs index a7d5ee864bf..508e28db924 100644 --- a/shared/src/types/transaction/mod.rs +++ b/shared/src/types/transaction/mod.rs @@ -343,7 +343,7 @@ pub mod tx_types { #[cfg(test)] mod test_process_tx { use super::*; - use crate::types::address::xan; + use crate::types::address::nam; use crate::types::storage::Epoch; fn gen_keypair() -> common::SecretKey { @@ -427,7 +427,7 @@ pub mod tx_types { let wrapper = WrapperTx::new( Fee { amount: 10.into(), - token: xan(), + token: nam(), }, &keypair, Epoch(0), @@ -462,7 +462,7 @@ pub mod tx_types { let wrapper = WrapperTx::new( Fee { amount: 10.into(), - token: xan(), + token: nam(), }, &keypair, Epoch(0), diff --git a/shared/src/types/transaction/wrapper.rs b/shared/src/types/transaction/wrapper.rs index ad27b807aae..e0e6dab6be6 100644 --- a/shared/src/types/transaction/wrapper.rs +++ b/shared/src/types/transaction/wrapper.rs @@ -337,7 +337,7 @@ pub mod wrapper_tx { mod test_wrapper_tx { use super::*; use crate::proto::SignedTxData; - use crate::types::address::xan; + use crate::types::address::nam; fn gen_keypair() -> common::SecretKey { use rand::prelude::ThreadRng; @@ -360,7 +360,7 @@ pub mod wrapper_tx { let wrapper = WrapperTx::new( Fee { amount: 10.into(), - token: xan(), + token: nam(), }, &keypair, Epoch(0), @@ -386,7 +386,7 @@ pub mod wrapper_tx { let mut wrapper = WrapperTx::new( Fee { amount: 10.into(), - token: xan(), + token: nam(), }, &gen_keypair(), Epoch(0), @@ -418,7 +418,7 @@ pub mod wrapper_tx { let mut tx = WrapperTx::new( Fee { amount: 10.into(), - token: xan(), + token: nam(), }, &keypair, Epoch(0), diff --git a/shared/src/vm/host_env.rs b/shared/src/vm/host_env.rs index 1ac0754e253..47eba121e81 100644 --- a/shared/src/vm/host_env.rs +++ b/shared/src/vm/host_env.rs @@ -12,7 +12,7 @@ use super::wasm::TxCache; #[cfg(feature = "wasm-runtime")] use super::wasm::VpCache; use super::WasmCacheAccess; -use crate::ledger::gas::{self, BlockGasMeter, VpGasMeter}; +use crate::ledger::gas::{self, BlockGasMeter, VpGasMeter, MIN_STORAGE_GAS}; use crate::ledger::storage::write_log::{self, WriteLog}; use crate::ledger::storage::{self, Storage, StorageHasher}; use crate::ledger::vp_env; @@ -1555,6 +1555,28 @@ where Ok(epoch.0) } +/// Get the native token's address +pub fn tx_get_native_token( + env: &TxVmEnv, + result_ptr: u64, +) -> TxResult<()> +where + MEM: VmMemory, + DB: storage::DB + for<'iter> storage::DBIter<'iter>, + H: StorageHasher, + CA: WasmCacheAccess, +{ + let storage = unsafe { env.ctx.storage.get() }; + tx_add_gas(env, MIN_STORAGE_GAS)?; + let native_token = storage.native_token.clone(); + let native_token_string = native_token.encode(); + let gas = env + .memory + .write_string(result_ptr, native_token_string) + .map_err(|e| TxRuntimeError::MemoryError(Box::new(e)))?; + tx_add_gas(env, gas) +} + /// Getting the chain ID function exposed to the wasm VM VP environment. pub fn vp_get_chain_id( env: &VpVmEnv, @@ -1804,6 +1826,29 @@ where .to_i64()) } +/// Get the native token's address +pub fn vp_get_native_token( + env: &VpVmEnv, + result_ptr: u64, +) -> vp_env::EnvResult<()> +where + MEM: VmMemory, + DB: storage::DB + for<'iter> storage::DBIter<'iter>, + H: StorageHasher, + EVAL: VpEvaluator, + CA: WasmCacheAccess, +{ + let gas_meter = unsafe { env.ctx.gas_meter.get() }; + let storage = unsafe { env.ctx.storage.get() }; + let native_token = vp_env::get_native_token(gas_meter, storage)?; + let native_token_string = native_token.encode(); + let gas = env + .memory + .write_string(result_ptr, native_token_string) + .map_err(|e| vp_env::RuntimeError::MemoryError(Box::new(e)))?; + vp_env::add_gas(gas_meter, gas) +} + /// Log a string from exposed to the wasm VM VP environment. The message will be /// printed at the [`tracing::Level::INFO`]. This function is for development /// only. diff --git a/shared/src/vm/wasm/host_env.rs b/shared/src/vm/wasm/host_env.rs index 06d45fa4f93..7c94b9390db 100644 --- a/shared/src/vm/wasm/host_env.rs +++ b/shared/src/vm/wasm/host_env.rs @@ -78,6 +78,7 @@ where "anoma_tx_get_block_time" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_get_block_time), "anoma_tx_get_block_hash" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_get_block_hash), "anoma_tx_get_block_epoch" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_get_block_epoch), + "anoma_tx_get_native_token" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_get_native_token), "anoma_tx_log_string" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_log_string), }, } @@ -118,6 +119,7 @@ where "anoma_vp_get_block_epoch" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_get_block_epoch), "anoma_vp_verify_tx_signature" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_verify_tx_signature), "anoma_vp_eval" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_eval), + "anoma_vp_get_native_token" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_get_native_token), "anoma_vp_log_string" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_log_string), }, } diff --git a/tests/src/e2e/ledger_tests.rs b/tests/src/e2e/ledger_tests.rs index a998844764e..d7c8a300263 100644 --- a/tests/src/e2e/ledger_tests.rs +++ b/tests/src/e2e/ledger_tests.rs @@ -95,7 +95,7 @@ fn test_node_connectivity() -> Result<()> { "--target", ALBERT, "--token", - XAN, + NAM, "--amount", "10.1", "--fee-amount", @@ -103,7 +103,7 @@ fn test_node_connectivity() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -129,7 +129,7 @@ fn test_node_connectivity() -> Result<()> { "--owner", ALBERT, "--token", - XAN, + NAM, "--ledger-address", ledger_rpc, ] @@ -141,7 +141,7 @@ fn test_node_connectivity() -> Result<()> { for ledger_rpc in &[validator_0_rpc, validator_1_rpc, non_validator_rpc] { let mut client = run!(test, Bin::Client, query_balance_args(ledger_rpc), Some(40))?; - client.exp_string("XAN: 1000010.1")?; + client.exp_string("NAM: 1000010.1")?; client.assert_success(); } @@ -283,7 +283,7 @@ fn ledger_txs_and_queries() -> Result<()> { "--target", ALBERT, "--token", - XAN, + NAM, "--amount", "10.1", "--fee-amount", @@ -291,7 +291,7 @@ fn ledger_txs_and_queries() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ], @@ -308,7 +308,7 @@ fn ledger_txs_and_queries() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ], @@ -326,7 +326,7 @@ fn ledger_txs_and_queries() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc ], @@ -347,7 +347,7 @@ fn ledger_txs_and_queries() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ], @@ -379,12 +379,12 @@ fn ledger_txs_and_queries() -> Result<()> { "--owner", BERTHA, "--token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ], // expect a decimal - r"XAN: \d+(\.\d+)?", + r"NAM: \d+(\.\d+)?", ), ]; for (query_args, expected) in &query_args_and_expected_response { @@ -396,8 +396,8 @@ fn ledger_txs_and_queries() -> Result<()> { let christel = find_address(&test, CHRISTEL)?; // as setup in `genesis/e2e-tests-single-node.toml` let christel_balance = token::Amount::whole(1000000); - let xan = find_address(&test, XAN)?; - let storage_key = token::balance_key(&xan, &christel).to_string(); + let nam = find_address(&test, NAM)?; + let storage_key = token::balance_key(&nam, &christel).to_string(); let query_args_and_expected_response = vec![ // 7. Query storage key and get hex-encoded raw bytes ( @@ -447,7 +447,7 @@ fn invalid_transactions() -> Result<()> { let transfer = token::Transfer { source: find_address(&test, DAEWON)?, target: find_address(&test, ALBERT)?, - token: find_address(&test, XAN)?, + token: find_address(&test, NAM)?, sub_prefix: None, amount: token::Amount::whole(1), }; @@ -474,7 +474,7 @@ fn invalid_transactions() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -528,7 +528,7 @@ fn invalid_transactions() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, // Force to ignore client check that fails on the balance check of the // source address "--force", @@ -604,7 +604,7 @@ fn pos_bonds() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -627,7 +627,7 @@ fn pos_bonds() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -647,7 +647,7 @@ fn pos_bonds() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -670,7 +670,7 @@ fn pos_bonds() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -710,7 +710,7 @@ fn pos_bonds() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -731,7 +731,7 @@ fn pos_bonds() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -747,7 +747,7 @@ fn pos_bonds() -> Result<()> { /// 1. Run the ledger node with shorter epochs for faster progression /// 2. Initialize a new validator account /// 3. Submit a delegation to the new validator -/// 4. Transfer some XAN to the new validator +/// 4. Transfer some NAM to the new validator /// 5. Submit a self-bond for the new validator /// 6. Wait for the pipeline epoch /// 7. Check the new validator's voting power @@ -800,7 +800,7 @@ fn pos_init_validator() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -817,7 +817,7 @@ fn pos_init_validator() -> Result<()> { "--target", &new_validator_key, "--token", - XAN, + NAM, "--amount", "0.5", "--fee-amount", @@ -825,7 +825,7 @@ fn pos_init_validator() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -846,7 +846,7 @@ fn pos_init_validator() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -854,7 +854,7 @@ fn pos_init_validator() -> Result<()> { client.exp_string("Transaction is valid.")?; client.assert_success(); - // 4. Transfer some XAN to the new validator + // 4. Transfer some NAM to the new validator let tx_args = vec![ "transfer", "--source", @@ -862,7 +862,7 @@ fn pos_init_validator() -> Result<()> { "--target", new_validator, "--token", - XAN, + NAM, "--amount", "10999.5", "--fee-amount", @@ -870,7 +870,7 @@ fn pos_init_validator() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -890,7 +890,7 @@ fn pos_init_validator() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -958,7 +958,7 @@ fn ledger_many_txs_in_a_block() -> Result<()> { "--target", ALBERT, "--token", - XAN, + NAM, "--amount", "10.1", "--fee-amount", @@ -966,7 +966,7 @@ fn ledger_many_txs_in_a_block() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", ]); @@ -1075,7 +1075,7 @@ fn proposal_submission() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -1146,13 +1146,13 @@ fn proposal_submission() -> Result<()> { "--owner", ALBERT, "--token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; let mut client = run!(test, Bin::Client, query_balance_args, Some(40))?; - client.exp_string("XAN: 999500")?; + client.exp_string("NAM: 999500")?; client.assert_success(); // 5. Query token balance governance @@ -1161,13 +1161,13 @@ fn proposal_submission() -> Result<()> { "--owner", GOVERNANCE_ADDRESS, "--token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; let mut client = run!(test, Bin::Client, query_balance_args, Some(40))?; - client.exp_string("XAN: 500")?; + client.exp_string("NAM: 500")?; client.assert_success(); // 6. Submit an invalid proposal @@ -1248,13 +1248,13 @@ fn proposal_submission() -> Result<()> { "--owner", ALBERT, "--token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; let mut client = run!(test, Bin::Client, query_balance_args, Some(40))?; - client.exp_string("XAN: 999500")?; + client.exp_string("NAM: 999500")?; client.assert_success(); // 9. Send a yay vote from a validator @@ -1353,13 +1353,13 @@ fn proposal_submission() -> Result<()> { "--owner", ALBERT, "--token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; let mut client = run!(test, Bin::Client, query_balance_args, Some(30))?; - client.exp_string("XAN: 1000000")?; + client.exp_string("NAM: 1000000")?; client.assert_success(); // 13. Check if governance funds are 0 @@ -1368,13 +1368,13 @@ fn proposal_submission() -> Result<()> { "--owner", GOVERNANCE_ADDRESS, "--token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; let mut client = run!(test, Bin::Client, query_balance_args, Some(30))?; - client.exp_string("XAN: 0")?; + client.exp_string("NAM: 0")?; client.assert_success(); // // 14. Query parameters @@ -1424,7 +1424,7 @@ fn proposal_offline() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -1859,7 +1859,7 @@ fn test_genesis_validators() -> Result<()> { "--target", validator_1_alias, "--token", - XAN, + NAM, "--amount", "10.1", "--fee-amount", @@ -1867,7 +1867,7 @@ fn test_genesis_validators() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; @@ -2003,7 +2003,7 @@ fn double_signing_gets_slashed() -> Result<()> { "--target", ALBERT, "--token", - XAN, + NAM, "--amount", "10.1", "--fee-amount", @@ -2011,7 +2011,7 @@ fn double_signing_gets_slashed() -> Result<()> { "--gas-limit", "0", "--fee-token", - XAN, + NAM, "--ledger-address", &validator_one_rpc, ]; diff --git a/tests/src/e2e/setup.rs b/tests/src/e2e/setup.rs index b20f14d54f0..3d6ff5e951d 100644 --- a/tests/src/e2e/setup.rs +++ b/tests/src/e2e/setup.rs @@ -766,7 +766,7 @@ pub mod constants { pub const GOVERNANCE_ADDRESS: &str = "governance"; // Fungible token addresses - pub const XAN: &str = "XAN"; + pub const NAM: &str = "NAM"; pub const BTC: &str = "BTC"; pub const ETH: &str = "ETH"; pub const DOT: &str = "DOT"; diff --git a/tests/src/native_vp/pos.rs b/tests/src/native_vp/pos.rs index ec6f75a15f0..00a57b46838 100644 --- a/tests/src/native_vp/pos.rs +++ b/tests/src/native_vp/pos.rs @@ -101,9 +101,7 @@ use namada::ledger::pos::namada_proof_of_stake::PosBase; use namada::types::storage::Epoch; -use namada_tx_prelude::proof_of_stake::{ - staking_token_address, GenesisValidator, PosParams, -}; +use namada_tx_prelude::proof_of_stake::{GenesisValidator, PosParams}; use crate::tx::tx_host_env; @@ -119,7 +117,8 @@ pub fn init_pos( tx_host_env::with(|tx_env| { // Ensure that all the used // addresses exist - tx_env.spawn_accounts([&staking_token_address()]); + let native_token = tx_env.storage.native_token.clone(); + tx_env.spawn_accounts([&native_token]); for validator in genesis_validators { tx_env.spawn_accounts([ &validator.address, @@ -587,7 +586,7 @@ pub mod testing { WeightedValidator, }; use namada_tx_prelude::proof_of_stake::{ - staking_token_address, BondId, Bonds, PosParams, Unbonds, + BondId, Bonds, PosParams, Unbonds, }; use namada_tx_prelude::{Address, StorageRead, StorageWrite}; use proptest::prelude::*; @@ -1478,7 +1477,7 @@ pub mod testing { } PosStorageChange::StakingTokenPosBalance { delta } => { let balance_key = token::balance_key( - &staking_token_address(), + &tx::ctx().get_native_token().unwrap(), &::POS_ADDRESS, ); let mut balance: token::Amount = diff --git a/tests/src/vm_host_env/mod.rs b/tests/src/vm_host_env/mod.rs index 3325c6eb6a7..75c27f649f0 100644 --- a/tests/src/vm_host_env/mod.rs +++ b/tests/src/vm_host_env/mod.rs @@ -260,6 +260,10 @@ mod tests { tx::ctx().get_block_epoch().unwrap(), tx_host_env::with(|env| env.storage.get_current_epoch().0) ); + assert_eq!( + tx::ctx().get_native_token().unwrap(), + tx_host_env::with(|env| env.storage.native_token.clone()) + ); } /// An example how to write a VP host environment integration test @@ -510,6 +514,10 @@ mod tests { vp::CTX.get_block_epoch().unwrap(), vp_host_env::with(|env| env.storage.get_current_epoch().0) ); + assert_eq!( + vp::CTX.get_native_token().unwrap(), + vp_host_env::with(|env| env.storage.native_token.clone()) + ); } #[test] diff --git a/tests/src/vm_host_env/tx.rs b/tests/src/vm_host_env/tx.rs index 6a3ef960848..ec16f89a273 100644 --- a/tests/src/vm_host_env/tx.rs +++ b/tests/src/vm_host_env/tx.rs @@ -380,5 +380,6 @@ mod native_tx_host_env { native_host_fn!(tx_get_block_time() -> i64); native_host_fn!(tx_get_block_hash(result_ptr: u64)); native_host_fn!(tx_get_block_epoch() -> u64); + native_host_fn!(tx_get_native_token(result_ptr: u64)); native_host_fn!(tx_log_string(str_ptr: u64, str_len: u64)); } diff --git a/tests/src/vm_host_env/vp.rs b/tests/src/vm_host_env/vp.rs index 88aa63d530b..99a6facc031 100644 --- a/tests/src/vm_host_env/vp.rs +++ b/tests/src/vm_host_env/vp.rs @@ -334,6 +334,7 @@ mod native_vp_host_env { native_host_fn!(vp_get_block_hash(result_ptr: u64)); native_host_fn!(vp_get_tx_code_hash(result_ptr: u64)); native_host_fn!(vp_get_block_epoch() -> u64); + native_host_fn!(vp_get_native_token(result_ptr: u64)); native_host_fn!(vp_verify_tx_signature( pk_ptr: u64, pk_len: u64, diff --git a/tx_prelude/src/governance.rs b/tx_prelude/src/governance.rs index 2dbab74a9e5..f33a30cab62 100644 --- a/tx_prelude/src/governance.rs +++ b/tx_prelude/src/governance.rs @@ -2,7 +2,6 @@ use namada::ledger::governance::storage; use namada::ledger::governance::vp::ADDRESS as governance_address; -use namada::types::address::xan as m1t; use namada::types::token::Amount; use namada::types::transaction::governance::{ InitProposalData, VoteProposalData, @@ -59,7 +58,7 @@ pub fn init_proposal(ctx: &mut Ctx, data: InitProposalData) -> TxResult { ctx, &data.author, &governance_address, - &m1t(), + &ctx.get_native_token()?, None, min_proposal_funds, ) diff --git a/tx_prelude/src/lib.rs b/tx_prelude/src/lib.rs index 730adb3155b..209c8e132f3 100644 --- a/tx_prelude/src/lib.rs +++ b/tx_prelude/src/lib.rs @@ -168,6 +168,20 @@ impl StorageRead<'_> for Ctx { Ok(Epoch(unsafe { anoma_tx_get_block_epoch() })) } + /// Get the native token address + fn get_native_token(&self) -> Result { + let result = Vec::with_capacity(address::ADDRESS_LEN); + unsafe { + anoma_tx_get_native_token(result.as_ptr() as _); + } + let slice = unsafe { + slice::from_raw_parts(result.as_ptr(), address::ADDRESS_LEN) + }; + let address_str = + std::str::from_utf8(slice).expect("Cannot decode native address"); + Ok(Address::decode(address_str).expect("Cannot decode native address")) + } + fn iter_prefix( &self, prefix: &namada::types::storage::Key, diff --git a/vm_env/src/lib.rs b/vm_env/src/lib.rs index 1421dbde488..62212fd5e81 100644 --- a/vm_env/src/lib.rs +++ b/vm_env/src/lib.rs @@ -101,6 +101,9 @@ pub mod tx { // Get the current block epoch pub fn anoma_tx_get_block_epoch() -> u64; + // Get the native token address + pub fn anoma_tx_get_native_token(result_ptr: u64); + // Requires a node running with "Info" log level pub fn anoma_tx_log_string(str_ptr: u64, str_len: u64); } @@ -181,6 +184,9 @@ pub mod vp { // Get the current block epoch pub fn anoma_vp_get_block_epoch() -> u64; + // Get the native token address + pub fn anoma_vp_get_native_token(result_ptr: u64); + // Verify a transaction signature pub fn anoma_vp_verify_tx_signature( pk_ptr: u64, diff --git a/vp_prelude/src/lib.rs b/vp_prelude/src/lib.rs index e6618bc5de7..14fef3133cd 100644 --- a/vp_prelude/src/lib.rs +++ b/vp_prelude/src/lib.rs @@ -241,6 +241,11 @@ impl<'view> VpEnv<'view> for Ctx { get_block_epoch() } + fn get_native_token(&'view self) -> Result { + // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl + get_native_token() + } + fn iter_prefix( &self, prefix: &storage::Key, @@ -361,6 +366,10 @@ impl StorageRead<'_> for CtxPreStorageRead<'_> { fn get_block_epoch(&self) -> Result { get_block_epoch() } + + fn get_native_token(&self) -> Result { + get_native_token() + } } impl StorageRead<'_> for CtxPostStorageRead<'_> { @@ -422,6 +431,10 @@ impl StorageRead<'_> for CtxPostStorageRead<'_> { fn get_block_epoch(&self) -> Result { get_block_epoch() } + + fn get_native_token(&self) -> Result { + get_native_token() + } } fn iter_prefix_impl( @@ -474,3 +487,15 @@ fn get_block_hash() -> Result { fn get_block_epoch() -> Result { Ok(Epoch(unsafe { anoma_vp_get_block_epoch() })) } + +fn get_native_token() -> Result { + let result = Vec::with_capacity(address::ADDRESS_LEN); + unsafe { + anoma_vp_get_native_token(result.as_ptr() as _); + } + let slice = + unsafe { slice::from_raw_parts(result.as_ptr(), address::ADDRESS_LEN) }; + let address_str = + std::str::from_utf8(slice).expect("Cannot decode native address"); + Ok(Address::decode(address_str).expect("Cannot decode native address")) +} diff --git a/wasm/checksums.json b/wasm/checksums.json index 01140354ba3..b17477b7325 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,18 +1,18 @@ { - "tx_bond.wasm": "tx_bond.38c037a51f9215c2be9c1b01f647251ffdc96a02a0c958c5d3db4ee36ccde43b.wasm", - "tx_ibc.wasm": "tx_ibc.5f86477029d987073ebfec66019dc991b0bb8b80717d4885b860f910916cbcdd.wasm", - "tx_init_account.wasm": "tx_init_account.8d901bce15d1ab63a591def00421183a651d4d5e09ace4291bf0a9044692741d.wasm", - "tx_init_nft.wasm": "tx_init_nft.1991808f44c1c24d4376a3d46b602bed27575f6c0359095c53f37b9225050ffc.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.716cd08d59b26bd75815511f03e141e6ac27bc0b7d7be10a71b04559244722c2.wasm", - "tx_init_validator.wasm": "tx_init_validator.611edff2746f71cdaa7547a84a96676b555821f00af8375a28f8dab7ae9fc9fa.wasm", + "tx_bond.wasm": "tx_bond.9fb0f31c3f51443b2a68bb4a1c127e573dd456547d3f46e4bd17a5ca43159285.wasm", + "tx_ibc.wasm": "tx_ibc.54c3f2de323d44f18aeb1eeca7f8f6ac0fdb8f129ca792688a96a14657028918.wasm", + "tx_init_account.wasm": "tx_init_account.d71b97412b1140f373d20b69d249bbd6dffbdef51273abb5e1a47605d137756b.wasm", + "tx_init_nft.wasm": "tx_init_nft.472df9bd8075b84e9299822430f0d43aff923f28ec9f84bf69b2ca07f7e0f6b6.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.1a41a44258fa21d2fffbad45f7e03f12df6d8be2d5625a05d2737930dcb0a4cf.wasm", + "tx_init_validator.wasm": "tx_init_validator.f1b2d731fca5885e5928c0a2380ad00305b1d6835d8cd4019cf3d21aa07bd347.wasm", "tx_mint_nft.wasm": "tx_mint_nft.3f20f1a86da43cc475ccc127428944bd177d40fbe2d2d1588c6fadd069cbe4b2.wasm", - "tx_transfer.wasm": "tx_transfer.5653340103a32e6685f9668ec24855f65ae17bcc43035c2559a13f5c47bb67af.wasm", - "tx_unbond.wasm": "tx_unbond.71e66ac6f792123a2aaafd60b3892d74a7d0e7a03c3ea34f15fea9089010b810.wasm", + "tx_transfer.wasm": "tx_transfer.00a7efcb41c94bd7fa4639f21f1248c0a918f8673c54ea55d20cfde2b2334cb1.wasm", + "tx_unbond.wasm": "tx_unbond.155d5a01f28979ebeab420e2e831358610a44499fd600e269f9044686e879f6f.wasm", "tx_update_vp.wasm": "tx_update_vp.6d291dadb43545a809ba33fe26582b7984c67c65f05e363a93dbc62e06a33484.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.ff3def7b4bb0c46635bd6d544ac1745362757ce063feb8142d2ed9ab207f2a12.wasm", - "tx_withdraw.wasm": "tx_withdraw.ba1a743cf8914a353d7706777e0b1a37e20cd271b16e022fd3b50ad28971291f.wasm", - "vp_nft.wasm": "vp_nft.4471284b5c5f3e28c973f0a2ad2dde52ebe4a1dcd5dc15e93b380706fd0e35ea.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.7d7eb09cddc7ae348417da623e21ec4a4f8c78f15ae12de5abe7087eeab1e0db.wasm", - "vp_token.wasm": "vp_token.4a5436f7519de15c80103557add57e8d06e766e1ec1f7a642ffca252be01c5d0.wasm", - "vp_user.wasm": "vp_user.729b18aab60e8ae09b75b5f067658f30459a5ccfcd34f909b88da96523681019.wasm" + "tx_vote_proposal.wasm": "tx_vote_proposal.206bdcfbf1e640c6f5f665122f96ea55fdd6ee00807aa45d19bfe6e79974c160.wasm", + "tx_withdraw.wasm": "tx_withdraw.66f8393b08b9505a0a4f3dddf9b434052275064ded5745804397cae37eed98df.wasm", + "vp_nft.wasm": "vp_nft.ce4de0794341532b7556605415273bc05768469ba2f49c346616ba61801b6457.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.0cff74823844198fa789ade3da8189bdc83e67f4c306e8b008e00b940305ca39.wasm", + "vp_token.wasm": "vp_token.0d10511e4d46e83b5bbc17544e17e86e2f707dfe955fdeae41ff796a7c2feb3b.wasm", + "vp_user.wasm": "vp_user.4a1204d76987b1362dd61358d45cb2f1b518ef883b1a2321102e7eb78a6796f8.wasm" } \ No newline at end of file diff --git a/wasm/wasm_source/src/tx_bond.rs b/wasm/wasm_source/src/tx_bond.rs index 6718988657a..650d6eb3a16 100644 --- a/wasm/wasm_source/src/tx_bond.rs +++ b/wasm/wasm_source/src/tx_bond.rs @@ -35,9 +35,7 @@ mod tests { use namada_vp_prelude::proof_of_stake::types::{ Bond, VotingPower, VotingPowerDelta, }; - use namada_vp_prelude::proof_of_stake::{ - staking_token_address, BondId, GenesisValidator, PosVP, - }; + use namada_vp_prelude::proof_of_stake::{BondId, GenesisValidator, PosVP}; use proptest::prelude::*; use super::*; @@ -82,14 +80,16 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); - tx_host_env::with(|tx_env| { + let native_token = tx_host_env::with(|tx_env| { if let Some(source) = &bond.source { tx_env.spawn_accounts([source]); } // Ensure that the bond's source has enough tokens for the bond let target = bond.source.as_ref().unwrap_or(&bond.validator); - tx_env.credit_tokens(target, &staking_token_address(), bond.amount); + let native_token = tx_env.storage.native_token.clone(); + tx_env.credit_tokens(target, &native_token, bond.amount); + native_token }); let tx_code = vec![]; @@ -100,7 +100,7 @@ mod tests { // Read the data before the tx is executed let pos_balance_key = token::balance_key( - &staking_token_address(), + &native_token, &Address::Internal(InternalAddress::PoS), ); let pos_balance_pre: token::Amount = ctx() diff --git a/wasm/wasm_source/src/tx_unbond.rs b/wasm/wasm_source/src/tx_unbond.rs index 6199393fb1f..7bbef99372b 100644 --- a/wasm/wasm_source/src/tx_unbond.rs +++ b/wasm/wasm_source/src/tx_unbond.rs @@ -33,9 +33,7 @@ mod tests { use namada_vp_prelude::proof_of_stake::types::{ Bond, Unbond, VotingPower, VotingPowerDelta, }; - use namada_vp_prelude::proof_of_stake::{ - staking_token_address, BondId, GenesisValidator, PosVP, - }; + use namada_vp_prelude::proof_of_stake::{BondId, GenesisValidator, PosVP}; use proptest::prelude::*; use super::*; @@ -87,7 +85,8 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); - tx_host_env::with(|tx_env| { + let native_token = tx_host_env::with(|tx_env| { + let native_token = tx_env.storage.native_token.clone(); if is_delegation { let source = unbond.source.as_ref().unwrap(); tx_env.spawn_accounts([source]); @@ -96,12 +95,9 @@ mod tests { // bond first. // First, credit the bond's source with the initial stake, // before we initialize the bond below - tx_env.credit_tokens( - source, - &staking_token_address(), - initial_stake, - ); + tx_env.credit_tokens(source, &native_token, initial_stake); } + native_token }); if is_delegation { @@ -131,7 +127,7 @@ mod tests { }; let pos_balance_key = token::balance_key( - &staking_token_address(), + &native_token, &Address::Internal(InternalAddress::PoS), ); let pos_balance_pre: token::Amount = ctx() diff --git a/wasm/wasm_source/src/tx_withdraw.rs b/wasm/wasm_source/src/tx_withdraw.rs index 8add20a78d8..cfabee5d998 100644 --- a/wasm/wasm_source/src/tx_withdraw.rs +++ b/wasm/wasm_source/src/tx_withdraw.rs @@ -35,9 +35,7 @@ mod tests { use namada_tx_prelude::key::testing::arb_common_keypair; use namada_tx_prelude::key::RefTo; use namada_tx_prelude::proof_of_stake::parameters::testing::arb_pos_params; - use namada_vp_prelude::proof_of_stake::{ - staking_token_address, BondId, GenesisValidator, PosVP, - }; + use namada_vp_prelude::proof_of_stake::{BondId, GenesisValidator, PosVP}; use proptest::prelude::*; use super::*; @@ -94,7 +92,8 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); - tx_host_env::with(|tx_env| { + let native_token = tx_host_env::with(|tx_env| { + let native_token = tx_env.storage.native_token.clone(); if is_delegation { let source = withdraw.source.as_ref().unwrap(); tx_env.spawn_accounts([source]); @@ -103,12 +102,9 @@ mod tests { // bond first. // First, credit the bond's source with the initial stake, // before we initialize the bond below - tx_env.credit_tokens( - source, - &staking_token_address(), - initial_stake, - ); + tx_env.credit_tokens(source, &native_token, initial_stake); } + native_token }); if is_delegation { @@ -150,7 +146,7 @@ mod tests { // Read data before we apply tx: let pos_balance_key = token::balance_key( - &staking_token_address(), + &native_token, &Address::Internal(InternalAddress::PoS), ); let pos_balance_pre: token::Amount = ctx() diff --git a/wasm/wasm_source/src/vp_testnet_faucet.rs b/wasm/wasm_source/src/vp_testnet_faucet.rs index 9582791565a..35e2dd8fbc1 100644 --- a/wasm/wasm_source/src/vp_testnet_faucet.rs +++ b/wasm/wasm_source/src/vp_testnet_faucet.rs @@ -131,7 +131,7 @@ mod tests { let vp_owner = address::testing::established_address_1(); let source = address::testing::established_address_2(); - let token = address::xan(); + let token = address::nam(); let amount = token::Amount::from(10_098_123); // Spawn the accounts to be able to modify their storage @@ -267,7 +267,7 @@ mod tests { let vp_owner = address::testing::established_address_1(); let target = address::testing::established_address_2(); - let token = address::xan(); + let token = address::nam(); let amount = token::Amount::from(amount); // Spawn the accounts to be able to modify their storage @@ -300,7 +300,7 @@ mod tests { let vp_owner = address::testing::established_address_1(); let target = address::testing::established_address_2(); - let token = address::xan(); + let token = address::nam(); let amount = token::Amount::from(amount); // Spawn the accounts to be able to modify their storage diff --git a/wasm/wasm_source/src/vp_user.rs b/wasm/wasm_source/src/vp_user.rs index 256dc6bb17a..078e5280130 100644 --- a/wasm/wasm_source/src/vp_user.rs +++ b/wasm/wasm_source/src/vp_user.rs @@ -231,7 +231,7 @@ mod tests { let vp_owner = address::testing::established_address_1(); let source = address::testing::established_address_2(); - let token = address::xan(); + let token = address::nam(); let amount = token::Amount::from(10_098_123); // Spawn the accounts to be able to modify their storage @@ -275,7 +275,7 @@ mod tests { let vp_owner = address::testing::established_address_1(); let target = address::testing::established_address_2(); - let token = address::xan(); + let token = address::nam(); let amount = token::Amount::from(10_098_123); // Spawn the accounts to be able to modify their storage @@ -321,7 +321,7 @@ mod tests { let keypair = key::testing::keypair_1(); let public_key = keypair.ref_to(); let target = address::testing::established_address_2(); - let token = address::xan(); + let token = address::nam(); let amount = token::Amount::from(10_098_123); // Spawn the accounts to be able to modify their storage @@ -371,7 +371,7 @@ mod tests { let vp_owner = address::testing::established_address_1(); let source = address::testing::established_address_2(); let target = address::testing::established_address_3(); - let token = address::xan(); + let token = address::nam(); let amount = token::Amount::from(10_098_123); // Spawn the accounts to be able to modify their storage