Expose ChannelCounterparty and ReserveType in ChannelDetails#841
Expose ChannelCounterparty and ReserveType in ChannelDetails#841enigbe wants to merge 3 commits intolightningdevkit:mainfrom
Conversation
|
I've assigned @tnull as a reviewer! |
This fixup moves node feature exposure from freestanding APIs to NodeStatus, as suggested in review. Rather than exposing init_features(), channel_features(), bolt11_invoice_features(), and node_features() as separate public methods on Node, this embeds NodeFeatures in the NodeStatus struct returned by Node::status(). Additionally, channel and invoice features at node level are confusing. Users would expect negotiated per-peer/channel/invoice features, not what the node generally supports. Access to negotiated features are addressed in lightningdevkit#841
tnull
left a comment
There was a problem hiding this comment.
Thanks! Looks pretty good, have a few initial comments.
src/types.rs
Outdated
| } | ||
| } | ||
|
|
||
| /// Information needed for constructing an invoice route hint for this channel. |
There was a problem hiding this comment.
Everything related to uniffi should live in ffi/types.rs, which also avoids the feature-gate on individual items.
There was a problem hiding this comment.
This seems unresolved, I think we can move this CounterpartyForwardingInfo to ffi/types.rs?
src/types.rs
Outdated
| uniffi::custom_type!(InitFeatures, Vec<u8>, { | ||
| remote, | ||
| try_lift: |val| Ok(InitFeatures::from_le_bytes(val)), | ||
| lower: |obj| obj.le_flags().to_vec(), |
There was a problem hiding this comment.
Generally not the biggest fan of exposing this as Vec<u8>, but if we do, why pick little endian over big endian?
There was a problem hiding this comment.
I was mistaken about the LE/BE ease of bit indexing vs over the wire serialization. I've replaced the Vec with a dedicated wrapper type that stores LdkInitFeatures directly, so the endianness question no longer applies.
33a36bd to
63f32ab
Compare
tnull
left a comment
There was a problem hiding this comment.
One comment, otherwise looks good. Feel free to squash (also the new fixup)
src/types.rs
Outdated
| } | ||
| } | ||
|
|
||
| /// Information needed for constructing an invoice route hint for this channel. |
There was a problem hiding this comment.
This seems unresolved, I think we can move this CounterpartyForwardingInfo to ffi/types.rs?
63f32ab to
56d86f7
Compare
|
Squashed all fix-ups. |
| ReserveType::Adaptive | ||
| } | ||
| } else { | ||
| ReserveType::Adaptive |
There was a problem hiding this comment.
Hmm, isn't this wrong? I believe we'd fallback to legacy if we don't have an anchors_channel_config set?
I guess we could only land here if we had already accepted an anchor channel and then the user changed anchors_channels_config afterwards?
Might be good to at least leave some comments here to give some rationale.
There was a problem hiding this comment.
Good catch here. You are right that we only reach this branch if an anchor channel was previously opened with anchor_channels_config set, and then later unset. In that case, Legacy would be incorrect and Adaptive could also be wrong . The channel will still be an anchor type, but if it was originally TrustedPeersNoReserve, we'd silently reclassify it as Adaptive.
I think the main problem is that we derive the reserve_type at query time from the current config rather than recording it when the channel is opened. So any config change could cause a loss of distinction where we can't distinguish between anchor channels that were Adaptive vs TrustedPeersNoReserve.
We could explore persisting the reserve type (keyed by ChannelId) when we open a channel, and have list_channels look up the stored value instead of re-deriving it. What do you think?
There was a problem hiding this comment.
I'd rather not persist it. Can we just determine based on the feature, and then decide between Adaptive and TrustedPeersNoReserve based on whether or not the peer is present in the no reserve list? I guess that's kind of what we're doing already?
There was a problem hiding this comment.
Yeah, we already do this. There's just that one edge case where a user unsets the anchor channels config after previously setting it. We'd be able to tell if it's an anchor channel but not whether it's adaptive or not.
There was a problem hiding this comment.
I guess that's fine. Could you maybe add a comment to reflect the current rationale/thinking and documenting this edge case? And then we can probably move ahead. Not sure if it's worth over-engineering this.
There was a problem hiding this comment.
Sure. I'll add the comment.
We previously flattened ChannelCounterparty fields into ChannelDetails as individual counterparty_* fields, and InitFeatures was entirely omitted. This made it impossible for consumers to access per-peer feature flags, and awkward to access counterparty forwarding information without navigating the flattened field names. This commit replaces the flattened fields with a structured ChannelCounterparty type that mirrors LDK's ChannelCounterparty, exposing InitFeatures and CounterpartyForwardingInfo that were previously inaccessible. Breaking change!
We expose the reserve type of each channel through a new ReserveType enum on ChannelDetails. This tells users whether a channel uses adaptive anchor reserves, has no reserve due to a trusted peer, or is a legacy pre-anchor channel. The reserve type is derived at query time in list_channels by checking the channel's type features against trusted_peers_no_reserve. Additionally, We replace the From<LdkChannelDetails> impl with an explicit from_ldk method that takes the anchor channels config.
document the selection of adaptive reserve type in the event a user sets and then unsets the anchor channels config
56d86f7 to
77dcbc4
Compare
What this PR does
In #305, we needed a way to expose channel type and the channel reserve without leaking implementation details not useful to users. The related discussion in #141 proposed a
ReserveTypeabstraction that bakes in both in a user-relevant way. This PR introduces the said enumeration toChannelDetailswith the following variants:Legacy: signifying pre-anchor channel types where on-chain fees paying for broadcast transactions following channel closure were pre-determinedTrustedPeersNoReserve: for anchor type channels with trusted peersAdaptive: indicating anchor channel with adaptive reserve, reflecting dynamic best-effort attempt at fee-bumping.(see @jkczyz's suggestion)
We modify the
ChannelDetailsconstructor to accept an optional anchor channels config to address the challenge of users cross-referencing the channel details and config to determine if counterparties are trusted.Additionally, following recommendation in #810 about negotiated features, this PR exposes per-peer
InitFeatures, and as a consequence, modifiesChannelDetailsby replacing the flattenedcounterparty_*withChannelCounterpartythat encapsulates them and mirror LDK's.Issue Addressed
Closes #305.
Builds on discussions and recommendations from #141 and #810.