X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=sidebyside;f=lightning%2Fsrc%2Fln%2Fmsgs.rs;h=87e8a814d33c11db0abb494ff16de1c79f6dcb92;hb=da7a916682a01daf399b5afb0ed291b8767c6dc5;hp=2088c51fb5b038baad52a61951c89ab8e48bd255;hpb=143b8b361580bcb47b2d7f499a9dcc78cb126f8b;p=rust-lightning diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 2088c51f..87e8a814 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -32,15 +32,15 @@ use bitcoin::blockdata::script::ScriptBuf; use bitcoin::hash_types::Txid; use crate::blinded_path::payment::{BlindedPaymentTlvs, ForwardTlvs, ReceiveTlvs}; -use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret}; +use crate::ln::types::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret}; use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; use crate::ln::onion_utils; use crate::onion_message; use crate::sign::{NodeSigner, Recipient}; +#[allow(unused_imports)] use crate::prelude::*; -#[cfg(feature = "std")] -use core::convert::TryFrom; + use core::fmt; use core::fmt::Debug; use core::ops::Deref; @@ -91,6 +91,16 @@ pub enum DecodeError { Io(io::ErrorKind), /// The message included zlib-compressed values, which we don't support. UnsupportedCompression, + /// Value is validly encoded but is dangerous to use. + /// + /// This is used for things like [`ChannelManager`] deserialization where we want to ensure + /// that we don't use a [`ChannelManager`] which is in out of sync with the [`ChannelMonitor`]. + /// This indicates that there is a critical implementation flaw in the storage implementation + /// and it's unsafe to continue. + /// + /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager + /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor + DangerousValue, } /// An [`init`] message to be sent to or received from a peer. @@ -533,6 +543,8 @@ pub struct TxSignatures { pub tx_hash: Txid, /// The list of witnesses pub witnesses: Vec, + /// Optional signature for the shared input -- the previous funding outpoint -- signed by both peers + pub funding_outpoint_sig: Option, } /// A tx_init_rbf message which initiates a replacement of the transaction after it's been @@ -1450,10 +1462,13 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider { // Splicing /// Handle an incoming `splice` message from the given peer. + #[cfg(splicing)] fn handle_splice(&self, their_node_id: &PublicKey, msg: &Splice); /// Handle an incoming `splice_ack` message from the given peer. + #[cfg(splicing)] fn handle_splice_ack(&self, their_node_id: &PublicKey, msg: &SpliceAck); /// Handle an incoming `splice_locked` message from the given peer. + #[cfg(splicing)] fn handle_splice_locked(&self, their_node_id: &PublicKey, msg: &SpliceLocked); // Interactive channel construction @@ -1662,12 +1677,14 @@ pub struct FinalOnionHopData { mod fuzzy_internal_msgs { use bitcoin::secp256k1::PublicKey; - use crate::blinded_path::payment::{PaymentConstraints, PaymentRelay}; - use crate::prelude::*; - use crate::ln::{PaymentPreimage, PaymentSecret}; + use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, PaymentRelay}; + use crate::ln::types::{PaymentPreimage, PaymentSecret}; use crate::ln::features::BlindedHopFeatures; use super::{FinalOnionHopData, TrampolineOnionPacket}; + #[allow(unused_imports)] + use crate::prelude::*; + // These types aren't intended to be pub, but are exposed for direct fuzzing (as we deserialize // them from untrusted input): @@ -1699,6 +1716,7 @@ mod fuzzy_internal_msgs { cltv_expiry_height: u32, payment_secret: PaymentSecret, payment_constraints: PaymentConstraints, + payment_context: PaymentContext, intro_node_blinding_point: Option, keysend_preimage: Option, custom_tlvs: Vec<(u64, Vec)>, @@ -1742,6 +1760,17 @@ mod fuzzy_internal_msgs { } } + pub(crate) enum OutboundTrampolinePayload { + #[allow(unused)] + Forward { + /// The value, in msat, of the payment after this hop's fee is deducted. + amt_to_forward: u64, + outgoing_cltv_value: u32, + /// The node id to which the trampoline node must find a route + outgoing_node_id: PublicKey, + } + } + pub struct DecodedOnionErrorPacket { pub(crate) hmac: [u8; 32], pub(crate) failuremsg: Vec, @@ -1800,7 +1829,7 @@ pub struct TrampolineOnionPacket { // Unlike the onion packets used for payments, Trampoline onion packets have to be shorter than // 1300 bytes. The expected default is 650 bytes. // TODO: if 650 ends up being the most common size, optimize this to be: - // enum { ThirteenHundred([u8; 650]), VarLen(Vec) } + // enum { SixFifty([u8; 650]), VarLen(Vec) } pub hop_data: Vec, /// HMAC to verify the integrity of hop_data pub hmac: [u8; 32], @@ -1851,6 +1880,7 @@ impl fmt::Display for DecodeError { DecodeError::BadLengthDescriptor => f.write_str("A length descriptor in the packet didn't describe the later data correctly"), DecodeError::Io(ref e) => fmt::Debug::fmt(e, f), DecodeError::UnsupportedCompression => f.write_str("We don't support receiving messages with zlib-compressed fields"), + DecodeError::DangerousValue => f.write_str("Value would be dangerous to continue execution with"), } } } @@ -2091,7 +2121,9 @@ impl_writeable_msg!(TxSignatures, { channel_id, tx_hash, witnesses, -}, {}); +}, { + (0, funding_outpoint_sig, option), +}); impl_writeable_msg!(TxInitRbf, { channel_id, @@ -2604,6 +2636,22 @@ impl Writeable for OutboundOnionPayload { } } +impl Writeable for OutboundTrampolinePayload { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + match self { + Self::Forward { amt_to_forward, outgoing_cltv_value, outgoing_node_id } => { + _encode_varint_length_prefixed_tlv!(w, { + (2, HighZeroBytesDroppedBigSize(*amt_to_forward), required), + (4, HighZeroBytesDroppedBigSize(*outgoing_cltv_value), required), + (14, outgoing_node_id, required) + }); + } + } + Ok(()) + } +} + + impl ReadableArgs<(Option, &NS)> for InboundOnionPayload where NS::Target: NodeSigner { fn read(r: &mut R, args: (Option, &NS)) -> Result { let (update_add_blinding_point, node_signer) = args; @@ -2673,7 +2721,7 @@ impl ReadableArgs<(Option, &NS)> for InboundOnionPayload w }) }, ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs { - payment_secret, payment_constraints + payment_secret, payment_constraints, payment_context })} => { if total_msat.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) } Ok(Self::BlindedReceive { @@ -2682,6 +2730,7 @@ impl ReadableArgs<(Option, &NS)> for InboundOnionPayload w cltv_expiry_height: cltv_value.ok_or(DecodeError::InvalidValue)?, payment_secret, payment_constraints, + payment_context, intro_node_blinding_point, keysend_preimage, custom_tlvs, @@ -3125,11 +3174,9 @@ impl_writeable_msg!(GossipTimestampFilter, { #[cfg(test)] mod tests { - use std::convert::TryFrom; use bitcoin::{Transaction, TxIn, ScriptBuf, Sequence, Witness, TxOut}; use hex::DisplayHex; - use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret}; - use crate::ln::ChannelId; + use crate::ln::types::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret}; use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket, CommonOpenChannelFields, CommonAcceptChannelFields, TrampolineOnionPacket}; use crate::ln::msgs::SocketAddress; @@ -3913,6 +3960,10 @@ mod tests { #[test] fn encoding_tx_signatures() { + let secp_ctx = Secp256k1::new(); + let (privkey_1, _) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx); + let sig_1 = get_sig_on!(privkey_1, secp_ctx, String::from("01010101010101010101010101010101")); + let tx_signatures = msgs::TxSignatures { channel_id: ChannelId::from_bytes([2; 32]), tx_hash: Txid::from_str("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap(), @@ -3924,6 +3975,7 @@ mod tests { >::from_hex("3045022100ee00dbf4a862463e837d7c08509de814d620e4d9830fa84818713e0fa358f145022021c3c7060c4d53fe84fd165d60208451108a778c13b92ca4c6bad439236126cc01").unwrap(), >::from_hex("028fbbf0b16f5ba5bcb5dd37cd4047ce6f726a21c06682f9ec2f52b057de1dbdb5").unwrap()]), ], + funding_outpoint_sig: Some(sig_1), }; let encoded_value = tx_signatures.encode(); let mut target_value = >::from_hex("0202020202020202020202020202020202020202020202020202020202020202").unwrap(); // channel_id @@ -3943,6 +3995,8 @@ mod tests { target_value.append(&mut >::from_hex("3045022100ee00dbf4a862463e837d7c08509de814d620e4d9830fa84818713e0fa358f145022021c3c7060c4d53fe84fd165d60208451108a778c13b92ca4c6bad439236126cc01").unwrap()); target_value.append(&mut >::from_hex("21").unwrap()); // len of witness element data (VarInt) target_value.append(&mut >::from_hex("028fbbf0b16f5ba5bcb5dd37cd4047ce6f726a21c06682f9ec2f52b057de1dbdb5").unwrap()); + target_value.append(&mut >::from_hex("0040").unwrap()); // type and len (64) + target_value.append(&mut >::from_hex("d977cb9b53d93a6ff64bb5f1e158b4094b66e798fb12911168a3ccdf80a83096340a6a95da0ae8d9f776528eecdbb747eb6b545495a4319ed5378e35b21e073a").unwrap()); assert_eq!(encoded_value, target_value); }