-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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 config options for custom feature bits #7568
Add config options for custom feature bits #7568
Conversation
Getting back to this - looking for an apprach ACK then I'll add some itest converge :) |
f7c712b
to
e5e2a82
Compare
@positiveblue: review reminder |
Hi Carla I am interested in hosting this PR in the Review Club on may 25th. Do you consider it a good idea, or is it still to early? |
No objections from me! PR is ready for review + has itest coverage for new features. |
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 @carlaKC 🎉 Thank you very much for making a "sane" version of getNodeAnnouncement
The itests are failing but you just need to close the channel that alice opened ht.CloseChannel(ht.Alice, chanPoint)
(you can get the chanPoint from the OpenChannel
call)
f2924f1
to
a9ec486
Compare
Rebased + addressed first round of review!
Interesting, I swear these passed locally 🤔 Thanks for the tip! |
LGTM 🚀 |
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 nice PR, really enlightened my understanding regarding features in lightning in general. Thanks for your work on this :)
During review I found that the cmd: lncli peers updatenodeannouncement
has a typo in the description which could also be fixed in this context?
--feature_bit_remove value a feature bit that needs to be disabledCan be set multiple times in the same command
=> ... disabled. Can ...
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.
Went through the tests today, and I must say I find it weird, that config bits set by us are labeled as unkown in our view when calling lncli getinfo
. I think we need to mark them maybe custom or something rather than unknown?
Started lnd with: --protocol.custom-init=555
and then calling lncli getinfo
. I mean we are setting them so I would expect they are at least known to us?
"555": {
"name": "unknown",
"is_required": false,
"is_known": false
},
Moreover I think we need to maybe disallow setting feature bits which are greater 10 bits at least for the invoice custom features:
Started lnd with: --protocol.custom-invoice=1117
Then tried to add an invoice which resulted in the following error:
rlncli-wt addinvoice
[lncli] rpc error: code = Unknown desc = data length too big to fit within 10 bits: 1117
If we cannot encode such big features, should we maybe not allow to set them in the first place?
Great catch, thanks for the review! Will add some validation on existing RPC and config.
I'll take a look at how much more code this would be. While I agree it's odd, it is how we currently have it for |
a9ec486
to
8b76556
Compare
Agree with you, just see whether its a big change and leave it out if it's too much. Just a small nit and definitely not worth it if the change is not small. |
8b76556
to
da450d9
Compare
@ziggie1984 are you sure you ran into Added a new commit to enforce a maximum custom feature for invoices, if we try to configure LND with custom invoice features out of the allowed range it will now error:
|
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.
Sorry for confusion just saw the log message with 1117
in my lnd instance and wrote the comment. You are correct I must have started my lnd instance with something like [11175 - 5 ~ 11175).
You covered all my comments LGTM ⚡️
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 nice PR🎉 and thanks for taking the time to refactor the code! I think it's very close, just a few questions/typos/nits.
nodeAnnFeatures := currentNodeAnn.Features | ||
featureUpdates := len(req.FeatureUpdates) > 0 | ||
if featureUpdates { | ||
var ( |
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.
hmm don't think we need to declare them here?
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.
nodeAnnFeatures
needs to be declared outside so that we can use it on 396, and if we use :=
it's shadowed and we get an unused var error.
netann/host_ann.go
Outdated
@@ -168,8 +168,8 @@ func (h *HostAnnouncer) hostWatcher() { | |||
// NodeAnnUpdater describes a function that's able to update our current node | |||
// announcement on disk. It returns the updated node announcement given a set | |||
// of updates to be applied to the current node announcement. | |||
type NodeAnnUpdater func(modifier ...NodeAnnModifier, | |||
) (lnwire.NodeAnnouncement, error) | |||
type NodeAnnUpdater func(modifier ...NodeAnnModifier) ( |
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: wrong commit?
itest/lnd_custom_features.go
Outdated
|
||
// assertNotSet checks that the features provided aren't contained in a feature | ||
// map. | ||
func assertNotSet(ht *lntest.HarnessTest, features []uint32, |
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: could make it a helper closure inside the test as it's only used by this test(and likely to be the only case).
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.
would prefer to leave as is - imo closures can cultter up an itest vs a well named function which makes it clear what it's doing. Plus we do one itest / one file nowadays so it won't get in anyone's way here.
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.
Plus we do one itest / one file nowadays so it won't get in anyone's way here.
Not sure about that, but this is not gonna be scalable and don't think we'll go that route.
closures can cultter up an itest vs a well named function
The issue with the current func is it can get in others' way, as assertNotSet
is a broad term and can mean many things - just imagine another itest also wanna assert something is not set.
Non-blocking tho, maybe we could address this and similar issues in a dedicated PR.
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.
Updated to assertFeatureNotInSet
to keep out of the way 👍
611bdda
to
15363f3
Compare
Thanks for the review @yyforyongyu, addressed nits in latest push. |
itest/lnd_custom_features.go
Outdated
|
||
// assertNotSet checks that the features provided aren't contained in a feature | ||
// map. | ||
func assertNotSet(ht *lntest.HarnessTest, features []uint32, |
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.
Plus we do one itest / one file nowadays so it won't get in anyone's way here.
Not sure about that, but this is not gonna be scalable and don't think we'll go that route.
closures can cultter up an itest vs a well named function
The issue with the current func is it can get in others' way, as assertNotSet
is a broad term and can mean many things - just imagine another itest also wanna assert something is not set.
Non-blocking tho, maybe we could address this and similar issues in a dedicated PR.
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🥳
Needs a rebase! |
In preparation for moving feature bit modification inside of the feature manager, separate node modification from signing.
In preparation for a more complex function signature for set node announcement, separate get and set so that readonly callers don't need to handle the extra arguments.
Disallow update of any features that are defined by LND (since just updating the feature, but not the functionality will result in strange behavior). All known feature bits should be toggled using protocol config options.
Base 32 encoded bolt 11 invoices only allow 10 bits to express the length of the feature vector in a tagged field, so there is a much lower limit on the values invoice custom features can hold. Other places in the protocol are theoretically limited by the maximum message size, but since we express a feature bit as u16 we don't need to be concerned about this. The decision is made to track maximum per-set in the feature manager, which is conceptually aware of sets and then validate in lnwire/features against some arbitrary maximum value provided to the caller to keep the base features package unaware of sets.
Move merge of our features into the feature manager, rather than updating our node announcement then retrospectively setting the feature manger's set to the new vector. This allows us to use the feature vector as our single source of truth for announcements.
15363f3
to
820920a
Compare
Rebased + addressed last nits! |
Thanks for the work/merge guys! |
Change Description
updatenodeannouncement
from making changes to LND's standard feature bits.Init
/NodeAnn
/Invoice
features at startup, and disallow modifying of these features via API (we consider them "hard set" like LND's defined feature bits). AMP isn't included because I really can't see a use case for it, but happy to tack it on!Fixes: #7094, Replaces #7168.
Steps to Test
Disallow unsetting of defined feature bits:
lncli peers updatenodeannouncement --feature_bit_remove=5
->can't unset feature bit 5 (upfront-shutdown-script): feature is used in standard protocol set
Disallow setting of defined feature bits:
lncli peers updatenodeannouncement --feature_bit_remove=3
->can't set feature bit 3 (initial-routing-sync): feature is used in standard protocol set
Configure
Init
feature:dev
taglnd --protocol.custom-init=555
, run bob as usual and connect to alicelncli-bob listpeers
->555
listed in alice's featuresConfigure
NodeAnn
feature:dev
taglnd --protocol.custom-nodeann=777
lncli-bob describgraph
-> alice listed with777
feature (might take a sec to update, gossip batching)lncli-alice peers updatenodeannouncement --feature_bit_remove=777
->can't unset configured feature
Configure
Invoice
feature:dev
taglnd --protocol.custom-invoice=999
lncli addinvoice
->lnbc...
lncli decodepayreq lnbc...
->999
listed in features