Implement the closing_signed TLV suffix with allowed fee ranges
authorMatt Corallo <git@bluematt.me>
Mon, 5 Jul 2021 23:21:36 +0000 (23:21 +0000)
committerMatt Corallo <git@bluematt.me>
Fri, 13 Aug 2021 23:02:23 +0000 (23:02 +0000)
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
fuzz/src/msg_targets/mod.rs
fuzz/src/msg_targets/msg_closing_signed.rs
lightning/src/ln/channel.rs
lightning/src/ln/msgs.rs

index 044f1a1ef08b7296887922ff572fc42973615218..0c1d061a74dc6047a334b386c05056349c04747e 100755 (executable)
@@ -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 ""
index e11e3eb26a2892bd44e87f3fbf77f1d75c07903d..0f273cb7606d1e51b5304e5cfe46671c441e2b5f 100644 (file)
@@ -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;
index 47881d32d241e07318295ac229025c78e6ab6cf6..52f39af29a98f82150d6150493065c7b942cebe0 100644 (file)
@@ -17,11 +17,11 @@ use utils::test_logger;
 
 #[inline]
 pub fn msg_closing_signed_test<Out: test_logger::Output>(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);
 }
index d6ebbf1cff20c769f6911f9e0d0243fc55b3230c..cd819fb14ddf046e50440c8b0b3e801bf346e023 100644 (file)
@@ -3384,6 +3384,7 @@ impl<Signer: Sign> Channel<Signer> {
                        channel_id: self.channel_id,
                        fee_satoshis: total_fee_satoshis,
                        signature: sig.unwrap(),
+                       fee_range: None,
                })
        }
 
@@ -3567,6 +3568,7 @@ impl<Signer: Sign> Channel<Signer> {
                                        channel_id: self.channel_id,
                                        fee_satoshis: used_total_fee,
                                        signature: sig,
+                                       fee_range: None,
                                }), None))
                        }
                }
@@ -3608,6 +3610,7 @@ impl<Signer: Sign> Channel<Signer> {
                        channel_id: self.channel_id,
                        fee_satoshis: msg.fee_satoshis,
                        signature: sig,
+                       fee_range: None,
                }), Some(closing_tx)))
        }
 
index 0042cf51bf3c2c570c5f1f007567b317230fc54a..f94909a9ae5499c35a5c6f5719c1705ede98ed91 100644 (file)
@@ -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<ClosingSignedFeeRange>,
 }
 
 /// 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<W: Writer>(&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: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               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]