mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
funder: pull out previous input list from datastore on RBF
It'd be nice to know which utxos we used previously, so we can rebuild a transaction using them!
This commit is contained in:
committed by
Christian Decker
parent
a5e9035e2e
commit
7733c2b0f4
116
plugins/funder.c
116
plugins/funder.c
@@ -361,6 +361,9 @@ struct open_info {
|
|||||||
u32 node_blockheight;
|
u32 node_blockheight;
|
||||||
|
|
||||||
struct amount_sat requested_lease;
|
struct amount_sat requested_lease;
|
||||||
|
|
||||||
|
/* List of previously-used utxos */
|
||||||
|
struct bitcoin_outpoint **prev_outs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct open_info *new_open_info(const tal_t *ctx)
|
static struct open_info *new_open_info(const tal_t *ctx)
|
||||||
@@ -372,6 +375,7 @@ static struct open_info *new_open_info(const tal_t *ctx)
|
|||||||
info->requested_lease = AMOUNT_SAT(0);
|
info->requested_lease = AMOUNT_SAT(0);
|
||||||
info->lease_blockheight = 0;
|
info->lease_blockheight = 0;
|
||||||
info->node_blockheight = 0;
|
info->node_blockheight = 0;
|
||||||
|
info->prev_outs = NULL;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@@ -612,7 +616,7 @@ json_openchannel2_call(struct command *cmd,
|
|||||||
const char *buf,
|
const char *buf,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
struct open_info *info = tal(cmd, struct open_info);
|
struct open_info *info = new_open_info(cmd);
|
||||||
struct amount_msat max_htlc_inflight, htlc_minimum;
|
struct amount_msat max_htlc_inflight, htlc_minimum;
|
||||||
u64 commitment_feerate_perkw,
|
u64 commitment_feerate_perkw,
|
||||||
feerate_our_max, feerate_our_min;
|
feerate_our_max, feerate_our_min;
|
||||||
@@ -739,6 +743,99 @@ json_openchannel2_call(struct command *cmd,
|
|||||||
return send_outreq(cmd->plugin, req);
|
return send_outreq(cmd->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct command_result *
|
||||||
|
datastore_list_fail(struct command *cmd,
|
||||||
|
const char *buf,
|
||||||
|
const jsmntok_t *error,
|
||||||
|
struct open_info *info)
|
||||||
|
{
|
||||||
|
struct out_req *req;
|
||||||
|
|
||||||
|
/* Oops, something's broken */
|
||||||
|
plugin_log(cmd->plugin, LOG_BROKEN,
|
||||||
|
"`datastore` list failed: %*.s",
|
||||||
|
json_tok_full_len(error),
|
||||||
|
json_tok_full(buf, error));
|
||||||
|
|
||||||
|
/* Figure out what our funds are... same flow
|
||||||
|
* as with openchannel2 callback. */
|
||||||
|
req = jsonrpc_request_start(cmd->plugin, cmd,
|
||||||
|
"listfunds",
|
||||||
|
&listfunds_success,
|
||||||
|
&listfunds_failed,
|
||||||
|
info);
|
||||||
|
return send_outreq(cmd->plugin, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct command_result *
|
||||||
|
datastore_list_success(struct command *cmd,
|
||||||
|
const char *buf,
|
||||||
|
const jsmntok_t *result,
|
||||||
|
struct open_info *info)
|
||||||
|
{
|
||||||
|
struct out_req *req;
|
||||||
|
const char *key, *err;
|
||||||
|
const u8 *utxos_bin;
|
||||||
|
size_t len, i;
|
||||||
|
const jsmntok_t *ds_arr_tok, *ds_result;
|
||||||
|
|
||||||
|
ds_arr_tok = json_get_member(buf, result, "datastore");
|
||||||
|
assert(ds_arr_tok->type == JSMN_ARRAY);
|
||||||
|
|
||||||
|
/* There should only be one result */
|
||||||
|
utxos_bin = NULL;
|
||||||
|
json_for_each_arr(i, ds_result, ds_arr_tok) {
|
||||||
|
err = json_scan(tmpctx, buf, ds_result,
|
||||||
|
"{key:%,hex:%}",
|
||||||
|
JSON_SCAN_TAL(cmd, json_strdup, &key),
|
||||||
|
JSON_SCAN_TAL(cmd, json_tok_bin_from_hex,
|
||||||
|
&utxos_bin));
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
plugin_err(cmd->plugin,
|
||||||
|
"`listdatastore` payload did"
|
||||||
|
" not scan. %s: %*.s",
|
||||||
|
err, json_tok_full_len(result),
|
||||||
|
json_tok_full(buf, result));
|
||||||
|
|
||||||
|
/* We found the prev utxo list */
|
||||||
|
plugin_log(cmd->plugin, LOG_DBG,
|
||||||
|
"Saved utxos for channel (%s)"
|
||||||
|
" pulled from datastore", key);
|
||||||
|
|
||||||
|
/* There should only be one result */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resurrect outpoints from stashed binary */
|
||||||
|
len = tal_bytelen(utxos_bin);
|
||||||
|
while (len > 0) {
|
||||||
|
struct bitcoin_outpoint *outpoint =
|
||||||
|
tal(info, struct bitcoin_outpoint);
|
||||||
|
fromwire_bitcoin_outpoint(&utxos_bin,
|
||||||
|
&len, outpoint);
|
||||||
|
/* Cursor gets set to null if above fails */
|
||||||
|
if (!utxos_bin)
|
||||||
|
plugin_err(cmd->plugin,
|
||||||
|
"Unable to parse saved utxos: %.*s",
|
||||||
|
json_tok_full_len(result),
|
||||||
|
json_tok_full(buf, result));
|
||||||
|
|
||||||
|
if (!info->prev_outs)
|
||||||
|
info->prev_outs =
|
||||||
|
tal_arr(info, struct bitcoin_outpoint *, 0);
|
||||||
|
|
||||||
|
tal_arr_expand(&info->prev_outs, outpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
req = jsonrpc_request_start(cmd->plugin, cmd,
|
||||||
|
"listfunds",
|
||||||
|
&listfunds_success,
|
||||||
|
&listfunds_failed,
|
||||||
|
info);
|
||||||
|
return send_outreq(cmd->plugin, req);
|
||||||
|
}
|
||||||
|
|
||||||
/* Peer has asked us to RBF */
|
/* Peer has asked us to RBF */
|
||||||
static struct command_result *
|
static struct command_result *
|
||||||
json_rbf_channel_call(struct command *cmd,
|
json_rbf_channel_call(struct command *cmd,
|
||||||
@@ -747,7 +844,7 @@ json_rbf_channel_call(struct command *cmd,
|
|||||||
{
|
{
|
||||||
struct open_info *info = new_open_info(cmd);
|
struct open_info *info = new_open_info(cmd);
|
||||||
u64 feerate_our_max, feerate_our_min;
|
u64 feerate_our_max, feerate_our_min;
|
||||||
const char *err;
|
const char *err, *chan_key;
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
|
|
||||||
info->their_last_funding = tal(info, struct amount_sat);
|
info->their_last_funding = tal(info, struct amount_sat);
|
||||||
@@ -805,15 +902,16 @@ json_rbf_channel_call(struct command *cmd,
|
|||||||
return command_hook_success(cmd);
|
return command_hook_success(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out what our funds are... same flow
|
/* Fetch out previous utxos from the datastore */
|
||||||
* as with openchannel2 callback. We assume that THEY
|
|
||||||
* will use the same inputs, so we use whatever we want here */
|
|
||||||
req = jsonrpc_request_start(cmd->plugin, cmd,
|
req = jsonrpc_request_start(cmd->plugin, cmd,
|
||||||
"listfunds",
|
"listdatastore",
|
||||||
&listfunds_success,
|
&datastore_list_success,
|
||||||
&listfunds_failed,
|
&datastore_list_fail,
|
||||||
info);
|
info);
|
||||||
|
chan_key = tal_fmt(cmd, "funder/%s",
|
||||||
|
type_to_string(cmd, struct channel_id,
|
||||||
|
&info->cid));
|
||||||
|
json_add_string(req->js, "key", chan_key);
|
||||||
return send_outreq(cmd->plugin, req);
|
return send_outreq(cmd->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user