Skip to content

Commit 01af6ed

Browse files
committed
NIH the delegate macro
1 parent 4017a48 commit 01af6ed

File tree

3 files changed

+131
-142
lines changed

3 files changed

+131
-142
lines changed

lightning/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"]
1717

1818
[features]
1919
# Internal test utilities exposed to other repo crates
20-
_test_utils = ["regex", "bitcoin/bitcoinconsensus", "lightning-types/_test_utils", "delegate"]
20+
_test_utils = ["regex", "bitcoin/bitcoinconsensus", "lightning-types/_test_utils"]
2121
_externalize_tests = ["inventory", "_test_utils"]
2222
# Allow signing of local transactions that may have been revoked or will be revoked, for functional testing (e.g. justice tx handling).
2323
# This is unsafe to use in production because it may result in the counterparty publishing taking our funds.
@@ -48,14 +48,12 @@ regex = { version = "1.5.6", optional = true }
4848
backtrace = { version = "0.3", optional = true }
4949

5050
libm = { version = "0.2", default-features = false }
51-
delegate = { version = "0.13.1", optional = true }
5251
inventory = { version = "0.3", optional = true }
5352

5453
[dev-dependencies]
5554
regex = "1.5.6"
5655
lightning-types = { version = "0.3.0", path = "../lightning-types", features = ["_test_utils"] }
5756
lightning-macros = { path = "../lightning-macros" }
58-
delegate = { version = "0.13.1" }
5957

6058
[dev-dependencies.bitcoin]
6159
version = "0.32.2"

lightning/src/util/dyn_signer.rs

Lines changed: 93 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
use crate::prelude::*;
44

55
use core::any::Any;
6-
use delegate::delegate;
76

87
use crate::chain::transaction::OutPoint;
8+
use crate::delegate;
99
use crate::io::Read;
1010
use crate::ln::chan_utils::{
1111
ChannelPublicKeys, ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
@@ -256,44 +256,30 @@ impl EcdsaChannelSigner for DynSigner {
256256
}
257257
}
258258

259-
impl ChannelSignerExt for DynSigner {
260-
delegate! {
261-
to self.inner {
262-
fn commitment_seed(&self) -> [u8; 32];
263-
fn channel_type_features(&self) -> Option<&ChannelTypeFeatures>;
264-
fn counterparty_pubkeys(&self) -> Option<&ChannelPublicKeys>;
265-
fn funding_outpoint(&self) -> Option<&OutPoint>;
266-
fn get_channel_parameters(&self) -> Option<&ChannelTransactionParameters>;
267-
}
268-
}
269-
}
270-
271-
impl ChannelSigner for DynSigner {
272-
delegate! {
273-
to self.inner {
274-
fn get_per_commitment_point(
275-
&self,
276-
idx: u64,
277-
secp_ctx: &Secp256k1<secp256k1::All>,
278-
) -> Result<PublicKey, ()>;
279-
fn release_commitment_secret(&self, idx: u64) -> Result<[u8; 32], ()>;
280-
281-
fn validate_holder_commitment(
282-
&self,
283-
holder_tx: &HolderCommitmentTransaction,
284-
preimages: Vec<PaymentPreimage>,
285-
) -> Result<(), ()>;
286-
287-
fn pubkeys(&self) -> &ChannelPublicKeys;
288-
289-
fn channel_keys_id(&self) -> [u8; 32];
290-
291-
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
292-
293-
fn validate_counterparty_revocation(&self, idx: u64, secret: &SecretKey) -> Result<(), ()>;
294-
}
295-
}
296-
}
259+
delegate!(DynSigner, ChannelSignerExt,
260+
inner,
261+
fn commitment_seed(,) -> [u8; 32],
262+
fn channel_type_features(,) -> Option<&ChannelTypeFeatures>,
263+
fn counterparty_pubkeys(,) -> Option<&ChannelPublicKeys>,
264+
fn funding_outpoint(,) -> Option<&OutPoint>,
265+
fn get_channel_parameters(,) -> Option<&ChannelTransactionParameters>);
266+
267+
delegate!(DynSigner, ChannelSigner,
268+
inner,
269+
fn get_per_commitment_point(,
270+
idx: u64,
271+
secp_ctx: &Secp256k1<secp256k1::All>
272+
) -> Result<PublicKey, ()>,
273+
fn release_commitment_secret(, idx: u64) -> Result<[u8; 32], ()>,
274+
fn validate_holder_commitment(,
275+
holder_tx: &HolderCommitmentTransaction,
276+
preimages: Vec<PaymentPreimage>
277+
) -> Result<(), ()>,
278+
fn pubkeys(,) -> &ChannelPublicKeys,
279+
fn channel_keys_id(,) -> [u8; 32],
280+
fn validate_counterparty_revocation(, idx: u64, secret: &SecretKey) -> Result<(), ()>,
281+
fn provide_channel_parameters(mut, channel_parameters: &ChannelTransactionParameters) -> ()
282+
);
297283

