/// block_connected() to step towards your best block) upon deserialization before using the
/// object!
///
-/// Note that ChannelManager is responsible of tracking liveness of its channels and by so
-/// to generate ChannelUpdate messages intended to be broadcast on the gossip layer. To avoid
-/// spam due to quick connection/reconnection, updates should be first stagged then after a period
-/// of 1 min flushed to the network through call to timer_chan_freshness_every_min. You may
-/// delay or anticipate call to this method to suit your announcements requirements different than
-/// the 1 min period.
+/// Note that ChannelManager is responsible for tracking liveness of its channels and generating
+/// ChannelUpdate messages informing peers that the channel is temporarily disabled. To avoid
+/// spam due to quick disconnection/reconnection, updates are not sent until the channel has been
+/// offline for a full minute. In order to track this, you must call
+/// timer_chan_freshness_every_min roughly once per minute, though it doesn't have to be perfec.
pub struct ChannelManager<'a> {
default_configuration: UserConfig,
genesis_hash: Sha256dHash,
self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() });
}
for tx in local_txn {
+ log_trace!(self, "Broadcast onchain {}", log_tx!(tx));
self.tx_broadcaster.broadcast_transaction(&tx);
}
}
};
let pending_forward_info = if next_hop_data.hmac == [0; 32] {
+ #[cfg(test)]
+ {
+ // In tests, make sure that the initial onion pcket data is, at least, non-0.
+ // We could do some fancy randomness test here, but, ehh, whatever.
+ // This checks for the issue where you can calculate the path length given the
+ // onion data as all the path entries that the originator sent will be here
+ // as-is (and were originally 0s).
+ // Of course reverse path calculation is still pretty easy given naive routing
+ // algorithms, but this fixes the most-obvious case.
+ let mut new_packet_data = [0; 19*65];
+ chacha.process(&msg.onion_routing_packet.hop_data[65..], &mut new_packet_data[0..19*65]);
+ assert_ne!(new_packet_data[0..65], [0; 65][..]);
+ assert_ne!(new_packet_data[..], [0; 19*65][..]);
+ }
+
// OUR PAYMENT!
// final_expiry_too_soon
if (msg.cltv_expiry as u64) < self.latest_block_height.load(Ordering::Acquire) as u64 + (CLTV_CLAIM_BUFFER + LATENCY_GRACE_PERIOD_BLOCKS) as u64 {
}
}
- let session_priv = self.keys_manager.get_session_key();
+ let (session_priv, prng_seed) = self.keys_manager.get_onion_rand();
let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
let onion_keys = secp_call!(onion_utils::construct_onion_keys(&self.secp_ctx, &route, &session_priv),
APIError::RouteError{err: "Pubkey along hop was maliciously selected"});
let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height)?;
- let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, &payment_hash);
+ let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, prng_seed, &payment_hash);
let _ = self.total_consistency_lock.read().unwrap();
events.append(&mut new_events);
}
- /// Latency/peer disconnection may trigger us to mark as disabled some
- /// of our channels. After some time, if channels are still disabled
- /// we need to broadcast ChannelUpdate to inform other network peers
- /// about the uselessness of this channels.
+ /// If a peer is disconnected we mark any channels with that peer as 'disabled'.
+ /// After some time, if channels are still disabled we need to broadcast a ChannelUpdate
+ /// to inform the network about the uselessness of these channels.
+ ///
+ /// This method handles all the details, and must be called roughly once per minute.
pub fn timer_chan_freshness_every_min(&self) {
let _ = self.total_consistency_lock.read().unwrap();
let mut channel_state_lock = self.channel_state.lock().unwrap();
}
};
if let Some(broadcast_tx) = tx {
+ log_trace!(self, "Broadcast onchain {}", log_tx!(broadcast_tx));
self.tx_broadcaster.broadcast_transaction(&broadcast_tx);
}
if let Some(chan) = chan_option {