Skip to content

Commit d2043bc

Browse files
committed
Sign gossip messages with NodeSigner
1 parent b08b798 commit d2043bc

File tree

10 files changed

+308
-111
lines changed

10 files changed

+308
-111
lines changed

fuzz/src/full_stack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ impl<'a> std::hash::Hash for Peer<'a> {
183183
type ChannelMan<'a> = ChannelManager<
184184
Arc<chainmonitor::ChainMonitor<EnforcingSigner, Arc<dyn chain::Filter>, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<TestPersister>>>,
185185
Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<FuzzEstimator>, &'a FuzzRouter, Arc<dyn Logger>>;
186-
type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler>;
186+
type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler, Arc<KeyProvider>>;
187187

188188
struct MoneyLossDetector<'a> {
189189
manager: Arc<ChannelMan<'a>>,
@@ -462,7 +462,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
462462
chan_handler: channelmanager.clone(),
463463
route_handler: gossip_sync.clone(),
464464
onion_message_handler: IgnoringMessageHandler {},
465-
}, our_network_key, 0, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0], Arc::clone(&logger), IgnoringMessageHandler{}));
465+
}, our_network_key, 0, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0], Arc::clone(&logger), IgnoringMessageHandler{}, keys_manager.clone()));
466466

467467
let mut should_forward = false;
468468
let mut payments_received: Vec<PaymentHash> = Vec::new();

lightning-background-processor/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ pub async fn process_events_async<
385385
PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
386386
RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
387387
UMH: 'static + Deref + Send + Sync,
388-
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH>> + Send + Sync,
388+
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH, NS>> + Send + Sync,
389389
S: 'static + Deref<Target = SC> + Send + Sync,
390390
SC: WriteableScore<'a>,
391391
SleepFuture: core::future::Future<Output = bool> + core::marker::Unpin,
@@ -514,7 +514,7 @@ impl BackgroundProcessor {
514514
PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
515515
RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
516516
UMH: 'static + Deref + Send + Sync,
517-
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH>> + Send + Sync,
517+
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH, NS>> + Send + Sync,
518518
S: 'static + Deref<Target = SC> + Send + Sync,
519519
SC: WriteableScore<'a>,
520520
>(
@@ -663,7 +663,7 @@ mod tests {
663663
node: Arc<SimpleArcChannelManager<ChainMonitor, test_utils::TestBroadcaster, test_utils::TestFeeEstimator, test_utils::TestLogger>>,
664664
p2p_gossip_sync: PGS,
665665
rapid_gossip_sync: RGS,
666-
peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, IgnoringMessageHandler, Arc<test_utils::TestLogger>, IgnoringMessageHandler>>,
666+
peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, IgnoringMessageHandler, Arc<test_utils::TestLogger>, IgnoringMessageHandler, Arc<KeysManager>>>,
667667
chain_monitor: Arc<ChainMonitor>,
668668
persister: Arc<FilesystemPersister>,
669669
tx_broadcaster: Arc<test_utils::TestBroadcaster>,
@@ -786,7 +786,7 @@ mod tests {
786786
let p2p_gossip_sync = Arc::new(P2PGossipSync::new(network_graph.clone(), Some(chain_source.clone()), logger.clone()));
787787
let rapid_gossip_sync = Arc::new(RapidGossipSync::new(network_graph.clone()));
788788
let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new()), onion_message_handler: IgnoringMessageHandler{}};
789-
let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), 0, &seed, logger.clone(), IgnoringMessageHandler{}));
789+
let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), 0, &seed, logger.clone(), IgnoringMessageHandler{}, keys_manager.clone()));
790790
let node = Node { node: manager, p2p_gossip_sync, rapid_gossip_sync, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block, scorer };
791791
nodes.push(node);
792792
}

lightning-net-tokio/src/lib.rs

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
//! type TxBroadcaster = dyn lightning::chain::chaininterface::BroadcasterInterface + Send + Sync;
3333
//! type FeeEstimator = dyn lightning::chain::chaininterface::FeeEstimator + Send + Sync;
3434
//! type Logger = dyn lightning::util::logger::Logger + Send + Sync;
35+
//! type NodeSigner = dyn lightning::chain::keysinterface::NodeSigner + Send + Sync;
3536
//! type ChainAccess = dyn lightning::chain::Access + Send + Sync;
3637
//! type ChainFilter = dyn lightning::chain::Filter + Send + Sync;
3738
//! type DataPersister = dyn lightning::chain::chainmonitor::Persist<lightning::chain::keysinterface::InMemorySigner> + Send + Sync;
@@ -80,6 +81,7 @@ use tokio::{io, time};
8081
use tokio::sync::mpsc;
8182
use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt};
8283

84+
use lightning::chain::keysinterface::NodeSigner;
8385
use lightning::ln::peer_handler;
8486
use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait;
8587
use lightning::ln::peer_handler::CustomMessageHandler;
@@ -123,21 +125,23 @@ struct Connection {
123125
id: u64,
124126
}
125127
impl Connection {
126-
async fn poll_event_process<PM, CMH, RMH, OMH, L, UMH>(
128+
async fn poll_event_process<PM, CMH, RMH, OMH, L, UMH, NS>(
127129
peer_manager: PM,
128130
mut event_receiver: mpsc::Receiver<()>,
129131
) where
130-
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync,
132+
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync,
131133
CMH: Deref + 'static + Send + Sync,
132134
RMH: Deref + 'static + Send + Sync,
133135
OMH: Deref + 'static + Send + Sync,
134136
L: Deref + 'static + Send + Sync,
135137
UMH: Deref + 'static + Send + Sync,
138+
NS: Deref + 'static + Send + Sync,
136139
CMH::Target: ChannelMessageHandler + Send + Sync,
137140
RMH::Target: RoutingMessageHandler + Send + Sync,
138141
OMH::Target: OnionMessageHandler + Send + Sync,
139142
L::Target: Logger + Send + Sync,
140143
UMH::Target: CustomMessageHandler + Send + Sync,
144+
NS::Target: NodeSigner + Send + Sync,
141145
{
142146
loop {
143147
if event_receiver.recv().await.is_none() {
@@ -147,24 +151,26 @@ impl Connection {
147151
}
148152
}
149153

150-
async fn schedule_read<PM, CMH, RMH, OMH, L, UMH>(
154+
async fn schedule_read<PM, CMH, RMH, OMH, L, UMH, NS>(
151155
peer_manager: PM,
152156
us: Arc<Mutex<Self>>,
153157
mut reader: io::ReadHalf<TcpStream>,
154158
mut read_wake_receiver: mpsc::Receiver<()>,
155159
mut write_avail_receiver: mpsc::Receiver<()>,
156160
) where
157-
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
161+
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
158162
CMH: Deref + 'static + Send + Sync,
159163
RMH: Deref + 'static + Send + Sync,
160164
OMH: Deref + 'static + Send + Sync,
161165
L: Deref + 'static + Send + Sync,
162166
UMH: Deref + 'static + Send + Sync,
167+
NS: Deref + 'static + Send + Sync,
163168
CMH::Target: ChannelMessageHandler + 'static + Send + Sync,
164169
RMH::Target: RoutingMessageHandler + 'static + Send + Sync,
165170
OMH::Target: OnionMessageHandler + 'static + Send + Sync,
166171
L::Target: Logger + 'static + Send + Sync,
167172
UMH::Target: CustomMessageHandler + 'static + Send + Sync,
173+
NS::Target: NodeSigner + 'static + Send + Sync,
168174
{
169175
// Create a waker to wake up poll_event_process, above
170176
let (event_waker, event_receiver) = mpsc::channel(1);
@@ -283,21 +289,23 @@ fn get_addr_from_stream(stream: &StdTcpStream) -> Option<NetAddress> {
283289
/// The returned future will complete when the peer is disconnected and associated handling
284290
/// futures are freed, though, because all processing futures are spawned with tokio::spawn, you do
285291
/// not need to poll the provided future in order to make progress.
286-
pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH>(
292+
pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH, NS>(
287293
peer_manager: PM,
288294
stream: StdTcpStream,
289295
) -> impl std::future::Future<Output=()> where
290-
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
296+
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
291297
CMH: Deref + 'static + Send + Sync,
292298
RMH: Deref + 'static + Send + Sync,
293299
OMH: Deref + 'static + Send + Sync,
294300
L: Deref + 'static + Send + Sync,
295301
UMH: Deref + 'static + Send + Sync,
302+
NS: Deref + 'static + Send + Sync,
296303
CMH::Target: ChannelMessageHandler + Send + Sync,
297304
RMH::Target: RoutingMessageHandler + Send + Sync,
298305
OMH::Target: OnionMessageHandler + Send + Sync,
299306
L::Target: Logger + Send + Sync,
300307
UMH::Target: CustomMessageHandler + Send + Sync,
308+
NS::Target: NodeSigner + Send + Sync,
301309
{
302310
let remote_addr = get_addr_from_stream(&stream);
303311
let (reader, write_receiver, read_receiver, us) = Connection::new(stream);
@@ -336,22 +344,24 @@ pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH>(
336344
/// The returned future will complete when the peer is disconnected and associated handling
337345
/// futures are freed, though, because all processing futures are spawned with tokio::spawn, you do
338346
/// not need to poll the provided future in order to make progress.
339-
pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH>(
347+
pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH, NS>(
340348
peer_manager: PM,
341349
their_node_id: PublicKey,
342350
stream: StdTcpStream,
343351
) -> impl std::future::Future<Output=()> where
344-
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
352+
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
345353
CMH: Deref + 'static + Send + Sync,
346354
RMH: Deref + 'static + Send + Sync,
347355
OMH: Deref + 'static + Send + Sync,
348356
L: Deref + 'static + Send + Sync,
349357
UMH: Deref + 'static + Send + Sync,
358+
NS: Deref + 'static + Send + Sync,
350359
CMH::Target: ChannelMessageHandler + Send + Sync,
351360
RMH::Target: RoutingMessageHandler + Send + Sync,
352361
OMH::Target: OnionMessageHandler + Send + Sync,
353362
L::Target: Logger + Send + Sync,
354363
UMH::Target: CustomMessageHandler + Send + Sync,
364+
NS::Target: NodeSigner + Send + Sync,
355365
{
356366
let remote_addr = get_addr_from_stream(&stream);
357367
let (reader, mut write_receiver, read_receiver, us) = Connection::new(stream);
@@ -419,22 +429,24 @@ pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH>(
419429
/// disconnected and associated handling futures are freed, though, because all processing in said
420430
/// futures are spawned with tokio::spawn, you do not need to poll the second future in order to
421431
/// make progress.
422-
pub async fn connect_outbound<PM, CMH, RMH, OMH, L, UMH>(
432+
pub async fn connect_outbound<PM, CMH, RMH, OMH, L, UMH, NS>(
423433
peer_manager: PM,
424434
their_node_id: PublicKey,
425435
addr: SocketAddr,
426436
) -> Option<impl std::future::Future<Output=()>> where
427-
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
437+
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
428438
CMH: Deref + 'static + Send + Sync,
429439
RMH: Deref + 'static + Send + Sync,
430440
OMH: Deref + 'static + Send + Sync,
431441
L: Deref + 'static + Send + Sync,
432442
UMH: Deref + 'static + Send + Sync,
443+
NS: Deref + 'static + Send + Sync,
433444
CMH::Target: ChannelMessageHandler + Send + Sync,
434445
RMH::Target: RoutingMessageHandler + Send + Sync,
435446
OMH::Target: OnionMessageHandler + Send + Sync,
436447
L::Target: Logger + Send + Sync,
437448
UMH::Target: CustomMessageHandler + Send + Sync,
449+
NS::Target: NodeSigner + Send + Sync,
438450
{
439451
if let Ok(Ok(stream)) = time::timeout(Duration::from_secs(10), async { TcpStream::connect(&addr).await.map(|s| s.into_std().unwrap()) }).await {
440452
Some(setup_outbound(peer_manager, their_node_id, stream))
@@ -568,12 +580,14 @@ impl Hash for SocketDescriptor {
568580

569581
#[cfg(test)]
570582
mod tests {
583+
use lightning::chain::keysinterface::{NodeSigner, Recipient};
571584
use lightning::ln::features::*;
572585
use lightning::ln::msgs::*;
573586
use lightning::ln::peer_handler::{MessageHandler, PeerManager};
574587
use lightning::ln::features::NodeFeatures;
575588
use lightning::util::events::*;
576589
use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey};
590+
use bitcoin::secp256k1::ecdh::SharedSecret;
577591

578592
use tokio::sync::mpsc;
579593

@@ -589,6 +603,57 @@ mod tests {
589603
}
590604
}
591605

606+
struct TestNodeSigner {
607+
node_secret: SecretKey,
608+
}
609+
610+
impl TestNodeSigner {
611+
fn new(node_secret: SecretKey) -> Self {
612+
Self { node_secret }
613+
}
614+
}
615+
616+
impl NodeSigner for TestNodeSigner {
617+
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
618+
let node_secret = match recipient {
619+
Recipient::Node => Ok(self.node_secret.clone()),
620+
Recipient::PhantomNode => Err(())
621+
}?;
622+
Ok(node_secret)
623+
}
624+
625+
fn get_inbound_payment_key_material(&self) -> lightning::chain::keysinterface::KeyMaterial {
626+
unreachable!()
627+
}
628+
629+
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
630+
let node_secret = match recipient {
631+
Recipient::Node => Ok(&self.node_secret),
632+
Recipient::PhantomNode => Err(())
633+
}?;
634+
Ok(PublicKey::from_secret_key(&Secp256k1::new(), node_secret))
635+
}
636+
637+
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&bitcoin::secp256k1::Scalar>) -> Result<SharedSecret, ()> {
638+
let mut node_secret = match recipient {
639+
Recipient::Node => Ok(self.node_secret.clone()),
640+
Recipient::PhantomNode => Err(())
641+
}?;
642+
if let Some(tweak) = tweak {
643+
node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
644+
}
645+
Ok(SharedSecret::new(other_key, &node_secret))
646+
}
647+
648+
fn sign_invoice(&self, _: &[u8], _: &[bitcoin::bech32::u5], _: Recipient) -> Result<bitcoin::secp256k1::ecdsa::RecoverableSignature, ()> {
649+
unreachable!()
650+
}
651+
652+
fn sign_gossip_message(&self, _: lightning::ln::msgs::UnsignedGossipMessage) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
653+
unreachable!()
654+
}
655+
}
656+
592657
struct MsgHandler{
593658
expected_pubkey: PublicKey,
594659
pubkey_connected: mpsc::Sender<()>,
@@ -688,7 +753,7 @@ mod tests {
688753
chan_handler: Arc::clone(&a_handler),
689754
route_handler: Arc::clone(&a_handler),
690755
onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
691-
}, a_key.clone(), 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
756+
}, a_key.clone(), 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(a_key))));
692757

693758
let (b_connected_sender, mut b_connected) = mpsc::channel(1);
694759
let (b_disconnected_sender, mut b_disconnected) = mpsc::channel(1);
@@ -703,7 +768,7 @@ mod tests {
703768
chan_handler: Arc::clone(&b_handler),
704769
route_handler: Arc::clone(&b_handler),
705770
onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
706-
}, b_key.clone(), 0, &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
771+
}, b_key.clone(), 0, &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(b_key))));
707772

708773
// We bind on localhost, hoping the environment is properly configured with a local
709774
// address. This may not always be the case in containers and the like, so if this test is
@@ -756,7 +821,7 @@ mod tests {
756821
chan_handler: Arc::new(lightning::ln::peer_handler::ErroringMessageHandler::new()),
757822
onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
758823
route_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
759-
}, a_key, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
824+
}, a_key, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(a_key))));
760825

761826
// Make two connections, one for an inbound and one for an outbound connection
762827
let conn_a = {

lightning/src/chain/keysinterface.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,9 @@ pub trait BaseSign {
392392
/// Note that if this fails or is rejected, the channel will not be publicly announced and
393393
/// our counterparty may (though likely will not) close the channel on us for violating the
394394
/// protocol.
395-
fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
396-
-> Result<(Signature, Signature), ()>;
395+
fn sign_channel_announcement_with_funding_key(
396+
&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
397+
) -> Result<Signature, ()>;
397398
/// Set the counterparty static channel data, including basepoints,
398399
/// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
399400
///
@@ -880,10 +881,11 @@ impl BaseSign for InMemorySigner {
880881
Ok(sign(secp_ctx, &hash_to_message!(&sighash[..]), &self.funding_key))
881882
}
882883

883-
fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
884-
-> Result<(Signature, Signature), ()> {
884+
fn sign_channel_announcement_with_funding_key(
885+
&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
886+
) -> Result<Signature, ()> {
885887
let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
886-
Ok((sign(secp_ctx, &msghash, &self.node_secret), sign(secp_ctx, &msghash, &self.funding_key)))
888+
Ok(sign(secp_ctx, &msghash, &self.funding_key))
887889
}
888890

889891
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {

0 commit comments

Comments
 (0)