From e73c499fb014752c464b8c1c7c656be59f7b9fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Sun, 8 Sep 2024 13:43:19 +0200 Subject: [PATCH] fix code using moved tx ctx --- Cargo.lock | 9 + crates/tests/Cargo.toml | 2 +- crates/tests/src/integration/ledger_tests.rs | 10 +- crates/tests/src/lib.rs | 2 +- crates/tests/src/native_vp/eth_bridge_pool.rs | 6 +- crates/tests/src/native_vp/mod.rs | 2 +- crates/tests/src/native_vp/pos.rs | 45 +- .../src/storage_api/collections/lazy_map.rs | 16 +- .../src/storage_api/collections/lazy_set.rs | 16 +- .../src/storage_api/collections/lazy_vec.rs | 16 +- .../collections/nested_lazy_map.rs | 16 +- crates/tests/src/vm_host_env/ibc.rs | 25 +- crates/tests/src/vm_host_env/mod.rs | 327 +++++++------- crates/tests/src/vm_host_env/tx_env.rs | 120 ++++++ crates/tests/src/vm_host_env/vp.rs | 6 +- crates/tx_env/Cargo.toml | 41 ++ crates/tx_env/src/ctx.rs | 405 +++++++++++++++++ crates/tx_env/src/lib.rs | 4 + crates/tx_env/src/testing.rs | 149 ++----- crates/tx_prelude/Cargo.toml | 2 +- crates/tx_prelude/src/ibc.rs | 37 +- crates/tx_prelude/src/lib.rs | 407 +----------------- crates/tx_prelude/src/proof_of_stake.rs | 125 +++++- crates/tx_prelude/src/token.rs | 5 +- crates/vm/src/wasm/mod.rs | 1 + wasm/Cargo.lock | 7 + wasm/tx_become_validator/src/lib.rs | 2 +- wasm/tx_bond/src/lib.rs | 27 +- wasm/tx_change_consensus_key/src/lib.rs | 4 +- .../tx_change_validator_commission/src/lib.rs | 18 +- wasm/tx_change_validator_metadata/src/lib.rs | 4 +- wasm/tx_claim_rewards/src/lib.rs | 2 +- wasm/tx_redelegate/src/lib.rs | 22 +- wasm/tx_unbond/src/lib.rs | 21 +- wasm/tx_update_steward_commission/src/lib.rs | 2 +- wasm/tx_withdraw/src/lib.rs | 27 +- wasm/vp_implicit/src/lib.rs | 64 +-- wasm/vp_user/src/lib.rs | 86 ++-- wasm_for_tests/Cargo.lock | 4 + wasm_for_tests/vp_eval/src/lib.rs | 2 +- 40 files changed, 1138 insertions(+), 948 deletions(-) create mode 100644 crates/tests/src/vm_host_env/tx_env.rs create mode 100644 crates/tx_env/src/ctx.rs diff --git a/Cargo.lock b/Cargo.lock index fbf14cfafd..f591318b08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5602,9 +5602,18 @@ dependencies = [ name = "namada_tx_env" version = "0.43.0" dependencies = [ + "concat-idents", "namada_core", "namada_events", + "namada_gas", + "namada_state", "namada_storage", + "namada_tx", + "namada_vm", + "namada_vm_env", + "proptest", + "tempfile", + "test-log", ] [[package]] diff --git a/crates/tests/Cargo.toml b/crates/tests/Cargo.toml index 92d86abe47..05d632296d 100644 --- a/crates/tests/Cargo.toml +++ b/crates/tests/Cargo.toml @@ -30,7 +30,7 @@ namada-eth-bridge = [ namada_core = {path = "../core", features = ["testing"]} namada_sdk = {path = "../sdk", default-features=false, features = ["download-params", "testing", "wasm-runtime"]} namada_test_utils = {path = "../test_utils"} -namada_tx_env = {path = "../tx_env"} +namada_tx_env = {path = "../tx_env", features = ["testing"]} namada_tx_prelude = {path = "../tx_prelude"} namada_vp = {path = "../vp"} namada_vp_prelude = {path = "../vp_prelude"} diff --git a/crates/tests/src/integration/ledger_tests.rs b/crates/tests/src/integration/ledger_tests.rs index ed34692bb7..598826d707 100644 --- a/crates/tests/src/integration/ledger_tests.rs +++ b/crates/tests/src/integration/ledger_tests.rs @@ -24,6 +24,9 @@ use namada_node::shell::SnapshotSync; use namada_node::storage::DbSnapshot; use namada_sdk::account::AccountPublicKeysMap; use namada_sdk::collections::HashMap; +use namada_sdk::governance::cli::onchain::{PgfFunding, StewardsUpdate}; +use namada_sdk::governance::pgf::cli::steward::Commission; +use namada_sdk::governance::storage::proposal::{PGFInternalTarget, PGFTarget}; use namada_sdk::migrations; use namada_sdk::queries::RPC; use namada_sdk::token::{self, DenominatedAmount}; @@ -46,13 +49,6 @@ use crate::strings::{ TX_APPLIED_SUCCESS, TX_INSUFFICIENT_BALANCE, TX_REJECTED, }; use crate::tendermint::abci::ApplySnapshotChunkResult; -use crate::tx::tx_host_env::gov_storage::proposal::{ - PGFInternalTarget, PGFTarget, -}; -use crate::tx::tx_host_env::governance::cli::onchain::{ - PgfFunding, StewardsUpdate, -}; -use crate::tx::tx_host_env::governance::pgf::cli::steward::Commission; /// In this test we: /// 1. Run the ledger node diff --git a/crates/tests/src/lib.rs b/crates/tests/src/lib.rs index e76a81a430..2a6feba6d3 100644 --- a/crates/tests/src/lib.rs +++ b/crates/tests/src/lib.rs @@ -6,7 +6,7 @@ #![deny(rustdoc::private_intra_doc_links)] mod vm_host_env; -pub use vm_host_env::{tx, vp}; +pub use vm_host_env::{tx_env, vp}; #[cfg(test)] mod e2e; #[cfg(test)] diff --git a/crates/tests/src/native_vp/eth_bridge_pool.rs b/crates/tests/src/native_vp/eth_bridge_pool.rs index 686fadc0c6..87e950627a 100644 --- a/crates/tests/src/native_vp/eth_bridge_pool.rs +++ b/crates/tests/src/native_vp/eth_bridge_pool.rs @@ -26,7 +26,7 @@ mod test_bridge_pool_vp { use namada_tx_prelude::BatchedTx; use crate::native_vp::TestNativeVpEnv; - use crate::tx::{tx_host_env, TestTxEnv}; + use crate::tx_env::{self, TestTxEnv, TestTxEnvExt}; const ASSET: EthAddress = EthAddress([1; 20]); const BERTHA_WEALTH: u64 = 1_000_000; const BERTHA_TOKENS: u64 = 10_000; @@ -110,8 +110,8 @@ mod test_bridge_pool_vp { fn run_vp(tx: BatchedTx) -> bool { let env = setup_env(tx); - tx_host_env::set(env); - let mut tx_env = tx_host_env::take(); + tx_env::set(env); + let mut tx_env = tx_env::take(); tx_env.execute_tx().expect("Test failed."); let gas_meter = RefCell::new(VpGasMeter::new_from_tx_meter( &tx_env.gas_meter.borrow(), diff --git a/crates/tests/src/native_vp/mod.rs b/crates/tests/src/native_vp/mod.rs index 677c3827ae..4fe31bab45 100644 --- a/crates/tests/src/native_vp/mod.rs +++ b/crates/tests/src/native_vp/mod.rs @@ -14,7 +14,7 @@ use namada_vm::wasm::VpCache; use namada_vm::WasmCacheRwAccess; use namada_vp::native_vp::{self, Ctx, NativeVp}; -use crate::tx::TestTxEnv; +use crate::tx_env::TestTxEnv; type NativeVpCtx<'a> = Ctx< 'a, diff --git a/crates/tests/src/native_vp/pos.rs b/crates/tests/src/native_vp/pos.rs index 4244e456dc..007ea82e97 100644 --- a/crates/tests/src/native_vp/pos.rs +++ b/crates/tests/src/native_vp/pos.rs @@ -100,7 +100,8 @@ use namada_sdk::proof_of_stake::parameters::{OwnedPosParams, PosParams}; use namada_sdk::proof_of_stake::test_utils::test_init_genesis as init_genesis; use namada_sdk::proof_of_stake::types::GenesisValidator; -use crate::tx::tx_host_env; +use crate::tx_env; +use crate::tx_env::TestTxEnvExt; /// initialize proof-of-stake genesis with the given list of validators and /// parameters. @@ -109,9 +110,9 @@ pub fn init_pos( params: &OwnedPosParams, start_epoch: Epoch, ) -> PosParams { - tx_host_env::init(); + tx_env::init(); - tx_host_env::with(|tx_env| { + tx_env::with(|tx_env| { // Ensure that all the used // addresses exist let native_token = tx_env.state.in_mem().native_token.clone(); @@ -255,7 +256,7 @@ mod tests { change.clone().apply(true) } // Commit the genesis block - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); Self { // we only generate and apply valid actions in the initial state @@ -272,19 +273,19 @@ mod tests { Transition::CommitTx => { if !test_state.is_current_tx_valid { // Clear out the changes - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.drop_tx_batch(); }); } // Commit the last transaction(s) changes, if any - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); // Starting a new tx test_state.is_current_tx_valid = true; } Transition::NextEpoch => { - tx_host_env::with(|env| { + tx_env::with(|env| { // Clear out the changes if !test_state.is_current_tx_valid { env.state.drop_tx_batch(); @@ -322,7 +323,7 @@ mod tests { test_state.validate_transitions(); // Clear out the invalid changes - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.drop_tx_batch(); }) } @@ -443,7 +444,7 @@ mod tests { impl ConcretePosState { fn validate_transitions(&self) { // Use the tx_env to run PoS VP - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); let gas_meter = RefCell::new(VpGasMeter::new_from_tx_meter( &tx_env.gas_meter.borrow(), @@ -453,7 +454,7 @@ mod tests { let result = vp_env.validate_tx(&vp); // Put the tx_env back before checking the result - tx_host_env::set(vp_env.tx_env); + tx_env::set(vp_env.tx_env); // The expected result depends on the current state match (self.is_current_tx_valid, result) { @@ -608,7 +609,7 @@ pub mod testing { use namada_tx_prelude::{Address, StorageRead, StorageWrite}; use proptest::prelude::*; - use crate::tx::{self, tx_host_env}; + use crate::tx_env; #[derive(Clone, Debug, Default)] pub struct TestValidator { @@ -872,9 +873,10 @@ pub mod testing { pub fn apply(self, is_current_tx_valid: bool) { // Read the PoS parameters let params = - read_pos_params::<_, governance::Store<_>>(tx::ctx()).unwrap(); + read_pos_params::<_, governance::Store<_>>(tx_env::ctx()) + .unwrap(); - let current_epoch = tx_host_env::with(|env| { + let current_epoch = tx_env::with(|env| { // Reset the gas meter on each change, so that we never run // out in this test let gas_limit = env.gas_meter.borrow().tx_gas_limit; @@ -1079,7 +1081,7 @@ pub mod testing { ) { match change { PosStorageChange::SpawnAccount { address } => { - tx_host_env::with(move |env| { + tx_env::with(move |env| { env.spawn_accounts([&address]); }); } @@ -1331,11 +1333,13 @@ pub mod testing { } PosStorageChange::StakingTokenPosBalance { delta } => { let balance_key = token::storage_key::balance_key( - &tx::ctx().get_native_token().unwrap(), + &tx_env::ctx().get_native_token().unwrap(), &POS_ADDRESS, ); - let mut balance: token::Amount = - tx::ctx().read(&balance_key).unwrap().unwrap_or_default(); + let mut balance: token::Amount = tx_env::ctx() + .read(&balance_key) + .unwrap() + .unwrap_or_default(); if !delta.non_negative() { let to_spend = token::Amount::from_change(delta); balance.spend(&to_spend).unwrap(); @@ -1343,7 +1347,7 @@ pub mod testing { let to_recv = token::Amount::from_change(delta); balance.receive(&to_recv).unwrap(); } - tx::ctx().write(&balance_key, balance).unwrap(); + tx_env::ctx().write(&balance_key, balance).unwrap(); } PosStorageChange::WithdrawUnbond { owner: _, @@ -1587,7 +1591,8 @@ pub mod testing { pub fn apply(self) { // Read the PoS parameters let params = - read_pos_params::<_, governance::Store<_>>(tx::ctx()).unwrap(); + read_pos_params::<_, governance::Store<_>>(tx_env::ctx()) + .unwrap(); for (epoch, changes) in self.changes { for change in changes { @@ -1603,7 +1608,7 @@ pub mod testing { current_epoch: Epoch, ) -> bool { let num_consensus_validators = - get_num_consensus_validators(tx::ctx(), current_epoch).unwrap(); + get_num_consensus_validators(tx_env::ctx(), current_epoch).unwrap(); params.max_validator_slots > num_consensus_validators } } diff --git a/crates/tests/src/storage_api/collections/lazy_map.rs b/crates/tests/src/storage_api/collections/lazy_map.rs index a9b1941177..d71d3b975a 100644 --- a/crates/tests/src/storage_api/collections/lazy_map.rs +++ b/crates/tests/src/storage_api/collections/lazy_map.rs @@ -15,7 +15,7 @@ mod tests { }; use test_log::test; - use crate::tx::tx_host_env; + use crate::tx_env; use crate::vp::vp_host_env; prop_state_machine! { @@ -200,12 +200,12 @@ mod tests { _initial_state: &::State, ) -> Self::SystemUnderTest { // Init transaction env in which we'll be applying the transitions - tx_host_env::init(); + tx_env::init(); // The lazy_map's path must be prefixed by the address to be able // to trigger a validity predicate on it let address = address::testing::established_address_1(); - tx_host_env::with(|env| env.spawn_accounts([&address])); + tx_env::with(|env| env.spawn_accounts([&address])); let lazy_map_prefix: storage::Key = address.to_db_key().into(); Self { @@ -224,7 +224,7 @@ mod tests { transition: ::Transition, ) -> Self::SystemUnderTest { // Apply transitions in transaction env - let ctx = tx_host_env::ctx(); + let ctx = tx_env::ctx(); // Persist the transitions in the current tx, or clear previous ones // if we're committing a tx @@ -241,11 +241,11 @@ mod tests { match &transition { Transition::CommitTx => { // commit the tx without committing the block - tx_host_env::with(|env| env.state.commit_tx_batch()); + tx_env::with(|env| env.state.commit_tx_batch()); } Transition::CommitTxAndBlock => { // commit the tx and the block - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); } Transition::Insert(key, value) => { state.lazy_map.insert(ctx, *key, value.clone()).unwrap(); @@ -380,7 +380,7 @@ mod tests { fn assert_validation_accepted(&self) { // Init the VP env from tx env in which we applied the map // transitions - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); vp_host_env::init_from_tx(self.address.clone(), tx_env, |_| {}); // Simulate a validity predicate run using the lazy map's validation @@ -497,7 +497,7 @@ mod tests { } // Put the tx_env back before checking the result - tx_host_env::set_from_vp_env(vp_host_env::take()); + tx_env::set_from_vp_env(vp_host_env::take()); } } diff --git a/crates/tests/src/storage_api/collections/lazy_set.rs b/crates/tests/src/storage_api/collections/lazy_set.rs index b00a273fdb..ccbcc62af8 100644 --- a/crates/tests/src/storage_api/collections/lazy_set.rs +++ b/crates/tests/src/storage_api/collections/lazy_set.rs @@ -14,7 +14,7 @@ mod tests { }; use test_log::test; - use crate::tx::tx_host_env; + use crate::tx_env; use crate::vp::vp_host_env; prop_state_machine! { @@ -188,12 +188,12 @@ mod tests { _initial_state: &::State, ) -> Self::SystemUnderTest { // Init transaction env in which we'll be applying the transitions - tx_host_env::init(); + tx_env::init(); // The lazy_set's path must be prefixed by the address to be able // to trigger a validity predicate on it let address = address::testing::established_address_1(); - tx_host_env::with(|env| env.spawn_accounts([&address])); + tx_env::with(|env| env.spawn_accounts([&address])); let lazy_set_prefix: storage::Key = address.to_db_key().into(); Self { @@ -212,7 +212,7 @@ mod tests { transition: ::Transition, ) -> Self::SystemUnderTest { // Apply transitions in transaction env - let ctx = tx_host_env::ctx(); + let ctx = tx_env::ctx(); // Persist the transitions in the current tx, or clear previous ones // if we're committing a tx @@ -229,11 +229,11 @@ mod tests { match &transition { Transition::CommitTx => { // commit the tx without committing the block - tx_host_env::with(|env| env.state.commit_tx_batch()); + tx_env::with(|env| env.state.commit_tx_batch()); } Transition::CommitTxAndBlock => { // commit the tx and the block - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); } Transition::Insert(key) => { state.lazy_set.insert(ctx, *key).unwrap(); @@ -343,7 +343,7 @@ mod tests { fn assert_validation_accepted(&self) { // Init the VP env from tx env in which we applied the set // transitions - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); vp_host_env::init_from_tx(self.address.clone(), tx_env, |_| {}); // Simulate a validity predicate run using the lazy set's validation @@ -460,7 +460,7 @@ mod tests { } // Put the tx_env back before checking the result - tx_host_env::set_from_vp_env(vp_host_env::take()); + tx_env::set_from_vp_env(vp_host_env::take()); } } diff --git a/crates/tests/src/storage_api/collections/lazy_vec.rs b/crates/tests/src/storage_api/collections/lazy_vec.rs index 8bbf51ca9c..337f895c71 100644 --- a/crates/tests/src/storage_api/collections/lazy_vec.rs +++ b/crates/tests/src/storage_api/collections/lazy_vec.rs @@ -14,7 +14,7 @@ mod tests { }; use test_log::test; - use crate::tx::tx_host_env; + use crate::tx_env; use crate::vp::vp_host_env; prop_state_machine! { @@ -193,12 +193,12 @@ mod tests { _initial_state: &::State, ) -> Self::SystemUnderTest { // Init transaction env in which we'll be applying the transitions - tx_host_env::init(); + tx_env::init(); // The lazy_vec's path must be prefixed by the address to be able // to trigger a validity predicate on it let address = address::testing::established_address_1(); - tx_host_env::with(|env| env.spawn_accounts([&address])); + tx_env::with(|env| env.spawn_accounts([&address])); let lazy_vec_prefix: storage::Key = address.to_db_key().into(); Self { @@ -217,7 +217,7 @@ mod tests { transition: ::Transition, ) -> Self::SystemUnderTest { // Apply transitions in transaction env - let ctx = tx_host_env::ctx(); + let ctx = tx_env::ctx(); // Persist the transitions in the current tx, or clear previous ones // if we're committing a tx @@ -234,11 +234,11 @@ mod tests { match &transition { Transition::CommitTx => { // commit the tx without committing the block - tx_host_env::with(|env| env.state.commit_tx_batch()); + tx_env::with(|env| env.state.commit_tx_batch()); } Transition::CommitTxAndBlock => { // commit the tx and the block - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); } Transition::Push(value) => { let old_len = state.lazy_vec.len(ctx).unwrap(); @@ -369,7 +369,7 @@ mod tests { fn assert_validation_accepted(&self, new_vec_len: u64) { // Init the VP env from tx env in which we applied the vec // transitions - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); vp_host_env::init_from_tx(self.address.clone(), tx_env, |_| {}); // Simulate a validity predicate run using the lazy vec's validation @@ -496,7 +496,7 @@ mod tests { } // Put the tx_env back before checking the result - tx_host_env::set_from_vp_env(vp_host_env::take()); + tx_env::set_from_vp_env(vp_host_env::take()); } } diff --git a/crates/tests/src/storage_api/collections/nested_lazy_map.rs b/crates/tests/src/storage_api/collections/nested_lazy_map.rs index 82159ce23f..475d3a8669 100644 --- a/crates/tests/src/storage_api/collections/nested_lazy_map.rs +++ b/crates/tests/src/storage_api/collections/nested_lazy_map.rs @@ -18,7 +18,7 @@ mod tests { }; use test_log::test; - use crate::tx::tx_host_env; + use crate::tx_env; use crate::vp::vp_host_env; prop_state_machine! { @@ -213,12 +213,12 @@ mod tests { _initial_state: &::State, ) -> Self::SystemUnderTest { // Init transaction env in which we'll be applying the transitions - tx_host_env::init(); + tx_env::init(); // The lazy_map's path must be prefixed by the address to be able // to trigger a validity predicate on it let address = address::testing::established_address_1(); - tx_host_env::with(|env| env.spawn_accounts([&address])); + tx_env::with(|env| env.spawn_accounts([&address])); let lazy_map_prefix: storage::Key = address.to_db_key().into(); Self { @@ -237,7 +237,7 @@ mod tests { transition: ::Transition, ) -> Self::SystemUnderTest { // Apply transitions in transaction env - let ctx = tx_host_env::ctx(); + let ctx = tx_env::ctx(); // Persist the transitions in the current tx, or clear previous ones // if we're committing a tx @@ -254,11 +254,11 @@ mod tests { match &transition { Transition::CommitTx => { // commit the tx without committing the block - tx_host_env::with(|env| env.state.commit_tx_batch()); + tx_env::with(|env| env.state.commit_tx_batch()); } Transition::CommitTxAndBlock => { // commit the tx and the block - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); } Transition::Insert( (key_outer, key_middle, key_inner), @@ -461,7 +461,7 @@ mod tests { fn assert_validation_accepted(&self) { // Init the VP env from tx env in which we applied the map // transitions - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); vp_host_env::init_from_tx(self.address.clone(), tx_env, |_| {}); // Simulate a validity predicate run using the lazy map's validation @@ -608,7 +608,7 @@ mod tests { } // Put the tx_env back before checking the result - tx_host_env::set_from_vp_env(vp_host_env::take()); + tx_env::set_from_vp_env(vp_host_env::take()); } } diff --git a/crates/tests/src/vm_host_env/ibc.rs b/crates/tests/src/vm_host_env/ibc.rs index b11526f0b7..7d5106493f 100644 --- a/crates/tests/src/vm_host_env/ibc.rs +++ b/crates/tests/src/vm_host_env/ibc.rs @@ -81,7 +81,8 @@ use namada_vm::{wasm, WasmCacheRwAccess}; use namada_vp::native_vp; use namada_vp::native_vp::{Ctx, NativeVp}; -use crate::tx::*; +use super::tx_env; +use crate::tx_env::*; const ADDRESS: Address = Address::Internal(InternalAddress::Ibc); pub const ANY_DENOMINATION: u8 = token::NATIVE_MAX_DECIMAL_PLACES; @@ -191,13 +192,13 @@ pub fn validate_multitoken_vp_from_tx<'a>( TestMultitokenVp { multitoken_vp }.validate(batched_tx) } -/// Initialize the test storage. Requires initialized [`tx_host_env::ENV`]. +/// Initialize the test storage. Requires initialized [`tx_env::ENV`]. pub fn init_storage() -> (Address, Address) { // wasm for init_account let code = TestWasms::VpAlwaysTrue.read_bytes(); let code_hash = Hash::sha256(&code); - tx_host_env::with(|env| { + tx_env::with(|env| { namada_sdk::parameters::init_test_storage(&mut env.state).unwrap(); ibc::init_genesis_storage(&mut env.state); let gov_params = GovernanceParameters::default(); @@ -235,18 +236,14 @@ pub fn init_storage() -> (Address, Address) { }); // initialize a token - let token = tx_host_env::ctx() - .init_account(code_hash, &None, &[]) - .unwrap(); + let token = tx_env::ctx().init_account(code_hash, &None, &[]).unwrap(); let denom_key = token::storage_key::denom_key(&token); let token_denom = token::Denomination(ANY_DENOMINATION); // initialize an account - let account = tx_host_env::ctx() - .init_account(code_hash, &None, &[]) - .unwrap(); + let account = tx_env::ctx().init_account(code_hash, &None, &[]).unwrap(); let key = token::storage_key::balance_key(&token, &account); let init_bal = token::Amount::from_uint(100, token_denom).unwrap(); - tx_host_env::with(|env| { + tx_env::with(|env| { env.state .db_write(&denom_key, &token_denom.serialize_to_vec()) .unwrap(); @@ -262,12 +259,12 @@ pub fn init_storage() -> (Address, Address) { min_duration: DurationSecs(100), }; let bytes = epoch_duration.serialize_to_vec(); - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.db_write(&key, &bytes).unwrap(); }); // commit the initialized token and account - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.commit_tx_batch(); env.state.commit_block().unwrap(); @@ -302,7 +299,7 @@ pub fn prepare_client() -> (ClientId, Any, HashMap>) { writes.insert(key, bytes); // client update time let key = client_update_timestamp_key(&client_id); - let time = tx_host_env::with(|env| { + let time = tx_env::with(|env| { let header = StateRead::get_block_header(&env.state, None) .unwrap() .0 @@ -313,7 +310,7 @@ pub fn prepare_client() -> (ClientId, Any, HashMap>) { writes.insert(key, bytes); // client update height let key = client_update_height_key(&client_id); - let height = tx_host_env::with(|env| { + let height = tx_env::with(|env| { let height = env.state.in_mem().get_block_height().0; Height::new(0, height.0).expect("invalid height") }); diff --git a/crates/tests/src/vm_host_env/mod.rs b/crates/tests/src/vm_host_env/mod.rs index 4e6aa6fd64..bc8d96f5d9 100644 --- a/crates/tests/src/vm_host_env/mod.rs +++ b/crates/tests/src/vm_host_env/mod.rs @@ -13,7 +13,7 @@ #[cfg(test)] pub mod ibc; -pub mod tx; +pub mod tx_env; pub mod vp; #[cfg(test)] @@ -49,17 +49,17 @@ mod tests { use prost::Message; use test_log::test; - use super::{ibc, tx, vp}; - use crate::tx::{tx_host_env, TestTxEnv}; + use super::{ibc, vp}; + use crate::tx_env::{self, TestTxEnv, TestTxEnvExt}; use crate::vp::{vp_host_env, TestVpEnv}; #[test] fn test_tx_read_write() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let key = storage::Key::parse("key").unwrap(); - let read_value: Option = tx::ctx().read(&key).unwrap(); + let read_value: Option = tx_env::ctx().read(&key).unwrap(); assert_eq!( None, read_value, "Trying to read a key that doesn't exists shouldn't find any value" @@ -67,9 +67,9 @@ mod tests { // Write some value let value = "test".repeat(4); - tx::ctx().write(&key, value.clone()).unwrap(); + tx_env::ctx().write(&key, value.clone()).unwrap(); - let read_value: Option = tx::ctx().read(&key).unwrap(); + let read_value: Option = tx_env::ctx().read(&key).unwrap(); assert_eq!( Some(value), read_value, @@ -78,8 +78,8 @@ mod tests { ); let value = vec![1_u8; 1000]; - tx::ctx().write(&key, value.clone()).unwrap(); - let read_value: Option> = tx::ctx().read(&key).unwrap(); + tx_env::ctx().write(&key, value.clone()).unwrap(); + let read_value: Option> = tx_env::ctx().read(&key).unwrap(); assert_eq!( Some(value), read_value, @@ -90,20 +90,20 @@ mod tests { #[test] fn test_tx_has_key() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let key = storage::Key::parse("key").unwrap(); assert!( - !tx::ctx().has_key(&key).unwrap(), + !tx_env::ctx().has_key(&key).unwrap(), "Before a key-value is written, its key shouldn't be found" ); // Write some value let value = "test".to_string(); - tx::ctx().write(&key, value).unwrap(); + tx_env::ctx().write(&key, value).unwrap(); assert!( - tx::ctx().has_key(&key).unwrap(), + tx_env::ctx().has_key(&key).unwrap(), "After a key-value has been written, its key should be found" ); } @@ -114,31 +114,31 @@ mod tests { let mut env = TestTxEnv::default(); let test_account = address::testing::established_address_1(); env.spawn_accounts([&test_account]); - tx_host_env::set(env); + tx_env::set(env); // Trying to delete a key that doesn't exists should be a no-op let key = storage::Key::parse("key").unwrap(); - tx::ctx().delete(&key).unwrap(); + tx_env::ctx().delete(&key).unwrap(); let value = "test".to_string(); - tx::ctx().write(&key, value).unwrap(); + tx_env::ctx().write(&key, value).unwrap(); assert!( - tx::ctx().has_key(&key).unwrap(), + tx_env::ctx().has_key(&key).unwrap(), "After a key-value has been written, its key should be found" ); // Then delete it - tx::ctx().delete(&key).unwrap(); + tx_env::ctx().delete(&key).unwrap(); assert!( - !tx::ctx().has_key(&key).unwrap(), + !tx_env::ctx().has_key(&key).unwrap(), "After a key has been deleted, its key shouldn't be found" ); // Trying to delete a validity predicate should fail let key = storage::Key::validity_predicate(&test_account); assert!( - panic::catch_unwind(|| { tx::ctx().delete(&key).unwrap() }) + panic::catch_unwind(|| { tx_env::ctx().delete(&key).unwrap() }) .err() .map(|a| a.downcast_ref::().cloned().unwrap()) .unwrap() @@ -149,11 +149,11 @@ mod tests { #[test] fn test_tx_iter_prefix() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let empty_key = storage::Key::parse("empty").unwrap(); let mut iter = - namada_tx_prelude::iter_prefix_bytes(tx::ctx(), &empty_key) + namada_tx_prelude::iter_prefix_bytes(tx_env::ctx(), &empty_key) .unwrap(); assert!( iter.next().is_none(), @@ -166,7 +166,7 @@ mod tests { let sub_keys = [2_i32, 1, i32::MAX, -1, 260, -2, i32::MIN, 5, 0]; // Write the values directly into the storage first - tx_host_env::with(|env| { + tx_env::with(|env| { for i in sub_keys.iter() { let key = prefix.push(i).unwrap(); env.state.write(&key, i).unwrap(); @@ -174,7 +174,7 @@ mod tests { }); // Then try to iterate over their prefix - let iter = namada_tx_prelude::iter_prefix(tx::ctx(), &prefix) + let iter = namada_tx_prelude::iter_prefix(tx_env::ctx(), &prefix) .unwrap() .map(Result::unwrap); @@ -189,20 +189,20 @@ mod tests { #[test] fn test_tx_insert_verifier() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); assert!( - tx_host_env::with(|env| env.verifiers.is_empty()), + tx_env::with(|env| env.verifiers.is_empty()), "pre-condition" ); let verifier = address::testing::established_address_1(); - tx::ctx().insert_verifier(&verifier).unwrap(); + tx_env::ctx().insert_verifier(&verifier).unwrap(); assert!( - tx_host_env::with(|env| env.verifiers.contains(&verifier)), + tx_env::with(|env| env.verifiers.contains(&verifier)), "The verifier should have been inserted" ); assert_eq!( - tx_host_env::with(|env| env.verifiers.len()), + tx_env::with(|env| env.verifiers.len()), 1, "There should be only one verifier inserted" ); @@ -212,25 +212,25 @@ mod tests { #[should_panic] fn test_tx_init_account_with_invalid_vp() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let code = vec![]; - tx::ctx().init_account(code, &None, &[]).unwrap(); + tx_env::ctx().init_account(code, &None, &[]).unwrap(); } #[test] fn test_tx_init_account_with_valid_vp() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let code = TestWasms::VpAlwaysTrue.read_bytes(); let code_hash = Hash::sha256(&code); - tx_host_env::with(|env| { + tx_env::with(|env| { // store wasm code let key = Key::wasm_code(&code_hash); env.state.write(&key, &code).unwrap(); }); - tx::ctx().init_account(code_hash, &None, &[]).unwrap(); + tx_env::ctx().init_account(code_hash, &None, &[]).unwrap(); } /// Test that a tx updating validity predicate that is not in the allowlist @@ -239,7 +239,7 @@ mod tests { #[should_panic = "DisallowedVp"] fn test_tx_update_vp_not_allowed_rejected() { // Initialize a tx environment - tx_host_env::init(); + tx_env::init(); let vp_owner = address::testing::established_address_1(); let keypair = key::testing::keypair_1(); @@ -247,7 +247,7 @@ mod tests { let vp_code = TestWasms::VpAlwaysTrue.read_bytes(); let vp_hash = sha256(&vp_code); - tx_host_env::with(|tx_env| { + tx_env::with(|tx_env| { // let mut tx_env = TestTxEnv::default(); tx_env.init_parameters( None, @@ -262,7 +262,7 @@ mod tests { // Update VP in a transaction. // Panics only due to unwrap in `native_host_fn!` test macro - tx::ctx() + tx_env::ctx() .update_validity_predicate(&vp_owner, vp_hash, &None) .unwrap() } @@ -273,7 +273,7 @@ mod tests { #[should_panic = "DisallowedVp"] fn test_tx_write_vp_not_allowed_rejected() { // Initialize a tx environment - tx_host_env::init(); + tx_env::init(); let vp_owner = address::testing::established_address_1(); let keypair = key::testing::keypair_1(); @@ -281,7 +281,7 @@ mod tests { let vp_code = TestWasms::VpAlwaysTrue.read_bytes(); let vp_hash = sha256(&vp_code); - tx_host_env::with(|tx_env| { + tx_env::with(|tx_env| { // let mut tx_env = TestTxEnv::default(); tx_env.init_parameters( None, @@ -296,7 +296,7 @@ mod tests { // Writing the VP to storage directly should fail let vp_key = Key::validity_predicate(&vp_owner); - tx::ctx().write(&vp_key, vp_hash).unwrap(); + tx_env::ctx().write(&vp_key, vp_hash).unwrap(); } /// Test that a tx initializing a new account with validity predicate that @@ -305,7 +305,7 @@ mod tests { #[should_panic = "DisallowedVp"] fn test_tx_init_vp_not_allowed_rejected() { // Initialize a tx environment - tx_host_env::init(); + tx_env::init(); let vp_owner = address::testing::established_address_1(); let keypair = key::testing::keypair_1(); @@ -313,7 +313,7 @@ mod tests { let vp_code = TestWasms::VpAlwaysTrue.read_bytes(); let vp_hash = sha256(&vp_code); - tx_host_env::with(|tx_env| { + tx_env::with(|tx_env| { // let mut tx_env = TestTxEnv::default(); tx_env.init_parameters( None, @@ -327,40 +327,39 @@ mod tests { }); // Initializing a new account with the VP should fail - tx::ctx().init_account(vp_hash, &None, &[]).unwrap(); + tx_env::ctx().init_account(vp_hash, &None, &[]).unwrap(); } #[test] fn test_tx_get_metadata() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); assert_eq!( - tx::ctx().get_chain_id().unwrap(), - tx_host_env::with(|env| env.state.in_mem().get_chain_id().0) + tx_env::ctx().get_chain_id().unwrap(), + tx_env::with(|env| env.state.in_mem().get_chain_id().0) ); assert_eq!( - tx::ctx().get_block_height().unwrap(), - tx_host_env::with(|env| env.state.in_mem().get_block_height().0) + tx_env::ctx().get_block_height().unwrap(), + tx_env::with(|env| env.state.in_mem().get_block_height().0) ); assert_eq!( - tx::ctx().get_block_epoch().unwrap(), - tx_host_env::with(|env| env.state.in_mem().get_current_epoch().0) + tx_env::ctx().get_block_epoch().unwrap(), + tx_env::with(|env| env.state.in_mem().get_current_epoch().0) ); assert_eq!( - tx::ctx().get_native_token().unwrap(), - tx_host_env::with(|env| env.state.in_mem().native_token.clone()) + tx_env::ctx().get_native_token().unwrap(), + tx_env::with(|env| env.state.in_mem().native_token.clone()) ); } #[test] fn test_tx_get_pred_epochs() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); - let pred_epochs = tx::ctx().get_pred_epochs().unwrap(); - let expected = - tx_host_env::take().state.in_mem().block.pred_epochs.clone(); + let pred_epochs = tx_env::ctx().get_pred_epochs().unwrap(); + let expected = tx_env::take().state.in_mem().block.pred_epochs.clone(); assert_eq!(expected, pred_epochs); } @@ -372,7 +371,7 @@ mod tests { let key = storage::Key::from(addr.to_db_key()); // We can write some data from a transaction vp_host_env::init_from_tx(addr, TestTxEnv::default(), |_addr| { - tx::ctx().write(&key, &value).unwrap(); + tx_env::ctx().write(&key, &value).unwrap(); }); let read_pre_value: Option = vp::CTX.read_pre(&key).unwrap(); @@ -405,10 +404,10 @@ mod tests { // Initialize the VP environment via a transaction vp_host_env::init_from_tx(addr, tx_env, |_addr| { // Override the existing key - tx::ctx().write(&existing_key, &override_value).unwrap(); + tx_env::ctx().write(&existing_key, &override_value).unwrap(); // Write the new key-value - tx::ctx().write(&new_key, new_value.clone()).unwrap(); + tx_env::ctx().write(&new_key, new_value.clone()).unwrap(); }); assert!( @@ -490,10 +489,10 @@ mod tests { // Initialize the VP environment via a transaction vp_host_env::init_from_tx(addr, tx_env, |_addr| { // Override one of the existing keys - tx::ctx().write(&existing_key, 100_i32).unwrap(); + tx_env::ctx().write(&existing_key, 100_i32).unwrap(); // Write the new key-value under the same prefix - tx::ctx().write(&new_key, 11_i32).unwrap(); + tx_env::ctx().write(&new_key, 11_i32).unwrap(); }); let ctx_pre = vp::CTX.pre(); @@ -676,7 +675,7 @@ mod tests { #[test] fn test_ibc_client() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); ibc::init_storage(); let keypair = key::testing::keypair_1(); @@ -696,12 +695,12 @@ mod tests { .sign_wrapper(keypair.clone()); // create a client with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("creating a client failed"); // Check - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -718,7 +717,7 @@ mod tests { .unwrap(); // Start a transaction to update the client - tx_host_env::set(env); + tx_env::set(env); let client_id = ibc::client_id(); let msg = ibc::msg_update_client(client_id); let mut tx_data = vec![]; @@ -729,12 +728,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // update the client with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("updating a client failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -745,7 +744,7 @@ mod tests { #[test] fn test_ibc_connection_init_and_open() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -757,7 +756,7 @@ mod tests { ibc::init_storage(); let (client_id, client_state, writes) = ibc::prepare_client(); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -772,12 +771,12 @@ mod tests { .sign_raw(keypairs.clone(), pks_map.clone(), None) .sign_wrapper(keypair.clone()); // init a connection with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("creating a connection failed"); // Check - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -792,7 +791,7 @@ mod tests { .in_mem_mut() .set_header(get_dummy_header()) .unwrap(); - tx_host_env::set(env); + tx_env::set(env); // Start the next transaction for ConnectionOpenAck let conn_id = ibc::ConnectionId::new(0); @@ -805,12 +804,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // open the connection with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("opening the connection failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -821,7 +820,7 @@ mod tests { #[test] fn test_ibc_connection_try_and_open() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); // Set the initial state before starting transactions ibc::init_storage(); @@ -834,7 +833,7 @@ mod tests { let (client_id, client_state, writes) = ibc::prepare_client(); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }) }); @@ -849,12 +848,12 @@ mod tests { .sign_raw(keypairs.clone(), pks_map.clone(), None) .sign_wrapper(keypair.clone()); // open try a connection with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("creating a connection failed"); // Check - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -869,7 +868,7 @@ mod tests { .in_mem_mut() .set_header(get_dummy_header()) .unwrap(); - tx_host_env::set(env); + tx_env::set(env); // Start the next transaction for ConnectionOpenConfirm let conn_id = ibc::ConnectionId::new(0); @@ -882,12 +881,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // open the connection with the mssage - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("opening the connection failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -898,7 +897,7 @@ mod tests { #[test] fn test_ibc_channel_init_and_open() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -912,7 +911,7 @@ mod tests { let (conn_id, conn_writes) = ibc::prepare_opened_connection(&client_id); writes.extend(conn_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -928,12 +927,12 @@ mod tests { .sign_raw(keypairs.clone(), pks_map.clone(), None) .sign_wrapper(keypair.clone()); // init a channel with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("creating a channel failed"); // Check - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -948,7 +947,7 @@ mod tests { .in_mem_mut() .set_header(get_dummy_header()) .unwrap(); - tx_host_env::set(env); + tx_env::set(env); // Start the next transaction for ChannelOpenAck let channel_id = ibc::ChannelId::new(0); @@ -961,12 +960,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // open the channel with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("opening the channel failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -977,7 +976,7 @@ mod tests { #[test] fn test_ibc_channel_try_and_open() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); // Set the initial state before starting transactions ibc::init_storage(); @@ -985,7 +984,7 @@ mod tests { let (conn_id, conn_writes) = ibc::prepare_opened_connection(&client_id); writes.extend(conn_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1007,12 +1006,12 @@ mod tests { .sign_raw(keypairs.clone(), pks_map.clone(), None) .sign_wrapper(keypair.clone()); // try open a channel with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("creating a channel failed"); // Check - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1027,7 +1026,7 @@ mod tests { .in_mem_mut() .set_header(get_dummy_header()) .unwrap(); - tx_host_env::set(env); + tx_env::set(env); // Start the next transaction for ChannelOpenConfirm let channel_id = ibc::ChannelId::new(0); @@ -1041,12 +1040,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // open a channel with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("opening the channel failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1057,7 +1056,7 @@ mod tests { #[test] fn test_ibc_channel_close_init_fail() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); // Set the initial state before starting transactions ibc::init_storage(); @@ -1068,7 +1067,7 @@ mod tests { ibc::prepare_opened_channel(&conn_id, true); writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1090,7 +1089,7 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // close the channel with the message - let mut actions = tx_host_env::ibc::ibc_actions(tx::ctx()); + let mut actions = tx_env::ibc::ibc_actions(tx_env::ctx()); // the dummy module closes the channel let dummy_module = DummyTransferModule {}; actions.add_transfer_module(dummy_module); @@ -1101,7 +1100,7 @@ mod tests { .expect("closing the channel failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1118,7 +1117,7 @@ mod tests { #[test] fn test_ibc_channel_close_confirm() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); // Set the initial state before starting transactions ibc::init_storage(); @@ -1129,7 +1128,7 @@ mod tests { ibc::prepare_opened_channel(&conn_id, true); writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1152,12 +1151,12 @@ mod tests { .sign_wrapper(keypair); // close the channel with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("closing the channel failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1168,7 +1167,7 @@ mod tests { #[test] fn test_ibc_send_token() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); // Set the initial state before starting transactions let (token, sender) = ibc::init_storage(); @@ -1179,7 +1178,7 @@ mod tests { ibc::prepare_opened_channel(&conn_id, false); writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1201,12 +1200,12 @@ mod tests { .sign_raw(keypairs.clone(), pks_map.clone(), None) .sign_wrapper(keypair.clone()); // send the token and a packet with the data - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("sending a token failed"); // Check - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1232,7 +1231,7 @@ mod tests { .in_mem_mut() .set_header(get_dummy_header()) .unwrap(); - tx_host_env::set(env); + tx_env::set(env); // Start the next transaction for receiving an ack let counterparty = ibc::dummy_channel_counterparty(); @@ -1251,21 +1250,21 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // ack the packet with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("ack failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), ); assert!(result.is_ok()); // Check the balance - tx_host_env::set(env); + tx_env::set(env); let balance_key = token::storage_key::balance_key(&token, &sender); - let balance: Option = tx_host_env::with(|env| { + let balance: Option = tx_env::with(|env| { env.state.read(&balance_key).expect("read error") }); assert_eq!( @@ -1276,7 +1275,7 @@ mod tests { &token, &address::Address::Internal(address::InternalAddress::Ibc), ); - let escrow: Option = tx_host_env::with(|env| { + let escrow: Option = tx_env::with(|env| { env.state.read(&escrow_key).expect("read error") }); assert_eq!( @@ -1288,7 +1287,7 @@ mod tests { #[test] fn test_ibc_burn_token() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -1322,7 +1321,7 @@ mod tests { writes.insert(mint_amount_key, init_bal.serialize_to_vec()); writes.insert(minted_key.clone(), init_bal.serialize_to_vec()); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1338,12 +1337,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // send the token and a packet with the data - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("sending a token failed"); // Check - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); // The token must be part of the verifier set (checked by MultitokenVp) env.verifiers.insert(ibc_token); let result = ibc::validate_ibc_vp_from_tx( @@ -1365,12 +1364,12 @@ mod tests { "Expected VP to accept the tx, got {result:?}" ); // Check the balance - tx_host_env::set(env); - let balance: Option = tx_host_env::with(|env| { + tx_env::set(env); + let balance: Option = tx_env::with(|env| { env.state.read(&balance_key).expect("read error") }); assert_eq!(balance, Some(Amount::from_u64(0))); - let minted: Option = tx_host_env::with(|env| { + let minted: Option = tx_env::with(|env| { env.state.read(&minted_key).expect("read error") }); assert_eq!(minted, Some(Amount::from_u64(0))); @@ -1379,7 +1378,7 @@ mod tests { #[test] fn test_ibc_receive_token() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -1397,7 +1396,7 @@ mod tests { writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1422,12 +1421,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // receive a packet with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("receiving the token failed"); // Check - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1458,12 +1457,12 @@ mod tests { "Expected VP to accept the tx, got {result:?}" ); // Check the balance - tx_host_env::set(env); + tx_env::set(env); let key = ibc::balance_key_with_ibc_prefix(denom, &receiver); let balance: Option = - tx_host_env::with(|env| env.state.read(&key).expect("read error")); + tx_env::with(|env| env.state.read(&key).expect("read error")); assert_eq!(balance, Some(Amount::native_whole(100))); - let minted: Option = tx_host_env::with(|env| { + let minted: Option = tx_env::with(|env| { env.state.read(&minted_key).expect("read error") }); assert_eq!(minted, Some(Amount::native_whole(100))); @@ -1472,7 +1471,7 @@ mod tests { #[test] fn test_ibc_receive_no_token() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -1490,7 +1489,7 @@ mod tests { writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1517,21 +1516,21 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // Receive the packet, but no token is received - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("receiving the token failed"); // Check if the transaction is valid - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), ); assert!(result.is_ok()); // Check if the ack has an error due to the invalid packet data - tx_host_env::set(env); + tx_env::set(env); let ack_key = ibc_storage::ack_key(&port_id, &channel_id, sequence); - let ack = tx_host_env::with(|env| { + let ack = tx_env::with(|env| { env.state.read_bytes(&ack_key).expect("read error").unwrap() }); let expected_ack = @@ -1541,7 +1540,7 @@ mod tests { // Check if only the ack and the receipt are added let receipt_key = ibc_storage::receipt_key(&port_id, &channel_id, sequence); - let changed_keys = tx_host_env::with(|env| { + let changed_keys = tx_env::with(|env| { env.state .write_log() .verifiers_and_changed_keys(&BTreeSet::new()) @@ -1554,7 +1553,7 @@ mod tests { #[test] fn test_ibc_unescrow_token() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -1571,7 +1570,7 @@ mod tests { ibc::prepare_opened_channel(&conn_id, false); writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1581,7 +1580,7 @@ mod tests { &address::Address::Internal(address::InternalAddress::Ibc), ); let val = Amount::from_uint(100, ibc::ANY_DENOMINATION).unwrap(); - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write(&escrow_key, val).expect("write error"); }); @@ -1612,12 +1611,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // receive a packet with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("receiving a token failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1631,15 +1630,15 @@ mod tests { ); assert!(result.is_ok()); // Check the balance - tx_host_env::set(env); + tx_env::set(env); let key = token::storage_key::balance_key(&token, &receiver); let balance: Option = - tx_host_env::with(|env| env.state.read(&key).expect("read error")); + tx_env::with(|env| env.state.read(&key).expect("read error")); assert_eq!( balance, Some(Amount::from_uint(200, ibc::ANY_DENOMINATION).unwrap()) ); - let escrow: Option = tx_host_env::with(|env| { + let escrow: Option = tx_env::with(|env| { env.state.read(&escrow_key).expect("read error") }); assert_eq!( @@ -1651,7 +1650,7 @@ mod tests { #[test] fn test_ibc_unescrow_received_token() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -1668,7 +1667,7 @@ mod tests { ibc::prepare_opened_channel(&conn_id, false); writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }); }); @@ -1682,7 +1681,7 @@ mod tests { &address::Address::Internal(address::InternalAddress::Ibc), ); let val = Amount::native_whole(100); - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write(&escrow_key, val).expect("write error"); }); @@ -1716,12 +1715,12 @@ mod tests { .sign_raw(keypairs, pks_map, None) .sign_wrapper(keypair); // receive a packet with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("receiving a token failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1735,15 +1734,15 @@ mod tests { ); assert!(result.is_ok()); // Check the balance - tx_host_env::set(env); + tx_env::set(env); // without the source trace path let denom = format!("{}/{}/{}", dummy_src_port, dummy_src_channel, token); let key = ibc::balance_key_with_ibc_prefix(denom, &receiver); let balance: Option = - tx_host_env::with(|env| env.state.read(&key).expect("read error")); + tx_env::with(|env| env.state.read(&key).expect("read error")); assert_eq!(balance, Some(Amount::native_whole(100))); - let escrow: Option = tx_host_env::with(|env| { + let escrow: Option = tx_env::with(|env| { env.state.read(&escrow_key).expect("read error") }); assert_eq!(escrow, Some(Amount::from_u64(0))); @@ -1752,7 +1751,7 @@ mod tests { #[test] fn test_ibc_packet_timeout() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -1769,7 +1768,7 @@ mod tests { ibc::prepare_opened_channel(&conn_id, true); writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }) }); @@ -1780,12 +1779,12 @@ mod tests { ibc::set_timeout_timestamp(&mut msg.message); let tx_data = msg.serialize_to_vec(); // send a packet with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("sending a token failed"); // Commit - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); env.commit_tx_and_block(); // for the next block env.state.in_mem_mut().begin_block(BlockHeight(2)).unwrap(); @@ -1793,7 +1792,7 @@ mod tests { .in_mem_mut() .set_header(get_dummy_header()) .unwrap(); - tx_host_env::set(env); + tx_env::set(env); // Start a transaction to notify the timeout let counterparty = ibc::dummy_channel_counterparty(); @@ -1812,12 +1811,12 @@ mod tests { .sign_wrapper(keypair); // timeout the packet - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("timeout failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), @@ -1839,7 +1838,7 @@ mod tests { #[test] fn test_ibc_timeout_on_close() { // The environment must be initialized first - tx_host_env::init(); + tx_env::init(); let keypair = key::testing::keypair_1(); let keypairs = vec![keypair.clone()]; @@ -1856,7 +1855,7 @@ mod tests { ibc::prepare_opened_channel(&conn_id, true); writes.extend(channel_writes); writes.into_iter().for_each(|(key, val)| { - tx_host_env::with(|env| { + tx_env::with(|env| { env.state.write_bytes(&key, &val).expect("write error"); }) }); @@ -1866,12 +1865,12 @@ mod tests { ibc::msg_transfer(port_id, channel_id, token.to_string(), &sender); let tx_data = msg.serialize_to_vec(); // send a packet with the message - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("sending a token failed"); // Commit - let mut env = tx_host_env::take(); + let mut env = tx_env::take(); env.commit_tx_and_block(); // for the next block env.state.in_mem_mut().begin_block(BlockHeight(2)).unwrap(); @@ -1879,7 +1878,7 @@ mod tests { .in_mem_mut() .set_header(get_dummy_header()) .unwrap(); - tx_host_env::set(env); + tx_env::set(env); // Start a transaction to notify the timing-out on closed let counterparty = ibc::dummy_channel_counterparty(); @@ -1898,12 +1897,12 @@ mod tests { .sign_wrapper(keypair); // timeout the packet - tx_host_env::ibc::ibc_actions(tx::ctx()) + tx_env::ibc::ibc_actions(tx_env::ctx()) .execute::(&tx_data) .expect("timeout on close failed"); // Check - let env = tx_host_env::take(); + let env = tx_env::take(); let result = ibc::validate_ibc_vp_from_tx( &env, &tx.batch_ref_first_tx().unwrap(), diff --git a/crates/tests/src/vm_host_env/tx_env.rs b/crates/tests/src/vm_host_env/tx_env.rs new file mode 100644 index 0000000000..04e07994b0 --- /dev/null +++ b/crates/tests/src/vm_host_env/tx_env.rs @@ -0,0 +1,120 @@ +//! This module combines the native host function implementations from +//! `native_tx_env` with the functions exposed to the tx wasm +//! that will call to the native functions, instead of interfacing via a +//! wasm runtime. It can be used for WASM and host environment integration +//! tests. + +use namada_core::time::DurationSecs; +pub use namada_tx_env::ctx::{Ctx, *}; +pub use namada_tx_env::testing::native_tx_env::*; +pub use namada_tx_env::testing::{ctx, TestTxEnv}; +pub use namada_tx_prelude::*; +use parameters::EpochDuration; + +use crate::vp::TestVpEnv; + +/// Set the [`TestTxEnv`] back from a [`TestVpEnv`]. This is useful when +/// testing validation with multiple transactions that accumulate some state +/// changes. +pub fn set_from_vp_env(vp_env: TestVpEnv) { + let TestVpEnv { + state, + batched_tx, + vp_wasm_cache, + vp_cache_dir, + .. + } = vp_env; + let tx_env = TestTxEnv { + state, + vp_wasm_cache, + vp_cache_dir, + batched_tx, + ..Default::default() + }; + set(tx_env); +} + +pub trait TestTxEnvExt { + fn init_parameters( + &mut self, + epoch_duration: Option, + vp_allowlist: Option>, + tx_allowlist: Option>, + ); + + /// Credit tokens to the target account. + fn credit_tokens( + &mut self, + target: &Address, + token: &Address, + amount: token::Amount, + ); + + fn init_account_storage( + &mut self, + owner: &Address, + public_keys: Vec, + threshold: u8, + ); + + /// Set public key for the address. + fn write_account_threshold(&mut self, address: &Address, threshold: u8); +} + +impl TestTxEnvExt for TestTxEnv { + fn init_parameters( + &mut self, + epoch_duration: Option, + vp_allowlist: Option>, + tx_allowlist: Option>, + ) { + parameters::update_epoch_parameter( + &mut self.state, + &epoch_duration.unwrap_or(EpochDuration { + min_num_of_blocks: 1, + min_duration: DurationSecs(5), + }), + ) + .unwrap(); + parameters::update_tx_allowlist_parameter( + &mut self.state, + tx_allowlist.unwrap_or_default(), + ) + .unwrap(); + parameters::update_vp_allowlist_parameter( + &mut self.state, + vp_allowlist.unwrap_or_default(), + ) + .unwrap(); + } + + fn credit_tokens( + &mut self, + target: &Address, + token: &Address, + amount: token::Amount, + ) { + let storage_key = token::storage_key::balance_key(token, target); + self.state.write(&storage_key, amount).unwrap(); + } + + fn init_account_storage( + &mut self, + owner: &Address, + public_keys: Vec, + threshold: u8, + ) { + account::init_account_storage( + &mut self.state, + owner, + &public_keys, + threshold, + ) + .expect("Unable to write Account substorage."); + } + + fn write_account_threshold(&mut self, address: &Address, threshold: u8) { + let storage_key = account::threshold_key(address); + self.state.write(&storage_key, threshold).unwrap(); + } +} diff --git a/crates/tests/src/vm_host_env/vp.rs b/crates/tests/src/vm_host_env/vp.rs index 4c7843e29e..ce834c5e4c 100644 --- a/crates/tests/src/vm_host_env/vp.rs +++ b/crates/tests/src/vm_host_env/vp.rs @@ -15,7 +15,7 @@ use namada_vm::WasmCacheRwAccess; use namada_vp_prelude::Ctx; use tempfile::TempDir; -use crate::tx::{tx_host_env, TestTxEnv}; +use crate::tx_env::{self, TestTxEnv}; /// VP execution context provides access to host env functions pub static CTX: Ctx = unsafe { Ctx::new() }; @@ -187,10 +187,10 @@ mod native_vp_host_env { let vp_key = Key::validity_predicate(&addr); tx_env.state.db_write(&vp_key, vec![]).unwrap(); - tx_host_env::set(tx_env); + tx_env::set(tx_env); apply_tx(&addr); - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); let verifiers_from_tx = &tx_env.verifiers; let (verifiers, keys_changed) = tx_env .state diff --git a/crates/tx_env/Cargo.toml b/crates/tx_env/Cargo.toml index 2d61902f35..20b56a1c85 100644 --- a/crates/tx_env/Cargo.toml +++ b/crates/tx_env/Cargo.toml @@ -12,7 +12,48 @@ readme.workspace = true repository.workspace = true version.workspace = true +[features] +default = [] + +# Provides `Ctx` implementation - this should only be used by +# `namada_tx_prelude` and for testing code that uses `trait TxEnv` +ctx = [ + "namada_gas", + "namada_state", + "namada_tx", + "namada_vm_env", +] + +testing = [ + "ctx", + "namada_state/testing", + "namada_tx/testing", + "namada_vm", + "namada_vm/testing", + "concat-idents", + "tempfile", +] + [dependencies] namada_core = { path = "../core" } namada_events = { path = "../events", default-features = false } +namada_gas = { path = "../gas", optional = true } namada_storage = { path = "../storage" } +namada_state = { path = "../state", optional = true } +namada_tx = { path = "../tx", optional = true } +namada_vm = { path = "../vm", optional = true } +namada_vm_env = { path = "../vm_env", optional = true } + +concat-idents = { workspace = true, optional = true } +tempfile = { workspace = true, optional = true } + +[dev-dependencies] +namada_state = { path = "../state" } +namada_tx = { path = "../tx" } +namada_vm = { path = "../vm" } +namada_vm_env = { path = "../vm_env" } + +concat-idents.workspace = true +proptest.workspace = true +tempfile.workspace = true +test-log.workspace = true diff --git a/crates/tx_env/src/ctx.rs b/crates/tx_env/src/ctx.rs new file mode 100644 index 0000000000..38ef86c2f7 --- /dev/null +++ b/crates/tx_env/src/ctx.rs @@ -0,0 +1,405 @@ +//! Transaction execution context + +use core::slice; +use std::marker::PhantomData; +use std::str::FromStr; + +pub use namada_core::address::Address; +pub use namada_core::borsh::{ + BorshDeserialize, BorshSerialize, BorshSerializeExt, +}; +pub use namada_core::chain::{ + BlockHash, BlockHeader, BlockHeight, Epoch, BLOCK_HASH_LENGTH, +}; +use namada_core::chain::{ChainId, CHAIN_ID_LENGTH}; +pub use namada_core::ethereum_events::EthAddress; +use namada_core::internal::HostEnvResult; +pub use namada_core::key::common; +use namada_core::storage::TxIndex; +pub use namada_core::{ + address, booleans, borsh, chain, dec, encode, eth_bridge_pool, hash, masp, + storage, +}; +use namada_events::{EmitEvents, Event, EventToEmit, EventType}; +pub use namada_state::{ + collections, iter_prefix, iter_prefix_bytes, Error, OptionExt, Result, + ResultExt, StorageRead, StorageWrite, +}; +pub use namada_tx::{ + action, data, Authorization, BatchedTx, Code, Data, Section, Tx, +}; +use namada_vm_env::tx::*; +use namada_vm_env::{read_from_buffer, read_key_val_bytes_from_buffer}; + +use crate::TxEnv; + +/// Log a string. The message will be printed at the `tracing::Level::Info`. +pub fn log_string>(msg: T) { + let msg = msg.as_ref(); + unsafe { + namada_tx_log_string(msg.as_ptr() as _, msg.len() as _); + } +} + +/// Format and log a string in a debug build. +/// +/// In WASM target debug build, the message will be printed at the +/// `tracing::Level::Info` when executed in the VM. An optimized build will +/// omit any `debug_log!` statements unless `-C debug-assertions` is passed to +/// the compiler. +/// +/// In non-WASM target, the message is simply printed out to stdout. +#[macro_export] +macro_rules! debug_log { + ($($arg:tt)*) => {{ + ( + if cfg!(target_arch = "wasm32") { + if cfg!(debug_assertions) + { + log_string(format!($($arg)*)); + } + } else { + println!($($arg)*); + } + ) + }}; +} + +/// Execution context provides access to the host environment functions +#[derive(Debug, Clone)] +pub struct Ctx(()); + +impl Ctx { + /// Create a host context. The context on WASM side is only provided by + /// the VM once its being executed (in here it's implicit). But + /// because we want to have interface identical with the native + /// VPs, in which the context is explicit, in here we're just + /// using an empty `Ctx` to "fake" it. + /// + /// # Safety + /// + /// When using `#[transaction]` macro from `namada_macros`, + /// the constructor should not be called from transactions and validity + /// predicates implementation directly - they receive `&Self` as + /// an argument provided by the macro that wrap the low-level WASM + /// interface with Rust native types. + /// + /// Otherwise, this should only be called once to initialize this "fake" + /// context in order to benefit from type-safety of the host environment + /// methods implemented on the context. + #[allow(clippy::new_without_default)] + pub const unsafe fn new() -> Self { + Self(()) + } + + /// Yield a byte array value back to the host environment. + pub fn yield_value>(&self, value: V) { + let value = value.as_ref(); + unsafe { + namada_tx_yield_value(value.as_ptr() as _, value.len() as _); + } + } + + /// Get the transaction data for the specified inner tx + pub fn get_tx_data(&mut self, batched_tx: &BatchedTx) -> Result> { + let BatchedTx { tx, ref cmt } = batched_tx; + + tx.data(cmt).ok_or_err_msg("Missing data").map_err(|err| { + self.set_commitment_sentinel(); + err + }) + } +} + +/// Transaction result +pub type TxResult = Result<()>; + +/// Storage key-val pair iterator +#[derive(Debug)] +pub struct KeyValIterator(pub u64, pub PhantomData); + +impl StorageRead for Ctx { + type PrefixIter<'iter> = KeyValIterator<(String, Vec)>; + + fn read_bytes(&self, key: &storage::Key) -> Result>> { + let key = key.to_string(); + let read_result = + unsafe { namada_tx_read(key.as_ptr() as _, key.len() as _) }; + Ok(read_from_buffer(read_result, namada_tx_result_buffer)) + } + + fn has_key(&self, key: &storage::Key) -> Result { + let key = key.to_string(); + let found = + unsafe { namada_tx_has_key(key.as_ptr() as _, key.len() as _) }; + Ok(HostEnvResult::is_success(found)) + } + + fn get_chain_id(&self) -> Result { + let result = Vec::with_capacity(CHAIN_ID_LENGTH); + unsafe { + namada_tx_get_chain_id(result.as_ptr() as _); + } + let slice = + unsafe { slice::from_raw_parts(result.as_ptr(), CHAIN_ID_LENGTH) }; + Ok(ChainId::from_str( + std::str::from_utf8(slice).expect("Chain ID must be valid utf8"), + ) + .expect("Chain ID must be valid")) + } + + fn get_block_height(&self) -> Result { + Ok(BlockHeight(unsafe { namada_tx_get_block_height() })) + } + + fn get_block_header( + &self, + height: BlockHeight, + ) -> Result> { + let read_result = unsafe { namada_tx_get_block_header(height.0) }; + match read_from_buffer(read_result, namada_tx_result_buffer) { + Some(value) => Ok(Some( + BlockHeader::try_from_slice(&value[..]) + .expect("The conversion shouldn't fail"), + )), + None => Ok(None), + } + } + + fn get_block_epoch(&self) -> Result { + Ok(Epoch(unsafe { namada_tx_get_block_epoch() })) + } + + fn get_pred_epochs(&self) -> Result { + let read_result = unsafe { namada_tx_get_pred_epochs() }; + let bytes = read_from_buffer(read_result, namada_tx_result_buffer) + .ok_or(Error::SimpleMessage( + "Missing result from `namada_tx_get_pred_epochs` call", + ))?; + Ok(namada_core::decode(bytes).expect("Cannot decode pred epochs")) + } + + /// Get the native token address + fn get_native_token(&self) -> Result
{ + let result = Vec::with_capacity(address::ADDRESS_LEN); + unsafe { + namada_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<'iter>( + &'iter self, + prefix: &storage::Key, + ) -> Result> { + let prefix = prefix.to_string(); + let iter_id = unsafe { + namada_tx_iter_prefix(prefix.as_ptr() as _, prefix.len() as _) + }; + Ok(KeyValIterator(iter_id, PhantomData)) + } + + fn iter_next<'iter>( + &'iter self, + iter: &mut Self::PrefixIter<'iter>, + ) -> Result)>> { + let read_result = unsafe { namada_tx_iter_next(iter.0) }; + Ok(read_key_val_bytes_from_buffer( + read_result, + namada_tx_result_buffer, + )) + } + + fn get_tx_index(&self) -> Result { + let tx_index = unsafe { namada_tx_get_tx_index() }; + Ok(TxIndex(tx_index)) + } +} + +impl StorageWrite for Ctx { + fn write_bytes( + &mut self, + key: &storage::Key, + val: impl AsRef<[u8]>, + ) -> Result<()> { + let key = key.to_string(); + unsafe { + namada_tx_write( + key.as_ptr() as _, + key.len() as _, + val.as_ref().as_ptr() as _, + val.as_ref().len() as _, + ) + }; + Ok(()) + } + + fn delete(&mut self, key: &storage::Key) -> Result<()> { + let key = key.to_string(); + unsafe { namada_tx_delete(key.as_ptr() as _, key.len() as _) }; + Ok(()) + } +} + +impl EmitEvents for Ctx { + #[inline] + fn emit(&mut self, event: E) + where + E: EventToEmit, + { + _ = self.emit_event(event); + } + + fn emit_many(&mut self, event_batch: B) + where + B: IntoIterator, + E: EventToEmit, + { + for event in event_batch { + self.emit(event.into()); + } + } +} + +impl TxEnv for Ctx { + fn read_bytes_temp(&self, key: &storage::Key) -> Result>> { + let key = key.to_string(); + let read_result = + unsafe { namada_tx_read_temp(key.as_ptr() as _, key.len() as _) }; + Ok(read_from_buffer(read_result, namada_tx_result_buffer)) + } + + fn write_bytes_temp( + &mut self, + key: &storage::Key, + val: impl AsRef<[u8]>, + ) -> Result<()> { + let key = key.to_string(); + unsafe { + namada_tx_write_temp( + key.as_ptr() as _, + key.len() as _, + val.as_ref().as_ptr() as _, + val.as_ref().len() as _, + ) + }; + Ok(()) + } + + fn insert_verifier(&mut self, addr: &Address) -> Result<()> { + let addr = addr.encode(); + unsafe { + namada_tx_insert_verifier(addr.as_ptr() as _, addr.len() as _) + } + Ok(()) + } + + fn init_account( + &mut self, + code_hash: impl AsRef<[u8]>, + code_tag: &Option, + entropy_source: &[u8], + ) -> Result
{ + let code_hash = code_hash.as_ref(); + let code_tag = code_tag.serialize_to_vec(); + let result = Vec::with_capacity(address::ESTABLISHED_ADDRESS_BYTES_LEN); + unsafe { + namada_tx_init_account( + code_hash.as_ptr() as _, + code_hash.len() as _, + code_tag.as_ptr() as _, + code_tag.len() as _, + entropy_source.as_ptr() as _, + entropy_source.len() as _, + result.as_ptr() as _, + ) + }; + let slice = unsafe { + slice::from_raw_parts( + result.as_ptr(), + address::ESTABLISHED_ADDRESS_BYTES_LEN, + ) + }; + Ok(Address::try_from_slice(slice) + .expect("Decoding address created by the ledger shouldn't fail")) + } + + fn update_validity_predicate( + &mut self, + addr: &Address, + code_hash: impl AsRef<[u8]>, + code_tag: &Option, + ) -> Result<()> { + let addr = addr.encode(); + let code_hash = code_hash.as_ref(); + let code_tag = code_tag.serialize_to_vec(); + unsafe { + namada_tx_update_validity_predicate( + addr.as_ptr() as _, + addr.len() as _, + code_hash.as_ptr() as _, + code_hash.len() as _, + code_tag.as_ptr() as _, + code_tag.len() as _, + ) + }; + Ok(()) + } + + fn emit_event(&mut self, event: E) -> Result<()> { + let event: Event = event.into(); + let event = borsh::to_vec(&event).unwrap(); + unsafe { namada_tx_emit_event(event.as_ptr() as _, event.len() as _) }; + Ok(()) + } + + fn charge_gas(&mut self, used_gas: u64) -> Result<()> { + unsafe { namada_tx_charge_gas(used_gas) }; + Ok(()) + } + + fn get_events(&self, event_type: &EventType) -> Result> { + let event_type = event_type.to_string(); + let read_result = unsafe { + namada_tx_get_events( + event_type.as_ptr() as _, + event_type.len() as _, + ) + }; + match read_from_buffer(read_result, namada_tx_result_buffer) { + Some(value) => Ok(Vec::::try_from_slice(&value[..]) + .expect("The conversion shouldn't fail")), + None => Ok(Vec::new()), + } + } + + fn set_commitment_sentinel(&mut self) { + unsafe { namada_tx_set_commitment_sentinel() } + } +} + +impl namada_tx::action::Read for Ctx { + type Err = Error; + + fn read_temp( + &self, + key: &storage::Key, + ) -> Result> { + TxEnv::read_temp(self, key) + } +} + +impl namada_tx::action::Write for Ctx { + fn write_temp( + &mut self, + key: &storage::Key, + val: T, + ) -> Result<()> { + TxEnv::write_temp(self, key, val) + } +} diff --git a/crates/tx_env/src/lib.rs b/crates/tx_env/src/lib.rs index 7eb99caa85..9148fd9d52 100644 --- a/crates/tx_env/src/lib.rs +++ b/crates/tx_env/src/lib.rs @@ -18,6 +18,10 @@ clippy::print_stderr )] +#[cfg(feature = "ctx")] +pub mod ctx; +#[cfg(any(test, feature = "testing"))] +pub mod testing; pub use namada_core::address::Address; pub use namada_core::borsh::{ BorshDeserialize, BorshSerialize, BorshSerializeExt, diff --git a/crates/tx_env/src/testing.rs b/crates/tx_env/src/testing.rs index 776c53f0cf..9684475ea5 100644 --- a/crates/tx_env/src/testing.rs +++ b/crates/tx_env/src/testing.rs @@ -1,29 +1,29 @@ +//! Utils for testing with transaction code with `Ctx` and/or `TxEnv`. + +#![allow(missing_docs)] +#![allow(clippy::print_stdout, clippy::arithmetic_side_effects)] + use std::borrow::Borrow; use std::cell::RefCell; use std::collections::BTreeSet; use std::rc::Rc; -use namada_sdk::address::Address; -use namada_sdk::gas::TxGasMeter; -use namada_sdk::hash::Hash; -use namada_sdk::parameters::{self, EpochDuration}; -use namada_sdk::state::prefix_iter::PrefixIterators; -use namada_sdk::state::testing::TestState; -use namada_sdk::storage::mockdb::MockDB; -use namada_sdk::storage::{Key, TxIndex}; -use namada_sdk::time::DurationSecs; -pub use namada_sdk::tx::data::TxType; -pub use namada_sdk::tx::*; -use namada_sdk::{account, token}; -use namada_tx_prelude::transaction::TxSentinel; -use namada_tx_prelude::{BorshSerializeExt, Ctx}; +use namada_core::address::Address; +use namada_core::hash::Hash; +use namada_gas::TxGasMeter; +use namada_state::mockdb::MockDB; +use namada_state::prefix_iter::PrefixIterators; +use namada_state::testing::TestState; +use namada_state::{Key, TxIndex}; +use namada_tx::data::TxSentinel; +pub use namada_tx::data::TxType; +pub use namada_tx::*; use namada_vm::wasm::run::Error; -use namada_vm::wasm::{self, TxCache, VpCache}; +use namada_vm::wasm::{self, wasmer, TxCache, VpCache}; use namada_vm::WasmCacheRwAccess; -use namada_vp_prelude::key::common; use tempfile::TempDir; -use crate::vp::TestVpEnv; +use crate::ctx::Ctx; /// Tx execution context provides access to host env functions static mut CTX: Ctx = unsafe { Ctx::new() }; @@ -33,17 +33,6 @@ pub fn ctx() -> &'static mut Ctx { unsafe { &mut *std::ptr::addr_of_mut!(CTX) } } -/// This module combines the native host function implementations from -/// `native_tx_host_env` with the functions exposed to the tx wasm -/// that will call to the native functions, instead of interfacing via a -/// wasm runtime. It can be used for host environment integration tests. -pub mod tx_host_env { - pub use namada_tx_prelude::*; - - pub use super::ctx; - pub use super::native_tx_host_env::*; -} - /// Host environment structures required for transactions. #[derive(Debug)] pub struct TestTxEnv { @@ -109,32 +98,6 @@ impl TestTxEnv { .0 } - pub fn init_parameters( - &mut self, - epoch_duration: Option, - vp_allowlist: Option>, - tx_allowlist: Option>, - ) { - parameters::update_epoch_parameter( - &mut self.state, - &epoch_duration.unwrap_or(EpochDuration { - min_num_of_blocks: 1, - min_duration: DurationSecs(5), - }), - ) - .unwrap(); - parameters::update_tx_allowlist_parameter( - &mut self.state, - tx_allowlist.unwrap_or_default(), - ) - .unwrap(); - parameters::update_vp_allowlist_parameter( - &mut self.state, - vp_allowlist.unwrap_or_default(), - ) - .unwrap(); - } - pub fn store_wasm_code(&mut self, code: Vec) { let hash = Hash::sha256(&code); let key = Key::wasm_code(&hash); @@ -166,33 +129,6 @@ impl TestTxEnv { } } - pub fn init_account_storage( - &mut self, - owner: &Address, - public_keys: Vec, - threshold: u8, - ) { - account::init_account_storage( - &mut self.state, - owner, - &public_keys, - threshold, - ) - .expect("Unable to write Account substorage."); - } - - /// Set public key for the address. - pub fn write_account_threshold( - &mut self, - address: &Address, - threshold: u8, - ) { - let storage_key = account::threshold_key(address); - self.state - .db_write(&storage_key, threshold.serialize_to_vec()) - .unwrap(); - } - /// Commit the genesis state. Typically, you'll want to call this after /// setting up the initial state, before running a transaction. pub fn commit_genesis(&mut self) { @@ -209,19 +145,6 @@ impl TestTxEnv { self.verifiers = BTreeSet::default(); } - /// Credit tokens to the target account. - pub fn credit_tokens( - &mut self, - target: &Address, - token: &Address, - amount: token::Amount, - ) { - let storage_key = token::storage_key::balance_key(token, target); - self.state - .db_write(&storage_key, amount.serialize_to_vec()) - .unwrap(); - } - /// Apply the tx changes to the write log. pub fn execute_tx(&mut self) -> Result<(), Error> { wasm::run::tx( @@ -241,7 +164,7 @@ impl TestTxEnv { /// It keeps a thread-local global `TxEnv`, which is passed to any of /// invoked host environment functions and so it must be initialized /// before the test. -mod native_tx_host_env { +pub mod native_tx_env { use std::pin::Pin; // TODO replace with `std::concat_idents` once stabilized (https://github.com/rust-lang/rust/issues/29599) @@ -284,7 +207,7 @@ mod native_tx_host_env { .as_mut() .expect( "Did you forget to initialize the ENV? (e.g. call to \ - `tx_host_env::init()`)", + `tx_env::init()`)", ) .as_mut(); f(&mut env) @@ -297,7 +220,7 @@ mod native_tx_host_env { let mut env = env.borrow_mut(); let env = env.take().expect( "Did you forget to initialize the ENV? (e.g. call to \ - `tx_host_env::init()`)", + `tx_env::init()`)", ); let env = Pin::into_inner(env); *env @@ -308,27 +231,6 @@ mod native_tx_host_env { with(|env| env.commit_tx_and_block()) } - /// Set the [`TestTxEnv`] back from a [`TestVpEnv`]. This is useful when - /// testing validation with multiple transactions that accumulate some state - /// changes. - pub fn set_from_vp_env(vp_env: TestVpEnv) { - let TestVpEnv { - state, - batched_tx, - vp_wasm_cache, - vp_cache_dir, - .. - } = vp_env; - let tx_env = TestTxEnv { - state, - vp_wasm_cache, - vp_cache_dir, - batched_tx, - ..Default::default() - }; - set(tx_env); - } - /// A helper macro to create implementations of the host environment /// functions exported to wasm, which uses the environment from the /// `ENV` variable. @@ -535,8 +437,7 @@ mod native_tx_host_env { #[cfg(test)] mod tests { use namada_core::hash::Sha256Hasher; - use namada_sdk::storage; - use namada_tx_prelude::StorageWrite; + use namada_state::{Key as StorageKey, StorageWrite}; use namada_vm::host_env::{self, TxVmEnv}; use namada_vm::memory::VmMemory; use proptest::prelude::*; @@ -549,7 +450,7 @@ mod tests { write_to_memory: bool, write_to_wl: bool, write_to_storage: bool, - key: storage::Key, + key: StorageKey, key_memory_ptr: u64, read_buffer_memory_ptr: u64, val: Vec, @@ -793,7 +694,7 @@ mod tests { any::(), any::(), any::(), - namada_sdk::storage::testing::arb_key(), + namada_state::testing::arb_key(), arb_u64(), arb_u64(), any::>(), @@ -826,10 +727,10 @@ mod tests { prop_oneof![ 5 => Just(u64::MIN), 5 => Just(u64::MIN + 1), - 5 => u64::MIN + 2..=u32::MAX as u64, + 5 => u64::MIN + 2..=u64::from(u32::MAX), 1 => Just(u64::MAX), 1 => Just(u64::MAX - 1), - 1 => u32::MAX as u64 + 1..u64::MAX - 1, + 1 => u64::from(u32::MAX) + 1..u64::MAX - 1, ] } } diff --git a/crates/tx_prelude/Cargo.toml b/crates/tx_prelude/Cargo.toml index 98833c9923..f097ef9245 100644 --- a/crates/tx_prelude/Cargo.toml +++ b/crates/tx_prelude/Cargo.toml @@ -29,7 +29,7 @@ namada_proof_of_stake = { path = "../proof_of_stake" } namada_state = { path = "../state" } namada_token = { path = "../token" } namada_tx = { path = "../tx", default-features = false } -namada_tx_env = { path = "../tx_env" } +namada_tx_env = { path = "../tx_env", features = ["ctx"] } namada_vm_env = { path = "../vm_env" } borsh.workspace = true diff --git a/crates/tx_prelude/src/ibc.rs b/crates/tx_prelude/src/ibc.rs index 4a20dcae17..0b5520e17a 100644 --- a/crates/tx_prelude/src/ibc.rs +++ b/crates/tx_prelude/src/ibc.rs @@ -17,37 +17,40 @@ pub use namada_ibc::{ IbcActions, IbcCommonContext, IbcStorageContext, NftTransferModule, ProofSpec, TransferModule, }; -use namada_tx_env::TxEnv; -use crate::token::transfer; -use crate::{Ctx, Result}; +use super::token::transfer; +use super::{parameters, token, Ctx}; +use crate::{Result, TxEnv}; /// IBC actions to handle an IBC message. The `verifiers` inserted into the set /// must be inserted into the tx context with `Ctx::insert_verifier` after tx /// execution. pub fn ibc_actions( ctx: &mut Ctx, -) -> IbcActions<'_, Ctx, crate::parameters::Store, crate::token::Store> -{ - let ctx = Rc::new(RefCell::new(ctx.clone())); +) -> IbcActions<'_, CtxWrapper, parameters::Store, token::Store> { + let ctx = Rc::new(RefCell::new(CtxWrapper(ctx.clone()))); let verifiers = Rc::new(RefCell::new(BTreeSet::
::new())); let mut actions = IbcActions::new(ctx.clone(), verifiers.clone()); let module = TransferModule::new(ctx.clone(), verifiers); actions.add_transfer_module(module); - let module = NftTransferModule::>::new(ctx); + let module = NftTransferModule::>::new(ctx); actions.add_transfer_module(module); actions } -impl IbcStorageContext for Ctx { - type Storage = Self; +/// A wrapper type to impl foreign traits on foreign type +#[derive(Debug)] +pub struct CtxWrapper(Ctx); + +impl IbcStorageContext for CtxWrapper { + type Storage = Ctx; fn storage(&self) -> &Self::Storage { - self + &self.0 } fn storage_mut(&mut self) -> &mut Self::Storage { - self + &mut self.0 } fn log_string(&self, message: String) { @@ -55,7 +58,7 @@ impl IbcStorageContext for Ctx { } fn emit_ibc_event(&mut self, event: IbcEvent) -> Result<()> { - ::emit_event(self, event) + ::emit_event(&mut self.0, event) } fn transfer_token( @@ -65,7 +68,7 @@ impl IbcStorageContext for Ctx { token: &Address, amount: Amount, ) -> Result<()> { - transfer(self, src, dest, token, amount) + transfer(&mut self.0, src, dest, token, amount) } fn mint_token( @@ -74,7 +77,7 @@ impl IbcStorageContext for Ctx { token: &Address, amount: Amount, ) -> Result<()> { - mint_tokens::<_, crate::token::Store<_>>(self, target, token, amount) + mint_tokens::<_, token::Store<_>>(&mut self.0, target, token, amount) } fn burn_token( @@ -83,12 +86,12 @@ impl IbcStorageContext for Ctx { token: &Address, amount: Amount, ) -> Result<()> { - burn_tokens::<_, crate::token::Store<_>>(self, target, token, amount) + burn_tokens::<_, token::Store<_>>(&mut self.0, target, token, amount) } fn insert_verifier(&mut self, addr: &Address) -> Result<()> { - TxEnv::insert_verifier(self, addr) + TxEnv::insert_verifier(&mut self.0, addr) } } -impl IbcCommonContext for Ctx {} +impl IbcCommonContext for CtxWrapper {} diff --git a/crates/tx_prelude/src/lib.rs b/crates/tx_prelude/src/lib.rs index 6297857ce8..2fa43cfc54 100644 --- a/crates/tx_prelude/src/lib.rs +++ b/crates/tx_prelude/src/lib.rs @@ -19,414 +19,24 @@ pub mod pgf; pub mod proof_of_stake; pub mod token; -use core::slice; -use std::marker::PhantomData; -use std::str::FromStr; - -use chain::ChainId; use namada_account::AccountPublicKeysMap; -pub use namada_core::address::Address; -pub use namada_core::borsh::{ - BorshDeserialize, BorshSerialize, BorshSerializeExt, -}; -use namada_core::chain::CHAIN_ID_LENGTH; -pub use namada_core::chain::{ - BlockHash, BlockHeader, BlockHeight, Epoch, BLOCK_HASH_LENGTH, -}; -pub use namada_core::ethereum_events::EthAddress; -use namada_core::internal::HostEnvResult; -use namada_core::key::common; -use namada_core::storage::TxIndex; -pub use namada_core::{address, encode, eth_bridge_pool, storage, *}; -use namada_events::{EmitEvents, Event, EventToEmit, EventType}; pub use namada_governance::storage as gov_storage; pub use namada_macros::transaction; pub use namada_parameters::storage as parameters_storage; -pub use namada_state::{ - collections, iter_prefix, iter_prefix_bytes, Error, OptionExt, Result, - ResultExt, StorageRead, StorageWrite, -}; use namada_token::MaspTransaction; -pub use namada_tx::{action, data as transaction, BatchedTx, Section, Tx}; -pub use namada_tx_env::TxEnv; -use namada_vm_env::tx::*; -use namada_vm_env::{read_from_buffer, read_key_val_bytes_from_buffer}; +pub use namada_tx_env::ctx::*; +pub use namada_tx_env::{debug_log, TxEnv}; +use namada_vm_env::tx::{ + namada_tx_update_masp_note_commitment_tree, + namada_tx_verify_tx_section_signature, +}; +use namada_vm_env::HostEnvResult; +pub use proof_of_stake::PosCtxExt; pub use { namada_gas as gas, namada_governance as governance, namada_parameters as parameters, }; -/// Log a string. The message will be printed at the `tracing::Level::Info`. -pub fn log_string>(msg: T) { - let msg = msg.as_ref(); - unsafe { - namada_tx_log_string(msg.as_ptr() as _, msg.len() as _); - } -} - -/// Format and log a string in a debug build. -/// -/// In WASM target debug build, the message will be printed at the -/// `tracing::Level::Info` when executed in the VM. An optimized build will -/// omit any `debug_log!` statements unless `-C debug-assertions` is passed to -/// the compiler. -/// -/// In non-WASM target, the message is simply printed out to stdout. -#[macro_export] -macro_rules! debug_log { - ($($arg:tt)*) => {{ - ( - if cfg!(target_arch = "wasm32") { - if cfg!(debug_assertions) - { - log_string(format!($($arg)*)); - } - } else { - println!($($arg)*); - } - ) - }}; -} - -/// Execution context provides access to the host environment functions -#[derive(Debug, Clone)] -pub struct Ctx(()); - -impl Ctx { - /// Create a host context. The context on WASM side is only provided by - /// the VM once its being executed (in here it's implicit). But - /// because we want to have interface identical with the native - /// VPs, in which the context is explicit, in here we're just - /// using an empty `Ctx` to "fake" it. - /// - /// # Safety - /// - /// When using `#[transaction]` macro from `namada_macros`, - /// the constructor should not be called from transactions and validity - /// predicates implementation directly - they receive `&Self` as - /// an argument provided by the macro that wrap the low-level WASM - /// interface with Rust native types. - /// - /// Otherwise, this should only be called once to initialize this "fake" - /// context in order to benefit from type-safety of the host environment - /// methods implemented on the context. - #[allow(clippy::new_without_default)] - pub const unsafe fn new() -> Self { - Self(()) - } - - /// Yield a byte array value back to the host environment. - pub fn yield_value>(&self, value: V) { - let value = value.as_ref(); - unsafe { - namada_tx_yield_value(value.as_ptr() as _, value.len() as _); - } - } - - /// Get the transaction data for the specified inner tx - pub fn get_tx_data(&mut self, batched_tx: &BatchedTx) -> Result> { - let BatchedTx { tx, ref cmt } = batched_tx; - - tx.data(cmt).ok_or_err_msg("Missing data").map_err(|err| { - self.set_commitment_sentinel(); - err - }) - } -} - -/// Transaction result -pub type TxResult = Result<()>; - -/// Storage key-val pair iterator -#[derive(Debug)] -pub struct KeyValIterator(pub u64, pub PhantomData); - -impl StorageRead for Ctx { - type PrefixIter<'iter> = KeyValIterator<(String, Vec)>; - - fn read_bytes(&self, key: &storage::Key) -> Result>> { - let key = key.to_string(); - let read_result = - unsafe { namada_tx_read(key.as_ptr() as _, key.len() as _) }; - Ok(read_from_buffer(read_result, namada_tx_result_buffer)) - } - - fn has_key(&self, key: &storage::Key) -> Result { - let key = key.to_string(); - let found = - unsafe { namada_tx_has_key(key.as_ptr() as _, key.len() as _) }; - Ok(HostEnvResult::is_success(found)) - } - - fn get_chain_id(&self) -> Result { - let result = Vec::with_capacity(CHAIN_ID_LENGTH); - unsafe { - namada_tx_get_chain_id(result.as_ptr() as _); - } - let slice = - unsafe { slice::from_raw_parts(result.as_ptr(), CHAIN_ID_LENGTH) }; - Ok(ChainId::from_str( - std::str::from_utf8(slice).expect("Chain ID must be valid utf8"), - ) - .expect("Chain ID must be valid")) - } - - fn get_block_height(&self) -> Result { - Ok(BlockHeight(unsafe { namada_tx_get_block_height() })) - } - - fn get_block_header( - &self, - height: BlockHeight, - ) -> Result> { - let read_result = unsafe { namada_tx_get_block_header(height.0) }; - match read_from_buffer(read_result, namada_tx_result_buffer) { - Some(value) => Ok(Some( - BlockHeader::try_from_slice(&value[..]) - .expect("The conversion shouldn't fail"), - )), - None => Ok(None), - } - } - - fn get_block_epoch(&self) -> Result { - Ok(Epoch(unsafe { namada_tx_get_block_epoch() })) - } - - fn get_pred_epochs(&self) -> Result { - let read_result = unsafe { namada_tx_get_pred_epochs() }; - let bytes = read_from_buffer(read_result, namada_tx_result_buffer) - .ok_or(Error::SimpleMessage( - "Missing result from `namada_tx_get_pred_epochs` call", - ))?; - Ok(namada_core::decode(bytes).expect("Cannot decode pred epochs")) - } - - /// Get the native token address - fn get_native_token(&self) -> Result
{ - let result = Vec::with_capacity(address::ADDRESS_LEN); - unsafe { - namada_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<'iter>( - &'iter self, - prefix: &storage::Key, - ) -> Result> { - let prefix = prefix.to_string(); - let iter_id = unsafe { - namada_tx_iter_prefix(prefix.as_ptr() as _, prefix.len() as _) - }; - Ok(KeyValIterator(iter_id, PhantomData)) - } - - fn iter_next<'iter>( - &'iter self, - iter: &mut Self::PrefixIter<'iter>, - ) -> Result)>> { - let read_result = unsafe { namada_tx_iter_next(iter.0) }; - Ok(read_key_val_bytes_from_buffer( - read_result, - namada_tx_result_buffer, - )) - } - - fn get_tx_index(&self) -> Result { - let tx_index = unsafe { namada_tx_get_tx_index() }; - Ok(TxIndex(tx_index)) - } -} - -impl StorageWrite for Ctx { - fn write_bytes( - &mut self, - key: &storage::Key, - val: impl AsRef<[u8]>, - ) -> Result<()> { - let key = key.to_string(); - unsafe { - namada_tx_write( - key.as_ptr() as _, - key.len() as _, - val.as_ref().as_ptr() as _, - val.as_ref().len() as _, - ) - }; - Ok(()) - } - - fn delete(&mut self, key: &storage::Key) -> Result<()> { - let key = key.to_string(); - unsafe { namada_tx_delete(key.as_ptr() as _, key.len() as _) }; - Ok(()) - } -} - -impl EmitEvents for Ctx { - #[inline] - fn emit(&mut self, event: E) - where - E: EventToEmit, - { - _ = self.emit_event(event); - } - - fn emit_many(&mut self, event_batch: B) - where - B: IntoIterator, - E: EventToEmit, - { - for event in event_batch { - self.emit(event.into()); - } - } -} - -impl TxEnv for Ctx { - fn read_bytes_temp(&self, key: &storage::Key) -> Result>> { - let key = key.to_string(); - let read_result = - unsafe { namada_tx_read_temp(key.as_ptr() as _, key.len() as _) }; - Ok(read_from_buffer(read_result, namada_tx_result_buffer)) - } - - fn write_bytes_temp( - &mut self, - key: &storage::Key, - val: impl AsRef<[u8]>, - ) -> Result<()> { - let key = key.to_string(); - unsafe { - namada_tx_write_temp( - key.as_ptr() as _, - key.len() as _, - val.as_ref().as_ptr() as _, - val.as_ref().len() as _, - ) - }; - Ok(()) - } - - fn insert_verifier(&mut self, addr: &Address) -> Result<()> { - let addr = addr.encode(); - unsafe { - namada_tx_insert_verifier(addr.as_ptr() as _, addr.len() as _) - } - Ok(()) - } - - fn init_account( - &mut self, - code_hash: impl AsRef<[u8]>, - code_tag: &Option, - entropy_source: &[u8], - ) -> Result
{ - let code_hash = code_hash.as_ref(); - let code_tag = code_tag.serialize_to_vec(); - let result = Vec::with_capacity(address::ESTABLISHED_ADDRESS_BYTES_LEN); - unsafe { - namada_tx_init_account( - code_hash.as_ptr() as _, - code_hash.len() as _, - code_tag.as_ptr() as _, - code_tag.len() as _, - entropy_source.as_ptr() as _, - entropy_source.len() as _, - result.as_ptr() as _, - ) - }; - let slice = unsafe { - slice::from_raw_parts( - result.as_ptr(), - address::ESTABLISHED_ADDRESS_BYTES_LEN, - ) - }; - Ok(Address::try_from_slice(slice) - .expect("Decoding address created by the ledger shouldn't fail")) - } - - fn update_validity_predicate( - &mut self, - addr: &Address, - code_hash: impl AsRef<[u8]>, - code_tag: &Option, - ) -> Result<()> { - let addr = addr.encode(); - let code_hash = code_hash.as_ref(); - let code_tag = code_tag.serialize_to_vec(); - unsafe { - namada_tx_update_validity_predicate( - addr.as_ptr() as _, - addr.len() as _, - code_hash.as_ptr() as _, - code_hash.len() as _, - code_tag.as_ptr() as _, - code_tag.len() as _, - ) - }; - Ok(()) - } - - fn emit_event(&mut self, event: E) -> Result<()> { - let event: Event = event.into(); - let event = borsh::to_vec(&event).unwrap(); - unsafe { namada_tx_emit_event(event.as_ptr() as _, event.len() as _) }; - Ok(()) - } - - fn charge_gas(&mut self, used_gas: u64) -> Result<()> { - unsafe { namada_tx_charge_gas(used_gas) }; - Ok(()) - } - - fn get_events(&self, event_type: &EventType) -> Result> { - let event_type = event_type.to_string(); - let read_result = unsafe { - namada_tx_get_events( - event_type.as_ptr() as _, - event_type.len() as _, - ) - }; - match read_from_buffer(read_result, namada_tx_result_buffer) { - Some(value) => Ok(Vec::::try_from_slice(&value[..]) - .expect("The conversion shouldn't fail")), - None => Ok(Vec::new()), - } - } - - fn set_commitment_sentinel(&mut self) { - unsafe { namada_tx_set_commitment_sentinel() } - } -} - -impl namada_tx::action::Read for Ctx { - type Err = Error; - - fn read_temp( - &self, - key: &storage::Key, - ) -> Result> { - TxEnv::read_temp(self, key) - } -} - -impl namada_tx::action::Write for Ctx { - fn write_temp( - &mut self, - key: &storage::Key, - val: T, - ) -> Result<()> { - TxEnv::write_temp(self, key, val) - } -} - /// Verify section signatures against the given list of keys pub fn verify_signatures_of_pks( tx: &Tx, @@ -452,7 +62,6 @@ pub fn verify_signatures_of_pks( Ok(HostEnvResult::is_success(valid)) } - /// Update the masp note commitment tree in storage with the new notes pub fn update_masp_note_commitment_tree( transaction: &MaspTransaction, diff --git a/crates/tx_prelude/src/proof_of_stake.rs b/crates/tx_prelude/src/proof_of_stake.rs index 575cddc22c..1afafad2d3 100644 --- a/crates/tx_prelude/src/proof_of_stake.rs +++ b/crates/tx_prelude/src/proof_of_stake.rs @@ -1,5 +1,6 @@ //! Proof of Stake system integration with functions for transactions +use namada_account::Address; use namada_core::dec::Dec; use namada_core::key; pub use namada_proof_of_stake::parameters::PosParams; @@ -13,19 +14,113 @@ use namada_proof_of_stake::{ redelegate_tokens, unbond_tokens, unjail_validator, withdraw_tokens, }; pub use namada_proof_of_stake::{parameters, storage, storage_key, types}; +pub use namada_state::StorageRead; use namada_tx::action::{ Action, ClaimRewards, PosAction, Redelegation, Unbond, Withdraw, Write, }; use namada_tx::data::pos::{BecomeValidator, Bond}; +use namada_tx_env::ctx::{common, Ctx, TxResult}; +use namada_tx_env::{Result, TxEnv}; -use super::*; -use crate::token; +use crate::{governance, token}; -impl Ctx { +/// Extension trait to add PoS methods to `Ctx`. +pub trait PosCtxExt { /// Self-bond tokens to a validator when `source` is `None` or equal to /// the `validator` address, or delegate tokens from the `source` to the /// `validator`. - pub fn bond_tokens( + fn bond_tokens( + &mut self, + source: Option<&Address>, + validator: &Address, + amount: token::Amount, + ) -> TxResult; + + /// Unbond self-bonded tokens from a validator when `source` is `None` + /// or equal to the `validator` address, or unbond delegated tokens from + /// the `source` to the `validator`. + fn unbond_tokens( + &mut self, + source: Option<&Address>, + validator: &Address, + amount: token::Amount, + ) -> Result; + + /// Withdraw unbonded tokens from a self-bond to a validator when + /// `source` is `None` or equal to the `validator` address, or withdraw + /// unbonded tokens delegated to the `validator` to the `source`. + fn withdraw_tokens( + &mut self, + source: Option<&Address>, + validator: &Address, + ) -> Result; + + /// Change validator consensus key. + fn change_validator_consensus_key( + &mut self, + validator: &Address, + consensus_key: &common::PublicKey, + ) -> TxResult; + + /// Change validator commission rate. + fn change_validator_commission_rate( + &mut self, + validator: &Address, + rate: &Dec, + ) -> TxResult; + + /// Unjail a jailed validator and re-enter the validator sets. + fn unjail_validator(&mut self, validator: &Address) -> TxResult; + + /// Redelegate bonded tokens from one validator to another one. + fn redelegate_tokens( + &mut self, + owner: &Address, + src_validator: &Address, + dest_validator: &Address, + amount: token::Amount, + ) -> TxResult; + + /// Claim available reward tokens + fn claim_reward_tokens( + &mut self, + source: Option<&Address>, + validator: &Address, + ) -> Result; + + /// Attempt to initialize a validator account. On success, returns the + /// initialized validator account's address. + fn become_validator( + &mut self, + become_validator: BecomeValidator, + ) -> Result
; + + /// Deactivate validator + fn deactivate_validator(&mut self, validator: &Address) -> TxResult; + + /// Reactivate validator + fn reactivate_validator(&mut self, validator: &Address) -> TxResult; + + /// Change validator metadata. + #[allow(clippy::too_many_arguments)] + fn change_validator_metadata( + &mut self, + validator: &Address, + email: Option, + description: Option, + website: Option, + discord_handle: Option, + avatar: Option, + name: Option, + commission_rate: Option, + ) -> TxResult; +} + +impl PosCtxExt for Ctx { + /// Self-bond tokens to a validator when `source` is `None` or equal to + /// the `validator` address, or delegate tokens from the `source` to the + /// `validator`. + fn bond_tokens( &mut self, source: Option<&Address>, validator: &Address, @@ -55,7 +150,7 @@ impl Ctx { /// Unbond self-bonded tokens from a validator when `source` is `None` /// or equal to the `validator` address, or unbond delegated tokens from /// the `source` to the `validator`. - pub fn unbond_tokens( + fn unbond_tokens( &mut self, source: Option<&Address>, validator: &Address, @@ -85,7 +180,7 @@ impl Ctx { /// Withdraw unbonded tokens from a self-bond to a validator when /// `source` is `None` or equal to the `validator` address, or withdraw /// unbonded tokens delegated to the `validator` to the `source`. - pub fn withdraw_tokens( + fn withdraw_tokens( &mut self, source: Option<&Address>, validator: &Address, @@ -109,7 +204,7 @@ impl Ctx { } /// Change validator consensus key. - pub fn change_validator_consensus_key( + fn change_validator_consensus_key( &mut self, validator: &Address, consensus_key: &common::PublicKey, @@ -131,7 +226,7 @@ impl Ctx { } /// Change validator commission rate. - pub fn change_validator_commission_rate( + fn change_validator_commission_rate( &mut self, validator: &Address, rate: &Dec, @@ -153,7 +248,7 @@ impl Ctx { } /// Unjail a jailed validator and re-enter the validator sets. - pub fn unjail_validator(&mut self, validator: &Address) -> TxResult { + fn unjail_validator(&mut self, validator: &Address) -> TxResult { // The tx must be authorized by the source address self.insert_verifier(validator)?; @@ -168,7 +263,7 @@ impl Ctx { } /// Redelegate bonded tokens from one validator to another one. - pub fn redelegate_tokens( + fn redelegate_tokens( &mut self, owner: &Address, src_validator: &Address, @@ -197,7 +292,7 @@ impl Ctx { } /// Claim available reward tokens - pub fn claim_reward_tokens( + fn claim_reward_tokens( &mut self, source: Option<&Address>, validator: &Address, @@ -222,7 +317,7 @@ impl Ctx { /// Attempt to initialize a validator account. On success, returns the /// initialized validator account's address. - pub fn become_validator( + fn become_validator( &mut self, BecomeValidator { address, @@ -280,7 +375,7 @@ impl Ctx { } /// Deactivate validator - pub fn deactivate_validator(&mut self, validator: &Address) -> TxResult { + fn deactivate_validator(&mut self, validator: &Address) -> TxResult { // The tx must be authorized by the source address self.insert_verifier(validator)?; @@ -297,7 +392,7 @@ impl Ctx { } /// Reactivate validator - pub fn reactivate_validator(&mut self, validator: &Address) -> TxResult { + fn reactivate_validator(&mut self, validator: &Address) -> TxResult { // The tx must be authorized by the source address self.insert_verifier(validator)?; @@ -315,7 +410,7 @@ impl Ctx { /// Change validator metadata. #[allow(clippy::too_many_arguments)] - pub fn change_validator_metadata( + fn change_validator_metadata( &mut self, validator: &Address, email: Option, diff --git a/crates/tx_prelude/src/token.rs b/crates/tx_prelude/src/token.rs index 6718ebdfd3..993c5ac0bc 100644 --- a/crates/tx_prelude/src/token.rs +++ b/crates/tx_prelude/src/token.rs @@ -12,9 +12,8 @@ pub use namada_token::testing; pub use namada_token::{ storage_key, utils, Amount, DenominatedAmount, Store, Transfer, }; -use namada_tx_env::TxEnv; - -use crate::{Ctx, Result, TxResult}; +use namada_tx_env::ctx::{Ctx, TxResult}; +use namada_tx_env::{Result, TxEnv}; /// A transparent token transfer that can be used in a transaction. pub fn transfer( diff --git a/crates/vm/src/wasm/mod.rs b/crates/vm/src/wasm/mod.rs index 96d2dd7ce6..de6c0dc593 100644 --- a/crates/vm/src/wasm/mod.rs +++ b/crates/vm/src/wasm/mod.rs @@ -8,3 +8,4 @@ pub mod run; pub use compilation_cache::common::{Cache, CacheName}; pub use compilation_cache::tx::TxCache; pub use compilation_cache::vp::VpCache; +pub use wasmer; diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index caa7f23b94..41ab71e4fb 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -4150,9 +4150,16 @@ dependencies = [ name = "namada_tx_env" version = "0.43.0" dependencies = [ + "concat-idents", "namada_core", "namada_events", + "namada_gas", + "namada_state", "namada_storage", + "namada_tx", + "namada_vm", + "namada_vm_env", + "tempfile", ] [[package]] diff --git a/wasm/tx_become_validator/src/lib.rs b/wasm/tx_become_validator/src/lib.rs index 6dee2d5d05..80cf446ffa 100644 --- a/wasm/tx_become_validator/src/lib.rs +++ b/wasm/tx_become_validator/src/lib.rs @@ -2,7 +2,7 @@ //! validity predicates. use booleans::ResultBoolExt; -use namada_tx_prelude::transaction::pos::BecomeValidator; +use namada_tx_prelude::data::pos::BecomeValidator; use namada_tx_prelude::*; #[transaction] diff --git a/wasm/tx_bond/src/lib.rs b/wasm/tx_bond/src/lib.rs index b8a1f60536..263b97ca0c 100644 --- a/wasm/tx_bond/src/lib.rs +++ b/wasm/tx_bond/src/lib.rs @@ -5,7 +5,7 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { let data = ctx.get_tx_data(&tx_data)?; - let bond = transaction::pos::Bond::try_from_slice(&data[..]) + let bond = data::pos::Bond::try_from_slice(&data[..]) .wrap_err("Failed to decode Bond tx data")?; ctx.bond_tokens(bond.source.as_ref(), &bond.validator, bond.amount) @@ -19,7 +19,8 @@ mod tests { use namada_tests::log::test; use namada_tests::native_vp::pos::init_pos; use namada_tests::native_vp::TestNativeVpEnv; - use namada_tests::tx::*; + use namada_tests::tx_env; + use namada_tests::tx_env::{ctx, TestTxEnvExt}; use namada_tests::validation::PosVp; use namada_tx_prelude::address::testing::{ arb_established_address, arb_non_internal_address, @@ -63,7 +64,7 @@ mod tests { fn test_tx_bond_aux( initial_stake: token::Amount, - bond: transaction::pos::Bond, + bond: data::pos::Bond, key: key::common::SecretKey, pos_params: OwnedPosParams, ) -> TxResult { @@ -98,7 +99,7 @@ mod tests { let pos_params = init_pos(&genesis_validators[..], &pos_params, Epoch(0)); - let native_token = tx_host_env::with(|tx_env| { + let native_token = tx_env::with(|tx_env| { if let Some(source) = &bond.source { tx_env.spawn_accounts([source]); } @@ -324,7 +325,7 @@ mod tests { } // Use the tx_env to run PoS VP - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); let gas_meter = RefCell::new(VpGasMeter::new_from_tx_meter( &tx_env.gas_meter.borrow(), )); @@ -349,25 +350,21 @@ mod tests { (bond in arb_bond(((i64::MAX/8) as u64) - u128::try_from(initial_stake).unwrap() as u64), // Use the generated initial stake too initial_stake in Just(initial_stake), - ) -> (token::Amount, transaction::pos::Bond) { + ) -> (token::Amount, data::pos::Bond) { (initial_stake, bond) } } - fn arb_bond( - max_amount: u64, - ) -> impl Strategy { + fn arb_bond(max_amount: u64) -> impl Strategy { ( arb_established_address(), prop::option::of(arb_non_internal_address()), token::testing::arb_amount_non_zero_ceiled(max_amount), ) - .prop_map(|(validator, source, amount)| { - transaction::pos::Bond { - validator: Address::Established(validator), - amount, - source, - } + .prop_map(|(validator, source, amount)| data::pos::Bond { + validator: Address::Established(validator), + amount, + source, }) } } diff --git a/wasm/tx_change_consensus_key/src/lib.rs b/wasm/tx_change_consensus_key/src/lib.rs index 94ab22c2ba..b437748fa7 100644 --- a/wasm/tx_change_consensus_key/src/lib.rs +++ b/wasm/tx_change_consensus_key/src/lib.rs @@ -1,7 +1,7 @@ //! A tx for a validator to change their consensus key. use booleans::ResultBoolExt; -use namada_tx_prelude::transaction::pos::ConsensusKeyChange; +use namada_tx_prelude::data::pos::ConsensusKeyChange; use namada_tx_prelude::*; #[transaction] @@ -10,7 +10,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { let ConsensusKeyChange { validator, consensus_key, - } = transaction::pos::ConsensusKeyChange::try_from_slice(&data[..]) + } = data::pos::ConsensusKeyChange::try_from_slice(&data[..]) .wrap_err("Failed to decode ConsensusKeyChange value")?; // Check that the tx has been signed with the new consensus key diff --git a/wasm/tx_change_validator_commission/src/lib.rs b/wasm/tx_change_validator_commission/src/lib.rs index 2218f5db61..209b8c45de 100644 --- a/wasm/tx_change_validator_commission/src/lib.rs +++ b/wasm/tx_change_validator_commission/src/lib.rs @@ -1,6 +1,6 @@ //! A tx for a validator to change their commission rate for PoS rewards. -use namada_tx_prelude::transaction::pos::CommissionChange; +use namada_tx_prelude::data::pos::CommissionChange; use namada_tx_prelude::*; #[transaction] @@ -9,7 +9,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { let CommissionChange { validator, new_rate, - } = transaction::pos::CommissionChange::try_from_slice(&data[..]) + } = data::pos::CommissionChange::try_from_slice(&data[..]) .wrap_err("Failed to decode CommissionChange value")?; ctx.change_validator_commission_rate(&validator, &new_rate) .wrap_err("Failed to change validator's commission rate") @@ -23,7 +23,8 @@ mod tests { use namada_tests::log::test; use namada_tests::native_vp::pos::init_pos; use namada_tests::native_vp::TestNativeVpEnv; - use namada_tests::tx::*; + use namada_tests::tx_env; + use namada_tests::tx_env::ctx; use namada_tests::validation::PosVp; use namada_tx_prelude::address::testing::arb_established_address; use namada_tx_prelude::chain::ChainId; @@ -62,7 +63,7 @@ mod tests { fn test_tx_change_validator_commission_aux( initial_rate: Dec, max_change: Dec, - commission_change: transaction::pos::CommissionChange, + commission_change: data::pos::CommissionChange, key: key::common::SecretKey, pos_params: OwnedPosParams, ) -> TxResult { @@ -149,7 +150,7 @@ mod tests { } // Use the tx_env to run PoS VP - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); let gas_meter = RefCell::new(VpGasMeter::new_from_tx_meter( &tx_env.gas_meter.borrow(), )); @@ -216,7 +217,7 @@ mod tests { fn arb_commission_change( rate_pre: Dec, max_change: Dec, - ) -> impl Strategy { + ) -> impl Strategy { ( arb_established_address(), if max_change.is_zero() { @@ -226,7 +227,7 @@ mod tests { }, ) .prop_map(|(validator, new_rate)| { - transaction::pos::CommissionChange { + data::pos::CommissionChange { validator: Address::Established(validator), new_rate, } @@ -234,8 +235,7 @@ mod tests { } fn arb_commission_info() - -> impl Strategy - { + -> impl Strategy { let min = Dec::zero(); let max = Dec::one(); let non_zero_min = Dec::one() / scale(); diff --git a/wasm/tx_change_validator_metadata/src/lib.rs b/wasm/tx_change_validator_metadata/src/lib.rs index ad8ae30fb8..52951f1fba 100644 --- a/wasm/tx_change_validator_metadata/src/lib.rs +++ b/wasm/tx_change_validator_metadata/src/lib.rs @@ -1,7 +1,7 @@ //! A tx for a validator to change various metadata, including its commission //! rate. -use namada_tx_prelude::transaction::pos::MetaDataChange; +use namada_tx_prelude::data::pos::MetaDataChange; use namada_tx_prelude::*; #[transaction] @@ -16,7 +16,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { avatar, name, commission_rate, - } = transaction::pos::MetaDataChange::try_from_slice(&data[..]) + } = data::pos::MetaDataChange::try_from_slice(&data[..]) .wrap_err("Failed to decode MetaDataChange value")?; ctx.change_validator_metadata( &validator, diff --git a/wasm/tx_claim_rewards/src/lib.rs b/wasm/tx_claim_rewards/src/lib.rs index eedd62c231..396ec6955f 100644 --- a/wasm/tx_claim_rewards/src/lib.rs +++ b/wasm/tx_claim_rewards/src/lib.rs @@ -6,7 +6,7 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { let data = ctx.get_tx_data(&tx_data)?; - let withdraw = transaction::pos::Withdraw::try_from_slice(&data[..]) + let withdraw = data::pos::Withdraw::try_from_slice(&data[..]) .wrap_err("Failed to decode Withdraw value")?; ctx.claim_reward_tokens(withdraw.source.as_ref(), &withdraw.validator) diff --git a/wasm/tx_redelegate/src/lib.rs b/wasm/tx_redelegate/src/lib.rs index 3ccbd7520e..060ffd0549 100644 --- a/wasm/tx_redelegate/src/lib.rs +++ b/wasm/tx_redelegate/src/lib.rs @@ -6,12 +6,12 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { let data = ctx.get_tx_data(&tx_data)?; - let transaction::pos::Redelegation { + let data::pos::Redelegation { src_validator, dest_validator, owner, amount, - } = transaction::pos::Redelegation::try_from_slice(&data[..]) + } = data::pos::Redelegation::try_from_slice(&data[..]) .wrap_err("Failed to decode a Redelegation tx data")?; ctx.redelegate_tokens(&owner, &src_validator, &dest_validator, amount) .wrap_err("Failed to redelegate tokens") @@ -25,7 +25,8 @@ mod tests { use namada_tests::log::test; use namada_tests::native_vp::pos::init_pos; use namada_tests::native_vp::TestNativeVpEnv; - use namada_tests::tx::*; + use namada_tests::tx_env; + use namada_tests::tx_env::{ctx, TestTxEnvExt}; use namada_tests::validation::PosVp; use namada_tx_prelude::address::InternalAddress; use namada_tx_prelude::chain::ChainId; @@ -67,7 +68,7 @@ mod tests { fn test_tx_redelegate_aux( initial_stake: token::Amount, - redelegation: transaction::pos::Redelegation, + redelegation: data::pos::Redelegation, key: key::common::SecretKey, pos_params: OwnedPosParams, ) -> TxResult { @@ -114,7 +115,7 @@ mod tests { let pos_params = init_pos(&genesis_validators[..], &pos_params, Epoch(0)); - let native_token = tx_host_env::with(|tx_env| { + let native_token = tx_env::with(|tx_env| { let native_token = tx_env.state.in_mem().native_token.clone(); let owner = &redelegation.owner; tx_env.spawn_accounts([owner]); @@ -131,7 +132,7 @@ mod tests { &redelegation.src_validator, initial_stake, )?; - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); let tx_code = vec![]; let tx_data = redelegation.serialize_to_vec(); @@ -360,7 +361,7 @@ mod tests { } // Use the tx_env to run PoS VP - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); let gas_meter = RefCell::new(VpGasMeter::new_from_tx_meter( &tx_env.gas_meter.borrow(), )); @@ -377,8 +378,7 @@ mod tests { /// Generates an initial validator stake and a redelegation, while making /// sure that the `initial_stake >= redelegation.amount`. fn arb_initial_stake_and_redelegation() - -> impl Strategy - { + -> impl Strategy { // Generate initial stake token::testing::arb_amount_ceiled((i64::MAX / 8) as u64).prop_flat_map( |initial_stake| { @@ -396,7 +396,7 @@ mod tests { /// above. fn arb_redelegation( max_amount: u64, - ) -> impl Strategy { + ) -> impl Strategy { ( address::testing::arb_established_address(), address::testing::arb_established_address(), @@ -418,7 +418,7 @@ mod tests { let src_validator = Address::Established(src_validator); let dest_validator = Address::Established(dest_validator); - Some(transaction::pos::Redelegation { + Some(data::pos::Redelegation { src_validator, dest_validator, owner, diff --git a/wasm/tx_unbond/src/lib.rs b/wasm/tx_unbond/src/lib.rs index 3188c16673..e5a605d268 100644 --- a/wasm/tx_unbond/src/lib.rs +++ b/wasm/tx_unbond/src/lib.rs @@ -6,7 +6,7 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { let data = ctx.get_tx_data(&tx_data)?; - let unbond = transaction::pos::Unbond::try_from_slice(&data[..]) + let unbond = data::pos::Unbond::try_from_slice(&data[..]) .wrap_err("Failed to decode Unbond tx data")?; ctx.unbond_tokens(unbond.source.as_ref(), &unbond.validator, unbond.amount) @@ -25,7 +25,8 @@ mod tests { use namada_tests::log::test; use namada_tests::native_vp::pos::init_pos; use namada_tests::native_vp::TestNativeVpEnv; - use namada_tests::tx::*; + use namada_tests::tx_env; + use namada_tests::tx_env::{ctx, TestTxEnvExt}; use namada_tests::validation::PosVp; use namada_tx_prelude::address::InternalAddress; use namada_tx_prelude::chain::ChainId; @@ -67,7 +68,7 @@ mod tests { fn test_tx_unbond_aux( initial_stake: token::Amount, - unbond: transaction::pos::Unbond, + unbond: data::pos::Unbond, key: key::common::SecretKey, pos_params: OwnedPosParams, ) -> TxResult { @@ -110,7 +111,7 @@ mod tests { let pos_params = init_pos(&genesis_validators[..], &pos_params, Epoch(0)); - let native_token = tx_host_env::with(|tx_env| { + let native_token = tx_env::with(|tx_env| { let native_token = tx_env.state.in_mem().native_token.clone(); if is_delegation { let source = unbond.source.as_ref().unwrap(); @@ -135,7 +136,7 @@ mod tests { initial_stake, )?; } - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); let tx_code = vec![]; let tx_data = unbond.serialize_to_vec(); @@ -336,7 +337,7 @@ mod tests { } // Use the tx_env to run PoS VP - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); let gas_meter = RefCell::new(VpGasMeter::new_from_tx_meter( &tx_env.gas_meter.borrow(), )); @@ -353,7 +354,7 @@ mod tests { /// Generates an initial validator stake and a unbond, while making sure /// that the `initial_stake >= unbond.amount`. fn arb_initial_stake_and_unbond() - -> impl Strategy { + -> impl Strategy { // Generate initial stake token::testing::arb_amount_ceiled((i64::MAX / 8) as u64).prop_flat_map( |initial_stake| { @@ -367,9 +368,7 @@ mod tests { } /// Generates an arbitrary unbond, with the amount constrained from above. - fn arb_unbond( - max_amount: u64, - ) -> impl Strategy { + fn arb_unbond(max_amount: u64) -> impl Strategy { ( address::testing::arb_established_address(), prop::option::of(address::testing::arb_non_internal_address()), @@ -377,7 +376,7 @@ mod tests { ) .prop_map(|(validator, source, amount)| { let validator = Address::Established(validator); - transaction::pos::Unbond { + data::pos::Unbond { validator, amount, source, diff --git a/wasm/tx_update_steward_commission/src/lib.rs b/wasm/tx_update_steward_commission/src/lib.rs index d03c411342..4dd5f4ef2a 100644 --- a/wasm/tx_update_steward_commission/src/lib.rs +++ b/wasm/tx_update_steward_commission/src/lib.rs @@ -1,7 +1,7 @@ //! A tx to update the commission distribution for a steward use namada_tx_prelude::action::{Action, PgfAction, Write}; -use namada_tx_prelude::transaction::pgf::UpdateStewardCommission; +use namada_tx_prelude::data::pgf::UpdateStewardCommission; use namada_tx_prelude::*; #[transaction] diff --git a/wasm/tx_withdraw/src/lib.rs b/wasm/tx_withdraw/src/lib.rs index 7a0dc5591d..2cae87c961 100644 --- a/wasm/tx_withdraw/src/lib.rs +++ b/wasm/tx_withdraw/src/lib.rs @@ -6,7 +6,7 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { let data = ctx.get_tx_data(&tx_data)?; - let withdraw = transaction::pos::Withdraw::try_from_slice(&data[..]) + let withdraw = data::pos::Withdraw::try_from_slice(&data[..]) .wrap_err("Failed to decode Withdraw tx data")?; let slashed = ctx @@ -25,7 +25,8 @@ mod tests { use namada_tests::log::test; use namada_tests::native_vp::pos::init_pos; use namada_tests::native_vp::TestNativeVpEnv; - use namada_tests::tx::*; + use namada_tests::tx_env; + use namada_tests::tx_env::{ctx, TestTxEnvExt}; use namada_tests::validation::PosVp; use namada_tx_prelude::address::testing::{ arb_established_address, arb_non_internal_address, @@ -69,7 +70,7 @@ mod tests { fn test_tx_withdraw_aux( initial_stake: token::Amount, unbonded_amount: token::Amount, - withdraw: transaction::pos::Withdraw, + withdraw: data::pos::Withdraw, key: key::common::SecretKey, pos_params: OwnedPosParams, ) -> TxResult { @@ -111,7 +112,7 @@ mod tests { let pos_params = init_pos(&genesis_validators[..], &pos_params, Epoch(0)); - let native_token = tx_host_env::with(|tx_env| { + let native_token = tx_env::with(|tx_env| { let native_token = tx_env.state.in_mem().native_token.clone(); if is_delegation { let source = withdraw.source.as_ref().unwrap(); @@ -143,12 +144,12 @@ mod tests { unbonded_amount, )?; - tx_host_env::commit_tx_and_block(); + tx_env::commit_tx_and_block(); // Fast forward to pipeline + unbonding + cubic_slashing_window_length // offset epoch so that it's possible to withdraw the unbonded // tokens - tx_host_env::with(|env| { + tx_env::with(|env| { for _ in 0..(pos_params.pipeline_len + pos_params.unbonding_len + pos_params.cubic_slashing_window_length) @@ -169,7 +170,7 @@ mod tests { ); assert_eq!( - tx_host_env::with(|env| env.state.in_mem().block.epoch), + tx_env::with(|env| env.state.in_mem().block.epoch), Epoch( pos_params.pipeline_len + pos_params.unbonding_len @@ -222,7 +223,7 @@ mod tests { assert_eq!(pos_balance_pre - pos_balance_post, unbonded_amount); // Use the tx_env to run PoS VP - let tx_env = tx_host_env::take(); + let tx_env = tx_env::take(); let gas_meter = RefCell::new(VpGasMeter::new_from_tx_meter( &tx_env.gas_meter.borrow(), )); @@ -252,16 +253,14 @@ mod tests { }) } - fn arb_withdraw() -> impl Strategy { + fn arb_withdraw() -> impl Strategy { ( arb_established_address(), prop::option::of(arb_non_internal_address()), ) - .prop_map(|(validator, source)| { - transaction::pos::Withdraw { - validator: Address::Established(validator), - source, - } + .prop_map(|(validator, source)| data::pos::Withdraw { + validator: Address::Established(validator), + source, }) } } diff --git a/wasm/vp_implicit/src/lib.rs b/wasm/vp_implicit/src/lib.rs index cffc14fe06..1b5768ac62 100644 --- a/wasm/vp_implicit/src/lib.rs +++ b/wasm/vp_implicit/src/lib.rs @@ -252,9 +252,9 @@ mod tests { use namada_test_utils::TestWasms; use namada_tests::log::test; use namada_tests::native_vp::pos::init_pos; - use namada_tests::tx::data::TxType; - use namada_tests::tx::{ - self, tx_host_env, Authorization, Code, Data, TestTxEnv, + use namada_tests::tx_env::data::TxType; + use namada_tests::tx_env::{ + self, Authorization, Code, Data, TestTxEnv, TestTxEnvExt, }; use namada_tests::vp::vp_host_env::storage::Key; use namada_tests::vp::*; @@ -263,7 +263,7 @@ mod tests { use namada_tx_prelude::dec::Dec; use namada_tx_prelude::proof_of_stake::parameters::OwnedPosParams; use namada_tx_prelude::proof_of_stake::types::GenesisValidator; - use namada_tx_prelude::{StorageWrite, TxEnv}; + use namada_tx_prelude::{PosCtxExt, StorageWrite, TxEnv}; use namada_vp_prelude::account::AccountPublicKeysMap; use namada_vp_prelude::key::RefTo; use proptest::prelude::*; @@ -311,7 +311,7 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(addr.clone(), tx_env, |_address| { // Apply reveal_pk in a transaction - tx_host_env::key::reveal_pk(tx::ctx(), &public_key).unwrap(); + tx_env::key::reveal_pk(tx_env::ctx(), &public_key).unwrap(); }); let vp_env = vp_host_env::take(); @@ -337,14 +337,14 @@ mod tests { // Commit the transaction and create another tx_env let vp_env = vp_host_env::take(); - tx_host_env::set_from_vp_env(vp_env); - tx_host_env::commit_tx_and_block(); - let tx_env = tx_host_env::take(); + tx_env::set_from_vp_env(vp_env); + tx_env::commit_tx_and_block(); + let tx_env = tx_env::take(); // Try to reveal it again vp_host_env::init_from_tx(addr.clone(), tx_env, |_address| { // Apply reveal_pk in a transaction - tx_host_env::key::reveal_pk(tx::ctx(), &public_key).unwrap(); + tx_env::key::reveal_pk(tx_env::ctx(), &public_key).unwrap(); }); let vp_env = vp_host_env::take(); @@ -388,7 +388,7 @@ mod tests { vp_host_env::init_from_tx(addr.clone(), tx_env, |_address| { // Do the same as reveal_pk, but with the wrong key let _ = account::set_public_key_at( - tx_host_env::ctx(), + tx_env::ctx(), &addr, &mismatched_pk, 0, @@ -454,8 +454,8 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Apply transfer in a transaction - tx_host_env::token::transfer( - tx::ctx(), + tx_env::token::transfer( + tx_env::ctx(), &source, address, &token, @@ -513,7 +513,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); tx_env.init_parameters(None, Some(vec![]), Some(vec![])); @@ -544,10 +544,10 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |_address| { // Bond the tokens, then unbond some of them - tx::ctx() + tx_env::ctx() .bond_tokens(Some(&vp_owner), &validator, bond_amount) .unwrap(); - tx::ctx() + tx_env::ctx() .unbond_tokens(Some(&vp_owner), &validator, unbond_amount) .unwrap(); }); @@ -611,7 +611,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); let secret_key = key::testing::keypair_1(); let public_key = secret_key.ref_to(); @@ -640,10 +640,10 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |_address| { // Bond the tokens, then unbond some of them - tx::ctx() + tx_env::ctx() .bond_tokens(Some(&vp_owner), &validator, bond_amount) .unwrap(); - tx::ctx() + tx_env::ctx() .unbond_tokens(Some(&vp_owner), &validator, unbond_amount) .unwrap(); }); @@ -708,8 +708,8 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Apply transfer in a transaction - tx_host_env::token::transfer( - tx::ctx(), + tx_env::token::transfer( + tx_env::ctx(), address, &target, &token, @@ -779,8 +779,8 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Apply transfer in a transaction - tx_host_env::token::transfer( - tx::ctx(), + tx_env::token::transfer( + tx_env::ctx(), address, &target, &token, @@ -850,10 +850,10 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { - tx::ctx().insert_verifier(address).unwrap(); + tx_env::ctx().insert_verifier(address).unwrap(); // Apply transfer in a transaction - tx_host_env::token::transfer( - tx::ctx(), + tx_env::token::transfer( + tx_env::ctx(), &source, &target, &token, @@ -891,7 +891,7 @@ mod tests { let addr: Address = (&pk).into(); // Generate a storage key other than its VP key (VP cannot be // modified directly via `write`, it has to be modified via - // `tx::update_validity_predicate`. + // `tx_env::update_validity_predicate`. let storage_key = arb_account_storage_key_no_vp(addr.clone()); (Just(sk), Just(addr), storage_key) }) @@ -918,9 +918,9 @@ mod tests { vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |_address| { // Write or delete some data in the transaction if let Some(value) = &storage_value { - tx::ctx().write(&storage_key, value).unwrap(); + tx_env::ctx().write(&storage_key, value).unwrap(); } else { - tx::ctx().delete(&storage_key).unwrap(); + tx_env::ctx().delete(&storage_key).unwrap(); } }); @@ -957,15 +957,15 @@ mod tests { tx_env.spawn_accounts(storage_key_addresses); let public_key = secret_key.ref_to(); - let _ = account::set_public_key_at(tx_host_env::ctx(), &vp_owner, &public_key, 0); + let _ = account::set_public_key_at(tx_env::ctx(), &vp_owner, &public_key, 0); // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |_address| { // Write or delete some data in the transaction if let Some(value) = &storage_value { - tx::ctx().write(&storage_key, value).unwrap(); + tx_env::ctx().write(&storage_key, value).unwrap(); } else { - tx::ctx().delete(&storage_key).unwrap(); + tx_env::ctx().delete(&storage_key).unwrap(); } }); @@ -1011,7 +1011,7 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Update VP in a transaction - tx::ctx() + tx_env::ctx() .update_validity_predicate(address, vp_hash, &None) .unwrap(); }); diff --git a/wasm/vp_user/src/lib.rs b/wasm/vp_user/src/lib.rs index 78544afca6..e0a5ca089c 100644 --- a/wasm/vp_user/src/lib.rs +++ b/wasm/vp_user/src/lib.rs @@ -223,9 +223,9 @@ mod tests { // Use this as `#[test]` annotation to enable logging use namada_tests::log::test; use namada_tests::native_vp::pos::init_pos; - use namada_tests::tx::data::{self, TxType}; - use namada_tests::tx::{ - self, tx_host_env, Authorization, Code, Data, TestTxEnv, + use namada_tests::tx_env::data::{self, TxType}; + use namada_tests::tx_env::{ + self, Authorization, Code, Data, TestTxEnv, TestTxEnvExt, }; use namada_tests::vp::vp_host_env::storage::Key; use namada_tests::vp::*; @@ -235,7 +235,7 @@ mod tests { OwnedPosParams, PosParams, }; use namada_tx_prelude::proof_of_stake::types::GenesisValidator; - use namada_tx_prelude::{StorageWrite, TxEnv}; + use namada_tx_prelude::{PosCtxExt, StorageWrite, TxEnv}; use namada_vp_prelude::account::AccountPublicKeysMap; use namada_vp_prelude::key::RefTo; use proof_of_stake::jail_validator; @@ -305,8 +305,8 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Apply transfer in a transaction - tx_host_env::token::transfer( - tx::ctx(), + tx_env::token::transfer( + tx_env::ctx(), &source, address, &token, @@ -366,8 +366,8 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Apply transfer in a transaction - tx_host_env::token::transfer( - tx::ctx(), + tx_env::token::transfer( + tx_env::ctx(), address, &target, &token, @@ -436,8 +436,8 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Apply transfer in a transaction - tx_host_env::token::transfer( - tx::ctx(), + tx_env::token::transfer( + tx_env::ctx(), address, &target, &token, @@ -499,7 +499,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); let secret_key = key::testing::keypair_1(); let public_key = secret_key.ref_to(); @@ -528,10 +528,10 @@ mod tests { // Initialize VP environment from non-validator PoS actions vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |_address| { // Bond the tokens, then unbond some of them - tx::ctx() + tx_env::ctx() .bond_tokens(Some(&vp_owner), &validator, bond_amount) .unwrap(); - tx::ctx() + tx_env::ctx() .unbond_tokens(Some(&vp_owner), &validator, unbond_amount) .unwrap(); }); @@ -642,7 +642,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); // Set the validator accounts' keys tx_env.init_account_storage(&validator1, vec![ck1], 1); tx_env.init_account_storage(&validator2, vec![ck2], 1); @@ -671,7 +671,7 @@ mod tests { // Initialize VP environment vp_host_env::init_from_tx(validator3.clone(), tx_env, |_address| { // Unjail validator3 - tx::ctx().unjail_validator(&validator3).unwrap() + tx_env::ctx().unjail_validator(&validator3).unwrap() }); let pks_map = AccountPublicKeysMap::from_iter(vec![ck3]); @@ -744,7 +744,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); let secret_key = key::testing::keypair_1(); let public_key = secret_key.ref_to(); @@ -784,7 +784,7 @@ mod tests { avatar: None, name: None, }; - tx::ctx().become_validator(args).unwrap(); + tx_env::ctx().become_validator(args).unwrap(); }); let vp_env = vp_host_env::take(); @@ -841,7 +841,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); let secret_key = key::testing::keypair_1(); let public_key = secret_key.ref_to(); @@ -869,14 +869,14 @@ mod tests { // Validator PoS actions vp_host_env::init_from_tx(validator.clone(), tx_env, |_address| { // Bond the tokens, then unbond some of them - tx::ctx() + tx_env::ctx() .bond_tokens(Some(&validator), &validator, bond_amount) .unwrap(); - tx::ctx() + tx_env::ctx() .unbond_tokens(Some(&validator), &validator, unbond_amount) .unwrap(); - tx::ctx().deactivate_validator(&validator).unwrap(); - tx::ctx() + tx_env::ctx().deactivate_validator(&validator).unwrap(); + tx_env::ctx() .change_validator_metadata( &validator, Some("email".to_owned()), @@ -948,7 +948,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); let secret_key = key::testing::keypair_1(); let public_key = secret_key.ref_to(); @@ -978,10 +978,10 @@ mod tests { // Initialize VP environment from non-validator PoS actions vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |_address| { // Bond the tokens, then unbond some of them - tx::ctx() + tx_env::ctx() .bond_tokens(Some(&vp_owner), &validator, bond_amount) .unwrap(); - tx::ctx() + tx_env::ctx() .unbond_tokens(Some(&vp_owner), &validator, unbond_amount) .unwrap(); }); @@ -1039,7 +1039,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); let secret_key = key::testing::keypair_1(); let public_key = secret_key.ref_to(); @@ -1079,7 +1079,7 @@ mod tests { avatar: None, name: None, }; - tx::ctx().become_validator(args).unwrap(); + tx_env::ctx().become_validator(args).unwrap(); }); let pks_map = AccountPublicKeysMap::from_iter(vec![public_key]); @@ -1139,7 +1139,7 @@ mod tests { init_pos(&genesis_validators[..], &pos_params, Epoch(0)); // Initialize a tx environment - let mut tx_env = tx_host_env::take(); + let mut tx_env = tx_env::take(); let secret_key = key::testing::keypair_1(); let public_key = secret_key.ref_to(); @@ -1168,14 +1168,14 @@ mod tests { // Validator PoS actions vp_host_env::init_from_tx(validator.clone(), tx_env, |_address| { // Bond the tokens, then unbond some of them - tx::ctx() + tx_env::ctx() .bond_tokens(Some(&validator), &validator, bond_amount) .unwrap(); - tx::ctx() + tx_env::ctx() .unbond_tokens(Some(&validator), &validator, unbond_amount) .unwrap(); - tx::ctx().deactivate_validator(&validator).unwrap(); - tx::ctx() + tx_env::ctx().deactivate_validator(&validator).unwrap(); + tx_env::ctx() .change_validator_metadata( &validator, Some("email".to_owned()), @@ -1238,10 +1238,10 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { - tx::ctx().insert_verifier(address).unwrap(); + tx_env::ctx().insert_verifier(address).unwrap(); // Apply transfer in a transaction - tx_host_env::token::transfer( - tx::ctx(), + tx_env::token::transfer( + tx_env::ctx(), &source, &target, &token, @@ -1276,7 +1276,7 @@ mod tests { (address in arb_non_internal_address()) // Generate a storage key other than its VP key (VP cannot be // modified directly via `write`, it has to be modified via - // `tx::update_validity_predicate`. + // `tx_env::update_validity_predicate`. (storage_key in arb_account_storage_key_no_vp(address.clone()), // Use the generated address too address in Just(address)) @@ -1306,9 +1306,9 @@ mod tests { vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |_address| { // Write or delete some data in the transaction if let Some(value) = &storage_value { - tx::ctx().write(&storage_key, value).unwrap(); + tx_env::ctx().write(&storage_key, value).unwrap(); } else { - tx::ctx().delete(&storage_key).unwrap(); + tx_env::ctx().delete(&storage_key).unwrap(); } }); @@ -1356,9 +1356,9 @@ mod tests { vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |_address| { // Write or delete some data in the transaction if let Some(value) = &storage_value { - tx::ctx().write(&storage_key, value).unwrap(); + tx_env::ctx().write(&storage_key, value).unwrap(); } else { - tx::ctx().delete(&storage_key).unwrap(); + tx_env::ctx().delete(&storage_key).unwrap(); } }); @@ -1402,7 +1402,7 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Update VP in a transaction - tx::ctx() + tx_env::ctx() .update_validity_predicate(address, vp_hash, &None) .unwrap(); }); @@ -1455,7 +1455,7 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Update VP in a transaction - tx::ctx() + tx_env::ctx() .update_validity_predicate(address, vp_hash, &None) .unwrap(); }); @@ -1506,7 +1506,7 @@ mod tests { // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { // Update VP in a transaction - tx::ctx() + tx_env::ctx() .update_validity_predicate(address, vp_hash, &None) .unwrap(); }); diff --git a/wasm_for_tests/Cargo.lock b/wasm_for_tests/Cargo.lock index 5edf14667d..c9e84068f3 100644 --- a/wasm_for_tests/Cargo.lock +++ b/wasm_for_tests/Cargo.lock @@ -2315,7 +2315,11 @@ version = "0.43.0" dependencies = [ "namada_core", "namada_events", + "namada_gas", + "namada_state", "namada_storage", + "namada_tx", + "namada_vm_env", ] [[package]] diff --git a/wasm_for_tests/vp_eval/src/lib.rs b/wasm_for_tests/vp_eval/src/lib.rs index 8fd58d66f2..805771f592 100644 --- a/wasm_for_tests/vp_eval/src/lib.rs +++ b/wasm_for_tests/vp_eval/src/lib.rs @@ -8,7 +8,7 @@ fn validate_tx( _keys_changed: BTreeSet, _verifiers: BTreeSet
, ) -> VpResult { - use namada_tx_prelude::transaction::eval_vp::EvalVp; + use namada_tx_prelude::data::eval_vp::EvalVp; let BatchedTx { tx: tx_data, ref cmt,