mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
lightningd/json: make wallet_tx functions take amount_sat.
Using param_tok is generally deprecated, as it doesn't give any sanity checking for the JSON 'check' command. So make param_wtx usable directly, and also make it have a struct amount_sat. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
3ba544bfde
commit
2632cc3f34
@ -4,26 +4,53 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
|
|
||||||
void wtx_init(struct command *cmd, struct wallet_tx * wtx)
|
void wtx_init(struct command *cmd, struct wallet_tx *wtx, struct amount_sat max)
|
||||||
{
|
{
|
||||||
wtx->cmd = cmd;
|
wtx->cmd = cmd;
|
||||||
wtx->amount = 0;
|
wtx->amount = max;
|
||||||
wtx->change_key_index = 0;
|
|
||||||
wtx->utxos = NULL;
|
|
||||||
wtx->all_funds = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct command_result *check_amount(const struct wallet_tx *tx,
|
struct command_result *param_wtx(struct command *cmd,
|
||||||
u64 amount)
|
const char *name,
|
||||||
|
const char *buffer,
|
||||||
|
const jsmntok_t *tok,
|
||||||
|
struct wallet_tx *wtx)
|
||||||
{
|
{
|
||||||
if (tal_count(tx->utxos) == 0) {
|
struct amount_sat max = wtx->amount;
|
||||||
return command_fail(tx->cmd, FUND_CANNOT_AFFORD,
|
|
||||||
|
if (json_tok_streq(buffer, tok, "all")) {
|
||||||
|
wtx->all_funds = true;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wtx->all_funds = false;
|
||||||
|
if (!parse_amount_sat(&wtx->amount,
|
||||||
|
buffer + tok->start, tok->end - tok->start))
|
||||||
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%s' should be satoshis or 'all', not '%.*s'",
|
||||||
|
name,
|
||||||
|
tok->end - tok->start,
|
||||||
|
buffer + tok->start);
|
||||||
|
|
||||||
|
if (amount_sat_greater(wtx->amount, max))
|
||||||
|
return command_fail(wtx->cmd, FUND_MAX_EXCEEDED,
|
||||||
|
"Amount exceeded %s",
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&max));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct command_result *check_amount(const struct wallet_tx *wtx,
|
||||||
|
struct amount_sat amount)
|
||||||
|
{
|
||||||
|
if (tal_count(wtx->utxos) == 0) {
|
||||||
|
return command_fail(wtx->cmd, FUND_CANNOT_AFFORD,
|
||||||
"Cannot afford transaction");
|
"Cannot afford transaction");
|
||||||
}
|
}
|
||||||
if (amount < 546) {
|
if (amount.satoshis < get_chainparams(wtx->cmd->ld)->dust_limit) {
|
||||||
return command_fail(tx->cmd, FUND_OUTPUT_IS_DUST,
|
return command_fail(wtx->cmd, FUND_OUTPUT_IS_DUST,
|
||||||
"Output %"PRIu64" satoshis would be dust",
|
"Output %s would be dust",
|
||||||
amount);
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&amount));
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -34,18 +61,21 @@ struct command_result *wtx_select_utxos(struct wallet_tx *tx,
|
|||||||
{
|
{
|
||||||
struct command_result *res;
|
struct command_result *res;
|
||||||
u64 fee_estimate;
|
u64 fee_estimate;
|
||||||
|
|
||||||
if (tx->all_funds) {
|
if (tx->all_funds) {
|
||||||
u64 amount;
|
struct amount_sat amount;
|
||||||
tx->utxos = wallet_select_all(tx->cmd, tx->cmd->ld->wallet,
|
tx->utxos = wallet_select_all(tx->cmd, tx->cmd->ld->wallet,
|
||||||
fee_rate_per_kw, out_len,
|
fee_rate_per_kw, out_len,
|
||||||
&amount,
|
&amount.satoshis,
|
||||||
&fee_estimate);
|
&fee_estimate);
|
||||||
res = check_amount(tx, amount);
|
res = check_amount(tx, amount);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (amount <= tx->amount) {
|
/* tx->amount is max permissible */
|
||||||
tx->change = 0;
|
if (amount_sat_less_eq(amount, tx->amount)) {
|
||||||
|
tx->change = AMOUNT_SAT(0);
|
||||||
|
tx->change_key_index = 0;
|
||||||
tx->amount = amount;
|
tx->amount = amount;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -56,15 +86,15 @@ struct command_result *wtx_select_utxos(struct wallet_tx *tx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tx->utxos = wallet_select_coins(tx->cmd, tx->cmd->ld->wallet,
|
tx->utxos = wallet_select_coins(tx->cmd, tx->cmd->ld->wallet,
|
||||||
tx->amount,
|
tx->amount.satoshis,
|
||||||
fee_rate_per_kw, out_len,
|
fee_rate_per_kw, out_len,
|
||||||
&fee_estimate, &tx->change);
|
&fee_estimate, &tx->change.satoshis);
|
||||||
res = check_amount(tx, tx->amount);
|
res = check_amount(tx, tx->amount);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (tx->change < 546) {
|
if (tx->change.satoshis < get_chainparams(tx->cmd->ld)->dust_limit) {
|
||||||
tx->change = 0;
|
tx->change = AMOUNT_SAT(0);
|
||||||
tx->change_key_index = 0;
|
tx->change_key_index = 0;
|
||||||
} else {
|
} else {
|
||||||
tx->change_key_index = wallet_get_newindex(tx->cmd->ld);
|
tx->change_key_index = wallet_get_newindex(tx->cmd->ld);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define LIGHTNING_COMMON_WALLET_TX_H
|
#define LIGHTNING_COMMON_WALLET_TX_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <ccan/short_types/short_types.h>
|
#include <ccan/short_types/short_types.h>
|
||||||
|
#include <common/amount.h>
|
||||||
#include <lightningd/json.h>
|
#include <lightningd/json.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
@ -11,15 +12,21 @@
|
|||||||
*/
|
*/
|
||||||
struct wallet_tx {
|
struct wallet_tx {
|
||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
u64 amount;
|
struct amount_sat amount, change;
|
||||||
u64 change;
|
|
||||||
u32 change_key_index;
|
u32 change_key_index;
|
||||||
const struct utxo **utxos;
|
const struct utxo **utxos;
|
||||||
|
|
||||||
bool all_funds; /* In this case, amount is a maximum. */
|
bool all_funds; /* In this case, amount is a maximum. */
|
||||||
};
|
};
|
||||||
|
|
||||||
void wtx_init(struct command *cmd, struct wallet_tx *wtx);
|
void wtx_init(struct command *cmd, struct wallet_tx *wtx, struct amount_sat max);
|
||||||
|
|
||||||
|
struct command_result *param_wtx(struct command *cmd,
|
||||||
|
const char *name,
|
||||||
|
const char *buffer,
|
||||||
|
const jsmntok_t *tok,
|
||||||
|
struct wallet_tx *wtx);
|
||||||
|
|
||||||
struct command_result *wtx_select_utxos(struct wallet_tx *tx,
|
struct command_result *wtx_select_utxos(struct wallet_tx *tx,
|
||||||
u32 fee_rate_per_kw,
|
u32 fee_rate_per_kw,
|
||||||
size_t out_len);
|
size_t out_len);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <common/memleak.h>
|
#include <common/memleak.h>
|
||||||
#include <common/param.h>
|
#include <common/param.h>
|
||||||
#include <common/type_to_string.h>
|
#include <common/type_to_string.h>
|
||||||
|
#include <common/wallet_tx.h>
|
||||||
#include <common/wireaddr.h>
|
#include <common/wireaddr.h>
|
||||||
#include <gossipd/routing.h>
|
#include <gossipd/routing.h>
|
||||||
#include <lightningd/json.h>
|
#include <lightningd/json.h>
|
||||||
|
@ -157,9 +157,4 @@ enum address_parse_result json_tok_address_scriptpubkey(const tal_t *ctx,
|
|||||||
const struct chainparams *chainparams,
|
const struct chainparams *chainparams,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *tok, const u8 **scriptpubkey);
|
const jsmntok_t *tok, const u8 **scriptpubkey);
|
||||||
|
|
||||||
/* Parse the satoshi token in wallet_tx. */
|
|
||||||
struct command_result *param_wtx(struct wallet_tx * tx, const char * buffer,
|
|
||||||
const jsmntok_t * sattok, u64 max);
|
|
||||||
|
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_JSON_H */
|
#endif /* LIGHTNING_LIGHTNINGD_JSON_H */
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include <common/param.h>
|
#include <common/param.h>
|
||||||
#include <common/timeout.h>
|
#include <common/timeout.h>
|
||||||
#include <common/version.h>
|
#include <common/version.h>
|
||||||
#include <common/wallet_tx.h>
|
|
||||||
#include <common/wireaddr.h>
|
#include <common/wireaddr.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -1031,22 +1030,6 @@ json_tok_address_scriptpubkey(const tal_t *cxt,
|
|||||||
return ADDRESS_PARSE_UNRECOGNIZED;
|
return ADDRESS_PARSE_UNRECOGNIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct command_result *param_wtx(struct wallet_tx * tx, const char * buffer,
|
|
||||||
const jsmntok_t *sattok, u64 max)
|
|
||||||
{
|
|
||||||
if (json_tok_streq(buffer, sattok, "all")) {
|
|
||||||
tx->all_funds = true;
|
|
||||||
tx->amount = max;
|
|
||||||
} else if (!json_to_u64(buffer, sattok, &tx->amount)) {
|
|
||||||
return command_fail(tx->cmd, JSONRPC2_INVALID_PARAMS,
|
|
||||||
"Invalid satoshis");
|
|
||||||
} else if (tx->amount > max) {
|
|
||||||
return command_fail(tx->cmd, FUND_MAX_EXCEEDED,
|
|
||||||
"Amount exceeded %"PRIu64, max);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct command_result *param_command(struct command *cmd,
|
static struct command_result *param_command(struct command *cmd,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
|
@ -128,7 +128,7 @@ void json_add_uncommitted_channel(struct json_stream *response,
|
|||||||
json_array_end(response);
|
json_array_end(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
msatoshi_total = uc->fc->wtx.amount * 1000;
|
msatoshi_total = uc->fc->wtx.amount.satoshis * 1000;
|
||||||
our_msatoshi = msatoshi_total - uc->fc->push_msat;
|
our_msatoshi = msatoshi_total - uc->fc->push_msat;
|
||||||
json_add_u64(response, "msatoshi_to_us", our_msatoshi);
|
json_add_u64(response, "msatoshi_to_us", our_msatoshi);
|
||||||
json_add_u64(response, "msatoshi_total", msatoshi_total);
|
json_add_u64(response, "msatoshi_total", msatoshi_total);
|
||||||
@ -317,16 +317,16 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
|||||||
&channel_info.remote_per_commit));
|
&channel_info.remote_per_commit));
|
||||||
|
|
||||||
/* Generate the funding tx. */
|
/* Generate the funding tx. */
|
||||||
if (fc->wtx.change
|
if (!amount_sat_eq(fc->wtx.change, AMOUNT_SAT(0))
|
||||||
&& !bip32_pubkey(ld->wallet->bip32_base,
|
&& !bip32_pubkey(ld->wallet->bip32_base,
|
||||||
&changekey, fc->wtx.change_key_index))
|
&changekey, fc->wtx.change_key_index))
|
||||||
fatal("Error deriving change key %u", fc->wtx.change_key_index);
|
fatal("Error deriving change key %u", fc->wtx.change_key_index);
|
||||||
|
|
||||||
fundingtx = funding_tx(tmpctx, &funding_outnum,
|
fundingtx = funding_tx(tmpctx, &funding_outnum,
|
||||||
fc->wtx.utxos, fc->wtx.amount,
|
fc->wtx.utxos, fc->wtx.amount.satoshis,
|
||||||
&fc->uc->local_funding_pubkey,
|
&fc->uc->local_funding_pubkey,
|
||||||
&channel_info.remote_fundingkey,
|
&channel_info.remote_fundingkey,
|
||||||
fc->wtx.change, &changekey,
|
fc->wtx.change.satoshis, &changekey,
|
||||||
ld->wallet->bip32_base);
|
ld->wallet->bip32_base);
|
||||||
|
|
||||||
log_debug(fc->uc->log, "Funding tx has %zi inputs, %zu outputs:",
|
log_debug(fc->uc->log, "Funding tx has %zi inputs, %zu outputs:",
|
||||||
@ -346,22 +346,29 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
|||||||
if (!bitcoin_txid_eq(&funding_txid, &expected_txid)) {
|
if (!bitcoin_txid_eq(&funding_txid, &expected_txid)) {
|
||||||
log_broken(fc->uc->log,
|
log_broken(fc->uc->log,
|
||||||
"Funding txid mismatch:"
|
"Funding txid mismatch:"
|
||||||
" satoshi %"PRIu64" change %"PRIu64
|
" amount %s change %s"
|
||||||
" changeidx %u"
|
" changeidx %u"
|
||||||
" localkey %s remotekey %s",
|
" localkey %s remotekey %s",
|
||||||
fc->wtx.amount,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
fc->wtx.change, fc->wtx.change_key_index,
|
&fc->wtx.amount),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&fc->wtx.change),
|
||||||
|
fc->wtx.change_key_index,
|
||||||
type_to_string(fc, struct pubkey,
|
type_to_string(fc, struct pubkey,
|
||||||
&fc->uc->local_funding_pubkey),
|
&fc->uc->local_funding_pubkey),
|
||||||
type_to_string(fc, struct pubkey,
|
type_to_string(fc, struct pubkey,
|
||||||
&channel_info.remote_fundingkey));
|
&channel_info.remote_fundingkey));
|
||||||
was_pending(command_fail(fc->cmd, JSONRPC2_INVALID_PARAMS,
|
was_pending(command_fail(fc->cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Funding txid mismatch:"
|
"Funding txid mismatch:"
|
||||||
" satoshi %"PRIu64" change %"PRIu64
|
" amount %s change %s"
|
||||||
" changeidx %u"
|
" changeidx %u"
|
||||||
" localkey %s remotekey %s",
|
" localkey %s remotekey %s",
|
||||||
fc->wtx.amount,
|
type_to_string(tmpctx,
|
||||||
fc->wtx.change,
|
struct amount_sat,
|
||||||
|
&fc->wtx.amount),
|
||||||
|
type_to_string(tmpctx,
|
||||||
|
struct amount_sat,
|
||||||
|
&fc->wtx.change),
|
||||||
fc->wtx.change_key_index,
|
fc->wtx.change_key_index,
|
||||||
type_to_string(fc, struct pubkey,
|
type_to_string(fc, struct pubkey,
|
||||||
&fc->uc->local_funding_pubkey),
|
&fc->uc->local_funding_pubkey),
|
||||||
@ -376,7 +383,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
|||||||
&remote_commit_sig,
|
&remote_commit_sig,
|
||||||
&funding_txid,
|
&funding_txid,
|
||||||
funding_outnum,
|
funding_outnum,
|
||||||
fc->wtx.amount,
|
fc->wtx.amount.satoshis,
|
||||||
fc->push_msat,
|
fc->push_msat,
|
||||||
fc->channel_flags,
|
fc->channel_flags,
|
||||||
&channel_info,
|
&channel_info,
|
||||||
@ -391,7 +398,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
|||||||
log_debug(channel->log, "Getting HSM to sign funding tx");
|
log_debug(channel->log, "Getting HSM to sign funding tx");
|
||||||
|
|
||||||
msg = towire_hsm_sign_funding(tmpctx, channel->funding_satoshi,
|
msg = towire_hsm_sign_funding(tmpctx, channel->funding_satoshi,
|
||||||
fc->wtx.change, fc->wtx.change_key_index,
|
fc->wtx.change.satoshis,
|
||||||
|
fc->wtx.change_key_index,
|
||||||
&fc->uc->local_funding_pubkey,
|
&fc->uc->local_funding_pubkey,
|
||||||
&channel_info.remote_fundingkey,
|
&channel_info.remote_fundingkey,
|
||||||
fc->wtx.utxos);
|
fc->wtx.utxos);
|
||||||
@ -804,7 +812,6 @@ static struct command_result *json_fund_channel(struct command *cmd,
|
|||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
struct command_result *res;
|
struct command_result *res;
|
||||||
const jsmntok_t *sattok;
|
|
||||||
struct funding_channel * fc = tal(cmd, struct funding_channel);
|
struct funding_channel * fc = tal(cmd, struct funding_channel);
|
||||||
struct pubkey *id;
|
struct pubkey *id;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
@ -812,23 +819,21 @@ static struct command_result *json_fund_channel(struct command *cmd,
|
|||||||
u32 *feerate_per_kw;
|
u32 *feerate_per_kw;
|
||||||
bool *announce_channel;
|
bool *announce_channel;
|
||||||
u8 *msg;
|
u8 *msg;
|
||||||
u64 max_funding_satoshi = get_chainparams(cmd->ld)->max_funding_satoshi;
|
struct amount_sat max_funding_satoshi;
|
||||||
|
|
||||||
|
max_funding_satoshi.satoshis = get_chainparams(cmd->ld)->max_funding_satoshi;
|
||||||
|
|
||||||
fc->cmd = cmd;
|
fc->cmd = cmd;
|
||||||
fc->uc = NULL;
|
fc->uc = NULL;
|
||||||
wtx_init(cmd, &fc->wtx);
|
wtx_init(cmd, &fc->wtx, max_funding_satoshi);
|
||||||
if (!param(fc->cmd, buffer, params,
|
if (!param(fc->cmd, buffer, params,
|
||||||
p_req("id", param_pubkey, &id),
|
p_req("id", param_pubkey, &id),
|
||||||
p_req("satoshi", param_tok, &sattok),
|
p_req("satoshi", param_wtx, &fc->wtx),
|
||||||
p_opt("feerate", param_feerate, &feerate_per_kw),
|
p_opt("feerate", param_feerate, &feerate_per_kw),
|
||||||
p_opt_def("announce", param_bool, &announce_channel, true),
|
p_opt_def("announce", param_bool, &announce_channel, true),
|
||||||
NULL))
|
NULL))
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
res = param_wtx(&fc->wtx, buffer, sattok, max_funding_satoshi);
|
|
||||||
if (res)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
if (!feerate_per_kw) {
|
if (!feerate_per_kw) {
|
||||||
feerate_per_kw = tal(cmd, u32);
|
feerate_per_kw = tal(cmd, u32);
|
||||||
*feerate_per_kw = opening_feerate(cmd->ld->topology);
|
*feerate_per_kw = opening_feerate(cmd->ld->topology);
|
||||||
@ -876,16 +881,16 @@ static struct command_result *json_fund_channel(struct command *cmd,
|
|||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
assert(fc->wtx.amount <= max_funding_satoshi);
|
assert(!amount_sat_greater(fc->wtx.amount, max_funding_satoshi));
|
||||||
|
|
||||||
peer->uncommitted_channel->fc = tal_steal(peer->uncommitted_channel, fc);
|
peer->uncommitted_channel->fc = tal_steal(peer->uncommitted_channel, fc);
|
||||||
fc->uc = peer->uncommitted_channel;
|
fc->uc = peer->uncommitted_channel;
|
||||||
|
|
||||||
msg = towire_opening_funder(NULL,
|
msg = towire_opening_funder(NULL,
|
||||||
fc->wtx.amount,
|
fc->wtx.amount.satoshis,
|
||||||
fc->push_msat,
|
fc->push_msat,
|
||||||
*feerate_per_kw,
|
*feerate_per_kw,
|
||||||
fc->wtx.change,
|
fc->wtx.change.satoshis,
|
||||||
fc->wtx.change_key_index,
|
fc->wtx.change_key_index,
|
||||||
fc->channel_flags,
|
fc->channel_flags,
|
||||||
fc->wtx.utxos,
|
fc->wtx.utxos,
|
||||||
|
@ -66,7 +66,7 @@ static void wallet_withdrawal_broadcast(struct bitcoind *bitcoind UNUSED,
|
|||||||
|
|
||||||
/* Note normally, change_satoshi == withdraw->wtx.change, but
|
/* Note normally, change_satoshi == withdraw->wtx.change, but
|
||||||
* not if we're actually making a payment to ourselves! */
|
* not if we're actually making a payment to ourselves! */
|
||||||
assert(change_satoshi >= withdraw->wtx.change);
|
assert(change_satoshi >= withdraw->wtx.change.satoshis);
|
||||||
|
|
||||||
struct json_stream *response = json_stream_success(cmd);
|
struct json_stream *response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
@ -93,7 +93,7 @@ static struct command_result *json_withdraw(struct command *cmd,
|
|||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
const jsmntok_t *desttok, *sattok;
|
const jsmntok_t *desttok;
|
||||||
struct withdrawal *withdraw = tal(cmd, struct withdrawal);
|
struct withdrawal *withdraw = tal(cmd, struct withdrawal);
|
||||||
u32 *feerate_per_kw;
|
u32 *feerate_per_kw;
|
||||||
struct bitcoin_tx *tx;
|
struct bitcoin_tx *tx;
|
||||||
@ -103,19 +103,15 @@ static struct command_result *json_withdraw(struct command *cmd,
|
|||||||
struct command_result *res;
|
struct command_result *res;
|
||||||
|
|
||||||
withdraw->cmd = cmd;
|
withdraw->cmd = cmd;
|
||||||
wtx_init(cmd, &withdraw->wtx);
|
wtx_init(cmd, &withdraw->wtx, AMOUNT_SAT(-1ULL));
|
||||||
|
|
||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("destination", param_tok, &desttok),
|
p_req("destination", param_tok, &desttok),
|
||||||
p_req("satoshi", param_tok, &sattok),
|
p_req("satoshi", param_wtx, &withdraw->wtx),
|
||||||
p_opt("feerate", param_feerate, &feerate_per_kw),
|
p_opt("feerate", param_feerate, &feerate_per_kw),
|
||||||
NULL))
|
NULL))
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
res = param_wtx(&withdraw->wtx, buffer, sattok, -1ULL);
|
|
||||||
if (res)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
if (!feerate_per_kw) {
|
if (!feerate_per_kw) {
|
||||||
res = param_feerate_estimate(cmd, &feerate_per_kw,
|
res = param_feerate_estimate(cmd, &feerate_per_kw,
|
||||||
FEERATE_NORMAL);
|
FEERATE_NORMAL);
|
||||||
@ -160,8 +156,8 @@ static struct command_result *json_withdraw(struct command *cmd,
|
|||||||
txfilter_add_derkey(cmd->ld->owned_txfilter, ext.pub_key);
|
txfilter_add_derkey(cmd->ld->owned_txfilter, ext.pub_key);
|
||||||
|
|
||||||
u8 *msg = towire_hsm_sign_withdrawal(cmd,
|
u8 *msg = towire_hsm_sign_withdrawal(cmd,
|
||||||
withdraw->wtx.amount,
|
withdraw->wtx.amount.satoshis,
|
||||||
withdraw->wtx.change,
|
withdraw->wtx.change.satoshis,
|
||||||
withdraw->wtx.change_key_index,
|
withdraw->wtx.change_key_index,
|
||||||
withdraw->destination,
|
withdraw->destination,
|
||||||
withdraw->wtx.utxos);
|
withdraw->wtx.utxos);
|
||||||
|
Loading…
Reference in New Issue
Block a user