From 66784e32fe454e9a5b2080b85fc4d8816ac5e436 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 31 May 2021 16:44:59 +0000 Subject: [PATCH] Convert remaining channel inner structs and enums to TLV-based ser --- lightning/src/ln/chan_utils.rs | 47 +---- lightning/src/ln/channel.rs | 36 +--- lightning/src/ln/channelmanager.rs | 286 ++++++----------------------- lightning/src/routing/router.rs | 54 ++---- 4 files changed, 86 insertions(+), 337 deletions(-) diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index 81b0df09..b698558e 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -22,7 +22,7 @@ use bitcoin::hash_types::{Txid, PubkeyHash}; use ln::{PaymentHash, PaymentPreimage}; use ln::msgs::DecodeError; -use util::ser::{Readable, Writeable, Writer, MAX_BUF_SIZE}; +use util::ser::{Readable, Writeable, Writer}; use util::byte_utils; use bitcoin::hash_types::WPubkeyHash; @@ -36,18 +36,11 @@ use core::cmp; use ln::chan_utils; use util::transaction_utils::sort_outputs; use ln::channel::INITIAL_COMMITMENT_NUMBER; -use std::io::Read; use core::ops::Deref; use chain; -// Maximum size of a serialized HTLCOutputInCommitment -pub(crate) const HTLC_OUTPUT_IN_COMMITMENT_SIZE: usize = 1 + 8 + 4 + 32 + 5; - pub(crate) const MAX_HTLCS: u16 = 483; -// This checks that the buffer size is greater than the maximum possible size for serialized HTLCS -const _EXCESS_BUFFER_SIZE: usize = MAX_BUF_SIZE - MAX_HTLCS as usize * HTLC_OUTPUT_IN_COMMITMENT_SIZE; - pub(super) const HTLC_SUCCESS_TX_WEIGHT: u64 = 703; pub(super) const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663; @@ -866,44 +859,16 @@ impl PartialEq for CommitmentTransaction { } } -/// (C-not exported) as users never need to call this directly -impl Writeable for Vec { - #[inline] - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { - (self.len() as u16).write(w)?; - for e in self.iter() { - e.write(w)?; - } - Ok(()) - } -} - -/// (C-not exported) as users never need to call this directly -impl Readable for Vec { - #[inline] - fn read(r: &mut R) -> Result { - let len: u16 = Readable::read(r)?; - let byte_size = (len as usize) - .checked_mul(HTLC_OUTPUT_IN_COMMITMENT_SIZE) - .ok_or(DecodeError::BadLengthDescriptor)?; - if byte_size > MAX_BUF_SIZE { - return Err(DecodeError::BadLengthDescriptor); - } - let mut ret = Vec::with_capacity(len as usize); - for _ in 0..len { ret.push(HTLCOutputInCommitment::read(r)?); } - Ok(ret) - } -} - impl_writeable_tlv_based!(CommitmentTransaction, { (0, commitment_number), (2, to_broadcaster_value_sat), (4, to_countersignatory_value_sat), (6, feerate_per_kw), - (8, htlcs), - (10, keys), - (12, built), -}, {}, {}); + (8, keys), + (10, built), +}, {}, { + (12, htlcs), +}); impl CommitmentTransaction { /// Construct an object of the class while assigning transaction output indices to HTLCs. diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 40b73c3b..07293a10 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -4382,37 +4382,11 @@ fn is_unsupported_shutdown_script(their_features: &InitFeatures, script: &Script const SERIALIZATION_VERSION: u8 = 1; const MIN_SERIALIZATION_VERSION: u8 = 1; -impl Writeable for InboundHTLCRemovalReason { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match self { - &InboundHTLCRemovalReason::FailRelay(ref error_packet) => { - 0u8.write(writer)?; - error_packet.write(writer)?; - }, - &InboundHTLCRemovalReason::FailMalformed((ref onion_hash, ref err_code)) => { - 1u8.write(writer)?; - onion_hash.write(writer)?; - err_code.write(writer)?; - }, - &InboundHTLCRemovalReason::Fulfill(ref payment_preimage) => { - 2u8.write(writer)?; - payment_preimage.write(writer)?; - }, - } - Ok(()) - } -} - -impl Readable for InboundHTLCRemovalReason { - fn read(reader: &mut R) -> Result { - Ok(match ::read(reader)? { - 0 => InboundHTLCRemovalReason::FailRelay(Readable::read(reader)?), - 1 => InboundHTLCRemovalReason::FailMalformed((Readable::read(reader)?, Readable::read(reader)?)), - 2 => InboundHTLCRemovalReason::Fulfill(Readable::read(reader)?), - _ => return Err(DecodeError::InvalidValue), - }) - } -} +impl_writeable_tlv_based_enum!(InboundHTLCRemovalReason,; + (0, FailRelay), + (1, FailMalformed), + (2, Fulfill), +); impl Writeable for ChannelUpdateStatus { fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 9c1f8ecf..7ab1d2b4 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4317,43 +4317,16 @@ impl PersistenceNotifier { const SERIALIZATION_VERSION: u8 = 1; const MIN_SERIALIZATION_VERSION: u8 = 1; -impl Writeable for PendingHTLCRouting { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match &self { - &PendingHTLCRouting::Forward { ref onion_packet, ref short_channel_id } => { - 0u8.write(writer)?; - onion_packet.write(writer)?; - short_channel_id.write(writer)?; - }, - &PendingHTLCRouting::Receive { ref payment_data, ref incoming_cltv_expiry } => { - 1u8.write(writer)?; - payment_data.payment_secret.write(writer)?; - payment_data.total_msat.write(writer)?; - incoming_cltv_expiry.write(writer)?; - }, - } - Ok(()) - } -} - -impl Readable for PendingHTLCRouting { - fn read(reader: &mut R) -> Result { - match Readable::read(reader)? { - 0u8 => Ok(PendingHTLCRouting::Forward { - onion_packet: Readable::read(reader)?, - short_channel_id: Readable::read(reader)?, - }), - 1u8 => Ok(PendingHTLCRouting::Receive { - payment_data: msgs::FinalOnionHopData { - payment_secret: Readable::read(reader)?, - total_msat: Readable::read(reader)?, - }, - incoming_cltv_expiry: Readable::read(reader)?, - }), - _ => Err(DecodeError::InvalidValue), - } - } -} +impl_writeable_tlv_based_enum!(PendingHTLCRouting, + (0, Forward) => { + (0, onion_packet), + (2, short_channel_id), + }, {}, {}, + (1, Receive) => { + (0, payment_data), + (2, incoming_cltv_expiry), + }, {}, {} +;); impl_writeable_tlv_based!(PendingHTLCInfo, { (0, routing), @@ -4363,57 +4336,14 @@ impl_writeable_tlv_based!(PendingHTLCInfo, { (8, outgoing_cltv_value) }, {}, {}); -impl Writeable for HTLCFailureMsg { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match self { - &HTLCFailureMsg::Relay(ref fail_msg) => { - 0u8.write(writer)?; - fail_msg.write(writer)?; - }, - &HTLCFailureMsg::Malformed(ref fail_msg) => { - 1u8.write(writer)?; - fail_msg.write(writer)?; - } - } - Ok(()) - } -} - -impl Readable for HTLCFailureMsg { - fn read(reader: &mut R) -> Result { - match ::read(reader)? { - 0 => Ok(HTLCFailureMsg::Relay(Readable::read(reader)?)), - 1 => Ok(HTLCFailureMsg::Malformed(Readable::read(reader)?)), - _ => Err(DecodeError::InvalidValue), - } - } -} - -impl Writeable for PendingHTLCStatus { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match self { - &PendingHTLCStatus::Forward(ref forward_info) => { - 0u8.write(writer)?; - forward_info.write(writer)?; - }, - &PendingHTLCStatus::Fail(ref fail_msg) => { - 1u8.write(writer)?; - fail_msg.write(writer)?; - } - } - Ok(()) - } -} - -impl Readable for PendingHTLCStatus { - fn read(reader: &mut R) -> Result { - match ::read(reader)? { - 0 => Ok(PendingHTLCStatus::Forward(Readable::read(reader)?)), - 1 => Ok(PendingHTLCStatus::Fail(Readable::read(reader)?)), - _ => Err(DecodeError::InvalidValue), - } - } -} +impl_writeable_tlv_based_enum!(HTLCFailureMsg, ; + (0, Relay), + (1, Malformed), +); +impl_writeable_tlv_based_enum!(PendingHTLCStatus, ; + (0, Forward), + (1, Fail), +); impl_writeable_tlv_based!(HTLCPreviousHopData, { (0, short_channel_id), @@ -4422,148 +4352,46 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, { (6, incoming_packet_shared_secret) }, {}, {}); -impl Writeable for ClaimableHTLC { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - write_tlv_fields!(writer, { - (0, self.prev_hop), - (2, self.value), - (4, self.payment_data.payment_secret), - (6, self.payment_data.total_msat), - (8, self.cltv_expiry) - }, {}); - Ok(()) - } -} - -impl Readable for ClaimableHTLC { - fn read(reader: &mut R) -> Result { - let mut prev_hop = HTLCPreviousHopData { - short_channel_id: 0, htlc_id: 0, - incoming_packet_shared_secret: [0; 32], - outpoint: OutPoint::null(), - }; - let mut value = 0; - let mut payment_secret = PaymentSecret([0; 32]); - let mut total_msat = 0; - let mut cltv_expiry = 0; - read_tlv_fields!(reader, { - (0, prev_hop), - (2, value), - (4, payment_secret), - (6, total_msat), - (8, cltv_expiry) - }, {}); - Ok(ClaimableHTLC { - prev_hop, - value, - payment_data: msgs::FinalOnionHopData { - payment_secret, - total_msat, - }, - cltv_expiry, - }) - } -} - -impl Writeable for HTLCSource { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match self { - &HTLCSource::PreviousHopData(ref hop_data) => { - 0u8.write(writer)?; - hop_data.write(writer)?; - }, - &HTLCSource::OutboundRoute { ref path, ref session_priv, ref first_hop_htlc_msat } => { - 1u8.write(writer)?; - path.write(writer)?; - session_priv.write(writer)?; - first_hop_htlc_msat.write(writer)?; - } - } - Ok(()) - } -} - -impl Readable for HTLCSource { - fn read(reader: &mut R) -> Result { - match ::read(reader)? { - 0 => Ok(HTLCSource::PreviousHopData(Readable::read(reader)?)), - 1 => Ok(HTLCSource::OutboundRoute { - path: Readable::read(reader)?, - session_priv: Readable::read(reader)?, - first_hop_htlc_msat: Readable::read(reader)?, - }), - _ => Err(DecodeError::InvalidValue), - } - } -} - -impl Writeable for HTLCFailReason { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match self { - &HTLCFailReason::LightningError { ref err } => { - 0u8.write(writer)?; - err.write(writer)?; - }, - &HTLCFailReason::Reason { ref failure_code, ref data } => { - 1u8.write(writer)?; - failure_code.write(writer)?; - data.write(writer)?; - } - } - Ok(()) - } -} - -impl Readable for HTLCFailReason { - fn read(reader: &mut R) -> Result { - match ::read(reader)? { - 0 => Ok(HTLCFailReason::LightningError { err: Readable::read(reader)? }), - 1 => Ok(HTLCFailReason::Reason { - failure_code: Readable::read(reader)?, - data: Readable::read(reader)?, - }), - _ => Err(DecodeError::InvalidValue), - } - } -} - -impl Writeable for HTLCForwardInfo { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match self { - &HTLCForwardInfo::AddHTLC { ref prev_short_channel_id, ref prev_funding_outpoint, ref prev_htlc_id, ref forward_info } => { - 0u8.write(writer)?; - prev_short_channel_id.write(writer)?; - prev_funding_outpoint.write(writer)?; - prev_htlc_id.write(writer)?; - forward_info.write(writer)?; - }, - &HTLCForwardInfo::FailHTLC { ref htlc_id, ref err_packet } => { - 1u8.write(writer)?; - htlc_id.write(writer)?; - err_packet.write(writer)?; - }, - } - Ok(()) - } -} +impl_writeable_tlv_based!(ClaimableHTLC, { + (0, prev_hop), + (2, value), + (4, payment_data), + (6, cltv_expiry), +}, {}, {}); -impl Readable for HTLCForwardInfo { - fn read(reader: &mut R) -> Result { - match ::read(reader)? { - 0 => Ok(HTLCForwardInfo::AddHTLC { - prev_short_channel_id: Readable::read(reader)?, - prev_funding_outpoint: Readable::read(reader)?, - prev_htlc_id: Readable::read(reader)?, - forward_info: Readable::read(reader)?, - }), - 1 => Ok(HTLCForwardInfo::FailHTLC { - htlc_id: Readable::read(reader)?, - err_packet: Readable::read(reader)?, - }), - _ => Err(DecodeError::InvalidValue), - } - } -} +impl_writeable_tlv_based_enum!(HTLCSource, + (0, OutboundRoute) => { + (0, session_priv), + (2, first_hop_htlc_msat), + }, {}, { + (4, path), + }; + (1, PreviousHopData) +); + +impl_writeable_tlv_based_enum!(HTLCFailReason, + (0, LightningError) => { + (0, err), + }, {}, {}, + (1, Reason) => { + (0, failure_code), + }, {}, { + (2, data), + }, +;); + +impl_writeable_tlv_based_enum!(HTLCForwardInfo, + (0, AddHTLC) => { + (0, forward_info), + (2, prev_short_channel_id), + (4, prev_htlc_id), + (6, prev_funding_outpoint), + }, {}, {}, + (1, FailHTLC) => { + (0, htlc_id), + (2, err_packet), + }, {}, {}, +;); impl_writeable_tlv_based!(PendingInboundPayment, { (0, payment_secret), diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 3bda19fd..6d481651 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -49,40 +49,14 @@ pub struct RouteHop { pub cltv_expiry_delta: u32, } -/// (C-not exported) -impl Writeable for Vec { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - (self.len() as u8).write(writer)?; - for hop in self.iter() { - hop.pubkey.write(writer)?; - hop.node_features.write(writer)?; - hop.short_channel_id.write(writer)?; - hop.channel_features.write(writer)?; - hop.fee_msat.write(writer)?; - hop.cltv_expiry_delta.write(writer)?; - } - Ok(()) - } -} - -/// (C-not exported) -impl Readable for Vec { - fn read(reader: &mut R) -> Result, DecodeError> { - let hops_count: u8 = Readable::read(reader)?; - let mut hops = Vec::with_capacity(hops_count as usize); - for _ in 0..hops_count { - hops.push(RouteHop { - pubkey: Readable::read(reader)?, - node_features: Readable::read(reader)?, - short_channel_id: Readable::read(reader)?, - channel_features: Readable::read(reader)?, - fee_msat: Readable::read(reader)?, - cltv_expiry_delta: Readable::read(reader)?, - }); - } - Ok(hops) - } -} +impl_writeable_tlv_based!(RouteHop, { + (0, pubkey), + (2, node_features), + (4, short_channel_id), + (6, channel_features), + (8, fee_msat), + (10, cltv_expiry_delta), +}, {}, {}); /// A route directs a payment from the sender (us) to the recipient. If the recipient supports MPP, /// it can take multiple paths. Each path is composed of one or more hops through the network. @@ -105,7 +79,10 @@ impl Writeable for Route { write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION); (self.paths.len() as u64).write(writer)?; for hops in self.paths.iter() { - hops.write(writer)?; + (hops.len() as u8).write(writer)?; + for hop in hops.iter() { + hop.write(writer)?; + } } write_tlv_fields!(writer, {}, {}); Ok(()) @@ -118,7 +95,12 @@ impl Readable for Route { let path_count: u64 = Readable::read(reader)?; let mut paths = Vec::with_capacity(cmp::min(path_count, 128) as usize); for _ in 0..path_count { - paths.push(Readable::read(reader)?); + let hop_count: u8 = Readable::read(reader)?; + let mut hops = Vec::with_capacity(hop_count as usize); + for _ in 0..hop_count { + hops.push(Readable::read(reader)?); + } + paths.push(hops); } read_tlv_fields!(reader, {}, {}); Ok(Route { paths }) -- 2.30.2