From 3127b764c06d677cc5d18abaf57c6ddedafbe35a Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Thu, 27 Jun 2024 12:02:14 +0200 Subject: [PATCH 1/9] Generalized the TransparentTransfer to support a shielded action. --- crates/sdk/src/lib.rs | 8 ++-- crates/sdk/src/signing.rs | 8 ++-- crates/sdk/src/tx.rs | 5 ++- crates/token/src/lib.rs | 12 +++++- wasm/checksums.json | 55 +++++++++++++------------ wasm/tx_transparent_transfer/src/lib.rs | 22 +++++++++- 6 files changed, 71 insertions(+), 39 deletions(-) diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 7d83a93895..274639f8f2 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -1117,8 +1117,8 @@ pub mod testing { code_hash in arb_hash(), (masp_tx_type, (shielded_transfer, asset_types, build_params)) in prop_oneof![ (Just(MaspTxType::Shielded), arb_shielded_transfer(0..MAX_ASSETS)), - (Just(MaspTxType::Shielding), arb_shielding_transfer(encode_address(&transfers.0.first().unwrap().source), 1)), - (Just(MaspTxType::Unshielding), arb_deshielding_transfer(encode_address(&transfers.0.first().unwrap().target), 1)), + (Just(MaspTxType::Shielding), arb_shielding_transfer(encode_address(&transfers.data.first().unwrap().source), 1)), + (Just(MaspTxType::Unshielding), arb_deshielding_transfer(encode_address(&transfers.data.first().unwrap().target), 1)), ], transfers in Just(transfers), ) -> (Tx, TxData) { @@ -1143,7 +1143,7 @@ pub mod testing { decoded.denom, ); tx.add_code_from_hash(code_hash, Some(TX_SHIELDING_TRANSFER_WASM.to_owned())); - let data = transfers.0.into_iter().map(|transfer| + let data = transfers.data.into_iter().map(|transfer| ShieldingTransferData{ source: transfer.source, token: token.clone(), @@ -1163,7 +1163,7 @@ pub mod testing { decoded.denom, ); tx.add_code_from_hash(code_hash, Some(TX_UNSHIELDING_TRANSFER_WASM.to_owned())); - let data = transfers.0.into_iter().map(|transfer| + let data = transfers.data.into_iter().map(|transfer| UnshieldingTransferData{ target: transfer.target, token: token.clone(), diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index aa9417c36f..2616d47a98 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -718,7 +718,7 @@ impl TokenTransfer<'_> { fn sources(&self) -> Vec<&Address> { match self { TokenTransfer::Transparent(transfers) => transfers - .0 + .data .iter() .map(|transfer| &transfer.source) .collect(), @@ -735,7 +735,7 @@ impl TokenTransfer<'_> { fn targets(&self) -> Vec<&Address> { match self { TokenTransfer::Transparent(transfers) => transfers - .0 + .data .iter() .map(|transfer| &transfer.target) .collect(), @@ -761,7 +761,7 @@ impl TokenTransfer<'_> { match address { TransferSide::Source(source) => { - for transfer in &transfers.0 { + for transfer in &transfers.data { if source == &transfer.source { Self::update_token_amount_map( &mut map, @@ -772,7 +772,7 @@ impl TokenTransfer<'_> { } } TransferSide::Target(target) => { - for transfer in &transfers.0 { + for transfer in &transfers.data { if target == &transfer.target { Self::update_token_amount_map( &mut map, diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index 60e6c19074..6757bc7e67 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -2928,7 +2928,10 @@ pub async fn build_transparent_transfer( transfers.push(transfer_data); } // Construct the corresponding transparent Transfer object - let transfer = token::TransparentTransfer(transfers); + let transfer = token::TransparentTransfer { + data: transfers, + shielded_section_hash: None, + }; let tx = build_pow_flag( context, diff --git a/crates/token/src/lib.rs b/crates/token/src/lib.rs index 4470d08925..758eeae2d9 100644 --- a/crates/token/src/lib.rs +++ b/crates/token/src/lib.rs @@ -82,7 +82,12 @@ where Serialize, Deserialize, )] -pub struct TransparentTransfer(pub Vec); +pub struct TransparentTransfer { + /// Transfer-specific data + pub data: Vec, + /// Hash of tx section that contains the MASP transaction + pub shielded_section_hash: Option, +} /// Arguments for a transparent token transfer #[derive( @@ -307,6 +312,9 @@ pub mod testing { number_of_txs: usize, ) -> impl Strategy { proptest::collection::vec(arb_transparent_transfer(), 0..number_of_txs) - .prop_map(TransparentTransfer) + .prop_map(|data| TransparentTransfer { + data, + shielded_section_hash: None, + }) } } diff --git a/wasm/checksums.json b/wasm/checksums.json index ae9470452a..0ed3052622 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,29 +1,30 @@ { - "tx_become_validator.wasm": "tx_become_validator.9499cd491944c2a1eca4544d529c2ac133b504c4ac10b121d30d092b13fb486f.wasm", - "tx_bond.wasm": "tx_bond.732f85dd8ef096a1e358296287f2457f362663e0f23f68333fa209d8d97ae494.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.e940f9695742c8967811115bc28f9eb4458d500a8522657174997d4c9d946198.wasm", - "tx_change_consensus_key.wasm": "tx_change_consensus_key.b5bf392325e332f19901eb9237cb32766cbee0e64c9cc47d65dd62882f716337.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.243491629bc622b6ca7a0e9179b635f1d269b58a3597121fab2e3d135749b016.wasm", - "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.0e7d7586c52c29c51256020058a93665203af00da985371a9df1702f208d9cd1.wasm", - "tx_claim_rewards.wasm": "tx_claim_rewards.ae5b42e465e46c68c5f185321a34dceeffa8e56b0994ea680b6cb70a8880aed5.wasm", - "tx_deactivate_validator.wasm": "tx_deactivate_validator.fe46741d2440a2a5b9e01ece72a0938e6e1727ce97a2753951aac101fc667d88.wasm", - "tx_ibc.wasm": "tx_ibc.c630d1b1ca76a6c877d0d0fb7c91ebeed99f263cec1c9cd37ce9fce1513ba347.wasm", - "tx_init_account.wasm": "tx_init_account.afe7d7be1b9781f5fa66855b8195bc2bea897c9ee20d729d0728145716da5305.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.10bfbf2c4d87db3d1ae3c319f140db85f1ae44ea54c92aa3ece4b9bf8dbdefa9.wasm", - "tx_reactivate_validator.wasm": "tx_reactivate_validator.a71e116b6ab4ac37940dd32361e922ed43e8d0b9bb9129f4fd0e89dae8f3c902.wasm", - "tx_redelegate.wasm": "tx_redelegate.bcd3f7332de530df6407a6d6cb77046d43904609bea467065028c45f50e775ef.wasm", - "tx_resign_steward.wasm": "tx_resign_steward.d60c11ddfef084421ed46444f1c0165125e29ac2305cc8d82b6cbc579a03803d.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.9cc8f2fec826ddf606b1f0244ce485f63a8928adf18174f55a656db6423cbf73.wasm", - "tx_shielded_transfer.wasm": "tx_shielded_transfer.f77c6fc4bcf121977e00a4ebc24b5c60fbb1a182062b51ec96df21701cee5ffc.wasm", - "tx_shielding_transfer.wasm": "tx_shielding_transfer.0bcb41dbc0bceafccc65bc5262510a40ee0c0450c0c08303b676b37de6514647.wasm", - "tx_transparent_transfer.wasm": "tx_transparent_transfer.cf989d4d445340e7c98e446f414a4c7c9d353638a34b40198b2b63a05fbbf69a.wasm", - "tx_unbond.wasm": "tx_unbond.16130834f9cbb300e50ce5405b3531618c733156430fa6788a086fb303eb61c9.wasm", - "tx_unjail_validator.wasm": "tx_unjail_validator.088c40fa51dc5cbab896e5464daa71bb205e999ba2aa24e8775a63c2ebf10084.wasm", - "tx_unshielding_transfer.wasm": "tx_unshielding_transfer.7a7e3e048ff135642a6694437cc6e0a4c7c6943e9c149a4f81363f063fe28dbf.wasm", - "tx_update_account.wasm": "tx_update_account.bcd9bc9f531015719cfe1009af1c5bcfd6567cea55f4cec053bd45c96a2143df.wasm", - "tx_update_steward_commission.wasm": "tx_update_steward_commission.ee6739d438764e8aaaa91cace5ca7fa70b06a4cd4d021f3764fa28d94bd0d202.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.45cda2bb54d6101206297be8e97a437806a24fb47fe7f91b61f05dbe8314bb53.wasm", - "tx_withdraw.wasm": "tx_withdraw.bca31434c620eee98fc1394a9dfb071033e87830152f0585ec82cc9c68ad310a.wasm", - "vp_implicit.wasm": "vp_implicit.1d6894f6b285a65561cf5ff0599deb5b5e7ac6227a074bf571cba28f63b4813f.wasm", - "vp_user.wasm": "vp_user.3e7c5f520227e3b49b8a66218ef9ce18976400d70a6b36e0878638ed9912e147.wasm" + "tx_become_validator.wasm": "tx_become_validator.76e5ddf2b1ec805df627d220a472cf691e54fd56206910deb44a84e881e6f872.wasm", + "tx_bond.wasm": "tx_bond.277546629805e35f60fe1e4f208d36f488906c75a008217dd301b9e11fb17de5.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.b853589ea716d1865b6dba2788c70e120b8ce9711b17895593cd2c1b57bd2b57.wasm", + "tx_change_consensus_key.wasm": "tx_change_consensus_key.edf0b19a0d851d75dcd39c498c352f30157b7de7fcfeb189d111ceddc10ec930.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.c62598cd97bebec856a967228e78df455cd620818e16ad2617de22e1073c4b05.wasm", + "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.38d2819cdb4fe80a832c163c5b316c9e74c564deba9732ed7452cb2b3bef42c2.wasm", + "tx_claim_rewards.wasm": "tx_claim_rewards.1fd1118484a918947a005442b5dcac77556c538533982ccbcba9d7b02de533b0.wasm", + "tx_deactivate_validator.wasm": "tx_deactivate_validator.9dacf4d4aef2bc4d5ee8fce78f73544783376a974de686adc87ff0957e5a46fb.wasm", + "tx_ibc.wasm": "tx_ibc.c4e9528a911bd0ebf7c59e69eeed9f5b8f60b083a86ef69882b6a6c130c60560.wasm", + "tx_init_account.wasm": "tx_init_account.d2f3a2c059e0f92d683471df83afb4cd7e143e4a0428893cf7e6155382d8270d.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.04cb9b3468e6ffc7604231acb1668ff92e0c28a06354c7ad26698fb549a7aab5.wasm", + "tx_reactivate_validator.wasm": "tx_reactivate_validator.0c52fcf238c1b9be9455891744f5f495b4c78c26bbe20fad5eddbb28b6176792.wasm", + "tx_redelegate.wasm": "tx_redelegate.c584955237fb27964fc94c1aaa2c04eb9190894f6c24b4634e0b07cee511cce8.wasm", + "tx_resign_steward.wasm": "tx_resign_steward.c3f8a4465aad3fb674dbd80c2c994e1881a25315215b615dcd570885271c481b.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.79455aadb09effe70b407a88dcb50552344e32d9b9e30897b7e0e24ce34e76a2.wasm", + "tx_shielded_transfer.wasm": "tx_shielded_transfer.4a1a14ed6fa19fe15b47fab5170a9d7b3098dcaec9e9437cdf7fc3fc12545f6d.wasm", + "tx_shielding_transfer.wasm": "tx_shielding_transfer.f4402e2c5e793021775bd4289ac3f777a41d06743cc5e77dcc3a5c0b9c9cfe17.wasm", + "tx_transfer.wasm": "tx_transfer.8acfe426d01adc17018c07b1c9f2eb3f77ddff4a6e452c8d5ae16832a0e79c85.wasm", + "tx_transparent_transfer.wasm": "tx_transparent_transfer.423b3423cc3a0fb49a52ea20b76460f800cedde60485d2af05bdf2d500ab6f1e.wasm", + "tx_unbond.wasm": "tx_unbond.3d69f98b7832de1d63cdff4e2dec3eb8ba6da44104af00ed0607f040c300d52c.wasm", + "tx_unjail_validator.wasm": "tx_unjail_validator.d736868736feccea85d7bb8a5bd5cc67c19315521f608838ad60befbfc9e7738.wasm", + "tx_unshielding_transfer.wasm": "tx_unshielding_transfer.45f38800ba76682d965cb1aa894a29801d2c9faf3e9d41b2394a12e44aa99055.wasm", + "tx_update_account.wasm": "tx_update_account.3daaa7d67b1545a161a65efb99fa930a09f3ecdc87e3f0a6e965d49756912b6c.wasm", + "tx_update_steward_commission.wasm": "tx_update_steward_commission.a62fcce86de9723ceff0f838d106be6f912d06f48cf10a3163dbb9ef53620c96.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.724a81d2cc2a0e491381d98d22753f46003f781f09f968bff29ad57bddd6f5f8.wasm", + "tx_withdraw.wasm": "tx_withdraw.1c6766e0b777b961700c0c6542dcf88bef7650924ba7b11c20a0c7caeae65f50.wasm", + "vp_implicit.wasm": "vp_implicit.13cdf1daf217ae900e7ac2838d66a584a4aa8cd627e10ad99786acc3aedc3e30.wasm", + "vp_user.wasm": "vp_user.f1336b2653d225c95a15d7be9971eff708196386eb83373bcc13855c0379da85.wasm" } \ No newline at end of file diff --git a/wasm/tx_transparent_transfer/src/lib.rs b/wasm/tx_transparent_transfer/src/lib.rs index 0da40600d8..96586a1e44 100644 --- a/wasm/tx_transparent_transfer/src/lib.rs +++ b/wasm/tx_transparent_transfer/src/lib.rs @@ -2,6 +2,7 @@ //! This tx uses `token::TransparentTransfer` wrapped inside `SignedTxData` //! as its input as declared in `namada` crate. +use namada_tx_prelude::action::{Action, MaspAction, Write}; use namada_tx_prelude::*; #[transaction] @@ -11,7 +12,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { .wrap_err("Failed to decode token::TransparentTransfer tx data")?; debug_log!("apply_tx called with transfer: {:#?}", transfers); - for transfer in transfers.0 { + for transfer in transfers.data { token::transfer( ctx, &transfer.source, @@ -22,5 +23,24 @@ fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { .wrap_err("Token transfer failed")?; } + if let Some(masp_section_ref) = transfers.shielded_section_hash { + let shielded = tx_data + .tx + .get_section(&masp_section_ref) + .and_then(|x| x.as_ref().masp_tx()) + .ok_or_err_msg( + "Unable to find required shielded section in tx data", + ) + .map_err(|err| { + ctx.set_commitment_sentinel(); + err + })?; + token::utils::handle_masp_tx(ctx, &shielded) + .wrap_err("Encountered error while handling MASP transaction")?; + update_masp_note_commitment_tree(&shielded) + .wrap_err("Failed to update the MASP commitment tree")?; + ctx.push_action(Action::Masp(MaspAction { masp_section_ref }))?; + } + Ok(()) } From 83af4ba96299b44bb7d67aa3b8c395bb256f341c Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Thu, 27 Jun 2024 12:13:52 +0200 Subject: [PATCH 2/9] Renamed TransparentTransfer to Transfer. --- crates/benches/host_env.rs | 4 ++-- crates/benches/native_vps.rs | 4 ++-- crates/benches/process_wrapper.rs | 6 ++---- crates/encoding_spec/src/main.rs | 3 +-- crates/light_sdk/src/transaction/transfer.rs | 11 ++++------ crates/sdk/src/lib.rs | 4 ++-- crates/sdk/src/signing.rs | 4 ++-- crates/sdk/src/tx.rs | 4 ++-- crates/tests/src/integration/ledger_tests.rs | 21 ++++++++++---------- crates/token/src/lib.rs | 16 +++++++-------- crates/tx_prelude/src/token.rs | 2 +- wasm/tx_transparent_transfer/src/lib.rs | 2 +- 12 files changed, 37 insertions(+), 44 deletions(-) diff --git a/crates/benches/host_env.rs b/crates/benches/host_env.rs index 48e521cfd3..f9af5d7539 100644 --- a/crates/benches/host_env.rs +++ b/crates/benches/host_env.rs @@ -3,7 +3,7 @@ use namada::core::account::AccountPublicKeysMap; use namada::core::address; use namada::core::collections::{HashMap, HashSet}; use namada::ledger::storage::DB; -use namada::token::{Amount, TransparentTransfer, TransparentTransferData}; +use namada::token::{Amount, Transfer, TransferData}; use namada::tx::Authorization; use namada::vm::wasm::TxCache; use namada_apps_lib::wallet::defaults; @@ -18,7 +18,7 @@ use namada_node::bench_utils::{ // transaction fn tx_section_signature_validation(c: &mut Criterion) { let shell = BenchShell::default(); - let transfer_data = TransparentTransfer(vec![TransparentTransferData { + let transfer_data = Transfer(vec![TransferData { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), diff --git a/crates/benches/native_vps.rs b/crates/benches/native_vps.rs index aba3cb9802..1fb6007d66 100644 --- a/crates/benches/native_vps.rs +++ b/crates/benches/native_vps.rs @@ -55,7 +55,7 @@ use namada::sdk::masp_primitives::merkle_tree::CommitmentTree; use namada::sdk::masp_primitives::transaction::Transaction; use namada::sdk::masp_proofs::sapling::SaplingVerificationContextInner; use namada::state::{Epoch, StorageRead, StorageWrite, TxIndex}; -use namada::token::{Amount, TransparentTransfer, TransparentTransferData}; +use namada::token::{Amount, Transfer, TransferData}; use namada::tx::{BatchedTx, Code, Section, Tx}; use namada_apps_lib::wallet::defaults; use namada_node::bench_utils::{ @@ -476,7 +476,7 @@ fn vp_multitoken(c: &mut Criterion) { let transfer = shell.generate_tx( TX_TRANSPARENT_TRANSFER_WASM, - TransparentTransfer(vec![TransparentTransferData { + Transfer(vec![TransferData { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), diff --git a/crates/benches/process_wrapper.rs b/crates/benches/process_wrapper.rs index 65edb93467..49d789ba93 100644 --- a/crates/benches/process_wrapper.rs +++ b/crates/benches/process_wrapper.rs @@ -3,9 +3,7 @@ use namada::core::address; use namada::core::key::RefTo; use namada::core::storage::BlockHeight; use namada::core::time::DateTimeUtc; -use namada::token::{ - Amount, DenominatedAmount, TransparentTransfer, TransparentTransferData, -}; +use namada::token::{Amount, DenominatedAmount, Transfer, TransferData}; use namada::tx::data::{Fee, WrapperTx}; use namada::tx::Authorization; use namada_apps_lib::wallet::defaults; @@ -21,7 +19,7 @@ fn process_tx(c: &mut Criterion) { let mut batched_tx = shell.generate_tx( TX_TRANSPARENT_TRANSFER_WASM, - TransparentTransfer(vec![TransparentTransferData { + Transfer(vec![TransferData { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), diff --git a/crates/encoding_spec/src/main.rs b/crates/encoding_spec/src/main.rs index efb5c0c79c..97bcd7ba46 100644 --- a/crates/encoding_spec/src/main.rs +++ b/crates/encoding_spec/src/main.rs @@ -81,8 +81,7 @@ fn main() -> Result<(), Box> { let signature_schema = schema_container_of::(); let init_account_schema = schema_container_of::(); let init_validator_schema = schema_container_of::(); - let transparent_transfer_schema = - schema_container_of::(); + let transparent_transfer_schema = schema_container_of::(); let shielded_transfer_schema = schema_container_of::(); let shielding_transfer_schema = diff --git a/crates/light_sdk/src/transaction/transfer.rs b/crates/light_sdk/src/transaction/transfer.rs index 9dc7aa8e45..a8bff2ea53 100644 --- a/crates/light_sdk/src/transaction/transfer.rs +++ b/crates/light_sdk/src/transaction/transfer.rs @@ -4,7 +4,7 @@ use namada_sdk::key::common; use namada_sdk::token::transaction::Transaction; use namada_sdk::token::ShieldingTransferData; pub use namada_sdk::token::{ - DenominatedAmount, TransparentTransfer, UnshieldingTransferData, + DenominatedAmount, Transfer, UnshieldingTransferData, }; use namada_sdk::tx::data::GasLimit; use namada_sdk::tx::{ @@ -18,14 +18,11 @@ use crate::transaction; /// A transfer transaction #[derive(Debug, Clone)] -pub struct Transfer(Tx); +pub struct TransferBuilder(Tx); -impl Transfer { +impl TransferBuilder { /// Build a transparent transfer transaction from the given parameters - pub fn transparent( - transfers: TransparentTransfer, - args: GlobalArgs, - ) -> Self { + pub fn transparent(transfers: Transfer, args: GlobalArgs) -> Self { Self(transaction::build_tx( args, transfers, diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 274639f8f2..fd5b11058d 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -853,7 +853,7 @@ pub mod testing { use namada_governance::{InitProposalData, VoteProposalData}; use namada_ibc::testing::arb_ibc_any; use namada_token::testing::arb_denominated_amount; - use namada_token::{ShieldedTransfer, TransparentTransfer}; + use namada_token::{ShieldedTransfer, Transfer}; use namada_tx::data::pgf::UpdateStewardCommission; use namada_tx::data::pos::{ BecomeValidator, Bond, CommissionChange, ConsensusKeyChange, @@ -911,7 +911,7 @@ pub mod testing { UpdateAccount(UpdateAccount), VoteProposal(VoteProposalData), Withdraw(Withdraw), - TransparentTransfer(TransparentTransfer), + TransparentTransfer(Transfer), ShieldedTransfer(ShieldedTransfer, (StoredBuildParams, String)), ShieldingTransfer(ShieldingMultiTransfer, (StoredBuildParams, String)), UnshieldingTransfer( diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index 2616d47a98..083f2b6272 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -708,7 +708,7 @@ enum TransferSide<'a> { } enum TokenTransfer<'a> { - Transparent(&'a token::TransparentTransfer), + Transparent(&'a token::Transfer), Shielded, Shielding(&'a token::ShieldingMultiTransfer), Unshielding(&'a token::UnshieldingMultiTransfer), @@ -1390,7 +1390,7 @@ pub async fn to_ledger_vector( } } else if code_sec.tag == Some(TX_TRANSPARENT_TRANSFER_WASM.to_string()) { - let transfer = token::TransparentTransfer::try_from_slice( + let transfer = token::Transfer::try_from_slice( &tx.data(cmt) .ok_or_else(|| Error::Other("Invalid Data".to_string()))?, ) diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index 6757bc7e67..a724f66536 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -2918,7 +2918,7 @@ pub async fn build_transparent_transfer( } // Construct the corresponding transparent Transfer object - let transfer_data = token::TransparentTransferData { + let transfer_data = token::TransferData { source: source.to_owned(), target: target.to_owned(), token: token.to_owned(), @@ -2928,7 +2928,7 @@ pub async fn build_transparent_transfer( transfers.push(transfer_data); } // Construct the corresponding transparent Transfer object - let transfer = token::TransparentTransfer { + let transfer = token::Transfer { data: transfers, shielded_section_hash: None, }; diff --git a/crates/tests/src/integration/ledger_tests.rs b/crates/tests/src/integration/ledger_tests.rs index 3ec0da9b0e..0713770220 100644 --- a/crates/tests/src/integration/ledger_tests.rs +++ b/crates/tests/src/integration/ledger_tests.rs @@ -59,17 +59,16 @@ fn ledger_txs_and_queries() -> Result<()> { let validator_one_rpc = "http://127.0.0.1:26567"; let (node, _services) = setup::setup()?; - let transfer = - token::TransparentTransfer(vec![token::TransparentTransferData { - source: defaults::bertha_address(), - target: defaults::albert_address(), - token: node.native_token(), - amount: token::DenominatedAmount::new( - token::Amount::native_whole(10), - token::NATIVE_MAX_DECIMAL_PLACES.into(), - ), - }]) - .serialize_to_vec(); + let transfer = token::Transfer(vec![token::TransferData { + source: defaults::bertha_address(), + target: defaults::albert_address(), + token: node.native_token(), + amount: token::DenominatedAmount::new( + token::Amount::native_whole(10), + token::NATIVE_MAX_DECIMAL_PLACES.into(), + ), + }]) + .serialize_to_vec(); let tx_data_path = node.test_dir.path().join("tx.data"); std::fs::write(&tx_data_path, transfer).unwrap(); let tx_data_path = tx_data_path.to_string_lossy(); diff --git a/crates/token/src/lib.rs b/crates/token/src/lib.rs index 758eeae2d9..2f2b51d4ff 100644 --- a/crates/token/src/lib.rs +++ b/crates/token/src/lib.rs @@ -82,9 +82,9 @@ where Serialize, Deserialize, )] -pub struct TransparentTransfer { +pub struct Transfer { /// Transfer-specific data - pub data: Vec, + pub data: Vec, /// Hash of tx section that contains the MASP transaction pub shielded_section_hash: Option, } @@ -104,7 +104,7 @@ pub struct TransparentTransfer { Serialize, Deserialize, )] -pub struct TransparentTransferData { +pub struct TransferData { /// Source address will spend the tokens pub source: Address, /// Target address will receive the tokens @@ -288,7 +288,7 @@ pub mod testing { pub use namada_trans_token::testing::*; use proptest::prelude::*; - use super::{TransparentTransfer, TransparentTransferData}; + use super::{Transfer, TransferData}; prop_compose! { /// Generate a transparent transfer @@ -297,8 +297,8 @@ pub mod testing { target in arb_non_internal_address(), token in arb_established_address().prop_map(Address::Established), amount in arb_denominated_amount(), - ) -> TransparentTransferData{ - TransparentTransferData { + ) -> TransferData{ + TransferData { source, target, token, @@ -310,9 +310,9 @@ pub mod testing { /// Generate a vectorized transparent transfer pub fn arb_vectorized_transparent_transfer( number_of_txs: usize, - ) -> impl Strategy { + ) -> impl Strategy { proptest::collection::vec(arb_transparent_transfer(), 0..number_of_txs) - .prop_map(|data| TransparentTransfer { + .prop_map(|data| Transfer { data, shielded_section_hash: None, }) diff --git a/crates/tx_prelude/src/token.rs b/crates/tx_prelude/src/token.rs index cd59dcdcd4..42179969fd 100644 --- a/crates/tx_prelude/src/token.rs +++ b/crates/tx_prelude/src/token.rs @@ -6,7 +6,7 @@ use namada_events::{EmitEvents, EventLevel}; pub use namada_token::testing; pub use namada_token::{ storage_key, utils, Amount, DenominatedAmount, ShieldedTransfer, - ShieldingMultiTransfer, ShieldingTransfer, TransparentTransfer, + ShieldingMultiTransfer, ShieldingTransfer, Transfer, UnshieldingMultiTransfer, UnshieldingTransfer, }; use namada_tx_env::TxEnv; diff --git a/wasm/tx_transparent_transfer/src/lib.rs b/wasm/tx_transparent_transfer/src/lib.rs index 96586a1e44..11ffa18147 100644 --- a/wasm/tx_transparent_transfer/src/lib.rs +++ b/wasm/tx_transparent_transfer/src/lib.rs @@ -8,7 +8,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 transfers = token::TransparentTransfer::try_from_slice(&data[..]) + let transfers = token::Transfer::try_from_slice(&data[..]) .wrap_err("Failed to decode token::TransparentTransfer tx data")?; debug_log!("apply_tx called with transfer: {:#?}", transfers); From 6d1b7856828322c7d02adac38e04892b3cc6a492 Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Thu, 27 Jun 2024 12:52:19 +0200 Subject: [PATCH 3/9] Subsumed shielded transfer into generalized transfer. --- crates/apps_lib/src/cli.rs | 14 ++--- crates/benches/host_env.rs | 13 ++-- crates/benches/native_vps.rs | 7 +-- crates/benches/process_wrapper.rs | 6 +- crates/encoding_spec/src/main.rs | 14 ++--- crates/light_sdk/src/transaction/transfer.rs | 17 +++--- crates/node/src/bench_utils.rs | 21 +++---- crates/sdk/src/lib.rs | 26 ++++---- crates/sdk/src/signing.rs | 29 ++++----- crates/sdk/src/tx.rs | 62 ++++++++++---------- crates/tests/src/integration/ledger_tests.rs | 6 +- crates/token/src/lib.rs | 30 ++++------ crates/tx_prelude/src/token.rs | 5 +- wasm/Cargo.lock | 9 --- wasm/Cargo.toml | 1 - 15 files changed, 113 insertions(+), 147 deletions(-) diff --git a/crates/apps_lib/src/cli.rs b/crates/apps_lib/src/cli.rs index ff0745ffc1..3ae496de32 100644 --- a/crates/apps_lib/src/cli.rs +++ b/crates/apps_lib/src/cli.rs @@ -3099,11 +3099,11 @@ pub mod args { TX_CHANGE_METADATA_WASM, TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, - TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_SHIELDED_TRANSFER_WASM, - TX_SHIELDING_TRANSFER_WASM, TX_TRANSPARENT_TRANSFER_WASM, - TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, - TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, - TX_WITHDRAW_WASM, VP_USER_WASM, + TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_SHIELDING_TRANSFER_WASM, + TX_TRANSFER_WASM, TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, + TX_UNSHIELDING_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, + TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, + VP_USER_WASM, }; use namada_sdk::DEFAULT_GAS_LIMIT; @@ -4365,7 +4365,7 @@ pub mod args { let target = TARGET.parse(matches); let token = TOKEN.parse(matches); let amount = InputAmount::Unvalidated(AMOUNT.parse(matches)); - let tx_code_path = PathBuf::from(TX_TRANSPARENT_TRANSFER_WASM); + let tx_code_path = PathBuf::from(TX_TRANSFER_WASM); let data = vec![TxTransparentTransferData { source, target, @@ -4431,7 +4431,7 @@ pub mod args { let target = PAYMENT_ADDRESS_TARGET.parse(matches); let token = TOKEN.parse(matches); let amount = InputAmount::Unvalidated(AMOUNT.parse(matches)); - let tx_code_path = PathBuf::from(TX_SHIELDED_TRANSFER_WASM); + let tx_code_path = PathBuf::from(TX_TRANSFER_WASM); let data = vec![TxShieldedTransferData { source, target, diff --git a/crates/benches/host_env.rs b/crates/benches/host_env.rs index f9af5d7539..ce939fa043 100644 --- a/crates/benches/host_env.rs +++ b/crates/benches/host_env.rs @@ -9,23 +9,22 @@ use namada::vm::wasm::TxCache; use namada_apps_lib::wallet::defaults; use namada_apps_lib::wasm_loader; use namada_node::bench_utils::{ - BenchShell, TX_INIT_PROPOSAL_WASM, TX_REVEAL_PK_WASM, - TX_TRANSPARENT_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, VP_USER_WASM, - WASM_DIR, + BenchShell, TX_INIT_PROPOSAL_WASM, TX_REVEAL_PK_WASM, TX_TRANSFER_WASM, + TX_UPDATE_ACCOUNT_WASM, VP_USER_WASM, WASM_DIR, }; // Benchmarks the validation of a single signature on a single `Section` of a // transaction fn tx_section_signature_validation(c: &mut Criterion) { let shell = BenchShell::default(); - let transfer_data = Transfer(vec![TransferData { + let transfer_data = Transfer::transparent(vec![TransferData { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), amount: Amount::native_whole(500).native_denominated(), }]); let tx = shell.generate_tx( - TX_TRANSPARENT_TRANSFER_WASM, + TX_TRANSFER_WASM, transfer_data, None, None, @@ -62,7 +61,7 @@ fn compile_wasm(c: &mut Criterion) { let mut txs: HashMap<&str, Vec> = HashMap::default(); for tx in [ - TX_TRANSPARENT_TRANSFER_WASM, + TX_TRANSFER_WASM, TX_INIT_PROPOSAL_WASM, TX_REVEAL_PK_WASM, TX_UPDATE_ACCOUNT_WASM, @@ -111,7 +110,7 @@ fn untrusted_wasm_validation(c: &mut Criterion) { let mut txs: HashMap<&str, Vec> = HashMap::default(); for tx in [ - TX_TRANSPARENT_TRANSFER_WASM, + TX_TRANSFER_WASM, TX_INIT_PROPOSAL_WASM, TX_REVEAL_PK_WASM, TX_UPDATE_ACCOUNT_WASM, diff --git a/crates/benches/native_vps.rs b/crates/benches/native_vps.rs index 1fb6007d66..a62031a2a7 100644 --- a/crates/benches/native_vps.rs +++ b/crates/benches/native_vps.rs @@ -62,8 +62,7 @@ use namada_node::bench_utils::{ generate_foreign_key_tx, BenchShell, BenchShieldedCtx, ALBERT_PAYMENT_ADDRESS, ALBERT_SPENDING_KEY, BERTHA_PAYMENT_ADDRESS, TX_BRIDGE_POOL_WASM, TX_IBC_WASM, TX_INIT_PROPOSAL_WASM, TX_RESIGN_STEWARD, - TX_TRANSPARENT_TRANSFER_WASM, TX_UPDATE_STEWARD_COMMISSION, - TX_VOTE_PROPOSAL_WASM, + TX_TRANSFER_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL_WASM, }; use rand_core::OsRng; @@ -475,8 +474,8 @@ fn vp_multitoken(c: &mut Criterion) { generate_foreign_key_tx(&defaults::albert_keypair()); let transfer = shell.generate_tx( - TX_TRANSPARENT_TRANSFER_WASM, - Transfer(vec![TransferData { + TX_TRANSFER_WASM, + Transfer::transparent(vec![TransferData { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), diff --git a/crates/benches/process_wrapper.rs b/crates/benches/process_wrapper.rs index 49d789ba93..efa721de49 100644 --- a/crates/benches/process_wrapper.rs +++ b/crates/benches/process_wrapper.rs @@ -7,7 +7,7 @@ use namada::token::{Amount, DenominatedAmount, Transfer, TransferData}; use namada::tx::data::{Fee, WrapperTx}; use namada::tx::Authorization; use namada_apps_lib::wallet::defaults; -use namada_node::bench_utils::{BenchShell, TX_TRANSPARENT_TRANSFER_WASM}; +use namada_node::bench_utils::{BenchShell, TX_TRANSFER_WASM}; use namada_node::shell::process_proposal::ValidationMeta; fn process_tx(c: &mut Criterion) { @@ -18,8 +18,8 @@ fn process_tx(c: &mut Criterion) { BlockHeight(2); let mut batched_tx = shell.generate_tx( - TX_TRANSPARENT_TRANSFER_WASM, - Transfer(vec![TransferData { + TX_TRANSFER_WASM, + Transfer::transparent(vec![TransferData { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), diff --git a/crates/encoding_spec/src/main.rs b/crates/encoding_spec/src/main.rs index 97bcd7ba46..de20faef26 100644 --- a/crates/encoding_spec/src/main.rs +++ b/crates/encoding_spec/src/main.rs @@ -81,9 +81,7 @@ fn main() -> Result<(), Box> { let signature_schema = schema_container_of::(); let init_account_schema = schema_container_of::(); let init_validator_schema = schema_container_of::(); - let transparent_transfer_schema = schema_container_of::(); - let shielded_transfer_schema = - schema_container_of::(); + let transfer_schema = schema_container_of::(); let shielding_transfer_schema = schema_container_of::(); let unshielding_transfer_schema = @@ -114,8 +112,7 @@ fn main() -> Result<(), Box> { definitions.extend(btree(&signature_schema)); definitions.extend(btree(&init_account_schema)); definitions.extend(btree(&init_validator_schema)); - definitions.extend(btree(&transparent_transfer_schema)); - definitions.extend(btree(&shielded_transfer_schema)); + definitions.extend(btree(&transfer_schema)); definitions.extend(btree(&shielding_transfer_schema)); definitions.extend(btree(&unshielding_transfer_schema)); definitions.extend(btree(&update_account)); @@ -190,11 +187,10 @@ fn main() -> Result<(), Box> { ).with_rust_doc_link("https://dev.namada.net/master/rustdoc/namada/types/transaction/struct.InitValidator.html"); tables.push(init_validator_table); - let token_transfer_definition = definitions - .remove(transparent_transfer_schema.declaration()) - .unwrap(); + let token_transfer_definition = + definitions.remove(transfer_schema.declaration()).unwrap(); let token_transfer_table = definition_to_table( - transparent_transfer_schema.declaration(), + transfer_schema.declaration(), token_transfer_definition, ).with_rust_doc_link("https://dev.namada.net/master/rustdoc/namada/types/token/struct.Transfer.html"); tables.push(token_transfer_table); diff --git a/crates/light_sdk/src/transaction/transfer.rs b/crates/light_sdk/src/transaction/transfer.rs index a8bff2ea53..97da79b1e5 100644 --- a/crates/light_sdk/src/transaction/transfer.rs +++ b/crates/light_sdk/src/transaction/transfer.rs @@ -8,8 +8,7 @@ pub use namada_sdk::token::{ }; use namada_sdk::tx::data::GasLimit; use namada_sdk::tx::{ - Authorization, Tx, TxError, TX_SHIELDED_TRANSFER_WASM, - TX_SHIELDING_TRANSFER_WASM, TX_TRANSPARENT_TRANSFER_WASM, + Authorization, Tx, TxError, TX_SHIELDING_TRANSFER_WASM, TX_TRANSFER_WASM, TX_UNSHIELDING_TRANSFER_WASM, }; @@ -26,7 +25,7 @@ impl TransferBuilder { Self(transaction::build_tx( args, transfers, - TX_TRANSPARENT_TRANSFER_WASM.to_string(), + TX_TRANSFER_WASM.to_string(), )) } @@ -36,15 +35,13 @@ impl TransferBuilder { transaction: Transaction, args: GlobalArgs, ) -> Self { - let data = namada_sdk::token::ShieldedTransfer { - section_hash: shielded_section_hash, + let data = namada_sdk::token::Transfer { + data: vec![], + shielded_section_hash: Some(shielded_section_hash), }; - let mut tx = transaction::build_tx( - args, - data, - TX_SHIELDED_TRANSFER_WASM.to_string(), - ); + let mut tx = + transaction::build_tx(args, data, TX_TRANSFER_WASM.to_string()); tx.add_masp_tx_section(transaction); Self(tx) diff --git a/crates/node/src/bench_utils.rs b/crates/node/src/bench_utils.rs index bd5503f316..0067d0b086 100644 --- a/crates/node/src/bench_utils.rs +++ b/crates/node/src/bench_utils.rs @@ -76,8 +76,8 @@ use namada::ledger::queries::{ use namada::masp::MaspTxRefs; use namada::state::StorageRead; use namada::token::{ - Amount, DenominatedAmount, ShieldedTransfer, ShieldingMultiTransfer, - ShieldingTransfer, ShieldingTransferData, UnshieldingMultiTransfer, + Amount, DenominatedAmount, ShieldingMultiTransfer, ShieldingTransfer, + ShieldingTransferData, Transfer, UnshieldingMultiTransfer, UnshieldingTransferData, }; use namada::tx::data::pos::Bond; @@ -105,11 +105,11 @@ pub use namada_sdk::tx::{ TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL as TX_INIT_PROPOSAL_WASM, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, - TX_REVEAL_PK as TX_REVEAL_PK_WASM, TX_SHIELDED_TRANSFER_WASM, - TX_SHIELDING_TRANSFER_WASM, TX_TRANSPARENT_TRANSFER_WASM, TX_UNBOND_WASM, - TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, - TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, - TX_VOTE_PROPOSAL as TX_VOTE_PROPOSAL_WASM, TX_WITHDRAW_WASM, VP_USER_WASM, + TX_REVEAL_PK as TX_REVEAL_PK_WASM, TX_SHIELDING_TRANSFER_WASM, + TX_TRANSFER_WASM, TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, + TX_UNSHIELDING_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, + TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL as TX_VOTE_PROPOSAL_WASM, + TX_WITHDRAW_WASM, VP_USER_WASM, }; use namada_sdk::wallet::Wallet; use namada_sdk::{Namada, NamadaImpl}; @@ -1117,9 +1117,10 @@ impl BenchShieldedCtx { && target.effective_address() == MASP { namada.client().generate_tx( - TX_SHIELDED_TRANSFER_WASM, - ShieldedTransfer { - section_hash: shielded_section_hash, + TX_TRANSFER_WASM, + Transfer { + data: vec![], + shielded_section_hash: Some(shielded_section_hash), }, Some(shielded), None, diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index fd5b11058d..51d1716464 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -73,11 +73,10 @@ use tx::{ TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, TX_REVEAL_PK, - TX_SHIELDED_TRANSFER_WASM, TX_SHIELDING_TRANSFER_WASM, - TX_TRANSPARENT_TRANSFER_WASM, TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, - TX_UNSHIELDING_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, - TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, - VP_USER_WASM, + TX_SHIELDING_TRANSFER_WASM, TX_TRANSFER_WASM, TX_UNBOND_WASM, + TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, + TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, + TX_WITHDRAW_WASM, VP_USER_WASM, }; use wallet::{Wallet, WalletIo, WalletStorage}; @@ -179,7 +178,7 @@ pub trait Namada: Sized + MaybeSync + MaybeSend { ) -> args::TxTransparentTransfer { args::TxTransparentTransfer { data, - tx_code_path: PathBuf::from(TX_TRANSPARENT_TRANSFER_WASM), + tx_code_path: PathBuf::from(TX_TRANSFER_WASM), tx: self.tx_builder(), } } @@ -192,7 +191,7 @@ pub trait Namada: Sized + MaybeSync + MaybeSend { ) -> args::TxShieldedTransfer { args::TxShieldedTransfer { data, - tx_code_path: PathBuf::from(TX_SHIELDED_TRANSFER_WASM), + tx_code_path: PathBuf::from(TX_TRANSFER_WASM), tx: self.tx_builder(), } } @@ -853,7 +852,7 @@ pub mod testing { use namada_governance::{InitProposalData, VoteProposalData}; use namada_ibc::testing::arb_ibc_any; use namada_token::testing::arb_denominated_amount; - use namada_token::{ShieldedTransfer, Transfer}; + use namada_token::Transfer; use namada_tx::data::pgf::UpdateStewardCommission; use namada_tx::data::pos::{ BecomeValidator, Bond, CommissionChange, ConsensusKeyChange, @@ -912,7 +911,7 @@ pub mod testing { VoteProposal(VoteProposalData), Withdraw(Withdraw), TransparentTransfer(Transfer), - ShieldedTransfer(ShieldedTransfer, (StoredBuildParams, String)), + ShieldedTransfer(Transfer, (StoredBuildParams, String)), ShieldingTransfer(ShieldingMultiTransfer, (StoredBuildParams, String)), UnshieldingTransfer( UnshieldingMultiTransfer, @@ -1082,7 +1081,7 @@ pub mod testing { header.tx_type = TxType::Wrapper(Box::new(wrapper)); let mut tx = Tx { header, sections: vec![] }; tx.add_data(transfer.clone()); - tx.add_code_from_hash(code_hash, Some(TX_TRANSPARENT_TRANSFER_WASM.to_owned())); + tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); (tx, TxData::TransparentTransfer(transfer)) } } @@ -1129,8 +1128,11 @@ pub mod testing { data_encoding::HEXLOWER.encode(&build_params.serialize_to_vec()); let tx_data = match masp_tx_type { MaspTxType::Shielded => { - tx.add_code_from_hash(code_hash, Some(TX_SHIELDED_TRANSFER_WASM.to_owned())); - let data = ShieldedTransfer { section_hash: shielded_section_hash }; + tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); + let data = Transfer { + data: vec![], + shielded_section_hash: Some(shielded_section_hash), + }; tx.add_data(data.clone()); TxData::ShieldedTransfer(data, (build_params, build_param_bytes)) }, diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index 083f2b6272..6a5dda0c67 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -48,11 +48,11 @@ use crate::tx::{ TX_CHANGE_METADATA_WASM, TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, - TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_SHIELDED_TRANSFER_WASM, - TX_SHIELDING_TRANSFER_WASM, TX_TRANSPARENT_TRANSFER_WASM, TX_UNBOND_WASM, - TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, - TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, - TX_WITHDRAW_WASM, VP_USER_WASM, + TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_SHIELDING_TRANSFER_WASM, + TX_TRANSFER_WASM, TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, + TX_UNSHIELDING_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, + TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, + VP_USER_WASM, }; pub use crate::wallet::store::AddressVpType; use crate::wallet::{Wallet, WalletIo}; @@ -709,7 +709,6 @@ enum TransferSide<'a> { enum TokenTransfer<'a> { Transparent(&'a token::Transfer), - Shielded, Shielding(&'a token::ShieldingMultiTransfer), Unshielding(&'a token::UnshieldingMultiTransfer), } @@ -722,7 +721,6 @@ impl TokenTransfer<'_> { .iter() .map(|transfer| &transfer.source) .collect(), - TokenTransfer::Shielded => Default::default(), TokenTransfer::Shielding(transfers) => transfers .data .iter() @@ -739,8 +737,6 @@ impl TokenTransfer<'_> { .iter() .map(|transfer| &transfer.target) .collect(), - - TokenTransfer::Shielded => Default::default(), TokenTransfer::Shielding(_) => Default::default(), TokenTransfer::Unshielding(transfers) => transfers .data @@ -786,7 +782,6 @@ impl TokenTransfer<'_> { map } - TokenTransfer::Shielded => Default::default(), TokenTransfer::Shielding(transfers) => { let mut map: HashMap<&Address, DenominatedAmount> = HashMap::new(); @@ -1388,8 +1383,7 @@ pub async fn to_ledger_vector( HEXLOWER.encode(&extra_code_hash.0) )]); } - } else if code_sec.tag == Some(TX_TRANSPARENT_TRANSFER_WASM.to_string()) - { + } else if code_sec.tag == Some(TX_TRANSFER_WASM.to_string()) { let transfer = token::Transfer::try_from_slice( &tx.data(cmt) .ok_or_else(|| Error::Other("Invalid Data".to_string()))?, @@ -1417,8 +1411,8 @@ pub async fn to_ledger_vector( &HashMap::default(), ) .await?; - } else if code_sec.tag == Some(TX_SHIELDED_TRANSFER_WASM.to_string()) { - let transfer = token::ShieldedTransfer::try_from_slice( + } else if code_sec.tag == Some(TX_TRANSFER_WASM.to_string()) { + let transfer = token::Transfer::try_from_slice( &tx.data(cmt) .ok_or_else(|| Error::Other("Invalid Data".to_string()))?, ) @@ -1429,7 +1423,8 @@ pub async fn to_ledger_vector( let mut asset_types = HashMap::new(); let builder = tx.sections.iter().find_map(|x| match x { Section::MaspBuilder(builder) - if builder.target == transfer.section_hash => + if Some(builder.target) + == transfer.shielded_section_hash => { for decoded in &builder.asset_types { match decoded.encode() { @@ -1451,7 +1446,7 @@ pub async fn to_ledger_vector( make_ledger_token_transfer_endpoints( &tokens, &mut tv.output, - TokenTransfer::Shielded, + TokenTransfer::Transparent(&transfer), builder, &asset_types, ) @@ -1459,7 +1454,7 @@ pub async fn to_ledger_vector( make_ledger_token_transfer_endpoints( &tokens, &mut tv.output_expert, - TokenTransfer::Shielded, + TokenTransfer::Transparent(&transfer), builder, &asset_types, ) diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index a724f66536..413535328c 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -108,9 +108,7 @@ pub const TX_REVEAL_PK: &str = "tx_reveal_pk.wasm"; /// Update validity predicate WASM path pub const TX_UPDATE_ACCOUNT_WASM: &str = "tx_update_account.wasm"; /// Transparent transfer transaction WASM path -pub const TX_TRANSPARENT_TRANSFER_WASM: &str = "tx_transparent_transfer.wasm"; -/// Shielded transfer transaction WASM path -pub const TX_SHIELDED_TRANSFER_WASM: &str = "tx_shielded_transfer.wasm"; +pub const TX_TRANSFER_WASM: &str = "tx_transparent_transfer.wasm"; /// Shielding transfer transaction WASM path pub const TX_SHIELDING_TRANSFER_WASM: &str = "tx_shielding_transfer.wasm"; /// Unshielding transfer transaction WASM path @@ -2989,39 +2987,39 @@ pub async fn build_shielded_transfer( .await? .expect("Shielded transfer must have shielded parts"); - let add_shielded_parts = - |tx: &mut Tx, data: &mut token::ShieldedTransfer| { - // Add the MASP Transaction and its Builder to facilitate validation - let ( - ShieldedTransfer { - builder, - masp_tx, - metadata, - epoch: _, - }, - asset_types, - ) = shielded_parts; - // Add a MASP Transaction section to the Tx and get the tx hash - let section_hash = tx.add_masp_tx_section(masp_tx).1; - - tx.add_masp_builder(MaspBuilder { - asset_types, - // Store how the Info objects map to Descriptors/Outputs - metadata, - // Store the data that was used to construct the Transaction + let add_shielded_parts = |tx: &mut Tx, data: &mut token::Transfer| { + // Add the MASP Transaction and its Builder to facilitate validation + let ( + ShieldedTransfer { builder, - // Link the Builder to the Transaction by hash code - target: section_hash, - }); + masp_tx, + metadata, + epoch: _, + }, + asset_types, + ) = shielded_parts; + // Add a MASP Transaction section to the Tx and get the tx hash + let section_hash = tx.add_masp_tx_section(masp_tx).1; - data.section_hash = section_hash; - tracing::debug!("Transfer data {data:?}"); - Ok(()) - }; + tx.add_masp_builder(MaspBuilder { + asset_types, + // Store how the Info objects map to Descriptors/Outputs + metadata, + // Store the data that was used to construct the Transaction + builder, + // Link the Builder to the Transaction by hash code + target: section_hash, + }); + + data.shielded_section_hash = Some(section_hash); + tracing::debug!("Transfer data {data:?}"); + Ok(()) + }; // Construct the tx data with a placeholder shielded section hash - let data = token::ShieldedTransfer { - section_hash: Hash::zero(), + let data = token::Transfer { + data: vec![], + shielded_section_hash: None, }; let tx = build_pow_flag( context, diff --git a/crates/tests/src/integration/ledger_tests.rs b/crates/tests/src/integration/ledger_tests.rs index 0713770220..f4ada9c6e7 100644 --- a/crates/tests/src/integration/ledger_tests.rs +++ b/crates/tests/src/integration/ledger_tests.rs @@ -19,7 +19,7 @@ use namada_node::shell::testing::node::NodeResults; use namada_node::shell::testing::utils::{Bin, CapturedOutput}; use namada_sdk::migrations; use namada_sdk::queries::RPC; -use namada_sdk::tx::{TX_TRANSPARENT_TRANSFER_WASM, VP_USER_WASM}; +use namada_sdk::tx::{TX_TRANSFER_WASM, VP_USER_WASM}; use namada_test_utils::TestWasms; use test_log::test; @@ -59,7 +59,7 @@ fn ledger_txs_and_queries() -> Result<()> { let validator_one_rpc = "http://127.0.0.1:26567"; let (node, _services) = setup::setup()?; - let transfer = token::Transfer(vec![token::TransferData { + let transfer = token::Transfer::transparent(vec![token::TransferData { source: defaults::bertha_address(), target: defaults::albert_address(), token: node.native_token(), @@ -140,7 +140,7 @@ fn ledger_txs_and_queries() -> Result<()> { vec![ "tx", "--code-path", - TX_TRANSPARENT_TRANSFER_WASM, + TX_TRANSFER_WASM, "--data-path", &tx_data_path, "--owner", diff --git a/crates/token/src/lib.rs b/crates/token/src/lib.rs index 2f2b51d4ff..5b94d87861 100644 --- a/crates/token/src/lib.rs +++ b/crates/token/src/lib.rs @@ -89,6 +89,16 @@ pub struct Transfer { pub shielded_section_hash: Option, } +impl Transfer { + /// Make a transparent transfer + pub fn transparent(data: Vec) -> Self { + Self { + data, + shielded_section_hash: None, + } + } +} + /// Arguments for a transparent token transfer #[derive( Debug, @@ -115,26 +125,6 @@ pub struct TransferData { pub amount: DenominatedAmount, } -/// Arguments for a shielded token transfer -#[derive( - Debug, - Clone, - PartialEq, - BorshSerialize, - BorshDeserialize, - BorshDeserializer, - BorshSchema, - Hash, - Eq, - PartialOrd, - Serialize, - Deserialize, -)] -pub struct ShieldedTransfer { - /// Hash of tx section that contains the MASP transaction - pub section_hash: Hash, -} - /// Arguments for a shielding transfer (from a transparent token to a shielded /// token) #[derive( diff --git a/crates/tx_prelude/src/token.rs b/crates/tx_prelude/src/token.rs index 42179969fd..d7fa7bb017 100644 --- a/crates/tx_prelude/src/token.rs +++ b/crates/tx_prelude/src/token.rs @@ -5,9 +5,8 @@ use namada_events::{EmitEvents, EventLevel}; #[cfg(any(test, feature = "testing"))] pub use namada_token::testing; pub use namada_token::{ - storage_key, utils, Amount, DenominatedAmount, ShieldedTransfer, - ShieldingMultiTransfer, ShieldingTransfer, Transfer, - UnshieldingMultiTransfer, UnshieldingTransfer, + storage_key, utils, Amount, DenominatedAmount, ShieldingMultiTransfer, + ShieldingTransfer, Transfer, UnshieldingMultiTransfer, UnshieldingTransfer, }; use namada_tx_env::TxEnv; diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index 7c491ea3d2..55fd0f4962 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -6888,15 +6888,6 @@ dependencies = [ "rlsf", ] -[[package]] -name = "tx_shielded_transfer" -version = "0.39.0" -dependencies = [ - "getrandom 0.2.15", - "namada_tx_prelude", - "rlsf", -] - [[package]] name = "tx_shielding_transfer" version = "0.39.0" diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index b0212b5def..3496714896 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -17,7 +17,6 @@ members = [ "tx_redelegate", "tx_resign_steward", "tx_reveal_pk", - "tx_shielded_transfer", "tx_shielding_transfer", "tx_transparent_transfer", "tx_unbond", From 79429192ab79ee5c427f8411deceeba9bfbfb9dc Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Thu, 27 Jun 2024 14:42:29 +0200 Subject: [PATCH 4/9] Subsumed shielding transfer into generalized transfer. --- crates/apps_lib/src/cli.rs | 11 ++- crates/encoding_spec/src/main.rs | 3 - crates/ibc/src/lib.rs | 4 +- crates/ibc/src/msg.rs | 22 ++--- crates/light_sdk/src/transaction/transfer.rs | 18 ++--- crates/node/src/bench_utils.rs | 40 +++++----- crates/sdk/src/lib.rs | 27 ++++--- crates/sdk/src/signing.rs | 81 +------------------ crates/sdk/src/tx.rs | 84 ++++++++++---------- crates/token/src/lib.rs | 71 ----------------- crates/tx_prelude/src/token.rs | 4 +- wasm/Cargo.lock | 9 --- wasm/Cargo.toml | 1 - wasm/checksums.json | 8 +- wasm/tx_ibc/src/lib.rs | 2 +- 15 files changed, 113 insertions(+), 272 deletions(-) diff --git a/crates/apps_lib/src/cli.rs b/crates/apps_lib/src/cli.rs index 3ae496de32..010e467d1f 100644 --- a/crates/apps_lib/src/cli.rs +++ b/crates/apps_lib/src/cli.rs @@ -3099,11 +3099,10 @@ pub mod args { TX_CHANGE_METADATA_WASM, TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, - TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_SHIELDING_TRANSFER_WASM, - TX_TRANSFER_WASM, TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, - TX_UNSHIELDING_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, - TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, - VP_USER_WASM, + TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_TRANSFER_WASM, TX_UNBOND_WASM, + TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, + TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, + TX_WITHDRAW_WASM, VP_USER_WASM, }; use namada_sdk::DEFAULT_GAS_LIMIT; @@ -4502,7 +4501,7 @@ pub mod args { let target = PAYMENT_ADDRESS_TARGET.parse(matches); let token = TOKEN.parse(matches); let amount = InputAmount::Unvalidated(AMOUNT.parse(matches)); - let tx_code_path = PathBuf::from(TX_SHIELDING_TRANSFER_WASM); + let tx_code_path = PathBuf::from(TX_TRANSFER_WASM); let data = vec![TxShieldingTransferData { source, token, diff --git a/crates/encoding_spec/src/main.rs b/crates/encoding_spec/src/main.rs index de20faef26..9208c7d2c0 100644 --- a/crates/encoding_spec/src/main.rs +++ b/crates/encoding_spec/src/main.rs @@ -82,8 +82,6 @@ fn main() -> Result<(), Box> { let init_account_schema = schema_container_of::(); let init_validator_schema = schema_container_of::(); let transfer_schema = schema_container_of::(); - let shielding_transfer_schema = - schema_container_of::(); let unshielding_transfer_schema = schema_container_of::(); let update_account = schema_container_of::(); @@ -113,7 +111,6 @@ fn main() -> Result<(), Box> { definitions.extend(btree(&init_account_schema)); definitions.extend(btree(&init_validator_schema)); definitions.extend(btree(&transfer_schema)); - definitions.extend(btree(&shielding_transfer_schema)); definitions.extend(btree(&unshielding_transfer_schema)); definitions.extend(btree(&update_account)); definitions.extend(btree(&pos_bond_schema)); diff --git a/crates/ibc/src/lib.rs b/crates/ibc/src/lib.rs index 15a673c9c6..b58b9041ef 100644 --- a/crates/ibc/src/lib.rs +++ b/crates/ibc/src/lib.rs @@ -76,7 +76,7 @@ use ibc::primitives::proto::Any; pub use ibc::*; pub use msg::*; use namada_core::address::{self, Address}; -use namada_token::ShieldingTransfer; +use namada_token::Transfer; pub use nft::*; use prost::Message; use thiserror::Error; @@ -152,7 +152,7 @@ where pub fn execute( &mut self, tx_data: &[u8], - ) -> Result, Error> { + ) -> Result, Error> { let message = decode_message(tx_data)?; match &message { IbcMessage::Transfer(msg) => { diff --git a/crates/ibc/src/msg.rs b/crates/ibc/src/msg.rs index 7502cf1e31..714584675a 100644 --- a/crates/ibc/src/msg.rs +++ b/crates/ibc/src/msg.rs @@ -7,7 +7,7 @@ use ibc::core::channel::types::msgs::{ }; use ibc::core::handler::types::msgs::MsgEnvelope; use ibc::primitives::proto::Protobuf; -use namada_token::ShieldingTransfer; +use namada_token::Transfer; /// The different variants of an Ibc message pub enum IbcMessage { @@ -31,7 +31,7 @@ pub struct MsgTransfer { /// IBC transfer message pub message: IbcMsgTransfer, /// Shieleded transfer for MASP transaction - pub transfer: Option, + pub transfer: Option, } impl BorshSerialize for MsgTransfer { @@ -50,7 +50,7 @@ impl BorshDeserialize for MsgTransfer { reader: &mut R, ) -> std::io::Result { use std::io::{Error, ErrorKind}; - let (msg, transfer): (Vec, Option) = + let (msg, transfer): (Vec, Option) = BorshDeserialize::deserialize_reader(reader)?; let message = IbcMsgTransfer::decode_vec(&msg) .map_err(|err| Error::new(ErrorKind::InvalidData, err))?; @@ -64,7 +64,7 @@ pub struct MsgNftTransfer { /// IBC NFT transfer message pub message: IbcMsgNftTransfer, /// Shieleded transfer for MASP transaction - pub transfer: Option, + pub transfer: Option, } impl BorshSerialize for MsgNftTransfer { @@ -83,7 +83,7 @@ impl BorshDeserialize for MsgNftTransfer { reader: &mut R, ) -> std::io::Result { use std::io::{Error, ErrorKind}; - let (msg, transfer): (Vec, Option) = + let (msg, transfer): (Vec, Option) = BorshDeserialize::deserialize_reader(reader)?; let message = IbcMsgNftTransfer::decode_vec(&msg) .map_err(|err| Error::new(ErrorKind::InvalidData, err))?; @@ -97,7 +97,7 @@ pub struct MsgRecvPacket { /// IBC receiving packet message pub message: IbcMsgRecvPacket, /// Shieleded transfer for MASP transaction - pub transfer: Option, + pub transfer: Option, } impl BorshSerialize for MsgRecvPacket { @@ -116,7 +116,7 @@ impl BorshDeserialize for MsgRecvPacket { reader: &mut R, ) -> std::io::Result { use std::io::{Error, ErrorKind}; - let (msg, transfer): (Vec, Option) = + let (msg, transfer): (Vec, Option) = BorshDeserialize::deserialize_reader(reader)?; let message = IbcMsgRecvPacket::decode_vec(&msg) .map_err(|err| Error::new(ErrorKind::InvalidData, err))?; @@ -131,7 +131,7 @@ pub struct MsgAcknowledgement { /// IBC acknowledgement message pub message: IbcMsgAcknowledgement, /// Shieleded transfer for MASP transaction - pub transfer: Option, + pub transfer: Option, } impl BorshSerialize for MsgAcknowledgement { @@ -150,7 +150,7 @@ impl BorshDeserialize for MsgAcknowledgement { reader: &mut R, ) -> std::io::Result { use std::io::{Error, ErrorKind}; - let (msg, transfer): (Vec, Option) = + let (msg, transfer): (Vec, Option) = BorshDeserialize::deserialize_reader(reader)?; let message = IbcMsgAcknowledgement::decode_vec(&msg) .map_err(|err| Error::new(ErrorKind::InvalidData, err))?; @@ -165,7 +165,7 @@ pub struct MsgTimeout { /// IBC timeout message pub message: IbcMsgTimeout, /// Shieleded transfer for MASP transaction - pub transfer: Option, + pub transfer: Option, } impl BorshSerialize for MsgTimeout { @@ -184,7 +184,7 @@ impl BorshDeserialize for MsgTimeout { reader: &mut R, ) -> std::io::Result { use std::io::{Error, ErrorKind}; - let (msg, transfer): (Vec, Option) = + let (msg, transfer): (Vec, Option) = BorshDeserialize::deserialize_reader(reader)?; let message = IbcMsgTimeout::decode_vec(&msg) .map_err(|err| Error::new(ErrorKind::InvalidData, err))?; diff --git a/crates/light_sdk/src/transaction/transfer.rs b/crates/light_sdk/src/transaction/transfer.rs index 97da79b1e5..5dc0115712 100644 --- a/crates/light_sdk/src/transaction/transfer.rs +++ b/crates/light_sdk/src/transaction/transfer.rs @@ -2,14 +2,13 @@ use namada_sdk::address::Address; use namada_sdk::hash::Hash; use namada_sdk::key::common; use namada_sdk::token::transaction::Transaction; -use namada_sdk::token::ShieldingTransferData; +use namada_sdk::token::TransferData; pub use namada_sdk::token::{ DenominatedAmount, Transfer, UnshieldingTransferData, }; use namada_sdk::tx::data::GasLimit; use namada_sdk::tx::{ - Authorization, Tx, TxError, TX_SHIELDING_TRANSFER_WASM, TX_TRANSFER_WASM, - TX_UNSHIELDING_TRANSFER_WASM, + Authorization, Tx, TxError, TX_TRANSFER_WASM, TX_UNSHIELDING_TRANSFER_WASM, }; use super::{attach_fee, attach_fee_signature, GlobalArgs}; @@ -49,21 +48,18 @@ impl TransferBuilder { /// Build a shielding transfer transaction from the given parameters pub fn shielding( - transfers: Vec, + transfers: Vec, shielded_section_hash: Hash, transaction: Transaction, args: GlobalArgs, ) -> Self { - let data = namada_sdk::token::ShieldingMultiTransfer { + let data = namada_sdk::token::Transfer { data: transfers, - shielded_section_hash, + shielded_section_hash: Some(shielded_section_hash), }; - let mut tx = transaction::build_tx( - args, - data, - TX_SHIELDING_TRANSFER_WASM.to_string(), - ); + let mut tx = + transaction::build_tx(args, data, TX_TRANSFER_WASM.to_string()); tx.add_masp_tx_section(transaction); Self(tx) diff --git a/crates/node/src/bench_utils.rs b/crates/node/src/bench_utils.rs index 0067d0b086..a845356175 100644 --- a/crates/node/src/bench_utils.rs +++ b/crates/node/src/bench_utils.rs @@ -76,9 +76,8 @@ use namada::ledger::queries::{ use namada::masp::MaspTxRefs; use namada::state::StorageRead; use namada::token::{ - Amount, DenominatedAmount, ShieldingMultiTransfer, ShieldingTransfer, - ShieldingTransferData, Transfer, UnshieldingMultiTransfer, - UnshieldingTransferData, + Amount, DenominatedAmount, Transfer, TransferData, + UnshieldingMultiTransfer, UnshieldingTransferData, }; use namada::tx::data::pos::Bond; use namada::tx::data::{ @@ -105,11 +104,10 @@ pub use namada_sdk::tx::{ TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL as TX_INIT_PROPOSAL_WASM, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, - TX_REVEAL_PK as TX_REVEAL_PK_WASM, TX_SHIELDING_TRANSFER_WASM, - TX_TRANSFER_WASM, TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, - TX_UNSHIELDING_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, - TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL as TX_VOTE_PROPOSAL_WASM, - TX_WITHDRAW_WASM, VP_USER_WASM, + TX_REVEAL_PK as TX_REVEAL_PK_WASM, TX_TRANSFER_WASM, TX_UNBOND_WASM, + TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, + TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, + TX_VOTE_PROPOSAL as TX_VOTE_PROPOSAL_WASM, TX_WITHDRAW_WASM, VP_USER_WASM, }; use namada_sdk::wallet::Wallet; use namada_sdk::{Namada, NamadaImpl}; @@ -1128,14 +1126,15 @@ impl BenchShieldedCtx { ) } else if target.effective_address() == MASP { namada.client().generate_tx( - TX_SHIELDING_TRANSFER_WASM, - ShieldingMultiTransfer { - data: vec![ShieldingTransferData { + TX_TRANSFER_WASM, + Transfer { + data: vec![TransferData { source: source.effective_address(), + target: MASP, token: address::testing::nam(), amount: DenominatedAmount::native(amount), }], - shielded_section_hash, + shielded_section_hash: Some(shielded_section_hash), }, Some(shielded), None, @@ -1215,17 +1214,18 @@ impl BenchShieldedCtx { timeout_timestamp_on_b: timeout_timestamp, }; - let vectorized_transfer = ShieldingMultiTransfer::deserialize( - &mut tx.tx.data(&tx.cmt).unwrap().as_slice(), - ) - .unwrap(); - let transfer = ShieldingTransfer { - data: vectorized_transfer.data.first().unwrap().to_owned(), - shielded_section_hash: vectorized_transfer.shielded_section_hash, + let vectorized_transfer = + Transfer::deserialize(&mut tx.tx.data(&tx.cmt).unwrap().as_slice()) + .unwrap(); + let transfer = Transfer { + data: vec![vectorized_transfer.data.first().unwrap().to_owned()], + shielded_section_hash: Some( + vectorized_transfer.shielded_section_hash.unwrap(), + ), }; let masp_tx = tx .tx - .get_section(&transfer.shielded_section_hash) + .get_section(&transfer.shielded_section_hash.unwrap()) .unwrap() .masp_tx() .unwrap(); diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 51d1716464..2186e23b8f 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -72,9 +72,8 @@ use tx::{ TX_CHANGE_CONSENSUS_KEY_WASM, TX_CHANGE_METADATA_WASM, TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, - TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, TX_REVEAL_PK, - TX_SHIELDING_TRANSFER_WASM, TX_TRANSFER_WASM, TX_UNBOND_WASM, - TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, + TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_TRANSFER_WASM, + TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, VP_USER_WASM, }; @@ -206,7 +205,7 @@ pub trait Namada: Sized + MaybeSync + MaybeSend { args::TxShieldingTransfer { data, target, - tx_code_path: PathBuf::from(TX_SHIELDING_TRANSFER_WASM), + tx_code_path: PathBuf::from(TX_TRANSFER_WASM), tx: self.tx_builder(), } } @@ -843,6 +842,7 @@ pub mod testing { use namada_core::address::testing::{ arb_established_address, arb_non_internal_address, }; + use namada_core::address::MASP; use namada_core::eth_bridge_pool::PendingTransfer; use namada_core::hash::testing::arb_hash; use namada_core::key::testing::arb_common_keypair; @@ -866,8 +866,7 @@ pub mod testing { use sha2::Digest; use token::testing::arb_vectorized_transparent_transfer; use token::{ - ShieldingMultiTransfer, ShieldingTransferData, - UnshieldingMultiTransfer, UnshieldingTransferData, + TransferData, UnshieldingMultiTransfer, UnshieldingTransferData, }; use super::*; @@ -912,7 +911,7 @@ pub mod testing { Withdraw(Withdraw), TransparentTransfer(Transfer), ShieldedTransfer(Transfer, (StoredBuildParams, String)), - ShieldingTransfer(ShieldingMultiTransfer, (StoredBuildParams, String)), + ShieldingTransfer(Transfer, (StoredBuildParams, String)), UnshieldingTransfer( UnshieldingMultiTransfer, (StoredBuildParams, String), @@ -1144,15 +1143,19 @@ pub mod testing { token::Amount::from_masp_denominated(*value, decoded.position), decoded.denom, ); - tx.add_code_from_hash(code_hash, Some(TX_SHIELDING_TRANSFER_WASM.to_owned())); + tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); let data = transfers.data.into_iter().map(|transfer| - ShieldingTransferData{ + TransferData{ source: transfer.source, - token: token.clone(), - amount + token: token.clone(), + amount, + target: MASP, } ).collect(); - let data = ShieldingMultiTransfer{data, shielded_section_hash }; + let data = Transfer{ + data, + shielded_section_hash: Some(shielded_section_hash), + }; tx.add_data(data.clone()); TxData::ShieldingTransfer(data, (build_params, build_param_bytes)) }, diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index 6a5dda0c67..5f6b1c5c0f 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -48,11 +48,10 @@ use crate::tx::{ TX_CHANGE_METADATA_WASM, TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, - TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_SHIELDING_TRANSFER_WASM, - TX_TRANSFER_WASM, TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, - TX_UNSHIELDING_TRANSFER_WASM, TX_UPDATE_ACCOUNT_WASM, - TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, - VP_USER_WASM, + TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_TRANSFER_WASM, TX_UNBOND_WASM, + TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, + TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, + TX_WITHDRAW_WASM, VP_USER_WASM, }; pub use crate::wallet::store::AddressVpType; use crate::wallet::{Wallet, WalletIo}; @@ -709,7 +708,6 @@ enum TransferSide<'a> { enum TokenTransfer<'a> { Transparent(&'a token::Transfer), - Shielding(&'a token::ShieldingMultiTransfer), Unshielding(&'a token::UnshieldingMultiTransfer), } @@ -721,11 +719,6 @@ impl TokenTransfer<'_> { .iter() .map(|transfer| &transfer.source) .collect(), - TokenTransfer::Shielding(transfers) => transfers - .data - .iter() - .map(|transfer| &transfer.source) - .collect(), TokenTransfer::Unshielding(_) => Default::default(), } } @@ -737,7 +730,6 @@ impl TokenTransfer<'_> { .iter() .map(|transfer| &transfer.target) .collect(), - TokenTransfer::Shielding(_) => Default::default(), TokenTransfer::Unshielding(transfers) => transfers .data .iter() @@ -782,24 +774,6 @@ impl TokenTransfer<'_> { map } - TokenTransfer::Shielding(transfers) => { - let mut map: HashMap<&Address, DenominatedAmount> = - HashMap::new(); - - if let TransferSide::Source(source_addr) = address { - for transfer in &transfers.data { - if &transfer.source == source_addr { - Self::update_token_amount_map( - &mut map, - &transfer.token, - transfer.amount, - )?; - } - } - } - - map - } TokenTransfer::Unshielding(transfers) => { let mut map: HashMap<&Address, DenominatedAmount> = HashMap::new(); @@ -1459,53 +1433,6 @@ pub async fn to_ledger_vector( &asset_types, ) .await?; - } else if code_sec.tag == Some(TX_SHIELDING_TRANSFER_WASM.to_string()) { - let transfer = token::ShieldingMultiTransfer::try_from_slice( - &tx.data(cmt) - .ok_or_else(|| Error::Other("Invalid Data".to_string()))?, - ) - .map_err(|err| { - Error::from(EncodingError::Conversion(err.to_string())) - })?; - // To facilitate lookups of MASP AssetTypes - let mut asset_types = HashMap::new(); - let builder = tx.sections.iter().find_map(|x| match x { - Section::MaspBuilder(builder) - if builder.target == transfer.shielded_section_hash => - { - for decoded in &builder.asset_types { - match decoded.encode() { - Err(_) => None, - Ok(asset) => { - asset_types.insert(asset, decoded.clone()); - Some(builder) - } - }?; - } - Some(builder) - } - _ => None, - }); - - tv.name = "ShieldingTransfer_0".to_string(); - - tv.output.push("Type : ShieldingTransfer".to_string()); - make_ledger_token_transfer_endpoints( - &tokens, - &mut tv.output, - TokenTransfer::Shielding(&transfer), - builder, - &asset_types, - ) - .await?; - make_ledger_token_transfer_endpoints( - &tokens, - &mut tv.output_expert, - TokenTransfer::Shielding(&transfer), - builder, - &asset_types, - ) - .await?; } else if code_sec.tag == Some(TX_UNSHIELDING_TRANSFER_WASM.to_string()) { let transfer = token::UnshieldingMultiTransfer::try_from_slice( diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index 413535328c..dda4d54c6a 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -65,7 +65,7 @@ use namada_tx::data::{pos, BatchedTxResult, ResultCode, TxResult}; pub use namada_tx::{Authorization, *}; use num_traits::Zero; use rand_core::{OsRng, RngCore}; -use token::ShieldingTransferData; +use token::TransferData; use crate::args::{ TxShieldedTransferData, TxShieldingTransferData, TxTransparentTransferData, @@ -109,8 +109,6 @@ pub const TX_REVEAL_PK: &str = "tx_reveal_pk.wasm"; pub const TX_UPDATE_ACCOUNT_WASM: &str = "tx_update_account.wasm"; /// Transparent transfer transaction WASM path pub const TX_TRANSFER_WASM: &str = "tx_transparent_transfer.wasm"; -/// Shielding transfer transaction WASM path -pub const TX_SHIELDING_TRANSFER_WASM: &str = "tx_shielding_transfer.wasm"; /// Unshielding transfer transaction WASM path pub const TX_UNSHIELDING_TRANSFER_WASM: &str = "tx_unshielding_transfer.wasm"; /// IBC transaction WASM path @@ -2574,15 +2572,16 @@ pub async fn build_ibc_transfer( let transfer = shielded_parts.map(|(shielded_transfer, asset_types)| { let masp_tx_hash = tx.add_masp_tx_section(shielded_transfer.masp_tx.clone()).1; - let transfer = token::ShieldingTransfer { - data: ShieldingTransferData { + let transfer = token::Transfer { + data: vec![TransferData { // The token will be escrowed to IBC address source: source.clone(), + target: MASP, token: args.token.clone(), amount: validated_amount, - }, + }], // Link the Transfer to the MASP Transaction by hash code - shielded_section_hash: masp_tx_hash, + shielded_section_hash: Some(masp_tx_hash), }; tx.add_masp_builder(MaspBuilder { asset_types, @@ -3102,8 +3101,9 @@ pub async fn build_shielding_transfer( amount: validated_amount, }); - data.push(token::ShieldingTransferData { + data.push(token::TransferData { source: source.to_owned(), + target: MASP, token: token.to_owned(), amount: validated_amount, }); @@ -3118,40 +3118,39 @@ pub async fn build_shielding_transfer( .expect("Shielding transfer must have shielded parts"); let shielded_tx_epoch = shielded_parts.0.epoch; - let add_shielded_parts = - |tx: &mut Tx, data: &mut token::ShieldingMultiTransfer| { - // Add the MASP Transaction and its Builder to facilitate validation - let ( - ShieldedTransfer { - builder, - masp_tx, - metadata, - epoch: _, - }, - asset_types, - ) = shielded_parts; - // Add a MASP Transaction section to the Tx and get the tx hash - let shielded_section_hash = tx.add_masp_tx_section(masp_tx).1; - - tx.add_masp_builder(MaspBuilder { - asset_types, - // Store how the Info objects map to Descriptors/Outputs - metadata, - // Store the data that was used to construct the Transaction + let add_shielded_parts = |tx: &mut Tx, data: &mut token::Transfer| { + // Add the MASP Transaction and its Builder to facilitate validation + let ( + ShieldedTransfer { builder, - // Link the Builder to the Transaction by hash code - target: shielded_section_hash, - }); + masp_tx, + metadata, + epoch: _, + }, + asset_types, + ) = shielded_parts; + // Add a MASP Transaction section to the Tx and get the tx hash + let shielded_section_hash = tx.add_masp_tx_section(masp_tx).1; - data.shielded_section_hash = shielded_section_hash; - tracing::debug!("Transfer data {data:?}"); - Ok(()) - }; + tx.add_masp_builder(MaspBuilder { + asset_types, + // Store how the Info objects map to Descriptors/Outputs + metadata, + // Store the data that was used to construct the Transaction + builder, + // Link the Builder to the Transaction by hash code + target: shielded_section_hash, + }); + + data.shielded_section_hash = Some(shielded_section_hash); + tracing::debug!("Transfer data {data:?}"); + Ok(()) + }; // Construct the tx data with a placeholder shielded section hash - let data = token::ShieldingMultiTransfer { + let data = token::Transfer { data, - shielded_section_hash: Hash::zero(), + shielded_section_hash: None, }; let tx = build_pow_flag( @@ -3575,7 +3574,7 @@ pub async fn build_custom( pub async fn gen_ibc_shielding_transfer( context: &N, args: args::GenIbcShieldedTransfer, -) -> Result> { +) -> Result> { let source = Address::Internal(InternalAddress::Ibc); let (src_port_id, src_channel_id) = get_ibc_src_port_channel(context, &args.port_id, &args.channel_id) @@ -3633,13 +3632,14 @@ pub async fn gen_ibc_shielding_transfer( if let Some(shielded_transfer) = shielded_transfer { let masp_tx_hash = Section::MaspTx(shielded_transfer.masp_tx.clone()).get_hash(); - let transfer = token::ShieldingTransfer { - data: ShieldingTransferData { + let transfer = token::Transfer { + data: vec![TransferData { source: source.clone(), + target: MASP, token: token.clone(), amount: validated_amount, - }, - shielded_section_hash: masp_tx_hash, + }], + shielded_section_hash: Some(masp_tx_hash), }; Ok(Some((transfer, shielded_transfer.masp_tx))) } else { diff --git a/crates/token/src/lib.rs b/crates/token/src/lib.rs index 5b94d87861..14431dfa21 100644 --- a/crates/token/src/lib.rs +++ b/crates/token/src/lib.rs @@ -125,77 +125,6 @@ pub struct TransferData { pub amount: DenominatedAmount, } -/// Arguments for a shielding transfer (from a transparent token to a shielded -/// token) -#[derive( - Debug, - Clone, - PartialEq, - BorshSerialize, - BorshDeserialize, - BorshDeserializer, - BorshSchema, - Hash, - Eq, - PartialOrd, - Serialize, - Deserialize, -)] -pub struct ShieldingTransferData { - /// Source address will spend the tokens - pub source: Address, - /// Token's address - pub token: Address, - /// The amount of tokens - pub amount: DenominatedAmount, -} - -/// Arguments for a shielding transfer (from a transparent token to a shielded -/// token) -#[derive( - Debug, - Clone, - PartialEq, - BorshSerialize, - BorshDeserialize, - BorshDeserializer, - BorshSchema, - Hash, - Eq, - PartialOrd, - Serialize, - Deserialize, -)] -pub struct ShieldingTransfer { - /// Transfer-specific data - pub data: ShieldingTransferData, - /// Hash of tx section that contains the MASP transaction - pub shielded_section_hash: Hash, -} - -/// Arguments for a shielding transfer (from a transparent token to a shielded -/// token) -#[derive( - Debug, - Clone, - PartialEq, - BorshSerialize, - BorshDeserialize, - BorshDeserializer, - BorshSchema, - Hash, - Eq, - PartialOrd, - Serialize, - Deserialize, -)] -pub struct ShieldingMultiTransfer { - /// Transfer-specific data - pub data: Vec, - /// Hash of tx section that contains the MASP transaction - pub shielded_section_hash: Hash, -} - /// Arguments for an unshielding transfer (from a shielded token to a /// transparent token) #[derive( diff --git a/crates/tx_prelude/src/token.rs b/crates/tx_prelude/src/token.rs index d7fa7bb017..7271881c87 100644 --- a/crates/tx_prelude/src/token.rs +++ b/crates/tx_prelude/src/token.rs @@ -5,8 +5,8 @@ use namada_events::{EmitEvents, EventLevel}; #[cfg(any(test, feature = "testing"))] pub use namada_token::testing; pub use namada_token::{ - storage_key, utils, Amount, DenominatedAmount, ShieldingMultiTransfer, - ShieldingTransfer, Transfer, UnshieldingMultiTransfer, UnshieldingTransfer, + storage_key, utils, Amount, DenominatedAmount, Transfer, + UnshieldingMultiTransfer, UnshieldingTransfer, }; use namada_tx_env::TxEnv; diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index 55fd0f4962..016495c1f9 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -6888,15 +6888,6 @@ dependencies = [ "rlsf", ] -[[package]] -name = "tx_shielding_transfer" -version = "0.39.0" -dependencies = [ - "getrandom 0.2.15", - "namada_tx_prelude", - "rlsf", -] - [[package]] name = "tx_transparent_transfer" version = "0.39.0" diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index 3496714896..bc353fb215 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -17,7 +17,6 @@ members = [ "tx_redelegate", "tx_resign_steward", "tx_reveal_pk", - "tx_shielding_transfer", "tx_transparent_transfer", "tx_unbond", "tx_unjail_validator", diff --git a/wasm/checksums.json b/wasm/checksums.json index 0ed3052622..59d828bca9 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -7,17 +7,17 @@ "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.38d2819cdb4fe80a832c163c5b316c9e74c564deba9732ed7452cb2b3bef42c2.wasm", "tx_claim_rewards.wasm": "tx_claim_rewards.1fd1118484a918947a005442b5dcac77556c538533982ccbcba9d7b02de533b0.wasm", "tx_deactivate_validator.wasm": "tx_deactivate_validator.9dacf4d4aef2bc4d5ee8fce78f73544783376a974de686adc87ff0957e5a46fb.wasm", - "tx_ibc.wasm": "tx_ibc.c4e9528a911bd0ebf7c59e69eeed9f5b8f60b083a86ef69882b6a6c130c60560.wasm", + "tx_ibc.wasm": "tx_ibc.dc05de488be5664844c93fad966000190c2b0847d4b5c20834c165a56ee716a7.wasm", "tx_init_account.wasm": "tx_init_account.d2f3a2c059e0f92d683471df83afb4cd7e143e4a0428893cf7e6155382d8270d.wasm", "tx_init_proposal.wasm": "tx_init_proposal.04cb9b3468e6ffc7604231acb1668ff92e0c28a06354c7ad26698fb549a7aab5.wasm", "tx_reactivate_validator.wasm": "tx_reactivate_validator.0c52fcf238c1b9be9455891744f5f495b4c78c26bbe20fad5eddbb28b6176792.wasm", "tx_redelegate.wasm": "tx_redelegate.c584955237fb27964fc94c1aaa2c04eb9190894f6c24b4634e0b07cee511cce8.wasm", "tx_resign_steward.wasm": "tx_resign_steward.c3f8a4465aad3fb674dbd80c2c994e1881a25315215b615dcd570885271c481b.wasm", "tx_reveal_pk.wasm": "tx_reveal_pk.79455aadb09effe70b407a88dcb50552344e32d9b9e30897b7e0e24ce34e76a2.wasm", - "tx_shielded_transfer.wasm": "tx_shielded_transfer.4a1a14ed6fa19fe15b47fab5170a9d7b3098dcaec9e9437cdf7fc3fc12545f6d.wasm", - "tx_shielding_transfer.wasm": "tx_shielding_transfer.f4402e2c5e793021775bd4289ac3f777a41d06743cc5e77dcc3a5c0b9c9cfe17.wasm", + "tx_shielded_transfer.wasm": "tx_shielded_transfer.325ffb8c64c659ae32b23ba16604dcbd8bc4a2ddf9e9996796ef21ceed46acbc.wasm", + "tx_shielding_transfer.wasm": "tx_shielding_transfer.faa52f9523afc330bc32df84d8f71fa933dbb65bf8ff84bcf0bfbb84f79dc09c.wasm", "tx_transfer.wasm": "tx_transfer.8acfe426d01adc17018c07b1c9f2eb3f77ddff4a6e452c8d5ae16832a0e79c85.wasm", - "tx_transparent_transfer.wasm": "tx_transparent_transfer.423b3423cc3a0fb49a52ea20b76460f800cedde60485d2af05bdf2d500ab6f1e.wasm", + "tx_transparent_transfer.wasm": "tx_transparent_transfer.fcf550221ccdad9c1d7125acd058b9376bc7202bcd0d9084f4405644a62111c9.wasm", "tx_unbond.wasm": "tx_unbond.3d69f98b7832de1d63cdff4e2dec3eb8ba6da44104af00ed0607f040c300d52c.wasm", "tx_unjail_validator.wasm": "tx_unjail_validator.d736868736feccea85d7bb8a5bd5cc67c19315521f608838ad60befbfc9e7738.wasm", "tx_unshielding_transfer.wasm": "tx_unshielding_transfer.45f38800ba76682d965cb1aa894a29801d2c9faf3e9d41b2394a12e44aa99055.wasm", diff --git a/wasm/tx_ibc/src/lib.rs b/wasm/tx_ibc/src/lib.rs index e131a90c9a..fec8318ca9 100644 --- a/wasm/tx_ibc/src/lib.rs +++ b/wasm/tx_ibc/src/lib.rs @@ -13,7 +13,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { ibc::ibc_actions(ctx).execute(&data).into_storage_result()?; if let Some(masp_section_ref) = - transfer.map(|transfer| transfer.shielded_section_hash) + transfer.and_then(|transfer| transfer.shielded_section_hash) { let shielded = tx_data .tx From 7a80d5998d04d384d53643be4e139306cfde3d9b Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Thu, 27 Jun 2024 17:51:58 +0200 Subject: [PATCH 5/9] Subsumed unshielding transfer into generalized transfer. --- crates/apps_lib/src/cli.rs | 8 +- crates/encoding_spec/src/main.rs | 3 - crates/light_sdk/src/transaction/transfer.rs | 21 ++---- crates/node/src/bench_utils.rs | 20 +++-- crates/sdk/src/lib.rs | 26 +++---- crates/sdk/src/signing.rs | 79 +------------------- crates/sdk/src/tx.rs | 62 ++++++++------- crates/token/src/lib.rs | 71 ------------------ crates/tx_prelude/src/token.rs | 1 - wasm/Cargo.lock | 9 --- wasm/Cargo.toml | 1 - 11 files changed, 64 insertions(+), 237 deletions(-) diff --git a/crates/apps_lib/src/cli.rs b/crates/apps_lib/src/cli.rs index 010e467d1f..bc4da08739 100644 --- a/crates/apps_lib/src/cli.rs +++ b/crates/apps_lib/src/cli.rs @@ -3100,9 +3100,9 @@ pub mod args { TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_TRANSFER_WASM, TX_UNBOND_WASM, - TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, - TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, - TX_WITHDRAW_WASM, VP_USER_WASM, + TX_UNJAIL_VALIDATOR_WASM, TX_UPDATE_ACCOUNT_WASM, + TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, + VP_USER_WASM, }; use namada_sdk::DEFAULT_GAS_LIMIT; @@ -4573,7 +4573,7 @@ pub mod args { let target = TARGET.parse(matches); let token = TOKEN.parse(matches); let amount = InputAmount::Unvalidated(AMOUNT.parse(matches)); - let tx_code_path = PathBuf::from(TX_UNSHIELDING_TRANSFER_WASM); + let tx_code_path = PathBuf::from(TX_TRANSFER_WASM); let data = vec![TxUnshieldingTransferData { target, token, diff --git a/crates/encoding_spec/src/main.rs b/crates/encoding_spec/src/main.rs index 9208c7d2c0..b0a3bdb858 100644 --- a/crates/encoding_spec/src/main.rs +++ b/crates/encoding_spec/src/main.rs @@ -82,8 +82,6 @@ fn main() -> Result<(), Box> { let init_account_schema = schema_container_of::(); let init_validator_schema = schema_container_of::(); let transfer_schema = schema_container_of::(); - let unshielding_transfer_schema = - schema_container_of::(); let update_account = schema_container_of::(); let pos_bond_schema = schema_container_of::(); let pos_withdraw_schema = schema_container_of::(); @@ -111,7 +109,6 @@ fn main() -> Result<(), Box> { definitions.extend(btree(&init_account_schema)); definitions.extend(btree(&init_validator_schema)); definitions.extend(btree(&transfer_schema)); - definitions.extend(btree(&unshielding_transfer_schema)); definitions.extend(btree(&update_account)); definitions.extend(btree(&pos_bond_schema)); definitions.extend(btree(&pos_withdraw_schema)); diff --git a/crates/light_sdk/src/transaction/transfer.rs b/crates/light_sdk/src/transaction/transfer.rs index 5dc0115712..483a490150 100644 --- a/crates/light_sdk/src/transaction/transfer.rs +++ b/crates/light_sdk/src/transaction/transfer.rs @@ -3,13 +3,9 @@ use namada_sdk::hash::Hash; use namada_sdk::key::common; use namada_sdk::token::transaction::Transaction; use namada_sdk::token::TransferData; -pub use namada_sdk::token::{ - DenominatedAmount, Transfer, UnshieldingTransferData, -}; +pub use namada_sdk::token::{DenominatedAmount, Transfer}; use namada_sdk::tx::data::GasLimit; -use namada_sdk::tx::{ - Authorization, Tx, TxError, TX_TRANSFER_WASM, TX_UNSHIELDING_TRANSFER_WASM, -}; +use namada_sdk::tx::{Authorization, Tx, TxError, TX_TRANSFER_WASM}; use super::{attach_fee, attach_fee_signature, GlobalArgs}; use crate::transaction; @@ -67,21 +63,18 @@ impl TransferBuilder { /// Build an unshielding transfer transaction from the given parameters pub fn unshielding( - transfers: Vec, + transfers: Vec, shielded_section_hash: Hash, transaction: Transaction, args: GlobalArgs, ) -> Self { - let data = namada_sdk::token::UnshieldingMultiTransfer { + let data = namada_sdk::token::Transfer { data: transfers, - shielded_section_hash, + shielded_section_hash: Some(shielded_section_hash), }; - let mut tx = transaction::build_tx( - args, - data, - TX_UNSHIELDING_TRANSFER_WASM.to_string(), - ); + let mut tx = + transaction::build_tx(args, data, TX_TRANSFER_WASM.to_string()); tx.add_masp_tx_section(transaction); Self(tx) diff --git a/crates/node/src/bench_utils.rs b/crates/node/src/bench_utils.rs index a845356175..37e4dd6a44 100644 --- a/crates/node/src/bench_utils.rs +++ b/crates/node/src/bench_utils.rs @@ -75,10 +75,7 @@ use namada::ledger::queries::{ }; use namada::masp::MaspTxRefs; use namada::state::StorageRead; -use namada::token::{ - Amount, DenominatedAmount, Transfer, TransferData, - UnshieldingMultiTransfer, UnshieldingTransferData, -}; +use namada::token::{Amount, DenominatedAmount, Transfer, TransferData}; use namada::tx::data::pos::Bond; use namada::tx::data::{ BatchResults, BatchedTxResult, Fee, TxResult, VpsResult, @@ -105,9 +102,9 @@ pub use namada_sdk::tx::{ TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL as TX_INIT_PROPOSAL_WASM, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, TX_REVEAL_PK as TX_REVEAL_PK_WASM, TX_TRANSFER_WASM, TX_UNBOND_WASM, - TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, - TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, - TX_VOTE_PROPOSAL as TX_VOTE_PROPOSAL_WASM, TX_WITHDRAW_WASM, VP_USER_WASM, + TX_UNJAIL_VALIDATOR_WASM, TX_UPDATE_ACCOUNT_WASM, + TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL as TX_VOTE_PROPOSAL_WASM, + TX_WITHDRAW_WASM, VP_USER_WASM, }; use namada_sdk::wallet::Wallet; use namada_sdk::{Namada, NamadaImpl}; @@ -1142,14 +1139,15 @@ impl BenchShieldedCtx { ) } else { namada.client().generate_tx( - TX_UNSHIELDING_TRANSFER_WASM, - UnshieldingMultiTransfer { - data: vec![UnshieldingTransferData { + TX_TRANSFER_WASM, + Transfer { + data: vec![TransferData { + source: MASP, target: target.effective_address(), token: address::testing::nam(), amount: DenominatedAmount::native(amount), }], - shielded_section_hash, + shielded_section_hash: Some(shielded_section_hash), }, Some(shielded), None, diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 2186e23b8f..6e483b4871 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -73,9 +73,9 @@ use tx::{ TX_CLAIM_REWARDS_WASM, TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_TRANSFER_WASM, - TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, - TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, - TX_WITHDRAW_WASM, VP_USER_WASM, + TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM, TX_UPDATE_ACCOUNT_WASM, + TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, + VP_USER_WASM, }; use wallet::{Wallet, WalletIo, WalletStorage}; @@ -220,7 +220,7 @@ pub trait Namada: Sized + MaybeSync + MaybeSend { args::TxUnshieldingTransfer { source, data, - tx_code_path: PathBuf::from(TX_UNSHIELDING_TRANSFER_WASM), + tx_code_path: PathBuf::from(TX_TRANSFER_WASM), tx: self.tx_builder(), } } @@ -865,9 +865,7 @@ pub mod testing { use ripemd::Digest as RipemdDigest; use sha2::Digest; use token::testing::arb_vectorized_transparent_transfer; - use token::{ - TransferData, UnshieldingMultiTransfer, UnshieldingTransferData, - }; + use token::TransferData; use super::*; use crate::account::tests::{arb_init_account, arb_update_account}; @@ -912,10 +910,7 @@ pub mod testing { TransparentTransfer(Transfer), ShieldedTransfer(Transfer, (StoredBuildParams, String)), ShieldingTransfer(Transfer, (StoredBuildParams, String)), - UnshieldingTransfer( - UnshieldingMultiTransfer, - (StoredBuildParams, String), - ), + UnshieldingTransfer(Transfer, (StoredBuildParams, String)), Bond(Bond), Redelegation(Redelegation), UpdateStewardCommission(UpdateStewardCommission), @@ -1167,15 +1162,16 @@ pub mod testing { token::Amount::from_masp_denominated(*value, decoded.position), decoded.denom, ); - tx.add_code_from_hash(code_hash, Some(TX_UNSHIELDING_TRANSFER_WASM.to_owned())); + tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); let data = transfers.data.into_iter().map(|transfer| - UnshieldingTransferData{ + TransferData{ target: transfer.target, token: token.clone(), - amount + amount, + source: MASP, } ).collect(); - let data = UnshieldingMultiTransfer{data, shielded_section_hash }; + let data = Transfer{data, shielded_section_hash: Some(shielded_section_hash) }; tx.add_data(data.clone()); TxData::UnshieldingTransfer(data, (build_params, build_param_bytes)) }, diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index 5f6b1c5c0f..5c92356887 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -49,9 +49,9 @@ use crate::tx::{ TX_DEACTIVATE_VALIDATOR_WASM, TX_IBC_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM, TX_RESIGN_STEWARD, TX_REVEAL_PK, TX_TRANSFER_WASM, TX_UNBOND_WASM, - TX_UNJAIL_VALIDATOR_WASM, TX_UNSHIELDING_TRANSFER_WASM, - TX_UPDATE_ACCOUNT_WASM, TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, - TX_WITHDRAW_WASM, VP_USER_WASM, + TX_UNJAIL_VALIDATOR_WASM, TX_UPDATE_ACCOUNT_WASM, + TX_UPDATE_STEWARD_COMMISSION, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, + VP_USER_WASM, }; pub use crate::wallet::store::AddressVpType; use crate::wallet::{Wallet, WalletIo}; @@ -708,7 +708,6 @@ enum TransferSide<'a> { enum TokenTransfer<'a> { Transparent(&'a token::Transfer), - Unshielding(&'a token::UnshieldingMultiTransfer), } impl TokenTransfer<'_> { @@ -719,7 +718,6 @@ impl TokenTransfer<'_> { .iter() .map(|transfer| &transfer.source) .collect(), - TokenTransfer::Unshielding(_) => Default::default(), } } @@ -730,11 +728,6 @@ impl TokenTransfer<'_> { .iter() .map(|transfer| &transfer.target) .collect(), - TokenTransfer::Unshielding(transfers) => transfers - .data - .iter() - .map(|transfer| &transfer.target) - .collect(), } } @@ -772,24 +765,6 @@ impl TokenTransfer<'_> { } } - map - } - TokenTransfer::Unshielding(transfers) => { - let mut map: HashMap<&Address, DenominatedAmount> = - HashMap::new(); - - if let TransferSide::Target(target_addr) = address { - for transfer in &transfers.data { - if &transfer.target == target_addr { - Self::update_token_amount_map( - &mut map, - &transfer.token, - transfer.amount, - )?; - } - } - } - map } }) @@ -1433,54 +1408,6 @@ pub async fn to_ledger_vector( &asset_types, ) .await?; - } else if code_sec.tag == Some(TX_UNSHIELDING_TRANSFER_WASM.to_string()) - { - let transfer = token::UnshieldingMultiTransfer::try_from_slice( - &tx.data(cmt) - .ok_or_else(|| Error::Other("Invalid Data".to_string()))?, - ) - .map_err(|err| { - Error::from(EncodingError::Conversion(err.to_string())) - })?; - // To facilitate lookups of MASP AssetTypes - let mut asset_types = HashMap::new(); - let builder = tx.sections.iter().find_map(|x| match x { - Section::MaspBuilder(builder) - if builder.target == transfer.shielded_section_hash => - { - for decoded in &builder.asset_types { - match decoded.encode() { - Err(_) => None, - Ok(asset) => { - asset_types.insert(asset, decoded.clone()); - Some(builder) - } - }?; - } - Some(builder) - } - _ => None, - }); - - tv.name = "UnshieldingTransfer_0".to_string(); - - tv.output.push("Type : UnshieldingTransfer".to_string()); - make_ledger_token_transfer_endpoints( - &tokens, - &mut tv.output, - TokenTransfer::Unshielding(&transfer), - builder, - &asset_types, - ) - .await?; - make_ledger_token_transfer_endpoints( - &tokens, - &mut tv.output_expert, - TokenTransfer::Unshielding(&transfer), - builder, - &asset_types, - ) - .await?; } else if code_sec.tag == Some(TX_IBC_WASM.to_string()) { let any_msg = Any::decode( tx.data(cmt) diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index dda4d54c6a..db613a5fc7 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -109,8 +109,6 @@ pub const TX_REVEAL_PK: &str = "tx_reveal_pk.wasm"; pub const TX_UPDATE_ACCOUNT_WASM: &str = "tx_update_account.wasm"; /// Transparent transfer transaction WASM path pub const TX_TRANSFER_WASM: &str = "tx_transparent_transfer.wasm"; -/// Unshielding transfer transaction WASM path -pub const TX_UNSHIELDING_TRANSFER_WASM: &str = "tx_unshielding_transfer.wasm"; /// IBC transaction WASM path pub const TX_IBC_WASM: &str = "tx_ibc.wasm"; /// User validity predicate WASM path @@ -3198,7 +3196,8 @@ pub async fn build_unshielding_transfer( amount: validated_amount, }); - data.push(token::UnshieldingTransferData { + data.push(token::TransferData { + source: MASP, target: target.to_owned(), token: token.to_owned(), amount: validated_amount, @@ -3215,40 +3214,39 @@ pub async fn build_unshielding_transfer( .await? .expect("Shielding transfer must have shielded parts"); - let add_shielded_parts = - |tx: &mut Tx, data: &mut token::UnshieldingMultiTransfer| { - // Add the MASP Transaction and its Builder to facilitate validation - let ( - ShieldedTransfer { - builder, - masp_tx, - metadata, - epoch: _, - }, - asset_types, - ) = shielded_parts; - // Add a MASP Transaction section to the Tx and get the tx hash - let shielded_section_hash = tx.add_masp_tx_section(masp_tx).1; - - tx.add_masp_builder(MaspBuilder { - asset_types, - // Store how the Info objects map to Descriptors/Outputs - metadata, - // Store the data that was used to construct the Transaction + let add_shielded_parts = |tx: &mut Tx, data: &mut token::Transfer| { + // Add the MASP Transaction and its Builder to facilitate validation + let ( + ShieldedTransfer { builder, - // Link the Builder to the Transaction by hash code - target: shielded_section_hash, - }); + masp_tx, + metadata, + epoch: _, + }, + asset_types, + ) = shielded_parts; + // Add a MASP Transaction section to the Tx and get the tx hash + let shielded_section_hash = tx.add_masp_tx_section(masp_tx).1; - data.shielded_section_hash = shielded_section_hash; - tracing::debug!("Transfer data {data:?}"); - Ok(()) - }; + tx.add_masp_builder(MaspBuilder { + asset_types, + // Store how the Info objects map to Descriptors/Outputs + metadata, + // Store the data that was used to construct the Transaction + builder, + // Link the Builder to the Transaction by hash code + target: shielded_section_hash, + }); + + data.shielded_section_hash = Some(shielded_section_hash); + tracing::debug!("Transfer data {data:?}"); + Ok(()) + }; // Construct the tx data with a placeholder shielded section hash - let data = token::UnshieldingMultiTransfer { + let data = token::Transfer { data, - shielded_section_hash: Hash::zero(), + shielded_section_hash: None, }; let tx = build_pow_flag( diff --git a/crates/token/src/lib.rs b/crates/token/src/lib.rs index 14431dfa21..cc2caf2487 100644 --- a/crates/token/src/lib.rs +++ b/crates/token/src/lib.rs @@ -125,77 +125,6 @@ pub struct TransferData { pub amount: DenominatedAmount, } -/// Arguments for an unshielding transfer (from a shielded token to a -/// transparent token) -#[derive( - Debug, - Clone, - PartialEq, - BorshSerialize, - BorshDeserialize, - BorshDeserializer, - BorshSchema, - Hash, - Eq, - PartialOrd, - Serialize, - Deserialize, -)] -pub struct UnshieldingTransferData { - /// Target address will receive the tokens - pub target: Address, - /// Token's address - pub token: Address, - /// The amount of tokens - pub amount: DenominatedAmount, -} - -/// Arguments for an unshielding transfer (from a shielded token to a -/// transparent token) -#[derive( - Debug, - Clone, - PartialEq, - BorshSerialize, - BorshDeserialize, - BorshDeserializer, - BorshSchema, - Hash, - Eq, - PartialOrd, - Serialize, - Deserialize, -)] -pub struct UnshieldingTransfer { - /// Transfer-specific data - pub data: UnshieldingTransferData, - /// Hash of tx section that contains the MASP transaction - pub shielded_section_hash: Hash, -} - -/// Arguments for a multi-source unshielding transfer (from a shielded token to -/// a transparent token) -#[derive( - Debug, - Clone, - PartialEq, - BorshSerialize, - BorshDeserialize, - BorshDeserializer, - BorshSchema, - Hash, - Eq, - PartialOrd, - Serialize, - Deserialize, -)] -pub struct UnshieldingMultiTransfer { - /// Transfer-specific data - pub data: Vec, - /// Hash of tx section that contains the MASP transaction - pub shielded_section_hash: Hash, -} - #[cfg(any(test, feature = "testing"))] /// Testing helpers and strategies for tokens pub mod testing { diff --git a/crates/tx_prelude/src/token.rs b/crates/tx_prelude/src/token.rs index 7271881c87..99af630dbb 100644 --- a/crates/tx_prelude/src/token.rs +++ b/crates/tx_prelude/src/token.rs @@ -6,7 +6,6 @@ use namada_events::{EmitEvents, EventLevel}; pub use namada_token::testing; pub use namada_token::{ storage_key, utils, Amount, DenominatedAmount, Transfer, - UnshieldingMultiTransfer, UnshieldingTransfer, }; use namada_tx_env::TxEnv; diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index 016495c1f9..d7ac775cc1 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -6923,15 +6923,6 @@ dependencies = [ "rlsf", ] -[[package]] -name = "tx_unshielding_transfer" -version = "0.39.0" -dependencies = [ - "getrandom 0.2.15", - "namada_tx_prelude", - "rlsf", -] - [[package]] name = "tx_update_account" version = "0.39.0" diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index bc353fb215..7cebbe0304 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -20,7 +20,6 @@ members = [ "tx_transparent_transfer", "tx_unbond", "tx_unjail_validator", - "tx_unshielding_transfer", "tx_update_account", "tx_update_steward_commission", "tx_vote_proposal", From 29a64ebb06577f620ff5bcb0af8fc8d58161a5cc Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Thu, 27 Jun 2024 18:38:50 +0200 Subject: [PATCH 6/9] Remove now dead code. --- crates/light_sdk/src/transaction/transfer.rs | 32 ++--- crates/sdk/src/lib.rs | 10 +- crates/sdk/src/signing.rs | 116 ++++++------------ crates/sdk/src/tx.rs | 2 +- wasm/Cargo.lock | 2 +- wasm/Cargo.toml | 2 +- wasm/checksums.json | 6 +- wasm/tx_shielded_transfer/src/lib.rs | 29 ----- wasm/tx_shielding_transfer/Cargo.toml | 18 --- wasm/tx_shielding_transfer/src/lib.rs | 41 ------- .../Cargo.toml | 2 +- .../src/lib.rs | 0 wasm/tx_transparent_transfer/Cargo.toml | 18 --- wasm/tx_unshielding_transfer/Cargo.toml | 18 --- wasm/tx_unshielding_transfer/src/lib.rs | 41 ------- 15 files changed, 56 insertions(+), 281 deletions(-) delete mode 100644 wasm/tx_shielded_transfer/src/lib.rs delete mode 100644 wasm/tx_shielding_transfer/Cargo.toml delete mode 100644 wasm/tx_shielding_transfer/src/lib.rs rename wasm/{tx_shielded_transfer => tx_transfer}/Cargo.toml (92%) rename wasm/{tx_transparent_transfer => tx_transfer}/src/lib.rs (100%) delete mode 100644 wasm/tx_transparent_transfer/Cargo.toml delete mode 100644 wasm/tx_unshielding_transfer/Cargo.toml delete mode 100644 wasm/tx_unshielding_transfer/src/lib.rs diff --git a/crates/light_sdk/src/transaction/transfer.rs b/crates/light_sdk/src/transaction/transfer.rs index 483a490150..167d264ae5 100644 --- a/crates/light_sdk/src/transaction/transfer.rs +++ b/crates/light_sdk/src/transaction/transfer.rs @@ -16,10 +16,15 @@ pub struct TransferBuilder(Tx); impl TransferBuilder { /// Build a transparent transfer transaction from the given parameters - pub fn transparent(transfers: Transfer, args: GlobalArgs) -> Self { + pub fn transparent(transfers: Vec, args: GlobalArgs) -> Self { + let data = namada_sdk::token::Transfer { + data: transfers, + shielded_section_hash: None, + }; + Self(transaction::build_tx( args, - transfers, + data, TX_TRANSFER_WASM.to_string(), )) } @@ -42,27 +47,8 @@ impl TransferBuilder { Self(tx) } - /// Build a shielding transfer transaction from the given parameters - pub fn shielding( - transfers: Vec, - shielded_section_hash: Hash, - transaction: Transaction, - args: GlobalArgs, - ) -> Self { - let data = namada_sdk::token::Transfer { - data: transfers, - shielded_section_hash: Some(shielded_section_hash), - }; - - let mut tx = - transaction::build_tx(args, data, TX_TRANSFER_WASM.to_string()); - tx.add_masp_tx_section(transaction); - - Self(tx) - } - - /// Build an unshielding transfer transaction from the given parameters - pub fn unshielding( + /// Build a MASP transfer transaction from the given parameters + pub fn masp( transfers: Vec, shielded_section_hash: Hash, transaction: Transaction, diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 6e483b4871..5e9c58657d 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -908,9 +908,7 @@ pub mod testing { VoteProposal(VoteProposalData), Withdraw(Withdraw), TransparentTransfer(Transfer), - ShieldedTransfer(Transfer, (StoredBuildParams, String)), - ShieldingTransfer(Transfer, (StoredBuildParams, String)), - UnshieldingTransfer(Transfer, (StoredBuildParams, String)), + MaspTransfer(Transfer, (StoredBuildParams, String)), Bond(Bond), Redelegation(Redelegation), UpdateStewardCommission(UpdateStewardCommission), @@ -1128,7 +1126,7 @@ pub mod testing { shielded_section_hash: Some(shielded_section_hash), }; tx.add_data(data.clone()); - TxData::ShieldedTransfer(data, (build_params, build_param_bytes)) + TxData::MaspTransfer(data, (build_params, build_param_bytes)) }, MaspTxType::Shielding => { // Set the transparent amount and token @@ -1152,7 +1150,7 @@ pub mod testing { shielded_section_hash: Some(shielded_section_hash), }; tx.add_data(data.clone()); - TxData::ShieldingTransfer(data, (build_params, build_param_bytes)) + TxData::MaspTransfer(data, (build_params, build_param_bytes)) }, MaspTxType::Unshielding => { // Set the transparent amount and token @@ -1173,7 +1171,7 @@ pub mod testing { ).collect(); let data = Transfer{data, shielded_section_hash: Some(shielded_section_hash) }; tx.add_data(data.clone()); - TxData::UnshieldingTransfer(data, (build_params, build_param_bytes)) + TxData::MaspTransfer(data, (build_params, build_param_bytes)) }, }; tx.add_masp_builder(MaspBuilder { diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index 5c92356887..b37a750aec 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -706,68 +706,56 @@ enum TransferSide<'a> { Target(&'a Address), } -enum TokenTransfer<'a> { - Transparent(&'a token::Transfer), -} +struct TokenTransfer<'a>(&'a token::Transfer); impl TokenTransfer<'_> { fn sources(&self) -> Vec<&Address> { - match self { - TokenTransfer::Transparent(transfers) => transfers - .data - .iter() - .map(|transfer| &transfer.source) - .collect(), - } + self.0 + .data + .iter() + .map(|transfer| &transfer.source) + .collect() } fn targets(&self) -> Vec<&Address> { - match self { - TokenTransfer::Transparent(transfers) => transfers - .data - .iter() - .map(|transfer| &transfer.target) - .collect(), - } + self.0 + .data + .iter() + .map(|transfer| &transfer.target) + .collect() } fn tokens_and_amounts( &self, address: TransferSide<'_>, ) -> Result, Error> { - Ok(match self { - TokenTransfer::Transparent(transfers) => { - let mut map: HashMap<&Address, DenominatedAmount> = - HashMap::new(); - - match address { - TransferSide::Source(source) => { - for transfer in &transfers.data { - if source == &transfer.source { - Self::update_token_amount_map( - &mut map, - &transfer.token, - transfer.amount, - )?; - } - } + let mut map: HashMap<&Address, DenominatedAmount> = HashMap::new(); + + match address { + TransferSide::Source(source) => { + for transfer in &self.0.data { + if source == &transfer.source { + Self::update_token_amount_map( + &mut map, + &transfer.token, + transfer.amount, + )?; } - TransferSide::Target(target) => { - for transfer in &transfers.data { - if target == &transfer.target { - Self::update_token_amount_map( - &mut map, - &transfer.token, - transfer.amount, - )?; - } - } + } + } + TransferSide::Target(target) => { + for transfer in &self.0.data { + if target == &transfer.target { + Self::update_token_amount_map( + &mut map, + &transfer.token, + transfer.amount, + )?; } } - - map } - }) + } + Ok(map) } fn update_token_amount_map<'a>( @@ -1340,34 +1328,6 @@ pub async fn to_ledger_vector( .map_err(|err| { Error::from(EncodingError::Conversion(err.to_string())) })?; - - tv.name = "Transfer_0".to_string(); - - tv.output.push("Type : TransparentTransfer".to_string()); - make_ledger_token_transfer_endpoints( - &tokens, - &mut tv.output, - TokenTransfer::Transparent(&transfer), - None, - &HashMap::default(), - ) - .await?; - make_ledger_token_transfer_endpoints( - &tokens, - &mut tv.output_expert, - TokenTransfer::Transparent(&transfer), - None, - &HashMap::default(), - ) - .await?; - } else if code_sec.tag == Some(TX_TRANSFER_WASM.to_string()) { - let transfer = token::Transfer::try_from_slice( - &tx.data(cmt) - .ok_or_else(|| Error::Other("Invalid Data".to_string()))?, - ) - .map_err(|err| { - Error::from(EncodingError::Conversion(err.to_string())) - })?; // To facilitate lookups of MASP AssetTypes let mut asset_types = HashMap::new(); let builder = tx.sections.iter().find_map(|x| match x { @@ -1389,13 +1349,13 @@ pub async fn to_ledger_vector( _ => None, }); - tv.name = "ShieldedTransfer_0".to_string(); + tv.name = "Transfer_0".to_string(); - tv.output.push("Type : ShieldedTransfer".to_string()); + tv.output.push("Type : Transfer".to_string()); make_ledger_token_transfer_endpoints( &tokens, &mut tv.output, - TokenTransfer::Transparent(&transfer), + TokenTransfer(&transfer), builder, &asset_types, ) @@ -1403,7 +1363,7 @@ pub async fn to_ledger_vector( make_ledger_token_transfer_endpoints( &tokens, &mut tv.output_expert, - TokenTransfer::Transparent(&transfer), + TokenTransfer(&transfer), builder, &asset_types, ) diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index db613a5fc7..7c27a08a59 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -108,7 +108,7 @@ pub const TX_REVEAL_PK: &str = "tx_reveal_pk.wasm"; /// Update validity predicate WASM path pub const TX_UPDATE_ACCOUNT_WASM: &str = "tx_update_account.wasm"; /// Transparent transfer transaction WASM path -pub const TX_TRANSFER_WASM: &str = "tx_transparent_transfer.wasm"; +pub const TX_TRANSFER_WASM: &str = "tx_transfer.wasm"; /// IBC transaction WASM path pub const TX_IBC_WASM: &str = "tx_ibc.wasm"; /// User validity predicate WASM path diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index d7ac775cc1..bc3953440f 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -6889,7 +6889,7 @@ dependencies = [ ] [[package]] -name = "tx_transparent_transfer" +name = "tx_transfer" version = "0.39.0" dependencies = [ "getrandom 0.2.15", diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index 7cebbe0304..f9b0737140 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -17,7 +17,7 @@ members = [ "tx_redelegate", "tx_resign_steward", "tx_reveal_pk", - "tx_transparent_transfer", + "tx_transfer", "tx_unbond", "tx_unjail_validator", "tx_update_account", diff --git a/wasm/checksums.json b/wasm/checksums.json index 59d828bca9..f73d7a0fd7 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -14,13 +14,9 @@ "tx_redelegate.wasm": "tx_redelegate.c584955237fb27964fc94c1aaa2c04eb9190894f6c24b4634e0b07cee511cce8.wasm", "tx_resign_steward.wasm": "tx_resign_steward.c3f8a4465aad3fb674dbd80c2c994e1881a25315215b615dcd570885271c481b.wasm", "tx_reveal_pk.wasm": "tx_reveal_pk.79455aadb09effe70b407a88dcb50552344e32d9b9e30897b7e0e24ce34e76a2.wasm", - "tx_shielded_transfer.wasm": "tx_shielded_transfer.325ffb8c64c659ae32b23ba16604dcbd8bc4a2ddf9e9996796ef21ceed46acbc.wasm", - "tx_shielding_transfer.wasm": "tx_shielding_transfer.faa52f9523afc330bc32df84d8f71fa933dbb65bf8ff84bcf0bfbb84f79dc09c.wasm", - "tx_transfer.wasm": "tx_transfer.8acfe426d01adc17018c07b1c9f2eb3f77ddff4a6e452c8d5ae16832a0e79c85.wasm", - "tx_transparent_transfer.wasm": "tx_transparent_transfer.fcf550221ccdad9c1d7125acd058b9376bc7202bcd0d9084f4405644a62111c9.wasm", + "tx_transfer.wasm": "tx_transfer.a3fd5a7966b2a56790b7e8ca3578e492e8ae2ef03dadd090ec0e82f521f5c493.wasm", "tx_unbond.wasm": "tx_unbond.3d69f98b7832de1d63cdff4e2dec3eb8ba6da44104af00ed0607f040c300d52c.wasm", "tx_unjail_validator.wasm": "tx_unjail_validator.d736868736feccea85d7bb8a5bd5cc67c19315521f608838ad60befbfc9e7738.wasm", - "tx_unshielding_transfer.wasm": "tx_unshielding_transfer.45f38800ba76682d965cb1aa894a29801d2c9faf3e9d41b2394a12e44aa99055.wasm", "tx_update_account.wasm": "tx_update_account.3daaa7d67b1545a161a65efb99fa930a09f3ecdc87e3f0a6e965d49756912b6c.wasm", "tx_update_steward_commission.wasm": "tx_update_steward_commission.a62fcce86de9723ceff0f838d106be6f912d06f48cf10a3163dbb9ef53620c96.wasm", "tx_vote_proposal.wasm": "tx_vote_proposal.724a81d2cc2a0e491381d98d22753f46003f781f09f968bff29ad57bddd6f5f8.wasm", diff --git a/wasm/tx_shielded_transfer/src/lib.rs b/wasm/tx_shielded_transfer/src/lib.rs deleted file mode 100644 index cc9e70a638..0000000000 --- a/wasm/tx_shielded_transfer/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! A tx for shielded token transfer. - -use namada_tx_prelude::action::{Action, MaspAction, Write}; -use namada_tx_prelude::*; - -#[transaction] -fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { - let data = ctx.get_tx_data(&tx_data)?; - let transfer = token::ShieldedTransfer::try_from_slice(&data[..]) - .wrap_err("Failed to decode token::ShieldedTransfer tx data")?; - debug_log!("apply_tx called with transfer: {:#?}", transfer); - - let masp_section_ref = transfer.section_hash; - let shielded = tx_data - .tx - .get_section(&masp_section_ref) - .and_then(|x| x.as_ref().masp_tx()) - .ok_or_err_msg("Unable to find required shielded section in tx data") - .map_err(|err| { - ctx.set_commitment_sentinel(); - err - })?; - token::utils::handle_masp_tx(ctx, &shielded) - .wrap_err("Encountered error while handling MASP transaction")?; - update_masp_note_commitment_tree(&shielded) - .wrap_err("Failed to update the MASP commitment tree")?; - ctx.push_action(Action::Masp(MaspAction { masp_section_ref }))?; - Ok(()) -} diff --git a/wasm/tx_shielding_transfer/Cargo.toml b/wasm/tx_shielding_transfer/Cargo.toml deleted file mode 100644 index 54dca625ec..0000000000 --- a/wasm/tx_shielding_transfer/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "tx_shielding_transfer" -description = "WASM transaction to transfer tokens" -authors.workspace = true -edition.workspace = true -license.workspace = true -version.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -namada_tx_prelude.workspace = true - -rlsf.workspace = true -getrandom.workspace = true - -[lib] -crate-type = ["cdylib"] diff --git a/wasm/tx_shielding_transfer/src/lib.rs b/wasm/tx_shielding_transfer/src/lib.rs deleted file mode 100644 index 499f983b3c..0000000000 --- a/wasm/tx_shielding_transfer/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! A tx for shielding token transfer. - -use namada_tx_prelude::action::{Action, MaspAction, Write}; -use namada_tx_prelude::*; - -#[transaction] -fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { - let data = ctx.get_tx_data(&tx_data)?; - let transfers = token::ShieldingMultiTransfer::try_from_slice(&data[..]) - .wrap_err("Failed to decode token::ShieldingTransfer tx data")?; - debug_log!("apply_tx called with transfer: {:#?}", transfers); - - for transfer in transfers.data { - token::transfer( - ctx, - &transfer.source, - &address::MASP, - &transfer.token, - transfer.amount.amount(), - ) - .wrap_err("Token transfer failed")?; - } - - let masp_section_ref = transfers.shielded_section_hash; - let shielded = tx_data - .tx - .get_section(&masp_section_ref) - .and_then(|x| x.as_ref().masp_tx()) - .ok_or_err_msg("Unable to find required shielded section in tx data") - .map_err(|err| { - ctx.set_commitment_sentinel(); - err - })?; - token::utils::handle_masp_tx(ctx, &shielded) - .wrap_err("Encountered error while handling MASP transaction")?; - update_masp_note_commitment_tree(&shielded) - .wrap_err("Failed to update the MASP commitment tree")?; - ctx.push_action(Action::Masp(MaspAction { masp_section_ref }))?; - - Ok(()) -} diff --git a/wasm/tx_shielded_transfer/Cargo.toml b/wasm/tx_transfer/Cargo.toml similarity index 92% rename from wasm/tx_shielded_transfer/Cargo.toml rename to wasm/tx_transfer/Cargo.toml index 8398b69750..868a5e6538 100644 --- a/wasm/tx_shielded_transfer/Cargo.toml +++ b/wasm/tx_transfer/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "tx_shielded_transfer" +name = "tx_transfer" description = "WASM transaction to transfer tokens" authors.workspace = true edition.workspace = true diff --git a/wasm/tx_transparent_transfer/src/lib.rs b/wasm/tx_transfer/src/lib.rs similarity index 100% rename from wasm/tx_transparent_transfer/src/lib.rs rename to wasm/tx_transfer/src/lib.rs diff --git a/wasm/tx_transparent_transfer/Cargo.toml b/wasm/tx_transparent_transfer/Cargo.toml deleted file mode 100644 index 7408b86688..0000000000 --- a/wasm/tx_transparent_transfer/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "tx_transparent_transfer" -description = "WASM transaction to transfer tokens" -authors.workspace = true -edition.workspace = true -license.workspace = true -version.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -namada_tx_prelude.workspace = true - -rlsf.workspace = true -getrandom.workspace = true - -[lib] -crate-type = ["cdylib"] diff --git a/wasm/tx_unshielding_transfer/Cargo.toml b/wasm/tx_unshielding_transfer/Cargo.toml deleted file mode 100644 index 03d9aa125d..0000000000 --- a/wasm/tx_unshielding_transfer/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "tx_unshielding_transfer" -description = "WASM transaction to transfer tokens" -authors.workspace = true -edition.workspace = true -license.workspace = true -version.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -namada_tx_prelude.workspace = true - -rlsf.workspace = true -getrandom.workspace = true - -[lib] -crate-type = ["cdylib"] diff --git a/wasm/tx_unshielding_transfer/src/lib.rs b/wasm/tx_unshielding_transfer/src/lib.rs deleted file mode 100644 index f0bf375c73..0000000000 --- a/wasm/tx_unshielding_transfer/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! A tx for unshielding token transfer. - -use namada_tx_prelude::action::{Action, MaspAction, Write}; -use namada_tx_prelude::*; - -#[transaction] -fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { - let data = ctx.get_tx_data(&tx_data)?; - let transfers = token::UnshieldingMultiTransfer::try_from_slice(&data[..]) - .wrap_err("Failed to decode token::UnshieldingTransfer tx data")?; - debug_log!("apply_tx called with transfer: {:#?}", transfers); - - for transfer in transfers.data { - token::transfer( - ctx, - &address::MASP, - &transfer.target, - &transfer.token, - transfer.amount.amount(), - ) - .wrap_err("Token transfer failed")?; - } - - let masp_section_ref = transfers.shielded_section_hash; - let shielded = tx_data - .tx - .get_section(&masp_section_ref) - .and_then(|x| x.as_ref().masp_tx()) - .ok_or_err_msg("Unable to find required shielded section in tx data") - .map_err(|err| { - ctx.set_commitment_sentinel(); - err - })?; - token::utils::handle_masp_tx(ctx, &shielded) - .wrap_err("Encountered error while handling MASP transaction")?; - update_masp_note_commitment_tree(&shielded) - .wrap_err("Failed to update the MASP commitment tree")?; - ctx.push_action(Action::Masp(MaspAction { masp_section_ref }))?; - - Ok(()) -} From ddded01e757393f0b3e1868617a57ebcde183c85 Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Fri, 28 Jun 2024 22:27:26 +0200 Subject: [PATCH 7/9] Added a changelog entry. --- .../improvements/3446-generalize-vectorized-transfers.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/3446-generalize-vectorized-transfers.md diff --git a/.changelog/unreleased/improvements/3446-generalize-vectorized-transfers.md b/.changelog/unreleased/improvements/3446-generalize-vectorized-transfers.md new file mode 100644 index 0000000000..c81570de73 --- /dev/null +++ b/.changelog/unreleased/improvements/3446-generalize-vectorized-transfers.md @@ -0,0 +1,2 @@ +- Combined the various Transfer formats into one general one. + ([\#3446](https://github.com/anoma/namada/pull/3446)) \ No newline at end of file From 611072671211da0583b994629a0825207e4acb14 Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Mon, 1 Jul 2024 17:05:03 +0200 Subject: [PATCH 8/9] Renamed some data structures. --- crates/benches/host_env.rs | 4 ++-- crates/benches/native_vps.rs | 4 ++-- crates/benches/process_wrapper.rs | 4 ++-- crates/light_sdk/src/transaction/transfer.rs | 15 ++++++++------ crates/node/src/bench_utils.rs | 12 ++++++----- crates/sdk/src/args.rs | 2 +- crates/sdk/src/lib.rs | 20 +++++++++---------- crates/sdk/src/signing.rs | 8 ++++---- crates/sdk/src/tx.rs | 20 +++++++++---------- crates/tests/src/integration/ledger_tests.rs | 21 ++++++++++---------- crates/token/src/lib.rs | 16 +++++++-------- wasm/tx_transfer/src/lib.rs | 2 +- 12 files changed, 67 insertions(+), 61 deletions(-) diff --git a/crates/benches/host_env.rs b/crates/benches/host_env.rs index ce939fa043..3d944a245b 100644 --- a/crates/benches/host_env.rs +++ b/crates/benches/host_env.rs @@ -3,7 +3,7 @@ use namada::core::account::AccountPublicKeysMap; use namada::core::address; use namada::core::collections::{HashMap, HashSet}; use namada::ledger::storage::DB; -use namada::token::{Amount, Transfer, TransferData}; +use namada::token::{Amount, Transfer, TransparentTransfer}; use namada::tx::Authorization; use namada::vm::wasm::TxCache; use namada_apps_lib::wallet::defaults; @@ -17,7 +17,7 @@ use namada_node::bench_utils::{ // transaction fn tx_section_signature_validation(c: &mut Criterion) { let shell = BenchShell::default(); - let transfer_data = Transfer::transparent(vec![TransferData { + let transfer_data = Transfer::transparent(vec![TransparentTransfer { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), diff --git a/crates/benches/native_vps.rs b/crates/benches/native_vps.rs index a62031a2a7..8670583f4a 100644 --- a/crates/benches/native_vps.rs +++ b/crates/benches/native_vps.rs @@ -55,7 +55,7 @@ use namada::sdk::masp_primitives::merkle_tree::CommitmentTree; use namada::sdk::masp_primitives::transaction::Transaction; use namada::sdk::masp_proofs::sapling::SaplingVerificationContextInner; use namada::state::{Epoch, StorageRead, StorageWrite, TxIndex}; -use namada::token::{Amount, Transfer, TransferData}; +use namada::token::{Amount, Transfer, TransparentTransfer}; use namada::tx::{BatchedTx, Code, Section, Tx}; use namada_apps_lib::wallet::defaults; use namada_node::bench_utils::{ @@ -475,7 +475,7 @@ fn vp_multitoken(c: &mut Criterion) { let transfer = shell.generate_tx( TX_TRANSFER_WASM, - Transfer::transparent(vec![TransferData { + Transfer::transparent(vec![TransparentTransfer { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), diff --git a/crates/benches/process_wrapper.rs b/crates/benches/process_wrapper.rs index efa721de49..19d449474e 100644 --- a/crates/benches/process_wrapper.rs +++ b/crates/benches/process_wrapper.rs @@ -3,7 +3,7 @@ use namada::core::address; use namada::core::key::RefTo; use namada::core::storage::BlockHeight; use namada::core::time::DateTimeUtc; -use namada::token::{Amount, DenominatedAmount, Transfer, TransferData}; +use namada::token::{Amount, DenominatedAmount, Transfer, TransparentTransfer}; use namada::tx::data::{Fee, WrapperTx}; use namada::tx::Authorization; use namada_apps_lib::wallet::defaults; @@ -19,7 +19,7 @@ fn process_tx(c: &mut Criterion) { let mut batched_tx = shell.generate_tx( TX_TRANSFER_WASM, - Transfer::transparent(vec![TransferData { + Transfer::transparent(vec![TransparentTransfer { source: defaults::albert_address(), target: defaults::bertha_address(), token: address::testing::nam(), diff --git a/crates/light_sdk/src/transaction/transfer.rs b/crates/light_sdk/src/transaction/transfer.rs index 167d264ae5..93ad473d08 100644 --- a/crates/light_sdk/src/transaction/transfer.rs +++ b/crates/light_sdk/src/transaction/transfer.rs @@ -2,7 +2,7 @@ use namada_sdk::address::Address; use namada_sdk::hash::Hash; use namada_sdk::key::common; use namada_sdk::token::transaction::Transaction; -use namada_sdk::token::TransferData; +use namada_sdk::token::TransparentTransfer; pub use namada_sdk::token::{DenominatedAmount, Transfer}; use namada_sdk::tx::data::GasLimit; use namada_sdk::tx::{Authorization, Tx, TxError, TX_TRANSFER_WASM}; @@ -16,9 +16,12 @@ pub struct TransferBuilder(Tx); impl TransferBuilder { /// Build a transparent transfer transaction from the given parameters - pub fn transparent(transfers: Vec, args: GlobalArgs) -> Self { + pub fn transparent( + transfers: Vec, + args: GlobalArgs, + ) -> Self { let data = namada_sdk::token::Transfer { - data: transfers, + transparent: transfers, shielded_section_hash: None, }; @@ -36,7 +39,7 @@ impl TransferBuilder { args: GlobalArgs, ) -> Self { let data = namada_sdk::token::Transfer { - data: vec![], + transparent: vec![], shielded_section_hash: Some(shielded_section_hash), }; @@ -49,13 +52,13 @@ impl TransferBuilder { /// Build a MASP transfer transaction from the given parameters pub fn masp( - transfers: Vec, + transfers: Vec, shielded_section_hash: Hash, transaction: Transaction, args: GlobalArgs, ) -> Self { let data = namada_sdk::token::Transfer { - data: transfers, + transparent: transfers, shielded_section_hash: Some(shielded_section_hash), }; diff --git a/crates/node/src/bench_utils.rs b/crates/node/src/bench_utils.rs index 37e4dd6a44..116b9facea 100644 --- a/crates/node/src/bench_utils.rs +++ b/crates/node/src/bench_utils.rs @@ -75,7 +75,7 @@ use namada::ledger::queries::{ }; use namada::masp::MaspTxRefs; use namada::state::StorageRead; -use namada::token::{Amount, DenominatedAmount, Transfer, TransferData}; +use namada::token::{Amount, DenominatedAmount, Transfer, TransparentTransfer}; use namada::tx::data::pos::Bond; use namada::tx::data::{ BatchResults, BatchedTxResult, Fee, TxResult, VpsResult, @@ -1114,7 +1114,7 @@ impl BenchShieldedCtx { namada.client().generate_tx( TX_TRANSFER_WASM, Transfer { - data: vec![], + transparent: vec![], shielded_section_hash: Some(shielded_section_hash), }, Some(shielded), @@ -1125,7 +1125,7 @@ impl BenchShieldedCtx { namada.client().generate_tx( TX_TRANSFER_WASM, Transfer { - data: vec![TransferData { + transparent: vec![TransparentTransfer { source: source.effective_address(), target: MASP, token: address::testing::nam(), @@ -1141,7 +1141,7 @@ impl BenchShieldedCtx { namada.client().generate_tx( TX_TRANSFER_WASM, Transfer { - data: vec![TransferData { + transparent: vec![TransparentTransfer { source: MASP, target: target.effective_address(), token: address::testing::nam(), @@ -1216,7 +1216,9 @@ impl BenchShieldedCtx { Transfer::deserialize(&mut tx.tx.data(&tx.cmt).unwrap().as_slice()) .unwrap(); let transfer = Transfer { - data: vec![vectorized_transfer.data.first().unwrap().to_owned()], + transparent: vec![ + vectorized_transfer.transparent.first().unwrap().to_owned(), + ], shielded_section_hash: Some( vectorized_transfer.shielded_section_hash.unwrap(), ), diff --git a/crates/sdk/src/args.rs b/crates/sdk/src/args.rs index 7cc775829a..306024a609 100644 --- a/crates/sdk/src/args.rs +++ b/crates/sdk/src/args.rs @@ -341,7 +341,7 @@ impl TxShieldedTransfer { } } -/// Shielded transfer-specific arguments +/// Shielding transfer-specific arguments #[derive(Clone, Debug)] pub struct TxShieldingTransferData { /// Transfer source spending key diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 5e9c58657d..62764a1a90 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -865,7 +865,7 @@ pub mod testing { use ripemd::Digest as RipemdDigest; use sha2::Digest; use token::testing::arb_vectorized_transparent_transfer; - use token::TransferData; + use token::TransparentTransfer; use super::*; use crate::account::tests::{arb_init_account, arb_update_account}; @@ -1108,8 +1108,8 @@ pub mod testing { code_hash in arb_hash(), (masp_tx_type, (shielded_transfer, asset_types, build_params)) in prop_oneof![ (Just(MaspTxType::Shielded), arb_shielded_transfer(0..MAX_ASSETS)), - (Just(MaspTxType::Shielding), arb_shielding_transfer(encode_address(&transfers.data.first().unwrap().source), 1)), - (Just(MaspTxType::Unshielding), arb_deshielding_transfer(encode_address(&transfers.data.first().unwrap().target), 1)), + (Just(MaspTxType::Shielding), arb_shielding_transfer(encode_address(&transfers.transparent.first().unwrap().source), 1)), + (Just(MaspTxType::Unshielding), arb_deshielding_transfer(encode_address(&transfers.transparent.first().unwrap().target), 1)), ], transfers in Just(transfers), ) -> (Tx, TxData) { @@ -1122,7 +1122,7 @@ pub mod testing { MaspTxType::Shielded => { tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); let data = Transfer { - data: vec![], + transparent: vec![], shielded_section_hash: Some(shielded_section_hash), }; tx.add_data(data.clone()); @@ -1137,8 +1137,8 @@ pub mod testing { decoded.denom, ); tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); - let data = transfers.data.into_iter().map(|transfer| - TransferData{ + let transparent = transfers.transparent.into_iter().map(|transfer| + TransparentTransfer{ source: transfer.source, token: token.clone(), amount, @@ -1146,7 +1146,7 @@ pub mod testing { } ).collect(); let data = Transfer{ - data, + transparent, shielded_section_hash: Some(shielded_section_hash), }; tx.add_data(data.clone()); @@ -1161,15 +1161,15 @@ pub mod testing { decoded.denom, ); tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); - let data = transfers.data.into_iter().map(|transfer| - TransferData{ + let transparent = transfers.transparent.into_iter().map(|transfer| + TransparentTransfer{ target: transfer.target, token: token.clone(), amount, source: MASP, } ).collect(); - let data = Transfer{data, shielded_section_hash: Some(shielded_section_hash) }; + let data = Transfer{transparent, shielded_section_hash: Some(shielded_section_hash) }; tx.add_data(data.clone()); TxData::MaspTransfer(data, (build_params, build_param_bytes)) }, diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index b37a750aec..03a427234c 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -711,7 +711,7 @@ struct TokenTransfer<'a>(&'a token::Transfer); impl TokenTransfer<'_> { fn sources(&self) -> Vec<&Address> { self.0 - .data + .transparent .iter() .map(|transfer| &transfer.source) .collect() @@ -719,7 +719,7 @@ impl TokenTransfer<'_> { fn targets(&self) -> Vec<&Address> { self.0 - .data + .transparent .iter() .map(|transfer| &transfer.target) .collect() @@ -733,7 +733,7 @@ impl TokenTransfer<'_> { match address { TransferSide::Source(source) => { - for transfer in &self.0.data { + for transfer in &self.0.transparent { if source == &transfer.source { Self::update_token_amount_map( &mut map, @@ -744,7 +744,7 @@ impl TokenTransfer<'_> { } } TransferSide::Target(target) => { - for transfer in &self.0.data { + for transfer in &self.0.transparent { if target == &transfer.target { Self::update_token_amount_map( &mut map, diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index 7c27a08a59..e851ec9de5 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -65,7 +65,7 @@ use namada_tx::data::{pos, BatchedTxResult, ResultCode, TxResult}; pub use namada_tx::{Authorization, *}; use num_traits::Zero; use rand_core::{OsRng, RngCore}; -use token::TransferData; +use token::TransparentTransfer; use crate::args::{ TxShieldedTransferData, TxShieldingTransferData, TxTransparentTransferData, @@ -2571,7 +2571,7 @@ pub async fn build_ibc_transfer( let masp_tx_hash = tx.add_masp_tx_section(shielded_transfer.masp_tx.clone()).1; let transfer = token::Transfer { - data: vec![TransferData { + transparent: vec![TransparentTransfer { // The token will be escrowed to IBC address source: source.clone(), target: MASP, @@ -2913,7 +2913,7 @@ pub async fn build_transparent_transfer( } // Construct the corresponding transparent Transfer object - let transfer_data = token::TransferData { + let transfer_data = token::TransparentTransfer { source: source.to_owned(), target: target.to_owned(), token: token.to_owned(), @@ -2924,7 +2924,7 @@ pub async fn build_transparent_transfer( } // Construct the corresponding transparent Transfer object let transfer = token::Transfer { - data: transfers, + transparent: transfers, shielded_section_hash: None, }; @@ -3015,7 +3015,7 @@ pub async fn build_shielded_transfer( // Construct the tx data with a placeholder shielded section hash let data = token::Transfer { - data: vec![], + transparent: vec![], shielded_section_hash: None, }; let tx = build_pow_flag( @@ -3099,7 +3099,7 @@ pub async fn build_shielding_transfer( amount: validated_amount, }); - data.push(token::TransferData { + data.push(token::TransparentTransfer { source: source.to_owned(), target: MASP, token: token.to_owned(), @@ -3147,7 +3147,7 @@ pub async fn build_shielding_transfer( // Construct the tx data with a placeholder shielded section hash let data = token::Transfer { - data, + transparent: data, shielded_section_hash: None, }; @@ -3196,7 +3196,7 @@ pub async fn build_unshielding_transfer( amount: validated_amount, }); - data.push(token::TransferData { + data.push(token::TransparentTransfer { source: MASP, target: target.to_owned(), token: token.to_owned(), @@ -3245,7 +3245,7 @@ pub async fn build_unshielding_transfer( // Construct the tx data with a placeholder shielded section hash let data = token::Transfer { - data, + transparent: data, shielded_section_hash: None, }; @@ -3631,7 +3631,7 @@ pub async fn gen_ibc_shielding_transfer( let masp_tx_hash = Section::MaspTx(shielded_transfer.masp_tx.clone()).get_hash(); let transfer = token::Transfer { - data: vec![TransferData { + transparent: vec![TransparentTransfer { source: source.clone(), target: MASP, token: token.clone(), diff --git a/crates/tests/src/integration/ledger_tests.rs b/crates/tests/src/integration/ledger_tests.rs index f4ada9c6e7..1e2423c1cb 100644 --- a/crates/tests/src/integration/ledger_tests.rs +++ b/crates/tests/src/integration/ledger_tests.rs @@ -59,16 +59,17 @@ fn ledger_txs_and_queries() -> Result<()> { let validator_one_rpc = "http://127.0.0.1:26567"; let (node, _services) = setup::setup()?; - let transfer = token::Transfer::transparent(vec![token::TransferData { - source: defaults::bertha_address(), - target: defaults::albert_address(), - token: node.native_token(), - amount: token::DenominatedAmount::new( - token::Amount::native_whole(10), - token::NATIVE_MAX_DECIMAL_PLACES.into(), - ), - }]) - .serialize_to_vec(); + let transfer = + token::Transfer::transparent(vec![token::TransparentTransfer { + source: defaults::bertha_address(), + target: defaults::albert_address(), + token: node.native_token(), + amount: token::DenominatedAmount::new( + token::Amount::native_whole(10), + token::NATIVE_MAX_DECIMAL_PLACES.into(), + ), + }]) + .serialize_to_vec(); let tx_data_path = node.test_dir.path().join("tx.data"); std::fs::write(&tx_data_path, transfer).unwrap(); let tx_data_path = tx_data_path.to_string_lossy(); diff --git a/crates/token/src/lib.rs b/crates/token/src/lib.rs index cc2caf2487..c7a5ac7d7d 100644 --- a/crates/token/src/lib.rs +++ b/crates/token/src/lib.rs @@ -84,16 +84,16 @@ where )] pub struct Transfer { /// Transfer-specific data - pub data: Vec, + pub transparent: Vec, /// Hash of tx section that contains the MASP transaction pub shielded_section_hash: Option, } impl Transfer { /// Make a transparent transfer - pub fn transparent(data: Vec) -> Self { + pub fn transparent(data: Vec) -> Self { Self { - data, + transparent: data, shielded_section_hash: None, } } @@ -114,7 +114,7 @@ impl Transfer { Serialize, Deserialize, )] -pub struct TransferData { +pub struct TransparentTransfer { /// Source address will spend the tokens pub source: Address, /// Target address will receive the tokens @@ -136,7 +136,7 @@ pub mod testing { pub use namada_trans_token::testing::*; use proptest::prelude::*; - use super::{Transfer, TransferData}; + use super::{Transfer, TransparentTransfer}; prop_compose! { /// Generate a transparent transfer @@ -145,8 +145,8 @@ pub mod testing { target in arb_non_internal_address(), token in arb_established_address().prop_map(Address::Established), amount in arb_denominated_amount(), - ) -> TransferData{ - TransferData { + ) -> TransparentTransfer{ + TransparentTransfer { source, target, token, @@ -161,7 +161,7 @@ pub mod testing { ) -> impl Strategy { proptest::collection::vec(arb_transparent_transfer(), 0..number_of_txs) .prop_map(|data| Transfer { - data, + transparent: data, shielded_section_hash: None, }) } diff --git a/wasm/tx_transfer/src/lib.rs b/wasm/tx_transfer/src/lib.rs index 11ffa18147..b11e841574 100644 --- a/wasm/tx_transfer/src/lib.rs +++ b/wasm/tx_transfer/src/lib.rs @@ -12,7 +12,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { .wrap_err("Failed to decode token::TransparentTransfer tx data")?; debug_log!("apply_tx called with transfer: {:#?}", transfers); - for transfer in transfers.data { + for transfer in transfers.transparent { token::transfer( ctx, &transfer.source, From 317b3ad2e3e504b0f90b2f082ebd4807bd81f1b9 Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Fri, 28 Jun 2024 09:00:07 +0200 Subject: [PATCH 9/9] Unconstrain transfers and combine transfer amounts. --- crates/benches/host_env.rs | 16 +- crates/benches/native_vps.rs | 16 +- crates/benches/process_wrapper.rs | 16 +- crates/light_sdk/src/transaction/transfer.rs | 38 +---- crates/node/src/bench_utils.rs | 54 +++---- crates/sdk/src/lib.rs | 49 +++--- crates/sdk/src/signing.rs | 123 ++++----------- crates/sdk/src/tx.rs | 133 +++++++--------- crates/tests/src/integration/ledger_tests.rs | 15 +- crates/token/src/lib.rs | 156 +++++++++++++++---- crates/trans_token/src/storage.rs | 60 +++++++ crates/tx_prelude/src/token.rs | 33 ++++ wasm/checksums.json | 38 ++--- wasm/tx_transfer/src/lib.rs | 32 ++-- 14 files changed, 431 insertions(+), 348 deletions(-) diff --git a/crates/benches/host_env.rs b/crates/benches/host_env.rs index 3d944a245b..d24a92ace5 100644 --- a/crates/benches/host_env.rs +++ b/crates/benches/host_env.rs @@ -3,7 +3,7 @@ use namada::core::account::AccountPublicKeysMap; use namada::core::address; use namada::core::collections::{HashMap, HashSet}; use namada::ledger::storage::DB; -use namada::token::{Amount, Transfer, TransparentTransfer}; +use namada::token::{Amount, Transfer}; use namada::tx::Authorization; use namada::vm::wasm::TxCache; use namada_apps_lib::wallet::defaults; @@ -17,12 +17,14 @@ use namada_node::bench_utils::{ // transaction fn tx_section_signature_validation(c: &mut Criterion) { let shell = BenchShell::default(); - let transfer_data = Transfer::transparent(vec![TransparentTransfer { - source: defaults::albert_address(), - target: defaults::bertha_address(), - token: address::testing::nam(), - amount: Amount::native_whole(500).native_denominated(), - }]); + let transfer_data = Transfer::default() + .transfer( + defaults::albert_address(), + defaults::bertha_address(), + address::testing::nam(), + Amount::native_whole(500).native_denominated(), + ) + .unwrap(); let tx = shell.generate_tx( TX_TRANSFER_WASM, transfer_data, diff --git a/crates/benches/native_vps.rs b/crates/benches/native_vps.rs index 8670583f4a..0138d8f965 100644 --- a/crates/benches/native_vps.rs +++ b/crates/benches/native_vps.rs @@ -55,7 +55,7 @@ use namada::sdk::masp_primitives::merkle_tree::CommitmentTree; use namada::sdk::masp_primitives::transaction::Transaction; use namada::sdk::masp_proofs::sapling::SaplingVerificationContextInner; use namada::state::{Epoch, StorageRead, StorageWrite, TxIndex}; -use namada::token::{Amount, Transfer, TransparentTransfer}; +use namada::token::{Amount, Transfer}; use namada::tx::{BatchedTx, Code, Section, Tx}; use namada_apps_lib::wallet::defaults; use namada_node::bench_utils::{ @@ -475,12 +475,14 @@ fn vp_multitoken(c: &mut Criterion) { let transfer = shell.generate_tx( TX_TRANSFER_WASM, - Transfer::transparent(vec![TransparentTransfer { - source: defaults::albert_address(), - target: defaults::bertha_address(), - token: address::testing::nam(), - amount: Amount::native_whole(1000).native_denominated(), - }]), + Transfer::default() + .transfer( + defaults::albert_address(), + defaults::bertha_address(), + address::testing::nam(), + Amount::native_whole(1000).native_denominated(), + ) + .unwrap(), None, None, vec![&defaults::albert_keypair()], diff --git a/crates/benches/process_wrapper.rs b/crates/benches/process_wrapper.rs index 19d449474e..bf3b80e34f 100644 --- a/crates/benches/process_wrapper.rs +++ b/crates/benches/process_wrapper.rs @@ -3,7 +3,7 @@ use namada::core::address; use namada::core::key::RefTo; use namada::core::storage::BlockHeight; use namada::core::time::DateTimeUtc; -use namada::token::{Amount, DenominatedAmount, Transfer, TransparentTransfer}; +use namada::token::{Amount, DenominatedAmount, Transfer}; use namada::tx::data::{Fee, WrapperTx}; use namada::tx::Authorization; use namada_apps_lib::wallet::defaults; @@ -19,12 +19,14 @@ fn process_tx(c: &mut Criterion) { let mut batched_tx = shell.generate_tx( TX_TRANSFER_WASM, - Transfer::transparent(vec![TransparentTransfer { - source: defaults::albert_address(), - target: defaults::bertha_address(), - token: address::testing::nam(), - amount: Amount::native_whole(1).native_denominated(), - }]), + Transfer::default() + .transfer( + defaults::albert_address(), + defaults::bertha_address(), + address::testing::nam(), + Amount::native_whole(1).native_denominated(), + ) + .unwrap(), None, None, vec![&defaults::albert_keypair()], diff --git a/crates/light_sdk/src/transaction/transfer.rs b/crates/light_sdk/src/transaction/transfer.rs index 93ad473d08..15c61b2a88 100644 --- a/crates/light_sdk/src/transaction/transfer.rs +++ b/crates/light_sdk/src/transaction/transfer.rs @@ -2,7 +2,6 @@ use namada_sdk::address::Address; use namada_sdk::hash::Hash; use namada_sdk::key::common; use namada_sdk::token::transaction::Transaction; -use namada_sdk::token::TransparentTransfer; pub use namada_sdk::token::{DenominatedAmount, Transfer}; use namada_sdk::tx::data::GasLimit; use namada_sdk::tx::{Authorization, Tx, TxError, TX_TRANSFER_WASM}; @@ -16,18 +15,10 @@ pub struct TransferBuilder(Tx); impl TransferBuilder { /// Build a transparent transfer transaction from the given parameters - pub fn transparent( - transfers: Vec, - args: GlobalArgs, - ) -> Self { - let data = namada_sdk::token::Transfer { - transparent: transfers, - shielded_section_hash: None, - }; - + pub fn transfer(transfer: Transfer, args: GlobalArgs) -> Self { Self(transaction::build_tx( args, - data, + transfer, TX_TRANSFER_WASM.to_string(), )) } @@ -38,30 +29,7 @@ impl TransferBuilder { transaction: Transaction, args: GlobalArgs, ) -> Self { - let data = namada_sdk::token::Transfer { - transparent: vec![], - shielded_section_hash: Some(shielded_section_hash), - }; - - let mut tx = - transaction::build_tx(args, data, TX_TRANSFER_WASM.to_string()); - tx.add_masp_tx_section(transaction); - - Self(tx) - } - - /// Build a MASP transfer transaction from the given parameters - pub fn masp( - transfers: Vec, - shielded_section_hash: Hash, - transaction: Transaction, - args: GlobalArgs, - ) -> Self { - let data = namada_sdk::token::Transfer { - transparent: transfers, - shielded_section_hash: Some(shielded_section_hash), - }; - + let data = Transfer::masp(shielded_section_hash); let mut tx = transaction::build_tx(args, data, TX_TRANSFER_WASM.to_string()); tx.add_masp_tx_section(transaction); diff --git a/crates/node/src/bench_utils.rs b/crates/node/src/bench_utils.rs index 116b9facea..9592d47c77 100644 --- a/crates/node/src/bench_utils.rs +++ b/crates/node/src/bench_utils.rs @@ -75,7 +75,7 @@ use namada::ledger::queries::{ }; use namada::masp::MaspTxRefs; use namada::state::StorageRead; -use namada::token::{Amount, DenominatedAmount, Transfer, TransparentTransfer}; +use namada::token::{Amount, DenominatedAmount, Transfer}; use namada::tx::data::pos::Bond; use namada::tx::data::{ BatchResults, BatchedTxResult, Fee, TxResult, VpsResult, @@ -1113,10 +1113,7 @@ impl BenchShieldedCtx { { namada.client().generate_tx( TX_TRANSFER_WASM, - Transfer { - transparent: vec![], - shielded_section_hash: Some(shielded_section_hash), - }, + Transfer::masp(shielded_section_hash), Some(shielded), None, vec![&defaults::albert_keypair()], @@ -1124,15 +1121,14 @@ impl BenchShieldedCtx { } else if target.effective_address() == MASP { namada.client().generate_tx( TX_TRANSFER_WASM, - Transfer { - transparent: vec![TransparentTransfer { - source: source.effective_address(), - target: MASP, - token: address::testing::nam(), - amount: DenominatedAmount::native(amount), - }], - shielded_section_hash: Some(shielded_section_hash), - }, + Transfer::masp(shielded_section_hash) + .transfer( + source.effective_address(), + MASP, + address::testing::nam(), + DenominatedAmount::native(amount), + ) + .unwrap(), Some(shielded), None, vec![&defaults::albert_keypair()], @@ -1140,15 +1136,14 @@ impl BenchShieldedCtx { } else { namada.client().generate_tx( TX_TRANSFER_WASM, - Transfer { - transparent: vec![TransparentTransfer { - source: MASP, - target: target.effective_address(), - token: address::testing::nam(), - amount: DenominatedAmount::native(amount), - }], - shielded_section_hash: Some(shielded_section_hash), - }, + Transfer::masp(shielded_section_hash) + .transfer( + MASP, + target.effective_address(), + address::testing::nam(), + DenominatedAmount::native(amount), + ) + .unwrap(), Some(shielded), None, vec![&defaults::albert_keypair()], @@ -1215,10 +1210,17 @@ impl BenchShieldedCtx { let vectorized_transfer = Transfer::deserialize(&mut tx.tx.data(&tx.cmt).unwrap().as_slice()) .unwrap(); + let sources = + vec![vectorized_transfer.sources.into_iter().next().unwrap()] + .into_iter() + .collect(); + let targets = + vec![vectorized_transfer.targets.into_iter().next().unwrap()] + .into_iter() + .collect(); let transfer = Transfer { - transparent: vec![ - vectorized_transfer.transparent.first().unwrap().to_owned(), - ], + sources, + targets, shielded_section_hash: Some( vectorized_transfer.shielded_section_hash.unwrap(), ), diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 62764a1a90..0bc6197ff8 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -865,7 +865,6 @@ pub mod testing { use ripemd::Digest as RipemdDigest; use sha2::Digest; use token::testing::arb_vectorized_transparent_transfer; - use token::TransparentTransfer; use super::*; use crate::account::tests::{arb_init_account, arb_update_account}; @@ -1108,8 +1107,8 @@ pub mod testing { code_hash in arb_hash(), (masp_tx_type, (shielded_transfer, asset_types, build_params)) in prop_oneof![ (Just(MaspTxType::Shielded), arb_shielded_transfer(0..MAX_ASSETS)), - (Just(MaspTxType::Shielding), arb_shielding_transfer(encode_address(&transfers.transparent.first().unwrap().source), 1)), - (Just(MaspTxType::Unshielding), arb_deshielding_transfer(encode_address(&transfers.transparent.first().unwrap().target), 1)), + (Just(MaspTxType::Shielding), arb_shielding_transfer(encode_address(&transfers.sources.keys().next().unwrap().owner), 1)), + (Just(MaspTxType::Unshielding), arb_deshielding_transfer(encode_address(&transfers.targets.keys().next().unwrap().owner), 1)), ], transfers in Just(transfers), ) -> (Tx, TxData) { @@ -1121,10 +1120,7 @@ pub mod testing { let tx_data = match masp_tx_type { MaspTxType::Shielded => { tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); - let data = Transfer { - transparent: vec![], - shielded_section_hash: Some(shielded_section_hash), - }; + let data = Transfer::masp(shielded_section_hash); tx.add_data(data.clone()); TxData::MaspTransfer(data, (build_params, build_param_bytes)) }, @@ -1137,18 +1133,15 @@ pub mod testing { decoded.denom, ); tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); - let transparent = transfers.transparent.into_iter().map(|transfer| - TransparentTransfer{ - source: transfer.source, - token: token.clone(), - amount, - target: MASP, - } - ).collect(); - let data = Transfer{ - transparent, - shielded_section_hash: Some(shielded_section_hash), - }; + let data = transfers.sources.into_iter().try_fold( + Transfer::masp(shielded_section_hash), + |acc, transfer| acc.transfer( + transfer.0.owner, + MASP, + token.clone(), + amount, + ), + ).unwrap(); tx.add_data(data.clone()); TxData::MaspTransfer(data, (build_params, build_param_bytes)) }, @@ -1161,15 +1154,15 @@ pub mod testing { decoded.denom, ); tx.add_code_from_hash(code_hash, Some(TX_TRANSFER_WASM.to_owned())); - let transparent = transfers.transparent.into_iter().map(|transfer| - TransparentTransfer{ - target: transfer.target, - token: token.clone(), - amount, - source: MASP, - } - ).collect(); - let data = Transfer{transparent, shielded_section_hash: Some(shielded_section_hash) }; + let data = transfers.targets.into_iter().try_fold( + Transfer::masp(shielded_section_hash), + |acc, transfer| acc.transfer( + MASP, + transfer.0.owner, + token.clone(), + amount, + ) + ).unwrap(); tx.add_data(data.clone()); TxData::MaspTransfer(data, (build_params, build_param_bytes)) }, diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index 03a427234c..66f5d78047 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -42,6 +42,7 @@ use crate::ibc::apps::transfer::types::msgs::transfer::MsgTransfer; use crate::ibc::primitives::proto::Any; use crate::io::*; use crate::rpc::validate_amount; +use crate::token::Account; use crate::tx::{ Commitment, TX_BECOME_VALIDATOR_WASM, TX_BOND_WASM, TX_BRIDGE_POOL_WASM, TX_CHANGE_COMMISSION_WASM, TX_CHANGE_CONSENSUS_KEY_WASM, @@ -701,79 +702,17 @@ fn format_outputs(output: &mut Vec) { } } -enum TransferSide<'a> { - Source(&'a Address), - Target(&'a Address), -} - -struct TokenTransfer<'a>(&'a token::Transfer); - -impl TokenTransfer<'_> { - fn sources(&self) -> Vec<&Address> { - self.0 - .transparent - .iter() - .map(|transfer| &transfer.source) - .collect() - } - - fn targets(&self) -> Vec<&Address> { - self.0 - .transparent - .iter() - .map(|transfer| &transfer.target) - .collect() - } - - fn tokens_and_amounts( - &self, - address: TransferSide<'_>, - ) -> Result, Error> { - let mut map: HashMap<&Address, DenominatedAmount> = HashMap::new(); - - match address { - TransferSide::Source(source) => { - for transfer in &self.0.transparent { - if source == &transfer.source { - Self::update_token_amount_map( - &mut map, - &transfer.token, - transfer.amount, - )?; - } - } - } - TransferSide::Target(target) => { - for transfer in &self.0.transparent { - if target == &transfer.target { - Self::update_token_amount_map( - &mut map, - &transfer.token, - transfer.amount, - )?; - } - } - } - } - Ok(map) - } - - fn update_token_amount_map<'a>( - map: &mut HashMap<&'a Address, DenominatedAmount>, - token: &'a Address, - amount: DenominatedAmount, - ) -> Result<(), Error> { - match map.get_mut(token) { - Some(prev_amount) => { - *prev_amount = checked!(prev_amount + amount)?; - } - None => { - map.insert(token, amount); - } - } - - Ok(()) +/// Convert a map with key pairs into a nested structure +fn nest_map( + map: BTreeMap, +) -> BTreeMap> { + let mut nested = BTreeMap::new(); + for (account, v) in map { + let inner: &mut BTreeMap<_, _> = + nested.entry(account.owner).or_default(); + inner.insert(account.token, v); } + nested } /// Adds a Ledger output for the senders and destinations for transparent and @@ -781,23 +720,22 @@ impl TokenTransfer<'_> { async fn make_ledger_token_transfer_endpoints( tokens: &HashMap, output: &mut Vec, - transfer: TokenTransfer<'_>, + transfer: &token::Transfer, builder: Option<&MaspBuilder>, assets: &HashMap, ) -> Result<(), Error> { - let sources = transfer.sources(); - if !sources.is_empty() { - for source in transfer.sources() { - output.push(format!("Sender : {}", source)); - for (token, amount) in - transfer.tokens_and_amounts(TransferSide::Source(source))? - { + for (owner, changes) in nest_map(transfer.sources.clone()) { + // MASP inputs will be printed below + if owner != MASP { + output.push(format!("Sender : {}", owner)); + for (token, amount) in changes { make_ledger_amount_addr( - tokens, output, amount, token, "Sending ", + tokens, output, amount, &token, "Sending ", ); } } - } else if let Some(builder) = builder { + } + if let Some(builder) = builder { for sapling_input in builder.builder.sapling_inputs() { let vk = ExtendedViewingKey::from(*sapling_input.key()); output.push(format!("Sender : {}", vk)); @@ -812,23 +750,22 @@ async fn make_ledger_token_transfer_endpoints( .await; } } - let targets = transfer.targets(); - if !targets.is_empty() { - for target in targets { - output.push(format!("Destination : {}", target)); - for (token, amount) in - transfer.tokens_and_amounts(TransferSide::Target(target))? - { + for (owner, changes) in nest_map(transfer.targets.clone()) { + // MASP outputs will be printed below + if owner != MASP { + output.push(format!("Destination : {}", owner)); + for (token, amount) in changes { make_ledger_amount_addr( tokens, output, amount, - token, + &token, "Receiving ", ); } } - } else if let Some(builder) = builder { + } + if let Some(builder) = builder { for sapling_output in builder.builder.sapling_outputs() { let pa = PaymentAddress::from(sapling_output.address()); output.push(format!("Destination : {}", pa)); @@ -1355,7 +1292,7 @@ pub async fn to_ledger_vector( make_ledger_token_transfer_endpoints( &tokens, &mut tv.output, - TokenTransfer(&transfer), + &transfer, builder, &asset_types, ) @@ -1363,7 +1300,7 @@ pub async fn to_ledger_vector( make_ledger_token_transfer_endpoints( &tokens, &mut tv.output_expert, - TokenTransfer(&transfer), + &transfer, builder, &asset_types, ) diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index e851ec9de5..445ea059b9 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -65,7 +65,6 @@ use namada_tx::data::{pos, BatchedTxResult, ResultCode, TxResult}; pub use namada_tx::{Authorization, *}; use num_traits::Zero; use rand_core::{OsRng, RngCore}; -use token::TransparentTransfer; use crate::args::{ TxShieldedTransferData, TxShieldingTransferData, TxTransparentTransferData, @@ -2567,28 +2566,30 @@ pub async fn build_ibc_transfer( tx.add_memo(memo); } - let transfer = shielded_parts.map(|(shielded_transfer, asset_types)| { - let masp_tx_hash = - tx.add_masp_tx_section(shielded_transfer.masp_tx.clone()).1; - let transfer = token::Transfer { - transparent: vec![TransparentTransfer { - // The token will be escrowed to IBC address - source: source.clone(), - target: MASP, - token: args.token.clone(), - amount: validated_amount, - }], - // Link the Transfer to the MASP Transaction by hash code - shielded_section_hash: Some(masp_tx_hash), - }; - tx.add_masp_builder(MaspBuilder { - asset_types, - metadata: shielded_transfer.metadata, - builder: shielded_transfer.builder, - target: masp_tx_hash, - }); - transfer - }); + let transfer = shielded_parts + .map(|(shielded_transfer, asset_types)| { + let masp_tx_hash = + tx.add_masp_tx_section(shielded_transfer.masp_tx.clone()).1; + let transfer = token::Transfer::masp(masp_tx_hash) + .transfer( + // The token will be escrowed to IBC address + source.clone(), + MASP, + args.token.clone(), + validated_amount, + ) + .ok_or(Error::Other( + "Combined transfer overflows".to_string(), + ))?; + tx.add_masp_builder(MaspBuilder { + asset_types, + metadata: shielded_transfer.metadata, + builder: shielded_transfer.builder, + target: masp_tx_hash, + }); + Result::Ok(transfer) + }) + .transpose()?; // Check the token and make the tx data let ibc_denom = @@ -2837,7 +2838,7 @@ pub async fn build_transparent_transfer( context: &N, args: &mut args::TxTransparentTransfer, ) -> Result<(Tx, SigningTxData)> { - let mut transfers = vec![]; + let mut transfers = token::Transfer::default(); // Evaluate signer and fees let (signing_data, fee_amount, updated_balance) = { @@ -2913,26 +2914,21 @@ pub async fn build_transparent_transfer( } // Construct the corresponding transparent Transfer object - let transfer_data = token::TransparentTransfer { - source: source.to_owned(), - target: target.to_owned(), - token: token.to_owned(), - amount: validated_amount, - }; - - transfers.push(transfer_data); + transfers = transfers + .transfer( + source.to_owned(), + target.to_owned(), + token.to_owned(), + validated_amount, + ) + .ok_or(Error::Other("Combined transfer overflows".to_string()))?; } - // Construct the corresponding transparent Transfer object - let transfer = token::Transfer { - transparent: transfers, - shielded_section_hash: None, - }; let tx = build_pow_flag( context, &args.tx, args.tx_code_path.clone(), - transfer, + transfers, do_nothing, fee_amount, &signing_data.fee_payer, @@ -3014,10 +3010,7 @@ pub async fn build_shielded_transfer( }; // Construct the tx data with a placeholder shielded section hash - let data = token::Transfer { - transparent: vec![], - shielded_section_hash: None, - }; + let data = token::Transfer::default(); let tx = build_pow_flag( context, &args.tx, @@ -3059,7 +3052,7 @@ pub async fn build_shielding_transfer( })?; let mut transfer_data = vec![]; - let mut data = vec![]; + let mut data = token::Transfer::default(); for TxShieldingTransferData { source, token, @@ -3099,12 +3092,14 @@ pub async fn build_shielding_transfer( amount: validated_amount, }); - data.push(token::TransparentTransfer { - source: source.to_owned(), - target: MASP, - token: token.to_owned(), - amount: validated_amount, - }); + data = data + .transfer( + source.to_owned(), + MASP, + token.to_owned(), + validated_amount, + ) + .ok_or(Error::Other("Combined transfer overflows".to_string()))?; } let shielded_parts = construct_shielded_parts( @@ -3145,12 +3140,6 @@ pub async fn build_shielding_transfer( Ok(()) }; - // Construct the tx data with a placeholder shielded section hash - let data = token::Transfer { - transparent: data, - shielded_section_hash: None, - }; - let tx = build_pow_flag( context, &args.tx, @@ -3177,7 +3166,7 @@ pub async fn build_unshielding_transfer( let fee_amount = validate_fee(context, &args.tx).await?; let mut transfer_data = vec![]; - let mut data = vec![]; + let mut data = token::Transfer::default(); for TxUnshieldingTransferData { target, token, @@ -3196,12 +3185,14 @@ pub async fn build_unshielding_transfer( amount: validated_amount, }); - data.push(token::TransparentTransfer { - source: MASP, - target: target.to_owned(), - token: token.to_owned(), - amount: validated_amount, - }); + data = data + .transfer( + MASP, + target.to_owned(), + token.to_owned(), + validated_amount, + ) + .ok_or(Error::Other("Combined transfer overflows".to_string()))?; } // TODO(namada#2597): this function should also take another arg as the fees @@ -3243,12 +3234,6 @@ pub async fn build_unshielding_transfer( Ok(()) }; - // Construct the tx data with a placeholder shielded section hash - let data = token::Transfer { - transparent: data, - shielded_section_hash: None, - }; - let tx = build_pow_flag( context, &args.tx, @@ -3630,15 +3615,9 @@ pub async fn gen_ibc_shielding_transfer( if let Some(shielded_transfer) = shielded_transfer { let masp_tx_hash = Section::MaspTx(shielded_transfer.masp_tx.clone()).get_hash(); - let transfer = token::Transfer { - transparent: vec![TransparentTransfer { - source: source.clone(), - target: MASP, - token: token.clone(), - amount: validated_amount, - }], - shielded_section_hash: Some(masp_tx_hash), - }; + let transfer = token::Transfer::masp(masp_tx_hash) + .transfer(source.clone(), MASP, token.clone(), validated_amount) + .ok_or(Error::Other("Combined transfer overflows".to_string()))?; Ok(Some((transfer, shielded_transfer.masp_tx))) } else { Ok(None) diff --git a/crates/tests/src/integration/ledger_tests.rs b/crates/tests/src/integration/ledger_tests.rs index 1e2423c1cb..293c81d973 100644 --- a/crates/tests/src/integration/ledger_tests.rs +++ b/crates/tests/src/integration/ledger_tests.rs @@ -59,16 +59,17 @@ fn ledger_txs_and_queries() -> Result<()> { let validator_one_rpc = "http://127.0.0.1:26567"; let (node, _services) = setup::setup()?; - let transfer = - token::Transfer::transparent(vec![token::TransparentTransfer { - source: defaults::bertha_address(), - target: defaults::albert_address(), - token: node.native_token(), - amount: token::DenominatedAmount::new( + let transfer = token::Transfer::default() + .transfer( + defaults::bertha_address(), + defaults::albert_address(), + node.native_token(), + token::DenominatedAmount::new( token::Amount::native_whole(10), token::NATIVE_MAX_DECIMAL_PLACES.into(), ), - }]) + ) + .unwrap() .serialize_to_vec(); let tx_data_path = node.test_dir.path().join("tx.data"); std::fs::write(&tx_data_path, transfer).unwrap(); diff --git a/crates/token/src/lib.rs b/crates/token/src/lib.rs index c7a5ac7d7d..d5ae2bc54e 100644 --- a/crates/token/src/lib.rs +++ b/crates/token/src/lib.rs @@ -31,6 +31,8 @@ pub mod storage_key { pub use namada_trans_token::storage_key::*; } +use std::collections::BTreeMap; + use namada_core::address::Address; use namada_events::EmitEvents; use namada_storage::{Result, StorageRead, StorageWrite}; @@ -67,7 +69,7 @@ where Ok(()) } -/// Arguments for a multi-party transparent token transfer +/// Accounts can send or receive funds in a transparent token transfer #[derive( Debug, Clone, @@ -78,28 +80,19 @@ where BorshSchema, Hash, Eq, + Ord, PartialOrd, Serialize, Deserialize, )] -pub struct Transfer { - /// Transfer-specific data - pub transparent: Vec, - /// Hash of tx section that contains the MASP transaction - pub shielded_section_hash: Option, -} - -impl Transfer { - /// Make a transparent transfer - pub fn transparent(data: Vec) -> Self { - Self { - transparent: data, - shielded_section_hash: None, - } - } +pub struct Account { + /// Owner of the account + pub owner: Address, + /// Token handled by the account + pub token: Address, } -/// Arguments for a transparent token transfer +/// Arguments for a multi-party token transfer #[derive( Debug, Clone, @@ -108,21 +101,114 @@ impl Transfer { BorshDeserialize, BorshDeserializer, BorshSchema, + Default, Hash, Eq, PartialOrd, Serialize, Deserialize, )] -pub struct TransparentTransfer { - /// Source address will spend the tokens - pub source: Address, - /// Target address will receive the tokens - pub target: Address, - /// Token's address - pub token: Address, - /// The amount of tokens - pub amount: DenominatedAmount, +pub struct Transfer { + /// Sources of this transfer + pub sources: BTreeMap, + /// Targets of this transfer + pub targets: BTreeMap, + /// Hash of tx section that contains the MASP transaction + pub shielded_section_hash: Option, +} + +impl Transfer { + /// Create a MASP transaction + pub fn masp(hash: Hash) -> Self { + Self { + shielded_section_hash: Some(hash), + ..Self::default() + } + } + + /// Set the key to the given amount + fn set( + map: &mut BTreeMap, + key: K, + val: DenominatedAmount, + ) { + if val.is_zero() { + // Zero entries do not need to be present + map.remove(&key); + } else { + map.insert(key, val); + } + } + + /// Debit the given account + pub fn debit( + mut self, + owner: Address, + token: Address, + amount: DenominatedAmount, + ) -> Option { + let account = Account { owner, token }; + let zero = DenominatedAmount::new(Amount::zero(), amount.denom()); + let source_amount = *self.sources.get(&account).unwrap_or(&zero); + let target_amount = *self.targets.get(&account).unwrap_or(&zero); + // If this account is already a target, then reduce the target + if amount < target_amount { + // Account still gets net increase + Self::set( + &mut self.targets, + account, + target_amount.checked_sub(amount)?, + ); + } else { + // Account now actually gets a net decrease + self.targets.remove(&account); + let new_amt = source_amount + .checked_add(amount.checked_sub(target_amount)?)?; + Self::set(&mut self.sources, account, new_amt); + } + Some(self) + } + + /// Credit the given account + pub fn credit( + mut self, + owner: Address, + token: Address, + amount: DenominatedAmount, + ) -> Option { + let account = Account { owner, token }; + let zero = DenominatedAmount::new(Amount::zero(), amount.denom()); + let source_amount = *self.sources.get(&account).unwrap_or(&zero); + let target_amount = *self.targets.get(&account).unwrap_or(&zero); + // If this account is already a source, then reduce the source + if amount < source_amount { + // Account still gets net decrease + Self::set( + &mut self.sources, + account, + source_amount.checked_sub(amount)?, + ); + } else { + // Account now actually gets a net increase + self.sources.remove(&account); + let new_amt = target_amount + .checked_add(amount.checked_sub(source_amount)?)?; + Self::set(&mut self.targets, account, new_amt); + } + Some(self) + } + + /// Transfer assets between accounts + pub fn transfer( + self, + source: Address, + target: Address, + token: Address, + amount: DenominatedAmount, + ) -> Option { + self.debit(source, token.clone(), amount)? + .credit(target, token, amount) + } } #[cfg(any(test, feature = "testing"))] @@ -136,7 +222,7 @@ pub mod testing { pub use namada_trans_token::testing::*; use proptest::prelude::*; - use super::{Transfer, TransparentTransfer}; + use super::Transfer; prop_compose! { /// Generate a transparent transfer @@ -145,13 +231,13 @@ pub mod testing { target in arb_non_internal_address(), token in arb_established_address().prop_map(Address::Established), amount in arb_denominated_amount(), - ) -> TransparentTransfer{ - TransparentTransfer { + ) -> (Address, Address, Address, DenominatedAmount) { + ( source, target, token, amount, - } + ) } } @@ -160,9 +246,13 @@ pub mod testing { number_of_txs: usize, ) -> impl Strategy { proptest::collection::vec(arb_transparent_transfer(), 0..number_of_txs) - .prop_map(|data| Transfer { - transparent: data, - shielded_section_hash: None, + .prop_filter_map("Transfers must not overflow", |data| { + data.into_iter().try_fold( + Transfer::default(), + |acc, (source, target, token, amount)| { + acc.transfer(source, target, token, amount) + }, + ) }) } } diff --git a/crates/trans_token/src/storage.rs b/crates/trans_token/src/storage.rs index a6ad50926c..1ba6f238f8 100644 --- a/crates/trans_token/src/storage.rs +++ b/crates/trans_token/src/storage.rs @@ -1,3 +1,5 @@ +use std::collections::{BTreeMap, BTreeSet}; + use namada_core::address::{Address, InternalAddress}; use namada_core::hints; use namada_core::token::{self, Amount, AmountError, DenominatedAmount}; @@ -258,6 +260,64 @@ where } } +/// Transfer tokens from `sources` to `dests`. Returns an `Err` if any source +/// has insufficient balance or if the transfer to any destination would +/// overflow (This can only happen if the total supply doesn't fit in +/// `token::Amount`). +pub fn multi_transfer( + storage: &mut S, + sources: &BTreeMap<(Address, Address), Amount>, + dests: &BTreeMap<(Address, Address), Amount>, +) -> storage::Result<()> +where + S: StorageRead + StorageWrite, +{ + // Collect all the accounts whose balance has changed + let mut accounts = BTreeSet::new(); + accounts.extend(sources.keys().cloned()); + accounts.extend(dests.keys().cloned()); + let unexpected_err = || { + storage::Error::new_const( + "Computing difference between amounts should never overflow", + ) + }; + // Apply the balance change for each account in turn + for ref account @ (ref owner, ref token) in accounts { + let overflow_err = || { + storage::Error::new_alloc(format!( + "The transfer would overflow balance of {owner}" + )) + }; + let underflow_err = || { + storage::Error::new_alloc(format!( + "{owner} has insufficient balance" + )) + }; + // Load account balances and deltas + let owner_key = balance_key(token, owner); + let owner_balance = read_balance(storage, token, owner)?; + let src_amt = sources.get(account).cloned().unwrap_or_default(); + let dest_amt = dests.get(account).cloned().unwrap_or_default(); + // Compute owner_balance + dest_amt - src_amt + let new_owner_balance = if src_amt <= dest_amt { + owner_balance + .checked_add( + dest_amt.checked_sub(src_amt).ok_or_else(unexpected_err)?, + ) + .ok_or_else(overflow_err)? + } else { + owner_balance + .checked_sub( + src_amt.checked_sub(dest_amt).ok_or_else(unexpected_err)?, + ) + .ok_or_else(underflow_err)? + }; + // Wite the new balance + storage.write(&owner_key, new_owner_balance)?; + } + Ok(()) +} + /// Mint `amount` of `token` as `minter` to `dest`. pub fn mint_tokens( storage: &mut S, diff --git a/crates/tx_prelude/src/token.rs b/crates/tx_prelude/src/token.rs index 99af630dbb..f283607799 100644 --- a/crates/tx_prelude/src/token.rs +++ b/crates/tx_prelude/src/token.rs @@ -1,5 +1,7 @@ //! Shielded and transparent tokens related functions +use std::collections::BTreeMap; + use namada_core::address::Address; use namada_events::{EmitEvents, EventLevel}; #[cfg(any(test, feature = "testing"))] @@ -50,3 +52,34 @@ pub fn transfer( Ok(()) } + +/// A transparent token transfer that can be used in a transaction. +pub fn multi_transfer( + ctx: &mut Ctx, + sources: &BTreeMap<(Address, Address), Amount>, + dests: &BTreeMap<(Address, Address), Amount>, +) -> TxResult { + for (src, token) in sources.keys() { + // The tx must be authorized by the source address + ctx.insert_verifier(src)?; + if token.is_internal() { + // Established address tokens do not have VPs themselves, their + // validation is handled by the `Multitoken` internal address, but + // internal token addresses have to verify the transfer + ctx.insert_verifier(token)?; + } + } + + for (_, token) in dests.keys() { + if token.is_internal() { + // Established address tokens do not have VPs themselves, their + // validation is handled by the `Multitoken` internal address, but + // internal token addresses have to verify the transfer + ctx.insert_verifier(token)?; + } + } + + namada_token::multi_transfer(ctx, sources, dests)?; + + Ok(()) +} diff --git a/wasm/checksums.json b/wasm/checksums.json index f73d7a0fd7..c8be40e985 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,26 +1,26 @@ { - "tx_become_validator.wasm": "tx_become_validator.76e5ddf2b1ec805df627d220a472cf691e54fd56206910deb44a84e881e6f872.wasm", - "tx_bond.wasm": "tx_bond.277546629805e35f60fe1e4f208d36f488906c75a008217dd301b9e11fb17de5.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.b853589ea716d1865b6dba2788c70e120b8ce9711b17895593cd2c1b57bd2b57.wasm", - "tx_change_consensus_key.wasm": "tx_change_consensus_key.edf0b19a0d851d75dcd39c498c352f30157b7de7fcfeb189d111ceddc10ec930.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.c62598cd97bebec856a967228e78df455cd620818e16ad2617de22e1073c4b05.wasm", - "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.38d2819cdb4fe80a832c163c5b316c9e74c564deba9732ed7452cb2b3bef42c2.wasm", - "tx_claim_rewards.wasm": "tx_claim_rewards.1fd1118484a918947a005442b5dcac77556c538533982ccbcba9d7b02de533b0.wasm", - "tx_deactivate_validator.wasm": "tx_deactivate_validator.9dacf4d4aef2bc4d5ee8fce78f73544783376a974de686adc87ff0957e5a46fb.wasm", - "tx_ibc.wasm": "tx_ibc.dc05de488be5664844c93fad966000190c2b0847d4b5c20834c165a56ee716a7.wasm", + "tx_become_validator.wasm": "tx_become_validator.21a0f29ba6f76a5e0f02a84f53cd1b05a667213ddee24bbb69a7e79d7c458d45.wasm", + "tx_bond.wasm": "tx_bond.c0d4b3452e8c662a51aeb555980c678321f4a3f17f6bdb214a9e466c14244fe8.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.59eb714b138ccc6b25ffc654700bd68630b704cd5ac0a036f26f029c5ff77ff2.wasm", + "tx_change_consensus_key.wasm": "tx_change_consensus_key.bcd6f8605b72c6ad29daa6d9fad1e93bc9cf660bd4d319ce25f1652c8bea8ad3.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.09eb1be7f44cb057c76a14290d688ea9ae97d733fc799109720dab3d2336e8d4.wasm", + "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.cc58554f05eed2739e40ec51bb0053cf44c388f54bedc779b3844ee2e47d7015.wasm", + "tx_claim_rewards.wasm": "tx_claim_rewards.9d74e1b5cdf644dfd23313bee45603de26ced0d7cf9369d3b28d9198ea2c7923.wasm", + "tx_deactivate_validator.wasm": "tx_deactivate_validator.127e6d82171acd05746fa87e7431237d60704ba233c6c78b7f8b28c04e4ca7fc.wasm", + "tx_ibc.wasm": "tx_ibc.73e5b25173624072b598f81d358e53ff9819ee5334e35e4589384bb96a2b7177.wasm", "tx_init_account.wasm": "tx_init_account.d2f3a2c059e0f92d683471df83afb4cd7e143e4a0428893cf7e6155382d8270d.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.04cb9b3468e6ffc7604231acb1668ff92e0c28a06354c7ad26698fb549a7aab5.wasm", - "tx_reactivate_validator.wasm": "tx_reactivate_validator.0c52fcf238c1b9be9455891744f5f495b4c78c26bbe20fad5eddbb28b6176792.wasm", - "tx_redelegate.wasm": "tx_redelegate.c584955237fb27964fc94c1aaa2c04eb9190894f6c24b4634e0b07cee511cce8.wasm", - "tx_resign_steward.wasm": "tx_resign_steward.c3f8a4465aad3fb674dbd80c2c994e1881a25315215b615dcd570885271c481b.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.48770c2d9e57bf77d58eb6d1028cc9c3d1b9c5ba18198b9ea6a0b648090760ee.wasm", + "tx_reactivate_validator.wasm": "tx_reactivate_validator.647a654fe0e0f9058b399df97a4fac597d31817df950c0d863b28cc121b68ec3.wasm", + "tx_redelegate.wasm": "tx_redelegate.7fd8dbd59e4978dbffa7c1c7c42383ce9a4d9d945fc03a5d236c9f7a31bde37d.wasm", + "tx_resign_steward.wasm": "tx_resign_steward.0746f767c4150afb94dd64ee60756dc6ef9a3d19e7410dd23ffe3d22910b716a.wasm", "tx_reveal_pk.wasm": "tx_reveal_pk.79455aadb09effe70b407a88dcb50552344e32d9b9e30897b7e0e24ce34e76a2.wasm", - "tx_transfer.wasm": "tx_transfer.a3fd5a7966b2a56790b7e8ca3578e492e8ae2ef03dadd090ec0e82f521f5c493.wasm", - "tx_unbond.wasm": "tx_unbond.3d69f98b7832de1d63cdff4e2dec3eb8ba6da44104af00ed0607f040c300d52c.wasm", - "tx_unjail_validator.wasm": "tx_unjail_validator.d736868736feccea85d7bb8a5bd5cc67c19315521f608838ad60befbfc9e7738.wasm", + "tx_transfer.wasm": "tx_transfer.98b685f3785001f0bd891c8d33b883da35edbb2298aba438de52478be9a907f1.wasm", + "tx_unbond.wasm": "tx_unbond.224541abc9b82ead25b0cbeecabc46a1842f56382637b6faf3126ce6147114a6.wasm", + "tx_unjail_validator.wasm": "tx_unjail_validator.0e3e066958d9aa211ba5596e25cab633b902843ab9eccd76372a99de6f50f6ef.wasm", "tx_update_account.wasm": "tx_update_account.3daaa7d67b1545a161a65efb99fa930a09f3ecdc87e3f0a6e965d49756912b6c.wasm", - "tx_update_steward_commission.wasm": "tx_update_steward_commission.a62fcce86de9723ceff0f838d106be6f912d06f48cf10a3163dbb9ef53620c96.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.724a81d2cc2a0e491381d98d22753f46003f781f09f968bff29ad57bddd6f5f8.wasm", - "tx_withdraw.wasm": "tx_withdraw.1c6766e0b777b961700c0c6542dcf88bef7650924ba7b11c20a0c7caeae65f50.wasm", + "tx_update_steward_commission.wasm": "tx_update_steward_commission.5e98935ed860bff5e3f5c0f0e82f7dbb194decc7c4a84c2eabbad2b0fb1e054a.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.c9eab9b143f0532c76f6015046b152461dc9e7b93a5a43e3d77c8767b84489f1.wasm", + "tx_withdraw.wasm": "tx_withdraw.1d2941b074e1ec40c1285a83538c5e93ac5feffd403f747456fb88d8f8d4b3cc.wasm", "vp_implicit.wasm": "vp_implicit.13cdf1daf217ae900e7ac2838d66a584a4aa8cd627e10ad99786acc3aedc3e30.wasm", "vp_user.wasm": "vp_user.f1336b2653d225c95a15d7be9971eff708196386eb83373bcc13855c0379da85.wasm" } \ No newline at end of file diff --git a/wasm/tx_transfer/src/lib.rs b/wasm/tx_transfer/src/lib.rs index b11e841574..6f9d9ede75 100644 --- a/wasm/tx_transfer/src/lib.rs +++ b/wasm/tx_transfer/src/lib.rs @@ -2,6 +2,8 @@ //! This tx uses `token::TransparentTransfer` wrapped inside `SignedTxData` //! as its input as declared in `namada` crate. +use std::collections::BTreeMap; + use namada_tx_prelude::action::{Action, MaspAction, Write}; use namada_tx_prelude::*; @@ -12,17 +14,29 @@ fn apply_tx(ctx: &mut Ctx, tx_data: BatchedTx) -> TxResult { .wrap_err("Failed to decode token::TransparentTransfer tx data")?; debug_log!("apply_tx called with transfer: {:#?}", transfers); - for transfer in transfers.transparent { - token::transfer( - ctx, - &transfer.source, - &transfer.target, - &transfer.token, - transfer.amount.amount(), - ) + // Prepare the sources of the multi-transfer + let sources = transfers + .sources + .into_iter() + .map(|(account, amount)| { + ((account.owner, account.token), amount.amount()) + }) + .collect::>(); + + // Prepare the target of the multi-transfer + let targets = transfers + .targets + .into_iter() + .map(|(account, amount)| { + ((account.owner, account.token), amount.amount()) + }) + .collect::>(); + + // Effect the multi transfer + token::multi_transfer(ctx, &sources, &targets) .wrap_err("Token transfer failed")?; - } + // Apply the shielded transfer if there is a link to one if let Some(masp_section_ref) = transfers.shielded_section_hash { let shielded = tx_data .tx