Skip to content

Commit

Permalink
merge check4 two steps into one
Browse files Browse the repository at this point in the history
  • Loading branch information
jbesraa committed Aug 13, 2023
1 parent e26ad17 commit ac4f10a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 44 deletions.
31 changes: 16 additions & 15 deletions payjoin-cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,22 +291,23 @@ impl App {
log::trace!("check3");

// Receive Check 4: have we seen this input before? More of a check for non-interactive i.e. payment processor receivers.
let payjoin = proposal.check_no_inputs_seen_before(|input| {
Ok(!self.insert_input_seen_before(*input).map_err(|e| Error::Server(e.into()))?)
})?;
let mut provisional_payjoin = proposal.check_no_inputs_seen_before(
|input| {
Ok(!self.insert_input_seen_before(*input).map_err(|e| Error::Server(e.into()))?)
},
|output_script| {
if let Ok(address) = bitcoin::Address::from_script(output_script, network) {
self.bitcoind
.get_address_info(&address)
.map(|info| info.is_mine.unwrap_or(false))
.map_err(|e| Error::Server(e.into()))
} else {
Ok(false)
}
},
)?;
log::trace!("check4");

let mut provisional_payjoin = payjoin.identify_receiver_outputs(|output_script| {
if let Ok(address) = bitcoin::Address::from_script(output_script, network) {
self.bitcoind
.get_address_info(&address)
.map(|info| info.is_mine.unwrap_or(false))
.map_err(|e| Error::Server(e.into()))
} else {
Ok(false)
}
})?;

if !self.config.sub_only {
// Select receiver payjoin inputs.
_ = try_contributing_inputs(&mut provisional_payjoin, &self.bitcoind)
Expand All @@ -329,7 +330,7 @@ impl App {
None,
Some(false),
)
.map(|res| res.psbt)
.map(|res| Psbt::from_str(&res.psbt).unwrap())
.map_err(|e| Error::Server(e.into()))
},
Some(bitcoin::FeeRate::MIN),
Expand Down
32 changes: 17 additions & 15 deletions payjoin/src/receive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,8 @@ impl MaybeInputsSeen {
pub fn check_no_inputs_seen_before(
self,
is_known: impl Fn(&OutPoint) -> Result<bool, Error>,
) -> Result<OutputsUnknown, Error> {
is_receiver_output: impl Fn(&Script) -> Result<bool, Error>,
) -> Result<ProvisionalProposal, Error> {
self.psbt.input_pairs().try_for_each(|input| {
match is_known(&input.txin.previous_output) {
Ok(false) => Ok::<(), Error>(()),
Expand All @@ -504,8 +505,10 @@ impl MaybeInputsSeen {
Err(e) => Err(Error::Server(e.into()))?,
}
})?;
let provisional_payjoin = OutputsUnknown { psbt: self.psbt, params: self.params }
.identify_receiver_outputs(is_receiver_output)?;

Ok(OutputsUnknown { psbt: self.psbt, params: self.params })
Ok(provisional_payjoin)
}
}

Expand Down Expand Up @@ -813,16 +816,14 @@ impl ProvisionalProposal {

pub fn finalize_proposal(
mut self,
wallet_process_psbt: impl Fn(&Psbt) -> Result<std::string::String, Error>,
wallet_process_psbt: impl Fn(&Psbt) -> Result<Psbt, Error>,
min_feerate_sat_per_vb: Option<FeeRate>,
) -> Result<PayjoinProposal, RequestError> {
let psbt = self.apply_fee(min_feerate_sat_per_vb)?;
let psbt = wallet_process_psbt(psbt).map_err(|_| {
log::error!("wallet_process_psbt error");
InternalRequestError::PsbtFinalizingError
})?;
let psbt =
Psbt::from_str(&psbt.to_string()).map_err(InternalRequestError::PsbtParseError)?;
let payjoin_proposal = self.prepare_psbt(psbt).map_err(RequestError::from)?;
Ok(payjoin_proposal)
}
Expand Down Expand Up @@ -886,16 +887,17 @@ mod test {
.expect("No inputs should be owned")
.check_no_mixed_input_scripts()
.expect("No mixed input scripts")
.check_no_inputs_seen_before(|_| Ok(false))
.expect("No inputs should be seen before")
.identify_receiver_outputs(|script| {
let network = Network::Bitcoin;
Ok(Address::from_script(script, network)
== Address::from_str(&"3CZZi7aWFugaCdUCS15dgrUUViupmB8bVM")
.unwrap()
.require_network(network))
})
.expect("Receiver output should be identified");
.check_no_inputs_seen_before(
|_| Ok(false),
|script| {
let network = Network::Bitcoin;
Ok(Address::from_script(script, network)
== Address::from_str(&"3CZZi7aWFugaCdUCS15dgrUUViupmB8bVM")
.unwrap()
.require_network(network))
},
)
.unwrap();
let payjoin = payjoin.apply_fee(None);

assert!(payjoin.is_ok(), "Payjoin should be a valid PSBT");
Expand Down
32 changes: 18 additions & 14 deletions payjoin/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod integration {
use bitcoin::psbt::Psbt;
use bitcoin::{Amount, OutPoint};
use bitcoind::bitcoincore_rpc;
use bitcoind::bitcoincore_rpc::core_rpc_json::AddressType;
use bitcoind::bitcoincore_rpc::core_rpc_json::{AddressType, WalletProcessPsbtResult};
use bitcoind::bitcoincore_rpc::RpcApi;
use log::{debug, log_enabled, Level};
use payjoin::bitcoin::base64;
Expand Down Expand Up @@ -165,15 +165,16 @@ mod integration {

// Receive Check 4: have we seen this input before? More of a check for non-interactive i.e. payment processor receivers.
let mut payjoin = proposal
.check_no_inputs_seen_before(|_| Ok(false))
.unwrap()
.identify_receiver_outputs(|output_script| {
let address =
bitcoin::Address::from_script(&output_script, bitcoin::Network::Regtest)
.unwrap();
Ok(receiver.get_address_info(&address).unwrap().is_mine.unwrap())
})
.expect("Receiver should have at least one output");
.check_no_inputs_seen_before(
|_| Ok(false),
|output_script| {
let address =
bitcoin::Address::from_script(&output_script, bitcoin::Network::Regtest)
.unwrap();
Ok(receiver.get_address_info(&address).unwrap().is_mine.unwrap())
},
)
.unwrap();

// Select receiver payjoin inputs. TODO Lock them.
let available_inputs = receiver.list_unspent(None, None, None, None, None).unwrap();
Expand Down Expand Up @@ -203,17 +204,20 @@ mod integration {
let payjoin_proposal = payjoin
.finalize_proposal(
|psbt: &Psbt| {
receiver
Ok(receiver
.wallet_process_psbt(
&bitcoin::base64::encode(psbt.serialize()),
None,
None,
Some(false),
)
.map(|res| res.psbt)
.map_err(|e| Error::Server(e.into()))
.map(|res: WalletProcessPsbtResult| {
let psbt = Psbt::from_str(&res.psbt).unwrap();
return psbt;
})
.unwrap())
},
Some(1),
Some(bitcoin::FeeRate::MIN),
)
.unwrap();
let psbt = payjoin_proposal.get_payjoin_psbt();
Expand Down

0 comments on commit ac4f10a

Please sign in to comment.