X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fkeysinterface.rs;h=f5a919bc22528c76caa9603e10ceec6ba42abb1a;hb=ebb55ff2aae55146239ff8fecd79c02ea4c3580f;hp=b65cd0df77d3a150011d53c321ccb1fec406c96c;hpb=6c9180f9729cb9785892cc2d844dcc42821d6ff9;p=rust-lightning diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index b65cd0df..f5a919bc 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -99,7 +99,7 @@ pub trait KeysInterface: Send + Sync { fn get_shutdown_pubkey(&self) -> PublicKey; /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you /// restarted with some stale data! - fn get_channel_keys(&self, inbound: bool) -> Self::ChanKeySigner; + fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner; /// Get a secret and PRNG seed for construting an onion packet fn get_onion_rand(&self) -> (SecretKey, [u8; 32]); /// Get a unique temporary channel id. Channels will be referred to by this until the funding @@ -155,13 +155,13 @@ pub trait ChannelKeys : Send { /// TODO: Document the things someone using this interface should enforce before signing. /// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and /// making the callee generate it via some util function we expose)! - fn sign_remote_commitment(&self, channel_value_satoshis: u64, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()>; + fn sign_remote_commitment(&self, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()>; /// Create a signature for a (proposed) closing transaction. /// /// Note that, due to rounding, there may be one "missing" satoshi, and either party may have /// chosen to forgo their output as dust. - fn sign_closing_transaction(&self, channel_value_satoshis: u64, channel_funding_redeemscript: &Script, closing_tx: &Transaction, secp_ctx: &Secp256k1) -> Result; + fn sign_closing_transaction(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1) -> Result; /// Signs a channel announcement message with our funding key, proving it comes from one /// of the channel participants. @@ -193,8 +193,10 @@ pub struct InMemoryChannelKeys { pub htlc_base_key: SecretKey, /// Commitment seed pub commitment_seed: [u8; 32], - /// Remote funding pubkey + /// Remote public keys and base points pub remote_channel_pubkeys: Option, + /// The total value of this channel + pub channel_value_satoshis: u64, } impl ChannelKeys for InMemoryChannelKeys { @@ -205,14 +207,14 @@ impl ChannelKeys for InMemoryChannelKeys { fn htlc_base_key(&self) -> &SecretKey { &self.htlc_base_key } fn commitment_seed(&self) -> &[u8; 32] { &self.commitment_seed } - fn sign_remote_commitment(&self, channel_value_satoshis: u64, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { + fn sign_remote_commitment(&self, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { if commitment_tx.input.len() != 1 { return Err(()); } let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); - let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_redeemscript, channel_value_satoshis)[..]); + let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]); let commitment_sig = secp_ctx.sign(&commitment_sighash, &self.funding_key); let commitment_txid = commitment_tx.txid(); @@ -234,13 +236,17 @@ impl ChannelKeys for InMemoryChannelKeys { Ok((commitment_sig, htlc_sigs)) } - fn sign_closing_transaction(&self, channel_value_satoshis: u64, channel_funding_redeemscript: &Script, closing_tx: &Transaction, secp_ctx: &Secp256k1) -> Result { + fn sign_closing_transaction(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1) -> Result { if closing_tx.input.len() != 1 { return Err(()); } if closing_tx.input[0].witness.len() != 0 { return Err(()); } if closing_tx.output.len() > 2 { return Err(()); } + let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); + let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); + let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); + let sighash = hash_to_message!(&bip143::SighashComponents::new(closing_tx) - .sighash_all(&closing_tx.input[0], &channel_funding_redeemscript, channel_value_satoshis)[..]); + .sighash_all(&closing_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]); Ok(secp_ctx.sign(&sighash, &self.funding_key)) } @@ -262,7 +268,8 @@ impl_writeable!(InMemoryChannelKeys, 0, { delayed_payment_base_key, htlc_base_key, commitment_seed, - remote_channel_pubkeys + remote_channel_pubkeys, + channel_value_satoshis }); /// Simple KeysInterface implementor that takes a 32-byte seed for use as a BIP 32 extended key @@ -371,7 +378,7 @@ impl KeysInterface for KeysManager { self.shutdown_pubkey.clone() } - fn get_channel_keys(&self, _inbound: bool) -> InMemoryChannelKeys { + fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> InMemoryChannelKeys { // We only seriously intend to rely on the channel_master_key for true secure // entropy, everything else just ensures uniqueness. We rely on the unique_start (ie // starting_time provided in the constructor) to be unique. @@ -412,6 +419,7 @@ impl KeysInterface for KeysManager { htlc_base_key, commitment_seed, remote_channel_pubkeys: None, + channel_value_satoshis, } }