Repository navigation
[Design][Interop] SSRI / IPC architecture decision: discovery, contract admission, and runtime communication #81
Description
What reviewers are being asked to assess
Status: design proposal. No architecture has been selected, implemented, or assigned a release date. This issue introduces CellScript to reviewers who may not know it and allows the maintainer to invite Hanssen, Retric, Guopeng, and others. Naming them does not imply that they have been invited, agreed, or completed a review.
The decision is which layers of CellScript cross-contract interoperability should reuse SSRI, which should reuse ckb-script-ipc, and which constraints CellScript must own. Review capabilities and trust boundaries before APIs. “IPC” can mean either CKB's process-communication syscalls or XuJiandong's library; do not conflate them.
In one sentence: how a wallet discovers a contract, how a contract admits a counterpart, and how processes exchange arguments and results at runtime are three related but distinct problems. Claims that “IPC is more advanced” need concrete evidence of interoperability, cost, maintenance, and security benefits.
1. CellScript in ten minutes
CellScript compiles .cell source into CKB-VM RISC-V ELF and emits typed interface and execution-boundary descriptions. An independent artefact checker verifies bounded structural contracts between the ELF and those descriptions; it does not establish arbitrary business-logic correctness. CKB still consumes existing Cells and creates new Cells, with each Lock/Type Script validating the same transaction.
| Concept | Plain-language description | Existing boundary |
|---|---|---|
| ProtocolBundle | Organises a transaction involving separately compiled contracts and checks roles, witnesses, and input/output conflicts | Off-chain orchestration; does not link ELFs together or replace execution of all Script groups |
| Interface receipt | Checked result binding code, interface, and compilation evidence | Type compatibility is not economic correctness or business equivalence |
| ScriptHandle / VerifierHandle | Selects a Script or child verifier under an authorised policy | Bounded profiles from #28/#29, not arbitrary function calls |
| InstanceScriptHandle | Constrains full Script args and concrete instances beyond implementation admission | #80; identical code can have different instances, and an allowed B cannot impersonate the selected A |
| Foreign view | Reads transaction Cells belonging to another contract | Observation confers neither spending permission nor proof that the other Script passed |
Foundational issues #9/#10/#11/#28/#29/#80 were closed (checked 18 October 2026). The code baseline is 602795b3, a bounded accepted state on the 0.32 development branch, not a new stable release or claim of public deployment.
Starting points: end-to-end tutorial, open-handle contract, and instance contract and real example.
2. One example, three distinct needs
Suppose an institution issues document credentials. Alice wants to revoke one credential and unlock an observer Lock that references it, in the same transaction.
- The wallet needs to discover the credential type, available methods, and how to construct a transaction: discovery and off-chain construction.
- The observer Lock must establish that the actual input credential comes from an approved implementation, belongs to the right namespace, has a permitted category, and matches the instance selected for this operation: identity and authorisation.
- The credential Type must actually validate the issuance/revocation rules, and the issuer Lock must check the signature: complete transaction execution.
- Only if the application additionally needs an independent algorithmic verifier must a parent Script launch it, transmit data, read its result, and handle failures: process communication. The first three steps do not themselves require general-purpose IPC.
---
config:
flowchart:
subGraphTitleMargin:
top: 10
bottom: 20
---
flowchart TB
subgraph Tool["Off-chain · Discovery and construction"]
D["SSRI / other discovery entry"] --> B["Construct candidate transaction"]
B --> P["ProtocolBundle · Check identity and roles"]
end
subgraph Chain["On-chain · Same transaction"]
P --> L["Issuer Lock · Check signature"]
P --> T["Credential Type · Validate revocation"]
P --> O["Observer Lock · Instance policy"]
O -. "Only if extra computation is required" .-> C["Parent process ⇄ Child verifier"]
L --> A["All required groups pass"]
T --> A
O --> A
end
classDef tools fill:#e8f1ff,stroke:#4267a8,color:#132e53;
classDef checks fill:#e5f6ee,stroke:#27835d,color:#133d2e;
classDef optional fill:#fff3d9,stroke:#aa791c,color:#513a12;
class D,B,P tools;
class L,T,O,A checks;
class C optional;
3. Research evidence: distinguish concepts, implementations, and unknowns
Verified on 18 October 2026. DeepWiki was used only for navigation; conclusions here rely on original proposals and pinned source.
- Hanssen's original SSRI proposal: Script-Sourced Rich Information, method paths, off-chain execution contexts, and information/logic provided by Scripts.
ckb-ssri-std@ 93f3a779: its README still lists TODOs such as a unified entry and attribute macros;ssri_methods!already provides discovery/dispatch. Conceptual soundness does not imply that every proposed feature is implemented.ckb-script-ipc@ 4044faee: procedural macros generate client/server code; runtime provides spawn/pipe, framing, and native execution. It is not exclusively on-chain.- RFC 0050: underlying spawn/wait/read/write/pipe semantics. Experiments must additionally pin node/VM/ckb-std versions, rather than relying solely on a moving RFC.
| Dimension | Inspected SSRI design/implementation | Inspected ckb-script-ipc | CellScript's own responsibility |
|---|---|---|---|
| Primary value | Script self-description, shared query/construction logic, conventional public methods | Rust trait → generated requests, responses, and communication code | Bind interface to actual code, instance, and permissions |
| Execution | Off-chain extended-VM contexts/queries must be explicitly marked | On-chain parent/child processes and a native host entry | Prevent off-chain results becoming on-chain authorisation |
| Methods and encoding | Short method paths, argv, Molecule convention; pin exact version | VLQ framing; default Channel uses serde_json; macro generates request/response enums | Full type/codec identity, bounds, errors, version migration |
| Discovery vs authorisation | Method presence indicates a claimed capability | Receiving a reply indicates receipt of data | Reject wrong code, instance, context, or forbidden operation |
| Resources | Server/VM budgets, pagination, return sizes | Repeated-request server loop, dynamic buffers, pipe lifecycle | Measured byte/request/memory/cycle ceilings and deterministic failure |
| Existing capabilities | Optional wallet/builder entry | Candidate transport for parameterised child verifiers | Preserve exact/open/instance ABIs and all peer checks |
These are source observations, not a security audit or performance ranking. Default JSON does not mean IPC framing can only carry JSON. Replacing it with Molecule requires an explicit negotiated interoperable profile or an honestly named new protocol incompatible with the default upstream client.
4. Compare four routes fairly
| Route | Expected advantage | Cost to demonstrate |
|---|---|---|
| A. Retain metadata and fixed verifiers; adopt neither for now | Minimum change; existing behaviour intact | Actual missed wallet interoperability and duplicated work |
| B. SSRI adapter; retain existing on-chain verifier path | Address discovery/transaction construction first | Same-ELF dispatch versus companion binding; extra VM/SDK maintenance |
| C. ckb-script-ipc as the primary service protocol, including discovery | One client/server mechanism across use cases | Whether SSRI/CCC consumers can use it directly; additional discovery conventions |
| D. Layered: SSRI discovery + bounded IPC | Potential integration with both ecosystems | Two protocol versions, adapters, duplicated encoding and tests |
A small independent protocol remains a possible implementation variant of A/C/D, but requires precise justification for not reusing upstream contracts, disclosure of shared wire semantics, and a long-term maintainer. “More secure” or “more advanced” alone is inadequate. The current preference is to experiment by layer, not to commit to D or any new dependency.
5. Comparable experiments and decision process
- Pin problems and samples: credential discovery/construction, one fixed-size pure verifier call, and two ordered calls. All routes use the same code identity, requests, context, expected success/failure. Do not compare an unauthenticated demo against fully checked CellScript.
- Freeze interface semantics: target identity, full signature/codec hash, method number, read permissions, effects, input/output bounds, and error classes. Short-ID collisions must fail or have verifiable disambiguation; method number alone is not interface identity.
- Native Rust baseline: implement equivalent checks with a pinned
ckb-std; measure application-specific code, reusable libraries, SDK construction, and testing. Compare complete implementations, not one DSL helper against all transitive Rust dependencies. - Disposable adapters: test SSRI, default upstream IPC, candidate bounded IPC, and existing fixed path. Mark unimplemented cases as missing, not zero-cost. Pseudocode must not be presented as a working API.
- Reproducible evidence: record exact source/lock/compiler/ELF/network/VM versions, raw transactions/witnesses, code and transport sizes, memory, single/repeated call cycles, maximum-success and latest-failure cases. Report off-chain cold/warm latency separately. Mark unobservable memory as unavailable.
- Architecture decision record (ADR): document decisions to adopt, reject, or defer, with reasons and reconsideration triggers. Address external review disagreements individually; the maintainer assigns ownership and implementation scope before development.
Authoring direction — 2026-10-19
The authoring requirements adopted in #47/#48/#49 also apply to this decision. Treat application-facing declarations and transport bindings as separate design decisions: choosing SSRI, IPC, both, or neither must not automatically freeze the upstream library's plumbing as CellScript syntax. Any shared interface description must preserve the different context, authority, error, and lifecycle contracts; a pleasant call expression is not evidence that these contracts are interchangeable.
Compare all four routes using complete author-written examples: credential discovery and candidate construction, one checked verifier request, and two ordered requests. Show the declarations, reusable helpers, caller, generated client/builder, and rejection paths. Evaluate named business roles and methods, structurally resolved typed fields and policies, and named resource limits declared once at the relevant interface or scope. Avoid repeated positional budgets, numeric role ordinals, duplicate type/role declarations, and hand-written transport details at ordinary use sites. A declaration must still resolve to exact checked identities, codec bounds, and execution obligations.
Use the same borrowing direction as #47–#49: ordinary direct reads should stay direct; an explicit borrow scope should express a real retained-view lifetime. Bounded non-escaping helper composition is a target for review, not an already implemented capability. Local read-only views, owned collections, off-chain query results, and child-process messages retain different authority and lifetime rules. Borrowed pointers are not a cross-process wire format, and a decoded response does not acquire authority over foreign Cells.
Authoring review is part of architecture acceptance before a stable API is frozen. Record which repetition the compiler or generated adapters remove, which limits and failure decisions the author must still state, and which helper shapes remain unsupported. Compare equivalent reusable Rust libraries fairly. Preserve exact/open/instance admission, complete Script-group validation, numeric resource evidence, and independent checking; concise syntax cannot waive any of them. Exact grammar and protocol selection remain undecided.
6. Actual dependencies on #47/#48/#49
- [0.33][Runtime] Extend bounded Cell selection and correspondence for heterogeneous and dynamic data #49 covers bounded selection, completeness, and input/output correspondence for heterogeneous role-based Cell collections; priority 1. Fixed-layout work can proceed separately. Cross-contract observation must not turn into ownership of foreign resources.
- [0.33][ABI] Support bounded nested dynamic values with canonical codecs #48 covers canonical codecs for nested variable-length values; priority 2. Bounded read-only decoding need not require heap allocation. Variable-length payload support in [0.33][Runtime] Extend bounded Cell selection and correspondence for heterogeneous and dynamic data #49 depends on its specific codec.
- [0.33][Runtime] Add bounded allocation-backed value collections and deterministic Map/Set #47 covers bounded per-invocation allocation and deterministic Map/Set; priority 3. It becomes a dependency only when owned dynamic values or general-purpose collections are selected.
- Fixed-request/fixed-result IPC tests and limited off-chain discovery should not be blocked by all three issues collectively. Conversely, integrating SSRI/IPC does not complete them.
- Hooks, economic deltas, and routing remain under [DeFi][FIN-19] Authenticated before/after operation hooks and permissions #69/[DeFi][FIN-21] Permissioned extension balance deltas and alternative pricing curves #71/[DeFi][FIN-25] Bounded command-plan routing and authenticated liquidity migration #75; successful communication proves neither asset conservation nor authorisation nor correct quotations.
7. Deliverables, review, and closure criteria
This issue owns architecture selection. Two companion issues cover SSRI integration and bounded IPC ABI/lifecycle design; see Design workstreams.
- Review complete authoring examples for all four routes against the [0.33][Runtime] Add bounded allocation-backed value collections and deterministic Map/Set #47/[0.33][ABI] Support bounded nested dynamic values with canonical codecs #48/[0.33][Runtime] Extend bounded Cell selection and correspondence for heterogeneous and dynamic data #49 direction: named roles/methods and limits, typed fields/policies, helper composition, and visible authority/lifecycle boundaries. Record remaining gaps before stable API freeze.
- Pin all three upstream source revisions and document discrepancies between SSRI concepts, inspected implementation, and server versions.
- Compare all four routes on equivalent scenarios; mark unexecuted measurements as absent, never pretend they are performance results.
- Complete the responsibility matrix for identity, instance, context, permissions, codec, lifecycle, resources, and errors.
- Supply comparable Rust and CellScript examples, clearly separating executable code, proposed APIs, and pseudocode.
- Give both companion designs executable implementation slices, threat cases, methods for freezing numeric budgets, and acceptance owners.
- Record actual invited reviewers' feedback and maintainer decisions. Silence is not endorsement; review waivers for earlier issues do not automatically carry over.
- Record written accept/reject/defer decisions and reopening conditions. Closing the design issue is not equivalent to implementation or deployment.
Questions for reviewers: Have we defined SSRI's scope too narrowly? Does the IPC library's actual evolution change these observations? Which existing external consumers are mandatory interoperability targets? Can we share interface descriptions while retaining distinct transports? Which state or permission decisions must never depend on a service return value? Is maintaining two protocols worthwhile for v1? Please provide concrete calls and failure cases.
Design workstreams
- Overall selection and decision record: [Design][Interop] SSRI / IPC architecture decision: discovery, contract admission, and runtime communication #81.
- SSRI entry, context, and candidate transactions: [Design][SSRI] Script self-description, contextual queries, and transaction construction for wallets and SDKs #82.
- Bounded IPC ABI, lifecycle, and interoperability: [Design][IPC] Bounded parameterised verification services: typed requests and responses, child lifecycle, and upstream interoperability #83.
All three are open designs. Small experiments in #82/#83 may run in parallel to produce evidence; #81 owns the final architecture decision. These are references, not claims that GitHub blocking dependencies have been configured.
Activity
[-][Design][Interop] SSRI / IPC 分层选型:发现、合约准入与运行时通信[/-][+][Design][Interop] SSRI / IPC architecture decision: discovery, contract admission, and runtime communication[/+]a19q3 commentedon Oct 18, 2026
考虑到本议题涉及的主要开发者和评审者中有不少以中文交流,为方便大家阅读与讨论,也出于对不同语言使用习惯的尊重,特在此附上中文版。英文正文仍作为当前 issue 的主要描述;以下中文内容供对照参考。
SSRI / IPC 分层架构选型:发现、合约准入与运行时通信
状态:设计提案。尚未完成选型、实现,也没有承诺发布日期。 本议题面向未必熟悉 CellScript 的评审者,欢迎 Hanssen、Retric、Guopeng 等参与讨论;提及姓名不代表已邀请、已同意或已完成审核。
核心问题是:CellScript 的跨合约互操作,哪些层适合复用 SSRI,哪些适合复用
ckb-script-ipc,哪些安全约束必须由 CellScript 自己承担?请先审能力与信任边界,再审 API。“IPC”可能指 CKB 的进程通信 syscall,也可能指 XuJiandong 的库,不应混淆。钱包如何认识合约、合约如何选择合作对象、运行时如何交换参数与结果,是三个相关但不同的问题。
1. CellScript 背景
CellScript 将
.cell编译为 CKB-VM RISC-V ELF,同时生成类型接口和执行边界描述。独立 artifact checker 检查 ELF 与这些描述之间有界的结构性契约,不证明任意业务逻辑正确。CKB 仍按 Cell 模型运行,同一交易的 Lock/Type Script group 各自执行验证。基础 issue #9/#10/#11/#28/#29/#80 已关闭(2026-10-18 核验);开发基线为 602795b3,属于 0.32 开发分支的有界接受状态,并非新的稳定版本或公开部署声明。
阅读材料:端到端教程、开放 handle 设计、实例策略及案例。
2. 用凭证注销说明不同层
设某机构签发文件凭证,Alice 希望在一笔交易中注销凭证,并解锁引用该凭证的观察 Lock:
flowchart TB subgraph Tool["链下:发现与构造"] D["SSRI / 其他发现入口"] --> B["构造候选交易"] B --> P["ProtocolBundle:身份及角色检查"] end subgraph Chain["链上:同一笔交易"] P --> L["发行者 Lock:验签"] P --> T["凭证 Type:注销规则"] P --> O["观察 Lock:实例策略"] O -. "仅在需要额外计算时" .-> C["父进程 ⇄ 子验证器"] L --> A["全部必要 Script group 通过"] T --> A O --> A end3. 调研来源和实现边界
2026-10-18 的核验以原始设计及固定源码为依据,DeepWiki 仅用于导航:
ckb-ssri-std@ 93f3a779:已有ssri_methods!分发,但 README 对 unified entry、属性宏等仍列有 TODO;不能将设计概念等同于全部实现。ckb-script-ipc@ 4044faee:宏生成客户端和服务端代码;运行时支持 spawn/pipe、framing 与 native 运行,并非仅限链上。这是源码观察,不是安全审计或性能排行。IPC 默认使用 JSON 不代表 framing 只能支持 JSON;若改用 Molecule,必须明确互通协商 profile,或将不兼容方案标记为新协议。
4. 公平比较四条路线
也可以考虑小型独立协议作为 A/C/D 的实现变体,但需证明为何不能复用上游、明确 wire 契约与维护者。当前只倾向按层分别试验,没有预选 D,也未承诺增加依赖。
5. 同题实验与 ADR
ckb-std做原生 Rust 对照,统计实际业务代码、可复用库、SDK 构造及测试,不拿 DSL 的一行调用与 Rust 全部依赖源码比较。作者接口方向 — 2026-10-19
#47/#48/#49 已采用的作者接口要求同样适用于本次选型。面向业务作者的声明方式与 transport 绑定应分别决策:选择 SSRI、IPC、两者结合或暂不引入,都不能自动把上游库的底层操作冻结为 CellScript 语法。共享接口描述仍须保留各自的上下文、权限、错误与生命周期契约;调用写法简洁不代表这些契约可以互换。
四条路线应使用完整的作者代码比较:凭证发现与候选交易构造、一次受检查的验证请求、两次有序请求。展示声明、可复用 helper、调用方、生成的客户端/builder 及拒绝路径。评估具名业务角色和方法、结构化解析的类型字段及策略,以及在对应接口或作用域集中声明的具名资源上限。普通使用处应避免重复位置参数预算、数字角色序号、重复类型/角色声明和手写 transport 细节;声明仍须解析为受检查的精确身份、codec 上限与执行义务。
借用方向与 #47–#49 一致:普通直接读取保持直接;显式 borrow 作用域应表达实际保留 view 的生命周期。有界且不逃逸的 helper 组合是待评审目标,不能写成已实现能力。本地只读 view、owned 集合、链下查询结果和子进程消息仍有不同权限与生命周期。借用指针不是跨进程 wire 格式,解码后的响应也不会取得外部 Cell 的权限。
作者接口评审属于稳定 API 冻结前的架构验收。记录编译器或生成的 adapter 消除了哪些重复、作者仍须明确哪些上限和失败决策、哪些 helper 形态尚不支持,并公平对照可复用 Rust 库。精确/开放/实例准入、全部必要 Script group 验证、数值资源证据和独立检查必须保留,不能因语法简化而豁免。具体语法和协议选型仍未决定。
6. 与 #47/#48/#49 的关系
7. 交付与关闭标准
请评审者讨论: SSRI 范围是否界定得过窄?IPC 库的实际演进是否改变比较基础?哪些外部消费者是必须兼容的目标?能否共享接口描述而保留不同 transport?哪些状态与权限绝不可交由服务返回值决定?v1 是否值得承担双协议维护?请尽量给出具体调用和失败实例。
Design workstreams
总选型与决策:#81;SSRI 入口和链下上下文:#82;有界 IPC ABI、生命周期和互通:#83。三个 issue 均为开放设计;#82/#83 可以并行开展小实验,由 #81 汇总选型。这只是引用关系,不表示设置了 GitHub 自动阻塞依赖。
延伸阅读:端到端教程。