Skip to content

Commit 53d1518

Browse files
committed
Move ChannelKeys creation into channelmanager
1 parent 4fbe0c9 commit 53d1518

File tree

3 files changed

+83
-34
lines changed

3 files changed

+83
-34
lines changed

fuzz/fuzz_targets/channel_target.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ use bitcoin::blockdata::transaction::{Transaction, TxOut};
77
use bitcoin::util::hash::Sha256dHash;
88
use bitcoin::network::serialize::{serialize, BitcoinHash};
99

10-
use lightning::ln::channel::Channel;
10+
use lightning::ln::channel::{Channel, ChannelKeys};
1111
use lightning::ln::channelmanager::{HTLCFailReason, PendingForwardHTLCInfo};
1212
use lightning::ln::msgs;
1313
use lightning::ln::msgs::MsgDecodable;
1414
use lightning::chain::chaininterface::{FeeEstimator, ConfirmationTarget};
1515
use lightning::util::reset_rng_state;
1616

17-
use secp256k1::key::PublicKey;
17+
use secp256k1::key::{PublicKey, SecretKey};
1818
use secp256k1::Secp256k1;
1919

2020
use std::sync::atomic::{AtomicUsize,Ordering};
@@ -164,13 +164,29 @@ pub fn do_test(data: &[u8]) {
164164
}
165165
}
166166

167+
macro_rules! chan_keys {
168+
() => {
169+
ChannelKeys {
170+
funding_key: SecretKey::from_slice(&secp_ctx, &[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, 0]).unwrap(),
171+
revocation_base_key: SecretKey::from_slice(&secp_ctx, &[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, 0]).unwrap(),
172+
payment_base_key: SecretKey::from_slice(&secp_ctx, &[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, 0]).unwrap(),
173+
delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &[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, 0]).unwrap(),
174+
htlc_base_key: SecretKey::from_slice(&secp_ctx, &[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, 0]).unwrap(),
175+
channel_close_key: SecretKey::from_slice(&secp_ctx, &[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, 0]).unwrap(),
176+
channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &[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, 0]).unwrap(),
177+
commitment_seed: [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, 0],
178+
}
179+
}
180+
}
181+
167182
let their_pubkey = get_pubkey!();
168183

169184
let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
170185

