Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixup fundchannel_cancel #3336

Merged

Conversation

niftynei
Copy link
Collaborator

@niftynei niftynei commented Dec 12, 2019

There's a few small, subtle bugs currently in fundchannel_cancel:

  • one: the remote peer can call fundchannel_cancel while waiting for lockin. it's debatable whether or not this is desirable. for now it seems prudent to remove the capability altogether.
  • two: if you attempt to cancel a channel while the peer is offline, your node will crash

this PR addresses both of these issues. note that forget_channel is currently exposed because in a later commit (in the dual funding branch) i'm using it elsewhere.

Copy link
Member

@cdecker cdecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some minor nits. Very nice fixup @niftynei 👍

lightningd/channel_control.c Outdated Show resolved Hide resolved
Comment on lines +1008 to +1043
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.rpc.fundchannel_start(l2.info['id'], amount)['funding_address']
assert l1.rpc.fundchannel_complete(l2.info['id'], prep['txid'], txout)['commitments_secured']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could do with a short description of what it tests. I guess i checks that we can still start and complete a fundchannel after cancelling?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit of an API assertion, in that it checks that the field commitments_secured is returned and is set to true. if this API changes, this test will fail.

@@ -1005,6 +1005,27 @@ def test_funding_external_wallet_corners(node_factory, bitcoind):
# We can cancel channel after fundchannel_complete
assert l1.rpc.fundchannel_cancel(l2.info['id'])['cancelled']

l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.rpc.fundchannel_start(l2.info['id'], amount)['funding_address']
assert l1.rpc.fundchannel_complete(l2.info['id'], prep['txid'], txout)['commitments_secured']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assert also seems a bit strange, are you trying to check that there is a commitments_secured element in the result? In that case an assert 'commitments_secured' in l1.rpc.fundchannel_complete... seems more appropriate.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, 'commitments_secured' is always true. Checking if 'commitments_secured' field exists is more reasonable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but if the commitments_secured is ever returned as false then this would not have been a successful fundchannel_complete.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you could instead just add a comment before this like # A successful funding_complete will always have a commitments_secured that is true, otherwise it would have failed.?

Copy link
Collaborator

@trueptolemy trueptolemy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! :-) Good work 👍

@@ -1005,6 +1005,27 @@ def test_funding_external_wallet_corners(node_factory, bitcoind):
# We can cancel channel after fundchannel_complete
assert l1.rpc.fundchannel_cancel(l2.info['id'])['cancelled']

l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.rpc.fundchannel_start(l2.info['id'], amount)['funding_address']
assert l1.rpc.fundchannel_complete(l2.info['id'], prep['txid'], txout)['commitments_secured']
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, 'commitments_secured' is always true. Checking if 'commitments_secured' field exists is more reasonable.

lightningd/channel_control.c Outdated Show resolved Hide resolved
@niftynei niftynei force-pushed the nifty/fixup_channel_cancels branch 3 times, most recently from 93009d7 to 522e8de Compare January 21, 2020 05:34
Copy link
Contributor

@rustyrussell rustyrussell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack 522e8de

restrict fundchannel_cancel usage to only the opener side

Changelog-Changed: Only the opener of a fundchannel can cancel the channel open with fundchannel_cancel
Break out a method for canceling a channel that will either
loop through contacting the peer to tell them of the error or
just directly cleans up if the peer is currently disconnected.
Use the new forget_channel method to cancel, which checks that
peer is still connected before attempting to send message.
if the channel hasn't been locked in yet, allow for a 'hard' error
to kill the channel
@rustyrussell
Copy link
Contributor

Ack 8d1d36a

@rustyrussell rustyrussell merged commit 27c7707 into ElementsProject:master Feb 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants