-
Notifications
You must be signed in to change notification settings - Fork 79
Tx cut-through #332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tx cut-through #332
Changes from all commits
b5dae4e
4325e93
4062b56
5f9ca53
d629598
b737500
f4f2f37
ab9b8b8
59c3d27
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,12 @@ | ||
| use std::collections::HashMap; | ||
| use std::str::FromStr; | ||
| use std::sync::Arc; | ||
|
|
||
| use anyhow::{anyhow, Context, Result}; | ||
| use bitcoincore_rpc::RpcApi; | ||
| use payjoin::bitcoin::consensus::encode::serialize_hex; | ||
| use payjoin::bitcoin::psbt::Psbt; | ||
| use payjoin::bitcoin::Amount; | ||
| use payjoin::bitcoin::{Amount, FeeRate}; | ||
| use payjoin::receive::v2::ActiveSession; | ||
| use payjoin::send::RequestContext; | ||
| use payjoin::{bitcoin, Error, Uri}; | ||
|
|
@@ -272,8 +273,6 @@ impl App { | |
| &self, | ||
| proposal: payjoin::receive::v2::UncheckedProposal, | ||
| ) -> Result<payjoin::receive::v2::PayjoinProposal, Error> { | ||
| use crate::app::try_contributing_inputs; | ||
|
|
||
| let bitcoind = self.bitcoind().map_err(|e| Error::Server(e.into()))?; | ||
|
|
||
| // in a payment processor where the sender could go offline, this is where you schedule to broadcast the original_tx | ||
|
|
@@ -317,19 +316,24 @@ impl App { | |
| })?; | ||
| log::trace!("check4"); | ||
|
|
||
| let mut provisional_payjoin = payjoin.identify_receiver_outputs(|output_script| { | ||
| if let Ok(address) = bitcoin::Address::from_script(output_script, network) { | ||
| bitcoind | ||
| .get_address_info(&address) | ||
| .map(|info| info.is_mine.unwrap_or(false)) | ||
| .map_err(|e| Error::Server(e.into())) | ||
| } else { | ||
| Ok(false) | ||
| } | ||
| })?; | ||
| let payjoin = payjoin | ||
| .identify_receiver_outputs(|output_script| { | ||
| if let Ok(address) = bitcoin::Address::from_script(output_script, network) { | ||
| bitcoind | ||
| .get_address_info(&address) | ||
| .map(|info| info.is_mine.unwrap_or(false)) | ||
| .map_err(|e| Error::Server(e.into())) | ||
| } else { | ||
| Ok(false) | ||
| } | ||
| })? | ||
| .commit_outputs(); | ||
|
|
||
| _ = try_contributing_inputs(&mut provisional_payjoin.inner, &bitcoind) | ||
| .map_err(|e| log::warn!("Failed to contribute inputs: {}", e)); | ||
| let provisional_payjoin = try_contributing_inputs(payjoin.clone(), &bitcoind) | ||
| .unwrap_or_else(|e| { | ||
| log::warn!("Failed to contribute inputs: {}", e); | ||
| payjoin.commit_inputs() | ||
| }); | ||
|
|
||
| let payjoin_proposal = provisional_payjoin.finalize_proposal( | ||
| |psbt: &Psbt| { | ||
|
|
@@ -339,13 +343,47 @@ impl App { | |
| .map_err(|e| Error::Server(e.into()))? | ||
| }, | ||
| Some(bitcoin::FeeRate::MIN), | ||
| self.config.max_fee_rate.map_or(Ok(FeeRate::ZERO), |fee_rate| { | ||
| FeeRate::from_sat_per_vb(fee_rate).ok_or(Error::Server("Invalid fee rate".into())) | ||
| })?, | ||
|
Comment on lines
+346
to
+348
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Raather than fail here with a
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It only fails if fwiw i added a docstring to that effect in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I misunderstood (apply_fee is sooo uncomplicated /s) But I guess that was default behavior from before so it makes sense as a default |
||
| )?; | ||
| let payjoin_proposal_psbt = payjoin_proposal.psbt(); | ||
| log::debug!("Receiver's Payjoin proposal PSBT Rsponse: {:#?}", payjoin_proposal_psbt); | ||
| Ok(payjoin_proposal) | ||
| } | ||
| } | ||
|
|
||
| fn try_contributing_inputs( | ||
| payjoin: payjoin::receive::v2::WantsInputs, | ||
| bitcoind: &bitcoincore_rpc::Client, | ||
| ) -> Result<payjoin::receive::v2::ProvisionalProposal> { | ||
| use bitcoin::OutPoint; | ||
|
|
||
| let available_inputs = bitcoind | ||
| .list_unspent(None, None, None, None, None) | ||
| .context("Failed to list unspent from bitcoind")?; | ||
| let candidate_inputs: HashMap<Amount, OutPoint> = available_inputs | ||
| .iter() | ||
| .map(|i| (i.amount, OutPoint { txid: i.txid, vout: i.vout })) | ||
| .collect(); | ||
|
|
||
| let selected_outpoint = payjoin.try_preserving_privacy(candidate_inputs).expect("gg"); | ||
| let selected_utxo = available_inputs | ||
| .iter() | ||
| .find(|i| i.txid == selected_outpoint.txid && i.vout == selected_outpoint.vout) | ||
| .context("This shouldn't happen. Failed to retrieve the privacy preserving utxo from those we provided to the seclector.")?; | ||
| log::debug!("selected utxo: {:#?}", selected_utxo); | ||
| let txo_to_contribute = bitcoin::TxOut { | ||
| value: selected_utxo.amount, | ||
| script_pubkey: selected_utxo.script_pub_key.clone(), | ||
| }; | ||
|
|
||
| Ok(payjoin | ||
| .contribute_witness_inputs(vec![(selected_outpoint, txo_to_contribute)]) | ||
| .expect("This shouldn't happen. Failed to contribute inputs.") | ||
| .commit_inputs()) | ||
| } | ||
|
|
||
| async fn unwrap_ohttp_keys_or_else_fetch(config: &AppConfig) -> Result<payjoin::OhttpKeys> { | ||
| if let Some(keys) = config.ohttp_keys.clone() { | ||
| println!("Using OHTTP Keys from config"); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.