X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fkeysinterface.rs;h=e56ac96f0632bfeb9efe704e6951ccb14c6e723d;hb=151d4ac0a3a6aa94d3f93995b71c874b7ea95967;hp=47ad84bbc596f1de3e0e387df7add2a67ad859a8;hpb=4345aa88ae415e558a177321a87905a134d4e24a;p=rust-lightning diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index 47ad84bb..e56ac96f 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -233,32 +233,28 @@ pub trait ChannelKeys : Send+Clone + Writeable { // TODO: Document the things someone using this interface should enforce before signing. fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()>; - /// Create a signature for a holder's commitment transaction. This will only ever be called with - /// the same commitment_tx (or a copy thereof), though there are currently no guarantees - /// that it will not be called multiple times. + /// Create a signatures for a holder's commitment transaction and its claiming HTLC transactions. + /// This will only ever be called with a non-revoked commitment_tx. This will be called with the + /// latest commitment_tx when we initiate a force-close. + /// This will be called with the previous latest, just to get claiming HTLC signatures, if we are + /// reacting to a ChannelMonitor replica that decided to broadcast before it had been updated to + /// the latest. + /// This may be called multiple times for the same transaction. + /// /// An external signer implementation should check that the commitment has not been revoked. + /// + /// May return Err if key derivation fails. Callers, such as ChannelMonitor, will panic in such a case. // // TODO: Document the things someone using this interface should enforce before signing. - fn sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result; + // TODO: Key derivation failure should panic rather than Err + fn sign_holder_commitment_and_htlcs(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()>; /// Same as sign_holder_commitment, but exists only for tests to get access to holder commitment /// transactions which will be broadcasted later, after the channel has moved on to a newer /// state. Thus, needs its own method as sign_holder_commitment may enforce that we only ever /// get called once. #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))] - fn unsafe_sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result; - - /// Create a signature for each HTLC transaction spending a holder's commitment transaction. - /// - /// Unlike sign_holder_commitment, this may be called multiple times with *different* - /// commitment_tx values. While this will never be called with a revoked - /// commitment_tx, it is possible that it is called with the second-latest - /// commitment_tx (only if we haven't yet revoked it) if some watchtower/secondary - /// ChannelMonitor decided to broadcast before it had been updated to the latest. - /// - /// Either an Err should be returned, or a Vec with one entry for each HTLC which exists in - /// commitment_tx. - fn sign_holder_commitment_htlc_transactions(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result, ()>; + fn unsafe_sign_holder_commitment_and_htlcs(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()>; /// Create a signature for the given input in a transaction spending an HTLC or commitment /// transaction output when our counterparty broadcasts an old state. @@ -344,6 +340,14 @@ pub trait KeysInterface: Send + Sync { /// onion packets and for temporary channel IDs. There is no requirement that these be /// persisted anywhere, though they must be unique across restarts. fn get_secure_random_bytes(&self) -> [u8; 32]; + + /// Reads a `ChanKeySigner` for this `KeysInterface` from the given input stream. + /// This is only called during deserialization of other objects which contain + /// `ChannelKeys`-implementing objects (ie `ChannelMonitor`s and `ChannelManager`s). + /// The bytes are exactly those which `::write()` writes, and + /// contain no versioning scheme. You may wish to include your own version prefix and ensure + /// you've read all of the provided bytes to ensure no corruption occurred. + fn read_chan_signer(&self, reader: &[u8]) -> Result; } #[derive(Clone)] @@ -492,24 +496,25 @@ impl ChannelKeys for InMemoryChannelKeys { Ok((commitment_sig, htlc_sigs)) } - fn sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result { + fn sign_holder_commitment_and_htlcs(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); let funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &self.counterparty_pubkeys().funding_pubkey); - let sig = commitment_tx.trust().built_transaction().sign(&self.funding_key, &funding_redeemscript, self.channel_value_satoshis, secp_ctx); - Ok(sig) + let trusted_tx = commitment_tx.trust(); + let sig = trusted_tx.built_transaction().sign(&self.funding_key, &funding_redeemscript, self.channel_value_satoshis, secp_ctx); + let channel_parameters = self.get_channel_parameters(); + let htlc_sigs = trusted_tx.get_htlc_sigs(&self.htlc_base_key, &channel_parameters.as_holder_broadcastable(), secp_ctx)?; + Ok((sig, htlc_sigs)) } #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))] - fn unsafe_sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result { + fn unsafe_sign_holder_commitment_and_htlcs(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); - let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &self.counterparty_pubkeys().funding_pubkey); - Ok(commitment_tx.trust().built_transaction().sign(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx)) - } - - fn sign_holder_commitment_htlc_transactions(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1) -> Result, ()> { - let channel_parameters = self.get_channel_parameters(); + let funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &self.counterparty_pubkeys().funding_pubkey); let trusted_tx = commitment_tx.trust(); - trusted_tx.get_htlc_sigs(&self.htlc_base_key, &channel_parameters.as_holder_broadcastable(), secp_ctx) + let sig = trusted_tx.built_transaction().sign(&self.funding_key, &funding_redeemscript, self.channel_value_satoshis, secp_ctx); + let channel_parameters = self.get_channel_parameters(); + let htlc_sigs = trusted_tx.get_htlc_sigs(&self.htlc_base_key, &channel_parameters.as_holder_broadcastable(), secp_ctx)?; + Ok((sig, htlc_sigs)) } fn sign_justice_transaction(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option, secp_ctx: &Secp256k1) -> Result { @@ -809,4 +814,8 @@ impl KeysInterface for KeysManager { sha.input(b"Unique Secure Random Bytes Salt"); Sha256::from_engine(sha).into_inner() } + + fn read_chan_signer(&self, reader: &[u8]) -> Result { + InMemoryChannelKeys::read(&mut std::io::Cursor::new(reader)) + } }