Skip to content

Commit

Permalink
initial pass at implementing UIP-5: outbound PFM support
Browse files Browse the repository at this point in the history
  • Loading branch information
avahowell committed Nov 14, 2024
1 parent 31fca7e commit c15701e
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 1 deletion.
1 change: 1 addition & 0 deletions crates/bin/pcli/src/command/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,7 @@ impl TxCmd {
// TODO: impl From<u64> for ChannelId
source_channel: ChannelId::from_str(format!("channel-{}", channel).as_ref())?,
use_compat_address: *use_compat_address,
ics20_memo: "".to_string(),
};

let plan = Planner::new(OsRng)
Expand Down
Binary file modified crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs
Binary file not shown.
1 change: 1 addition & 0 deletions crates/core/app/tests/common/ibc_tests/relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,7 @@ impl MockRelayer {
source_channel: ChannelId::from_str("channel-0")?,
// Penumbra <-> Penumbra so false
use_compat_address: false,
ics20_memo: "".to_string(),
};
// There will need to be `Spend` and `Output` actions
// within the transaction in order for it to balance
Expand Down
9 changes: 8 additions & 1 deletion crates/core/component/shielded-pool/src/ics20_withdrawal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ pub struct Ics20Withdrawal {
// Whether to use a "compat" (bech32, non-m) address for the return address in the withdrawal,
// for compatability with chains that expect to be able to parse the return address as bech32.
pub use_compat_address: bool,

// Arbitrary string data to be included in the `memo` field
// of the ICS-20 FungibleTokenPacketData for this withdrawal.
// Commonly used for packet forwarding support, or other protocols that may support usage of the memo field.
pub ics20_memo: String,
}

#[cfg(feature = "component")]
Expand Down Expand Up @@ -118,6 +123,7 @@ impl From<Ics20Withdrawal> for pb::Ics20Withdrawal {
timeout_time: w.timeout_time,
source_channel: w.source_channel.to_string(),
use_compat_address: w.use_compat_address,
ics20_memo: w.ics20_memo.to_string(),
}
}
}
Expand Down Expand Up @@ -148,6 +154,7 @@ impl TryFrom<pb::Ics20Withdrawal> for Ics20Withdrawal {
timeout_time: s.timeout_time,
source_channel: ChannelId::from_str(&s.source_channel)?,
use_compat_address: s.use_compat_address,
ics20_memo: s.ics20_memo,
})
}
}
Expand All @@ -164,7 +171,7 @@ impl From<Ics20Withdrawal> for pb::FungibleTokenPacketData {
denom: w.denom.to_string(),
receiver: w.destination_chain_address,
sender: return_address,
memo: "".to_string(),
memo: w.ics20_memo,
}
}
}
5 changes: 5 additions & 0 deletions crates/proto/src/gen/penumbra.core.component.ibc.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ pub struct Ics20Withdrawal {
/// for compatability with chains that expect to be able to parse the return address as bech32.
#[prost(bool, tag = "8")]
pub use_compat_address: bool,
/// Arbitrary string data to be included in the `memo` field
/// of the ICS-20 FungibleTokenPacketData for this withdrawal.
/// Commonly used for packet forwarding support, or other protocols that may support usage of the memo field.
#[prost(string, tag = "9")]
pub ics20_memo: ::prost::alloc::string::String,
}
impl ::prost::Name for Ics20Withdrawal {
const NAME: &'static str = "Ics20Withdrawal";
Expand Down
18 changes: 18 additions & 0 deletions crates/proto/src/gen/penumbra.core.component.ibc.v1.serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,9 @@ impl serde::Serialize for Ics20Withdrawal {
if self.use_compat_address {
len += 1;
}
if !self.ics20_memo.is_empty() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("penumbra.core.component.ibc.v1.Ics20Withdrawal", len)?;
if let Some(v) = self.amount.as_ref() {
struct_ser.serialize_field("amount", v)?;
Expand All @@ -1083,6 +1086,9 @@ impl serde::Serialize for Ics20Withdrawal {
if self.use_compat_address {
struct_ser.serialize_field("useCompatAddress", &self.use_compat_address)?;
}
if !self.ics20_memo.is_empty() {
struct_ser.serialize_field("ics20Memo", &self.ics20_memo)?;
}
struct_ser.end()
}
}
Expand All @@ -1107,6 +1113,8 @@ impl<'de> serde::Deserialize<'de> for Ics20Withdrawal {
"sourceChannel",
"use_compat_address",
"useCompatAddress",
"ics20_memo",
"ics20Memo",
];

#[allow(clippy::enum_variant_names)]
Expand All @@ -1119,6 +1127,7 @@ impl<'de> serde::Deserialize<'de> for Ics20Withdrawal {
TimeoutTime,
SourceChannel,
UseCompatAddress,
Ics20Memo,
__SkipField__,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
Expand Down Expand Up @@ -1149,6 +1158,7 @@ impl<'de> serde::Deserialize<'de> for Ics20Withdrawal {
"timeoutTime" | "timeout_time" => Ok(GeneratedField::TimeoutTime),
"sourceChannel" | "source_channel" => Ok(GeneratedField::SourceChannel),
"useCompatAddress" | "use_compat_address" => Ok(GeneratedField::UseCompatAddress),
"ics20Memo" | "ics20_memo" => Ok(GeneratedField::Ics20Memo),
_ => Ok(GeneratedField::__SkipField__),
}
}
Expand Down Expand Up @@ -1176,6 +1186,7 @@ impl<'de> serde::Deserialize<'de> for Ics20Withdrawal {
let mut timeout_time__ = None;
let mut source_channel__ = None;
let mut use_compat_address__ = None;
let mut ics20_memo__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::Amount => {
Expand Down Expand Up @@ -1228,6 +1239,12 @@ impl<'de> serde::Deserialize<'de> for Ics20Withdrawal {
}
use_compat_address__ = Some(map_.next_value()?);
}
GeneratedField::Ics20Memo => {
if ics20_memo__.is_some() {
return Err(serde::de::Error::duplicate_field("ics20Memo"));
}
ics20_memo__ = Some(map_.next_value()?);
}
GeneratedField::__SkipField__ => {
let _ = map_.next_value::<serde::de::IgnoredAny>()?;
}
Expand All @@ -1242,6 +1259,7 @@ impl<'de> serde::Deserialize<'de> for Ics20Withdrawal {
timeout_time: timeout_time__.unwrap_or_default(),
source_channel: source_channel__.unwrap_or_default(),
use_compat_address: use_compat_address__.unwrap_or_default(),
ics20_memo: ics20_memo__.unwrap_or_default(),
})
}
}
Expand Down
Binary file modified crates/proto/src/gen/proto_descriptor.bin.no_lfs
Binary file not shown.
5 changes: 5 additions & 0 deletions proto/penumbra/penumbra/core/component/ibc/v1/ibc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ message Ics20Withdrawal {
// Whether to use a "compat" (bech32, non-m) address for the return address in the withdrawal,
// for compatability with chains that expect to be able to parse the return address as bech32.
bool use_compat_address = 8;

// Arbitrary string data to be included in the `memo` field
// of the ICS-20 FungibleTokenPacketData for this withdrawal.
// Commonly used for packet forwarding support, or other protocols that may support usage of the memo field.
string ics20_memo = 9;
}

message ClientData {
Expand Down

0 comments on commit c15701e

Please sign in to comment.