Add log_trace on to_remote/to_local inclusion in commitment tx
[rust-lightning] / src / chain / keysinterface.rs
index 390b0cc5afebac8f696157924ebd065236b392ea..013a3388f797a302304b2307637804f408f2570a 100644 (file)
@@ -6,11 +6,11 @@ use bitcoin::blockdata::transaction::{OutPoint, TxOut};
 use bitcoin::blockdata::script::{Script, Builder};
 use bitcoin::blockdata::opcodes;
 use bitcoin::network::constants::Network;
-use bitcoin::util::hash::Hash160;
 use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, ChildNumber};
 
 use bitcoin_hashes::{Hash, HashEngine};
 use bitcoin_hashes::sha256::Hash as Sha256;
+use bitcoin_hashes::hash160::Hash as Hash160;
 
 use secp256k1::key::{SecretKey, PublicKey};
 use secp256k1::Secp256k1;
@@ -80,6 +80,10 @@ pub trait KeysInterface: Send + Sync {
        fn get_channel_keys(&self, inbound: bool) -> ChannelKeys;
        /// Get a secret for construting an onion packet
        fn get_session_key(&self) -> SecretKey;
+       /// Get a unique temporary channel id. Channels will be referred to by this until the funding
+       /// transaction is created, at which point they will use the outpoint in the funding
+       /// transaction.
+       fn get_channel_id(&self) -> [u8; 32];
 }
 
 /// Set of lightning keys needed to operate a channel as described in BOLT 3
@@ -116,7 +120,7 @@ impl_writeable!(ChannelKeys, 0, {
 /// Cooperative closes may use seed/2'
 /// The two close keys may be needed to claim on-chain funds!
 pub struct KeysManager {
-       secp_ctx: Secp256k1<secp256k1::All>,
+       secp_ctx: Secp256k1<secp256k1::SignOnly>,
        node_secret: SecretKey,
        destination_script: Script,
        shutdown_pubkey: PublicKey,
@@ -124,6 +128,8 @@ pub struct KeysManager {
        channel_child_index: AtomicUsize,
        session_master_key: ExtendedPrivKey,
        session_child_index: AtomicUsize,
+       channel_id_master_key: ExtendedPrivKey,
+       channel_id_child_index: AtomicUsize,
 
        logger: Arc<Logger>,
 }
@@ -132,25 +138,26 @@ impl KeysManager {
        /// Constructs a KeysManager from a 32-byte seed. If the seed is in some way biased (eg your
        /// RNG is busted) this may panic.
        pub fn new(seed: &[u8; 32], network: Network, logger: Arc<Logger>) -> KeysManager {
-               let secp_ctx = Secp256k1::new();
-               match ExtendedPrivKey::new_master(&secp_ctx, network.clone(), seed) {
+               let secp_ctx = Secp256k1::signing_only();
+               match ExtendedPrivKey::new_master(network.clone(), seed) {
                        Ok(master_key) => {
-                               let node_secret = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0)).expect("Your RNG is busted").secret_key;
-                               let destination_script = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1)) {
+                               let node_secret = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0).unwrap()).expect("Your RNG is busted").private_key.key;
+                               let destination_script = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1).unwrap()) {
                                        Ok(destination_key) => {
-                                               let pubkey_hash160 = Hash160::from_data(&ExtendedPubKey::from_private(&secp_ctx, &destination_key).public_key.serialize()[..]);
-                                               Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0)
-                                                             .push_slice(pubkey_hash160.as_bytes())
+                                               let pubkey_hash160 = Hash160::hash(&ExtendedPubKey::from_private(&secp_ctx, &destination_key).public_key.key.serialize()[..]);
+                                               Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0)
+                                                             .push_slice(&pubkey_hash160.into_inner())
                                                              .into_script()
                                        },
                                        Err(_) => panic!("Your RNG is busted"),
                                };
-                               let shutdown_pubkey = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(2)) {
-                                       Ok(shutdown_key) => ExtendedPubKey::from_private(&secp_ctx, &shutdown_key).public_key,
+                               let shutdown_pubkey = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(2).unwrap()) {
+                                       Ok(shutdown_key) => ExtendedPubKey::from_private(&secp_ctx, &shutdown_key).public_key.key,
                                        Err(_) => panic!("Your RNG is busted"),
                                };
-                               let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3)).expect("Your RNG is busted");
-                               let session_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4)).expect("Your RNG is busted");
+                               let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3).unwrap()).expect("Your RNG is busted");
+                               let session_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()).expect("Your RNG is busted");
+                               let channel_id_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap()).expect("Your RNG is busted");
                                KeysManager {
                                        secp_ctx,
                                        node_secret,
@@ -160,6 +167,8 @@ impl KeysManager {
                                        channel_child_index: AtomicUsize::new(0),
                                        session_master_key,
                                        session_child_index: AtomicUsize::new(0),
+                                       channel_id_master_key,
+                                       channel_id_child_index: AtomicUsize::new(0),
 
                                        logger,
                                }
@@ -198,8 +207,8 @@ impl KeysInterface for KeysManager {
                sha.input(&byte_utils::be64_to_array(now.as_secs()));
 
                let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
-               let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32)).expect("Your RNG is busted");
-               sha.input(&child_privkey.secret_key[..]);
+               let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
+               sha.input(&child_privkey.private_key.key[..]);
 
                seed = Sha256::from_engine(sha).into_inner();
 
@@ -215,7 +224,7 @@ impl KeysInterface for KeysManager {
                                sha.input(&seed);
                                sha.input(&$prev_key[..]);
                                sha.input(&$info[..]);
-                               SecretKey::from_slice(&self.secp_ctx, &Sha256::from_engine(sha).into_inner()).expect("SHA-256 is busted")
+                               SecretKey::from_slice(&Sha256::from_engine(sha).into_inner()).expect("SHA-256 is busted")
                        }}
                }
                let funding_key = key_step!(b"funding key", commitment_seed);
@@ -242,8 +251,22 @@ impl KeysInterface for KeysManager {
                sha.input(&byte_utils::be64_to_array(now.as_secs()));
 
                let child_ix = self.session_child_index.fetch_add(1, Ordering::AcqRel);
-               let child_privkey = self.session_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32)).expect("Your RNG is busted");
-               sha.input(&child_privkey.secret_key[..]);
-               SecretKey::from_slice(&self.secp_ctx, &Sha256::from_engine(sha).into_inner()).expect("Your RNG is busted")
+               let child_privkey = self.session_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
+               sha.input(&child_privkey.private_key.key[..]);
+               SecretKey::from_slice(&Sha256::from_engine(sha).into_inner()).expect("Your RNG is busted")
+       }
+
+       fn get_channel_id(&self) -> [u8; 32] {
+               let mut sha = Sha256::engine();
+
+               let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
+               sha.input(&byte_utils::be32_to_array(now.subsec_nanos()));
+               sha.input(&byte_utils::be64_to_array(now.as_secs()));
+
+               let child_ix = self.channel_id_child_index.fetch_add(1, Ordering::AcqRel);
+               let child_privkey = self.channel_id_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
+               sha.input(&child_privkey.private_key.key[..]);
+
+               (Sha256::from_engine(sha).into_inner())
        }
 }