171186
let mut channel = if get_slice!(1)[0] != 0 {
172187
let chan_value = slice_to_be24(get_slice!(3));
173-
let mut chan = Channel::new_outbound(&fee_est, their_pubkey, chan_value, get_slice!(1)[0] == 0, slice_to_be64(get_slice!(8)));
188+
189+
let mut chan = Channel::new_outbound(&fee_est, chan_keys!(), their_pubkey, chan_value, get_slice!(1)[0] == 0, slice_to_be64(get_slice!(8)));
174190
chan.get_open_channel(Sha256dHash::from(get_slice!(32)), &fee_est).unwrap();
175191
let accept_chan = if get_slice!(1)[0] == 0 {
176192
decode_msg_with_len16!(msgs::AcceptChannel, 270, 1)
@@ -192,7 +208,7 @@ pub fn do_test(data: &[u8]) {
192208
} else {
193209
decode_msg!(msgs::OpenChannel, 2*32+6*8+4+2*2+6*33+1)
194210
};
195-
let mut chan = match Channel::new_from_req(&fee_est, their_pubkey, &open_chan, slice_to_be64(get_slice!(8)), get_slice!(1)[0] == 0) {
211+
let mut chan = match Channel::new_from_req(&fee_est, chan_keys!(), their_pubkey, &open_chan, slice_to_be64(get_slice!(8)), get_slice!(1)[0] == 0) {
196212
Ok(chan) => chan,
197213
Err(_) => return,
198214
};

src/ln/channel.rs

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -349,21 +349,14 @@ impl Channel {
349349
// Constructors:
350350

351351
/// panics if channel_value_satoshis is >= (1 << 24)
352-
pub fn new_outbound(fee_estimator: &FeeEstimator, their_node_id: PublicKey, channel_value_satoshis: u64, announce_publicly: bool, user_id: u64) -> Channel {
352+
pub fn new_outbound(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, channel_value_satoshis: u64, announce_publicly: bool, user_id: u64) -> Channel {
353353
if channel_value_satoshis >= (1 << 24) {
354354
panic!("funding value > 2^24");
355355
}
356356

357357
let feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Normal);
358358
let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
359359

360-
let mut key_seed = [0u8; 32];
361-
rng::fill_bytes(&mut key_seed);
362-
let chan_keys = match ChannelKeys::new_from_seed(&key_seed) {
363-
Ok(key) => key,
364-
Err(_) => panic!("RNG is busted!")
365-
};
366-
367360
let secp_ctx = Secp256k1::new();
368361
let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
369362
let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script();
@@ -439,7 +432,7 @@ impl Channel {
439432
/// Assumes chain_hash has already been checked and corresponds with what we expect!
440433
/// Generally prefers to take the DisconnectPeer action on failure, as a notice to the sender
441434
/// that we're rejecting the new channel.
442-
pub fn new_from_req(fee_estimator: &FeeEstimator, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, announce_publicly: bool) -> Result<Channel, HandleError> {
435+
pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, announce_publicly: bool) -> Result<Channel, HandleError> {
443436
// Check sanity of message fields:
444437
if msg.funding_satoshis >= (1 << 24) {
445438
return Err(HandleError{err: "funding value > 2^24", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
@@ -479,13 +472,6 @@ impl Channel {
479472

480473
let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
481474

482-
let mut key_seed = [0u8; 32];
483-
rng::fill_bytes(&mut key_seed);
484-
let chan_keys = match ChannelKeys::new_from_seed(&key_seed) {
485-
Ok(key) => key,
486-
Err(_) => panic!("RNG is busted!")
487-
};
488-
489475
let secp_ctx = Secp256k1::new();
490476
let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
491477
let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script();
@@ -2303,7 +2289,7 @@ mod tests {
23032289
use bitcoin::util::bip143;
23042290
use bitcoin::network::serialize::serialize;
23052291
use bitcoin::blockdata::transaction::Transaction;
2306-
use ln::channel::{Channel,HTLCOutput,HTLCState,HTLCOutputInCommitment,TxCreationKeys};
2292+
use ln::channel::{Channel,ChannelKeys,HTLCOutput,HTLCState,HTLCOutputInCommitment,TxCreationKeys};
23072293
use ln::chan_utils;
23082294
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
23092295
use secp256k1::{Secp256k1,Message,Signature};
@@ -2324,20 +2310,26 @@ mod tests {
23242310
fn outbound_commitment_test() {
23252311
// Test vectors from BOLT 3 Appendix C:
23262312
let feeest = TestFeeEstimator{fee_est: 15000/250};
2327-
let mut chan = Channel::new_outbound(&feeest, PublicKey::new(), 10000000, false, 42); // Nothing uses their network key in this test
2328-
chan.their_to_self_delay = 144;
2329-
chan.our_dust_limit_satoshis = 546;
2330-
23312313
let secp_ctx = Secp256k1::new();
23322314

2333-
chan.local_keys.funding_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap();
2334-
assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan.local_keys.funding_key).unwrap().serialize()[..],
2315+
let chan_keys = ChannelKeys {
2316+
funding_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap(),
2317+
payment_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
2318+
delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..]).unwrap(),
2319+
htlc_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
2320+
2321+
// These aren't set in the test vectors:
2322+
revocation_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
2323+
channel_close_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
2324+
channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
2325+
commitment_seed: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
2326+
};
2327+
assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan_keys.funding_key).unwrap().serialize()[..],
23352328
hex_bytes("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]);
23362329

2337-
chan.local_keys.payment_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
2338-
chan.local_keys.delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..]).unwrap();
2339-
chan.local_keys.htlc_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
2340-
// chan.local_keys.commitment_seed isn't derived in the test vectors :(
2330+
let mut chan = Channel::new_outbound(&feeest, chan_keys, PublicKey::new(), 10000000, false, 42); // Nothing uses their network key in this test
2331+
chan.their_to_self_delay = 144;
2332+
chan.our_dust_limit_satoshis = 546;
23412333

23422334
chan.channel_monitor.set_funding_info(Sha256dHash::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
23432335

src/ln/channelmanager.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use secp256k1::ecdh::SharedSecret;
1212
use secp256k1;
1313

1414
use chain::chaininterface::{BroadcasterInterface,ChainListener,ChainWatchInterface,FeeEstimator};
15-
use ln::channel::Channel;
15+
use ln::channel::{Channel, ChannelKeys};
1616
use ln::channelmonitor::ManyChannelMonitor;
1717
use ln::router::Route;
1818
use ln::msgs;
@@ -230,7 +230,27 @@ impl ChannelManager {
230230
}
231231

232232
pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, user_id: u64) -> Result<msgs::OpenChannel, HandleError> {
233-
let channel = Channel::new_outbound(&*self.fee_estimator, their_network_key, channel_value_satoshis, self.announce_channels_publicly, user_id);
233+
let chan_keys = if cfg!(feature = "fuzztarget") {
234+
ChannelKeys {
235+
funding_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0]).unwrap(),
236+
revocation_base_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0]).unwrap(),
237+
payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0]).unwrap(),
238+
delayed_payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0]).unwrap(),
239+
htlc_base_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0]).unwrap(),
240+
channel_close_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0]).unwrap(),
241+
channel_monitor_claim_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0]).unwrap(),
242+
commitment_seed: [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, 0],
243+
}
244+
} else {
245+
let mut key_seed = [0u8; 32];
246+
rng::fill_bytes(&mut key_seed);
247+
match ChannelKeys::new_from_seed(&key_seed) {
248+
Ok(key) => key,
249+
Err(_) => panic!("RNG is busted!")
250+
}
251+
};
252+
253+
let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, self.announce_channels_publicly, user_id);
234254
let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator)?;
235255
let mut channel_state = self.channel_state.lock().unwrap();
236256
match channel_state.by_id.insert(channel.channel_id(), channel) {
@@ -978,7 +998,28 @@ impl ChannelMessageHandler for ChannelManager {
978998
if channel_state.by_id.contains_key(&msg.temporary_channel_id) {
979999
return Err(HandleError{err: "temporary_channel_id collision!", msg: None});
9801000
}
981-
let channel = Channel::new_from_req(&*self.fee_estimator, their_node_id.clone(), msg, 0, self.announce_channels_publicly)?;
1001+
1002+
let chan_keys = if cfg!(feature = "fuzztarget") {
1003+
ChannelKeys {
1004+
funding_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0, 0]).unwrap(),
1005+
revocation_base_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0, 0]).unwrap(),
1006+
payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0, 0]).unwrap(),
1007+
delayed_payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0, 0]).unwrap(),
1008+
htlc_base_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0, 0]).unwrap(),
1009+
channel_close_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0, 0]).unwrap(),
1010+
channel_monitor_claim_key: SecretKey::from_slice(&self.secp_ctx, &[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, 0, 0]).unwrap(),
1011+
commitment_seed: [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, 0],
1012+
}
1013+
} else {
1014+
let mut key_seed = [0u8; 32];
1015+
rng::fill_bytes(&mut key_seed);
1016+
match ChannelKeys::new_from_seed(&key_seed) {
1017+
Ok(key) => key,
1018+
Err(_) => panic!("RNG is busted!")
1019+
}
1020+
};
1021+
1022+
let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, self.announce_channels_publicly)?;
9821023
let accept_msg = channel.get_accept_channel()?;
9831024
channel_state.by_id.insert(channel.channel_id(), channel);
9841025
Ok(accept_msg)

0 commit comments

Comments
 (0)