Move ChannelKeys creation into channelmanager

This commit is contained in:
Matt Corallo 2018-04-17 12:32:52 -04:00
parent 4fbe0c90b8
commit 53d1518566
3 changed files with 83 additions and 34 deletions

View file

@ -7,14 +7,14 @@ use bitcoin::blockdata::transaction::{Transaction, TxOut};
use bitcoin::util::hash::Sha256dHash;
use bitcoin::network::serialize::{serialize, BitcoinHash};
use lightning::ln::channel::Channel;
use lightning::ln::channel::{Channel, ChannelKeys};
use lightning::ln::channelmanager::{HTLCFailReason, PendingForwardHTLCInfo};
use lightning::ln::msgs;
use lightning::ln::msgs::MsgDecodable;
use lightning::chain::chaininterface::{FeeEstimator, ConfirmationTarget};
use lightning::util::reset_rng_state;
use secp256k1::key::PublicKey;
use secp256k1::key::{PublicKey, SecretKey};
use secp256k1::Secp256k1;
use std::sync::atomic::{AtomicUsize,Ordering};
@ -164,13 +164,29 @@ pub fn do_test(data: &[u8]) {
}
}
macro_rules! chan_keys {
() => {
ChannelKeys {
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(),
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(),
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(),
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(),
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(),
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(),
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(),
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],
}
}
}
let their_pubkey = get_pubkey!();
let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
let mut channel = if get_slice!(1)[0] != 0 {
let chan_value = slice_to_be24(get_slice!(3));
let mut chan = Channel::new_outbound(&fee_est, their_pubkey, chan_value, get_slice!(1)[0] == 0, slice_to_be64(get_slice!(8)));
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)));
chan.get_open_channel(Sha256dHash::from(get_slice!(32)), &fee_est).unwrap();
let accept_chan = if get_slice!(1)[0] == 0 {
decode_msg_with_len16!(msgs::AcceptChannel, 270, 1)
@ -192,7 +208,7 @@ pub fn do_test(data: &[u8]) {
} else {
decode_msg!(msgs::OpenChannel, 2*32+6*8+4+2*2+6*33+1)
};
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) {
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) {
Ok(chan) => chan,
Err(_) => return,
};

View file

