Skip to content

feat: ledger 9-rc.3#1738

Draft
gilescope wants to merge 12 commits into
mainfrom
giles-ledger9-rc.3
Draft

feat: ledger 9-rc.3#1738
gilescope wants to merge 12 commits into
mainfrom
giles-ledger9-rc.3

Conversation

@gilescope

@gilescope gilescope commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Overview

ledger 9 rc.3 integration. Fixes: #1737

🗹 TODO before merging

  • Ready

📌 Submission Checklist

  • All commits are signed off (git commit -s) for the DCO
  • Changes are backward-compatible (or flagged if breaking)
  • Pull request description explains why the change is needed
  • Self-reviewed the diff
  • I have included a change file, or skipped for this reason:
  • If the changes introduce a new feature, I have bumped the node minor version
  • Update documentation (if relevant)
  • Updated AGENTS.md if build commands, architecture, or workflows changed
  • No new todos introduced

🧪 Testing Evidence

Please describe any additional testing aside from CI:

  • Additional tests are provided (if possible)

🔱 Fork Strategy

  • Node Runtime Update
  • Node Client Update
  • Other:
  • N/A

Links

Signed-off-by: Giles Cope <gilescope@gmail.com>
@datadog-official

datadog-official Bot commented Jun 23, 2026

Copy link
Copy Markdown

Pipelines

⚠️ Warnings

🚦 1 Pipeline job failed

CI + E2E | Check Genesis Rebuild   View in Datadog   GitHub Actions

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: c45367b | Docs | Give us feedback!

gilescope and others added 11 commits June 23, 2026 17:08
Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
We need to do this for 2 reasons:
1. We should not block the executor - awaiting on a new thread for high CPU work is the right choice
2. Ledger 9 no-longer has Send for the tx.prove() method. So our hand is forced here, even for remote proving

Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Assisted-by: Claude:claude-4.8-opus
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
ledger 9-rc.3 folds dust_actions into Intent::data_to_sign (the new
IntentSigningEnvelope), so a dust registration's night_key, dust_address
and allow_fee_payment are now part of the signed payload. Both toolkit
sign-paths computed data_to_sign before attaching the registrations to the
intent, so the signature no longer matched at validation and genesis
generation failed with InvalidDustRegistrationSignature.

Attach the registrations unsigned first, then compute data_to_sign and fill
in each signature, mirroring the ledger's own Transaction::sign. Affects
genesis_generator::add_dust_actions and the helper apply_dust path (new
DustRegistrationBuilder::build_unsigned).

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Under ledger 9-rc.3 ContractOperation is dual-stack: v1 (zk-stdlib v1) circuits
verify their proofs (ProofVersioned::V2) against the v2 slot, holding a 2.x
transient_crypto_old verifier key (verifier-key[v6]); v2 circuits use the v3 slot
(3.x transient_crypto, verifier-key[v7]).

The simple-merkle-tree and counter test contracts are v1 circuits, so their stored
verifier keys are 2.x keys. The toolkit deploy path loaded them via the 3.x
verifier_key()/contract_operation_new(), which could not deserialize the v6 keys
and produced an operation with no verifier key -- contract deploys failed with
VerifierKeyNotSet { operation: check }.

Add verifier_key_v1 (deserializes as 2.x) and a per-generation contract_operation_new_v1:
pre-ledger-9 it is the existing single-stack path; under ledger 9 it places the 2.x
key in ContractOperation::v2. The merkle-tree deploy now uses these. Verified
end-to-end (deploy -> store -> check), the check call's proof verifying against
op.v2_vk().

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
rc.3 folds dust_actions into Intent::data_to_sign, so the unshielded offer's
input signatures - not just the dust registration signatures - are signed over
a payload that includes the dust. StandardTrasactionInfo::apply_dust attached
dust_actions to the fallible intent *after* IntentInfo::build had already signed
that intent's unshielded offer, leaving those offer signatures stale. Validation
recomputed data_to_sign with the dust and balancing failed with
IntentSignatureVerificationFailure (e.g. generate-txs batches during genesis
generation).

apply_dust now assembles the full intent (offers + unsigned dust) first, then
computes data_to_sign once and re-signs both the unshielded offers and the dust
registrations over it, mirroring the ledger's own Intent::sign. The offer
signing keys are recovered from the originating IntentInfo via a new
BuildIntent::unshielded_signing_keys accessor.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade to ledger rc.3

2 participants