feat: GetChannelAttestations RPC + commitment-bundle events (RFC staging)#3
Draft
rsafier wants to merge 6 commits into
Draft
feat: GetChannelAttestations RPC + commitment-bundle events (RFC staging)#3rsafier wants to merge 6 commits into
rsafier wants to merge 6 commits into
Conversation
Extends events.proto with: - ChannelPending / ChannelReady / ChannelClosed lifecycle events (tags 8-10) covering the scope of lightningdevkit#134. - ChannelCommitmentUpdated (tag 11) carrying a ChannelCommitmentBundle: unsigned holder commit tx, counterparty ECDSA signature, both funding pubkeys, balances, commit fee, pending HTLCs, and channel_type marker. - AttestationHtlc record for per-HTLC fields on the bundle. Extends api.proto SubscribeEventsRequest with a repeated EventKind `only` filter and a new EventKind enum (PAYMENT / CHANNEL_LIFECYCLE / CHANNEL_COMMITMENT). Default behavior excludes CHANNEL_COMMITMENT because its rate is much higher than the other streams; attestors opt in. Proto bindings regenerated via RUSTFLAGS="--cfg genproto" cargo build. Bumps SubscribeEventsRequest from a unit struct to one with a field, so the two in-repo call sites use ::default() instead of `{}`. No emission or filter plumbing in this change — purely the schema. Motivates the attestation bundle via the RFC: "include commitment-bundle data on channel-state events (extends lightningdevkit#134)"
Decode the SubscribeEventsRequest body at stream start and apply its
`only` filter to outgoing events:
- Empty `only` (back-compat default): emit every kind EXCEPT
EVENT_KIND_CHANNEL_COMMITMENT. Commitment events fire per
commitment-state update and are opt-in so existing subscribers see
no rate change.
- Non-empty `only`: strict allow-list, including CHANNEL_COMMITMENT
when explicitly requested.
Unknown / future enum values in `only` are ignored rather than treated
as permissive; unknown event variants (proto evolution) default to
allowed so a newer server doesn't silently drop events for clients
running an older filter.
Unit tests cover: default exclusion, commitment-only subscribe, mixed
kinds, and unknown enum values.
Publish ChannelPending / ChannelReady / ChannelClosed on the SubscribeEvents broadcast channel (previously these were only logged). This is the lightningdevkit#134 lifecycle-event scope. On ChannelPending and ChannelReady, additionally publish a ChannelCommitmentUpdated carrying the per-channel attestation bundle identified in the RFC. The event is gated behind the opt-in EVENT_KIND_CHANNEL_COMMITMENT subscription filter introduced in the preceding commit, so default subscribers see no rate change. The bundle's cryptographic fields — unsigned holder commit tx, the counterparty's ECDSA signature, and the two funding pubkeys — are left empty for now with explicit TODOs. They are populated by the ldk-node API proposed in the sibling RFC: "expose channel attestation data" (Node::export_channel_attestation -> ChannelAttestation) Until that lands, the event carries the identity / capacity / balance fields derivable from ChannelDetails: - channel_id, counterparty_node_id, funding_txid/outnum - capacity_sats (channel_value_sats) - holder_balance_msat / counterparty_balance_msat (using outbound_capacity_msat / inbound_capacity_msat as a proxy until the commitment-derived balances are exposed) A consumer can detect the pre-bundle stub by checking that holder_commitment_tx is empty. Per-commitment emission (every state update, not just on lifecycle transitions) also waits on the ldk-node RFC — it requires an event on Persist<ChannelMonitor> updates that ldk-node does not currently expose. The proto schema is ready for it.
Exposes `Node::export_channel_attestation` (from the paired ldk-node fork) over gRPC for external regulatory-attestation tooling. Changes: - proto: new GetChannelAttestationsRequest / Response under api.proto with a ChannelCommitmentUpdated payload per channel, plus the corresponding RPC on the LightningNode service. - ldk-server: handler that calls node.list_channel_attestations() (or filters to specific channel_ids) and serializes each attestation bundle with the full crypto payload — unsigned commit tx, DER counterparty signature, both funding pubkeys distinguishably, balances, pending HTLCs, and commitment number. - ldk-server-client: get_channel_attestations() helper + new path const. - ldk-server-cli: `ldk-server-cli get-channel-attestations [--channel-id]` subcommand, used by the `lightning-attestor` fixture-generation script. Cargo wiring: - ldk-server Cargo.toml and e2e-tests Cargo.toml point at the fork `rsafier/ldk-node` branch `rfc/export-channel-attestation`. - Workspace Cargo.toml [patch."https://github.com/lightningdevkit/rust-lightning"] redirects transitive deps to `rsafier/rust-lightning` branch `rfc/channel-keys-id-accessor` (required because the fork's ldk-node references the upstream URL; Cargo patches only apply at the workspace root). Stacks on top of rfc/channel-commitment-emission: the event-stream path continues to ship the stub bundle until a follow-up commit replaces it with the real export_channel_attestation payload.
Adds `serialize_bytes_hex` helper and applies it to the ChannelCommitmentBundle and AttestationHtlc byte fields so `ldk-server-cli get-channel-attestations` emits a readable hex string instead of a JSON array of u8 integers. Keeps the downstream attestor Go extractor trivial: it just reads the hex string straight into the ChannelProof artifact without further decoding.
…ations RPC Instead of filter_map(.ok()) silently dropping failed exports, log the error via log::warn when iterating all channels, and return an InternalServerError with the error detail when a specific channel_id was requested.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status: review-staging draft on the rsafier fork. Stacks on three prior RFC branches (proto schema + EventKind filter + event emission) and sits on top of rsafier/ldk-node#1, which in turn depends on rsafier/rust-lightning#1.
Stack (view in order)
What this top commit adds specifically
Proof
lightning-attestor regtest harness builds `ldk-server` from this branch in Docker, drives six scenarios, and its Go extractor passes independent BIP-143 counterparty-sig verification on every one. This is the first stack where LDK parity with LND/CLN attestation is achievable.