Skip to content

Commit 233272a

Browse files
committed
Move node_id signing of ChannelAnnouncement into Signer
This removes one more place where we directly access the node_id secret key in `ChannelManager`, slowly marching towards allowing the node_id secret key to be offline in the signer. More importantly, it allows more ChannelAnnouncement logic to move into the `Channel` without having to pass the node secret key around, avoiding the announcement logic being split across two files.
1 parent 8d886ee commit 233272a

File tree

8 files changed

+58
-43
lines changed

8 files changed

+58
-43
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ impl KeysInterface for KeyProvider {
184184
let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed);
185185
let keys = InMemorySigner::new(
186186
&secp_ctx,
187+
self.get_node_secret(),
187188
SecretKey::from_slice(&[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, 4, self.node_id]).unwrap(),
188189
SecretKey::from_slice(&[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, 5, self.node_id]).unwrap(),
189190
SecretKey::from_slice(&[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, 6, self.node_id]).unwrap(),
@@ -207,7 +208,7 @@ impl KeysInterface for KeyProvider {
207208
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, DecodeError> {
208209
let mut reader = std::io::Cursor::new(buffer);
209210

210-
let inner: InMemorySigner = Readable::read(&mut reader)?;
211+
let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret())?;
211212
let state = self.make_enforcement_state_cell(inner.commitment_seed);
212213

213214
Ok(EnforcingSigner {

fuzz/src/full_stack.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use lightning::util::errors::APIError;
4545
use lightning::util::events::Event;
4646
use lightning::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
4747
use lightning::util::logger::Logger;
48-
use lightning::util::ser::Readable;
48+
use lightning::util::ser::ReadableArgs;
4949

5050
use utils::test_logger;
5151
use utils::test_persister::TestPersister;
@@ -286,6 +286,7 @@ impl KeysInterface for KeyProvider {
286286
EnforcingSigner::new(if inbound {
287287
InMemorySigner::new(
288288
&secp_ctx,
289+
self.node_secret.clone(),
289290
SecretKey::from_slice(&[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, 1, ctr]).unwrap(),
290291
SecretKey::from_slice(&[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, 2, ctr]).unwrap(),
291292
SecretKey::from_slice(&[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, 3, ctr]).unwrap(),
@@ -298,6 +299,7 @@ impl KeysInterface for KeyProvider {
298299
} else {
299300
InMemorySigner::new(
300301
&secp_ctx,
302+
self.node_secret.clone(),
301303
SecretKey::from_slice(&[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, 7, ctr]).unwrap(),
302304
SecretKey::from_slice(&[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, 8, ctr]).unwrap(),
303305
SecretKey::from_slice(&[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, 9, ctr]).unwrap(),
@@ -317,7 +319,7 @@ impl KeysInterface for KeyProvider {
317319
}
318320

319321
fn read_chan_signer(&self, mut data: &[u8]) -> Result<EnforcingSigner, DecodeError> {
320-
let inner: InMemorySigner = Readable::read(&mut data)?;
322+
let inner: InMemorySigner = ReadableArgs::read(&mut data, self.node_secret.clone())?;
321323
let state = Arc::new(Mutex::new(EnforcementState::new()));
322324

323325
Ok(EnforcingSigner::new_with_revoked(

lightning/src/chain/channelmonitor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3358,6 +3358,7 @@ mod tests {
33583358
SecretKey::from_slice(&[41; 32]).unwrap(),
33593359
SecretKey::from_slice(&[41; 32]).unwrap(),
33603360
SecretKey::from_slice(&[41; 32]).unwrap(),
3361+
SecretKey::from_slice(&[41; 32]).unwrap(),
33613362
[41; 32],
33623363
0,
33633364
[0; 32]

lightning/src/chain/keysinterface.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use bitcoin::secp256k1::recovery::RecoverableSignature;
3030
use bitcoin::secp256k1;
3131

3232
use util::{byte_utils, transaction_utils};
33-
use util::ser::{Writeable, Writer, Readable};
33+
use util::ser::{Writeable, Writer, Readable, ReadableArgs};
3434

3535
use chain::transaction::OutPoint;
3636
use ln::chan_utils;
@@ -324,13 +324,17 @@ pub trait BaseSign {
324324
/// chosen to forgo their output as dust.
325325
fn sign_closing_transaction(&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
326326

327-
/// Signs a channel announcement message with our funding key, proving it comes from one
328-
/// of the channel participants.
327+
/// Signs a channel announcement message with our funding key and our node secret key (aka
328+
/// node_id or network_key), proving it comes from one of the channel participants.
329+
///
330+
/// The first returned signature should be from our node secret key, the second from our
331+
/// funding key.
329332
///
330333
/// Note that if this fails or is rejected, the channel will not be publicly announced and
331334
/// our counterparty may (though likely will not) close the channel on us for violating the
332335
/// protocol.
333-
fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
336+
fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
337+
-> Result<(Signature, Signature), ()>;
334338

335339
/// Set the counterparty static channel data, including basepoints,
336340
/// counterparty_selected/holder_selected_contest_delay and funding outpoint.
@@ -419,6 +423,8 @@ pub struct InMemorySigner {
419423
pub commitment_seed: [u8; 32],
420424
/// Holder public keys and basepoints
421425
pub(crate) holder_channel_pubkeys: ChannelPublicKeys,
426+
/// Private key of our node secret, used for signing channel announcements
427+
node_secret: SecretKey,
422428
/// Counterparty public keys and counterparty/holder selected_contest_delay, populated on channel acceptance
423429
channel_parameters: Option<ChannelTransactionParameters>,
424430
/// The total value of this channel
@@ -431,6 +437,7 @@ impl InMemorySigner {
431437
/// Create a new InMemorySigner
432438
pub fn new<C: Signing>(
433439
secp_ctx: &Secp256k1<C>,
440+
node_secret: SecretKey,
434441
funding_key: SecretKey,
435442
revocation_base_key: SecretKey,
436443
payment_key: SecretKey,
@@ -450,6 +457,7 @@ impl InMemorySigner {
450457
delayed_payment_base_key,
451458
htlc_base_key,
452459
commitment_seed,
460+
node_secret,
453461
channel_value_satoshis,
454462
holder_channel_pubkeys,
455463
channel_parameters: None,
@@ -677,9 +685,10 @@ impl BaseSign for InMemorySigner {
677685
Ok(closing_tx.trust().sign(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
678686
}
679687

680-
fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
688+
fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
689+
-> Result<(Signature, Signature), ()> {
681690
let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
682-
Ok(secp_ctx.sign(&msghash, &self.funding_key))
691+
Ok((secp_ctx.sign(&msghash, &self.node_secret), secp_ctx.sign(&msghash, &self.funding_key)))
683692
}
684693

685694
fn ready_channel(&mut self, channel_parameters: &ChannelTransactionParameters) {
@@ -714,8 +723,8 @@ impl Writeable for InMemorySigner {
714723
}
715724
}
716725

717-
impl Readable for InMemorySigner {
718-
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
726+
impl ReadableArgs<SecretKey> for InMemorySigner {
727+
fn read<R: io::Read>(reader: &mut R, node_secret: SecretKey) -> Result<Self, DecodeError> {
719728
let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
720729

721730
let funding_key = Readable::read(reader)?;
@@ -741,6 +750,7 @@ impl Readable for InMemorySigner {
741750
payment_key,
742751
delayed_payment_base_key,
743752
htlc_base_key,
753+
node_secret,
744754
commitment_seed,
745755
channel_value_satoshis,
746756
holder_channel_pubkeys,
@@ -889,6 +899,7 @@ impl KeysManager {
889899

890900
InMemorySigner::new(
891901
&self.secp_ctx,
902+
self.node_secret,
892903
funding_key,
893904
revocation_base_key,
894905
payment_key,
@@ -1062,7 +1073,7 @@ impl KeysInterface for KeysManager {
10621073
}
10631074

10641075
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
1065-
InMemorySigner::read(&mut io::Cursor::new(reader))
1076+
InMemorySigner::read(&mut io::Cursor::new(reader), self.get_node_secret())
10661077
}
10671078

10681079
fn sign_invoice(&self, invoice_preimage: Vec<u8>) -> Result<RecoverableSignature, ()> {

lightning/src/ln/channel.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4438,7 +4438,7 @@ impl<Signer: Sign> Channel<Signer> {
44384438
/// https://github.com/lightningnetwork/lightning-rfc/issues/468
44394439
///
44404440
/// This will only return ChannelError::Ignore upon failure.
4441-
pub fn get_channel_announcement(&self, node_id: PublicKey, chain_hash: BlockHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), ChannelError> {
4441+
fn get_channel_announcement(&self, node_id: PublicKey, chain_hash: BlockHash) -> Result<msgs::UnsignedChannelAnnouncement, ChannelError> {
44424442
if !self.config.announced_channel {
44434443
return Err(ChannelError::Ignore("Channel is not available for public announcements".to_owned()));
44444444
}
@@ -4462,19 +4462,30 @@ impl<Signer: Sign> Channel<Signer> {
44624462
excess_data: Vec::new(),
44634463
};
44644464

4465-
let sig = self.holder_signer.sign_channel_announcement(&msg, &self.secp_ctx)
4465+
Ok(msg)
4466+
}
4467+
4468+
pub fn get_announcement_sigs(&self, node_pk: PublicKey, genesis_block_hash: BlockHash) -> Result<msgs::AnnouncementSignatures, ChannelError> {
4469+
let announcement = self.get_channel_announcement(node_pk, genesis_block_hash)?;
4470+
let (our_node_sig, our_bitcoin_sig) = self.holder_signer.sign_channel_announcement(&announcement, &self.secp_ctx)
44664471
.map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement".to_owned()))?;
44674472

4468-
Ok((msg, sig))
4473+
Ok(msgs::AnnouncementSignatures {
4474+
channel_id: self.channel_id(),
4475+
short_channel_id: self.get_short_channel_id().unwrap(),
4476+
node_signature: our_node_sig,
4477+
bitcoin_signature: our_bitcoin_sig,
4478+
})
44694479
}
44704480

44714481
/// Signs the given channel announcement, returning a ChannelError::Ignore if no keys are
44724482
/// available.
4473-
fn sign_channel_announcement(&self, our_node_secret: &SecretKey, our_node_id: PublicKey, msghash: secp256k1::Message, announcement: msgs::UnsignedChannelAnnouncement, our_bitcoin_sig: Signature) -> Result<msgs::ChannelAnnouncement, ChannelError> {
4483+
fn sign_channel_announcement(&self, our_node_id: PublicKey, announcement: msgs::UnsignedChannelAnnouncement) -> Result<msgs::ChannelAnnouncement, ChannelError> {
44744484
if let Some((their_node_sig, their_bitcoin_sig)) = self.announcement_sigs {
44754485
let were_node_one = announcement.node_id_1 == our_node_id;
44764486

4477-
let our_node_sig = self.secp_ctx.sign(&msghash, our_node_secret);
4487+
let (our_node_sig, our_bitcoin_sig) = self.holder_signer.sign_channel_announcement(&announcement, &self.secp_ctx)
4488+
.map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement".to_owned()))?;
44784489
Ok(msgs::ChannelAnnouncement {
44794490
node_signature_1: if were_node_one { our_node_sig } else { their_node_sig },
44804491
node_signature_2: if were_node_one { their_node_sig } else { our_node_sig },
@@ -4490,8 +4501,8 @@ impl<Signer: Sign> Channel<Signer> {
44904501
/// Processes an incoming announcement_signatures message, providing a fully-signed
44914502
/// channel_announcement message which we can broadcast and storing our counterparty's
44924503
/// signatures for later reconstruction/rebroadcast of the channel_announcement.
4493-
pub fn announcement_signatures(&mut self, our_node_secret: &SecretKey, our_node_id: PublicKey, chain_hash: BlockHash, msg: &msgs::AnnouncementSignatures) -> Result<msgs::ChannelAnnouncement, ChannelError> {
4494-
let (announcement, our_bitcoin_sig) = self.get_channel_announcement(our_node_id.clone(), chain_hash)?;
4504+
pub fn announcement_signatures(&mut self, our_node_id: PublicKey, chain_hash: BlockHash, msg: &msgs::AnnouncementSignatures) -> Result<msgs::ChannelAnnouncement, ChannelError> {
4505+
let announcement = self.get_channel_announcement(our_node_id.clone(), chain_hash)?;
44954506

44964507
let msghash = hash_to_message!(&Sha256d::hash(&announcement.encode()[..])[..]);
44974508

@@ -4508,18 +4519,17 @@ impl<Signer: Sign> Channel<Signer> {
45084519

45094520
self.announcement_sigs = Some((msg.node_signature, msg.bitcoin_signature));
45104521

4511-
self.sign_channel_announcement(our_node_secret, our_node_id, msghash, announcement, our_bitcoin_sig)
4522+
self.sign_channel_announcement(our_node_id, announcement)
45124523
}
45134524

45144525
/// Gets a signed channel_announcement for this channel, if we previously received an
45154526
/// announcement_signatures from our counterparty.
4516-
pub fn get_signed_channel_announcement(&self, our_node_secret: &SecretKey, our_node_id: PublicKey, chain_hash: BlockHash) -> Option<msgs::ChannelAnnouncement> {
4517-
let (announcement, our_bitcoin_sig) = match self.get_channel_announcement(our_node_id.clone(), chain_hash) {
4527+
pub fn get_signed_channel_announcement(&self, our_node_id: PublicKey, chain_hash: BlockHash) -> Option<msgs::ChannelAnnouncement> {
4528+
let announcement = match self.get_channel_announcement(our_node_id.clone(), chain_hash) {
45184529
Ok(res) => res,
45194530
Err(_) => return None,
45204531
};
4521-
let msghash = hash_to_message!(&Sha256d::hash(&announcement.encode()[..])[..]);
4522-
match self.sign_channel_announcement(our_node_secret, our_node_id, msghash, announcement, our_bitcoin_sig) {
4532+
match self.sign_channel_announcement(our_node_id, announcement) {
45234533
Ok(res) => Some(res),
45244534
Err(_) => None,
45254535
}
@@ -6034,6 +6044,7 @@ mod tests {
60346044

60356045
let mut signer = InMemorySigner::new(
60366046
&secp_ctx,
6047+
SecretKey::from_slice(&hex::decode("4242424242424242424242424242424242424242424242424242424242424242").unwrap()[..]).unwrap(),
60376048
SecretKey::from_slice(&hex::decode("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap(),
60386049
SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
60396050
SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),

lightning/src/ln/channelmanager.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2487,20 +2487,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
24872487
log_trace!(self.logger, "Can't send announcement_signatures for private channel {}", log_bytes!(chan.channel_id()));
24882488
return None
24892489
}
2490-
2491-
let (announcement, our_bitcoin_sig) = match chan.get_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone()) {
2492-
Ok(res) => res,
2493-
Err(_) => return None, // Only in case of state precondition violations eg channel is closing
2494-
};
2495-
let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]);
2496-
let our_node_sig = self.secp_ctx.sign(&msghash, &self.our_network_key);
2497-
2498-
Some(msgs::AnnouncementSignatures {
2499-
channel_id: chan.channel_id(),
2500-
short_channel_id: chan.get_short_channel_id().unwrap(),
2501-
node_signature: our_node_sig,
2502-
bitcoin_signature: our_bitcoin_sig,
2503-
})
2490+
chan.get_announcement_sigs(self.get_our_node_id(), self.genesis_hash.clone()).ok()
25042491
}
25052492

25062493
#[allow(dead_code)]
@@ -2560,7 +2547,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
25602547

25612548
let mut announced_chans = false;
25622549
for (_, chan) in channel_state.by_id.iter() {
2563-
if let Some(msg) = chan.get_signed_channel_announcement(&self.our_network_key, self.get_our_node_id(), self.genesis_hash.clone()) {
2550+
if let Some(msg) = chan.get_signed_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone()) {
25642551
channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
25652552
msg,
25662553
update_msg: match self.get_channel_update_for_broadcast(chan) {
@@ -4214,7 +4201,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
42144201
}
42154202

42164203
channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
4217-
msg: try_chan_entry!(self, chan.get_mut().announcement_signatures(&self.our_network_key, self.get_our_node_id(), self.genesis_hash.clone(), msg), channel_state, chan),
4204+
msg: try_chan_entry!(self, chan.get_mut().announcement_signatures(self.get_our_node_id(), self.genesis_hash.clone(), msg), channel_state, chan),
42184205
// Note that announcement_signatures fails if the channel cannot be announced,
42194206
// so get_channel_update_for_broadcast will never fail by the time we get here.
42204207
update_msg: self.get_channel_update_for_broadcast(chan.get()).unwrap(),

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ impl BaseSign for EnforcingSigner {
188188
Ok(self.inner.sign_closing_transaction(closing_tx, secp_ctx).unwrap())
189189
}
190190

191-
fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
191+
fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
192+
-> Result<(Signature, Signature), ()> {
192193
self.inner.sign_channel_announcement(msg, secp_ctx)
193194
}
194195

lightning/src/util/test_utils.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
7676
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
7777

7878
fn read_chan_signer(&self, mut reader: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
79-
let inner: InMemorySigner = Readable::read(&mut reader)?;
79+
let dummy_sk = SecretKey::from_slice(&[42; 32]).unwrap();
80+
let inner: InMemorySigner = ReadableArgs::read(&mut reader, dummy_sk)?;
8081
let state = Arc::new(Mutex::new(EnforcementState::new()));
8182

8283
Ok(EnforcingSigner::new_with_revoked(
@@ -497,7 +498,7 @@ impl keysinterface::KeysInterface for TestKeysInterface {
497498
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
498499
let mut reader = io::Cursor::new(buffer);
499500

500-
let inner: InMemorySigner = Readable::read(&mut reader)?;
501+
let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret())?;
501502
let state = self.make_enforcement_state_cell(inner.commitment_seed);
502503

503504
Ok(EnforcingSigner::new_with_revoked(

0 commit comments

Comments
 (0)