BDR: Linearizing secp256k1 deps
[rust-lightning] / lightning / src / ln / msgs.rs
index e915f04152092f77388f20af1ad5d1d495cc245a..6c1d3cd928700a13550327c87d47b6fe1d634577 100644 (file)
 //! raw socket events into your non-internet-facing system and then send routing events back to
 //! track the network on the less-secure system.
 
-use secp256k1::key::PublicKey;
-use secp256k1::Signature;
-use secp256k1;
-use bitcoin_hashes::sha256d::Hash as Sha256dHash;
+use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::Signature;
+use bitcoin::secp256k1;
+use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::blockdata::script::Script;
 
 use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 
-use std::error::Error;
 use std::{cmp, fmt};
 use std::io::Read;
 use std::result::Result;
@@ -31,7 +30,7 @@ use std::result::Result;
 use util::events;
 use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt};
 
-use ln::channelmanager::{PaymentPreimage, PaymentHash};
+use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret};
 
 /// 21 million * 10^8 * 1000
 pub(crate) const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000;
@@ -615,11 +614,15 @@ pub trait RoutingMessageHandler : Send + Sync {
 }
 
 mod fuzzy_internal_msgs {
+       use ln::channelmanager::PaymentSecret;
+
        // These types aren't intended to be pub, but are exposed for direct fuzzing (as we deserialize
        // them from untrusted input):
        #[derive(Clone)]
        pub(crate) struct FinalOnionHopData {
-               pub(crate) payment_secret: [u8; 32],
+               pub(crate) payment_secret: PaymentSecret,
+               /// The total value, in msat, of the payment as received by the ultimate recipient.
+               /// Message serialization may panic if this value is more than 21 million Bitcoin.
                pub(crate) total_msat: u64,
        }
 
@@ -637,6 +640,8 @@ mod fuzzy_internal_msgs {
 
        pub struct OnionHopData {
                pub(crate) format: OnionHopDataFormat,
+               /// The value, in msat, of the payment after this hop's fee is deducted.
+               /// Message serialization may panic if this value is more than 21 million Bitcoin.
                pub(crate) amt_to_forward: u64,
                pub(crate) outgoing_cltv_value: u32,
                // 12 bytes of 0-padding for Legacy format
@@ -682,21 +687,16 @@ pub(crate) struct OnionErrorPacket {
        pub(crate) data: Vec<u8>,
 }
 
-impl Error for DecodeError {
-       fn description(&self) -> &str {
-               match *self {
-                       DecodeError::UnknownVersion => "Unknown realm byte in Onion packet",
-                       DecodeError::UnknownRequiredFeature => "Unknown required feature preventing decode",
-                       DecodeError::InvalidValue => "Nonsense bytes didn't map to the type they were interpreted as",
-                       DecodeError::ShortRead => "Packet extended beyond the provided bytes",
-                       DecodeError::BadLengthDescriptor => "A length descriptor in the packet didn't describe the later data correctly",
-                       DecodeError::Io(ref e) => e.description(),
-               }
-       }
-}
 impl fmt::Display for DecodeError {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-               f.write_str(self.description())
+               match *self {
+                       DecodeError::UnknownVersion => f.write_str("Unknown realm byte in Onion packet"),
+                       DecodeError::UnknownRequiredFeature => f.write_str("Unknown required feature preventing decode"),
+                       DecodeError::InvalidValue => f.write_str("Nonsense bytes didn't map to the type they were interpreted as"),
+                       DecodeError::ShortRead => f.write_str("Packet extended beyond the provided bytes"),
+                       DecodeError::BadLengthDescriptor => f.write_str("A length descriptor in the packet didn't describe the later data correctly"),
+                       DecodeError::Io(ref e) => e.fmt(f),
+               }
        }
 }
 
@@ -978,22 +978,26 @@ impl_writeable!(UpdateAddHTLC, 32+8+8+32+4+1366, {
 impl Writeable for FinalOnionHopData {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
                w.size_hint(32 + 8 - (self.total_msat.leading_zeros()/8) as usize);
-               self.payment_secret.write(w)?;
+               self.payment_secret.0.write(w)?;
                HighZeroBytesDroppedVarInt(self.total_msat).write(w)
        }
 }
 
 impl Readable for FinalOnionHopData {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let payment_secret = Readable::read(r)?;
+               let secret: [u8; 32] = Readable::read(r)?;
                let amt: HighZeroBytesDroppedVarInt<u64> = Readable::read(r)?;
-               Ok(Self { payment_secret, total_msat: amt.0 })
+               Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0 })
        }
 }
 
 impl Writeable for OnionHopData {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::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.
+               if self.amt_to_forward > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
                match self.format {
                        OnionHopDataFormat::Legacy { short_channel_id } => {
                                0u8.write(w)?;
@@ -1010,6 +1014,7 @@ impl Writeable for OnionHopData {
                                });
                        },
                        OnionHopDataFormat::FinalNode { payment_data: Some(ref final_data) } => {
+                               if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
                                encode_varint_length_prefixed_tlv!(w, {
                                        (2, HighZeroBytesDroppedVarInt(self.amt_to_forward)),
                                        (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value)),
@@ -1352,18 +1357,18 @@ mod tests {
        use hex;
        use ln::msgs;
        use ln::msgs::{ChannelFeatures, FinalOnionHopData, InitFeatures, NodeFeatures, OptionalField, OnionErrorPacket, OnionHopDataFormat};
-       use ln::channelmanager::{PaymentPreimage, PaymentHash};
+       use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret};
        use util::ser::{Writeable, Readable};
 
-       use bitcoin_hashes::sha256d::Hash as Sha256dHash;
-       use bitcoin_hashes::hex::FromHex;
+       use bitcoin::hashes::sha256d::Hash as Sha256dHash;
+       use bitcoin::hashes::hex::FromHex;
        use bitcoin::util::address::Address;
        use bitcoin::network::constants::Network;
        use bitcoin::blockdata::script::Builder;
        use bitcoin::blockdata::opcodes;
 
-       use secp256k1::key::{PublicKey,SecretKey};
-       use secp256k1::{Secp256k1, Message};
+       use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+       use bitcoin::secp256k1::{Secp256k1, Message};
 
        use std::io::Cursor;
 
@@ -2061,7 +2066,7 @@ mod tests {
 
        #[test]
        fn encoding_final_onion_hop_data_with_secret() {
-               let expected_payment_secret = [0x42u8; 32];
+               let expected_payment_secret = PaymentSecret([0x42u8; 32]);
                let mut msg = msgs::OnionHopData {
                        format: OnionHopDataFormat::FinalNode {
                                payment_data: Some(FinalOnionHopData {