-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Make channels public first after 6 confirmations #411
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
Make channels public first after 6 confirmations #411
Conversation
|
baaa9cd
to
c369b6d
Compare
lnrpc/rpc.proto
Outdated
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.
Why the change? So with this modification, the default will be private? That's a break from the current default behavior, and many confuse several current users.
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 default is set announce=true
in lncli
, but maybe it is still confusing for people utilizing grpc that their default will be false? Anyway, if we want it to default to private eventually, then we might as well start :P
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.
Changed back to private
cmd/lncli/commands.go
Outdated
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.
See my comment on the prior commit. If the default is to be set to true, why not just revert back to the private modifier?
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.
Note that you can also set the default directly by using the Value: default
attribute directly on the command's definition.
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.
I made it Announce
since we want it to default to false
eventually. And I guess we should have the invoice routing hints supported before we do that?
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.
And it doesn't look like BoolFlag
has a Value
attribute...
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.
Well we'd set it to false only in the desktop app or mobile app.
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.
Ok, I'll change the flag back to private
, and make it false by default.
discovery/gossiper.go
Outdated
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.
👍
discovery/gossiper.go
Outdated
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.
If this has just been added to the channel router (by the local party), then it will already have a nil AuthProof
. The AuthProof
is only set once we receive a AnnouncementSignatures
message from the remote party.
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.
This is only the case if the node that sent us the update is also one of the nodes in the OG ChannelAnnouncement
.
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.
So what you are saying is that the AuthProof
will always be nil
if it is coming from the local node? And this would be enough:
if !nMsg.isRemote {
...send...
}
?
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.
Yep! Although I guess the extra check can't hurt...may avoid a nil panic in a weird scenario.
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.
Ok, will keep as-is then :)
lnwallet/reservation.go
Outdated
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.
Ewww, a setter!
This is known ahead of time. As a result, it can simply be passed into the main constructor of the reservation.
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.
See other comment/quesition.
fundingmanager.go
Outdated
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.
From my reading, this'll directly announce the channel. Shouldn't it instead use an "un rolled" verion of handleFundingConfirmation
as done when we're the initiator of the channel?
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.
handleFundingConfirmation
is altered to also announce first after 6 confs. I should really make the state machine to centralize this logic...
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.
Yeah the state machine could really use a refactoring at this point. It sprawls far too much with this additional set of changes.
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.
I think I'll push the state machine refactoring to a new PR once this one is merged. This should work (even though it's messy), and that PR should not change any functionality. Adding the state machine cleanup to this PR looks like it might become a bit messy.
fundingmanager.go
Outdated
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.
Nit: extra new line.
fundingmanager.go
Outdated
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.
Nit: extra space after be
.
discovery/gossiper.go
Outdated
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.
This'll need to be update to parse it as a lnwire.ChanUpateFlag
.
fundingmanager.go
Outdated
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.
This will need to check the returned error. As atm, it may be rejected if this function partially succeeded. It should be looking for routing.ErrOutdated
or routing.ErrIgnored
.
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 other instance (where we actually try to announce), should also be modified to check the error. Otherwise, if we partially process the state, then we may never actually update the state in the database.
c369b6d
to
dd6cd6c
Compare
Needs a rebase to master. |
83b3789
to
59f854f
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.
Found one last little thing when testing locally. You'll find the comment inline. Aside, from that I've found this works as advertised. Yayy private channels!
Also left a comment about modifying the description on the command line. After these are addressed, we can finally get this thing merged!
You can also go ahead and squash down the set of commits. Thanks.
fundingmanager.go
Outdated
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.
I think this logging statement should be moved into the method above. As otherwise, we get conflicting logs like this (the channel was set to private):
2017-12-13 16:08:45.514 [DBG] FNDG: Channel with ShortChanID 1830686860312576 added to router graph
2017-12-13 16:08:45.514 [DBG] PEER: Received FundingLocked(chan_id=32d05b577966bb3280a58c8f2d7cbd2e0a916c4bdce67d8c024ffb693ccf2d88, next_point=033201ae22cbf6fa8cb07d0f2187ab764f33d8378bf830c1bc9b6e21063f5b7be6) from 127.0.0.1:10019
2017-12-13 16:08:45.516 [TRC] PEER: readMessage from 127.0.0.1:10019: (*lnwire.FundingLocked)(0xc4205981e0)({
ChanID: (lnwire.ChannelID) (len=32 cap=32) 32d05b577966bb3280a58c8f2d7cbd2e0a916c4bdce67d8c024ffb693ccf2d88,
NextPerCommitmentPoint: (*btcec.PublicKey)(0xc420174840)({
Curve: (elliptic.Curve) <nil>,
X: (*big.Int)(0xc420174860)(22618611118210622400841714471844468386370929431841625480347924787655014579174),
Y: (*big.Int)(0xc420174880)(5784334520023794081739208847968927079355214281329805474126131064251764117719)
})
})
2017-12-13 16:08:45.516 [DBG] FNDG: Received FundingLocked for ChannelID(32d05b577966bb3280a58c8f2d7cbd2e0a916c4bdce67d8c024ffb693ccf2d88) from peer 02cc27b8ef708b13a6832f1c4f3d8d1207851cda53f5be041f5b1e2ec1afeb755c
2017-12-13 16:08:45.515 [TRC] PEER: writeMessage to 127.0.0.1:10019: (*lnwire.ChannelUpdate)(0xc420082cd0)({
Signature: (*btcec.Signature)(0xc42026a0e0)({
R: (*big.Int)(0xc42023c1c0)(42098235645066207283475299495848826319528238987901551247437816008865568379280),
S: (*big.Int)(0xc42023c220)(36309963118044616166236141227015067109229028731851401167576737900038110028029)
}),
ChainHash: (chainhash.Hash) (len=32 cap=32) 683e86bd5c6d110d91b94b97137ba6bfe02dbbdb8e3dff722a669b5d69d77af6,
ShortChannelID: (lnwire.ShortChannelID) {
BlockHeight: (uint32) 1665,
TxIndex: (uint32) 1,
TxPosition: (uint16) 0
},
Timestamp: (uint32) 1513210125,
Flags: (lnwire.ChanUpdateFlag) 1,
TimeLockDelta: (uint16) 144,
HtlcMinimumMsat: (lnwire.MilliSatoshi) 0 mSAT,
BaseFee: (uint32) 1000,
FeeRate: (uint32) 1
})
2017-12-13 16:08:45.516 [DBG] FNDG: Will not announce private channel 1830686860312576.
discovery/gossiper.go
Outdated
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.
Atm with this, if we send just the ChannelUpdate
message, then the other node will reject it as there's a race condition where we might receive the FundingLocked
then this message before we ever send our own chann ann to our internal gossiper:
2017-12-13 16:16:18.052 [DBG] PEER: Received ChannelUpdate(chain_hash=683e86bd5c6d110d91b94b97137ba6bfe02dbbdb8e3dff722a669b5d69d77af6, short_chan_id=1836184418451456, flag=0, update_time=2017-12-13 16:16:18 -0800 PST) from 127.0.0.1:10019
2017-12-13 16:16:18.052 [TRC] PEER: readMessage from 127.0.0.1:10019: (*lnwire.ChannelUpdate)(0xc42048e9b0)({
Signature: (*btcec.Signature)(0xc420011140)({
R: (*big.Int)(0xc420118ea0)(24495463756957618076099430289234328219521735099568467680541926667560037384405),
S: (*big.Int)(0xc420118ec0)(41256671207089118935243535172289480169661446552925936953485820156560683126184)
}),
ChainHash: (chainhash.Hash) (len=32 cap=32) 683e86bd5c6d110d91b94b97137ba6bfe02dbbdb8e3dff722a669b5d69d77af6,
ShortChannelID: (lnwire.ShortChannelID) {
BlockHeight: (uint32) 1670,
TxIndex: (uint32) 1,
TxPosition: (uint16) 0
},
Timestamp: (uint32) 1513210578,
Flags: (lnwire.ChanUpdateFlag) 0,
TimeLockDelta: (uint16) 144,
HtlcMinimumMsat: (lnwire.MilliSatoshi) 0 mSAT,
BaseFee: (uint32) 1000,
FeeRate: (uint32) 1
})
2017-12-13 16:16:18.053 [ERR] DISC: unable to validate channel update short_chan_id=1836184418451456: edge not found
So one side doesn't see the other's edge:
⛰i lncli describegraph
{
"nodes": [
{
"last_update": 0,
"pub_key": "02cc27b8ef708b13a6832f1c4f3d8d1207851cda53f5be041f5b1e2ec1afeb755c",
"alias": "",
"addresses": [
],
"color": "#000000"
},
{
"last_update": 1513209865,
"pub_key": "03d381f8cd62e79e40f2a0f96caa0f2e9ee1f6526e80a05c4907dcdf8627f0974e",
"alias": "03d381f8cd62e79e40f2\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"addresses": [
],
"color": "#3399ff"
}
],
"edges": [
{
"channel_id": "1836184418451456",
"chan_point": "1592c661827f01270f3e309e82770150eb40fc1df4d4357c1d89c7bc5cf71cef:0",
"last_update": 1513210579,
"node1_pub": "02cc27b8ef708b13a6832f1c4f3d8d1207851cda53f5be041f5b1e2ec1afeb755c",
"node2_pub": "03d381f8cd62e79e40f2a0f96caa0f2e9ee1f6526e80a05c4907dcdf8627f0974e",
"capacity": "1500000",
"node1_policy": null,
"node2_policy": {
"time_lock_delta": 144,
"min_htlc": "0",
"fee_base_msat": "1000",
"fee_rate_milli_msat": "1"
}
}
]
}
This means that they wouldn't be able to craft a routing hint to route to the private channel.
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.
woops, this was a big oversight on my part!
I pushed a commit + tests now, that takes care of this case. It stores the ChannelUpdate
for the unknown channel in a map, and will reprocess it later, after the local ChannelAnnouncement
is processed. At the moment this is just a map in memory, not sure if it is needed/worth it at this point to make it persistent. @aakselrod
If this looks okay, I will squash and rebase this branch, getting it ready for merge 💪
cmd/lncli/commands.go
Outdated
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.
This isn't quite accurate, as we'll be using the payreqs to give routing hints in the future. Instead, we can say something like: "other nodes won't be able to route to this channel unassisted".
This commit introduces some new interdependent functionality. As soon as the fundingLocked message is sent, the channel is immediately added to the ChannelRouter's internal topology. Finally, channels are now only broadcasted to the greater network after six confirmations on the funding transaction has been reached.
Tests in fundingmanager_test.go that assert the privacy guarantees of non-broadcasting.
This make lncli openchannel take a --private parameter, set to false by default.
This commit adds the ChannelFlags field, of type lnwire.FundingFlags, to the OpenChannel struct, including serialization for database storage. This is done to preserve the flags that were sent during channel opening, currently used to determine whether a channel should be made public or not after opening.
This commit adds some comments and does some cleanup of the logic that makes sure non-public channels (channels with no AuthProof) are not broadcasted to the network.
This commits slightly rewrites the newly introduced logic for private channels. Instead of keeping the channel announce preference in a database within fundingManager, it is stored as part of the OpenChannel struct. In addition, the ChanOpenStatus_Open update is now sent after the channel is added to the router, instead of waiting until the 6 blocks confirmation has passed.
e54d8f1
to
2b77756
Compare
2b77756
to
7af8b9c
Compare
7af8b9c
to
a9ae8cc
Compare
This commit makes the gossiper store received ChannelUpdates that is not for any known channel in a map, such that they can be reprocessed when the ChannelAnnouncement arrives. This is done to handle the case where we receive a ChannelUpdate from our channel counterparty before we have been able to process our own local ChannelAnnouncement.
This commit adds a test that ensures that if we receive a ChannelUpdate for a channel we don't know about, it will be reprocessed after we receive a ChannelAnnouncement for that channel.
a9ae8cc
to
702f2a6
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 🚨
This PR builds on top of #332 by @Crypt-iQ, making channels public to the greater network first after 6 confirmations of the funding transaction. This also allows channels to stay "private", by not announcing them at all if the
announce
flag is not set during initial channel opening.For now, default behavior is kept the same, by making all channels public by default. Later this will probably be changed to private-by-default.
The separation of "local channel announcement" (
ChannelAnnouncement
andChannelUpdate
) from the "public announcement" (AnnounceSignatures
) creates another state in the internal funding manager state machine. A followup PR will address the now quite fragmented logic this leads to.