Skip to content

Take endpoints out of the source dependency cycle - #8475

Merged
Amaury Chamayou (achamayou) merged 1 commit into
mainfrom
achamayou-issue-3517-clarify-dependencies-between-framework-s-cd5d31
Sep 30, 2026
Merged

Amaury Chamayou (achamayou) merged 1 commit into
mainfrom
achamayou-issue-3517-clarify-dependencies-between-framework-s-cd5d31

Conversation

@achamayou

Copy link
Copy Markdown
Member

Motivation

Partially addresses #3517. This implements the endpoints -> node step from the latest analysis, which #8472 made the next cut.

Since #8472, the source dependency cycle has been {endpoints, js, node}. endpoints is in it only because three of its files include six node headers. Each of those is either a type that endpoints effectively owns, or node code that happens to be implemented in src/endpoints/. This PR moves them, so endpoints leaves the cycle and gets a dependency policy.

Before After
Direct internal edges 83 82
Components in the cycle endpoints, js, node js, node
Acyclic components, all with policies 22 23

The diagram shows every direct dependency among the three components that formed the cycle, each labelled with the number of #include directives behind it after this PR. The dashed red edge is the one this PR removes (6 before).

graph LR
  subgraph core["remaining cycle"]
    js -- 8 --> node
    node -- 14 --> js
  end
  js -- 8 --> endpoints
  node -- 5 --> endpoints
  endpoints -.->|6, removed| node
  linkStyle 4 stroke:#cf222e,stroke-width:3px
Loading

js -> node is now the last edge to cut before the source graph has no cycles.

Implementation summary

Code moves only, one per removed include:

  • rpc_context_impl.h moves from node/ to endpoints/. It only depends on public headers, and both endpoint registries (endpoint_registry.cpp and js/registry.cpp) cast to RpcContextImpl to fill in path parameters. node/rpc/http_rpc_context.h now includes it from endpoints, which is the intended direction. This also removes one js -> node include.
  • The body of build_receipt_for_committed_tx() moves to node/historical_queries_adapter.cpp. It is declared in the public ccf/endpoint_registry.h, but it is node code: it looks up the SignatureCacheInterface subsystem and rebuilds a MerkleTreeHistory to extract a proof. It now sits next to describe_receipt_v1() and the other public receipt functions implemented in node. Both files are compiled into ccf_endpoints, so linking does not change. This removes the tx_receipt_impl.h and signature_cache_interface.h includes, without the new subsystem or Merkle tree relocation that the analysis expected. endpoint_registry.cpp also drops ccf/node_context.h, which it no longer uses.
  • GetCommit, GetTxStatus and GetAPI move into common_endpoint_registry.cpp, their only user, with their JSON declarations. Their names, and so the generated OpenAPI schemas, do not change. This removes the node/rpc/call_types.h and node/rpc/serialization.h includes.
  • cose::Signature, is_ecdsa_alg() and is_rsa_alg() move from node/cose_common.h to crypto/cose.h, next to the alg constants they test. cose_auth.cpp used nothing else from cose_common.h. cose_common.h already includes crypto/cose.h, so its other users are unaffected.
  • source-dependencies.json gains an endpoints policy (ccf-api, crypto, ds, http, kv, service), which is exactly the measured set.

Following includes transitively, src/endpoints/ now reaches 125 files outside itself instead of 198, and none in node (previously 16).

Locally, a clang 21 Debug build of all targets produces no warnings, and all unit tests, schema_test, e2e_logging (including /log/blocking/private/receipt, which calls build_receipt_for_committed_tx()) and governance_test pass.

The only open PR that touches the same files is draft #8368, which replaces fmt::format in them, including in the moved body of build_receipt_for_committed_tx(). Rebasing it is mechanical.

Safety and compatibility

Production behaviour does not change. Every function and type keeps its body, and only the file that defines it changes:

  • Receipts built on commit, path parameter extraction, the /commit, /tx and /api responses, and the COSE governance signature algorithm checks run the same code as before.
  • build_receipt_for_committed_tx() keeps its public declaration and stays in the ccf_endpoints library, so applications compile and link as before.

Nothing under include/ changes. There are no wire, ledger or KV format changes, and no effect on mixed-version operation or recovery. Nothing is user-facing, so there is no CHANGELOG.md entry.

Fixes: #3517

endpoints was in the {endpoints, js, node} cycle only through six
includes of node headers from three files. Move each piece to its owner:

- rpc_context_impl.h moves from node/ to endpoints/.
- build_receipt_for_committed_tx() is now defined in
  node/historical_queries_adapter.cpp, next to the other public receipt
  functions implemented in node, in the same ccf_endpoints library.
- GetCommit, GetTxStatus and GetAPI move into
  common_endpoint_registry.cpp, their only user.
- cose::Signature, is_ecdsa_alg() and is_rsa_alg() move to
  crypto/cose.h, next to the alg constants.

Add an endpoints dependency policy. The remaining cycle is {js, node}.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings September 30, 2026 14:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The relocations preserve definitions and behavior, and the new dependency policy passes validation.

Review effort: Balanced
Findings: None

What changed in this PR

Moves endpoint-owned code out of node, removing endpoints from the source dependency cycle without changing runtime behavior.

Changes:

  • Relocates endpoint context, receipt, RPC schema, and COSE helpers.
  • Adds and validates an explicit dependency policy for endpoints.

Custom instructions used:

  • .github/copilot-instructions.md
  • .github/instructions/reviewing.instructions.md
File Description
src/​node/​rpc/​serialization.h Removes relocated endpoint JSON declarations.
src/​node/​rpc/​http_rpc_context.h Includes the relocated RPC context.
src/​node/​rpc/​call_types.h Removes endpoint-only call types.
src/​node/​historical_queries_adapter.cpp Hosts committed-transaction receipt construction.
src/​node/​cose_common.h Removes relocated COSE helpers.
src/​js/​registry.cpp Uses the endpoint-owned RPC context.
src/​endpoints/​rpc_context_impl.h Defines the relocated RPC context implementation.
src/​endpoints/​endpoint_registry.cpp Removes node-owned receipt dependencies.
src/​endpoints/​common_endpoint_registry.cpp Localizes endpoint call types and serialization.
src/​endpoints/​authentication/​cose_auth.cpp Uses crypto-owned COSE helpers.
src/​crypto/​cose.h Defines shared COSE signature and algorithm helpers.
scripts/​source-dependencies.json Adds the validated endpoints dependency policy.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@achamayou
Amaury Chamayou (achamayou) merged commit 63f989c into main Sep 30, 2026
13 checks passed
@achamayou
Amaury Chamayou (achamayou) deleted the achamayou-issue-3517-clarify-dependencies-between-framework-s-cd5d31 branch September 30, 2026 14:50
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.

Clarify dependencies between framework source components

3 participants