+
+ #[test]
+ fn decode_onion_hop_data_len_as_bigsize() {
+ // Tests that we can decode an onion payload that is >253 bytes.
+ // Previously, receiving a payload of this size could've caused us to fail to decode a valid
+ // payload, because we were decoding the length (a BigSize, big-endian) as a VarInt
+ // (little-endian).
+
+ // Encode a test onion payload with a big custom TLV such that it's >253 bytes, forcing the
+ // payload length to be encoded over multiple bytes rather than a single u8.
+ let big_payload = encode_big_payload().unwrap();
+ let mut rd = Cursor::new(&big_payload[..]);
+ <msgs::OnionHopData as Readable>::read(&mut rd).unwrap();
+ }
+ // see above test, needs to be a separate method for use of the serialization macros.
+ fn encode_big_payload() -> Result<Vec<u8>, io::Error> {
+ use util::ser::HighZeroBytesDroppedBigSize;
+ let payload = msgs::OnionHopData {
+ format: OnionHopDataFormat::NonFinalNode {
+ short_channel_id: 0xdeadbeef1bad1dea,
+ },
+ amt_to_forward: 1000,
+ outgoing_cltv_value: 0xffffffff,
+ };
+ let mut encoded_payload = Vec::new();
+ let test_bytes = vec![42u8; 1000];
+ if let OnionHopDataFormat::NonFinalNode { short_channel_id } = payload.format {
+ encode_varint_length_prefixed_tlv!(&mut encoded_payload, {
+ (1, test_bytes, vec_type),
+ (2, HighZeroBytesDroppedBigSize(payload.amt_to_forward), required),
+ (4, HighZeroBytesDroppedBigSize(payload.outgoing_cltv_value), required),
+ (6, short_channel_id, required)
+ });
+ }
+ Ok(encoded_payload)
+ }