-
Notifications
You must be signed in to change notification settings - Fork 492
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
extension-bolt: taproot gossip (features 32/33) #1059
base: master
Are you sure you want to change the base?
Conversation
Thanks to @rustyrussell , @joostjager & @GeorgeTsagk for the initial set of comments on the pre-draft PR! I will carry over some of the comments over to this PR so that a discussion can take place :) |
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.
Carry-over comments from the pre-draft PR
bolt-taproot-gossip.md
Outdated
This document aims to update the gossip protocol defined in [BOLT 7][bolt-7] to | ||
allow for advertisement and verification of taproot channels. An entirely new | ||
set of gossip messages are defined that use [BIP-340][bip-340] signatures and | ||
that use a purely TLV based schema. |
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 problem with TLV is that you now need everyone to check that compulsory fields are present. But some fields don't actually make sense as optional. We end up needing another version anyway.
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 the simplicity of using tlv for everything might be more future proof & less complicated in the end. For example, if we decide on a compulsory field now but then later on add a new one, it will have to be TLV and then we have to have 2 ways of checking that compulsory fields are present vs something clean like tlvstream.MustHaveTypes(1, 2, 3, 4, ...)
We end up needing another version anyway.
This is true but by using TLV for everything, adding a new version due to the change of 1 compulsory field becomes easier to define in the spec I think. Instead of needing to define a whole new message, can just say "drop this tlv field and add this other tlv field".
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.
You can't though, because that would not be backwards compatible :( So you actually do have compulsory fields, which cannot be removed, until everyone upgrades.
It's actually simpler to define a new type in that 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.
is that you now need everyone to check that compulsory fields are present. But some fields don't actually make sense as optional
Isn't this already the case for all the other TLV extensions we've added over time?
I think one scenario that optional fields can be useful is if say in the channel announcements, we allow the advertiser to include/omit information that enables verification of complete channel output binding (so the individual keys, and tweak -- which would just be the bip86 tweak if that was used).
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.
Isn't this already the case for all the other TLV extensions we've added over time?
Yeah plus one for this question. If we later add compulsory fields, they would be via TLV and there would be some feature bit associated with understanding the version of the message that includes this field. So the benefit of doing only TLV is that all mandatory fields (ones added now and ones we add later on) are checked in the same way.
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 like some of the lessons from protobufs: the message gets defined completely separately from the business logic (ie the validation checking if all the wanted fields are there) and then it is always possible to add more fields or remove any fields.
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.
Perhaps worth a quick discussion at the spec meeting.
bolt-taproot-gossip.md
Outdated
For legacy channels, these last two proofs are made possible by including four | ||
separate signatures in the `channel_announcement`. However, [BIP-340][bip-340] | ||
signatures and the MuSig2 protocol allow us to now aggregate these four | ||
signatures into a single one. Verifiers will then be able to aggregate the four | ||
keys (`bitcoin_key_1`, `bitcoin_key_2`, `node_ID_1` and `node_ID_2`) using | ||
MuSig2 key aggregation and then they can do a single signature verification | ||
check instead of four individual checks. |
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.
Can we weaken this (and future proof it) a little, by publishing only the taproot_output_key? Sure, that means any taproot output can pretend to be a channel, but this is also a feature.
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 there is some benefit to proving a binding to the LN context at least a little bit.
We could possibly just advertise the taproot_internal_key
though (although I need to check the musig verification math for this). Kinda nice to, at least initially, to prove that the output cant be spent via the script path (via BIP86) as this at least gives spammers some deterrence... although perhaps not enough - interested to hear what people think re preventing spam of non-channels in the "only advertise the taproot_output_key" 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.
I think that perhaps the "only announce taproot_output_key" scenario only works in full Gossip 2.0 where you have to prove you have some bitcoin in order to announce channels. But in this proposal (gossip 1.5), I think that might not be the 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.
Gossip v2 detached the proof-of-utxo from the channels in two ways:
- You could use any UTXO proofs
- The proofs were per-node, and not per-channel.
This is the former, without the latter. It allows for us to change to a different Taproot scheme in future if we wanted, without updating gossip, but still requires a proof-per-channel. Say, gossip 1.75?
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.
It allows for us to change to a different Taproot scheme in future if we wanted
Could you perhaps give an example? Do you mean like: we could possibly use the same gossip for a future channel factory or something in which case the internal key itself would be derived in a different way? (ie, something other than a 2-of-2 multisig)
If that is the case, then how about we make the "binding level" optional. Ie, we make the bitcoin_key_1
, bitcoin_key_2
and tapteak
fields optional and then if they are present, nodes can choose to be more strict with their verification or not.
bolt-taproot-gossip.md
Outdated
- MUST set `chain_hash` to the 32-byte hash that uniquely identifies the chain | ||
that the channel was opened within: | ||
- for the _Bitcoin blockchain_: | ||
- MUST set `chain_hash` value (encoded in hex) equal | ||
to `6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000`. |
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 suggest the same trick we use for offers: omitting this field means it is 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000. And you must omit the field if it would be 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 (remember: both sides need to agree on exactly what this message looks like!).
Note also: I like the use of the TLV here. Because if we want to later, we can adapt this for pre-taproot channels, which would require more / different sigs. Though maybe they'll all close by the time v1-apocolypse is 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.
Cool - yeah I like the idea.
I have heard a few oppositions to assuming defaults though so just gonna leave this thread open to leave room for people to discuss. But personally, I dont see why a default is that bad.
bolt-taproot-gossip.md
Outdated
9. subtype: `dns_hostname` | ||
10. data: | ||
* [`...*utf8`:`hostname`] | ||
* [`tu16`:`port`] |
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 if port is 0, say it's 9735?
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.
same here as for the above re defaults
bolt-taproot-gossip.md
Outdated
2. data (tlv_stream): | ||
1. type: 0 (`channel_id`) | ||
2. data: | ||
* [`channel_id`:`channel_id`] |
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 would definitely not use a TLV for channel_id. Every other message starts with channel_id, we should keep it fixed. The other two fields, well, they're OK, but it seems weird that they're optional.
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.
Yes, especially since this is not a gossip message, but a peer message which is much easier to upgrade.
bolt-taproot-gossip.md
Outdated
verify taproot channels. This part of the update affects the | ||
`announcement_signatures` and `channel_announcement` messages. | ||
|
||
The opportunity is also taken to rework the `node_announcement` and |
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.
Could you also not take this opportunity and keep using ecdsa signatures for those? That seems to reduce the delta of this proposal significantly, and maybe without loss of functionality for the user?
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.
yes we could definitely do this. but:
- getting to use schnorr sigs for them is quite beneficial for things like multi-key backed nodes
- see the section on "Bootstrapping Taproot Gossip", it is not necessary for nodes to use the new announcement message straight away. They can use the old one for as long as they like.
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 don't see a good reason to not just use schnorr everywhere. For node anns, this means you can actually create a composite node that's actually composed of multiple entities, either via musig2 or FROST (tho FORST integration at the channel level has some other implications re shachain).
bolt-taproot-gossip.md
Outdated
signatures at the time of spending the output. This extra cost provided some | ||
extra deterrence for attackers. This deterrence is not present with P2TR | ||
transactions. | ||
3. The owners of `bitcoin_key_1` and `bitcoin_key_2` agree to be associated with |
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.
Since the public announcements of channels pretty much reveal what the output is being used for, would it be fair to mention that this mainly benefits private channels?
Different phrasing: Taproot outputs all do look the same regardless of being used for a channel or not, but any participant in LN will eventually receive a (public) channel announcement that marks some taproot UTXO as a channel, so effectively it's only the private channels that can remain "incognito"
bolt-taproot-gossip.md
Outdated
To also prevent nodes from building up too large of a burst-buffer with which | ||
they can spam the network and to give a limit to how low the block height on a | ||
`node_announcement_2` can be: nodes should not be allowed to use a block height | ||
smaller 1440 (~ a day worth of blocks) below the current block height. |
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'm not sure if this spam prevention works in all scenarios:
- A has a block height of 800,144 and sends B a channel_update_2 with height 800,000
- B has a block height of 800,145 and rejects the channel_update_2
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.
That would be a big issue if implementations defaulted on using the lowest possible block in order to keep a high update budget.
Couldn't this be resolved on the implementation side? (i.e. use a height of -143 blocks instead of -144 to avoid this race condition)
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.
That's a good point, a buffer of blocks could be used here to avoid this issue
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.
You can't do this, since you can't tell if it's old or deliberately backdated. The two weeks comes from the fact that we expire gossip messages after that time currently, anyway. You're supposed to update rebroadcast say every 13 days, which is a compromise between spamminess and proof-of-life.
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.
You can't do this
are you referring to the idea of the burst-buffer
in general?
since you can't tell if it's old or deliberately backdated
does it matter? surely we can just say it is not old if it is the highest height that we have seen? (just like the current rules for "timestamp" used in current gossip)/
bolt-taproot-gossip.md
Outdated
To also prevent nodes from building up too large of a burst-buffer with which | ||
they can spam the network and to give a limit to how low the block height on a | ||
`node_announcement_2` can be: nodes should not be allowed to use a block height | ||
smaller 1440 (~ a day worth of blocks) below the current block height. |
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.
smaller 1440 (~ a day worth of blocks) below the current block height. | |
smaller 144 (~ a day worth of blocks) below the current block height. |
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.
ah - silly me. I actually meant to say 2 weeks worth of blocks (which would be 2016). i must have confused myself here 🙃
It is also semi arbitrary. We need to look at how fast gossip tends to spread
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 don't think we should even consider redoing gossip unless we take the opportunity to build in the obvious trivial privacy improvements.
bolt-taproot-gossip.md
Outdated
|
||
## Timestamp fields | ||
|
||
In this document, the `timestamp` fields in messages are block heights instead |
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.
Then let's call them block height?
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.
sure :)
bolt-taproot-gossip.md
Outdated
13. type: 6 (`bitcoin_key_1`) | ||
14. data: | ||
* [`point`:`point`] | ||
15. type: 7 (`bitcoin_key_2`) |
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.
Strong NACK on including both Bitcoin keys here - we have an opportunity to get some incredibly nontrivial privacy by letting folks being outside UTXOs for channel proofs here - setting up the verification end to support that by not including both Bitcoin keys and instead just including the aggregate that's already on chain is trivial and I don't really see why we should avoid it here. We'll have to add a protocol in the future where one node can offer an alternative UTXO and signature in the signature message, but we can do that later.
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 response to Rusty's comment above. Basically: I think we can go full-ghost mode once we do Gossip 2.0 (overcommit stuff) but before that (gossip 1.5 aka this) we should have at least some binding to the LN context. The way the proposal is currently designed, nodes can prove that the output cant be spent along the script path. Yes, perhaps we can smush the 2 bitcoin keys into one (i would just need to check that the musig verification can still work)
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.
we should have at least some binding to the LN context
Why? Your response to Rusty's above comment doesn't seem to explain why you think we should try to tie this to lightning more, but I don't really get it - its trivial not to, and a super great outcome if we dont bind it! In general, I'd say it should be considered an explicit goal to not "bind to the lightning context", especially given there's no additional complexity to doing so, even better it (I think?) reduces the size of the gossip!
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.
Yes, perhaps we can smush the 2 bitcoin keys into one (i would just need to check that the musig verification can still work)
Each key is tweaked individually and then added together, so this would require providing the tweaks for the node keys and including the bitcoin keys as one with their individual tweaks pre-applied.
If we choose to go with the taproot output key, then we'll have to deal with recursive MuSig2, which I believe we're still waiting on a security proof for. I guess we'd still have to handle recursive MuSig2 if either of the node keys are also multi-sig.
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.
Basically: I think we can go full-ghost mode once we do Gossip 2.0 (overcommit stuff) but before that (gossip 1.5 aka this) we should have at least some binding to the LN context. The way the proposal is currently designed, nodes can prove that the output cant be spent along the script path.
IIUC, it's important that node1 and node2 prove to each other that script path spends are impossible. But I don't see a reason we need to prove that to the rest of the network.
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.
it's important that node1 and node2 prove to each other that script path spends are impossible. But I don't see a reason we need to prove that to the rest of the network.
i don't think they need to prove this to eachother. They would not have generated the same output key & hence would not have produced the correct signatures if either node added a script path. They would not be able to hide such a path from the peer.
The reason for the "proving to the network" part is similar to today's reason for advertising the 2 keys: today we prove that the output can only be spent via a 2-of-2 multisig? this makes it a bit more difficult for an attacker to create fake spam since they are now limited in how they can spend the utxo since they would now have to pay more for spending from it (2 sigs). That disincentive is not available with taproot - so the idea here is that we at least show the network that we are limiting how the utxo can be spent in some way - by showing that we cant spend via a script path. But perhaps this is too "cosmetic" to consider sufficient in any case.
So i think the main thing we should iron out is: do we want to be able to prove (ie, do we care) that the utxo is created via a 2-of-2 musig2 or not. Perhaps a good topic for today's spec call
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.
That disincentive is not available with taproot - so the idea here is that we at least show the network that we are limiting how the utxo can be spent in some way - by showing that we cant spend via a script path. But perhaps this is too "cosmetic" to consider sufficient in any case.
The "no-script-path" limitation seems insignificant to me. I suspect most P2TR outputs today don't have a script path anyway.
So i think the main thing we should iron out is: do we want to be able to prove (ie, do we care) that the utxo is created via a 2-of-2 musig2 or not.
In the taproot world there's no fee difference between musig and single sig UTXOs. So spam prevention doesn't seem a compelling reason to prove a UTXO is a musig.
It seems to me that proof-of-UTXO is a "good enough" spam prevention. In fact, we're talking about moving to overcommit in the future, which would be a weaker spam prevention than is being proposed right 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.
yep - so I think the next version is gonna make this tweak optional. So by default, nodes will just use the output key found on chain & then if nodes want to include things like the 2 keys used in the musig2 & if they want to add a tweak then they can do so optionally.
bolt-taproot-gossip.md
Outdated
* [`chain_hash`:`chain_hash`] | ||
7. type: 3 (`short_channel_id`) | ||
8. data: | ||
* [`short_channel_id`:`short_channel_id`] |
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.
IMO we should have an option for a channel to not include an SCID at all, rather allowing a node to overcommit their balance by simply saying "I already have channel(s) that have utxos, let me announce more without a proof up to multiplier N by not including a proof on this channel".
This would also imply that we should move the UTXO profs to the node announcements, but we don't strictly have to - it works fine without that.
We'll have to define a protocol to negotiate such an announcement, but that can happen later and is rather trivial.
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.
IMO we should have an option for a channel to not include an SCID at all
since it is TLV, it can always be made optional in future.
rather allowing a node to overcommit their balance
I think you are referring to the full on Gossip 2.0 proposal. This proposal is the more vanilla gossip 1.5 that was discussed in oakland.
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 not just make it optional now? There's a bunch of complexity to adding the negotiation of building gossip with overcommit, so I wouldn't expect to actually build that now, but there's very little complexity to allowing overcommit now (with the exception of bikeshedding over the ratio 😂, but I'm open to someone rolling a die :)), so it seems like we should just 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.
here's a bunch of complexity to adding the negotiation of building gossip with overcommit, so I wouldn't expect to actually build that now, but there's very little complexity to allowing overcommit now
Could you expand on the details a bit?
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.
There's two ways to do overcommit on the receiver's-side, one a trivial modification of this existing logic, the other more "clean", but a bit more work.
In the simplest version, we (a) make the bitcoin point optional, if its not provided (b) an extra bit has to be set somewhere indicating if this channel should count against the overcommit of node_1 or node_2, and (c) the short_channel_id
should be greater than some number far, far into the future as an indication that its not a real channel (and to ensure receiving gossip always still works by making sure channels with utxo proofs come "before" channels without in scid-order).
Then we'd have to define some overcommit ratio (let's roll a dice or bikeshed for months), and a receiver of such a message must track the current amount of bitcoin in utxo-proven channels for each node in their graph, as well as the amount of channels which did not have a utxo proof, and if the utxo-proven channel amount is < amount of non-utxo-proven channels * the overcommit ratio the channels with the lowest (highest? whatever) fake scids are removed.
The alternative way to do this which is maybe cleaner but more of an overhaul would be to move the UTXO proofs entirely outside of the channel announcements and into the node announcements, relying exclusively on the overcommit format described above in channel announcements, and calculating against the total proven in the node announcement.
There's no need to describe the messages to actually negotiate this new format in announcement_signatures
(its not complicated, we could, but if you're trying to reduce new things here its fine not to, IMO), but I think its important to actually get it on the validating/receiving end sooner rather than later.
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.
Then we'd have to define some overcommit ratio (let's roll a dice or bikeshed for months), and a receiver of such a message must track the current amount of bitcoin in utxo-proven channels for each node in their graph, as well as the amount of channels which did not have a utxo proof, and if the utxo-proven channel amount is < amount of non-utxo-proven channels * the overcommit ratio the channels with the lowest (highest? whatever) fake scids are removed.
Should the overcommit amount depend on bitcoin amount in proven channels, or on number of proven channels?
Chain fees scale with number of proven channels, but not necessarily with bitcoin amount in channels. So I think number of proven channels provides stronger spam protection.
(Sorry if this was discussed in Oakland or elsewhere, I'm new 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.
IMO we should have an option for a channel to not include an SCID at all, rather allowing a node to overcommit their balance by simply saying "I already have channel(s) that have utxos, let me announce more without a proof up to multiplier N by not including a proof on this channel".
This is a somewhat unsettling proposition that I'm encountering for the first time. Has this been discussed anywhere as to why people think it's a good idea? I find it unusual that we are suggesting things that resemble leverage/fractional reserve at the protocol level in Bitcoin.
bolt-taproot-gossip.md
Outdated
|
||
A node can be assumed to understand the new gossip v2 messages if: | ||
|
||
- They advertise `option_taproot_gossip` in a legacy `node_announcement` message |
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.
Or in the init
message
These extra requirements only apply if the `option_taproot` channel type is set | ||
in the `open_channel` message. |
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.
Pretty sure everyone supports option_channel_type
these days, but if either node doesn't support it then we should rely on the features shared between both nodes.
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.
IMO channel type becomes even more important in this scenario as one may want to still preferentially open the old segwit v0 channel with certain peers. Assuming the advertised feature bits tell the complete story would implicltly mean that the taproot chans are the new "default", which likely won't be the case for some time (eg: zero fee anchors isn't yet the default for all impls).
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.
Assuming the advertised feature bits tell the complete story would implicltly mean that the taproot chans are the new "default", which likely won't be the case for some time
It's also less future proof. Even if we want TR channels to be assumed default which @Roasbeef already points out is unlikely to be the case for a while, in the future we may have a new default preferred channel type as the network continues to develop and mature.
bolt-taproot-gossip.md
Outdated
- MUST send the `announcement_signatures_2` message. | ||
- MUST NOT send `announcement_signatures_2` messages until `channel_ready` |
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.
- MUST send the `announcement_signatures_2` message. | |
- MUST NOT send `announcement_signatures_2` messages until `channel_ready` | |
- MUST send the `announcement_signatures_2` message once `channel_ready` |
bolt-taproot-gossip.md
Outdated
13. type: 6 (`bitcoin_key_1`) | ||
14. data: | ||
* [`point`:`point`] | ||
15. type: 7 (`bitcoin_key_2`) |
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.
Yes, perhaps we can smush the 2 bitcoin keys into one (i would just need to check that the musig verification can still work)
Each key is tweaked individually and then added together, so this would require providing the tweaks for the node keys and including the bitcoin keys as one with their individual tweaks pre-applied.
If we choose to go with the taproot output key, then we'll have to deal with recursive MuSig2, which I believe we're still waiting on a security proof for. I guess we'd still have to handle recursive MuSig2 if either of the node keys are also multi-sig.
bolt-taproot-gossip.md
Outdated
|
||
## Query Messages | ||
|
||
TODO: any updates that need to happen to this section? |
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.
We'll likely want to extend query_channel_range
and gossip_timestamp_filter
with new bits to specify if we should only receive legacy, taproot, or both.
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.
true 👍 will work on that section once there is more consensus around the general gossip direction
bolt-taproot-gossip.md
Outdated
* [`chain_hash`:`chain_hash`] | ||
7. type: 3 (`short_channel_id`) | ||
8. data: | ||
* [`short_channel_id`:`short_channel_id`] |
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.
Then we'd have to define some overcommit ratio (let's roll a dice or bikeshed for months), and a receiver of such a message must track the current amount of bitcoin in utxo-proven channels for each node in their graph, as well as the amount of channels which did not have a utxo proof, and if the utxo-proven channel amount is < amount of non-utxo-proven channels * the overcommit ratio the channels with the lowest (highest? whatever) fake scids are removed.
Should the overcommit amount depend on bitcoin amount in proven channels, or on number of proven channels?
Chain fees scale with number of proven channels, but not necessarily with bitcoin amount in channels. So I think number of proven channels provides stronger spam protection.
(Sorry if this was discussed in Oakland or elsewhere, I'm new here.)
bolt-taproot-gossip.md
Outdated
13. type: 6 (`bitcoin_key_1`) | ||
14. data: | ||
* [`point`:`point`] | ||
15. type: 7 (`bitcoin_key_2`) |
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.
Basically: I think we can go full-ghost mode once we do Gossip 2.0 (overcommit stuff) but before that (gossip 1.5 aka this) we should have at least some binding to the LN context. The way the proposal is currently designed, nodes can prove that the output cant be spent along the script path.
IIUC, it's important that node1 and node2 prove to each other that script path spends are impossible. But I don't see a reason we need to prove that to the rest of the network.
bolt-taproot-gossip.md
Outdated
This document aims to update the gossip protocol defined in [BOLT 7][bolt-7] to | ||
allow for advertisement and verification of taproot channels. An entirely new | ||
set of gossip messages are defined that use [BIP-340][bip-340] signatures and | ||
that use a purely TLV based schema. |
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.
is that you now need everyone to check that compulsory fields are present. But some fields don't actually make sense as optional
Isn't this already the case for all the other TLV extensions we've added over time?
I think one scenario that optional fields can be useful is if say in the channel announcements, we allow the advertiser to include/omit information that enables verification of complete channel output binding (so the individual keys, and tweak -- which would just be the bip86 tweak if that was used).
bolt-taproot-gossip.md
Outdated
[BOLT 7][bolt-7] was designed around P2WSH funding transactions. For these | ||
channels, the `channel_announcement` message is used to advertise the channel to | ||
the rest of the network. Nodes in the network use the content of this message to | ||
prove that the channel is sufficiently bound to the Lightning Network context |
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.
Explicitly mention that the LN context here meant a 2-of-2 p2wsh script? Then also the cross signing on the peer layer.
bolt-taproot-gossip.md
Outdated
verify taproot channels. This part of the update affects the | ||
`announcement_signatures` and `channel_announcement` messages. | ||
|
||
The opportunity is also taken to rework the `node_announcement` and |
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 don't see a good reason to not just use schnorr everywhere. For node anns, this means you can actually create a composite node that's actually composed of multiple entities, either via musig2 or FROST (tho FORST integration at the channel level has some other implications re shachain).
bolt-taproot-gossip.md
Outdated
along with a [BIP86 tweak][bip86-tweak]. This provides a slightly weaker | ||
binding to the LN context than legacy channels do but at least somewhat | ||
limits how the output can be spent due to the script-path being disabled. | ||
The context binding with legacy channels is greater because an attacker |
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.
Maybe more accurate to say faking a signal with the legacy protocol is more expensive due to additional on chain fees? Basically as a side effect of the keyspend path reducing on chain fees for cooperative contract paths.
|
||
### Rate Limiting | ||
|
||
A block height based timestamp results in more natural rate limiting for gossip |
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.
Pretty cool how we can indirectly gain global rate limiting by using block hashes. I think this has a few implications for the ways channel_updates
work in the network today:
- Any attempts to use
max_htlc
to leak out the available bandwidth for a channel (so increase/decrease with each forward) can be rate limited at a global level. - Protocols that would directly require a node to trigger a specific channel update are now less attractive from an incentives PoV as: those updates would eat into the node's available set of global updates within a block interval.
- Nodes can still do more rapid updates by sending their new
channel_update
in an onion error directly to the sender.
Also some implementations have extensions to the gossip query protocol to support timestamp channel update syncing, which can now be updated to use block height based syncing instead.
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.
Any attempts to use max_htlc to leak out the available bandwidth for a channel (so increase/decrease with each forward) can be rate limited at a global level
do you mean that some nodes explicitly try to leak their own available bandwidth via the use of a channel_update message?
These extra requirements only apply if the `option_taproot` channel type is set | ||
in the `open_channel` message. |
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.
IMO channel type becomes even more important in this scenario as one may want to still preferentially open the old segwit v0 channel with certain peers. Assuming the advertised feature bits tell the complete story would implicltly mean that the taproot chans are the new "default", which likely won't be the case for some time (eg: zero fee anchors isn't yet the default for all impls).
bolt-taproot-gossip.md
Outdated
|
||
1. `tlv_stream`: `channel_ready_tlvs` | ||
2. types: | ||
1. type: 0 (`announcement_node_pubnonce`) |
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 it's possible to only send a single (pre aggregated nonce) here, so then the final step would be just combining 2 signatures instead of 4. IIUC, this would require nested musig2 though, which I don't think any one has actually implemented in full.
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 cool I will need to look into nested musig2
|
||
### `channel_ready` Extensions | ||
|
||
These extensions only apply if the `option_taproot` channel type was set in the |
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.
Should specify that these values only need to be attached if an announcement signatures message hasn't already been full constructed.
We also need to think about the restart implications here as well. Eg: lnd today will sign then stash the ann_sig
message to read from disk to send to the remote party. However if each time we reconnect a new set of nonces is exchanged, then we'll need to wait for chan_reest
to be sent (channel_ready
isn't always sent once a channel is fully operational and has had updates), then we'll need to be ready to regen+ sign again.
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.
Should specify that these values only need to be attached if an announcement signatures message hasn't already been full constructed.
What do you mean? When would one be in a situation where the announcment sig message is fully constructed but you then need to send channel_ready
again?
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.
then we'll need to wait for chan_reest to be sent (channel_ready isn't always sent once a channel is fully operational and has had updates), then we'll need to be ready to regen+ sign again.
Ok, so you are saying we might need to add these fields to chan_reest
as-well?
bolt-taproot-gossip.md
Outdated
two nonces. The `announcement_node_nonce` is for `node_ID_x` and the | ||
`announcement_bitcoin_nonce` is for `bitcoin_key_x`. | ||
|
||
Since the channel can only be announced once the `channel_ready` messages have |
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 comment above: channel_ready
isn't always sent on reconnect. So if a channel is used before the gossip advertisement is finished, then the nonces won't be available to advertise.
bolt-taproot-gossip.md
Outdated
* [`point`:`node_id`] | ||
9. type: 4 (`color`) | ||
10. data: | ||
* [`rgb_color`:`rgb_color`] |
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.
Maybe remove the color field? Don't think it was ever seriously used....
On the other hand, if we go TLV everywhere, then it matters less as including it is optional.
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've made it an odd number so it is optional :)
4d9883a
to
534af57
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.
Thanks for the initial review everyone!
Made some of the more minor updates. I'm gonna wait until after the spec meeting in NYC before making any changes regarding the channel proofs.
Here is a small list of things that need to be answered:
- do we want to go full TLV or does that just not make sense?
- should we use recursive musig2 for the announcement sigs or leave it as a 4-or-4 for now with perhaps leaving enough wiggle room to upgrade to recursive musig2 in future.
- are we ok with only announcing the SCID (and hence just the taproot-output-key) or do we want to at least give nodes the option of adding the
bitcoin_key_1/2
andtap-tweak
to the channel announcement. - can we assume dynamic commitments will be in place to upgrade legacy channels to taproot channels which will then be able to use the new gossip messages (in other words, does everyone agree that the new gossip messages should not support advertising legacy channels)?
bolt-taproot-gossip.md
Outdated
This document aims to update the gossip protocol defined in [BOLT 7][bolt-7] to | ||
allow for advertisement and verification of taproot channels. An entirely new | ||
set of gossip messages are defined that use [BIP-340][bip-340] signatures and | ||
that use a purely TLV based schema. |
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.
Isn't this already the case for all the other TLV extensions we've added over time?
Yeah plus one for this question. If we later add compulsory fields, they would be via TLV and there would be some feature bit associated with understanding the version of the message that includes this field. So the benefit of doing only TLV is that all mandatory fields (ones added now and ones we add later on) are checked in the same way.
bolt-taproot-gossip.md
Outdated
For legacy channels, these last two proofs are made possible by including four | ||
separate signatures in the `channel_announcement`. However, [BIP-340][bip-340] | ||
signatures and the MuSig2 protocol allow us to now aggregate these four | ||
signatures into a single one. Verifiers will then be able to aggregate the four | ||
keys (`bitcoin_key_1`, `bitcoin_key_2`, `node_ID_1` and `node_ID_2`) using | ||
MuSig2 key aggregation and then they can do a single signature verification | ||
check instead of four individual checks. |
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.
It allows for us to change to a different Taproot scheme in future if we wanted
Could you perhaps give an example? Do you mean like: we could possibly use the same gossip for a future channel factory or something in which case the internal key itself would be derived in a different way? (ie, something other than a 2-of-2 multisig)
If that is the case, then how about we make the "binding level" optional. Ie, we make the bitcoin_key_1
, bitcoin_key_2
and tapteak
fields optional and then if they are present, nodes can choose to be more strict with their verification or not.
|
||
### Rate Limiting | ||
|
||
A block height based timestamp results in more natural rate limiting for gossip |
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.
Any attempts to use max_htlc to leak out the available bandwidth for a channel (so increase/decrease with each forward) can be rate limited at a global level
do you mean that some nodes explicitly try to leak their own available bandwidth via the use of a channel_update message?
bolt-taproot-gossip.md
Outdated
To also prevent nodes from building up too large of a burst-buffer with which | ||
they can spam the network and to give a limit to how low the block height on a | ||
`node_announcement_2` can be: nodes should not be allowed to use a block height | ||
smaller 1440 (~ a day worth of blocks) below the current block height. |
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.
You can't do this
are you referring to the idea of the burst-buffer
in general?
since you can't tell if it's old or deliberately backdated
does it matter? surely we can just say it is not old if it is the highest height that we have seen? (just like the current rules for "timestamp" used in current gossip)/
bolt-taproot-gossip.md
Outdated
- Nodes are encouraged to actively connect to other nodes that advertise the | ||
`option_taproot_gossip` feature bit as this is the only way in which they | ||
will learn about taproot channel announcements and updates. | ||
- Nodes should not use the new `node_announcement_2` message until they have |
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 they don't use node_announcement_2 at all, then none of their taproot channels will propagate.
Why not? they can still send out channel_announcement_2
. and their (legacy) node_announcement
will have the feature bit in it that informs nodes that they support taproot chans which hopefully encourages those nodes to connect to them so that their channel_announcement_2
messages will propogate.
What's the rationale here?
The main reason was so that legacy nodes continue to get updates about the node while they have a channel (legacy) that mean something to the legacy node.
bolt-taproot-gossip.md
Outdated
|
||
## Query Messages | ||
|
||
TODO: any updates that need to happen to this section? |
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.
true 👍 will work on that section once there is more consensus around the general gossip direction
bolt-taproot-gossip.md
Outdated
* [`point`:`node_id`] | ||
9. type: 4 (`color`) | ||
10. data: | ||
* [`rgb_color`:`rgb_color`] |
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've made it an odd number so it is optional :)
bolt-taproot-gossip.md
Outdated
This document aims to update the gossip protocol defined in [BOLT 7][bolt-7] to | ||
allow for advertisement and verification of taproot channels. An entirely new | ||
set of gossip messages are defined that use [BIP-340][bip-340] signatures and | ||
that use a purely TLV based schema. |
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 like some of the lessons from protobufs: the message gets defined completely separately from the business logic (ie the validation checking if all the wanted fields are there) and then it is always possible to add more fields or remove any fields.
bolt-taproot-gossip.md
Outdated
This document aims to update the gossip protocol defined in [BOLT 7][bolt-7] to | ||
allow for advertisement and verification of taproot channels. An entirely new | ||
set of gossip messages are defined that use [BIP-340][bip-340] signatures and | ||
that use a purely TLV based schema. |
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.
Perhaps worth a quick discussion at the spec meeting.
bolt-taproot-gossip.md
Outdated
|
||
1. `tlv_stream`: `channel_ready_tlvs` | ||
2. types: | ||
1. type: 0 (`announcement_node_pubnonce`) |
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 cool I will need to look into nested musig2
note from @rustyrussell - would be good to support legacy updates in the new messages in order to take advantage of the new |
Hey everyone! Was planning on having this doc updated by today but got side tracked a bit. Will aim to have the updated changes pushed by the time of the next bi-monthly meeting. In the meantime, here is a summary of what I plan to update as a result of the discussions from the NYC meeting. Let me know if something looks off. 1. Plan for a future where the script can be anythingInstead of requiring the channel peers to specify the two bitcoin keys in the
So to cater for this future, we can say that
For the signers, this would mean the following:
The verifier will be able to verify both types from the get go. 2. Plan for a future where not every channel announcement contains UTXO proofWe want to allow the flexibility so that in future we dont need to tie every channel to a UTXO but instead use the rule of "here is a channel without a proof, please look at all the other open channels I have announced with a proof and use that to determine if I do infact have the allowance to open one without" What I took away from the meeting is that to create a sort of carve-out for that future, what we will do today is to start putting the channel capacity in the Let me know if I missed something here. 3. Message structuresNew type definitions:
|
bolt-taproot-gossip.md
Outdated
derived by aggregating all the `node_ID` and `bitcoin_key` public keys. The | ||
signature for this key will thus be created by aggregating (via MuSig2) four | ||
partial signatures. One for each of the keys: `node_ID_1`, `node_ID_2`, | ||
`bitcoin_key_1` and `bitcoin_key_2`. A nonce will need to be generated and |
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.
`bitcoin_key_1` and `bitcoin_key_2`. A nonce will need to be generated and | |
`bitcoin_key_1` and `bitcoin_key_2`. A (MuSig2) nonce will need to be generated and |
bolt-taproot-gossip.md
Outdated
been exchanged and since it is generally preferred to keep nonce exchanges as | ||
Just In Time as possible, the nonces are exchanged via the `channel_ready` |
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.
Can we include a citation for the Just In Time preference? Reading BIP327, it seems to suggest in bullet 3 that it doesn't really matter how early you exchange them since it is valid to do so even before the exact signing participants have been determined.
- otherwise: | ||
- MUST NOT send the `announcement_signatures_2` message. |
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.
Isn't this message constructable before the 6conf requirement? If we send the announcement_signatures_2
message after channel_ready
but before 6 confs, how should the peer respond?
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.
good point.
I took the original logic from the legacy announcement_signatures
. But yeah - perhaps it is possible to construct it sooner as long as it isnt broadcast before 6 confs
First pass just from a gossip POV:
No doubt more feedback as we actually implement, this was just from trying to import spec into our code!
The message, With all the information mentioned, both peers can now construct the
@@ -1016,7 +1009,7 @@ P_agg = MuSig2.KeyAgg(MuSig2.KeySort( The signature can then be verified as follows:
@@ -1060,7 +1053,7 @@ The full list of inputs required:
@@ -1072,7 +1065,7 @@ P_agg = MuSig2.KeyAgg(MuSig2.KeySort( The signature can then be verified as follows:
|
Note: feature bit assignment clash with #1036 ! Someone needs to move? (This is why we put feature bits in the title, for easy disambiguation). |
I closed #1036 for now to free up that feature bit, taproot gossip is much more important to get as soon as we can ;) |
bolt-taproot-gossip.md
Outdated
* [`u32`:`fee_proportional_millionths`] | ||
|
||
|
||
The `disable_flags` bitfield is used to indicate that the channel is temporarily |
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 mentioned this in the meeting but not sure it got back to here, it'd be nice to also include a "this channel has been closed" bit indicating permanent failure.
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.
cool - will add 👍
Thanks for the feedback (added the suggested diff - thanks @rustyrussell!) ! A few notes/questions for discussion in the upcoming meeting:
|
2635a3a
to
481c125
Compare
This didn't manage to come up at the meeting, but I'm not sure its worth doing anything here. Yes, someone could send a closed update, cause you to remove it from your gossip store, then go get you to re-add it later, but...so what? They're misbehaving and gonna have people not route through their channel, that's their problem. Sure, you don't want gossip to flap causing lots of traffic on the network, but that can be addressed by just keeping a short-term cache (as long as your usual gossip rate-limiter) that prevents re-accepting this channel for a little bit. If someone really wants to do something and keep a log of deleted channels, they can totally do that, and again the nodes that screwed up their channel are now hosed, that's their problem, but the spec doesn't need to mandate this. |
Is there a future on using ZKP on pubkey ownership inside a large set as a way to eliminate the necessity on the UTXO announcement as spam filtering? https://github.com/AdamISZ/aut-ct This guy presented his project on delving bitcoin some months ago, but I have seen few people commenting on it. I'm not a bitcoin dev, but I'm commenting here because I got really curious on this proposal, and had some fear that people could be missing something important. |
Will be actively working on updating this PR given the convo from the summit over the next while. Main things on my mind:
I also think it might be a good idea to use 3 new feature bits:
Finally, another thought I had was that since we are going to allow nodes to sign chan_ann at any point (since they now need to go re-announce existing channel potentially), this sort of nicely paves the way for allowing 2 channel peers to decide to convert a previously un-announced channel to an announced one. So gonna try see if that can be worked in too. EDIT: ok I've written a much more in-depth version in this delving post |
Overview
The initial version of the Lightning Network gossip protocol as defined in
BOLT 7 was designed around P2WSH funding transactions. For these
channels, the
channel_announcement
message is used to advertise thechannel to the rest of the network. Nodes in the network use the content
of this message to prove that the channel is sufficiently bound to the
Lightning Network context and that it is owned by the nodes advertising
the channel. This proof and verification protocol is, however, not
compatible with SegWit V1 (P2TR) outputs and so cannot be used to
advertise the channels defined in the Simple Taproot Channel proposal.
This document thus aims to define an updated gossip protocol that will
allow nodes to both advertise and verify taproot channels. This part of the
update affects the
announcement_signatures
andchannel_announcement
messages.The opportunity is also taken to rework the
node_announcement
andchannel_update
messages to take advantage of BIP-340 signatures andTLV fields. Timestamp fields are also updated to be block heights instead of
Unix timestamps.