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
Add lncli command / RPC for manually setting channel state #5033
Add lncli command / RPC for manually setting channel state #5033
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great first-time contribution!
I've done an initial pass of the diff, but plan to do another to really grok some of the state machine transition modifications. I think we can also test the return to auto management by closing a channel in the itest to ensure that triggers a disable to be sent.
4b4586e
to
7427585
Compare
Thanks for taking a look! I've hopefully addressed your initial feedback. Updating the |
Actually I think there might be a blocking issue here. Converting to draft until I confirm it's fixed... |
OK, my main concern was around the following issue. Say Alice/Bob have a channel and Alice/Charlie have a channel. If we disable the Alice/Bob channel from Alice's end but then immediately send a payment Charlie -> Bob (i.e. before Alice broadcasts the Per discussion with @Roasbeef , we can proceed with the current PR and address the "eventual consistency" concern as a follow-up. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robot-dreams great work on this PR, I know a lot of people will be excited to have this feature! A+ commit structure as well, very easy to follow the changes
Say Alice/Bob have a channel and Alice/Charlie have a channel. If we disable the Alice/Bob channel from Alice's end but then immediately send a payment Charlie -> Bob (i.e. before Alice broadcasts the ChannelUpdate message) then Charlie's attempt to route the payment via Charlie -> Alice -> Bob will still succeed.
Per discussion with @Roasbeef , we can proceed with the current PR and address the "eventual consistency" concern as a follow-up.
Good observation here! Indeed we don't honor this in the switch currently, there have been some discussions in the past as to whether we treat the disable bit as more of a network signaling (aka you shouldn't try this channel) vs actually enforcing it. I can imagine cases where each mode might be useful, it could be worthwhile to explore adding a configuration-level toggle whether one wants to enforce "strict disables" or not.
I'd say this PR looks just about merge-ready, only a few nits from me. I really like the approach of adding the ability to return the status management back to auto, makes the API very clean 👍
switch curState.Status { | ||
|
||
// Channel is already disabled, nothing to do. | ||
case ChanStatusDisabled: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this imply the entry for outpoint
wasn't being cleaned up on channel close?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The entry was getting cleaned up for a cooperative close, since the channel would've started out in ChanStatusEnabled
so we don't hit this case.
However, it was not getting cleaned up if the channel was already in ChanStatusDisabled
(e.g. peer went offline for a while) and you do a force close.
More specifically (with extra debug logging for removing the channel from the map):
Before this PR
cooperative close:
[INF] NANN: Announcing channel(...) disabled [requested]
[DBG] NANN: Removing channel(...) from map
peer goes down + force close disabled channel:
[INF] NANN: Announcing channel(...) disabled [detected]
>>> force close doesn't remove channel from map
After this PR
cooperative close:
[INF] NANN: Announcing channel(...) disabled [requested]
[DBG] NANN: Removing channel(...) from map
peer goes down + force close disabled channel:
[INF] NANN: Announcing channel(...) disabled [detected]
[DBG] NANN: Removing channel(...) from map
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool, great catch! Always good to make ensure we clean up after ourselves.
7427585
to
70804ab
Compare
Thanks for the encouraging review and the helpful context! |
Add a new boolean parameter without changing any existing functionality. The parameter will be used to indicate whether a request to update a channel's status was made manually by a user (currently always false).
Add new value for ChanStatus without changing any existing functionality. The new value indicates that a user manually requested disabling a channel.
Add boolean parameter for test functions without changing any existing functionality. All current tests set manual = false, but Future tests can set manual = true to test manual requests to update channel state.
If a channel was manually disabled, subsequent automatic / background requests to update that channel's state will be ignored. A RequestAuto call restores automatic / background state management and indicates that such requests should no longer be ignored.
Update router.proto and rest-annotations.yaml, recompile protos, add a stub implementation to routerrpc.Server.
Allow router RPC requests to call into the ChanStatusManager to manually update channel state.
This refactor-only change makes the GetChanPointFundingTxid helper function available from sub-systems outside of the root lnd package.
Update UpdateChanStatus stub implementation to call into exposed ChanStatusManager methods in RouterBackend.
The updatechanstatus command calls into the UpdateChanStatus RPC in the router server.
70804ab
to
215bf63
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🔥
// update is propagated. | ||
sendReq(alice, chanPoint, routerrpc.ChanStatusAction_DISABLE) | ||
expectedPolicy.Disabled = true | ||
waitForChannelUpdate( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
neutrino integration test failed on this line with:
=== RUN TestLightningNetworkDaemon/18-of-72/neutrino/update_channel_status
test_harness.go:88: Failed: (update channel status): exited with error:
*errors.errorString did not receive channel update
/home/travis/gopath/src/github.com/lightningnetwork/lnd/lntest/itest/lnd_test.go:1814 (0xe7afb2)
waitForChannelUpdate: t.Fatalf("did not receive channel update")
/home/travis/gopath/src/github.com/lightningnetwork/lnd/lntest/itest/lnd_test.go:5344 (0xe8ec6f)
testUpdateChanStatus: waitForChannelUpdate(
/home/travis/gopath/src/github.com/lightningnetwork/lnd/lntest/itest/test_harness.go:112 (0xe4c3ee)
(*harnessTest).RunTestCase: testCase.test(h.lndHarness, h)
/home/travis/gopath/src/github.com/lightningnetwork/lnd/lntest/itest/lnd_test.go:14885 (0xeef005)
TestLightningNetworkDaemon.func4: ht.RunTestCase(testCase)
/home/travis/.gimme/versions/go1.15.7.linux.amd64/src/testing/testing.go:1123 (0x51c2ef)
tRunner: fn(t)
/home/travis/.gimme/versions/go1.15.7.linux.amd64/src/runtime/asm_amd64.s:1374 (0x46f821)
goexit: BYTE $0x90 // NOP
I think this related to another issue ( #4866) however, since the test passes locally for me. I think it's safe to ignore this for now and revisit once the other issue is fixed. I restarted the itest and it passed 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🧨
The road to figure out how to update a channel status lands here, but the command has changed. So anyone looking
|
Currently, there's no mechanism for manually setting the network state of a given channel. This PR adds an RPC endpoint to the routing sub-server, as well as a corresponding
lncli
command, so that users can manually update channel state.Note that such updates only the channel state that's broadcast over the network (i.e. whether or not the
lnwire.ChanUpdateDisabled
flag is set). In particular, disabling a channel does NOT close it.This change also interacts with the pre-existing mechanism for automtically enabling / disabling channels (e.g. when a peer disconnects or reconnects):
lncli setchannelstatus
command to set the state back toauto
.Sample behavior:
Fixes: #4543