X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fmsgs.rs;h=136ed4d317b35bfdc43618a0109e7c3ed1a729a1;hb=db7e69667303fb4ba8c2ae6e792d09442260d7ad;hp=89dff492067ed3c1b3dfa3b2dd9ea07b02f93ecc;hpb=7d68b608c8269c6b50d61c169c57eb0a203a4e01;p=rust-lightning diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 89dff492..136ed4d3 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -38,9 +38,9 @@ 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::blinded_path::payment::{PaymentConstraints, PaymentContext, PaymentRelay}; use crate::ln::{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,8 +1716,10 @@ 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)>, } } @@ -1741,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, @@ -1799,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], @@ -1850,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"), } } } @@ -2090,7 +2121,9 @@ impl_writeable_msg!(TxSignatures, { channel_id, tx_hash, witnesses, -}, {}); +}, { + (0, funding_outpoint_sig, option), +}); impl_writeable_msg!(TxInitRbf, { channel_id, @@ -2603,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; @@ -2672,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 { @@ -2681,8 +2730,10 @@ 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, }) }, } @@ -3123,7 +3174,6 @@ 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}; @@ -3911,6 +3961,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(), @@ -3922,6 +3976,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 @@ -3941,6 +3996,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); }