Conversation
Move the workspace off a set of long-stale majors: cln-grpc, cln-rpc and cln-plugin 0.4 -> 0.6, env_logger 0.10 -> 0.11, base64 0.21 -> 0.22, bech32 0.9 -> 0.11, reqwest 0.11 -> 0.12, ring 0.16 -> 0.17, rustls-pemfile 1 -> 2, rcgen 0.10 -> 0.13 and secp256k1 0.26 -> 0.29, with the call-site changes each of those majors requires. gl-plugin now takes cln-plugin from the workspace rather than pinning ^0.1 separately. `cargo check --workspace` is clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
Move PROTOC_TOOLCHAIN and TESTPROTOC_TOOLCHAIN from grpcio-tools 1.78.0 to 1.81.1 and regenerate, keeping the deliberate-bump discipline the pins already documented. Generated protobuf code asserts `runtime >= gencode` at import time and the grpc stubs refuse to load below the grpcio-tools that produced them, so the declared bounds move up with the stubs: protobuf >= 6.33.5 and grpcio >= 1.81.1. gl-client-py gained an explicit grpcio dependency; its stubs have always imported grpc at runtime but only declared it in the dev group, leaving it to arrive transitively via pyln-grpc-proto. gl-testing's test.proto stubs were still 4.25.1 gencode because the `protoc` target used the ambient venv instead of the pinned toolchain, and its -I. paths only resolved when run from libs/gl-testing rather than the repo root it is included into. Point it at the same isolated toolchain as testgrpc so its output no longer depends on who ran it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
The exact pins on 24.2 held the test harness two years behind the released pyln packages and, being the tightest constraint in the tree, dragged everything resolving alongside them back with it. Relax to floors at the current release, 26.6.6. Every pyln.testing.fixtures and pyln.testing.utils symbol gltesting imports still exists in 26.6.6. Note this also pulls pytest 7 -> 9 and flask 2 -> 3 for anything sharing the resolution. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
cln-grpc 0.7 is built against tonic 0.14, and WrappedNodeServer implements its generated `Node` trait using our own tonic's Request, Response and Status types. Two tonic majors in one tree therefore means the trait we implement is not the trait the server expects, so the cln-* bump and the tonic bump cannot be staged separately -- attempting the cln-* half alone fails with 57 errors. Move both, plus prost 0.12 -> 0.14 and the transitive hyper 0.14 -> 1.0 / http 0.2 -> 1.0 / tower 0.4 -> 0.5 that tonic 0.14 brings with it. Mechanical parts: - tonic's "tls" feature is now backend-specific; use "tls-ring". - tonic-build no longer emits prost code. Codegen moves to tonic-prost-build and the runtime gains tonic-prost; `compile` is `compile_protos`. - `tonic::body::BoxBody` is private, and `tonic::transport::Body` is gone; both are `tonic::body::Body`. The custom tower services (AuthService, SignatureContextService, RpcWaitService) are typed on http::Request/Response over that body. - http-body 1.0 replaces poll_data/poll_trailers with poll_frame, so StashBody is reimplemented and the body-buffering loop in SignatureContextService walks frames while keeping its size check. - hyper 1.0 no longer implements its IO traits for tokio types, so the hsmproxy connector wraps its UnixStream in hyper_util's TokioIo. - `Status::to_http` is `into_http`. API drift in cln 0.7 itself: - The Node trait gained 26 methods (splices, bkpr-report, xkeysend and a batch of notification subscriptions). Unary calls delegate to the inner server; the new subscriptions follow the existing ones in being unimplemented pending a public NotificationStream. - SendpayRoute made every field optional and added the newer `*_out`/`short_channel_id_dir` hop form; we still describe the hop the legacy way. - FeeratesPerkw dropped delayed_to_us and htlc_resolution, gained splice, and floor is no longer optional. One behaviour change worth noting: AuthService signed only the first body frame, since http-body 0.4's `data()` returns one chunk. It now collects the whole body, which is what the signature was meant to cover. `cargo check --workspace --all-targets` is clean and the tree resolves a single tonic 0.14.6 and prost 0.14.4. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
`generate_self_signed_device_cert` set `IsCa::ExplicitNoCa`, which emits a basicConstraints extension. Since rcgen 0.13 `serialize_request` rejects any basicConstraints in a CSR and returns `UnsupportedInCsr`, so every caller that turns these params into a CSR was failing: both device registration paths in scheduler.rs and the new-device pairing flow, not only the test that caught it. `NoCa` omits the extension and keeps the CSR valid; the certificate itself is only a vehicle for the params and key pair here, and is discarded once the CSR is built. Also stop asserting on bech32's error wording in the lnurl test. It checked for "invalid length", which was 0.9's message; 0.11 reports a checksum failure for that input. Asserting on our own wrapper text keeps the test meaningful across bech32 upgrades. Both regressions came in with the dependency modernization, which was verified with cargo check but not cargo test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
gl-client only uses picky's Pem and Csr types, but the default feature set also enables jose and http_trait_impl, and the latter pulls http 0.2 into a tree that is otherwise entirely on http 1. Selecting just the x509 feature removes that duplicate along with the unused jose stack. picky 7 would also work but is still a release candidate, which is not somewhere to take an X.509 parser for a deduplication. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
gl-client pulled three crates from the same family at mutually incompatible versions: picky 6 (which internally uses picky-asn1-x509 0.6), plus direct picky-asn1-x509 0.15 and picky-asn1-der 0.4. That put picky-asn1 in the tree three times, picky-asn1-der twice and picky-asn1-x509 twice. The version skew also explains the shape of verify_pairing_data: it serialised the CSR's public key to DER and parsed it back with picky-asn1-der purely to cross from picky's copy of the types to ours. picky's PublicKey is a thin wrapper over SubjectPublicKeyInfo and implements AsRef for it, so with matching versions the key can just be borrowed and the round-trip disappears along with the picky-asn1-der dependency. cargo tree -d now reports no picky duplicates at all. Also drop a `mut` that became redundant when AuthService moved to collecting the whole body. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
cargo-udeps flags async-stream and uuid as unused in gl-client and env_logger as unused in gl-plugin; grepping each confirms it. futures is a different case: it is genuinely used, but only from `#[cfg(test)]` code, so it moves to dev-dependencies rather than being removed. That also gives gl-client a dev-dependencies section, which it did not have before. sha256 was also flagged, and was genuinely unused when this was first written -- its only hits were calls to a local `crypto_utils::hkdf_sha256` rather than the crate. It is kept, because the splice work that has since landed on main calls `sha256::digest` for real. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
gl-client-py and gl-signerproxy declared hex, log and once_cell as `"*"`, which accepts any future breaking major. Lift those three into [workspace.dependencies] alongside the anyhow entry that was already there, and point every member at them. Beyond removing the wildcards this collapses a spread of spellings for the same crates -- hex appeared as "*", "0.4", "0.4.3" and log as "*", "0.4", "^0.4" -- so each now has one place to bump. Cargo.lock is unchanged; the resolved versions already matched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
`ListpeerchannelsRequest` gained server-side `channel_id` and `short_channel_id` filters in cln 0.7, so the struct literal in `old_splice_state` no longer compiles. Both are left unset: the call lists every channel and filters by channel_id in the following `find`, and changing the query shape is not something a dependency bump should decide. Surfaced by rebasing the dependency work onto main, where the splice support had landed in the meantime. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZoAzNVajT8Udj7XYrurTa
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.
Summary
Dependency consolidation for the client libraries, paired with the corresponding Greenlight
MR — the two must land together, since
gl-plugin-internalimplements cln-grpc's generatedservice trait and both sides have to be on the same tonic.
Lock: 544 → 514 entries, 56 → 34 crates at more than one version, 68 → 38
redundant copies.
cln-* 0.7 and tonic 0.14, in lockstep
cln-grpc 0.7 is built against tonic 0.14, and
WrappedNodeServerimplements its generatedNodetrait using our own tonic'sRequest/Response/Status. Two tonic majors in onetree therefore means the trait we implement is not the trait the server expects, so the two
bumps cannot be staged — the cln-* half alone fails with 57 errors.
Carries prost 0.12 → 0.14 and the transitive hyper 0.14 → 1.0 / http 0.2 → 1.0 /
tower 0.4 → 0.5.
tonic-buildno longer emits prost code (codegen moves totonic-prost-build, runtime gainstonic-prost),tonic::body::BoxBodyis private,http-body 1.0 replaces
poll_data/poll_trailerswithpoll_frame, and hyper 1.0 no longerimplements its IO traits for tokio types.
The
Nodetrait also gained 26 methods in cln 0.7; unary calls delegate to the inner serverand the new subscriptions follow the existing ones in being unimplemented pending a public
NotificationStream.A production bug this surfaced
generate_self_signed_device_certsetIsCa::ExplicitNoCa, and since rcgen 0.13serialize_requestrejects any basicConstraints in a CSR withUnsupportedInCsr. Everycaller that turns those params into a CSR was failing — both device registration paths in
scheduler.rsand the new-device pairing flow, not only the test that caught it.NoCaomits the extension and keeps the CSR valid; the certificate is only a vehicle for the params
and key pair here, and is discarded once the CSR is built.
Dependency hygiene
versions (picky 6, which internally uses picky-asn1-x509 0.6, plus direct 0.15 and
picky-asn1-der 0.4), putting
picky-asn1in the tree three times. That skew was also whyverify_pairing_dataserialised the CSR key to DER and parsed it back — it was crossingbetween two copies of the same types. With matching versions the key is just borrowed.
Selecting only picky's
x509feature additionally dropshttp 0.2.async-stream,sha256,uuid(gl-client),env_logger(gl-plugin), each confirmed by grep.
futureswas the one not to remove — real, but onlyunder
#[cfg(test)], so it moved to dev-dependencies."*"specs replaced with workspace dependencies.Cargo.lockunchanged.match the regenerated stubs, keeping the deliberate-bump discipline the pins documented.
One behaviour change worth review
AuthServicepreviously signed only the first body frame, because http-body 0.4'sdata()returns one chunk. It now collects the whole body, which is what the signature was meant to
cover.
Rebase note
Rebased onto current
main, which had gained the splice support in the meantime. Twoconsequences worth calling out, both caught by rebuilding afterwards rather than by the
rebase itself:
sha256was flagged unused and removed; the new splice code callssha256::digestforreal, so it is kept. (
async-streamanduuidremain genuinely unused.)ListpeerchannelsRequestgained server-side filters in cln 0.7, so the struct literal inold_splice_stateneeded the two new fields. Both left unset, preserving the existinglist-then-filter behaviour.
Testing
cargo check --all --all-targetsclean; 270 lib tests green.