FEATURED · 精选文章

BSC 节点 RPC 负载测试工具实战:深入解析 cmd/workload 的原理、用法与测试用例再生成

发布时间 / 2026/9/18 14:44:47
来源 / 创域科博编辑部
栏目 / 资讯中心
BSC 节点 RPC 负载测试工具实战:深入解析 cmd/workload 的原理、用法与测试用例再生成 BSC 节点 RPC 负载测试工具实战深入解析 cmd/workload 的原理、用法与测试用例再生成【免费下载链接】bscA BNB Smart Chain client based on the go-ethereum fork项目地址: https://gitcode.com/GitHub_Trending/bs/bsc本文面向 BSCBNB Smart Chain客户端开发者与节点运维人员完整讲解本仓库 cmd/workload 目录下的 Workload Testing Tool它如何对一个在线节点发起真实 RPC 调用并验证结果正确性如何针对 Sepolia 测试网与主网执行三类自动化测试日志过滤、历史数据检索、状态追踪以及如何利用filtergen、historygen、tracegen三个子命令从链上重新生成测试数据包括为全新网络生成测试集。读完本文你将掌握该工具的完整命令行用法、各子命令与参数的含义、测试用例文件的数据格式以及底层实现细节可直接用于 BSC 节点的功能验证与回归测试。工具定位用真实 RPC 调用验证节点行为Workload Testing Tool 是一个通过 RPC 协议对运行中的节点进行行为验证的测试工具。它并非单元测试而是把节点当作被测对象工具构造真实的eth_*系列 RPC 请求并发送到指定端点再把返回结果与预先录制的标准答案如区块哈希、收据哈希、日志结果哈希、trace 结果哈希逐一比对从而判断节点实现是否正确。从源码看cmd/workload/main.go 使用urfave/cli框架构建命令行入口共注册了 6 个子命令子命令用途test对 RPC 端点执行负载/功能测试主命令filtergen生成日志过滤log filter测试查询集historygen生成历史数据检索测试tracegen生成状态追踪trace测试filterperf对 RPC 端点执行日志过滤性能测试filterfuzz生成查询并对照 receipts 推导结果做模糊校验值得注意的是工具内置了两套测试数据Sepolia 测试网与主网Mainnet。其中主网测试数据通过 Go 的embed机制直接编译进二进制见 cmd/workload/testsuite.go 中的//go:embed queries与builtinTestFilesSepolia 测试数据则从当前工作目录加载。因此运行方式也略有差异下文会详细说明。重要前提所有测试都要求被测节点已完成完全同步fully synced否则测试样本如某些区块号、交易哈希可能不存在导致测试失败。快速上手编译与首次运行workload 是一个标准 Go 命令行程序位于仓库根目录cmd/workload下可直接用go run运行也可先编译成二进制# 方式一直接运行在仓库根目录 go run ./cmd/workload test --sepolia http://host:8545 # 方式二先编译再运行推荐便于重复执行 go build -o workload ./cmd/workload ./workload test --sepolia http://host:8545其中http://host:8545是节点的 RPC 端点地址替换为你的节点实际地址例如http://127.0.0.1:8545。若未提供端点地址程序会直接报错退出missing RPC endpoint URL as command-line argument见 cmd/workload/client.go 的makeClient。运行后会看到类似go test的输出风格每个测试用例一行显示用例名、耗时与通过/失败状态若有失败用例进程以退出码 1 结束见 cmd/workload/testsuite.go 的runTestCmd方便 CI 集成。test 子命令完整参数详解test是核心子命令其完整参数定义于 cmd/workload/testsuite.go如下参数类型说明RPC endpoint URL位置参数被测节点的 RPC 地址必填--sepoliabool使用 Sepolia 网络的测试用例--mainnetbool使用主网测试用例内置--run patternstring按模式过滤要运行的测试套件/用例语法与go test -run类似--archivebool启用需要归档节点完整历史状态的测试默认关闭--slowbool启用慢速测试耗时较长的用例默认关闭--tapbool以 TAPTest Anything Protocol格式输出测试结果--queries filestring指定日志过滤查询文件默认为filter_queries.json--history-tests filestring指定历史测试文件默认为history_tests.json--trace-tests filestring指定 trace 测试文件默认为trace_tests.json--trace-invalid dirstring指定目录用于保存 trace 结果不匹配时的详细输出文件几个关键设计从源码可确认网络选择互斥--mainnet与--sepolia不能同时使用cmd/workload/testsuite.go 中flags.CheckExclusive强制校验。选了--mainnet后不能再用--queries指定自定义查询文件二者同样互斥。主网数据内置、Sepolia 数据读盘--mainnet分支从二进制内嵌的builtinTestFiles读取queries/filter_queries_mainnet.json、queries/history_mainnet.json、queries/trace_mainnet.json未指定网络时程序以当前目录os.DirFS(.)为文件系统读取用户通过--queries等参数指定的文件。用例分级过滤每个测试用例在注册时被标记为普通、慢速Slow或归档archive。--slow与--archive未打开时对应的用例会被跳过cmd/workload/testsuite.go 的filterTests。例如--run History/getBlockBy这类模式只在匹配的用例中做子集筛选。日志静默除非显式传入--verbosity或--vmodule否则测试期间关闭日志输出避免干扰结果cmd/workload/testsuite.go。过滤已剪枝历史错误码 4444节点开启历史剪枝后访问剪枝点之前的区块会返回特殊 RPC 错误。工具对此做了专门处理cmd/workload/testsuite.go 的validateHistoryPruneErr若错误码为4444且被访问的区块号未超过剪枝阈值则视为正常跳过errPrunedHistory用例不报错若超过阈值仍返回剪枝错误则判定为节点实现异常。这意味着 workload 测试同样适用于启用历史剪枝的快照节点只是历史越深跳过的断言越多。三类测试套件Filter、History 与 TracerunTestCmd会把三类套件的全部用例合并后统一执行cmd/workload/testsuite.go./workload test --sepolia http://host:85451. Filter日志过滤测试对应 cmd/workload/filtertest.go验证eth_getLogsFilterLogs类查询的正确性。套件内包含三个用例Filter/ShortRange查询区间长度 ≤ 10000 个区块的日志过滤常量filterRangeThreshold 10000。Filter/LongRange查询区间长度 10000 个区块的日志过滤标记为慢速用例需要--slow。Filter/FullRange把每个查询的区间从创世块0一直延伸到最新latest块再在客户端侧过滤出原区间内的日志做比对该用例同样需要--slow且只对原区间超过最新块号一半的查询执行见filterFullRange的实现。每个查询的结构为对应filterQuery结构体见 cmd/workload/filtertest.go{ fromBlock: 329160, toBlock: 7369873, address: [0x7451ee8eecf3b8534fa07b15b4b5cee4bcc88778], topics: [ [0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925], [0x00000000000000000000000023c276729c2dc6ea306a5ac9b270598ce5ff2b37] ], resultHash: 0x25db53749138a4c37510a0805ae166c507f3acae2ab12a530deae7655f2823f8 }校验机制非常巧妙工具并不直接存储期望的日志列表而是存储结果哈希resultHash。执行查询时工具把节点返回的日志列表做 RLP 编码后计算 Keccak-256 哈希calculateHash与文件中的resultHash比对。这样既避免了海量日志数据的存储又能精确校验顺序与内容。另外topics支持通配null表示该 topic 位不限、多地址与多 topic 值的 OR 语义生成时也会刻意构造这些边界情况。每次查询调用带 30 秒超时cmd/workload/filtertest.go 的run方法长时间运行时会定期打印进度日志。2. History历史数据检索测试对应 cmd/workload/historytest.go验证 8 个常用历史读取 RPC 接口每个接口一个用例用例名校验内容History/getBlockByHash按哈希取区块校验哈希与块号一致History/getBlockByNumber按块号取区块校验哈希与块号一致History/getBlockReceiptsByHash按哈希取收据比对收据列表 RLPKeccak 哈希History/getBlockReceiptsByNumber按块号取收据同样比对收据哈希History/getBlockTransactionCountByHash按哈希取区块交易数与期望txCounts比对History/getBlockTransactionCountByNumber按块号取区块交易数比对txCountsHistory/getTransactionByBlockHashAndIndex取指定索引的交易校验交易哈希与索引History/getTransactionByBlockNumberAndIndex同上但用块号定位测试样本文件以 cmd/workload/queries/history_sepolia.json 为例是一组等长的并行数组{ blockNumbers: [0, 3891, 7782, 11673, ...], blockHashes: [0x25a5cc10..., ...], txCounts: [0, 0, 0, ...], txHashIndex: [0, 0, 0, ...], txHashes: [null, null, null, ...], blockReceiptsHashes: [0x1dcc4de8..., ...] }blockNumbers/blockHashes从链头到链尾均匀抽样的区块Sepolia 样本从块 0 开始步长约 3891 块。txCounts每个样本块的交易数。txHashIndex/txHashes若样本块非空记录其中间索引处len(txs)/2交易的哈希用于交易检索校验空块对应null用例直接跳过。blockReceiptsHashes整块收据 RLP 编码后的 Keccak 哈希calcReceiptsHash见 cmd/workload/historytestgen.go空块时即为空收据列表的哈希如 Sepolia 早期的0x1dcc4de8...。3. Trace状态追踪测试需要归档节点对应 cmd/workload/tracetest.go套件内只有一个用例Trace/Block它通过gethclient的TraceBlock对样本区块执行状态追踪并把追踪结果 JSON 序列化后取 Keccak 哈希与文件中的resultHashes比对。由于区块状态追踪需要读取该区块高度上的历史状态要求被测节点是保留全部历史状态的归档节点archive node因此该用例被标记为archive必须显式加上--archive才会执行./workload test --sepolia --archive --run Trace/Block http://host:8545若某区块的 trace 结果与期望哈希不一致工具默认只报错搭配--trace-invalid dir时会把不匹配的完整结果以 JSON 文件写入指定目录文件名形如invalid_blockhash便于人工定位差异见 cmd/workload/tracetest.go 的writeInvalidTraceResult。用 --run 精选用例--run的过滤语义与go test -run一致用正则/子串匹配用例全名。例如只跑区块检索与日志过滤./workload test --sepolia --run History/getBlockBy http://host:8545重新生成测试数据filtergen / historygen / tracegen测试数据并非一成不变——工具提供了从链上重新生成测试集的三个子命令对应 cmd/workload/filtertestgen.go、cmd/workload/historytestgen.go、cmd/workload/tracetestgen.go。这一步同样要求目标节点已完全同步且要使用被测试网络对应高度的数据。原文档以重建主网测试集为例在cmd/workload目录下执行go run . filtergen --queries queries/filter_queries_mainnet.json http://host:8545 go run . historygen --history-tests queries/history_mainnet.json http://host:8545 go run . tracegen --trace-tests queries/trace_mainnet.json --trace-start 4000000 --trace-end 4000100 http://host:8545filtergen随机生成日志过滤查询集filtergen会持续不断地生成随机过滤查询并逐一执行验证把结果哈希与查询参数存入输出文件默认--queries指定的 JSON 文件每 10 秒写盘一次。其生成策略cmd/workload/filtertestgen.go值得展开随机种子查询newSeedQuery随机挑一个未最终化finalized 之前的区块查询该单块的全部日志。合并查询newMergedQuery随机取两条已生成的查询将其地址与 topic 条件按 OR 语义合并构造更宽的过滤条件。收窄查询newNarrowedQuery随机取一条已生成查询从它的已知结果日志中抽取地址或 topic 补进空位让条件更精确。区间扩展extendRange以一定概率把查询区间向两侧扩展覆盖更大区块范围。生成的查询按结果密度分入 10 个桶filterBuckets每个桶最多 100 条maxFilterBucketSize保证测试集对高/低命中率的查询都有覆盖单条查询结果超过 1000 条maxFilterResultSize的会被丢弃避免响应过大。historygen按链头均匀抽样区块historygen从--earliest默认 0到最新块之间均匀抽取约 2000 个样本块常量historyTestBlockCount为每个样本块记录块哈希、交易数、中间交易哈希与收据哈希最终写入--history-tests指定的 JSON 文件。若节点未同步最新块不足 2000程序直接报错退出。生成的格式即上文 history 测试样本的格式可用来刷新现有测试集或为新区块高度补充样本。tracegen按块号区间批量执行追踪tracegen对--trace-start含到--trace-end不含之间的每个区块执行一次状态追踪追踪配置是随机挑选的cmd/workload/tracetestgen.go 的randomTraceOption10% 概率使用默认 struct-logger 配置structDefault记录栈与存储20%~30% 概率使用禁用栈记录的 struct-loggerstructStorage只记录存储其余概率使用原生 tracercallTracer、4byteTracer、flatCallTracer、muxTracer、noopTracer、prestateTracer六选一。每个成功追踪的区块记录其哈希、所用 tracer 配置与结果哈希还可以用--trace-output dir把每个区块的完整追踪结果按配置名_块哈希命名写入目录便于人工审查。区块范围、同步状态等参数不合法时如 start ≥ end、end 超过最新块程序会直接报错。进阶工具filterperf 与 filterfuzz除了录制-回放式测试工具还提供两个动态分析子命令filterperf对查询集中的每条过滤查询连续执行 3 轮常量passCount统计每轮耗时并计算中位数用于评估节点日志过滤接口的性能表现cmd/workload/filtertestperf.go。filterfuzz在链头附近最大区间 300 块持续生成过滤查询并不依赖预录哈希而是把节点返回的日志与从区块 receipts 中手工推导出的匹配结果做交叉比对cmd/workload/filtertestfuzz.go可用来发现节点过滤逻辑与收据数据不一致的深层问题。在 BSC 客户端上的使用建议综合文档与源码使用 workload 工具的典型流程是准备一个已完全同步的 BSC 节点开启 HTTP RPC如--http --http.addr 0.0.0.0 --http.port 8545。要跑 trace 测试还需以归档模式保留完整历史状态。用go build -o workload ./cmd/workload编译工具。先跑基础用例./workload test --sepolia --run History http://host:8545。逐步放开加--slow跑长区间日志过滤加--archive跑状态追踪。若测试网络是全新的或链高度远超内置样本用filtergen/historygen/tracegen在可信节点上重新生成测试文件放入 cmd/workload/queries 并注意与--sepolia/--mainnet的加载约定匹配主网文件需内嵌Sepolia 文件从工作目录读取。将 workload 接入 CI配合--tap输出与退出码判定实现节点每次构建后的自动化回归验证。整体而言cmd/workload把对在线节点做黑盒 RPC 正确性验证这件事做成了可复用、可再生成的工具链filtergen/historygen/tracegen负责从可信链数据采集期望结果test负责对任意节点含剪枝节点、归档节点做一致性校验filterperf/filterfuzz则补充了性能度量与动态交叉验证是 BSC 客户端开发与运维中一套实用的质量保障手段。【免费下载链接】bscA BNB Smart Chain client based on the go-ethereum fork项目地址: https://gitcode.com/GitHub_Trending/bs/bsc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