[msgs::ChannelReestablish] implement encoding and decoding 2018-07-68-rebased
authorSavil Srivastava <savil@cs.stanford.edu>
Sat, 21 Jul 2018 00:24:14 +0000 (17:24 -0700)
committerMatt Corallo <git@bluematt.me>
Mon, 23 Jul 2018 03:26:47 +0000 (23:26 -0400)
Summary:

Implementing these, taking inspiration from the surrounding code since i'm a rust n00b.

Test Plan:
```
cargo build
cargo test channel_reestablish
```
output:
```
running 3 tests
test ln::msgs::tests::encoding_channel_reestablish_with_secret ... ok
test ln::msgs::tests::decode_channel_reestablish_bad_length ... ok
test ln::msgs::tests::encoding_channel_reestablish_no_secret ... ok

test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 14 filtered out
```

fuzz/Cargo.toml
fuzz/fuzz_targets/msg_targets/gen_target.sh
fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs [new file with mode: 0644]
src/ln/msgs.rs

index 077aacfaf753449ba1499b1ed66f5dc214999c82..53724f356418a3898f8d605a2f654d1a1a582699 100644 (file)
@@ -110,3 +110,7 @@ path = "fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs"
 [[bin]]
 name = "msg_update_fail_htlc_target"
 path = "fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs"
+
+[[bin]]
+name = "msg_channel_reestablish_target"
+path = "fuzz_targets/msg_targets/msg_channel_reestablish_target.rs"
index a74319f4f829bbcb76626c5887165e56b3237add..4a5dc2fc5565d9c25739c97b01faf512c5f74e72 100755 (executable)
@@ -1,4 +1,4 @@
-for target in CommitmentSigned FundingCreated FundingLocked FundingSigned OpenChannel RevokeAndACK Shutdown UpdateAddHTLC UpdateFailHTLC UpdateFailMalformedHTLC UpdateFee UpdateFulfillHTLC AcceptChannel ClosingSigned; do
+for target in CommitmentSigned FundingCreated FundingLocked FundingSigned OpenChannel RevokeAndACK Shutdown UpdateAddHTLC UpdateFailHTLC UpdateFailMalformedHTLC UpdateFee UpdateFulfillHTLC AcceptChannel ClosingSigned ChannelReestablish; do
        tn=$(echo $target | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g')
        fn=msg_$(echo $tn | tr '[:upper:]' '[:lower:]')_target.rs
        cat msg_target_template.txt | sed s/MSG_TARGET/$target/ > $fn
diff --git a/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs b/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs
new file mode 100644 (file)
index 0000000..dc9c2ac
--- /dev/null
@@ -0,0 +1,48 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+use lightning::util::reset_rng_state;
+
+use lightning::ln::msgs::{MsgEncodable, MsgDecodable};
+
+mod utils;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       reset_rng_state();
+       test_msg!(msgs::ChannelReestablish, data);
+}
+
+#[cfg(feature = "afl")]
+extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       afl::read_stdio_bytes(|data| {
+               do_test(&data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+#[cfg(test)]
+mod tests {
+       use utils::extend_vec_from_hex;
+       #[test]
+       fn duplicate_crash() {
+               let mut a = Vec::new();
+               extend_vec_from_hex("00", &mut a);
+               super::do_test(&a);
+       }
+}
index a36202e4681c02991081d4e3bc9edbf8d8f58a8b..a10a50e22d3f1ba25644e3a55a05824a658d4327 100644 (file)
@@ -1101,13 +1101,50 @@ impl MsgEncodable for UpdateFee {
 }
 
 impl MsgDecodable for ChannelReestablish {
-       fn decode(_v: &[u8]) -> Result<Self, DecodeError> {
-               unimplemented!();
+       fn decode(v: &[u8]) -> Result<Self, DecodeError> {
+               if v.len() < 32+2*8+33 {
+                       return Err(DecodeError::WrongLength);
+               }
+
+               let your_last_per_commitment_secret = if v.len() > 32+2*8+33 {
+                       if v.len() < 32+2*8+33 + 32 {
+                               return Err(DecodeError::WrongLength);
+                       }
+                       let mut inner_array = [0; 32];
+                       inner_array.copy_from_slice(&v[48..48+32]);
+                       Some(inner_array)
+               } else { None };
+
+               let option_size = match &your_last_per_commitment_secret {
+                       &Some(ref _ary) => 32,
+                       &None => 0,
+               };
+               Ok(Self {
+                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       next_local_commitment_number: byte_utils::slice_to_be64(&v[32..40]),
+                       next_remote_commitment_number: byte_utils::slice_to_be64(&v[40..48]),
+                       your_last_per_commitment_secret: your_last_per_commitment_secret,
+                       my_current_per_commitment_point: {
+                               let ctx = Secp256k1::without_caps();
+                               secp_pubkey!(&ctx, &v[48+option_size..48+option_size+33])
+                       }
+               })
        }
 }
 impl MsgEncodable for ChannelReestablish {
        fn encode(&self) -> Vec<u8> {
-               unimplemented!();
+               let mut res = Vec::with_capacity(if self.your_last_per_commitment_secret.is_some() { 32+2*3+33 + 32 } else { 32+2*8+33 });
+
+               res.extend_from_slice(&serialize(&self.channel_id).unwrap()[..]);
+               res.extend_from_slice(&byte_utils::be64_to_array(self.next_local_commitment_number));
+               res.extend_from_slice(&byte_utils::be64_to_array(self.next_remote_commitment_number));
+
+               if let &Some(ref ary) = &self.your_last_per_commitment_secret {
+                       res.extend_from_slice(&ary[..]);
+               }
+
+               res.extend_from_slice(&self.my_current_per_commitment_point.serialize());
+               res
        }
 }
 
@@ -1562,3 +1599,56 @@ impl MsgEncodable for OnionErrorPacket {
                res
        }
 }
+
+#[cfg(test)]
+mod tests {
+       use bitcoin::util::misc::hex_bytes;
+       use ln::msgs::MsgEncodable;
+       use ln::msgs;
+       use secp256k1::key::{PublicKey,SecretKey};
+       use secp256k1::Secp256k1;
+
+       #[test]
+       fn encoding_channel_reestablish_no_secret() {
+               let public_key = {
+                       let secp_ctx = Secp256k1::new();
+                       PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()).unwrap()
+               };
+
+               let cr = msgs::ChannelReestablish {
+                       channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0],
+                       next_local_commitment_number: 3,
+                       next_remote_commitment_number: 4,
+                       your_last_per_commitment_secret: None,
+                       my_current_per_commitment_point: public_key,
+               };
+
+               let encoded_value = cr.encode();
+               assert_eq!(
+                       encoded_value, 
+                       vec![4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 3, 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143]
+               );
+       }
+
+       #[test]
+       fn encoding_channel_reestablish_with_secret() {
+               let public_key = {
+                       let secp_ctx = Secp256k1::new();
+                       PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()).unwrap()
+               };
+
+               let cr = msgs::ChannelReestablish {
+                       channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0],
+                       next_local_commitment_number: 3,
+                       next_remote_commitment_number: 4,
+                       your_last_per_commitment_secret: Some([9; 32]),
+                       my_current_per_commitment_point: public_key,
+               };
+
+               let encoded_value = cr.encode();
+               assert_eq!(
+                       encoded_value, 
+                       vec![4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143]
+               );
+       }
+}