298284
impl DynSignerTrait for InMemorySigner {}
299285

@@ -320,64 +306,41 @@ impl DynKeysInterface {
320306
}
321307
}
322308

323-
impl NodeSigner for DynKeysInterface {
324-
delegate! {
325-
to self.inner {
326-
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()>;
327-
fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()>;
328-
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>;
329-
330-
fn sign_invoice(&self, invoice: &RawBolt11Invoice, recipient: Recipient) -> Result<RecoverableSignature, ()>;
331-
332-
fn sign_bolt12_invoice(
333-
&self, invoice: &crate::offers::invoice::UnsignedBolt12Invoice
334-
) -> Result<secp256k1::schnorr::Signature, ()>;
335-
336-
fn get_inbound_payment_key(&self) -> ExpandedKey;
337-
}
338-
}
339-
}
340-
341-
impl SignerProvider for DynKeysInterface {
342-
type EcdsaSigner = DynSigner;
309+
delegate!(DynKeysInterface, NodeSigner,
310+
inner,
311+
fn get_node_id(, recipient: Recipient) -> Result<PublicKey, ()>,
312+
fn sign_gossip_message(, msg: UnsignedGossipMessage) -> Result<Signature, ()>,
313+
fn ecdh(, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>,
314+
fn sign_invoice(, invoice: &RawBolt11Invoice, recipient: Recipient) -> Result<RecoverableSignature, ()>,
315+
fn sign_bolt12_invoice(,
316+
invoice: &crate::offers::invoice::UnsignedBolt12Invoice
317+
) -> Result<secp256k1::schnorr::Signature, ()>,
318+
fn get_inbound_payment_key(,) -> ExpandedKey
319+
);
320+
321+
delegate!(DynKeysInterface, SignerProvider,
322+
inner,
323+
fn get_destination_script(, channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()>,
324+
fn get_shutdown_scriptpubkey(,) -> Result<ShutdownScript, ()>,
325+
fn generate_channel_keys_id(, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32],
326+
fn derive_channel_signer(, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner,
327+
fn read_chan_signer(, reader: &[u8]) -> Result<Self::EcdsaSigner, DecodeError>;
328+
type EcdsaSigner = DynSigner,
343329
#[cfg(taproot)]
344-
type TaprootSigner = DynSigner;
345-
346-
delegate! {
347-
to self.inner {
348-
fn get_destination_script(&self, channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()>;
349-
350-
fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()>;
351-
352-
fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32];
353-
354-
fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner;
355-
356-
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::EcdsaSigner, DecodeError>;
357-
}
358-
}
359-
}
360-
361-
impl EntropySource for DynKeysInterface {
362-
delegate! {
363-
to self.inner {
364-
fn get_secure_random_bytes(&self) -> [u8; 32];
365-
}
366-
}
367-
}
368-
369-
impl OutputSpender for DynKeysInterface {
370-
delegate! {
371-
to self.inner {
372-
fn spend_spendable_outputs(
373-
&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>,
374-
change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32,
375-
locktime: Option<LockTime>, secp_ctx: &Secp256k1<All>,
376-
) -> Result<Transaction, ()>;
377-
}
378-
}
379-
}
380-
330+
type TaprootSigner = DynSigner
331+
);
332+
333+
delegate!(DynKeysInterface, EntropySource, inner,
334+
fn get_secure_random_bytes(,) -> [u8; 32]
335+
);
336+
337+
delegate!(DynKeysInterface, OutputSpender, inner,
338+
fn spend_spendable_outputs(,
339+
descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>,
340+
change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32,
341+
locktime: Option<LockTime>, secp_ctx: &Secp256k1<All>
342+
) -> Result<Transaction, ()>
343+
);
381344
#[cfg(not(taproot))]
382345
/// A supertrait for all the traits that a keys interface implements
383346
pub trait DynKeysInterfaceTrait:
@@ -413,36 +376,34 @@ impl DynPhantomKeysInterface {
413376
}
414377
}
415378

416-
impl NodeSigner for DynPhantomKeysInterface {
417-
delegate! {
418-
to self.inner {
419-
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()>;
420-
fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()>;
421-
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>;
422-
423-
fn sign_invoice(&self, invoice: &RawBolt11Invoice, recipient: Recipient) -> Result<RecoverableSignature, ()>;
424-
425-
fn sign_bolt12_invoice(
426-
&self, invoice: &crate::offers::invoice::UnsignedBolt12Invoice
427-
) -> Result<secp256k1::schnorr::Signature, ()>;
428-
fn get_inbound_payment_key(&self) -> ExpandedKey;
429-
}
430-
}
431-
}
379+
delegate!(DynPhantomKeysInterface, NodeSigner,
380+
inner,
381+
fn get_node_id(, recipient: Recipient) -> Result<PublicKey, ()>,
382+
fn sign_gossip_message(, msg: UnsignedGossipMessage) -> Result<Signature, ()>,
383+
fn ecdh(, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>,
384+
fn sign_invoice(, invoice: &RawBolt11Invoice, recipient: Recipient) -> Result<RecoverableSignature, ()>,
385+
fn sign_bolt12_invoice(, invoice: &crate::offers::invoice::UnsignedBolt12Invoice
386+
) -> Result<secp256k1::schnorr::Signature, ()>,
387+
fn get_inbound_payment_key(,) -> ExpandedKey
388+
);
432389

433390
impl SignerProvider for DynPhantomKeysInterface {
434391
type EcdsaSigner = DynSigner;
435392
#[cfg(taproot)]
436393
type TaprootSigner = DynSigner;
437394

438-
delegate! {
439-
to self.inner {
440-
fn get_destination_script(&self, channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()>;
395+
fn get_destination_script(&self, channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()> {
396+
self.inner.get_destination_script(channel_keys_id)
397+
}
441398

442-
fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()>;
399+
fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()> {
400+
self.inner.get_shutdown_scriptpubkey()
401+
}
443402

444-
fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32];
445-
}
403+
fn generate_channel_keys_id(
404+
&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128,
405+
) -> [u8; 32] {
406+
self.inner.generate_channel_keys_id(_inbound, _channel_value_satoshis, _user_channel_id)
446407
}
447408

448409
fn derive_channel_signer(
@@ -452,30 +413,23 @@ impl SignerProvider for DynPhantomKeysInterface {
452413
DynSigner::new(inner)
453414
}
454415

455-
fn read_chan_signer(&self, _reader: &[u8]) -> Result<Self::EcdsaSigner, DecodeError> {
456-
todo!()
416+
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::EcdsaSigner, DecodeError> {
417+
let inner = self.inner.read_chan_signer(reader)?;
418+
Ok(DynSigner::new(inner))
457419
}
458420
}
459421

460-
impl EntropySource for DynPhantomKeysInterface {
461-
delegate! {
462-
to self.inner {
463-
fn get_secure_random_bytes(&self) -> [u8; 32];
464-
}
465-
}
466-
}
467-
468-
impl OutputSpender for DynPhantomKeysInterface {
469-
delegate! {
470-
to self.inner {
471-
fn spend_spendable_outputs(
472-
&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>,
473-
change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32,
474-
locktime: Option<LockTime>, secp_ctx: &Secp256k1<All>,
475-
) -> Result<Transaction, ()>;
476-
}
477-
}
478-
}
422+
delegate!(DynPhantomKeysInterface, EntropySource, inner,
423+
fn get_secure_random_bytes(,) -> [u8; 32]
424+
);
425+
426+
delegate!(DynPhantomKeysInterface, OutputSpender, inner,
427+
fn spend_spendable_outputs(,
428+
descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>,
429+
change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32,
430+
locktime: Option<LockTime>, secp_ctx: &Secp256k1<All>
431+
) -> Result<Transaction, ()>
432+
);
479433

480434
impl DynKeysInterfaceTrait for DynPhantomKeysInterface {
481435
#[cfg(test)]

lightning/src/util/mod.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,40 @@ pub mod string {
6868
//! [`lightning::types::string`]: crate::types::string
6969
pub use lightning_types::string::{PrintableString, UntrustedString};
7070
}
71+
72+
73+
/// A macro to delegate trait implementations to a field of a struct.
74+
///
75+
/// For example:
76+
/// ```no_run
77+
/// delegate!(A, T, inner,
78+
// fn b(, c: u64) -> u64,
79+
// fn m(mut, d: u64) -> (),
80+
// fn o(, ) -> u64,
81+
// #[cfg(debug_assertions)]
82+
// fn t(,) -> (),
83+
// ;
84+
// type O = u64,
85+
// #[cfg(debug_assertions)]
86+
// type T = (),
87+
// );
88+
#[macro_export]
89+
macro_rules! delegate {
90+
($N: ident, $T: ident, $ref: ident,
91+
$($(#[$fpat: meta])? fn $f: ident($($mu: ident)?, $($n: ident: $t: ty),*) -> $r: ty),* $(,)?
92+
$(;$($(#[$tpat: meta])? type $TN: ident = $TT: ty),*)? $(,)?
93+
) => {
94+
impl $T for $N {
95+
$(
96+
$(#[$fpat])?
97+
fn $f(&$($mu)? self, $($n: $t),*) -> $r {
98+
self.$ref.$f($($n),*)
99+
}
100+
)*
101+
$($(
102+
$(#[$tpat])?
103+
type $TN = $TT;
104+
)*)?
105+
}
106+
};
107+
}

0 commit comments

Comments
 (0)