X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fpackage.rs;h=bd983ecd9163589b19b12f85199c9d851d0fb5f0;hb=2eb7db9ace08b57bfedbdac2b26961897b032e0b;hp=bb44604317f630f97e911d5cd158b6802851e8b4;hpb=56491d91bbc2d73b97e222ccb33b69f8e17cd4a2;p=rust-lightning diff --git a/lightning/src/chain/package.rs b/lightning/src/chain/package.rs index bb4460431..bd983ecd9 100644 --- a/lightning/src/chain/package.rs +++ b/lightning/src/chain/package.rs @@ -387,68 +387,32 @@ impl PackageSolvingData { _ => { panic!("API Error!"); } } } -} - -impl Writeable for PackageSolvingData { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match self { - PackageSolvingData::RevokedOutput(ref revoked_outp) => { - 0u8.write(writer)?; - revoked_outp.write(writer)?; - }, - PackageSolvingData::RevokedHTLCOutput(ref revoked_outp) => { - 1u8.write(writer)?; - revoked_outp.write(writer)?; - }, - PackageSolvingData::CounterpartyOfferedHTLCOutput(ref counterparty_outp) => { - 2u8.write(writer)?; - counterparty_outp.write(writer)?; - }, - PackageSolvingData::CounterpartyReceivedHTLCOutput(ref counterparty_outp) => { - 3u8.write(writer)?; - counterparty_outp.write(writer)?; - }, - PackageSolvingData::HolderHTLCOutput(ref holder_outp) => { - 4u8.write(writer)?; - holder_outp.write(writer)?; - }, - PackageSolvingData::HolderFundingOutput(ref funding_outp) => { - 5u8.write(writer)?; - funding_outp.write(writer)?; - } - } - Ok(()) - } -} - -impl Readable for PackageSolvingData { - fn read(reader: &mut R) -> Result { - let byte = ::read(reader)?; - let solving_data = match byte { - 0 => { - PackageSolvingData::RevokedOutput(Readable::read(reader)?) - }, - 1 => { - PackageSolvingData::RevokedHTLCOutput(Readable::read(reader)?) - }, - 2 => { - PackageSolvingData::CounterpartyOfferedHTLCOutput(Readable::read(reader)?) - }, - 3 => { - PackageSolvingData::CounterpartyReceivedHTLCOutput(Readable::read(reader)?) - }, - 4 => { - PackageSolvingData::HolderHTLCOutput(Readable::read(reader)?) - }, - 5 => { - PackageSolvingData::HolderFundingOutput(Readable::read(reader)?) - } - _ => return Err(DecodeError::UnknownVersion) + fn absolute_tx_timelock(&self, output_conf_height: u32) -> u32 { + // Get the absolute timelock at which this output can be spent given the height at which + // this output was confirmed. We use `output_conf_height + 1` as a safe default as we can + // be confirmed in the next block and transactions with time lock `current_height + 1` + // always propagate. + let absolute_timelock = match self { + PackageSolvingData::RevokedOutput(_) => output_conf_height + 1, + PackageSolvingData::RevokedHTLCOutput(_) => output_conf_height + 1, + PackageSolvingData::CounterpartyOfferedHTLCOutput(_) => output_conf_height + 1, + PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => std::cmp::max(outp.htlc.cltv_expiry, output_conf_height + 1), + PackageSolvingData::HolderHTLCOutput(ref outp) => std::cmp::max(outp.cltv_expiry, output_conf_height + 1), + PackageSolvingData::HolderFundingOutput(_) => output_conf_height + 1, }; - Ok(solving_data) + absolute_timelock } } +impl_writeable_tlv_based_enum!(PackageSolvingData, ; + (0, RevokedOutput), + (1, RevokedHTLCOutput), + (2, CounterpartyOfferedHTLCOutput), + (3, CounterpartyReceivedHTLCOutput), + (4, HolderHTLCOutput), + (5, HolderFundingOutput), +); + /// A malleable package might be aggregated with other packages to save on fees. /// A untractable package has been counter-signed and aggregable will break cached counterparty /// signatures. @@ -598,6 +562,10 @@ impl PackageTemplate { } amounts } + pub(crate) fn package_timelock(&self) -> u32 { + self.inputs.iter().map(|(_, outp)| outp.absolute_tx_timelock(self.height_original)) + .max().expect("There must always be at least one output to spend in a PackageTemplate") + } pub(crate) fn package_weight(&self, destination_script: &Script) -> usize { let mut inputs_weight = 0; let mut witnesses_weight = 2; // count segwit flags