| 204 | } |
| 205 | |
| 206 | static struct command_result *json_sendonionmessage(struct command *cmd, |
| 207 | const char *buffer, |
| 208 | const jsmntok_t *obj UNNEEDED, |
| 209 | const jsmntok_t *params) |
| 210 | { |
| 211 | struct onion_hop *hops; |
| 212 | struct node_id *first_id; |
| 213 | struct pubkey *blinding; |
| 214 | struct sphinx_path *sphinx_path; |
| 215 | struct onionpacket *op; |
| 216 | struct secret *path_secrets; |
| 217 | size_t onion_size; |
| 218 | |
| 219 | if (!param(cmd, buffer, params, |
| 220 | p_req("first_id", param_node_id, &first_id), |
| 221 | p_req("blinding", param_pubkey, &blinding), |
| 222 | p_req("hops", param_onion_hops, &hops), |
| 223 | NULL)) |
| 224 | return command_param_failed(); |
| 225 | |
| 226 | if (!feature_offered(cmd->ld->our_features->bits[NODE_ANNOUNCE_FEATURE], |
| 227 | OPT_ONION_MESSAGES)) |
| 228 | return command_fail(cmd, LIGHTNINGD, |
| 229 | "experimental-onion-messages not enabled"); |
| 230 | |
| 231 | /* Sanity check first; connectd doesn't bother telling us if peer |
| 232 | * can't be reached. */ |
| 233 | if (!peer_by_id(cmd->ld, first_id)) |
| 234 | return command_fail(cmd, LIGHTNINGD, "Unknown first peer"); |
| 235 | |
| 236 | /* Create an onion which encodes this. */ |
| 237 | sphinx_path = sphinx_path_new(cmd, NULL); |
| 238 | for (size_t i = 0; i < tal_count(hops); i++) |
| 239 | sphinx_add_hop(sphinx_path, &hops[i].node, hops[i].tlv); |
| 240 | |
| 241 | /* BOLT-onion-message #4: |
| 242 | * - SHOULD set `len` to 1366 or 32834. |
| 243 | */ |
| 244 | if (sphinx_path_payloads_size(sphinx_path) <= ROUTING_INFO_SIZE) |
| 245 | onion_size = ROUTING_INFO_SIZE; |
| 246 | else |
| 247 | onion_size = 32768; |
| 248 | |
| 249 | op = create_onionpacket(tmpctx, sphinx_path, onion_size, &path_secrets); |
| 250 | if (!op) |
| 251 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 252 | "Creating onion failed (tlvs too long?)"); |
| 253 | |
| 254 | subd_send_msg(cmd->ld->connectd, |
| 255 | take(towire_connectd_send_onionmsg(NULL, first_id, |
| 256 | serialize_onionpacket(tmpctx, op), |
| 257 | blinding))); |
| 258 | |
| 259 | return command_success(cmd, json_stream_success(cmd)); |
| 260 | } |
| 261 | |
| 262 | static const struct json_command sendonionmessage_command = { |
| 263 | "sendonionmessage", |
nothing calls this directly
no test coverage detected