Skip to content

Commit 670b41a

Browse files
Merge pull request #2903 from jkczyz/2024-02-bindings-builders
Offers builders for C-bindings
2 parents 07059ec + 9277166 commit 670b41a

File tree

11 files changed

+1126
-476
lines changed

11 files changed

+1126
-476
lines changed

Diff for: fuzz/src/invoice_request_deser.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
use bitcoin::secp256k1::{KeyPair, Parity, PublicKey, Secp256k1, SecretKey, self};
1111
use crate::utils::test_logger;
12-
use core::convert::{Infallible, TryFrom};
12+
use core::convert::TryFrom;
1313
use lightning::blinded_path::BlindedPath;
1414
use lightning::sign::EntropySource;
1515
use lightning::ln::PaymentHash;
@@ -37,16 +37,16 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
3737
let even_pubkey = x_only_pubkey.public_key(Parity::Even);
3838
if signing_pubkey == odd_pubkey || signing_pubkey == even_pubkey {
3939
unsigned_invoice
40-
.sign::<_, Infallible>(
41-
|message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
40+
.sign(|message: &UnsignedBolt12Invoice|
41+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
4242
)
4343
.unwrap()
4444
.write(&mut buffer)
4545
.unwrap();
4646
} else {
4747
unsigned_invoice
48-
.sign::<_, Infallible>(
49-
|message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
48+
.sign(|message: &UnsignedBolt12Invoice|
49+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
5050
)
5151
.unwrap_err();
5252
}

Diff for: fuzz/src/offer_deser.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
1111
use crate::utils::test_logger;
12-
use core::convert::{Infallible, TryFrom};
12+
use core::convert::TryFrom;
1313
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
1414
use lightning::offers::offer::{Amount, Offer, Quantity};
1515
use lightning::offers::parse::Bolt12SemanticError;
@@ -29,8 +29,8 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
2929

3030
if let Ok(invoice_request) = build_response(&offer, pubkey) {
3131
invoice_request
32-
.sign::<_, Infallible>(
33-
|message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
32+
.sign(|message: &UnsignedInvoiceRequest|
33+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3434
)
3535
.unwrap()
3636
.write(&mut buffer)

Diff for: fuzz/src/refund_deser.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey, self};
1111
use crate::utils::test_logger;
12-
use core::convert::{Infallible, TryFrom};
12+
use core::convert::TryFrom;
1313
use lightning::blinded_path::BlindedPath;
1414
use lightning::sign::EntropySource;
1515
use lightning::ln::PaymentHash;
@@ -33,8 +33,8 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
3333

3434
if let Ok(invoice) = build_response(&refund, pubkey, &secp_ctx) {
3535
invoice
36-
.sign::<_, Infallible>(
37-
|message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
36+
.sign(|message: &UnsignedBolt12Invoice|
37+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3838
)
3939
.unwrap()
4040
.write(&mut buffer)

Diff for: lightning/src/crypto/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[cfg(not(fuzzing))]
12
use bitcoin::hashes::cmp::fixed_time_eq;
23

34
pub(crate) mod chacha20;

Diff for: lightning/src/ln/channelmanager.rs

+73-28
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
5858
use crate::ln::outbound_payment;
5959
use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, PaymentAttempts, PendingOutboundPayment, SendAlongPathArgs, StaleExpiration};
6060
use crate::ln::wire::Encode;
61-
use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, InvoiceBuilder};
61+
use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
6262
use crate::offers::invoice_error::InvoiceError;
63+
use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder};
6364
use crate::offers::merkle::SignError;
64-
use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
65+
use crate::offers::offer::{Offer, OfferBuilder};
6566
use crate::offers::parse::Bolt12SemanticError;
6667
use crate::offers::refund::{Refund, RefundBuilder};
6768
use crate::onion_message::messenger::{Destination, MessageRouter, PendingOnionMessage, new_pending_onion_message};
@@ -77,11 +78,17 @@ use crate::util::logger::{Level, Logger, WithContext};
7778
use crate::util::errors::APIError;
7879
#[cfg(not(c_bindings))]
7980
use {
81+
crate::offers::offer::DerivedMetadata,
8082
crate::routing::router::DefaultRouter,
8183
crate::routing::gossip::NetworkGraph,
8284
crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters},
8385
crate::sign::KeysManager,
8486
};
87+
#[cfg(c_bindings)]
88+
use {
89+
crate::offers::offer::OfferWithDerivedMetadataBuilder,
90+
crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder,
91+
};
8592

8693
use alloc::collections::{btree_map, BTreeMap};
8794

@@ -7633,7 +7640,9 @@ where
76337640
self.finish_close_channel(failure);
76347641
}
76357642
}
7643+
}
76367644

