X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fmsgs.rs;h=122dd7737b996507e2d8fb5135af443172fb65f8;hb=843d25d750c3408d3f8f917764b8a58019a9dd81;hp=0042cf51bf3c2c570c5f1f007567b317230fc54a;hpb=57feb2630779410b5977ccb3c12dd482a20440fc;p=rust-lightning diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 0042cf51..122dd773 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -194,7 +194,7 @@ pub struct FundingCreated { pub funding_txid: Txid, /// The specific output index funding this channel pub funding_output_index: u16, - /// The signature of the channel initiator (funder) on the funding transaction + /// The signature of the channel initiator (funder) on the initial commitment transaction pub signature: Signature, } @@ -203,7 +203,7 @@ pub struct FundingCreated { pub struct FundingSigned { /// The channel ID pub channel_id: [u8; 32], - /// The signature of the channel acceptor (fundee) on the funding transaction + /// The signature of the channel acceptor (fundee) on the initial commitment transaction pub signature: Signature, } @@ -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 @@ -729,35 +745,6 @@ pub struct CommitmentUpdate { pub commitment_signed: CommitmentSigned, } -/// The information we received from a peer along the route of a payment we originated. This is -/// returned by ChannelMessageHandler::handle_update_fail_htlc to be passed into -/// RoutingMessageHandler::handle_htlc_fail_channel_update to update our network map. -#[derive(Clone, Debug, PartialEq)] -pub enum HTLCFailChannelUpdate { - /// We received an error which included a full ChannelUpdate message. - ChannelUpdateMessage { - /// The unwrapped message we received - msg: ChannelUpdate, - }, - /// We received an error which indicated only that a channel has been closed - ChannelClosed { - /// The short_channel_id which has now closed. - short_channel_id: u64, - /// when this true, this channel should be permanently removed from the - /// consideration. Otherwise, this channel can be restored as new channel_update is received - is_permanent: bool, - }, - /// We received an error which indicated only that a node has failed - NodeFailure { - /// The node_id that has failed. - node_id: PublicKey, - /// when this true, node should be permanently removed from the - /// consideration. Otherwise, the channels connected to this node can be - /// restored as new channel_update is received - is_permanent: bool, - } -} - /// Messages could have optional fields to use with extended features /// As we wish to serialize these differently from Options (Options get a tag byte, but /// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a @@ -852,8 +839,6 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider { /// Handle an incoming channel_update message, returning true if it should be forwarded on, /// false or returning an Err otherwise. fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result; - /// Handle some updates to the route graph that we learned due to an outbound failed payment. - fn handle_htlc_fail_channel_update(&self, update: &HTLCFailChannelUpdate); /// Gets a subset of the channel announcements and updates required to dump our routing table /// to a remote node, starting at the short_channel_id indicated by starting_point and /// including the batch_amount entries immediately higher in numerical value than starting_point. @@ -1037,10 +1022,7 @@ impl Readable for OptionalField { } -impl_writeable_len_match!(AcceptChannel, { - {AcceptChannel{ shutdown_scriptpubkey: OptionalField::Present(ref script), .. }, 270 + 2 + script.len()}, - {_, 270} - }, { +impl_writeable_msg!(AcceptChannel, { temporary_channel_id, dust_limit_satoshis, max_htlc_value_in_flight_msat, @@ -1056,18 +1038,17 @@ impl_writeable_len_match!(AcceptChannel, { htlc_basepoint, first_per_commitment_point, shutdown_scriptpubkey -}); +}, {}); -impl_writeable!(AnnouncementSignatures, 32+8+64*2, { +impl_writeable_msg!(AnnouncementSignatures, { channel_id, short_channel_id, node_signature, bitcoin_signature -}); +}, {}); impl Writeable for ChannelReestablish { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(if let OptionalField::Present(..) = self.data_loss_protect { 32+2*8+33+32 } else { 32+2*8 }); self.channel_id.write(w)?; self.next_local_commitment_number.write(w)?; self.next_remote_commitment_number.write(w)?; @@ -1103,44 +1084,44 @@ impl Readable for ChannelReestablish{ } } -impl_writeable!(ClosingSigned, 32+8+64, { - channel_id, - fee_satoshis, - signature +impl_writeable_msg!(ClosingSigned, + { channel_id, fee_satoshis, signature }, + { (1, fee_range, option) } +); + +impl_writeable!(ClosingSignedFeeRange, { + min_fee_satoshis, + max_fee_satoshis }); -impl_writeable_len_match!(CommitmentSigned, { - { CommitmentSigned { ref htlc_signatures, .. }, 32+64+2+htlc_signatures.len()*64 } - }, { +impl_writeable_msg!(CommitmentSigned, { channel_id, signature, htlc_signatures -}); +}, {}); -impl_writeable_len_match!(DecodedOnionErrorPacket, { - { DecodedOnionErrorPacket { ref failuremsg, ref pad, .. }, 32 + 4 + failuremsg.len() + pad.len() } - }, { +impl_writeable!(DecodedOnionErrorPacket, { hmac, failuremsg, pad }); -impl_writeable!(FundingCreated, 32+32+2+64, { +impl_writeable_msg!(FundingCreated, { temporary_channel_id, funding_txid, funding_output_index, signature -}); +}, {}); -impl_writeable!(FundingSigned, 32+64, { +impl_writeable_msg!(FundingSigned, { channel_id, signature -}); +}, {}); -impl_writeable!(FundingLocked, 32+33, { +impl_writeable_msg!(FundingLocked, { channel_id, - next_per_commitment_point -}); + next_per_commitment_point, +}, {}); impl Writeable for Init { fn write(&self, w: &mut W) -> Result<(), io::Error> { @@ -1161,10 +1142,7 @@ impl Readable for Init { } } -impl_writeable_len_match!(OpenChannel, { - { OpenChannel { shutdown_scriptpubkey: OptionalField::Present(ref script), .. }, 319 + 2 + script.len() }, - { _, 319 } - }, { +impl_writeable_msg!(OpenChannel, { chain_hash, temporary_channel_id, funding_satoshis, @@ -1184,56 +1162,55 @@ impl_writeable_len_match!(OpenChannel, { first_per_commitment_point, channel_flags, shutdown_scriptpubkey -}); +}, {}); -impl_writeable!(RevokeAndACK, 32+32+33, { +impl_writeable_msg!(RevokeAndACK, { channel_id, per_commitment_secret, next_per_commitment_point -}); +}, {}); -impl_writeable_len_match!(Shutdown, { - { Shutdown { ref scriptpubkey, .. }, 32 + 2 + scriptpubkey.len() } - }, { +impl_writeable_msg!(Shutdown, { channel_id, scriptpubkey -}); +}, {}); -impl_writeable_len_match!(UpdateFailHTLC, { - { UpdateFailHTLC { ref reason, .. }, 32 + 10 + reason.data.len() } - }, { +impl_writeable_msg!(UpdateFailHTLC, { channel_id, htlc_id, reason -}); +}, {}); -impl_writeable!(UpdateFailMalformedHTLC, 32+8+32+2, { +impl_writeable_msg!(UpdateFailMalformedHTLC, { channel_id, htlc_id, sha256_of_onion, failure_code -}); +}, {}); -impl_writeable!(UpdateFee, 32+4, { +impl_writeable_msg!(UpdateFee, { channel_id, feerate_per_kw -}); +}, {}); -impl_writeable!(UpdateFulfillHTLC, 32+8+32, { +impl_writeable_msg!(UpdateFulfillHTLC, { channel_id, htlc_id, payment_preimage -}); +}, {}); -impl_writeable_len_match!(OnionErrorPacket, { - { OnionErrorPacket { ref data, .. }, 2 + data.len() } - }, { +// Note that this is written as a part of ChannelManager objects, and thus cannot change its +// serialization format in a way which assumes we know the total serialized length/message end +// position. +impl_writeable!(OnionErrorPacket, { data }); +// Note that this is written as a part of ChannelManager objects, and thus cannot change its +// serialization format in a way which assumes we know the total serialized length/message end +// position. impl Writeable for OnionPacket { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(1 + 33 + 20*65 + 32); self.version.write(w)?; match self.public_key { Ok(pubkey) => pubkey.write(w)?, @@ -1260,18 +1237,17 @@ impl Readable for OnionPacket { } } -impl_writeable!(UpdateAddHTLC, 32+8+8+32+4+1366, { +impl_writeable_msg!(UpdateAddHTLC, { channel_id, htlc_id, amount_msat, payment_hash, cltv_expiry, onion_routing_packet -}); +}, {}); impl Writeable for FinalOnionHopData { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(32 + 8 - (self.total_msat.leading_zeros()/8) as usize); self.payment_secret.0.write(w)?; HighZeroBytesDroppedVarInt(self.total_msat).write(w) } @@ -1287,7 +1263,6 @@ impl Readable for FinalOnionHopData { impl Writeable for OnionHopData { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(33); // Note that this should never be reachable if Rust-Lightning generated the message, as we // check values are sane long before we get here, though its possible in the future // user-generated messages may hit this. @@ -1388,7 +1363,6 @@ impl Readable for OnionHopData { impl Writeable for Ping { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(self.byteslen as usize + 4); self.ponglen.write(w)?; vec![0u8; self.byteslen as usize].write(w)?; // size-unchecked write Ok(()) @@ -1410,7 +1384,6 @@ impl Readable for Ping { impl Writeable for Pong { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(self.byteslen as usize + 2); vec![0u8; self.byteslen as usize].write(w)?; // size-unchecked write Ok(()) } @@ -1430,7 +1403,6 @@ impl Readable for Pong { impl Writeable for UnsignedChannelAnnouncement { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(2 + 32 + 8 + 4*33 + self.features.byte_count() + self.excess_data.len()); self.features.write(w)?; self.chain_hash.write(w)?; self.short_channel_id.write(w)?; @@ -1458,10 +1430,7 @@ impl Readable for UnsignedChannelAnnouncement { } } -impl_writeable_len_match!(ChannelAnnouncement, { - { ChannelAnnouncement { contents: UnsignedChannelAnnouncement {ref features, ref excess_data, ..}, .. }, - 2 + 32 + 8 + 4*33 + features.byte_count() + excess_data.len() + 4*64 } - }, { +impl_writeable!(ChannelAnnouncement, { node_signature_1, node_signature_2, bitcoin_signature_1, @@ -1471,13 +1440,10 @@ impl_writeable_len_match!(ChannelAnnouncement, { impl Writeable for UnsignedChannelUpdate { fn write(&self, w: &mut W) -> Result<(), io::Error> { - let mut size = 64 + self.excess_data.len(); let mut message_flags: u8 = 0; if let OptionalField::Present(_) = self.htlc_maximum_msat { - size += 8; message_flags = 1; } - w.size_hint(size); self.chain_hash.write(w)?; self.short_channel_id.write(w)?; self.timestamp.write(w)?; @@ -1516,17 +1482,13 @@ impl Readable for UnsignedChannelUpdate { } } -impl_writeable_len_match!(ChannelUpdate, { - { ChannelUpdate { contents: UnsignedChannelUpdate {ref excess_data, ref htlc_maximum_msat, ..}, .. }, - 64 + 64 + excess_data.len() + if let OptionalField::Present(_) = htlc_maximum_msat { 8 } else { 0 } } - }, { +impl_writeable!(ChannelUpdate, { signature, contents }); impl Writeable for ErrorMessage { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(32 + 2 + self.data.len()); self.channel_id.write(w)?; (self.data.len() as u16).write(w)?; w.write_all(self.data.as_bytes())?; @@ -1553,7 +1515,6 @@ impl Readable for ErrorMessage { impl Writeable for UnsignedNodeAnnouncement { fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(76 + self.features.byte_count() + self.addresses.len()*38 + self.excess_address_data.len() + self.excess_data.len()); self.features.write(w)?; self.timestamp.write(w)?; self.node_id.write(w)?; @@ -1636,10 +1597,7 @@ impl Readable for UnsignedNodeAnnouncement { } } -impl_writeable_len_match!(NodeAnnouncement, <=, { - { NodeAnnouncement { contents: UnsignedNodeAnnouncement { ref features, ref addresses, ref excess_address_data, ref excess_data, ..}, .. }, - 64 + 76 + features.byte_count() + addresses.len()*(NetAddress::MAX_LEN as usize + 1) + excess_address_data.len() + excess_data.len() } - }, { +impl_writeable!(NodeAnnouncement, { signature, contents }); @@ -1683,7 +1641,6 @@ impl Writeable for QueryShortChannelIds { // Calculated from 1-byte encoding_type plus 8-bytes per short_channel_id let encoding_len: u16 = 1 + self.short_channel_ids.len() as u16 * 8; - w.size_hint(32 + 2 + encoding_len as usize); self.chain_hash.write(w)?; encoding_len.write(w)?; @@ -1698,25 +1655,10 @@ impl Writeable for QueryShortChannelIds { } } -impl Readable for ReplyShortChannelIdsEnd { - fn read(r: &mut R) -> Result { - let chain_hash: BlockHash = Readable::read(r)?; - let full_information: bool = Readable::read(r)?; - Ok(ReplyShortChannelIdsEnd { - chain_hash, - full_information, - }) - } -} - -impl Writeable for ReplyShortChannelIdsEnd { - fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(32 + 1); - self.chain_hash.write(w)?; - self.full_information.write(w)?; - Ok(()) - } -} +impl_writeable_msg!(ReplyShortChannelIdsEnd, { + chain_hash, + full_information, +}, {}); impl QueryChannelRange { /** @@ -1731,28 +1673,11 @@ impl QueryChannelRange { } } -impl Readable for QueryChannelRange { - fn read(r: &mut R) -> Result { - let chain_hash: BlockHash = Readable::read(r)?; - let first_blocknum: u32 = Readable::read(r)?; - let number_of_blocks: u32 = Readable::read(r)?; - Ok(QueryChannelRange { - chain_hash, - first_blocknum, - number_of_blocks - }) - } -} - -impl Writeable for QueryChannelRange { - fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(32 + 4 + 4); - self.chain_hash.write(w)?; - self.first_blocknum.write(w)?; - self.number_of_blocks.write(w)?; - Ok(()) - } -} +impl_writeable_msg!(QueryChannelRange, { + chain_hash, + first_blocknum, + number_of_blocks +}, {}); impl Readable for ReplyChannelRange { fn read(r: &mut R) -> Result { @@ -1797,7 +1722,6 @@ impl Readable for ReplyChannelRange { impl Writeable for ReplyChannelRange { fn write(&self, w: &mut W) -> Result<(), io::Error> { let encoding_len: u16 = 1 + self.short_channel_ids.len() as u16 * 8; - w.size_hint(32 + 4 + 4 + 1 + 2 + encoding_len as usize); self.chain_hash.write(w)?; self.first_blocknum.write(w)?; self.number_of_blocks.write(w)?; @@ -1813,29 +1737,11 @@ impl Writeable for ReplyChannelRange { } } -impl Readable for GossipTimestampFilter { - fn read(r: &mut R) -> Result { - let chain_hash: BlockHash = Readable::read(r)?; - let first_timestamp: u32 = Readable::read(r)?; - let timestamp_range: u32 = Readable::read(r)?; - Ok(GossipTimestampFilter { - chain_hash, - first_timestamp, - timestamp_range, - }) - } -} - -impl Writeable for GossipTimestampFilter { - fn write(&self, w: &mut W) -> Result<(), io::Error> { - w.size_hint(32 + 4 + 4); - self.chain_hash.write(w)?; - self.first_timestamp.write(w)?; - self.timestamp_range.write(w)?; - Ok(()) - } -} - +impl_writeable_msg!(GossipTimestampFilter, { + chain_hash, + first_timestamp, + timestamp_range, +}, {}); #[cfg(test)] mod tests { @@ -2323,10 +2229,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]