Add anchor support to commitment HTLC outputs
[rust-lightning] / lightning / src / chain / onchaintx.rs
index cd28314651057d3659ee64dc5f2141935595b96b..6f64f3eec56210b3e383dd0a15b87368946a2201 100644 (file)
@@ -29,9 +29,10 @@ use chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER};
 use chain::keysinterface::{Sign, KeysInterface};
 use chain::package::PackageTemplate;
 use util::logger::Logger;
-use util::ser::{Readable, ReadableArgs, Writer, Writeable, VecWriter};
+use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, VecWriter};
 use util::byte_utils;
 
+use io;
 use prelude::*;
 use alloc::collections::BTreeMap;
 use core::cmp;
@@ -78,23 +79,46 @@ enum OnchainEvent {
        }
 }
 
-impl_writeable_tlv_based!(OnchainEventEntry, {
-       (0, txid, required),
-       (2, height, required),
-       (4, event, required),
-});
+impl Writeable for OnchainEventEntry {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               write_tlv_fields!(writer, {
+                       (0, self.txid, required),
+                       (2, self.height, required),
+                       (4, self.event, required),
+               });
+               Ok(())
+       }
+}
+
+impl MaybeReadable for OnchainEventEntry {
+       fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
+               let mut txid = Default::default();
+               let mut height = 0;
+               let mut event = None;
+               read_tlv_fields!(reader, {
+                       (0, txid, required),
+                       (2, height, required),
+                       (4, event, ignorable),
+               });
+               if let Some(ev) = event {
+                       Ok(Some(Self { txid, height, event: ev }))
+               } else {
+                       Ok(None)
+               }
+       }
+}
 
-impl_writeable_tlv_based_enum!(OnchainEvent,
+impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
        (0, Claim) => {
                (0, claim_request, required),
        },
        (1, ContentiousOutpoint) => {
                (0, package, required),
        },
-;);
+);
 
 impl Readable for Option<Vec<Option<(usize, Signature)>>> {
-       fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+       fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
                match Readable::read(reader)? {
                        0u8 => Ok(None),
                        1u8 => {
@@ -115,7 +139,7 @@ impl Readable for Option<Vec<Option<(usize, Signature)>>> {
 }
 
 impl Writeable for Option<Vec<Option<(usize, Signature)>>> {
-       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                match self {
                        &Some(ref vec) => {
                                1u8.write(writer)?;
@@ -191,7 +215,7 @@ const SERIALIZATION_VERSION: u8 = 1;
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
 impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
-       pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+       pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
 
                self.destination_script.write(writer)?;
@@ -242,7 +266,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
 }
 
 impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::Signer> {
-       fn read<R: ::std::io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
+       fn read<R: io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let destination_script = Readable::read(reader)?;
@@ -285,7 +309,7 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::Signer> {
                for _ in 0..locktimed_packages_len {
                        let locktime = Readable::read(reader)?;
                        let packages_len: u64 = Readable::read(reader)?;
-                       let mut packages = Vec::with_capacity(cmp::min(packages_len as usize, MAX_ALLOC_SIZE / std::mem::size_of::<PackageTemplate>()));
+                       let mut packages = Vec::with_capacity(cmp::min(packages_len as usize, MAX_ALLOC_SIZE / core::mem::size_of::<PackageTemplate>()));
                        for _ in 0..packages_len {
                                packages.push(Readable::read(reader)?);
                        }
@@ -295,7 +319,9 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::Signer> {
                let waiting_threshold_conf_len: u64 = Readable::read(reader)?;
                let mut onchain_events_awaiting_threshold_conf = Vec::with_capacity(cmp::min(waiting_threshold_conf_len as usize, MAX_ALLOC_SIZE / 128));
                for _ in 0..waiting_threshold_conf_len {
-                       onchain_events_awaiting_threshold_conf.push(Readable::read(reader)?);
+                       if let Some(val) = MaybeReadable::read(reader)? {
+                               onchain_events_awaiting_threshold_conf.push(val);
+                       }
                }
 
                read_tlv_fields!(reader, {});
@@ -339,6 +365,14 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                }
        }
 
+       pub(crate) fn get_prev_holder_commitment_to_self_value(&self) -> Option<u64> {
+               self.prev_holder_commitment.as_ref().map(|commitment| commitment.to_broadcaster_value_sat())
+       }
+
+       pub(crate) fn get_cur_holder_commitment_to_self_value(&self) -> u64 {
+               self.holder_commitment.to_broadcaster_value_sat()
+       }
+
        /// Lightning security model (i.e being able to redeem/timeout HTLC or penalize coutnerparty onchain) lays on the assumption of claim transactions getting confirmed before timelock expiration
        /// (CSV or CLTV following cases). In case of high-fee spikes, claim tx may stuck in the mempool, so you need to bump its feerate quickly using Replace-By-Fee or Child-Pay-For-Parent.
        /// Panics if there are signing errors, because signing operations in reaction to on-chain events
@@ -354,7 +388,8 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                let new_timer = Some(cached_request.get_height_timer(cur_height));
                if cached_request.is_malleable() {
                        let predicted_weight = cached_request.package_weight(&self.destination_script);
-                       if let Some((output_value, new_feerate)) = cached_request.compute_package_output(predicted_weight, fee_estimator, logger) {
+                       if let Some((output_value, new_feerate)) =
+                                       cached_request.compute_package_output(predicted_weight, self.destination_script.dust_value().as_sat(), fee_estimator, logger) {
                                assert!(new_feerate != 0);
 
                                let transaction = cached_request.finalize_package(self, output_value, self.destination_script.clone(), logger).unwrap();
@@ -751,6 +786,10 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                htlc_tx
        }
 
+       pub(crate) fn opt_anchors(&self) -> bool {
+               self.channel_transaction_parameters.opt_anchors.is_some()
+       }
+
        #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
        pub(crate) fn unsafe_get_fully_signed_htlc_tx(&mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>) -> Option<Transaction> {
                let latest_had_sigs = self.holder_htlc_sigs.is_some();