@ -349,7 +349,7 @@ impl Channel {
// Constructors:
/// panics if channel_value_satoshis is >= (1 << 24)
pub fn new_outbound(fee_estimator: &FeeEstimator, their_node_id: PublicKey, channel_value_satoshis: u64, announce_publicly: bool, user_id: u64) -> Channel {
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 {
if channel_value_satoshis >= (1 << 24) {
panic!("funding value > 2^24");
}
@ -357,13 +357,6 @@ impl Channel {
let feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Normal);
let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
let mut key_seed = [0u8; 32];
rng::fill_bytes(&mut key_seed);
let chan_keys = match ChannelKeys::new_from_seed(&key_seed) {
Ok(key) => key,
Err(_) => panic!("RNG is busted!")
};
let secp_ctx = Secp256k1::new();
let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
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 {
/// Assumes chain_hash has already been checked and corresponds with what we expect!
/// Generally prefers to take the DisconnectPeer action on failure, as a notice to the sender
/// that we're rejecting the new channel.
pub fn new_from_req(fee_estimator: &FeeEstimator, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, announce_publicly: bool) -> Result<Channel, HandleError> {
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> {
// Check sanity of message fields:
if msg.funding_satoshis >= (1 << 24) {
return Err(HandleError{err: "funding value > 2^24", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
@ -479,13 +472,6 @@ impl Channel {
let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
let mut key_seed = [0u8; 32];
rng::fill_bytes(&mut key_seed);
let chan_keys = match ChannelKeys::new_from_seed(&key_seed) {
Ok(key) => key,
Err(_) => panic!("RNG is busted!")
};
let secp_ctx = Secp256k1::new();
let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
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 {
use bitcoin::util::bip143;
use bitcoin::network::serialize::serialize;
use bitcoin::blockdata::transaction::Transaction;
use ln::channel::{Channel,HTLCOutput,HTLCState,HTLCOutputInCommitment,TxCreationKeys};
use ln::channel::{Channel,ChannelKeys,HTLCOutput,HTLCState,HTLCOutputInCommitment,TxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use secp256k1::{Secp256k1,Message,Signature};
@ -2324,20 +2310,26 @@ mod tests {
fn outbound_commitment_test() {
// Test vectors from BOLT 3 Appendix C:
let feeest = TestFeeEstimator{fee_est: 15000/250};
let mut chan = Channel::new_outbound(&feeest, PublicKey::new(), 10000000, false, 42); // Nothing uses their network key in this test
chan.their_to_self_delay = 144;
chan.our_dust_limit_satoshis = 546;
let secp_ctx = Secp256k1::new();
chan.local_keys.funding_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap();
assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan.local_keys.funding_key).unwrap().serialize()[..],
let chan_keys = ChannelKeys {
funding_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap(),
payment_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..]).unwrap(),
htlc_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
// These aren't set in the test vectors:
revocation_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
channel_close_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
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],
};
assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan_keys.funding_key).unwrap().serialize()[..],
hex_bytes("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]);
chan.local_keys.payment_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
chan.local_keys.delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..]).unwrap();
chan.local_keys.htlc_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
// chan.local_keys.commitment_seed isn't derived in the test vectors :(
let mut chan = Channel::new_outbound(&feeest, chan_keys, PublicKey::new(), 10000000, false, 42); // Nothing uses their network key in this test
chan.their_to_self_delay = 144;
chan.our_dust_limit_satoshis = 546;
chan.channel_monitor.set_funding_info(Sha256dHash::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);

View file

@ -12,7 +12,7 @@ use secp256k1::ecdh::SharedSecret;
use secp256k1;
use chain::chaininterface::{BroadcasterInterface,ChainListener,ChainWatchInterface,FeeEstimator};
use ln::channel::Channel;
use ln::channel::{Channel, ChannelKeys};
use ln::channelmonitor::ManyChannelMonitor;
use ln::router::Route;
use ln::msgs;
@ -230,7 +230,27 @@ impl ChannelManager {
}
pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, user_id: u64) -> Result<msgs::OpenChannel, HandleError> {
let channel = Channel::new_outbound(&*self.fee_estimator, their_network_key, channel_value_satoshis, self.announce_channels_publicly, user_id);
let chan_keys = if cfg!(feature = "fuzztarget") {
ChannelKeys {
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(),
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(),
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(),
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(),
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(),
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(),
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(),
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],
}
} else {
let mut key_seed = [0u8; 32];
rng::fill_bytes(&mut key_seed);
match ChannelKeys::new_from_seed(&key_seed) {
Ok(key) => key,
Err(_) => panic!("RNG is busted!")
}
};
let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, self.announce_channels_publicly, user_id);
let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator)?;
let mut channel_state = self.channel_state.lock().unwrap();
match channel_state.by_id.insert(channel.channel_id(), channel) {
@ -978,7 +998,28 @@ impl ChannelMessageHandler for ChannelManager {
if channel_state.by_id.contains_key(&msg.temporary_channel_id) {
return Err(HandleError{err: "temporary_channel_id collision!", msg: None});
}
let channel = Channel::new_from_req(&*self.fee_estimator, their_node_id.clone(), msg, 0, self.announce_channels_publicly)?;
let chan_keys = if cfg!(feature = "fuzztarget") {
ChannelKeys {
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(),
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(),
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(),
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(),
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(),
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(),
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(),
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],
}
} else {
let mut key_seed = [0u8; 32];
rng::fill_bytes(&mut key_seed);
match ChannelKeys::new_from_seed(&key_seed) {
Ok(key) => key,
Err(_) => panic!("RNG is busted!")
}
};
let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, self.announce_channels_publicly)?;
let accept_msg = channel.get_accept_channel()?;
channel_state.by_id.insert(channel.channel_id(), channel);
Ok(accept_msg)