Skip to content

Commit 1af5c40

Browse files
committed
Macro-ize RefundBuilder
RefundBuilder is not exported to bindings because it has methods that take `self` by value. Define these methods using macros such that different builders and related methods can be defined for c_bindings.
1 parent d9ab2fa commit 1af5c40

File tree

1 file changed

+58
-43
lines changed

1 file changed

+58
-43
lines changed

lightning/src/offers/refund.rs

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub struct RefundBuilder<'a, T: secp256k1::Signing> {
124124
secp_ctx: Option<&'a Secp256k1<T>>,
125125
}
126126

127-
impl<'a> RefundBuilder<'a, secp256k1::SignOnly> {
127+
macro_rules! refund_without_secp256k1_builder_methods { () => {
128128
/// Creates a new builder for a refund using the [`Refund::payer_id`] for the public node id to
129129
/// send to if no [`Refund::paths`] are set. Otherwise, it may be a transient pubkey.
130130
///
@@ -155,9 +155,11 @@ impl<'a> RefundBuilder<'a, secp256k1::SignOnly> {
155155
secp_ctx: None,
156156
})
157157
}
158-
}
158+
} }
159159

160-
impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> {
160+
macro_rules! refund_builder_methods { (
161+
$self: ident, $self_type: ty, $return_type: ty, $return_value: expr
162+
) => {
161163
/// Similar to [`RefundBuilder::new`] except, if [`RefundBuilder::path`] is called, the payer id
162164
/// is derived from the given [`ExpandedKey`] and nonce. This provides sender privacy by using a
163165
/// different payer id for each refund, assuming a different nonce is used. Otherwise, the
@@ -197,44 +199,44 @@ impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> {
197199
/// already passed is valid and can be checked for using [`Refund::is_expired`].
198200
///
199201
/// Successive calls to this method will override the previous setting.
200-
pub fn absolute_expiry(mut self, absolute_expiry: Duration) -> Self {
201-
self.refund.absolute_expiry = Some(absolute_expiry);
202-
self
202+
pub fn absolute_expiry(mut $self: $self_type, absolute_expiry: Duration) -> $return_type {
203+
$self.refund.absolute_expiry = Some(absolute_expiry);
204+
$return_value
203205
}
204206

205207
/// Sets the [`Refund::issuer`].
206208
///
207209
/// Successive calls to this method will override the previous setting.
208-
pub fn issuer(mut self, issuer: String) -> Self {
209-
self.refund.issuer = Some(issuer);
210-
self
210+
pub fn issuer(mut $self: $self_type, issuer: String) -> $return_type {
211+
$self.refund.issuer = Some(issuer);
212+
$return_value
211213
}
212214

213215
/// Adds a blinded path to [`Refund::paths`]. Must include at least one path if only connected
214216
/// by private channels or if [`Refund::payer_id`] is not a public node id.
215217
///
216218
/// Successive calls to this method will add another blinded path. Caller is responsible for not
217219
/// adding duplicate paths.
218-
pub fn path(mut self, path: BlindedPath) -> Self {
219-
self.refund.paths.get_or_insert_with(Vec::new).push(path);
220-
self
220+
pub fn path(mut $self: $self_type, path: BlindedPath) -> $return_type {
221+
$self.refund.paths.get_or_insert_with(Vec::new).push(path);
222+
$return_value
221223
}
222224

223225
/// Sets the [`Refund::chain`] of the given [`Network`] for paying an invoice. If not
224226
/// called, [`Network::Bitcoin`] is assumed.
225227
///
226228
/// Successive calls to this method will override the previous setting.
227-
pub fn chain(self, network: Network) -> Self {
228-
self.chain_hash(ChainHash::using_genesis_block(network))
229+
pub fn chain($self: $self_type, network: Network) -> $return_type {
230+
$self.chain_hash(ChainHash::using_genesis_block(network))
229231
}
230232

231233
/// Sets the [`Refund::chain`] of the given [`ChainHash`] for paying an invoice. If not called,
232234
/// [`Network::Bitcoin`] is assumed.
233235
///
234236
/// Successive calls to this method will override the previous setting.
235-
pub(crate) fn chain_hash(mut self, chain: ChainHash) -> Self {
236-
self.refund.chain = Some(chain);
237-
self
237+
pub(crate) fn chain_hash(mut $self: $self_type, chain: ChainHash) -> $return_type {
238+
$self.refund.chain = Some(chain);
239+
$return_value
238240
}
239241

240242
/// Sets [`Refund::quantity`] of items. This is purely for informational purposes. It is useful
@@ -246,66 +248,79 @@ impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> {
246248
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
247249
/// [`InvoiceRequest::quantity`]: crate::offers::invoice_request::InvoiceRequest::quantity
248250
/// [`Offer`]: crate::offers::offer::Offer
249-
pub fn quantity(mut self, quantity: u64) -> Self {
250-
self.refund.quantity = Some(quantity);
251-
self
251+
pub fn quantity(mut $self: $self_type, quantity: u64) -> $return_type {
252+
$self.refund.quantity = Some(quantity);
253+
$return_value
252254
}
253255

254256
/// Sets the [`Refund::payer_note`].
255257
///
256258
/// Successive calls to this method will override the previous setting.
257-
pub fn payer_note(mut self, payer_note: String) -> Self {
258-
self.refund.payer_note = Some(payer_note);
259-
self
259+
pub fn payer_note(mut $self: $self_type, payer_note: String) -> $return_type {
260+
$self.refund.payer_note = Some(payer_note);
261+
$return_value
260262
}
261263

262264
/// Builds a [`Refund`] after checking for valid semantics.
263-
pub fn build(mut self) -> Result<Refund, Bolt12SemanticError> {
264-
if self.refund.chain() == self.refund.implied_chain() {
265-
self.refund.chain = None;
265+
pub fn build(mut $self: $self_type) -> Result<Refund, Bolt12SemanticError> {
266+
if $self.refund.chain() == $self.refund.implied_chain() {
267+
$self.refund.chain = None;
266268
}
267269

268270
// Create the metadata for stateless verification of a Bolt12Invoice.
269-
if self.refund.payer.0.has_derivation_material() {
270-
let mut metadata = core::mem::take(&mut self.refund.payer.0);
271+
if $self.refund.payer.0.has_derivation_material() {
272+
let mut metadata = core::mem::take(&mut $self.refund.payer.0);
271273

272-
if self.refund.paths.is_none() {
274+
if $self.refund.paths.is_none() {
273275
metadata = metadata.without_keys();
274276
}
275277

276-
let mut tlv_stream = self.refund.as_tlv_stream();
278+
let mut tlv_stream = $self.refund.as_tlv_stream();
277279
tlv_stream.0.metadata = None;
278280
if metadata.derives_payer_keys() {
279281
tlv_stream.2.payer_id = None;
280282
}
281283

282-
let (derived_metadata, keys) = metadata.derive_from(tlv_stream, self.secp_ctx);
284+
let (derived_metadata, keys) = metadata.derive_from(tlv_stream, $self.secp_ctx);
283285
metadata = derived_metadata;
284286
if let Some(keys) = keys {
285-
self.refund.payer_id = keys.public_key();
287+
$self.refund.payer_id = keys.public_key();
286288
}
287289

288-
self.refund.payer.0 = metadata;
290+
$self.refund.payer.0 = metadata;
289291
}
290292

291293
let mut bytes = Vec::new();
292-
self.refund.write(&mut bytes).unwrap();
294+
$self.refund.write(&mut bytes).unwrap();
293295

294-
Ok(Refund { bytes, contents: self.refund })
296+
Ok(Refund { bytes, contents: $self.refund })
295297
}
296-
}
298+
} }
297299

298300
#[cfg(test)]
299-
impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> {
300-
pub(crate) fn clear_paths(mut self) -> Self {
301-
self.refund.paths = None;
302-
self
301+
macro_rules! refund_builder_test_methods { (
302+
$self: ident, $self_type: ty, $return_type: ty, $return_value: expr
303+
) => {
304+
pub(crate) fn clear_paths(mut $self: $self_type) -> $return_type {
305+
$self.refund.paths = None;
306+
$return_value
303307
}
304308

305-
fn features_unchecked(mut self, features: InvoiceRequestFeatures) -> Self {
306-
self.refund.features = features;
307-
self
309+
fn features_unchecked(mut $self: $self_type, features: InvoiceRequestFeatures) -> $return_type {
310+
$self.refund.features = features;
311+
$return_value
308312
}
313+
} }
314+
315+
impl<'a> RefundBuilder<'a, secp256k1::SignOnly> {
316+
refund_without_secp256k1_builder_methods!();
317+
}
318+
319+
impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> {
320+
refund_builder_methods!(self, Self, Self, self);
321+
322+
#[cfg(test)]
323+
refund_builder_test_methods!(self, Self, Self, self);
309324
}
310325

311326
/// A `Refund` is a request to send an [`Bolt12Invoice`] without a preceding [`Offer`].

0 commit comments

Comments
 (0)