Skip to content

Commit

Permalink
Merge pull request #3736 from anoma/tomas/refactor-token-transfer
Browse files Browse the repository at this point in the history
refactor token transfer and add more tests
  • Loading branch information
mergify[bot] authored Sep 23, 2024
2 parents 8d11769 + c3cbda3 commit 760462b
Show file tree
Hide file tree
Showing 22 changed files with 1,125 additions and 309 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Refactored token transfer functions and fixed checks for no-op conditions.
([\#3736](https://github.com/anoma/namada/pull/3736))
8 changes: 8 additions & 0 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions crates/core/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,12 @@ pub mod testing {
.expect("The token address decoding shouldn't fail")
}

/// A sampled established address for tests
pub fn established_address_5() -> Address {
Address::decode("tnam1qyftuue8fq25ezm0s8vj75d3qz759r2225ug7hll")
.expect("The token address decoding shouldn't fail")
}

/// Generate an arbitrary [`Address`] (established or implicit).
pub fn arb_non_internal_address() -> impl Strategy<Value = Address> {
prop_oneof![
Expand Down
4 changes: 3 additions & 1 deletion crates/core/src/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use borsh_ext::BorshSerializeExt;
use masp_primitives::asset_type::AssetType;
use masp_primitives::sapling::ViewingKey;
use masp_primitives::transaction::TransparentAddress;
pub use masp_primitives::transaction::TxId as TxIdInner;
pub use masp_primitives::transaction::{
Transaction as MaspTransaction, TxId as TxIdInner,
};
use namada_macros::BorshDeserializer;
#[cfg(feature = "migrations")]
use namada_migrations::*;
Expand Down
9 changes: 8 additions & 1 deletion crates/core/src/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,8 +1136,9 @@ impl PartialOrd for I320 {
}
}

#[cfg(any(test, feature = "testing"))]
/// Testing helpers
#[cfg(any(test, feature = "testing"))]
#[allow(clippy::arithmetic_side_effects)]
pub mod testing {
use super::*;

Expand Down Expand Up @@ -1166,6 +1167,12 @@ pub mod testing {
}
}

impl std::ops::SubAssign<I256> for I256 {
fn sub_assign(&mut self, rhs: I256) {
*self = *self - rhs;
}
}

impl std::ops::Mul<I256> for I256 {
type Output = Self;

Expand Down
3 changes: 1 addition & 2 deletions crates/shielded_token/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ pub mod vp;

use std::str::FromStr;

pub use masp_primitives::transaction::Transaction as MaspTransaction;
use namada_core::borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
pub use namada_core::dec::Dec;
pub use namada_core::masp::{MaspEpoch, MaspTxId, MaspValue};
pub use namada_core::masp::{MaspEpoch, MaspTransaction, MaspTxId, MaspValue};
pub use namada_state::{
ConversionLeaf, ConversionState, Error, Key, OptionExt, Result, ResultExt,
StorageRead, StorageWrite, WithConversionState,
Expand Down
4 changes: 4 additions & 0 deletions crates/tests/src/vm_host_env/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,10 @@ mod native_tx_host_env {
public_keys_map_len: u64,
threshold: u8,
) -> i64);
native_host_fn!(tx_update_masp_note_commitment_tree(
transaction_ptr: u64,
transaction_len: u64,
) -> i64);
native_host_fn!(tx_yield_value(
buf_ptr: u64,
buf_len: u64,
Expand Down
4 changes: 4 additions & 0 deletions crates/token/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ namada_events = { path = "../events", default-features = false }
namada_macros = { path = "../macros" }
namada_migrations = { path = "../migrations", optional = true }
namada_shielded_token = { path = "../shielded_token" }
namada_storage = { path = "../storage" }
namada_systems = { path = "../systems" }
namada_trans_token = { path = "../trans_token" }
namada_tx = { path = "../tx" }
namada_tx_env = { path = "../tx_env" }

arbitrary = { workspace = true, optional = true }
borsh.workspace = true
Expand All @@ -42,6 +45,7 @@ serde.workspace = true
[dev-dependencies]
namada_core = { path = "../core", features = ["testing"] }
namada_shielded_token = { path = "../shielded_token", features = ["testing"] }
namada_tests = { path = "../tests" }

masp_primitives.workspace = true

Expand Down
52 changes: 52 additions & 0 deletions crates/token/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub use namada_shielded_token::*;
use namada_systems::parameters;
pub use namada_trans_token::*;

pub mod tx;

/// Validity predicates
pub mod vp {
pub use namada_shielded_token::vp::MaspVp;
Expand All @@ -38,6 +40,7 @@ pub mod vp {
pub use namada_shielded_token::{Error, Result};
pub use namada_trans_token::vp::MultitokenVp;
}

use serde::{Deserialize, Serialize};

/// Token storage keys
Expand Down Expand Up @@ -172,6 +175,15 @@ pub struct Transfer {
pub shielded_section_hash: Option<MaspTxId>,
}

/// References to the transparent sections of a [`Transfer`].
#[derive(Debug, Clone)]
pub struct TransparentTransfersRef<'a> {
/// Sources of this transfer
pub sources: &'a BTreeMap<Account, DenominatedAmount>,
/// Targets of this transfer
pub targets: &'a BTreeMap<Account, DenominatedAmount>,
}

impl Transfer {
/// Create a MASP transaction
pub fn masp(hash: MaspTxId) -> Self {
Expand Down Expand Up @@ -264,6 +276,46 @@ impl Transfer {
self.debit(source, token.clone(), amount)?
.credit(target, token, amount)
}

/// Get references to the transparent sections.
pub fn transparent_part(&self) -> Option<TransparentTransfersRef<'_>> {
if self.sources.is_empty() && self.targets.is_empty() {
None
} else {
Some(TransparentTransfersRef {
sources: &self.sources,
targets: &self.targets,
})
}
}
}

impl TransparentTransfersRef<'_> {
/// Construct pairs of source address and token with a debited amount
pub fn sources(&self) -> BTreeMap<(Address, Address), Amount> {
self.sources
.iter()
.map(|(account, amount)| {
(
(account.owner.clone(), account.token.clone()),
amount.amount(),
)
})
.collect::<BTreeMap<_, _>>()
}

/// Construct pairs of target address and token with a credited amount
pub fn targets(&self) -> BTreeMap<(Address, Address), Amount> {
self.targets
.iter()
.map(|(account, amount)| {
(
(account.owner.clone(), account.token.clone()),
amount.amount(),
)
})
.collect::<BTreeMap<_, _>>()
}
}

#[cfg(all(any(test, feature = "testing"), feature = "masp"))]
Expand Down
Loading

0 comments on commit 760462b

Please sign in to comment.