lightningd/opening_control.c: Remove 'Try fundchannel_cancel again' error.

Changelog-Changed: `fundchannel_cancel` will now succeed even when executed while a `fundchannel_complete` is ongoing; in that case, it will be considered as cancelling the funding *after* the `fundchannel_complete` succeeds.

Let me introduce the concept of "Sequential Consistency":
All operations on parallel processes form a single total order agreed upon by all processes.

So for example, suppose we have parallel invocations of `fundchannel_complete` and `fundchannel_cancel`:

                          +--[fundchannel_complete]-->
                          |
    --[fundchannel_start]-+
                          |
                          +--[fundchannel_cancel]---->

What "Sequential Consistency" means is that the above parallel operations can be serialized as a single total order as:

    --[fundchannel_start]--[fundchannel_complete]--[fundchannel_cancel]-->

Or:

    --[fundchannel_start]--[fundchannel_cancel]--[fundchannel_complete]-->

In the first case, `fundchannel_complete` succeeds, and the `fundchannel_cancel` invocation also succeeds, sending an `error` to the peer to make them forget the chanel.

In the second case, `fundchannel_cancel` succeeds, and the succeeding `fundchannel_complete` invocation fails, since the funding is already cancelled and there is nothing to complete.

Note that in both cases, `fundchannel_cancel` **always** succeeds.

Unfortunately, prior to this commit, `fundchannel_cancel` could fail with a `Try fundchannel_cancel again` error if the `fundchannel_complete` is ongoing when the `fundchannel_cancel` is initiated.
This violates Sequential Consistency, as there is no single total order that would have caused `fundchannel_cancel` to fail.

This commit is a minimal patch which just reschedules `fundchannel_cancel` to occur after any `fundchannel_complete` that is ongoing.
This commit is contained in:
ZmnSCPxj jxPCSnmZ
2020-06-18 11:49:17 +08:00
committed by ZmnSCPxj, ZmnSCPxj jxPCSmnZ
parent e8936f9d23
commit 5db69f1b41
2 changed files with 65 additions and 13 deletions

View File

@@ -1025,7 +1025,7 @@ def test_funding_cancel_race(node_factory, bitcoind, executor):
else:
cancels.append(executor.submit(l1.rpc.fundchannel_cancel, n.info['id']))
# Only one should succeed.
# Only up to one should succeed.
success = False
for c in completes:
try:
@@ -1036,23 +1036,25 @@ def test_funding_cancel_race(node_factory, bitcoind, executor):
except RpcError:
pass
# These may both succeed, iff the above didn't.
# At least one of these must succeed, regardless of whether
# the completes succeeded or not.
cancelled = False
for c in cancels:
try:
c.result(TIMEOUT)
cancelled = True
assert not success
except RpcError:
pass
if cancelled:
num_cancel += 1
else:
assert success
# cancel always succeeds, as per Sequential Consistency.
# Either the cancel occurred before complete, in which
# case it prevents complete from succeeding, or it
# occurred after complete, in which case it errors the
# channel to force the remote to forget it.
assert cancelled
num_cancel += 1
print("Cancelled {} complete {}".format(num_cancel, num_complete))
assert num_cancel + num_complete == len(nodes)
assert num_cancel == len(nodes)
# We should have raced at least once!
if not VALGRIND: