Skip to content

mirror_worker: add the optional sign-subtree endpoint - #273

Open
lukevalenta wants to merge 3 commits into
mainfrom
lvalenta/mirror-worker-sign-subtree
Open

mirror_worker: add the optional sign-subtree endpoint#273
lukevalenta wants to merge 3 commits into
mainfrom
lvalenta/mirror-worker-sign-subtree

Conversation

@lukevalenta

Copy link
Copy Markdown
Contributor

Implement the tlog-witness sign-subtree cosigning path: verify the requested subtree is consistent with a reference checkpoint this mirror has cosigned, then countersign the subtree with SubtreeV1CheckpointSigner.

@lukevalenta lukevalenta self-assigned this Jul 31, 2026
@lukevalenta

Copy link
Copy Markdown
Contributor Author

/bigbonk review

ask-bonk[bot]
ask-bonk Bot previously requested changes Jul 31, 2026

@ask-bonk ask-bonk Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation is solid and closely follows the established pattern in witness_worker. The core logic — stateless checkpoint verification, subtree consistency proof, signing with timestamp=0 — is correct. clippy, tests, and fmt all pass on this branch.

Two doc-comment issues:

  1. add-entries references in sign_subtree doc comment (filed inline): The doc comment refers to add-entries three times but the mirror doesn't have that HTTP endpoint — the cosignature is produced on the commit path after entry ingestion. The witness_worker's equivalent doc says "the same cosigner emitted by add-checkpoint". Please update these references to the correct endpoint/operation name.

  2. Module-level route list not updated (frontend_worker.rs lines 4-16): The module header lists only POST /add-checkpoint, GET /metadata, and GET /. The new POST /sign-subtree route should be added between /add-checkpoint and /metadata, with a [signsub] link reference matching the one in lib.rs.

Comment thread crates/mirror_worker/src/frontend_worker.rs
@ask-bonk

ask-bonk Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review submitted. Here's a summary of the findings:

Overall: The implementation is correct and closely mirrors the established sign_subtree pattern in witness_worker. The core logic — stateless checkpoint verification via the mirror's own past cosignature, subtree consistency proof verification, and signing with timestamp=0 per spec — is sound. The MirrorSigner changes in lib.rs to store the SubtreeV1CheckpointSigner are clean and well-documented. All CI checks pass (clippy, tests, fmt).

Two doc-comment issues requiring changes:

  1. add-entries references (frontend_worker.rs:340,347,351): The sign_subtree handler's doc comment refers to add-entries three times, but the mirror has no such HTTP endpoint. The witness_worker's equivalent doc says "the same cosigner emitted by add-checkpoint". These references should be corrected.

  2. Module-level route list not updated (frontend_worker.rs:4-16): The module header still lists only three routes (POST /add-checkpoint, GET /metadata, GET /). The new POST /sign-subtree route should be added for completeness, with a [signsub] link reference matching the one added in lib.rs.

github run

lukevalenta added a commit that referenced this pull request Aug 1, 2026
Add the POST /sign-subtree route to the frontend_worker module doc's
route list with a [signsub] link, matching lib.rs. Addresses bonk #273
finding 2.
@lukevalenta

Copy link
Copy Markdown
Contributor Author

/bigbonk review again

@ask-bonk

ask-bonk Bot commented Aug 1, 2026

Copy link
Copy Markdown

Good. Now I have a clear picture. Let me finalize the review.

Summary of findings:

The previous review raised two issues:

  1. add-entries references in the sign_subtree doc comment -- The author responded that add-entries will be added by PR mirror_worker: implement the add-entries submission API #264, so these references are intentional and forward-looking. This is reasonable: the mirror_state_do already has 8 references to add-entries from prior PRs, and PR mirror_worker: implement the add-entries submission API #264 (currently open) implements the actual endpoint. The doc comments in this PR describe the trust relationship accurately for the state the codebase will be in once mirror_worker: implement the add-entries submission API #264 merges.

  2. Module-level route list not updated -- This was addressed in the second commit (e39bc5d mirror_worker: list /sign-subtree in the module route header). The route list at frontend_worker.rs:14-18 now includes POST /sign-subtree with the [signsub] link reference at line 27.

Both issues from the previous review are resolved.

Re-review of the implementation:

The implementation is correct and well-structured:

  • The handler at frontend_worker.rs:362-455 follows the same pattern as the witness_worker's sign_subtree, adapted for the mirror's simpler signer model (always ML-DSA-44, no Ed25519 fallback needed).
  • The MirrorSigner changes in lib.rs:136-165 store the SubtreeV1CheckpointSigner and expose it via as_subtree_signer(), with clear doc comments explaining why the concrete type is needed rather than the trait object.
  • The build_mirror_signer change at lib.rs:196-197 adds KeyName construction, which is required by SubtreeV1CheckpointSigner::new.
  • Error handling (ReferenceCheckpointNotCosignedByThisMirror, UnprocessableEntity) maps correctly to HTTP 403 and 422 respectively.
  • The MAX_SIGN_SUBTREE_BODY_SIZE constant at line 467 matches the witness_worker's reasoning and is also enforced via axum's DefaultBodyLimit layer rather than a manual check in the handler body.
  • All CI checks pass: clippy (pedantic, warnings-as-errors), full test suite (all 16 mirror_worker tests pass including the signer tests), and formatting.

No actionable findings remain.

github run

@lukevalenta
lukevalenta dismissed ask-bonk[bot]’s stale review August 1, 2026 00:51

comments addressed

@lukevalenta
lukevalenta marked this pull request as ready for review August 1, 2026 00:51
Comment thread crates/mirror_worker/src/frontend_worker.rs Outdated
Comment thread crates/mirror_worker/src/frontend_worker.rs Outdated
Comment thread crates/mirror_worker/src/frontend_worker.rs
Comment thread crates/mirror_worker/src/frontend_worker.rs
Implement the tlog-witness sign-subtree cosigning path: verify the
requested subtree is consistent with a reference checkpoint this mirror
has cosigned, then countersign the subtree with the concrete
SubtreeV1CheckpointSigner (the algorithm-agnostic CheckpointSigner trait
object cannot reach sign_subtree).

Give MirrorSigner an actual signing capability for this: it now holds a
boxed SubtreeV1CheckpointSigner built at load, since the foundation only
stored the public key (the mirror never cosigned before). Later cosigning
endpoints (add-entries) reuse this.

Adds the /sign-subtree route, a request-body size cap, the
UnprocessableEntity (422) and ReferenceCheckpointNotCosignedByThisMirror
errors.
Add the POST /sign-subtree route to the frontend_worker module doc's
route list with a [signsub] link, matching lib.rs. Addresses bonk #273
finding 2.
- Return the Display form of a malformed reference-checkpoint parse
  error, matching add-checkpoint, so the Rust type name stays out of the
  400 body.
- Reuse tlog_witness::MAX_REQUEST_BODY_SIZE for the sign-subtree body cap
  instead of duplicating the constant the parser already enforces.
- Log the previously-silent rejections (unknown origin 404, subtree
  bounds 400s, consistency-proof 422) with the subtree range and
  checkpoint size, so operators can tell which check failed.
- Map the unexpected verify errors (MismatchedVerifier/AmbiguousKey,
  unreachable over a one-element verifier list) to 500 rather than
  blaming the client with 400.
@lukevalenta
lukevalenta force-pushed the lvalenta/mirror-worker-sign-subtree branch from e39bc5d to 28593fb Compare August 6, 2026 13:24
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.

2 participants