7645+
macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
76377646
/// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
76387647
/// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer. The offer will
76397648
/// not have an expiration unless otherwise set on the builder.
@@ -7662,23 +7671,25 @@ where
76627671
/// [`Offer`]: crate::offers::offer::Offer
76637672
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
76647673
pub fn create_offer_builder(
7665-
&self, description: String
7666-
) -> Result<OfferBuilder<DerivedMetadata, secp256k1::All>, Bolt12SemanticError> {
7667-
let node_id = self.get_our_node_id();
7668-
let expanded_key = &self.inbound_payment_key;
7669-
let entropy = &*self.entropy_source;
7670-
let secp_ctx = &self.secp_ctx;
7671-
7672-
let path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
7674+
&$self, description: String
7675+
) -> Result<$builder, Bolt12SemanticError> {
7676+
let node_id = $self.get_our_node_id();
7677+
let expanded_key = &$self.inbound_payment_key;
7678+
let entropy = &*$self.entropy_source;
7679+
let secp_ctx = &$self.secp_ctx;
7680+
7681+
let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
76737682
let builder = OfferBuilder::deriving_signing_pubkey(
76747683
description, node_id, expanded_key, entropy, secp_ctx
76757684
)
7676-
.chain_hash(self.chain_hash)
7685+
.chain_hash($self.chain_hash)
76777686
.path(path);
76787687

7679-
Ok(builder)
7688+
Ok(builder.into())
76807689
}
7690+
} }
76817691

