-
Notifications
You must be signed in to change notification settings - Fork 112
Refactor unified_qr.rs to use bitcoin-payment-instructions #607
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
base: main
Are you sure you want to change the base?
Refactor unified_qr.rs to use bitcoin-payment-instructions #607
Conversation
👋 Thanks for assigning @tnull as a reviewer! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, thanks! Did a first ~high-level round. Feel free to undraft this.
src/payment/unified.rs
Outdated
@@ -304,7 +304,7 @@ impl DeserializationError for Extras { | |||
#[cfg(test)] | |||
mod tests { | |||
use super::*; | |||
use crate::payment::unified_qr::Extras; | |||
use crate::payment::unified::Extras; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think we can just drop this line as the super::*
import above covers Extras
. Although, it would actually be preferable to switch to explicit import here, i.e., use super::{Extras, ...}
.
src/payment/unified.rs
Outdated
@@ -189,7 +189,7 @@ impl UnifiedQrPayment { | |||
/// [`PaymentId`]: lightning::ln::channelmanager::PaymentId | |||
/// [`Txid`]: bitcoin::hash_types::Txid | |||
#[derive(Debug)] | |||
pub enum QrPaymentResult { | |||
pub enum PaymentResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe UnifiedPaymentResult
then?
Cargo.toml
Outdated
@@ -91,6 +91,7 @@ log = { version = "0.4.22", default-features = false, features = ["std"]} | |||
|
|||
vss-client = "0.3" | |||
prost = { version = "0.11.6", default-features = false} | |||
bitcoin-payment-instructions = { git = "https://github.com/rust-bitcoin/bitcoin-payment-instructions" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, @TheBlueMatt, can we get a bitcoin-payment-instructions
release that includes rust-bitcoin/bitcoin-payment-instructions#6 ?
@chuksys In the meantime, please import a specific commit via rev = ".."
, as otherwise our builds might break as soon as bitcoin-payment-instructions
's main
changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! You should be able to reference bitcoin-payment-instructions
0.5 now.
src/builder.rs
Outdated
@@ -1633,6 +1635,14 @@ fn build_with_store_internal( | |||
let (stop_sender, _) = tokio::sync::watch::channel(()); | |||
let background_processor_task = Mutex::new(None); | |||
|
|||
let hrn_resolver = Arc::new(LDKOnionMessageDNSSECHrnResolver::new(network_graph.clone())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Please use Arc::clone(&..)
here and everywhere for Arc
s. This helps distinguishing that we in fact do not clone the actual value here.
src/payment/unified.rs
Outdated
amount::Amount as BPIAmount, PaymentInstructions, PaymentMethod, | ||
}; | ||
|
||
use crate::types::HRNResolver; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Let's move this up to the other crate::
imports.
tests/integration_tests_rust.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please include the test changes in the corresponding commit(s) that require them. Each commit should build and test individually, not just the whole PR.
src/payment/unified.rs
Outdated
pub async fn send( | ||
&self, uri_str: &str, amount_msat: Option<u64>, | ||
) -> Result<PaymentResult, Error> { | ||
let instructions = match PaymentInstructions::parse( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than match
ing, let's just use .map_err(|e| .. )?
, which should make this more readable and less vertical.
Also possible for ~most other match
es below.
src/payment/unified.rs
Outdated
return Err(Error::InvalidAmount); | ||
} | ||
}, | ||
PaymentInstructions::FixedAmount(ref instr) => instr.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we at least check that the amount_msat
(if provided) is greater or equal to the fixed amount?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a rebase by now, also.
05a948e
to
b4a71f6
Compare
🔔 1st Reminder Hey @tnull! This PR has been waiting for your review. |
🔔 2nd Reminder Hey @tnull! This PR has been waiting for your review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR.
I have reviewed this and approve of the refactor. I just have a small note about per-commit compilation and testing where, because of a function signature mismatch between UnifiedPayment
's send
and the bindings-exposed definition, the corresponding commit (16fbedc) that introduced the change failed to compile. In the same vein, albeit not as important, in 7c1a2db, with warnings
enabled, compilation fails because of the unused hrn_resolver
.
Otherwise, this LGTM and I'd be happy to approve this when these are addressed.
src/payment/unified.rs
Outdated
@@ -139,7 +139,7 @@ impl UnifiedQrPayment { | |||
/// occurs, an `Error` is returned detailing the issue encountered. | |||
/// | |||
/// [BIP 21]: https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki | |||
pub fn send(&self, uri_str: &str) -> Result<QrPaymentResult, Error> { | |||
pub fn send(&self, uri_str: &str) -> Result<UnifiedPaymentResult, Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 16fbedcc, there's a function signature mismatch between send
and its bindings-exposed definition. The latter is async
and has an optional amount_msat
parameter. The commit does not compile because of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @enigbe for the review - I have fixed this.
🔔 3rd Reminder Hey @tnull! This PR has been waiting for your review. |
🔔 4th Reminder Hey @tnull! This PR has been waiting for your review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excuse the delay here!
Some comments, but generally looks pretty good as a first step (can't wait for end-to-end tests for the resolution though).
This is also still dependant on a release of bitcoin-payment-instructions
, which, as I hear, should happen really soon though.
src/payment/unified.rs
Outdated
uri_str, | ||
self.config.network, | ||
self.hrn_resolver.as_ref(), | ||
true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We set supports_proof_of_payment_callbacks
to true
here, but never actually handle the callback. This seems like an omission?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change this to false
for now.
src/payment/unified.rs
Outdated
Error::InvalidAmount | ||
})?; | ||
|
||
let amt = BPIAmount::from_sats(amount).map_err(|e| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we keep the msat
resolution here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! We should use BPIAmount::from_milli_sats
instead - will fix. Thanks for catching that!
src/payment/unified.rs
Outdated
Error::InvalidAmount | ||
})?; | ||
|
||
instr.clone().set_amount(amt, self.hrn_resolver.as_ref()).await.map_err(|e| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can easily avoid these clones
by not taking a ref
:
diff --git a/src/payment/unified.rs b/src/payment/unified.rs
index 68eb55e5..c9f26ee9 100644
--- a/src/payment/unified.rs
+++ b/src/payment/unified.rs
@@ -168,7 +168,7 @@ impl UnifiedPayment {
})?;
let resolved = match instructions {
- PaymentInstructions::ConfigurableAmount(ref instr) => {
+ PaymentInstructions::ConfigurableAmount(instr) => {
let amount = amount_msat.ok_or_else(|| {
log_error!(self.logger, "No amount specified. Aborting the payment.");
Error::InvalidAmount
@@ -179,13 +179,12 @@ impl UnifiedPayment {
Error::InvalidAmount
})?;
- instr.clone().set_amount(amt, self.hrn_resolver.as_ref()).await.map_err(|e| {
+ instr.set_amount(amt, self.hrn_resolver.as_ref()).await.map_err(|e| {
log_error!(self.logger, "Failed to set amount: {:?}", e);
Error::InvalidAmount
})?
},
- PaymentInstructions::FixedAmount(ref instr) => {
- let instr = instr.clone();
+ PaymentInstructions::FixedAmount(instr) => {
if let Some(user_amount) = amount_msat {
if instr.ln_payment_amount().map_or(false, |amt| user_amount < amt.milli_sats())
{
src/payment/unified.rs
Outdated
PaymentInstructions::FixedAmount(ref instr) => { | ||
let instr = instr.clone(); | ||
if let Some(user_amount) = amount_msat { | ||
if instr.ln_payment_amount().map_or(false, |amt| user_amount < amt.milli_sats()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We likely want to compare with max_amount
rather than the LN-specific one, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, comparing with max_amount
makes more sense! Thanks!
src/payment/unified.rs
Outdated
{ | ||
let offer = maybe_wrap(offer.clone()); | ||
let payment_result = if let Some(amount_msat) = amount_msat { | ||
self.bolt12_payment.send_using_amount(&offer, amount_msat, None, None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please indent by tabs, not spaces. (Not sure how this got past rustfmt
tbh.)
src/payment/unified.rs
Outdated
})?; | ||
|
||
let txid = | ||
self.onchain_payment.send_to_address(&address, amount.sats().unwrap(), None)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be a bug if this ever failed, but please still simply error out if amount.sats()
returns an error.
Thank you! Currently working on the end-to-end test - will open the PR for that asap. |
This rename reflects that this module is a unified payment interface for both QR code payments and HRN payments passed in as a string without scanning a QR code
…UnifiedPaymentResult These renamings are necessary to reflect the expanded responsibilities for this module.
This commit adds a HRN Resolver to the Node struct which will be useful for resolving HRNs when making BIP 353 payments. It also passes the HRN Resolver into UnifiedPayment.
b4a71f6
to
38e17d1
Compare
This PR introduces a
unified.rs
module (which is a refactor of theunified_qr.rs
module) - this refactor allows us to use this module as a single API for sending payments toBIP 21/321 URIs
as well asBIP 353 HRNs
, creating a simpler interface for users.https://github.com/rust-bitcoin/bitcoin-payment-instructions is used to parse
BIP 21/321 URIs
as well as theBIP 353 HRNs
.Changes
unified_qr.rs
module has been renamed tounified.rs.
UnifiedQrPayment
struct has been renamed toUnifiedPayment
.QRPaymentResult
enum has been renamed toUnifiedPaymentResult
.send
method inunified.rs
now supports sending to bothBIP 21/321 URIs
as well asBIP 353 HRNs
.I will follow-up with adding an end-to-end test that asserts that sending to HRNs using this API works.
This PR closes #521