+
+ // Check that the payment hash and secret are known. Note that we
+ // MUST take care to handle the "unknown payment hash" and
+ // "incorrect payment secret" cases here identically or we'd expose
+ // that we are the ultimate recipient of the given payment hash.
+ // Further, we must not expose whether we have any other HTLCs
+ // associated with the same payment_hash pending or not.
+ let mut payment_secrets = self.pending_inbound_payments.lock().unwrap();
+ match payment_secrets.entry(payment_hash) {
+ hash_map::Entry::Vacant(_) => {
+ log_trace!(self.logger, "Failing new HTLC with payment_hash {} as we didn't have a corresponding inbound payment.", log_bytes!(payment_hash.0));
+ fail_htlc!(claimable_htlc);
+ },
+ hash_map::Entry::Occupied(inbound_payment) => {
+ if inbound_payment.get().payment_secret != payment_data.payment_secret {
+ log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", log_bytes!(payment_hash.0));
+ fail_htlc!(claimable_htlc);
+ } else if inbound_payment.get().min_value_msat.is_some() && payment_data.total_msat < inbound_payment.get().min_value_msat.unwrap() {
+ log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our minimum value (had {}, needed {}).",
+ log_bytes!(payment_hash.0), payment_data.total_msat, inbound_payment.get().min_value_msat.unwrap());
+ fail_htlc!(claimable_htlc);
+ } else {
+ let mut total_value = 0;
+ let htlcs = channel_state.claimable_htlcs.entry(payment_hash)
+ .or_insert(Vec::new());
+ htlcs.push(claimable_htlc);
+ for htlc in htlcs.iter() {
+ total_value += htlc.value;
+ if htlc.payment_data.total_msat != payment_data.total_msat {
+ log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})",
+ log_bytes!(payment_hash.0), payment_data.total_msat, htlc.payment_data.total_msat);
+ total_value = msgs::MAX_VALUE_MSAT;
+ }
+ if total_value >= msgs::MAX_VALUE_MSAT { break; }
+ }
+ if total_value >= msgs::MAX_VALUE_MSAT || total_value > payment_data.total_msat {
+ log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the total value {} ran over expected value {} (or HTLCs were inconsistent)",
+ log_bytes!(payment_hash.0), total_value, payment_data.total_msat);
+ for htlc in htlcs.iter() {
+ fail_htlc!(htlc);
+ }
+ } else if total_value == payment_data.total_msat {
+ new_events.push(events::Event::PaymentReceived {
+ payment_hash,
+ payment_preimage: inbound_payment.get().payment_preimage,
+ payment_secret: payment_data.payment_secret,
+ amt: total_value,
+ user_payment_id: inbound_payment.get().user_payment_id,
+ });
+ // Only ever generate at most one PaymentReceived
+ // per registered payment_hash, even if it isn't
+ // claimed.
+ inbound_payment.remove_entry();
+ } else {
+ // Nothing to do - we haven't reached the total
+ // payment value yet, wait until we receive more
+ // MPP parts.
+ }
+ }
+ },
+ };