(&self, htlc: &Htlc, onion: &Onion)
| 100 | } |
| 101 | impl<A: DatastoreProvider + Lsps2OfferProvider + LightningProvider> HtlcAcceptedHookHandler<A> { |
| 102 | pub async fn handle(&self, htlc: &Htlc, onion: &Onion) -> Result<HtlcDecision, HtlcError> { |
| 103 | // A) Is this SCID one that we care about? |
| 104 | let ds_rec = match self.api.get_buy_request(&onion.short_channel_id).await { |
| 105 | Ok(rec) => rec, |
| 106 | Err(_) => return Ok(HtlcDecision::NotOurs), |
| 107 | }; |
| 108 | |
| 109 | // Fixme: Check that we don't have a channel yet with the peer that we await to |
| 110 | // become READY to use. |
| 111 | // --- |
| 112 | |
| 113 | // Fixme: We only accept no-mpp for now, mpp and other flows will be added later on |
| 114 | // Fixme: We continue mpp for now to let the test mock handle the htlc, as we need |
| 115 | // to test the client implementation for mpp payments. |
| 116 | if ds_rec.expected_payment_size.is_some() { |
| 117 | return Ok(HtlcDecision::Reject { |
| 118 | reason: RejectReason::MppNotSupported, |
| 119 | }); |
| 120 | } |
| 121 | |
| 122 | // B) Is the fee option menu still valid? |
| 123 | if Utc::now() >= ds_rec.opening_fee_params.valid_until { |
| 124 | // Not valid anymore, remove from DS and fail HTLC. |
| 125 | let _ = self.api.del_buy_request(&onion.short_channel_id).await; |
| 126 | return Ok(HtlcDecision::Reject { |
| 127 | reason: RejectReason::OfferExpired { |
| 128 | valid_until: ds_rec.opening_fee_params.valid_until, |
| 129 | }, |
| 130 | }); |
| 131 | } |
| 132 | |
| 133 | // C) Is the amount in the boundaries of the fee menu? |
| 134 | if htlc.amount_msat.msat() < ds_rec.opening_fee_params.min_fee_msat.msat() { |
| 135 | return Ok(HtlcDecision::Reject { |
| 136 | reason: RejectReason::AmountBelowMinimum { |
| 137 | minimum: ds_rec.opening_fee_params.min_fee_msat, |
| 138 | }, |
| 139 | }); |
| 140 | } |
| 141 | |
| 142 | if htlc.amount_msat.msat() > ds_rec.opening_fee_params.max_payment_size_msat.msat() { |
| 143 | return Ok(HtlcDecision::Reject { |
| 144 | reason: RejectReason::AmountAboveMaximum { |
| 145 | maximum: ds_rec.opening_fee_params.max_payment_size_msat, |
| 146 | }, |
| 147 | }); |
| 148 | } |
| 149 | |
| 150 | // D) Check that the amount_msat covers the opening fee (only for non-mpp right now) |
| 151 | let opening_fee = match compute_opening_fee( |
| 152 | htlc.amount_msat.msat(), |
| 153 | ds_rec.opening_fee_params.min_fee_msat.msat(), |
| 154 | ds_rec.opening_fee_params.proportional.ppm() as u64, |
| 155 | ) { |
| 156 | Some(fee) if fee + self.htlc_minimum_msat < htlc.amount_msat.msat() => fee, |
| 157 | Some(fee) => { |
| 158 | return Ok(HtlcDecision::Reject { |
| 159 | reason: RejectReason::InsufficientForFee { |
no test coverage detected