From 6dc9076e664a47486610cdc4572e4f43527426af Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 5 Jul 2021 23:21:36 +0000 Subject: [PATCH] Implement the closing_signed TLV suffix with allowed fee ranges This adds the serialization and structures for the new fee range specifiers in closing_signed as added upstream at https://github.com/lightningnetwork/lightning-rfc/pull/847 --- fuzz/src/msg_targets/gen_target.sh | 2 +- fuzz/src/msg_targets/mod.rs | 2 +- fuzz/src/msg_targets/msg_closing_signed.rs | 4 +- lightning/src/ln/channel.rs | 3 + lightning/src/ln/msgs.rs | 66 ++++++++++++++++++++-- 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/fuzz/src/msg_targets/gen_target.sh b/fuzz/src/msg_targets/gen_target.sh index 044f1a1e..0c1d061a 100755 --- a/fuzz/src/msg_targets/gen_target.sh +++ b/fuzz/src/msg_targets/gen_target.sh @@ -14,7 +14,6 @@ echo "mod utils;" > mod.rs GEN_TEST AcceptChannel test_msg "" GEN_TEST AnnouncementSignatures test_msg "" GEN_TEST ChannelReestablish test_msg "" -GEN_TEST ClosingSigned test_msg "" GEN_TEST CommitmentSigned test_msg "" GEN_TEST DecodedOnionErrorPacket test_msg "" GEN_TEST FundingCreated test_msg "" @@ -40,6 +39,7 @@ GEN_TEST UpdateAddHTLC test_msg_hole ", 85, 33" GEN_TEST ErrorMessage test_msg_hole ", 32, 2" GEN_TEST ChannelUpdate test_msg_hole ", 108, 1" +GEN_TEST ClosingSigned test_msg_simple "" GEN_TEST Init test_msg_simple "" GEN_TEST OnionHopData test_msg_simple "" GEN_TEST Ping test_msg_simple "" diff --git a/fuzz/src/msg_targets/mod.rs b/fuzz/src/msg_targets/mod.rs index e11e3eb2..0f273cb7 100644 --- a/fuzz/src/msg_targets/mod.rs +++ b/fuzz/src/msg_targets/mod.rs @@ -2,7 +2,6 @@ mod utils; pub mod msg_accept_channel; pub mod msg_announcement_signatures; pub mod msg_channel_reestablish; -pub mod msg_closing_signed; pub mod msg_commitment_signed; pub mod msg_decoded_onion_error_packet; pub mod msg_funding_created; @@ -25,6 +24,7 @@ pub mod msg_gossip_timestamp_filter; pub mod msg_update_add_htlc; pub mod msg_error_message; pub mod msg_channel_update; +pub mod msg_closing_signed; pub mod msg_init; pub mod msg_onion_hop_data; pub mod msg_ping; diff --git a/fuzz/src/msg_targets/msg_closing_signed.rs b/fuzz/src/msg_targets/msg_closing_signed.rs index 47881d32..52f39af2 100644 --- a/fuzz/src/msg_targets/msg_closing_signed.rs +++ b/fuzz/src/msg_targets/msg_closing_signed.rs @@ -17,11 +17,11 @@ use utils::test_logger; #[inline] pub fn msg_closing_signed_test(data: &[u8], _out: Out) { - test_msg!(msgs::ClosingSigned, data); + test_msg_simple!(msgs::ClosingSigned, data); } #[no_mangle] pub extern "C" fn msg_closing_signed_run(data: *const u8, datalen: usize) { let data = unsafe { std::slice::from_raw_parts(data, datalen) }; - test_msg!(msgs::ClosingSigned, data); + test_msg_simple!(msgs::ClosingSigned, data); } diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index d6ebbf1c..cd819fb1 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -3384,6 +3384,7 @@ impl Channel { channel_id: self.channel_id, fee_satoshis: total_fee_satoshis, signature: sig.unwrap(), + fee_range: None, }) } @@ -3567,6 +3568,7 @@ impl Channel { channel_id: self.channel_id, fee_satoshis: used_total_fee, signature: sig, + fee_range: None, }), None)) } } @@ -3608,6 +3610,7 @@ impl Channel { channel_id: self.channel_id, fee_satoshis: msg.fee_satoshis, signature: sig, + fee_range: None, }), Some(closing_tx))) } diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 0042cf51..f94909a9 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -226,6 +226,19 @@ pub struct Shutdown { pub scriptpubkey: Script, } +/// The minimum and maximum fees which the sender is willing to place on the closing transaction. +/// This is provided in [`ClosingSigned`] by both sides to indicate the fee range they are willing +/// to use. +#[derive(Clone, Debug, PartialEq)] +pub struct ClosingSignedFeeRange { + /// The minimum absolute fee, in satoshis, which the sender is willing to place on the closing + /// transaction. + pub min_fee_satoshis: u64, + /// The maximum absolute fee, in satoshis, which the sender is willing to place on the closing + /// transaction. + pub max_fee_satoshis: u64, +} + /// A closing_signed message to be sent or received from a peer #[derive(Clone, Debug, PartialEq)] pub struct ClosingSigned { @@ -235,6 +248,9 @@ pub struct ClosingSigned { pub fee_satoshis: u64, /// A signature on the closing transaction pub signature: Signature, + /// The minimum and maximum fees which the sender is willing to accept, provided only by new + /// nodes. + pub fee_range: Option, } /// An update_add_htlc message to be sent or received from a peer @@ -1103,10 +1119,35 @@ impl Readable for ChannelReestablish{ } } -impl_writeable!(ClosingSigned, 32+8+64, { - channel_id, - fee_satoshis, - signature +impl Writeable for ClosingSigned { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + w.size_hint(32 + 8 + 64 + if self.fee_range.is_some() { 1+1+ 2*8 } else { 0 }); + self.channel_id.write(w)?; + self.fee_satoshis.write(w)?; + self.signature.write(w)?; + encode_tlv_stream!(w, { + (1, self.fee_range, option), + }); + Ok(()) + } +} + +impl Readable for ClosingSigned { + fn read(r: &mut R) -> Result { + let channel_id = Readable::read(r)?; + let fee_satoshis = Readable::read(r)?; + let signature = Readable::read(r)?; + let mut fee_range = None; + decode_tlv_stream!(r, { + (1, fee_range, option), + }); + Ok(Self { channel_id, fee_satoshis, signature, fee_range }) + } +} + +impl_writeable!(ClosingSignedFeeRange, 2*8, { + min_fee_satoshis, + max_fee_satoshis }); impl_writeable_len_match!(CommitmentSigned, { @@ -2323,10 +2364,27 @@ mod tests { channel_id: [2; 32], fee_satoshis: 2316138423780173, signature: sig_1, + fee_range: None, }; let encoded_value = closing_signed.encode(); let target_value = hex::decode("020202020202020202020202020202020202020202020202020202020202020200083a840000034dd977cb9b53d93a6ff64bb5f1e158b4094b66e798fb12911168a3ccdf80a83096340a6a95da0ae8d9f776528eecdbb747eb6b545495a4319ed5378e35b21e073a").unwrap(); assert_eq!(encoded_value, target_value); + assert_eq!(msgs::ClosingSigned::read(&mut Cursor::new(&target_value)).unwrap(), closing_signed); + + let closing_signed_with_range = msgs::ClosingSigned { + channel_id: [2; 32], + fee_satoshis: 2316138423780173, + signature: sig_1, + fee_range: Some(msgs::ClosingSignedFeeRange { + min_fee_satoshis: 0xdeadbeef, + max_fee_satoshis: 0x1badcafe01234567, + }), + }; + let encoded_value_with_range = closing_signed_with_range.encode(); + let target_value_with_range = hex::decode("020202020202020202020202020202020202020202020202020202020202020200083a840000034dd977cb9b53d93a6ff64bb5f1e158b4094b66e798fb12911168a3ccdf80a83096340a6a95da0ae8d9f776528eecdbb747eb6b545495a4319ed5378e35b21e073a011000000000deadbeef1badcafe01234567").unwrap(); + assert_eq!(encoded_value_with_range, target_value_with_range); + assert_eq!(msgs::ClosingSigned::read(&mut Cursor::new(&target_value_with_range)).unwrap(), + closing_signed_with_range); } #[test] -- 2.30.2