@@ -2253,95 +2253,106 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
22532253 msg. timestamp
22542254 ) ;
22552255
2256- let mut channels = self . channels . write ( ) . unwrap ( ) ;
2257- match channels. get_mut ( & msg. short_channel_id ) {
2258- None => {
2259- core:: mem:: drop ( channels) ;
2260- self . pending_checks . check_hold_pending_channel_update ( msg, full_msg) ?;
2261- return Err ( LightningError {
2262- err : "Couldn't find channel for update" . to_owned ( ) ,
2263- action : ErrorAction :: IgnoreAndLog ( Level :: Gossip ) ,
2264- } ) ;
2265- } ,
2266- Some ( channel) => {
2267- if msg. htlc_maximum_msat > MAX_VALUE_MSAT {
2268- return Err ( LightningError { err :
2269- "htlc_maximum_msat is larger than maximum possible msats" . to_owned ( ) ,
2270- action : ErrorAction :: IgnoreError } ) ;
2256+ if msg. htlc_maximum_msat > MAX_VALUE_MSAT {
2257+ return Err ( LightningError { err :
2258+ "htlc_maximum_msat is larger than maximum possible msats" . to_owned ( ) ,
2259+ action : ErrorAction :: IgnoreError } ) ;
2260+ }
2261+
2262+ let check_update_latest = |target : & Option < ChannelUpdateInfo > | -> Result < ( ) , LightningError > {
2263+ if let Some ( existing_chan_info) = target {
2264+ // The timestamp field is somewhat of a misnomer - the BOLTs use it to
2265+ // order updates to ensure you always have the latest one, only
2266+ // suggesting that it be at least the current time. For
2267+ // channel_updates specifically, the BOLTs discuss the possibility of
2268+ // pruning based on the timestamp field being more than two weeks old,
2269+ // but only in the non-normative section.
2270+ if existing_chan_info. last_update > msg. timestamp {
2271+ return Err ( LightningError { err : "Update older than last processed update" . to_owned ( ) , action : ErrorAction :: IgnoreDuplicateGossip } ) ;
2272+ } else if existing_chan_info. last_update == msg. timestamp {
2273+ return Err ( LightningError { err : "Update had same timestamp as last processed update" . to_owned ( ) , action : ErrorAction :: IgnoreDuplicateGossip } ) ;
22712274 }
2275+ }
2276+ Ok ( ( ) )
2277+ } ;
22722278
2273- if let Some ( capacity_sats) = channel. capacity_sats {
2274- // It's possible channel capacity is available now, although it wasn't available at announcement (so the field is None).
2275- // Don't query UTXO set here to reduce DoS risks.
2276- if capacity_sats > MAX_VALUE_MSAT / 1000 || msg. htlc_maximum_msat > capacity_sats * 1000 {
2277- return Err ( LightningError { err :
2278- "htlc_maximum_msat is larger than channel capacity or capacity is bogus" . to_owned ( ) ,
2279- action : ErrorAction :: IgnoreError } ) ;
2280- }
2281- }
2282- macro_rules! check_update_latest {
2283- ( $target: expr) => {
2284- if let Some ( existing_chan_info) = $target. as_ref( ) {
2285- // The timestamp field is somewhat of a misnomer - the BOLTs use it to
2286- // order updates to ensure you always have the latest one, only
2287- // suggesting that it be at least the current time. For
2288- // channel_updates specifically, the BOLTs discuss the possibility of
2289- // pruning based on the timestamp field being more than two weeks old,
2290- // but only in the non-normative section.
2291- if existing_chan_info. last_update > msg. timestamp {
2292- return Err ( LightningError { err: "Update older than last processed update" . to_owned( ) , action: ErrorAction :: IgnoreDuplicateGossip } ) ;
2293- } else if existing_chan_info. last_update == msg. timestamp {
2294- return Err ( LightningError { err: "Update had same timestamp as last processed update" . to_owned( ) , action: ErrorAction :: IgnoreDuplicateGossip } ) ;
2295- }
2296- }
2297- }
2279+ let check_msg_sanity = |channel : & ChannelInfo | -> Result < ( ) , LightningError > {
2280+ if let Some ( capacity_sats) = channel. capacity_sats {
2281+ // It's possible channel capacity is available now, although it wasn't available at announcement (so the field is None).
2282+ // Don't query UTXO set here to reduce DoS risks.
2283+ if capacity_sats > MAX_VALUE_MSAT / 1000 || msg. htlc_maximum_msat > capacity_sats * 1000 {
2284+ return Err ( LightningError { err :
2285+ "htlc_maximum_msat is larger than channel capacity or capacity is bogus" . to_owned ( ) ,
2286+ action : ErrorAction :: IgnoreError } ) ;
22982287 }
2288+ }
22992289
2300- macro_rules! get_new_channel_info {
2301- ( ) => { {
2302- let last_update_message = if msg. excess_data. len( ) <= MAX_EXCESS_BYTES_FOR_RELAY
2303- { full_msg. cloned( ) } else { None } ;
2304-
2305- let updated_channel_update_info = ChannelUpdateInfo {
2306- enabled: chan_enabled,
2307- last_update: msg. timestamp,
2308- cltv_expiry_delta: msg. cltv_expiry_delta,
2309- htlc_minimum_msat: msg. htlc_minimum_msat,
2310- htlc_maximum_msat: msg. htlc_maximum_msat,
2311- fees: RoutingFees {
2312- base_msat: msg. fee_base_msat,
2313- proportional_millionths: msg. fee_proportional_millionths,
2314- } ,
2315- last_update_message
2316- } ;
2317- Some ( updated_channel_update_info)
2318- } }
2319- }
2290+ if msg. channel_flags & 1 == 1 {
2291+ check_update_latest ( & channel. two_to_one )
2292+ } else {
2293+ check_update_latest ( & channel. one_to_two )
2294+ }
2295+ } ;
23202296
2321- let msg_hash = hash_to_message ! ( & message_sha256d_hash( & msg) [ ..] ) ;
2322- if msg. channel_flags & 1 == 1 {
2323- check_update_latest ! ( channel. two_to_one) ;
2324- if let Some ( sig) = sig {
2325- secp_verify_sig ! ( self . secp_ctx, & msg_hash, & sig, & PublicKey :: from_slice( channel. node_two. as_slice( ) ) . map_err( |_| LightningError {
2297+ let node_pubkey;
2298+ {
2299+ let channels = self . channels . read ( ) . unwrap ( ) ;
2300+ match channels. get ( & msg. short_channel_id ) {
2301+ None => {
2302+ core:: mem:: drop ( channels) ;
2303+ self . pending_checks . check_hold_pending_channel_update ( msg, full_msg) ?;
2304+ return Err ( LightningError {
2305+ err : "Couldn't find channel for update" . to_owned ( ) ,
2306+ action : ErrorAction :: IgnoreAndLog ( Level :: Gossip ) ,
2307+ } ) ;
2308+ } ,
2309+ Some ( channel) => {
2310+ check_msg_sanity ( channel) ?;
2311+ let node_id = if msg. channel_flags & 1 == 1 {
2312+ channel. node_two . as_slice ( )
2313+ } else {
2314+ channel. node_one . as_slice ( )
2315+ } ;
2316+ node_pubkey = PublicKey :: from_slice ( node_id)
2317+ . map_err ( |_| LightningError {
23262318 err : "Couldn't parse source node pubkey" . to_owned ( ) ,
23272319 action : ErrorAction :: IgnoreAndLog ( Level :: Debug )
2328- } ) ?, "channel_update" ) ;
2329- }
2330- if !only_verify {
2331- channel. two_to_one = get_new_channel_info ! ( ) ;
2332- }
2333- } else {
2334- check_update_latest ! ( channel. one_to_two) ;
2335- if let Some ( sig) = sig {
2336- secp_verify_sig ! ( self . secp_ctx, & msg_hash, & sig, & PublicKey :: from_slice( channel. node_one. as_slice( ) ) . map_err( |_| LightningError {
2337- err: "Couldn't parse destination node pubkey" . to_owned( ) ,
2338- action: ErrorAction :: IgnoreAndLog ( Level :: Debug )
2339- } ) ?, "channel_update" ) ;
2340- }
2341- if !only_verify {
2342- channel. one_to_two = get_new_channel_info ! ( ) ;
2343- }
2344- }
2320+ } ) ?;
2321+ } ,
2322+ }
2323+ }
2324+
2325+ let msg_hash = hash_to_message ! ( & message_sha256d_hash( & msg) [ ..] ) ;
2326+ if let Some ( sig) = sig {
2327+ secp_verify_sig ! ( self . secp_ctx, & msg_hash, & sig, & node_pubkey, "channel_update" ) ;
2328+ }
2329+
2330+ if only_verify { return Ok ( ( ) ) ; }
2331+
2332+ let mut channels = self . channels . write ( ) . unwrap ( ) ;
2333+ if let Some ( channel) = channels. get_mut ( & msg. short_channel_id ) {
2334+ check_msg_sanity ( channel) ?;
2335+
2336+ let last_update_message = if msg. excess_data . len ( ) <= MAX_EXCESS_BYTES_FOR_RELAY
2337+ { full_msg. cloned ( ) } else { None } ;
2338+
2339+ let new_channel_info = Some ( ChannelUpdateInfo {
2340+ enabled : chan_enabled,
2341+ last_update : msg. timestamp ,
2342+ cltv_expiry_delta : msg. cltv_expiry_delta ,
2343+ htlc_minimum_msat : msg. htlc_minimum_msat ,
2344+ htlc_maximum_msat : msg. htlc_maximum_msat ,
2345+ fees : RoutingFees {
2346+ base_msat : msg. fee_base_msat ,
2347+ proportional_millionths : msg. fee_proportional_millionths ,
2348+ } ,
2349+ last_update_message
2350+ } ) ;
2351+
2352+ if msg. channel_flags & 1 == 1 {
2353+ channel. two_to_one = new_channel_info;
2354+ } else {
2355+ channel. one_to_two = new_channel_info;
23452356 }
23462357 }
23472358
0 commit comments