Skip to content

Commit

Permalink
Precaches ibc tokens instead of recomputing them from the packets
Browse files Browse the repository at this point in the history
  • Loading branch information
grarco committed Feb 14, 2025
1 parent 9f6f2de commit 367a5bd
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 105 deletions.
112 changes: 26 additions & 86 deletions shared/src/block.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::{BTreeMap, HashSet};
use std::str::FromStr;

use namada_ibc::apps::transfer::types::packet::PacketData;
use namada_ibc::core::channel::types::msgs::{MsgRecvPacket, PacketMsg};
use namada_ibc::core::handler::types::msgs::MsgEnvelope;
use namada_ibc::IbcMessage;
Expand All @@ -18,7 +17,6 @@ use crate::header::BlockHeader;
use crate::id::Id;
use crate::proposal::{GovernanceProposal, GovernanceProposalKind};
use crate::public_key::PublicKey;
use crate::ser;
use crate::token::{IbcToken, Token};
use crate::transaction::{
InnerTransaction, Transaction, TransactionExitStatus, TransactionKind,
Expand Down Expand Up @@ -532,36 +530,18 @@ impl Block {
&& tx.exit_code == TransactionExitStatus::Applied
})
.filter_map(|tx| match &tx.kind {
TransactionKind::IbcTrasparentTransfer((data, _))
| TransactionKind::IbcShieldingTransfer((data, _))
| TransactionKind::IbcUnshieldingTransfer((data, _)) => {
let data = Self::ibc_msg_recv_packet(data.0.to_owned())
.and_then(|msg| {
serde_json::from_slice::<PacketData>(
&msg.packet.data,
)
.map(|p| (msg, p))
.ok()
});

let (msg, packet_data) = data?;

let ibc_trace = format!(
"{}/{}/{}",
msg.packet.port_id_on_b,
msg.packet.chan_id_on_b,
packet_data.token.denom
);

let trace = Id::IbcTrace(ibc_trace.clone());
let address =
namada_ibc::trace::convert_to_address(ibc_trace)
.expect("Failed to convert IBC trace to address");
Some(IbcToken {
address: Id::from(address.clone()),
trace,
})
}
TransactionKind::IbcTrasparentTransfer((
Token::Ibc(ibc_token),
_,
))
| TransactionKind::IbcShieldingTransfer((
Token::Ibc(ibc_token),
_,
))
| TransactionKind::IbcUnshieldingTransfer((
Token::Ibc(ibc_token),
_,
)) => Some(ibc_token.to_owned()),
_ => None,
})
.collect()
Expand Down Expand Up @@ -620,12 +600,20 @@ impl Block {
})
.collect()
}
// FIXME: If data is only used here to extract the ibc token we should change it with the ibc token directly in TransactionKind
TransactionKind::IbcTrasparentTransfer((data, _))
| TransactionKind::IbcShieldingTransfer((data, _))
| TransactionKind::IbcUnshieldingTransfer((data, _)) => {
Self::parse_ibc_tx_balances(data, native_token)
.unwrap_or_default()
TransactionKind::IbcTrasparentTransfer((token, data))
| TransactionKind::IbcShieldingTransfer((token, data))
| TransactionKind::IbcUnshieldingTransfer((token, data)) => {
[&data.sources, &data.targets]
.iter()
.flat_map(|transfer_changes| {
transfer_changes.0.keys().map(|account| {
BalanceChange::new(
Id::from(account.owner.clone()),
token.to_owned(),
)
})
})
.collect()
}
TransactionKind::Bond(data) => {
let data = data.as_ref()?;
Expand Down Expand Up @@ -955,52 +943,4 @@ impl Block {
})
.collect()
}

fn parse_ibc_tx_balances(
data: &ser::IbcMessage<Transfer>,
native_token: &Id,
) -> Option<Vec<BalanceChange>> {
//FIXME: wrong, we should also check the other packets
let data =
Self::ibc_msg_recv_packet(data.0.to_owned()).and_then(|msg| {
serde_json::from_slice::<PacketData>(&msg.packet.data)
.map(|p| (msg, p))
.ok()
});

let (msg, packet_data) = data?;
let denom = packet_data.token.denom.to_string();

let ibc_trace = format!(
"{}/{}/{}",
msg.packet.port_id_on_b,
msg.packet.chan_id_on_b,
packet_data.token.denom
);

let trace = Id::IbcTrace(ibc_trace.clone());
let address = namada_ibc::trace::convert_to_address(ibc_trace)
.expect("Failed to convert IBC trace to address");

// FIXME: recheck this, I think it's wrong, why do we only care about the receiver?
let mut balances = vec![BalanceChange::new(
Id::Account(String::from(packet_data.receiver.as_ref())),
Token::Ibc(IbcToken {
address: Id::from(address.clone()),
trace,
}),
)];

// If the denom contains the namada native token, try to fetch
// the balance
//FIXME: why this? we can fetch the balance also of ibc tokens
//FIXME: we should just fix the usage of ibc token to check if it really is a foreign token or not
if denom.contains(&native_token.to_string()) {
balances.push(BalanceChange::new(
Id::Account(String::from(packet_data.receiver.as_ref())),
Token::Native(native_token.clone()),
))
}
Some(balances)
}
}
7 changes: 5 additions & 2 deletions shared/src/token.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use std::fmt::Display;

use serde::Serialize;

