let value_msat = if cur_value_msat == 0 { hop.fee_msat } else { cur_value_msat };
let cltv = if cur_cltv == starting_htlc_offset { hop.cltv_expiry_delta + starting_htlc_offset } else { cur_cltv };
res.insert(0, msgs::OnionHopData {
- realm: 0,
- data: msgs::OnionRealm0HopData {
- short_channel_id: last_short_channel_id,
- amt_to_forward: value_msat,
- outgoing_cltv_value: cltv,
- },
- hmac: [0; 32],
+ format: msgs::OnionHopDataFormat::Legacy,
+ short_channel_id: last_short_channel_id,
+ amt_to_forward: value_msat,
+ outgoing_cltv_value: cltv,
});
cur_value_msat += hop.fee_msat;
if cur_value_msat >= 21000000 * 100000000 * 1000 {
construct_onion_packet_with_init_noise(payloads, onion_keys, packet_data, associated_data)
}
-fn construct_onion_packet_with_init_noise(mut payloads: Vec<msgs::OnionHopData>, onion_keys: Vec<OnionKeys>, mut packet_data: [u8; 20*65], associated_data: &PaymentHash) -> msgs::OnionPacket {
+#[cfg(test)]
+// Used in testing to write bogus OnionHopDatas, which is otherwise not representable in
+// msgs::OnionHopData.
+pub(super) fn construct_onion_packet_bogus_hopdata<HD: Writeable>(payloads: Vec<HD>, onion_keys: Vec<OnionKeys>, prng_seed: [u8; 32], associated_data: &PaymentHash) -> msgs::OnionPacket {
+ let mut packet_data = [0; 20*65];
+
+ let mut chacha = ChaCha20::new(&prng_seed, &[0; 8]);
+ chacha.process(&[0; 20*65], &mut packet_data);
+
+ construct_onion_packet_with_init_noise(payloads, onion_keys, packet_data, associated_data)
+}
+
+fn construct_onion_packet_with_init_noise<HD: Writeable>(mut payloads: Vec<HD>, onion_keys: Vec<OnionKeys>, mut packet_data: [u8; 20*65], associated_data: &PaymentHash) -> msgs::OnionPacket {
let mut buf = Vec::with_capacity(21*65);
buf.resize(21*65, 0);
for (i, (payload, keys)) in payloads.iter_mut().zip(onion_keys.iter()).rev().enumerate() {
shift_arr_right(&mut packet_data);
- payload.hmac = hmac_res;
- packet_data[0..65].copy_from_slice(&payload.encode()[..]);
+ packet_data[0..33].copy_from_slice(&payload.encode()[..]);
+ packet_data[33..65].copy_from_slice(&hmac_res);
let mut chacha = ChaCha20::new(&keys.rho, &[0u8; 8]);
chacha.process(&packet_data, &mut buf[0..20*65]);
// Test vectors below are flat-out wrong: they claim to set outgoing_cltv_value to non-0 :/
let payloads = vec!(
msgs::OnionHopData {
- realm: 0,
- data: msgs::OnionRealm0HopData {
- short_channel_id: 0,
- amt_to_forward: 0,
- outgoing_cltv_value: 0,
- },
- hmac: [0; 32],
+ format: msgs::OnionHopDataFormat::Legacy,
+ short_channel_id: 0,
+ amt_to_forward: 0,
+ outgoing_cltv_value: 0,
},
msgs::OnionHopData {
- realm: 0,
- data: msgs::OnionRealm0HopData {
- short_channel_id: 0x0101010101010101,
- amt_to_forward: 0x0100000001,
- outgoing_cltv_value: 0,
- },
- hmac: [0; 32],
+ format: msgs::OnionHopDataFormat::Legacy,
+ short_channel_id: 0x0101010101010101,
+ amt_to_forward: 0x0100000001,
+ outgoing_cltv_value: 0,
},
msgs::OnionHopData {
- realm: 0,
- data: msgs::OnionRealm0HopData {
- short_channel_id: 0x0202020202020202,
- amt_to_forward: 0x0200000002,
- outgoing_cltv_value: 0,
- },
- hmac: [0; 32],
+ format: msgs::OnionHopDataFormat::Legacy,
+ short_channel_id: 0x0202020202020202,
+ amt_to_forward: 0x0200000002,
+ outgoing_cltv_value: 0,
},
msgs::OnionHopData {
- realm: 0,
- data: msgs::OnionRealm0HopData {
- short_channel_id: 0x0303030303030303,
- amt_to_forward: 0x0300000003,
- outgoing_cltv_value: 0,
- },
- hmac: [0; 32],
+ format: msgs::OnionHopDataFormat::Legacy,
+ short_channel_id: 0x0303030303030303,
+ amt_to_forward: 0x0300000003,
+ outgoing_cltv_value: 0,
},
msgs::OnionHopData {
- realm: 0,
- data: msgs::OnionRealm0HopData {
- short_channel_id: 0x0404040404040404,
- amt_to_forward: 0x0400000004,
- outgoing_cltv_value: 0,
- },
- hmac: [0; 32],
+ format: msgs::OnionHopDataFormat::Legacy,
+ short_channel_id: 0x0404040404040404,
+ amt_to_forward: 0x0400000004,
+ outgoing_cltv_value: 0,
},
);