| 157 | } |
| 158 | |
| 159 | static struct command_result *handle_invreq_response(struct command *cmd, |
| 160 | struct sent *sent, |
| 161 | const char *buf, |
| 162 | const jsmntok_t *om) |
| 163 | { |
| 164 | const u8 *invbin, *cursor; |
| 165 | const jsmntok_t *invtok; |
| 166 | size_t len; |
| 167 | struct tlv_invoice *inv; |
| 168 | struct sha256 merkle, sighash; |
| 169 | struct json_stream *out; |
| 170 | const char *badfield; |
| 171 | u64 *expected_amount; |
| 172 | const struct recurrence *recurrence; |
| 173 | |
| 174 | invtok = json_get_member(buf, om, "invoice"); |
| 175 | if (!invtok) { |
| 176 | plugin_log(cmd->plugin, LOG_UNUSUAL, |
| 177 | "Neither invoice nor invoice_request_failed in reply %.*s", |
| 178 | json_tok_full_len(om), |
| 179 | json_tok_full(buf, om)); |
| 180 | discard_result(command_fail(sent->cmd, |
| 181 | OFFER_BAD_INVREQ_REPLY, |
| 182 | "Neither invoice nor invoice_request_failed in reply %.*s", |
| 183 | json_tok_full_len(om), |
| 184 | json_tok_full(buf, om))); |
| 185 | return command_hook_success(cmd); |
| 186 | } |
| 187 | |
| 188 | invbin = json_tok_bin_from_hex(cmd, buf, invtok); |
| 189 | cursor = invbin; |
| 190 | len = tal_bytelen(invbin); |
| 191 | inv = fromwire_tlv_invoice(cmd, &cursor, &len); |
| 192 | if (!inv) { |
| 193 | badfield = "invoice"; |
| 194 | goto badinv; |
| 195 | } |
| 196 | |
| 197 | /* Raw send? Just fwd reply. */ |
| 198 | if (plugin_developer_mode(cmd->plugin) && !sent->offer) { |
| 199 | out = jsonrpc_stream_success(sent->cmd); |
| 200 | json_add_string(out, "invoice", invoice_encode(tmpctx, inv)); |
| 201 | discard_result(command_finished(sent->cmd, out)); |
| 202 | return command_hook_success(cmd); |
| 203 | } |
| 204 | |
| 205 | /* BOLT #12: |
| 206 | * - if the invoice is a response to an `invoice_request`: |
| 207 | * - MUST reject the invoice if all fields in ranges 0 to 159 and |
| 208 | * 1000000000 to 2999999999 (inclusive) do not exactly match the |
| 209 | * invoice request. |
| 210 | */ |
| 211 | if (!invoice_matches_request(cmd, invbin, sent->invreq)) { |
| 212 | badfield = "invoice_request match"; |
| 213 | goto badinv; |
| 214 | } |
| 215 | |
| 216 | /* BOLT #12: |
no test coverage detected