Build witness_script for remote htlc transactions inside
[rust-lightning] / lightning / src / ln / channelmonitor.rs
index 731e7775f085afdb074d732ade90660ebbde4b16..8cfbe4ee882eaada7adaf45bcad8f08d58b58a7f 100644 (file)
@@ -435,12 +435,12 @@ struct LocalSignedTx {
 pub(crate) enum InputMaterial {
        Revoked {
                per_commitment_point: PublicKey,
-               key: SecretKey,
+               per_commitment_key: SecretKey,
                input_descriptor: InputDescriptors,
                amount: u64,
        },
        RemoteHTLC {
-               witness_script: Script,
+               per_commitment_point: PublicKey,
                key: SecretKey,
                preimage: Option<PaymentPreimage>,
                amount: u64,
@@ -458,16 +458,16 @@ pub(crate) enum InputMaterial {
 impl Writeable for InputMaterial  {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
                match self {
-                       &InputMaterial::Revoked { ref per_commitment_point, ref key, ref input_descriptor, ref amount} => {
+                       &InputMaterial::Revoked { ref per_commitment_point, ref per_commitment_key, ref input_descriptor, ref amount} => {
                                writer.write_all(&[0; 1])?;
                                per_commitment_point.write(writer)?;
-                               writer.write_all(&key[..])?;
+                               writer.write_all(&per_commitment_key[..])?;
                                input_descriptor.write(writer)?;
                                writer.write_all(&byte_utils::be64_to_array(*amount))?;
                        },
-                       &InputMaterial::RemoteHTLC { ref witness_script, ref key, ref preimage, ref amount, ref locktime } => {
+                       &InputMaterial::RemoteHTLC { ref per_commitment_point, ref key, ref preimage, ref amount, ref locktime } => {
                                writer.write_all(&[1; 1])?;
-                               witness_script.write(writer)?;
+                               per_commitment_point.write(writer)?;
                                key.write(writer)?;
                                preimage.write(writer)?;
                                writer.write_all(&byte_utils::be64_to_array(*amount))?;
@@ -492,24 +492,24 @@ impl Readable for InputMaterial {
                let input_material = match <u8 as Readable>::read(reader)? {
                        0 => {
                                let per_commitment_point = Readable::read(reader)?;
-                               let key = Readable::read(reader)?;
+                               let per_commitment_key = Readable::read(reader)?;
                                let input_descriptor = Readable::read(reader)?;
                                let amount = Readable::read(reader)?;
                                InputMaterial::Revoked {
                                        per_commitment_point,
-                                       key,
+                                       per_commitment_key,
                                        input_descriptor,
                                        amount
                                }
                        },
                        1 => {
-                               let witness_script = Readable::read(reader)?;
+                               let per_commitment_point = Readable::read(reader)?;
                                let key = Readable::read(reader)?;
                                let preimage = Readable::read(reader)?;
                                let amount = Readable::read(reader)?;
                                let locktime = Readable::read(reader)?;
                                InputMaterial::RemoteHTLC {
-                                       witness_script,
+                                       per_commitment_point,
                                        key,
                                        preimage,
                                        amount,
@@ -1426,7 +1426,6 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                        let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret));
                        let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
                        let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().revocation_basepoint));
-                       let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &self.keys.revocation_base_key()));
                        let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.their_delayed_payment_base_key));
 
                        let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key);
@@ -1435,7 +1434,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                        // First, process non-htlc outputs (to_local & to_remote)
                        for (idx, outp) in tx.output.iter().enumerate() {
                                if outp.script_pubkey == revokeable_p2wsh {
-                                       let witness_data = InputMaterial::Revoked { per_commitment_point, key: revocation_key, input_descriptor: InputDescriptors::RevokedOutput, amount: outp.value };
+                                       let witness_data = InputMaterial::Revoked { per_commitment_point, per_commitment_key, input_descriptor: InputDescriptors::RevokedOutput, amount: outp.value };
                                        claimable_outpoints.push(ClaimRequest { absolute_timelock: height + self.our_to_self_delay as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: idx as u32 }, witness_data});
                                }
                        }
@@ -1448,7 +1447,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                                                                tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
                                                        return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user
                                                }
-                                               let witness_data = InputMaterial::Revoked { per_commitment_point, key: revocation_key, input_descriptor: if htlc.offered { InputDescriptors::RevokedOfferedHTLC } else { InputDescriptors::RevokedReceivedHTLC }, amount: tx.output[transaction_output_index as usize].value };
+                                               let witness_data = InputMaterial::Revoked { per_commitment_point, per_commitment_key, input_descriptor: if htlc.offered { InputDescriptors::RevokedOfferedHTLC } else { InputDescriptors::RevokedReceivedHTLC }, amount: tx.output[transaction_output_index as usize].value };
                                                claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
                                        }
                                }
@@ -1566,24 +1565,26 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                                                if revocation_points.0 == commitment_number + 1 { Some(point) } else { None }
                                        } else { None };
                                if let Some(revocation_point) = revocation_point_option {
-                                       let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &self.keys.pubkeys().revocation_basepoint));
-                                       let b_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &self.keys.pubkeys().htlc_basepoint));
                                        let htlc_privkey = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, revocation_point, &self.keys.htlc_base_key()));
-                                       let a_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &self.their_htlc_base_key));
+
+                                       self.remote_payment_script = {
+                                               // Note that the Network here is ignored as we immediately drop the address for the
+                                               // script_pubkey version
+                                               let payment_hash160 = WPubkeyHash::hash(&PublicKey::from_secret_key(&self.secp_ctx, &self.keys.payment_key()).serialize());
+                                               Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_hash160[..]).into_script()
+                                       };
 
                                        // Then, try to find htlc outputs
                                        for (_, &(ref htlc, _)) in per_commitment_data.iter().enumerate() {
                                                if let Some(transaction_output_index) = htlc.transaction_output_index {
-                                                       let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
                                                        if transaction_output_index as usize >= tx.output.len() ||
-                                                                       tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 ||
-                                                                       tx.output[transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() {
+                                                                       tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
                                                                return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user
                                                        }
                                                        let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
                                                        let aggregable = if !htlc.offered { false } else { true };
                                                        if preimage.is_some() || !htlc.offered {
-                                                               let witness_data = InputMaterial::RemoteHTLC { witness_script: expected_script, key: htlc_privkey, preimage, amount: htlc.amount_msat / 1000, locktime: htlc.cltv_expiry };
+                                                               let witness_data = InputMaterial::RemoteHTLC { per_commitment_point: *revocation_point, key: htlc_privkey, preimage, amount: htlc.amount_msat / 1000, locktime: htlc.cltv_expiry };
                                                                claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
                                                        }
                                                }
@@ -1613,10 +1614,9 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                let secret = if let Some(secret) = self.get_secret(commitment_number) { secret } else { return (Vec::new(), None); };
                let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret));
                let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
-               let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &self.keys.revocation_base_key()));
 
                log_trace!(logger, "Remote HTLC broadcast {}:{}", htlc_txid, 0);
-               let witness_data = InputMaterial::Revoked { per_commitment_point, key: revocation_key, input_descriptor: InputDescriptors::RevokedOutput, amount: tx.output[0].value };
+               let witness_data = InputMaterial::Revoked { per_commitment_point, per_commitment_key, input_descriptor: InputDescriptors::RevokedOutput, amount: tx.output[0].value };
                let claimable_outpoints = vec!(ClaimRequest { absolute_timelock: height + self.our_to_self_delay as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: htlc_txid, vout: 0}, witness_data });
                (claimable_outpoints, Some((htlc_txid, tx.output.clone())))
        }