| 75 | } |
| 76 | |
| 77 | static struct command_result *json_reserveinputs(struct command *cmd, |
| 78 | const char *buffer, |
| 79 | const jsmntok_t *obj UNNEEDED, |
| 80 | const jsmntok_t *params) |
| 81 | { |
| 82 | struct json_stream *response; |
| 83 | struct wally_psbt *psbt; |
| 84 | struct utxo **utxos = tal_arr(cmd, struct utxo *, 0); |
| 85 | bool *exclusive; |
| 86 | u32 *reserve, current_height; |
| 87 | |
| 88 | if (!param_check(cmd, buffer, params, |
| 89 | p_req("psbt", param_psbt, &psbt), |
| 90 | p_opt_def("exclusive", param_bool, &exclusive, true), |
| 91 | p_opt_def("reserve", param_number, &reserve, |
| 92 | RESERVATION_DEFAULT), |
| 93 | NULL)) |
| 94 | return command_param_failed(); |
| 95 | |
| 96 | /* We only deal with V2 internally */ |
| 97 | if (!psbt_set_version(psbt, 2)) { |
| 98 | return command_fail(cmd, LIGHTNINGD, |
| 99 | "Failed to set version for PSBT: %s", |
| 100 | fmt_wally_psbt(tmpctx, psbt)); |
| 101 | } |
| 102 | |
| 103 | current_height = get_block_height(cmd->ld->topology); |
| 104 | for (size_t i = 0; i < psbt->num_inputs; i++) { |
| 105 | struct bitcoin_outpoint outpoint; |
| 106 | struct utxo *utxo; |
| 107 | |
| 108 | wally_psbt_input_get_outpoint(&psbt->inputs[i], &outpoint); |
| 109 | utxo = wallet_utxo_get(cmd, cmd->ld->wallet, &outpoint); |
| 110 | if (!utxo) |
| 111 | continue; |
| 112 | if (*exclusive && utxo_is_reserved(utxo, current_height)) { |
| 113 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 114 | "%s already reserved", |
| 115 | fmt_bitcoin_outpoint(tmpctx, |
| 116 | &utxo->outpoint)); |
| 117 | } |
| 118 | if (utxo->status == OUTPUT_STATE_SPENT) |
| 119 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 120 | "%s already spent", |
| 121 | fmt_bitcoin_outpoint(tmpctx, |
| 122 | &utxo->outpoint)); |
| 123 | tal_arr_expand(&utxos, utxo); |
| 124 | } |
| 125 | |
| 126 | if (command_check_only(cmd)) |
| 127 | return command_check_done(cmd); |
| 128 | |
| 129 | response = json_stream_success(cmd); |
| 130 | reserve_and_report(response, cmd->ld->wallet, current_height, *reserve, utxos); |
| 131 | return command_success(cmd, response); |
| 132 | } |
| 133 | |
| 134 | static const struct json_command reserveinputs_command = { |
nothing calls this directly
no test coverage detected