Skip to content

Commit 1451b2e

Browse files
authored
Merge pull request #251 from anoma/fix-transparent-tx-kind
improve transfer classification
2 parents 9dbd562 + 433881c commit 1451b2e

File tree

13 files changed

+554
-42
lines changed

13 files changed

+554
-42
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- This file should undo anything in `up.sql`
2+
SELECT 1;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- Your SQL goes here
2+
ALTER TYPE TRANSACTION_KIND ADD VALUE 'mixed_transfer';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- This file should undo anything in `up.sql`
2+
SELECT 1;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Your SQL goes here
2+
ALTER TYPE TRANSACTION_KIND ADD VALUE 'ibc_transparent_transfer';
3+
ALTER TYPE TRANSACTION_KIND ADD VALUE 'ibc_shielding_transfer';
4+
ALTER TYPE TRANSACTION_KIND ADD VALUE 'ibc_unshielding_transfer';

orm/src/transactions.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ pub enum TransactionKindDb {
1616
ShieldedTransfer,
1717
ShieldingTransfer,
1818
UnshieldingTransfer,
19+
MixedTransfer,
1920
IbcMsgTransfer,
21+
IbcTransparentTransfer,
22+
IbcShieldingTransfer,
23+
IbcUnshieldingTransfer,
2024
Bond,
2125
Redelegation,
2226
Unbond,
@@ -41,7 +45,21 @@ impl From<TransactionKind> for TransactionKindDb {
4145
Self::TransparentTransfer
4246
}
4347
TransactionKind::ShieldedTransfer(_) => Self::ShieldedTransfer,
48+
TransactionKind::UnshieldingTransfer(_) => {
49+
Self::UnshieldingTransfer
50+
}
51+
TransactionKind::ShieldingTransfer(_) => Self::ShieldingTransfer,
52+
TransactionKind::MixedTransfer(_) => Self::MixedTransfer,
4453
TransactionKind::IbcMsgTransfer(_) => Self::IbcMsgTransfer,
54+
TransactionKind::IbcTrasparentTransfer(_) => {
55+
Self::IbcTransparentTransfer
56+
}
57+
TransactionKind::IbcShieldingTransfer(_) => {
58+
Self::IbcShieldingTransfer
59+
}
60+
TransactionKind::IbcUnshieldingTransfer(_) => {
61+
Self::IbcUnshieldingTransfer
62+
}
4563
TransactionKind::Bond(_) => Self::Bond,
4664
TransactionKind::Redelegation(_) => Self::Redelegation,
4765
TransactionKind::Unbond(_) => Self::Unbond,

shared/src/block.rs

Lines changed: 314 additions & 6 deletions
Large diffs are not rendered by default.

shared/src/block_result.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,6 @@ impl TxAttributesType {
159159
.unwrap_or_default()
160160
.to_owned();
161161

162-
tracing::error!("{}", timeout_timestamp);
163-
164162
Some(Self::SendPacket(SendPacket {
165163
source_port,
166164
dest_port,

shared/src/gas.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ pub struct GasEstimation {
1313
pub transparent_transfer: u64,
1414
pub shielded_transfer: u64,
1515
pub shielding_transfer: u64,
16+
pub ibc_unshielding_transfer: u64,
17+
pub ibc_shielding_transfer: u64,
1618
pub unshielding_transfer: u64,
1719
pub ibc_msg_transfer: u64,
20+
pub mixed_transfer: u64,
1821
pub bond: u64,
1922
pub redelegation: u64,
2023
pub unbond: u64,
@@ -34,7 +37,10 @@ impl GasEstimation {
3437
shielded_transfer: 0,
3538
shielding_transfer: 0,
3639
unshielding_transfer: 0,
40+
ibc_shielding_transfer: 0,
41+
ibc_unshielding_transfer: 0,
3742
ibc_msg_transfer: 0,
43+
mixed_transfer: 0,
3844
bond: 0,
3945
redelegation: 0,
4046
unbond: 0,
@@ -63,6 +69,18 @@ impl GasEstimation {
6369
self.unshielding_transfer += 1
6470
}
6571

72+
pub fn increase_mixed_transfer(&mut self) {
73+
self.mixed_transfer += 1
74+
}
75+
76+
pub fn increase_ibc_shielding_transfer(&mut self) {
77+
self.ibc_shielding_transfer += 1
78+
}
79+
80+
pub fn increase_ibc_unshielding_transfer(&mut self) {
81+
self.ibc_unshielding_transfer += 1
82+
}
83+
6684
pub fn increase_ibc_msg_transfer(&mut self) {
6785
self.ibc_msg_transfer += 1
6886
}

shared/src/ser.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl<'de> Deserialize<'de> for AccountsMap {
6868
}
6969

7070
#[derive(Deserialize, Serialize, Debug, Clone)]
71-
pub struct TransparentTransfer {
71+
pub struct TransferData {
7272
/// Sources of this transfer
7373
pub sources: AccountsMap,
7474
/// Targets of this transfer
@@ -77,13 +77,13 @@ pub struct TransparentTransfer {
7777
pub shielded_section_hash: Option<MaspTxId>,
7878
}
7979

80-
impl From<NamadaTransfer> for TransparentTransfer {
80+
impl From<NamadaTransfer> for TransferData {
8181
fn from(transfer: NamadaTransfer) -> Self {
8282
let sources = AccountsMap(transfer.sources);
8383
let targets = AccountsMap(transfer.targets);
8484
let shielded_section_hash = transfer.shielded_section_hash;
8585

86-
TransparentTransfer {
86+
TransferData {
8787
sources,
8888
targets,
8989
shielded_section_hash,

shared/src/transaction.rs

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use namada_governance::{InitProposalData, VoteProposalData};
55
use namada_sdk::address::Address;
66
use namada_sdk::borsh::BorshDeserialize;
77
use namada_sdk::key::common::PublicKey;
8-
use namada_sdk::masp::ShieldedTransfer;
98
use namada_sdk::token::Transfer;
109
use namada_sdk::uint::Uint;
1110
use namada_tx::data::pos::{
@@ -21,7 +20,8 @@ use crate::block::BlockHeight;
2120
use crate::block_result::{BlockResult, TxEventStatusCode};
2221
use crate::checksums::Checksums;
2322
use crate::id::Id;
24-
use crate::ser::{IbcMessage, TransparentTransfer};
23+
use crate::ser::{IbcMessage, TransferData};
24+
use crate::utils::{self, transfer_to_ibc_tx_kind};
2525

2626
// We wrap public key in a struct so we serialize data as object instead of
2727
// string
@@ -33,11 +33,15 @@ pub struct RevealPkData {
3333
#[derive(Serialize, Debug, Clone)]
3434
#[serde(untagged)]
3535
pub enum TransactionKind {
36-
TransparentTransfer(Option<TransparentTransfer>),
37-
// TODO: remove once ShieldedTransfer can be serialized
38-
#[serde(skip)]
39-
ShieldedTransfer(Option<ShieldedTransfer>),
36+
TransparentTransfer(Option<TransferData>),
37+
ShieldedTransfer(Option<TransferData>),
38+
ShieldingTransfer(Option<TransferData>),
39+
UnshieldingTransfer(Option<TransferData>),
40+
MixedTransfer(Option<TransferData>),
4041
IbcMsgTransfer(Option<IbcMessage<Transfer>>),
42+
IbcTrasparentTransfer((Option<IbcMessage<Transfer>>, TransferData)),
43+
IbcShieldingTransfer((Option<IbcMessage<Transfer>>, TransferData)),
44+
IbcUnshieldingTransfer((Option<IbcMessage<Transfer>>, TransferData)),
4145
Bond(Option<Bond>),
4246
Redelegation(Option<Redelegation>),
4347
Unbond(Option<Unbond>),
@@ -60,15 +64,18 @@ impl TransactionKind {
6064
serde_json::to_string(&self).ok()
6165
}
6266

63-
pub fn from(tx_kind_name: &str, data: &[u8]) -> Self {
67+
pub fn from(
68+
tx_kind_name: &str,
69+
data: &[u8],
70+
masp_address: &Address,
71+
) -> Self {
6472
match tx_kind_name {
6573
"tx_transfer" => {
66-
let data = if let Ok(data) = Transfer::try_from_slice(data) {
67-
Some(TransparentTransfer::from(data))
74+
if let Ok(transfer) = Transfer::try_from_slice(data) {
75+
utils::transfer_to_tx_kind(transfer, masp_address)
6876
} else {
69-
None
70-
};
71-
TransactionKind::TransparentTransfer(data)
77+
TransactionKind::Unknown
78+
}
7279
}
7380
"tx_bond" => {
7481
let data = if let Ok(data) = Bond::try_from_slice(data) {
@@ -173,15 +180,38 @@ impl TransactionKind {
173180
TransactionKind::ReactivateValidator(data)
174181
}
175182
"tx_ibc" => {
176-
let data = if let Ok(data) =
183+
if let Ok(ibc_data) =
177184
namada_ibc::decode_message::<Transfer>(data)
178185
{
179-
Some(data)
186+
match ibc_data.clone() {
187+
namada_ibc::IbcMessage::Envelope(_msg_envelope) => {
188+
TransactionKind::IbcMsgTransfer(Some(IbcMessage(
189+
ibc_data,
190+
)))
191+
}
192+
namada_ibc::IbcMessage::Transfer(transfer) => {
193+
if let Some(data) = transfer.transfer {
194+
utils::transfer_to_tx_kind(data, masp_address)
195+
} else {
196+
TransactionKind::IbcMsgTransfer(None)
197+
}
198+
}
199+
namada_ibc::IbcMessage::NftTransfer(transfer) => {
200+
if let Some(data) = transfer.transfer {
201+
transfer_to_ibc_tx_kind(
202+
data,
203+
masp_address,
204+
ibc_data,
205+
)
206+
} else {
207+
TransactionKind::IbcMsgTransfer(None)
208+
}
209+
}
210+
}
180211
} else {
181212
tracing::warn!("Cannot deserialize IBC transfer");
182-
None
183-
};
184-
TransactionKind::IbcMsgTransfer(data.map(IbcMessage))
213+
TransactionKind::IbcMsgTransfer(None)
214+
}
185215
}
186216
"tx_unjail_validator" => {
187217
let data = if let Ok(data) = Address::try_from_slice(data) {
@@ -281,6 +311,16 @@ impl InnerTransaction {
281311
pub fn was_successful(&self) -> bool {
282312
self.exit_code == TransactionExitStatus::Applied
283313
}
314+
315+
pub fn is_ibc(&self) -> bool {
316+
matches!(
317+
self.kind,
318+
TransactionKind::IbcMsgTransfer(_)
319+
| TransactionKind::IbcTrasparentTransfer(_)
320+
| TransactionKind::IbcUnshieldingTransfer(_)
321+
| TransactionKind::IbcShieldingTransfer(_)
322+
)
323+
}
284324
}
285325

286326
#[derive(Debug, Clone)]
@@ -299,6 +339,7 @@ impl Transaction {
299339
block_height: BlockHeight,
300340
checksums: Checksums,
301341
block_results: &BlockResult,
342+
masp_address: &Address,
302343
) -> Result<(WrapperTransaction, Vec<InnerTransaction>), String> {
303344
let transaction =
304345
Tx::try_from(raw_tx_bytes).map_err(|e| e.to_string())?;
@@ -379,7 +420,11 @@ impl Transaction {
379420
if let Some(tx_kind_name) =
380421
checksums.get_name_by_id(&id)
381422
{
382-
TransactionKind::from(&tx_kind_name, &tx_data)
423+
TransactionKind::from(
424+
&tx_kind_name,
425+
&tx_data,
426+
masp_address,
427+
)
383428
} else {
384429
TransactionKind::Unknown
385430
}

shared/src/utils.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
use namada_ibc::IbcMessage;
2+
use namada_sdk::address::Address;
3+
use namada_sdk::token::Transfer;
4+
15
use crate::id::Id;
6+
use crate::ser;
27
use crate::token::Token;
8+
use crate::transaction::TransactionKind;
39

410
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
511
pub struct BalanceChange {
@@ -25,3 +31,93 @@ pub struct DelegationPair {
2531
pub validator_address: Id,
2632
pub delegator_address: Id,
2733
}
34+
35+
pub fn transfer_to_tx_kind(
36+
data: Transfer,
37+
masp_address: &Address,
38+
) -> TransactionKind {
39+
let has_shielded_section = data.shielded_section_hash.is_some();
40+
41+
let (all_sources_are_masp, any_sources_are_masp) = data
42+
.sources
43+
.iter()
44+
.fold((true, false), |(all, any), (acc, _)| {
45+
let is_masp = acc.owner.eq(masp_address);
46+
(all && is_masp, any || is_masp)
47+
});
48+
49+
let (all_targets_are_masp, any_targets_are_masp) = data
50+
.targets
51+
.iter()
52+
.fold((true, false), |(all, any), (acc, _)| {
53+
let is_masp = acc.owner.eq(masp_address);
54+
(all && is_masp, any || is_masp)
55+
});
56+
57+
match (
58+
all_sources_are_masp,
59+
any_sources_are_masp,
60+
all_targets_are_masp,
61+
any_targets_are_masp,
62+
has_shielded_section,
63+
) {
64+
(true, _, true, _, true) => {
65+
TransactionKind::ShieldedTransfer(Some(data.into()))
66+
}
67+
(true, _, _, false, true) => {
68+
TransactionKind::UnshieldingTransfer(Some(data.into()))
69+
}
70+
(false, _, true, _, true) => {
71+
TransactionKind::ShieldingTransfer(Some(data.into()))
72+
}
73+
(false, _, false, _, false) => {
74+
TransactionKind::TransparentTransfer(Some(data.into()))
75+
}
76+
_ => TransactionKind::MixedTransfer(Some(data.into())),
77+
}
78+
}
79+
80+
pub fn transfer_to_ibc_tx_kind(
81+
data: Transfer,
82+
masp_address: &Address,
83+
ibc_data: IbcMessage<Transfer>,
84+
) -> TransactionKind {
85+
let has_shielded_section = data.shielded_section_hash.is_some();
86+
87+
let (all_sources_are_masp, any_sources_are_masp) = data
88+
.sources
89+
.iter()
90+
.fold((true, false), |(all, any), (acc, _)| {
91+
let is_masp = acc.owner.eq(masp_address);
92+
(all && is_masp, any || is_masp)
93+
});
94+
95+
let (all_targets_are_masp, any_targets_are_masp) = data
96+
.targets
97+
.iter()
98+
.fold((true, false), |(all, any), (acc, _)| {
99+
let is_masp = acc.owner.eq(masp_address);
100+
(all && is_masp, any || is_masp)
101+
});
102+
103+
match (
104+
all_sources_are_masp,
105+
any_sources_are_masp,
106+
all_targets_are_masp,
107+
any_targets_are_masp,
108+
has_shielded_section,
109+
) {
110+
(true, _, _, false, true) => TransactionKind::IbcUnshieldingTransfer((
111+
Some(ser::IbcMessage(ibc_data)),
112+
data.into(),
113+
)),
114+
(false, _, true, _, true) => TransactionKind::IbcShieldingTransfer((
115+
Some(ser::IbcMessage(ibc_data)),
116+
data.into(),
117+
)),
118+
(false, _, false, _, false) => TransactionKind::IbcTrasparentTransfer(
119+
(Some(ser::IbcMessage(ibc_data)), data.into()),
120+
),
121+
_ => TransactionKind::MixedTransfer(Some(data.into())),
122+
}
123+
}

0 commit comments

Comments
 (0)