use crate::id::Id;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
pub struct IbcToken {
pub address: Id,
pub trace: Id,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
// FIXME: review all the usage of this, I believe it's wrong, we use it even when we are not sure that we are dealing with the native token
pub enum Token {
Ibc(IbcToken),
Native(Id),
Expand Down
6 changes: 3 additions & 3 deletions shared/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ pub enum TransactionKind {
MixedTransfer(Option<TransferData>),
/// Generic, non-transfer, IBC messages
IbcMsg(Option<IbcMessage<Transfer>>),
IbcTrasparentTransfer((IbcMessage<Transfer>, TransferData)),
IbcShieldingTransfer((IbcMessage<Transfer>, TransferData)),
IbcUnshieldingTransfer((IbcMessage<Transfer>, TransferData)),
IbcTrasparentTransfer((crate::token::Token, TransferData)),
IbcShieldingTransfer((crate::token::Token, TransferData)),
IbcUnshieldingTransfer((crate::token::Token, TransferData)),
Bond(Option<Bond>),
Redelegation(Option<Redelegation>),
Unbond(Option<Unbond>),
Expand Down
42 changes: 28 additions & 14 deletions shared/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,27 @@ pub fn transfer_to_ibc_tx_kind(
) = msg_envelope.as_ref()
{
// Extract transfer info from the packet
let transfer_data = match msg.packet.port_id_on_b.as_str() {
let (transfer_data, token_id) = match msg
.packet
.port_id_on_b
.as_str()
{
FT_PORT_ID_STR => {
let packet_data =
serde_json::from_slice::<FtPacketData>(
&msg.packet.data,
)
.expect("Could not deserialize IBC fungible token packet");

let (token, denominated_amount) = if packet_data
let (token, token_id, denominated_amount) = if packet_data
.token
.denom
.to_string()
.contains(&native_token.to_string())
{
(
native_token.clone(),
crate::token::Token::Native(native_token.into()),
namada_sdk::token::DenominatedAmount::native(
namada_sdk::token::Amount::from_str(
&packet_data.token.amount.to_string(),
Expand All @@ -130,13 +135,16 @@ pub fn transfer_to_ibc_tx_kind(
msg.packet.chan_id_on_b,
packet_data.token.denom
);
(
let token_address =
namada_ibc::trace::convert_to_address(
ibc_trace,
ibc_trace.clone(),
)
.expect(
"Failed to convert IBC trace to address",
),
);
(
token_address.clone(),
crate::token::Token::Ibc(crate::token::IbcToken { address: token_address.into(), trace: Id::IbcTrace(ibc_trace) }),
namada_sdk::token::DenominatedAmount::new(
namada_sdk::token::Amount::from_str(
&packet_data.token.amount.to_string(),
Expand All @@ -148,7 +156,7 @@ pub fn transfer_to_ibc_tx_kind(
)
};

TransferData {
(TransferData {
sources: crate::ser::AccountsMap(
[(
namada_sdk::token::Account {
Expand All @@ -170,7 +178,8 @@ pub fn transfer_to_ibc_tx_kind(
.into(),
),
shielded_section_hash: None,
}
},
token_id)
}
NFT_PORT_ID_STR => {
// TODO: add support for indexing nfts
Expand All @@ -191,12 +200,12 @@ pub fn transfer_to_ibc_tx_kind(
.is_some();
if is_shielding {
TransactionKind::IbcShieldingTransfer((
ser::IbcMessage(ibc_data),
token_id,
transfer_data,
))
} else {
TransactionKind::IbcTrasparentTransfer((
ser::IbcMessage(ibc_data),
token_id,
transfer_data,
))
}
Expand All @@ -205,7 +214,7 @@ pub fn transfer_to_ibc_tx_kind(
}
}
namada_ibc::IbcMessage::Transfer(transfer) => {
let (token, denominated_amount) = if transfer
let (token, token_id, denominated_amount) = if transfer
.message
.packet_data
.token
Expand All @@ -215,6 +224,7 @@ pub fn transfer_to_ibc_tx_kind(
{
(
native_token.clone(),
crate::token::Token::Native(native_token.into()),
namada_sdk::token::DenominatedAmount::native(
namada_sdk::token::Amount::from_str(
&transfer
Expand All @@ -237,9 +247,13 @@ pub fn transfer_to_ibc_tx_kind(
transfer.message.chan_id_on_a,
transfer.message.packet_data.token.denom
);
let token_address =
namada_ibc::trace::convert_to_address(ibc_trace.clone())
.expect("Failed to convert IBC trace to address");
(
namada_ibc::trace::convert_to_address(ibc_trace)
.expect("Failed to convert IBC trace to address"),
token_address.clone(),

crate::token::Token::Ibc(crate::token::IbcToken { address: token_address.into(), trace: Id::IbcTrace(ibc_trace) }),
namada_sdk::token::DenominatedAmount::new(
namada_sdk::token::Amount::from_str(
&transfer
Expand Down Expand Up @@ -292,12 +306,12 @@ pub fn transfer_to_ibc_tx_kind(

if transfer.transfer.is_some() {
TransactionKind::IbcUnshieldingTransfer((
ser::IbcMessage(ibc_data),
token_id,
transfer_data,
))
} else {
TransactionKind::IbcTrasparentTransfer((
ser::IbcMessage(ibc_data),
token_id,
transfer_data,
))
}
Expand Down

0 comments on commit 367a5bd

Please sign in to comment.