Skip to content

Commit

Permalink
pytest: stress test funding_cancel vs funding_complete
Browse files Browse the repository at this point in the history
This fails, because they fight over the fc->cmd pointer, leaving
others hanging.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell authored and niftynei committed Jul 8, 2019
1 parent 2945b25 commit 13dbe6e
Showing 1 changed file with 57 additions and 1 deletion.
58 changes: 57 additions & 1 deletion tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from fixtures import * # noqa: F401,F403
from flaky import flaky # noqa: F401
from lightning import RpcError
from utils import DEVELOPER, only_one, wait_for, sync_blockheight, VALGRIND
from utils import DEVELOPER, only_one, wait_for, sync_blockheight, VALGRIND, TIMEOUT
from bitcoin.core import CMutableTransaction, CMutableTxOut

import binascii
Expand Down Expand Up @@ -853,6 +853,62 @@ def test_funding_external_wallet_corners(node_factory, bitcoind):
l1.rpc.fundchannel_start(l2.info['id'], amount)


@pytest.mark.xfail(strict=True)
def test_funding_cancel_race(node_factory, bitcoind, executor):
l1 = node_factory.get_node()
nodes = node_factory.get_nodes(100)

# Speed up cleanup by not cleaning our test nodes: on my laptop, this goes
# from 214 to 15 seconds
node_factory.nodes = [l1]

num_complete = 0
num_cancel = 0

for n in nodes:
l1.rpc.connect(n.info['id'], 'localhost', n.port)
l1.rpc.fundchannel_start(n.info['id'], "100000sat")

# We simply make up txids. And submit two of each at once.
completes = [executor.submit(l1.rpc.fundchannel_complete, n.info['id'], "9f1844419d2f41532a57fb5ef038cacb602000f7f37b3dae68dc2d047c89048f", 0),
executor.submit(l1.rpc.fundchannel_complete, n.info['id'], "9f1844419d2f41532a57fb5ef038cacb602000f7f37b3dae68dc2d047c89048f", 0)]
cancels = [executor.submit(l1.rpc.fundchannel_cancel, n.info['id']),
executor.submit(l1.rpc.fundchannel_cancel, n.info['id'])]

# Only one should succeed.
success = False
for c in completes:
try:
c.result(TIMEOUT)
num_complete += 1
assert not success
success = True
except RpcError:
pass

# These may both succeed, iff the above didn't.
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

print("Cancelled {} complete {}".format(num_cancel, num_complete))
assert num_cancel + num_complete == len(nodes)

# We should have raced at least once!
assert num_cancel > 0
assert num_complete > 0


def test_funding_external_wallet(node_factory, bitcoind):
l1 = node_factory.get_node()
l2 = node_factory.get_node()
Expand Down

0 comments on commit 13dbe6e

Please sign in to comment.