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,
}
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,
}
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 Option<T>s (Options get a tag byte, but
/// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a
/// 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<bool, LightningError>;
- /// 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.
}
-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,
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<W: Writer>(&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)?;
}
}
-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_writeable_msg!(ClosingSigned,
+ { channel_id, fee_satoshis, signature },
+ { (1, fee_range, option) }
+);
-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, {
+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<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
}
}
-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,
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<W: Writer>(&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)?,
}
}
-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<W: Writer>(&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)
}
impl Writeable for OnionHopData {
fn write<W: Writer>(&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.
impl Writeable for Ping {
fn write<W: Writer>(&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(())
impl Writeable for Pong {
fn write<W: Writer>(&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(())
}
impl Writeable for UnsignedChannelAnnouncement {
fn write<W: Writer>(&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)?;
}
}
-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,
impl Writeable for UnsignedChannelUpdate {
fn write<W: Writer>(&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)?;
}
}
-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<W: Writer>(&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())?;
impl Writeable for UnsignedNodeAnnouncement {
fn write<W: Writer>(&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)?;
}
}
-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
});
// 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)?;
}
}
-impl Readable for ReplyShortChannelIdsEnd {
- fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
- 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<W: Writer>(&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 {
/**
}
}
-impl Readable for QueryChannelRange {
- fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
- 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<W: Writer>(&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: Read>(r: &mut R) -> Result<Self, DecodeError> {
impl Writeable for ReplyChannelRange {
fn write<W: Writer>(&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)?;
}
}
-impl Readable for GossipTimestampFilter {
- fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
- 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<W: Writer>(&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 {