mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-02 18:35:00 +01:00
lightningd: allow multiple cancels on a single fundchannel command.
Instead of taking over the ->cmd pointer, append ourselves to a list of cancels. This fixes the test_funding_cancel_race. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
4b1a300ee3
commit
280bd60988
2 changed files with 30 additions and 11 deletions
|
@ -88,6 +88,9 @@ struct funding_channel {
|
||||||
|
|
||||||
/* Whether or not this is in the middle of getting funded */
|
/* Whether or not this is in the middle of getting funded */
|
||||||
bool inflight;
|
bool inflight;
|
||||||
|
|
||||||
|
/* Any commands trying to cancel us. */
|
||||||
|
struct command **cancels;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void uncommitted_channel_disconnect(struct uncommitted_channel *uc,
|
static void uncommitted_channel_disconnect(struct uncommitted_channel *uc,
|
||||||
|
@ -265,6 +268,11 @@ static void funding_success(struct channel *channel)
|
||||||
struct funding_channel *fc = channel->peer->uncommitted_channel->fc;
|
struct funding_channel *fc = channel->peer->uncommitted_channel->fc;
|
||||||
struct command *cmd = fc->cmd;
|
struct command *cmd = fc->cmd;
|
||||||
|
|
||||||
|
/* Well, those cancels didn't work! */
|
||||||
|
for (size_t i = 0; i < tal_count(fc->cancels); i++)
|
||||||
|
was_pending(command_fail(fc->cancels[i], LIGHTNINGD,
|
||||||
|
"Funding succeeded before cancel"));
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_add_string(response, "channel_id",
|
json_add_string(response, "channel_id",
|
||||||
type_to_string(tmpctx, struct channel_id, &fc->cid));
|
type_to_string(tmpctx, struct channel_id, &fc->cid));
|
||||||
|
@ -672,8 +680,6 @@ static void opening_funder_failed(struct subd *openingd, const u8 *msg,
|
||||||
char *desc;
|
char *desc;
|
||||||
bool is_err;
|
bool is_err;
|
||||||
|
|
||||||
struct json_stream *response;
|
|
||||||
|
|
||||||
if (!fromwire_opening_funder_failed(msg, msg, &desc, &is_err)) {
|
if (!fromwire_opening_funder_failed(msg, msg, &desc, &is_err)) {
|
||||||
log_broken(uc->log,
|
log_broken(uc->log,
|
||||||
"bad OPENING_FUNDER_FAILED %s",
|
"bad OPENING_FUNDER_FAILED %s",
|
||||||
|
@ -685,14 +691,26 @@ static void opening_funder_failed(struct subd *openingd, const u8 *msg,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_err)
|
/* Tell anyone who was trying to cancel */
|
||||||
was_pending(command_fail(uc->fc->cmd, LIGHTNINGD, "%s", desc));
|
for (size_t i = 0; i < tal_count(uc->fc->cancels); i++) {
|
||||||
else {
|
if (is_err)
|
||||||
response = json_stream_success(uc->fc->cmd);
|
was_pending(command_fail(uc->fc->cancels[i], LIGHTNINGD,
|
||||||
json_add_string(response, "cancelled", desc);
|
"Funding failed anyway: %s",
|
||||||
was_pending(command_success(uc->fc->cmd, response));
|
desc));
|
||||||
|
else {
|
||||||
|
struct json_stream *response;
|
||||||
|
|
||||||
|
response = json_stream_success(uc->fc->cancels[i]);
|
||||||
|
json_add_string(response, "cancelled", desc);
|
||||||
|
was_pending(command_success(uc->fc->cancels[i],
|
||||||
|
response));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tell any fundchannel_complete or fundchannel command */
|
||||||
|
if (uc->fc->cmd)
|
||||||
|
was_pending(command_fail(uc->fc->cmd, LIGHTNINGD, "%s", desc));
|
||||||
|
|
||||||
/* Clear uc->fc, so we can try again, and so we don't fail twice
|
/* Clear uc->fc, so we can try again, and so we don't fail twice
|
||||||
* if they close. */
|
* if they close. */
|
||||||
uc->fc = tal_free(uc->fc);
|
uc->fc = tal_free(uc->fc);
|
||||||
|
@ -1200,8 +1218,8 @@ static struct command_result *json_fund_channel_cancel(struct command *cmd,
|
||||||
* question about 'how long cancelable'.
|
* question about 'how long cancelable'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Update the cmd to the new cmd */
|
/* Make sure this gets notified if we succeed or cancel */
|
||||||
peer->uncommitted_channel->fc->cmd = cmd;
|
tal_arr_expand(&peer->uncommitted_channel->fc->cancels, cmd);
|
||||||
msg = towire_opening_funder_cancel(NULL);
|
msg = towire_opening_funder_cancel(NULL);
|
||||||
subd_send_msg(peer->uncommitted_channel->openingd, take(msg));
|
subd_send_msg(peer->uncommitted_channel->openingd, take(msg));
|
||||||
return command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
|
@ -1227,6 +1245,7 @@ static struct command_result *json_fund_channel_start(struct command *cmd,
|
||||||
|
|
||||||
max_funding_satoshi = get_chainparams(cmd->ld)->max_funding;
|
max_funding_satoshi = get_chainparams(cmd->ld)->max_funding;
|
||||||
fc->cmd = cmd;
|
fc->cmd = cmd;
|
||||||
|
fc->cancels = tal_arr(fc, struct command *, 0);
|
||||||
fc->uc = NULL;
|
fc->uc = NULL;
|
||||||
fc->inflight = false;
|
fc->inflight = false;
|
||||||
if (!param(fc->cmd, buffer, params,
|
if (!param(fc->cmd, buffer, params,
|
||||||
|
@ -1321,6 +1340,7 @@ static struct command_result *json_fund_channel(struct command *cmd,
|
||||||
max_funding_satoshi = get_chainparams(cmd->ld)->max_funding;
|
max_funding_satoshi = get_chainparams(cmd->ld)->max_funding;
|
||||||
|
|
||||||
fc->cmd = cmd;
|
fc->cmd = cmd;
|
||||||
|
fc->cancels = tal_arr(fc, struct command *, 0);
|
||||||
fc->uc = NULL;
|
fc->uc = NULL;
|
||||||
fc->inflight = false;
|
fc->inflight = false;
|
||||||
fc->wtx = tal(fc, struct wallet_tx);
|
fc->wtx = tal(fc, struct wallet_tx);
|
||||||
|
|
|
@ -853,7 +853,6 @@ def test_funding_external_wallet_corners(node_factory, bitcoind):
|
||||||
l1.rpc.fundchannel_start(l2.info['id'], amount)
|
l1.rpc.fundchannel_start(l2.info['id'], amount)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(strict=True)
|
|
||||||
def test_funding_cancel_race(node_factory, bitcoind, executor):
|
def test_funding_cancel_race(node_factory, bitcoind, executor):
|
||||||
l1 = node_factory.get_node()
|
l1 = node_factory.get_node()
|
||||||
nodes = node_factory.get_nodes(100)
|
nodes = node_factory.get_nodes(100)
|
||||||
|
|
Loading…
Add table
Reference in a new issue