Convert remaining channel inner structs and enums to TLV-based ser

This commit is contained in:
Matt Corallo 2021-05-31 16:44:59 +00:00
parent 86641ea680
commit 66784e32fe
4 changed files with 84 additions and 335 deletions

View file

@ -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<HTLCOutputInCommitment> {
#[inline]
fn write<W: Writer>(&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<HTLCOutputInCommitment> {
#[inline]
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
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.

View file

@ -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<W: Writer>(&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<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
Ok(match <u8 as Readable>::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<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {

View file

@ -4317,43 +4317,16 @@ impl PersistenceNotifier {
const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;
impl Writeable for PendingHTLCRouting {
fn write<W: Writer>(&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<R: ::std::io::Read>(reader: &mut R) -> Result<PendingHTLCRouting, DecodeError> {
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<W: Writer>(&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<R: ::std::io::Read>(reader: &mut R) -> Result<HTLCFailureMsg, DecodeError> {
match <u8 as Readable>::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<W: Writer>(&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<R: ::std::io::Read>(reader: &mut R) -> Result<PendingHTLCStatus, DecodeError> {
match <u8 as Readable>::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<W: Writer>(&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_writeable_tlv_based!(ClaimableHTLC, {
(0, prev_hop),
(2, value),
(4, payment_data),
(6, cltv_expiry),
}, {}, {});
impl Readable for ClaimableHTLC {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
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_tlv_based_enum!(HTLCSource,
(0, OutboundRoute) => {
(0, session_priv),
(2, first_hop_htlc_msat),
}, {}, {
(4, path),
};
(1, PreviousHopData)
);
impl Writeable for HTLCSource {
fn write<W: Writer>(&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_writeable_tlv_based_enum!(HTLCFailReason,
(0, LightningError) => {
(0, err),
}, {}, {},
(1, Reason) => {
(0, failure_code),
}, {}, {
(2, data),
},
;);
impl Readable for HTLCSource {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<HTLCSource, DecodeError> {
match <u8 as Readable>::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<W: Writer>(&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<R: ::std::io::Read>(reader: &mut R) -> Result<HTLCFailReason, DecodeError> {
match <u8 as Readable>::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<W: Writer>(&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 Readable for HTLCForwardInfo {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<HTLCForwardInfo, DecodeError> {
match <u8 as Readable>::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!(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),

View file

@ -49,40 +49,14 @@ pub struct RouteHop {
pub cltv_expiry_delta: u32,
}
/// (C-not exported)
impl Writeable for Vec<RouteHop> {
fn write<W: ::util::ser::Writer>(&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<RouteHop> {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Vec<RouteHop>, 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 })