| 214 | } |
| 215 | |
| 216 | struct command_result *handle_invoice(struct command *cmd, |
| 217 | const u8 *invbin, |
| 218 | struct blinded_path *reply_path STEALS, |
| 219 | const struct secret *secret) |
| 220 | { |
| 221 | const struct offers_data *od = get_offers_data(cmd->plugin); |
| 222 | size_t len = tal_count(invbin); |
| 223 | struct inv *inv = tal(cmd, struct inv); |
| 224 | struct out_req *req; |
| 225 | int bad_feature; |
| 226 | u64 invexpiry; |
| 227 | |
| 228 | inv->reply_path = tal_steal(inv, reply_path); |
| 229 | |
| 230 | inv->inv = fromwire_tlv_invoice(cmd, &invbin, &len); |
| 231 | if (!inv->inv) { |
| 232 | return fail_inv(cmd, inv, |
| 233 | "Invalid invoice %s", |
| 234 | tal_hex(tmpctx, invbin)); |
| 235 | } |
| 236 | |
| 237 | if (secret) { |
| 238 | const u8 *path_secret; |
| 239 | struct blinded_path **invreq_paths = inv->inv->invreq_paths; |
| 240 | struct sha256 invreq_id_nopath; |
| 241 | |
| 242 | /* Necessarily, path_id is taken without the invreq_paths. */ |
| 243 | inv->inv->invreq_paths = NULL; |
| 244 | invoice_invreq_id(inv->inv, &invreq_id_nopath); |
| 245 | inv->inv->invreq_paths = invreq_paths; |
| 246 | |
| 247 | path_secret = bolt12_path_id(tmpctx, &od->offerblinding_base, &invreq_id_nopath); |
| 248 | if (!memeq(path_secret, tal_count(path_secret), |
| 249 | secret, sizeof(*secret))) { |
| 250 | if (command_dev_apis(cmd)) |
| 251 | return fail_inv(cmd, inv, "Wrong blinded path (invreq_id_nopath = %s, path_secret = %s, secret = %s)", |
| 252 | fmt_sha256(tmpctx, &invreq_id_nopath), |
| 253 | tal_hex(tmpctx, path_secret), |
| 254 | fmt_secret(tmpctx, secret)); |
| 255 | /* Normally, "I don't know what you're talking about!" */ |
| 256 | return fail_inv(cmd, inv, "Unknown invoice_request %s", |
| 257 | fmt_sha256(tmpctx, &inv->invreq_id)); |
| 258 | } |
| 259 | } else { |
| 260 | /* BOLT #12: |
| 261 | * - if `invreq_paths` is present: |
| 262 | * - MUST reject the invoice if it did not arrive via one of those paths. |
| 263 | */ |
| 264 | /* Didn't use path. Was it supposed to? */ |
| 265 | if (inv->inv->invreq_paths) { |
| 266 | if (command_dev_apis(cmd)) |
| 267 | return fail_inv(cmd, inv, "Expected to use invreq_path!"); |
| 268 | /* Normally, "I don't know what you're talking about!" */ |
| 269 | return fail_inv(cmd, inv, "Unknown invoice_request %s", |
| 270 | fmt_sha256(tmpctx, &inv->invreq_id)); |
| 271 | } |
| 272 | } |
| 273 |
no test coverage detected