7692+
macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
76827693
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
76837694
/// [`ChannelManager`] when handling [`Bolt12Invoice`] messages for the refund.
76847695
///
@@ -7728,31 +7739,53 @@ where
77287739
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
77297740
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
77307741
pub fn create_refund_builder(
7731-
&self, description: String, amount_msats: u64, absolute_expiry: Duration,
7742+
&$self, description: String, amount_msats: u64, absolute_expiry: Duration,
77327743
payment_id: PaymentId, retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>
7733-
) -> Result<RefundBuilder<secp256k1::All>, Bolt12SemanticError> {
7734-
let node_id = self.get_our_node_id();
7735-
let expanded_key = &self.inbound_payment_key;
7736-
let entropy = &*self.entropy_source;
7737-
let secp_ctx = &self.secp_ctx;
7744+
) -> Result<$builder, Bolt12SemanticError> {
7745+
let node_id = $self.get_our_node_id();
7746+
let expanded_key = &$self.inbound_payment_key;
7747+
let entropy = &*$self.entropy_source;
7748+
let secp_ctx = &$self.secp_ctx;
77387749

7739-
let path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
7750+
let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
77407751
let builder = RefundBuilder::deriving_payer_id(
77417752
description, node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
77427753
)?
7743-
.chain_hash(self.chain_hash)
7754+
.chain_hash($self.chain_hash)
77447755
.absolute_expiry(absolute_expiry)
77457756
.path(path);
77467757

77477758
let expiration = StaleExpiration::AbsoluteTimeout(absolute_expiry);
7748-
self.pending_outbound_payments
7759+
$self.pending_outbound_payments
77497760
.add_new_awaiting_invoice(
77507761
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
77517762
)
77527763
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
77537764

7754-
Ok(builder)
7765+
Ok(builder.into())
77557766
}
7767+
} }
7768+
7769+
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, L>
7770+
where
7771+
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
7772+
T::Target: BroadcasterInterface,
7773+
ES::Target: EntropySource,
7774+
NS::Target: NodeSigner,
7775+
SP::Target: SignerProvider,
7776+
F::Target: FeeEstimator,
7777+
R::Target: Router,
7778+
L::Target: Logger,
7779+
{
7780+
#[cfg(not(c_bindings))]
7781+
create_offer_builder!(self, OfferBuilder<DerivedMetadata, secp256k1::All>);
7782+
#[cfg(not(c_bindings))]
7783+
create_refund_builder!(self, RefundBuilder<secp256k1::All>);
7784+
7785+
#[cfg(c_bindings)]
7786+
create_offer_builder!(self, OfferWithDerivedMetadataBuilder);
7787+
#[cfg(c_bindings)]
7788+
create_refund_builder!(self, RefundMaybeWithDerivedMetadataBuilder);
77567789

77577790
/// Pays for an [`Offer`] using the given parameters by creating an [`InvoiceRequest`] and
77587791
/// enqueuing it to be sent via an onion message. [`ChannelManager`] will pay the actual
@@ -7816,9 +7849,11 @@ where
78167849
let entropy = &*self.entropy_source;
78177850
let secp_ctx = &self.secp_ctx;
78187851

7819-
let builder = offer
7852+
let builder: InvoiceRequestBuilder<DerivedPayerId, secp256k1::All> = offer
78207853
.request_invoice_deriving_payer_id(expanded_key, entropy, secp_ctx, payment_id)?
7821-
.chain_hash(self.chain_hash)?;
7854+
.into();
7855+
let builder = builder.chain_hash(self.chain_hash)?;
7856+
78227857
let builder = match quantity {
78237858
None => builder,
78247859
Some(quantity) => builder.quantity(quantity)?,
@@ -7912,6 +7947,7 @@ where
79127947
let builder = refund.respond_using_derived_keys_no_std(
79137948
payment_paths, payment_hash, created_at, expanded_key, entropy
79147949
)?;
7950+
let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
79157951
let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
79167952
let reply_path = self.create_blinded_path()
79177953
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
@@ -9424,6 +9460,8 @@ where
94249460
let builder = invoice_request.respond_using_derived_keys_no_std(
94259461
payment_paths, payment_hash, created_at
94269462
);
9463+
let builder: Result<InvoiceBuilder<DerivedSigningPubkey>, _> =
9464+
builder.map(|b| b.into());
94279465
match builder.and_then(|b| b.allow_mpp().build_and_sign(secp_ctx)) {
94289466
Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
94299467
Err(error) => Some(OffersMessage::InvoiceError(error.into())),
@@ -9435,18 +9473,25 @@ where
94359473
let builder = invoice_request.respond_with_no_std(
94369474
payment_paths, payment_hash, created_at
94379475
);
9476+
let builder: Result<InvoiceBuilder<ExplicitSigningPubkey>, _> =
9477+
builder.map(|b| b.into());
94389478
let response = builder.and_then(|builder| builder.allow_mpp().build())
94399479
.map_err(|e| OffersMessage::InvoiceError(e.into()))
9440-
.and_then(|invoice|
9441-
match invoice.sign(|invoice| self.node_signer.sign_bolt12_invoice(invoice)) {
9480+
.and_then(|invoice| {
9481+
#[cfg(c_bindings)]
9482+
let mut invoice = invoice;
9483+
match invoice.sign(|invoice: &UnsignedBolt12Invoice|
9484+
self.node_signer.sign_bolt12_invoice(invoice)
9485+
) {
94429486
Ok(invoice) => Ok(OffersMessage::Invoice(invoice)),
9443-
Err(SignError::Signing(())) => Err(OffersMessage::InvoiceError(
9487+
Err(SignError::Signing) => Err(OffersMessage::InvoiceError(
94449488
InvoiceError::from_string("Failed signing invoice".to_string())
94459489
)),
94469490
Err(SignError::Verification(_)) => Err(OffersMessage::InvoiceError(
94479491
InvoiceError::from_string("Failed invoice signature verification".to_string())
94489492
)),
9449-
});
9493+
}
9494+
});
94509495
match response {
94519496
Ok(invoice) => Some(invoice),
94529497
Err(error) => Some(error),

0 commit comments

Comments
 (0)