fhEVM JS SDK 多 WASM 版本浏览器测试矩阵:基于 Playwright 的 multi-wasm 测试套件设计与实现
【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm
本文是 fhEVM JS SDK 中多 WASM 版本(Multi-WASM)测试计划的落地指南,围绕 notes/TEST_PLAN.md 阐述如何用 Playwright 构建一套覆盖全部 WASM 配置组合的浏览器测试矩阵,并深入解析仓库中已实现的 test/multi-wasm 套件:包括 JSON 测试矩阵与 schema、五种wasmAssetLoadMode加载模式、CLI 坐标筛选、FHETest 加解密往返链路以及 localstack 生命周期管理。读完本文,你将能理解并独立运行这套多版本共存回归测试,并掌握为多版本 WASM 模块编写矩阵化浏览器测试的完整方法。
背景:为什么需要多 WASM 版本测试
fhEVM JS SDK 在浏览器中通过 WASM 完成同态加密操作:加密(Encrypt)侧依赖TFHE模块(src/wasm/tfhe),解密(Decrypt)侧依赖TKMS模块(src/wasm/tkms)。仓库中同时保留了多个版本的 WASM 产物:
- TFHE:
v1.5.3、v1.6.0-dev、v1.6.2 - TKMS:
v0.13.10、v0.13.20-0、v0.14.0-1
多版本并存的根本原因是格式兼容性:docs/compatibility.md 明确指出,"tfhe.wasm@v1.5.3无法解析由tfhe.wasm@v1.6.2产生的 PubKey/CRS",且序列化格式在 minor 版本之间不向前兼容。链上或 Relayer 侧没有直接信号告知 SDK 当前链需要哪个版本的tfhe.wasm,因此 SDK 只能通过协议上下文(ACL 合约版本 + PubKey/CRS 版本)做启发式推断。由此带来的问题非常现实:不同链、不同协议版本需要不同组合的 WASM 模块,而同一页面/同一 JS realm 内可能同时存在多个版本的模块——这正是多 WASM 测试要覆盖的核心风险面。
notes/TEST_PLAN.md的定位十分明确:它只聚焦"新的多 WASM 支持(多版本支持)"这一项能力,要求建立一套覆盖所有可能 WASM 配置的完整测试套件,测试矩阵定义在 JSON 文件中,并且可以跑在真实浏览器页面中。
测试计划核心要求速览
原测试计划提出了一组清晰的验收条件,它们全部在 test/multi-wasm 中得到了落地实现:
| 计划要求 | 落地位置 |
|---|---|
| 测试矩阵定义在 JSON 文件中 | matrix.json + matrix.schema.json |
套件位于./test/multi-wasm | test/multi-wasm |
| 使用 Playwright 且可在浏览器页面运行 | playwright.config.ts、roundtrip.html |
| 每个测试执行一次加密/解密往返 | scripts/roundtrip.ts |
| 每个测试使用全新页面(一个页面无法运行多个 FhevmRuntime) | specs/roundtrip.spec.ts 中每个test()独立page.goto |
| 复用/重启 localstack(anvil 已在跑则跳过耗时重启) | support/localstack.ts + scripts/localstack-restart.sh |
支持--tfhe、--kms、--mode运行单个矩阵坐标 | run.mjs |
测试wasmAssetLoadMode各模式 | 五种模式全量枚举(见下文) |
| 测试 CDN 场景,URL 写进 JSON | assetUrlSets中的jsdelivr、unpkg |
一个值得注意的版本演进:计划初稿给出的首版矩阵为tfhe 1.5.3 + tkms 0.13.10与tfhe 1.6.1 + tkms 0.13.20-0;而当前 matrix.json 实际落地为tfhe 1.6.2 + tkms 0.13.20-0(SDK 源码中保存的是v1.6.2而非v1.6.1),并额外增加了tfhe 1.6.2 + tkms 0.14.0-1与仅限本地 CDN 的tfhe 1.6.0-dev行。这说明矩阵本身是持续演进的配置数据——这正是"矩阵放在 JSON 中"设计价值的体现。
测试矩阵的 JSON 设计
matrix.json:版本对 × 资产 URL 模板
matrix.json 是整个套件的配置核心,其结构分三层:
{ "$schema": "./matrix.schema.json", "schemaVersion": 1, "defaults": { "roundTrip": { "clearType": "uint8", "contractMethod": "setEuint8", "makePublic": true, "value": 42 } }, "supportedVersionPairs": [ { "tfhe": "1.5.3", "kms": "0.13.10" }, { "tfhe": "1.6.2", "kms": "0.13.20-0" }, { "tfhe": "1.6.2", "kms": "0.14.0-1" }, { "tfhe": "1.6.0-dev", "kms": "0.13.20-0", "cdns": ["local"] } ], "assetUrlSets": { "local": { "tfheWasm": "/src/wasm/tfhe/v{tfhe}/tfhe_bg.wasm", "tfheWorker": "/__raw_wasm/src/wasm/tfhe/v{tfhe}/tfhe-worker.mjs", "kmsWasm": "/src/wasm/tkms/v{kms}/kms_lib_bg.wasm" }, "jsdelivr": { "tfheWasm": "https://cdn.jsdelivr.net/npm/tfhe@{tfhe}/tfhe_bg.wasm", "tfheWorker": "/__raw_wasm/src/wasm/tfhe/v{tfhe}/tfhe-worker.mjs", "kmsWasm": "https://cdn.jsdelivr.net/npm/tkms@{kms}/kms_lib_bg.wasm" }, "unpkg": { "tfheWasm": "https://unpkg.com/tfhe@{tfhe}/tfhe_bg.wasm", "tfheWorker": "/__raw_wasm/src/wasm/tfhe/v{tfhe}/tfhe-worker.mjs", "kmsWasm": "https://unpkg.com/tkms@{kms}/kms_lib_bg.wasm" } } }设计要点:
supportedVersionPairs:声明所有受支持的 TFHE/TKMS 版本组合。每行可带可选的cdns白名单——tfhe 1.6.0-dev只允许本地 CDN,因为 dev 版本不会发布到公共 CDN。assetUrlSets:按 CDN 分组定义三件套资产 URL 模板(TFHE wasm、TFHE worker、KMS wasm),使用{tfhe}、{kms}占位符,在运行时由 support/matrix.ts 的renderAssetUrlTemplate替换成具体版本号。这正是测试计划中"在 JSON 文件中加入 CDN 测试 URL"的落地。defaults.roundTrip:全局默认的往返参数——本轮默认加密uint8类型、值42,调用FHETest.setEuint8,并开启makePublic(同时验证公开解密路径)。
matrix.schema.json:矩阵的契约
matrix.schema.json 基于 JSON Schema Draft 2020-12,为矩阵数据定义了严格的类型契约:
- 顶层必需字段:
schemaVersion(必须是常量1)、defaults、supportedVersionPairs(minItems: 1)、assetUrlSets; versionPair:必需tfhe与kms(均为 string),可选cdns(string 数组,minItems: 1、uniqueItems: true);assetUrlSets:对象,必须至少包含local,且每个assetUrlSet必需tfheWasm、tfheWorker、kmsWasm三个 URL 字符串;roundTrip:clearType枚举bool/uint8/uint16/uint32/uint64/uint128/uint256/address,contractMethod枚举对应的setEbool…setEaddress,value允许 boolean/integer/string。
schema 的约束在运行时还会被 support/matrix.ts 的validateMatrix/validateAssetUrlSets二次校验:版本对不允许重复(以tfhe\0kms为 key 去重)、cdns引用的 CDN 必须真实存在于assetUrlSets、assetUrlSets必须包含local等。
笛卡尔积生成与坐标筛选
support/matrix.ts 是矩阵的运行时大脑,两个核心函数:
generateMatrixEntries(matrix):对每个版本对 × 每种wasmAssetLoadMode× 每个 CDN 做笛卡尔积,生成带id(形如tfhe-1.5.3__kms-0.13.10__verified-blob__local)和label的矩阵条目。注意两个例外规则:embedded-base64模式只与localCDN 组合(其资产内嵌在 SDK 包中,天然没有 CDN 概念);- 版本对声明了
cdns白名单时只取白名单内的 CDN。
selectMatrixEntries(matrix, selection):按tfhe/kms/mode/cdn四个坐标过滤条目,一个坐标都没命中会抛出列出全部可用条目的错误——这正是"运行单个矩阵坐标"的底层机制。版本号统一经normalizeModuleVersion处理,接受v前缀(如v1.5.3与1.5.3等价)。
wasmAssetLoadMode:五种加载模式全解析
测试计划明确要求覆盖verified-blob、precheck-direct-url等加载模式。这些模式的权威定义在 src/core/types/wasmAssets.ts 的类型注释中,五种取值及其语义如下:
| 模式 | 传输方式 | Blob 封装 | SHA-256 校验 | 行为说明 |
|---|---|---|---|---|
embedded-base64 | base64 内嵌 | 是 | 否 | 读取内置于 SDK 模块的 base64 worker 源码;浏览器中解码为 Blob URL 后创建 module worker |
verified-blob | URL | 是 | 是 | 先从 URL 拉取字节并做 SHA-256 校验(复用已校验缓存),然后把这些精确字节作为 Blob worker(浏览器)/ eval worker(Node)执行——真正的一致性保证 |
precheck-direct-url | URL | 否 | 是(预检) | 先取一次 URL 校验哈希实现 fail-fast,但随后把 URL 直接交给运行时二次拉取执行——两次拉取相互独立,执行的字节并未被校验。注释明确警告:这不是完整性检查,只用于快速暴露配置错误/构建不匹配 |
trusted-direct-url | URL | 否 | 否 | 直接把配置的 worker URL 交给浏览器/Node 运行时加载执行,不做任何 SDK 侧字节校验 |
auto | — | — | — | 若配置了workerUrl则先用verified-blob尝试,失败或未配置则回退embedded-base64 |
理解这五种模式是读懂负向测试的前提:verified-blob是唯一把"校验过的字节"真正交给执行器的模式,因此它必须对 SHA-256 失配负责;trusted-direct-url是唯一"裸 URL"直连模式,因此它对 COOP/COEP 响应头最敏感(详见"负向测试"一节)。
在 scripts/roundtrip.ts 中,模式通过 URL 查询参数mode传入并做白名单校验,随后通过setFhevmRuntimeConfig({ wasmAssetLoadMode, locateFile })注入运行时配置:
const WASM_ASSET_LOAD_MODES = [ 'auto', 'embedded-base64', 'verified-blob', 'precheck-direct-url', 'trusted-direct-url', ]; // ... if (!WASM_ASSET_LOAD_MODES.includes(mode as WasmAssetLoadMode)) { throw new Error(`Unknown wasmAssetLoadMode: ${mode}`); } if (mode === 'embedded-base64' && cdn !== LOCAL_CDN) { throw new Error(`embedded-base64 is incompatible with cdn "${cdn}"`); }非内嵌模式下,资产 URL 由resolveAssetUrls按 CDN 模板渲染,再通过locateFile回调把 SDK 请求的文件名(如tfhe_bg.v1.5.3.wasm、tfhe-worker.v1.5.3.mjs、kms_lib_bg.v0.13.10.wasm)映射到具体 URL;embedded-base64模式则不给locateFile,走 SDK 内嵌资产。
CLI 运行器:按矩阵坐标精确筛选
run.mjs 是整个套件的统一入口,通过 npm scripttest:localstack:multi-wasm:full(见 package.json)调用。其设计思路是"所有标志都是对自动生成矩阵的独立过滤器",省略某个标志即运行该轴上的全部取值:
Usage: npm run test:multi-wasm -- [options] [-- playwright args] Options: --restart-localstack 重启 localstack 后再运行浏览器套件 --fhevm-cli-profile <name> 透传给 localstack-restart.sh 的 profile 文件名 --tfhe <version> 按 TFHE 版本过滤(接受前导 "v") --kms <version> 按 TKMS 版本过滤(接受前导 "v") --mode <mode> 按 wasmAssetLoadMode 过滤 --cdn <cdn> 按 CDN 过滤,默认所有 CDN -h, --help 显示帮助典型用法示例(来自脚本内置帮助文本):
# 全量运行所有矩阵条目 npm run test:localstack:multi-wasm:full # 只跑 tfhe 1.5.3 + kms 0.13.10 的全部条目 npm run test:multi-wasm -- --tfhe 1.5.3 --kms 0.13.10 # 该版本对 + 本地 CDN 的所有加载模式 npm run test:multi-wasm -- --tfhe 1.5.3 --kms 0.13.10 --cdn local # 精确到单个坐标:一个模式 + 一个 CDN npm run test:multi-wasm -- --tfhe 1.5.3 --kms 0.13.10 --mode verified-blob --cdn jsdelivr # 强制重启 localstack 并指定协议 profile npm run test:multi-wasm -- --restart-localstack --fhevm-cli-profile v0.11.0-mainnet.json # 透传 Playwright 参数(如 headed 模式) npm run test:multi-wasm -- --mode auto --cdn local -- --headedCLI 的校验逻辑值得注意:
--mode必须是五种模式之一;--cdn必须存在于matrix.json的assetUrlSets;--mode embedded-base64与--cdn(非 local)互斥,直接报错;--fhevm-cli-profile必须搭配--restart-localstack使用。
解析出的筛选条件会写入环境变量MULTI_WASM_TFHE_VERSION、MULTI_WASM_KMS_VERSION、MULTI_WASM_MODE、MULTI_WASM_CDN、MULTI_WASM_RESTART_LOCALSTACK、MULTI_WASM_FHEVM_CLI_PROFILE,随后以stdio: 'inherit'方式 spawnnpx playwright test --config test/multi-wasm/playwright.config.ts,过滤逻辑在 specs/roundtrip.spec.ts 中通过读取这些环境变量生效。
FHETest 加解密往返页面
页面入口与参数协议
pages/roundtrip.html 加载 scripts/roundtrip.ts,后者是每个矩阵坐标对应的浏览器执行体。测试计划要求"每个测试执行一次加解密往返(与既有 fheTest 文件一致)",页面通过 8 个查询参数描述一个矩阵坐标:
tfhe / kms / mode / cdn / chainName / rpcUrl / mnemonic / fheTestAddress往返主链路
roundtrip.ts的run()按如下顺序执行完整往返(对照既有fheTest测试形态):
- 解析并校验坐标:读取查询参数,校验
mode合法性、embedded-base64 × CDN兼容性,并从/test/multi-wasm/matrix.json加载矩阵、校验tfhe/kms是否为受支持版本对; - 配置运行时:
setFhevmRuntimeConfig({ wasmAssetLoadMode, locateFile, logger }),其中locateFile通过文件名映射表把版本化资产请求路由到 CDN 模板渲染出的 URL,出现未预期的资产请求会直接报错; - 解析链配置:用
import.meta.glob按chainName从test/chains/localstack*.ts动态加载对应链配置,并用 COEP 安全的 Vite 代理地址/__localstack_relayer覆盖relayerUrl(解决 MinIO 问题); - 创建客户端:
createFhevmClient({ chain, provider, options: { moduleVersions } }),其中moduleVersions = { tfhe, kms }显式固定版本(覆盖自动路由,保证测试确定性地落在指定坐标上);await client.ready完成 WASM 模块加载与 worker 启动; - 加密:
client.encryptValues({ contractAddress, userAddress, values: [typedValue] })生成密文与inputProof; - 上链:调用
FHETest.setEuint8(inputHandle, inputProof, clearValue, makePublic)并等待交易收据,receipt.status !== 1即判失败; - 私有解密:
generateTransportKeyPair()生成传输密钥对,signLegacyDecryptionPermit(...)签名解密许可,decryptValues(...)取回明文并断言与原值一致; - 公开解密:若矩阵默认
makePublic: true,再走decryptPublicValues断言公开解密结果; - 输出结果:全部通过时在 DOM 写入
<div id="result">const matrix = loadMatrix(); const entries = selectMatrixEntries(matrix, { tfhe: process.env.MULTI_WASM_TFHE_VERSION, kms: process.env.MULTI_WASM_KMS_VERSION, mode: process.env.MULTI_WASM_MODE, cdn: process.env.MULTI_WASM_CDN, }); for (const [entryIndex, entry] of entries.entries()) { test(`multi-WASM encrypt/decrypt round-trip: ${entry.label}`, async ({ page }) => { // ...构建查询参数,page.goto(roundtrip.html?tfhe=...&kms=...&mode=...&cdn=...) await page.goto(`/test/multi-wasm/pages/roundtrip.html?${query.toString()}`); const result = page.locator('#result'); await result.waitFor({ timeout: 600_000 }); expect(await result.getAttribute('data-status')).toBe('pass'); }); }实现细节与测试计划的对应关系:
- 每个测试一个全新页面:Playwright 默认每个
test()获得独立page与浏览器上下文,天然满足"一个页面无法运行多个 FhevmRuntime、必须 fresh page"的要求; - 套件级进度报告:spec 订阅页面
console消息(前缀[multi-wasm]),并通过ENTRY_PROGRESS_MILESTONES把页面日志行(Matrix entry:→Creating FHEVM client→Encrypting→Private decrypting→Public decrypting→All checks passed)映射为 0~100% 的条目进度,实时打印形如[suite 42.0% | entry 3/8]的进度行;若页面未输出实时日志,则失败时回退打印#log完整内容便于排查; - 600 秒超时:多 WASM 初始化与加密是重计算,
timeout: 600_000与result.waitFor保持一致; - 单 worker 串行:playwright.config.ts 设置
workers: 1、仅 Chromium 项目,保证多个矩阵条目不会互相干扰(也避免同时打爆 localstack)。
Localstack 生命周期:优先复用,按需重启
测试计划强调两点:套件必须对
localstack-restart.sh运行;若 localstack 已在运行则不要重启(非常耗时)。这一策略在三个文件中分层实现:global-setup:启动前就绪检查
global-setup.ts 读取环境变量:
const restart = process.env.MULTI_WASM_RESTART_LOCALSTACK === '1'; const chainName = process.env.CHAIN ?? 'localstack'; const { rpcUrl } = loadLocalstackChainDefaults(chainName); await ensureLocalstackReady({ restart, rpcUrl, chainName, fhevmCliProfile });ensureLocalstackReady:两级判定
support/localstack.ts 的判定逻辑:
- 若
restart=true,先以--force --chain <chainName>(以及可选的--fhevm-cli-profile)运行localstack-restart.sh; - 通过向
rpcUrl发eth_chainIdJSON-RPC POST 检查 anvil 是否存活(isJsonRpcReady); - 若已就绪直接返回;若未就绪且未要求重启,抛出明确错误:"Start it first, or rerun with --restart-localstack";若重启后仍无响应则报"still not responding after restart"。
localstack-restart.sh:守护脚本
scripts/localstack-restart.sh 是守护脚本本体,默认端口
8545、RPChttp://127.0.0.1:8545,支持--force/-f、--chain/-c(localstack、localstack_v11~localstack_v14)、--fhevm-cli-profile、--dry-run/-n等选项。其核心策略与测试计划完全一致:- 默认(无
--force):若 anvil 正在8545端口监听,则只做健康校验——读取chain-defaults.json解析FHETest地址,cast code确认有字节码、cast call CONTRACT_NAME()确认是FHETestv2——全部通过即退出 0,不重启;若端口被非 anvil 进程占用则报错退出;无进程则走完整启动; --force:先fhevm-cli down,再fhevm-cli up [--lock-file profiles/<profile>],然后forge clean并执行./scripts/fhetest-deploy.sh --chain <chain>重新部署 FHETest,最后再次校验部署。
链的 RPC 地址、助记词与 FHETest 合约地址统一维护在 test/chains/chain-defaults.json(
localstack系列默认http://localhost:8545、测试助记词、0x61a8e950...),由 support/chainDefaults.ts 读取;助记词缺省时回退到test/.env或MNEMONIC环境变量(对应测试计划中"localstack 使用专用 RPC URL"的要求,实现上统一收敛到了 chain-defaults.json 与.env)。版本自动路由与测试目标的衔接
虽然 multi-wasm 矩阵用
moduleVersions: { tfhe, kms }显式固定版本,但理解 SDK 的自动路由机制能帮你判断"这些版本为什么需要共存"。自动路由实现在 src/core/runtime/HyperWasmSolver-p.ts,它根据解析出的协议上下文(protocolVersion+pubKeyCrsVersion)命中兼容规则表:协议版本区间 PubKey/CRS 版本 TFHE 版本 TKMS 版本 < 0.13.0< 1.6.01.5.30.13.10[0.13.0, 0.14.0)< 1.6.01.6.20.13.20-0[0.13.0, 0.14.0)>= 1.6.01.6.20.13.20-0>= 0.14.0< 1.6.01.6.20.14.0-1>= 0.14.0>= 1.6.01.6.20.14.0-1该表以
compatibilityRules常量的形式内联在源码中(规则要求区间互斥,否则自动解析直接抛错)。每条规则还声明compatible白名单:例如协议0.13.x下显式指定 TFHE1.5.3仍然合法,但必须通过兼容性检查——src/core/types/moduleVersions.ts 定义了checkCompatibility: 'throw' | 'warn' | 'off'三种策略,throw(默认)在不兼容时直接抛错,warn仅告警,off跳过检查。分辨率优先级(源码注释明确说明):
- 客户端选项
moduleVersions: 'auto'强制走协议自动解析,且故意忽略运行时回退; - 客户端选项
moduleVersions.tfhe/kms优先于一切回退,再对照白名单检查; - 运行时全局配置
moduleVersions作为回退; - 否则从解析出的协议上下文自动解析。
由此可以推出:矩阵测试中显式指定
1.5.3 + 0.13.10与1.6.2 + 0.13.20-0等组合,等价于验证了"同一 JS realm 内、多个协议时代的 WASM 模块必须能够同时存活",而 test/MULTI_WASM_TEST_PLAN.md 则将这一目标细化为专门的共存(coexistence)计划(见下文)。负向测试:留待独立套件的未来工作
测试计划明确将负向测试排除在 happy-path 矩阵之外,作为独立套件的未来工作,并给出两个必须覆盖的场景:
- 无效 KMS SHA:当服务器提供的
kms_lib_bg.wasm字节与期望的 SHA-256 不一致时,wasmAssetLoadMode: verified-blob必须在日志中报SHA-256 mismatch而失败。这直接对应verified-blob"校验后执行"的语义——它是唯一真正把"校验过的字节"交给执行器的模式; - 缺失 COOP/COEP 响应头(本地模式):当托管 worker 脚本的服务器没有设置
Cross-Origin-Opener-Policy: same-origin和Cross-Origin-Embedder-Policy: require-corp(以及/或Cross-Origin-Resource-Policy: same-origin)时,wasmAssetLoadMode: trusted-direct-url必须给出清晰、可操作的错误,而不是当前的通用Worker error;而其余模式(embedded-base64、verified-blob、precheck-direct-url、auto)在同样的"破损响应头"配置下仍应成功——因为它们都把 worker 字节封装进 Blob URL,绕过了 COEP 限制。
这两个场景与 src/core/types/wasmAssets.ts 中五种模式的注释一一对应,可作为实现负向套件时的验收基准。注意负向测试不属于support/matrix.ts 的笛卡尔积生成器,需要独立编排。
延伸:共存(coexistence)与鲁棒性测试
同一目录树下的 test/MULTI_WASM_TEST_PLAN.md 是 multi-wasm 矩阵的姊妹计划,聚焦"同一 JS realm 内多版本模块共存"的更深层能力,与
notes/TEST_PLAN.md互补。它的核心结论之一是生命周期边界:已加载的 WASM 模块应被视为"JS realm 生命周期资源"——TFHE 多线程 worker 启动是每个生成模块版本的一次性操作,终止后再初始化同一版本在同一 realm 中不受支持;因此 SDK 的支持范围是"一个 JS realm 可以在其生命周期内并行运行 N 个受支持版本的给定 WASM 模块",而不支持同 realm 内的卸载/重启/替换。该计划给出了分层测试金字塔(单元 Vitest → Node 集成
worker_threads→ 浏览器 Playwright smoke)和分阶段实施路径(版本路由单测 → 单版本 smoke → Node 双客户端并行共存 → 跨版本污染防护 → 轻量浏览器共存),并提出了资源断言基线:显式配置numberOfThreads(推荐 1 或 2)、每个 TFHE 模块上报精确线程数、多线程场景下浏览器必须crossOriginIsolated === true。其实现在 test/browser-smoke:
- multiWasmHarness.ts 集中了运行时配置(
wasmAssetLoadMode: 'verified-blob'、singleThread: false、numberOfThreads: 1)、双 TFHE(1.5.3、1.6.2)+ 三 TKMS(0.13.10、0.13.20-0、0.14.0-1)模块的并发初始化、就绪断言(threadsAvailable、URL-backed 资产)、dummy 链构造与密钥注入(test/keys/key.1.4.0-alpha.3.json、key.1.5.4.json、key.1.6.1.json)等公共能力; - smoke-coexistence.ts 构造了
(模块版本 × 提供的密钥格式)兼容矩阵(如1.5.3 + key.1.6.1必须失败、1.6.2 + key.1.6.1必须成功),并基于"TFHE-rs 序列化格式向前兼容、不向后兼容"的规律对每个链定义shouldRun期望;随后用Promise.all并发执行全部迷你加密,再按定义顺序做确定性断言; - smoke-coexistence.spec.ts 将显式多线程共存 smoke 限定为 Chromium-only(跨浏览器 smoke 保持单版本/单线程,保证廉价与确定性)。
MULTI_WASM_TEST_PLAN 还规划了四个鲁棒性测试:跨模块对象拒绝(模块 A 的对象不能用于模块 B,且拒绝后两个模块仍健康)、并发幂等初始化风暴(同版本并发 init 必须折叠为单一模块与单一 worker 池——对一次性 TFHE worker 尤其危险)、单槽位缓存竞争与失败后恢复(利用
globalFheEncryptionKeyCache的_pendingChained待定链式合并)、交错轮询耐力(交替使用1.5.3/1.6.2与 TKMS 操作,监测跨模块状态漂移与内存增长,把内存视为高水位预算而非收缩检查)。快速上手:如何运行这套测试
前置条件:仓库已安装依赖(
sdk/js-sdk下npm install),本地可访问test-suite/fhevm的 fhevm-cli 环境与 Foundry(localstack-restart.sh会调用fhevm-cli up/down与forge clean)。# 1. 在 sdk/js-sdk 目录下,全量运行矩阵(localstack 已在跑则自动跳过重启) npm run test:localstack:multi-wasm:full # 2. 单坐标排查:只跑某个版本对 + 某个加载模式 npm run test:localstack:multi-wasm:full -- --tfhe 1.5.3 --kms 0.13.10 --mode verified-blob --cdn local # 3. 需要强制重启 localstack 并指定协议 profile 时 npm run test:localstack:multi-wasm:full -- --restart-localstack --fhevm-cli-profile v0.13.0.json # 4. 浏览器共存 smoke npm run test:browser-smoke运行中可通过 Playwright 控制台观察套件级进度行;失败时页面
#log会给出从矩阵条目、运行时配置、加密、上链、解密到断言的全链路日志,data-status="fail"与堆栈信息会一并回传。参考文件索引
- 测试计划:notes/TEST_PLAN.md、test/MULTI_WASM_TEST_PLAN.md
- 矩阵与 schema:test/multi-wasm/matrix.json、test/multi-wasm/matrix.schema.json
- 矩阵引擎与运行器:test/multi-wasm/support/matrix.ts、test/multi-wasm/run.mjs
- 浏览器往返链路:test/multi-wasm/scripts/roundtrip.ts、test/multi-wasm/specs/roundtrip.spec.ts、test/multi-wasm/playwright.config.ts
- localstack 管理:test/multi-wasm/global-setup.ts、test/multi-wasm/support/localstack.ts、test/scripts/localstack-restart.sh、test/chains/chain-defaults.json
- 加载模式与版本路由:src/core/types/wasmAssets.ts、src/core/runtime/HyperWasmSolver-p.ts、src/core/types/moduleVersions.ts
- 版本兼容表:docs/compatibility.md
- 浏览器共存 smoke:test/browser-smoke/scripts/multiWasmHarness.ts、test/browser-smoke/scripts/smoke-coexistence.ts、test/browser-smoke/specs/smoke-coexistence.spec.ts
- 测试密钥资产:test/keys(
key.1.4.0-alpha.3.json、key.1.5.4.json、key.1.6.1.json)
小结
notes/TEST_PLAN.md所描述的多 WASM 测试计划,在仓库中已经是一套可运行的完整工程:JSON 矩阵驱动、schema 约束、Playwright 浏览器执行、五种wasmAssetLoadMode全覆盖、CDN 资产模板化、CLI 坐标筛选、localstack 智能复用,以及为未来负向测试预留的明确接口。这套设计既回答了"多版本 WASM 如何在真实浏览器中回归验证",也为verified-blob等加载模式的安全性(SHA-256 校验、COOP/COEP 隔离)提供了可观测的验证载体。无论你是要为新版本对扩展矩阵、为某个加载模式定位问题,还是要补全负向测试,都可以从 test/multi-wasm 这个坐标体系出发,按版本对 × 加载模式 × CDN三个维度精确投放测试。【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications
项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm
- 每个测试一个全新页面:Playwright 默认每个
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考