Make Channel::commit_tx_fee_msat static and take fee explicitly
[rust-lightning] / lightning / src / chain / keysinterface.rs
index ee7d4d65972b544db75e842c8de5de1ec527765a..b36694eb126cded8b5048dd1a2f28461eb5c25f6 100644 (file)
@@ -34,7 +34,7 @@ use util::ser::{Writeable, Writer, Readable};
 
 use chain::transaction::OutPoint;
 use ln::chan_utils;
-use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction};
+use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
 use ln::msgs::UnsignedChannelAnnouncement;
 use ln::script::ShutdownScript;
 
@@ -218,7 +218,7 @@ pub trait BaseSign {
        /// secret won't leave us without a broadcastable holder transaction.
        /// Policy checks should be implemented in this function, including checking the amount
        /// sent to us and checking the HTLCs.
-       fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction);
+       fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction) -> Result<(), ()>;
        /// Gets the holder's channel public keys and basepoints
        fn pubkeys(&self) -> &ChannelPublicKeys;
        /// Gets an arbitrary identifier describing the set of keys which are provided back to you in
@@ -239,7 +239,7 @@ pub trait BaseSign {
        ///
        /// This is required in order for the signer to make sure that the state has moved
        /// forward and it is safe to sign the next counterparty commitment.
-       fn validate_counterparty_revocation(&self, idx: u64, secret: &SecretKey);
+       fn validate_counterparty_revocation(&self, idx: u64, secret: &SecretKey) -> Result<(), ()>;
 
        /// 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
@@ -322,7 +322,7 @@ pub trait BaseSign {
        ///
        /// 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, closing_tx: &Transaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
+       fn sign_closing_transaction(&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
 
        /// Signs a channel announcement message with our funding key, proving it comes from one
        /// of the channel participants.
@@ -573,7 +573,8 @@ impl BaseSign for InMemorySigner {
                chan_utils::build_commitment_secret(&self.commitment_seed, idx)
        }
 
-       fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction) {
+       fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction) -> Result<(), ()> {
+               Ok(())
        }
 
        fn pubkeys(&self) -> &ChannelPublicKeys { &self.holder_channel_pubkeys }
@@ -602,7 +603,8 @@ impl BaseSign for InMemorySigner {
                Ok((commitment_sig, htlc_sigs))
        }
 
-       fn validate_counterparty_revocation(&self, _idx: u64, _secret: &SecretKey) {
+       fn validate_counterparty_revocation(&self, _idx: u64, _secret: &SecretKey) -> Result<(), ()> {
+               Ok(())
        }
 
        fn sign_holder_commitment_and_htlcs(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
@@ -669,17 +671,10 @@ impl BaseSign for InMemorySigner {
                Err(())
        }
 
-       fn sign_closing_transaction(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
-               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(()); }
-
+       fn sign_closing_transaction(&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
                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);
-
-               let sighash = hash_to_message!(&bip143::SigHashCache::new(closing_tx)
-                       .signature_hash(0, &channel_funding_redeemscript, self.channel_value_satoshis, SigHashType::All)[..]);
-               Ok(secp_ctx.sign(&sighash, &self.funding_key))
+               Ok(closing_tx.trust().sign(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
        }
 
        fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
@@ -965,7 +960,8 @@ impl KeysManager {
                        input,
                        output: outputs,
                };
-               transaction_utils::maybe_add_change_output(&mut spend_tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script)?;
+               let expected_max_weight =
+                       transaction_utils::maybe_add_change_output(&mut spend_tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script)?;
 
                let mut keys_cache: Option<(InMemorySigner, [u8; 32])> = None;
                let mut input_idx = 0;
@@ -1019,6 +1015,12 @@ impl KeysManager {
                        }
                        input_idx += 1;
                }
+
+               debug_assert!(expected_max_weight >= spend_tx.get_weight());
+               // Note that witnesses with a signature vary somewhat in size, so allow
+               // `expected_max_weight` to overshoot by up to 3 bytes per input.
+               debug_assert!(expected_max_weight <= spend_tx.get_weight() + descriptors.len() * 3);
+
                Ok(spend_tx)
        }
 }