diff --git a/Cargo.toml b/Cargo.toml index a3e05211..b65e4b52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,14 +40,14 @@ axum-extra = { version = "0.9.3", features = ["query"] } chrono = { version = "0.4.30", features = ["serde"] } async-trait = "0.1.73" anyhow = "1.0.75" -namada_core = { git = "https://github.com/anoma/namada", tag = "v0.39.0" } -namada_sdk = { git = "https://github.com/anoma/namada", tag = "v0.39.0", default-features = false, features = ["tendermint-rpc", "std", "async-send", "download-params", "rand"] } -namada_tx = { git = "https://github.com/anoma/namada", tag = "v0.39.0" } -namada_governance = { git = "https://github.com/anoma/namada", tag = "v0.39.0" } -namada_ibc = { git = "https://github.com/anoma/namada", tag = "v0.39.0" } -namada_token = { git = "https://github.com/anoma/namada", tag = "v0.39.0" } -namada_parameters = { git = "https://github.com/anoma/namada", tag = "v0.39.0" } -namada_proof_of_stake = { git = "https://github.com/anoma/namada", tag = "v0.39.0" } +namada_core = { git = "https://github.com/anoma/namada", tag = "v0.40.0" } +namada_sdk = { git = "https://github.com/anoma/namada", tag = "v0.40.0", default-features = false, features = ["tendermint-rpc", "std", "async-send", "download-params", "rand"] } +namada_tx = { git = "https://github.com/anoma/namada", tag = "v0.40.0" } +namada_governance = { git = "https://github.com/anoma/namada", tag = "v0.40.0" } +namada_ibc = { git = "https://github.com/anoma/namada", tag = "v0.40.0" } +namada_token = { git = "https://github.com/anoma/namada", tag = "v0.40.0" } +namada_parameters = { git = "https://github.com/anoma/namada", tag = "v0.40.0" } +namada_proof_of_stake = { git = "https://github.com/anoma/namada", tag = "v0.40.0" } tendermint = "0.36.0" tendermint-config = "0.36.0" tendermint-rpc = { version = "0.36.0", features = ["http-client"] } diff --git a/shared/src/block.rs b/shared/src/block.rs index 021313b7..6db3595d 100644 --- a/shared/src/block.rs +++ b/shared/src/block.rs @@ -284,22 +284,17 @@ impl Block { for tx in inners_txs { let mut balance_change = match &tx.kind { TransactionKind::TransparentTransfer(data) => { - let transfer_data = data.clone(); - let transfer_source = - Id::from(transfer_data.source); - let transfer_target = - Id::from(transfer_data.target); - let transfer_token = Id::from(transfer_data.token); - vec![ - BalanceChange::new( - transfer_source, - transfer_token.clone(), - ), - BalanceChange::new( - transfer_target, - transfer_token, - ), - ] + [&data.sources, &data.targets] + .iter() + .flat_map(|transfer_changes| { + transfer_changes.0.keys().map(|account| { + BalanceChange::new( + Id::from(account.owner.clone()), + Id::from(account.token.clone()), + ) + }) + }) + .collect() } TransactionKind::Bond(data) => { let bond_data = data.clone(); diff --git a/shared/src/block_result.rs b/shared/src/block_result.rs index 3b53fdfd..4fbf40d4 100644 --- a/shared/src/block_result.rs +++ b/shared/src/block_result.rs @@ -60,7 +60,7 @@ pub struct BatchResults { impl From> for BatchResults { fn from(value: TxResult) -> Self { Self { - batch_results: value.batch_results.0.iter().fold( + batch_results: value.batch_results.iter().fold( BTreeMap::default(), |mut acc, (tx_hash, result)| { let tx_id = Id::from(*tx_hash); @@ -73,16 +73,18 @@ impl From> for BatchResults { acc }, ), - batch_errors: value.batch_results.0.into_iter().fold( + batch_errors: value.batch_results.iter().fold( BTreeMap::default(), |mut acc, (tx_hash, result)| { - let tx_id = Id::from(tx_hash); + let tx_id = Id::from(*tx_hash); let result = if let Ok(result) = result { result .vps_result .errors - .into_iter() - .map(|(address, error)| (Id::from(address), error)) + .iter() + .map(|(address, error)| { + (Id::from(address.clone()), error.clone()) + }) .collect() } else { BTreeMap::default() diff --git a/shared/src/checksums.rs b/shared/src/checksums.rs index fe6473c1..3ea79425 100644 --- a/shared/src/checksums.rs +++ b/shared/src/checksums.rs @@ -2,8 +2,7 @@ use bimap::BiMap; use namada_sdk::tx::{ TX_BOND_WASM, TX_CHANGE_COMMISSION_WASM, TX_CHANGE_METADATA_WASM, TX_CLAIM_REWARDS_WASM, TX_INIT_PROPOSAL, TX_REDELEGATE_WASM, TX_REVEAL_PK, - TX_TRANSPARENT_TRANSFER_WASM, TX_UNBOND_WASM, TX_VOTE_PROPOSAL, - TX_WITHDRAW_WASM, + TX_TRANSFER_WASM, TX_UNBOND_WASM, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, }; use serde::{Deserialize, Serialize}; @@ -31,7 +30,7 @@ impl Checksums { pub fn code_paths() -> Vec { vec![ TX_REVEAL_PK.to_string(), - TX_TRANSPARENT_TRANSFER_WASM.to_string(), + TX_TRANSFER_WASM.to_string(), TX_BOND_WASM.to_string(), TX_REDELEGATE_WASM.to_string(), TX_UNBOND_WASM.to_string(), diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 7b942e58..51216895 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -14,6 +14,7 @@ pub mod parameters; pub mod proposal; pub mod public_key; pub mod rewards; +pub mod ser; pub mod transaction; pub mod unbond; pub mod utils; diff --git a/shared/src/ser.rs b/shared/src/ser.rs new file mode 100644 index 00000000..7df6d77b --- /dev/null +++ b/shared/src/ser.rs @@ -0,0 +1,89 @@ +use serde::{Deserialize, Serialize}; + +use std::collections::{BTreeMap, HashMap}; +use std::str::FromStr; + +use namada_core::address::Address; +use namada_core::masp::TxId; +use namada_sdk::token::{ + Account as NamadaAccount, DenominatedAmount as NamadaDenominatedAmount, + Transfer as NamadaTransfer, +}; + +#[derive(Debug, Clone)] +pub struct AccountsMap(pub BTreeMap); + +impl Serialize for AccountsMap { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.collect_seq(self.0.iter().map(|(k, v)| { + HashMap::from([ + ("owner", k.owner.encode()), + ("token", k.token.encode()), + ("amount", v.to_string_precise()), + ]) + })) + } +} + +impl<'de> Deserialize<'de> for AccountsMap { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + > as Deserialize>::deserialize( + deserializer, + ) + .map(|v| { + AccountsMap( + v.into_iter() + .map(|val| { + let owner = + val.get("owner").expect("Cannot find owner"); + let token = + val.get("token").expect("Cannot find token"); + let amount = + val.get("amount").expect("Cannot find amount"); + + ( + NamadaAccount { + owner: Address::decode(owner) + .expect("Cannot parse Address for owner"), + token: Address::decode(token) + .expect("Cannot parse Address for token"), + }, + NamadaDenominatedAmount::from_str(amount) + .expect("Cannot parse DenominatedAmount"), + ) + }) + .collect(), + ) + }) + } +} + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct TransparentTransfer { + /// Sources of this transfer + pub sources: AccountsMap, + /// Targets of this transfer + pub targets: AccountsMap, + /// Hash of tx section that contains the MASP transaction + pub shielded_section_hash: Option, +} + +impl From for TransparentTransfer { + fn from(transfer: NamadaTransfer) -> Self { + let sources = AccountsMap(transfer.sources); + let targets = AccountsMap(transfer.targets); + let shielded_section_hash = transfer.shielded_section_hash; + + TransparentTransfer { + sources, + targets, + shielded_section_hash, + } + } +} diff --git a/shared/src/transaction.rs b/shared/src/transaction.rs index 42c44514..da09c50e 100644 --- a/shared/src/transaction.rs +++ b/shared/src/transaction.rs @@ -5,7 +5,7 @@ use namada_governance::{InitProposalData, VoteProposalData}; use namada_sdk::borsh::BorshDeserialize; use namada_sdk::key::common::PublicKey; use namada_sdk::masp::ShieldedTransfer; -use namada_sdk::token::TransparentTransfer; +use namada_sdk::token::Transfer; use namada_sdk::uint::Uint; use namada_tx::data::pos::{ Bond, ClaimRewards, CommissionChange, MetaDataChange, Redelegation, Unbond, @@ -19,6 +19,7 @@ use crate::block::BlockHeight; use crate::block_result::{BlockResult, TxEventStatusCode}; use crate::checksums::Checksums; use crate::id::Id; +use crate::ser::TransparentTransfer; // We wrap public key in a struct so we serialize data as object instead of // string @@ -54,10 +55,12 @@ impl TransactionKind { pub fn from(tx_kind_name: &str, data: &[u8]) -> Self { match tx_kind_name { - "tx_transparent_transfer" => TransactionKind::TransparentTransfer( - TransparentTransfer::try_from_slice(data) - .expect("Cannot deserialize TransparentTransfer"), - ), + "tx_transfer" => { + TransactionKind::TransparentTransfer(TransparentTransfer::from( + Transfer::try_from_slice(data) + .expect("Cannot deserialize Transfer"), + )) + } "tx_bond" => TransactionKind::Bond( Bond::try_from_slice(data).expect("Cannot deserialize Bond"), ),