Skip to content

Commit

Permalink
Populate additional Swap fields for Opaque variants
Browse files Browse the repository at this point in the history
  • Loading branch information
aubrika committed Apr 11, 2024
1 parent 10723ed commit b288996
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 7 deletions.
2 changes: 1 addition & 1 deletion crates/bin/pcli/src/transaction_view_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ impl TransactionViewExt for TransactionView {

["Swap", &action]
}
SwapView::Opaque { swap } => {
SwapView::Opaque { swap, .. } => {
action = format!(
"Opaque swap for trading pair: {} <=> {}",
format_asset_id(&swap.body.trading_pair.asset_1()),
Expand Down
31 changes: 28 additions & 3 deletions crates/core/component/dex/src/swap/view.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use penumbra_asset::asset::Metadata;
use penumbra_asset::{asset::Metadata, ValueView};
use penumbra_proto::{penumbra::core::component::dex::v1 as pb, DomainType};
use penumbra_shielded_pool::NoteView;
use penumbra_txhash::TransactionId;
Expand All @@ -24,6 +24,11 @@ pub enum SwapView {
},
Opaque {
swap: Swap,
batch_swap_output_data: Option<BatchSwapOutputData>,
output_1: Option<ValueView>,
output_2: Option<ValueView>,
asset_1_metadata: Option<Metadata>,
asset_2_metadata: Option<Metadata>,
},
}

Expand Down Expand Up @@ -63,6 +68,14 @@ impl TryFrom<pb::SwapView> for SwapView {
.swap
.ok_or_else(|| anyhow::anyhow!("missing swap field"))?
.try_into()?,
batch_swap_output_data: x
.batch_swap_output_data
.map(TryInto::try_into)
.transpose()?,
output_1: x.output_1_value.map(TryInto::try_into).transpose()?,
output_2: x.output_2_value.map(TryInto::try_into).transpose()?,
asset_1_metadata: x.asset_1_metadata.map(TryInto::try_into).transpose()?,
asset_2_metadata: x.asset_2_metadata.map(TryInto::try_into).transpose()?,
}),
}
}
Expand Down Expand Up @@ -93,9 +106,21 @@ impl From<SwapView> for pb::SwapView {
batch_swap_output_data: batch_swap_output_data.map(Into::into),
})),
},
SwapView::Opaque { swap } => Self {
SwapView::Opaque {
swap,
batch_swap_output_data,
output_1,
output_2,
asset_1_metadata,
asset_2_metadata,
} => Self {
swap_view: Some(sv::SwapView::Opaque(sv::Opaque {
swap: Some(swap.into()),
batch_swap_output_data: batch_swap_output_data.map(Into::into),
output_1_value: output_1.map(Into::into),
output_2_value: output_2.map(Into::into),
asset_1_metadata: asset_1_metadata.map(Into::into),
asset_2_metadata: asset_2_metadata.map(Into::into),
})),
},
}
Expand All @@ -106,7 +131,7 @@ impl From<SwapView> for Swap {
fn from(v: SwapView) -> Self {
match v {
SwapView::Visible { swap, .. } => swap,
SwapView::Opaque { swap } => swap,
SwapView::Opaque { swap, .. } => swap,
}
}
}
62 changes: 59 additions & 3 deletions crates/core/transaction/src/is_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,65 @@ impl IsAction for Swap {
.cloned(),
}
}
None => SwapView::Opaque {
swap: self.to_owned(),
},
None => {
// If we can find a matching BSOD in the TxP, we can use it to compute the output notes
// for the swap.
let bsod = txp
.batch_swap_output_data
.iter()
// This finds the first matching one; there should only be one
// per trading pair per block and we trust the TxP provider not to lie about it.
.find(|bsod| bsod.trading_pair == self.body.trading_pair);

// We can get the denom metadata whether we get a BSOD or not

let denom_1 = txp.denoms.get(&self.body.trading_pair.asset_1()).cloned();
let denom_2 = txp.denoms.get(&self.body.trading_pair.asset_2()).cloned();

match bsod {
None => {
// If we can't find a matching BSOD, we can't compute the output notes
// for the swap.
// TODO: is defaulting to 'None' the right behavior here, or is not matching on a BSOD as above an error?
SwapView::Opaque {
swap: self.to_owned(),
batch_swap_output_data: None,
output_1: None,
output_2: None,
asset_1_metadata: denom_1.clone(),
asset_2_metadata: denom_2.clone(),
}
}
Some(bsod) => {
// If we can find a matching BSOD, use it to compute the output notes
// for the swap.

let (lambda_1_i, lambda_2_i) =
bsod.pro_rata_outputs((self.body.delta_1_i, self.body.delta_2_i));

SwapView::Opaque {
swap: self.to_owned(),
batch_swap_output_data: Some(bsod.clone()),
asset_1_metadata: denom_1.clone(),
asset_2_metadata: denom_2.clone(),
output_1: Some(
Value {
amount: lambda_1_i,
asset_id: self.body.trading_pair.asset_1(),
}
.view_with_cache(&txp.denoms),
),
output_2: Some(
Value {
amount: lambda_2_i,
asset_id: self.body.trading_pair.asset_2(),
}
.view_with_cache(&txp.denoms),
),
}
}
}
}
})
}
}
Expand Down

0 comments on commit b288996

Please sign in to comment.