aptos-core replay-benchmark 实战指南:历史交易回放、状态覆盖与执行性能基准测试

发布时间:2026/9/17 21:11:26
aptos-core replay-benchmark 实战指南:历史交易回放、状态覆盖与执行性能基准测试 aptos-core replay-benchmark 实战指南历史交易回放、状态覆盖与执行性能基准测试【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core在 Aptos 核心节点仓库中aptos-move/replay-benchmark模块提供了一个名为aptos-replay-benchmark的命令行工具用于下载链上真实的历史交易、初始化执行输入状态、在修改后的状态上重放比较执行输出并对执行时间进行基准测量。阅读本篇指南后你将掌握该工具download/initialize/diff/benchmark四个子命令的完整用法与参数细节并理解其底层的读集read-set捕获机制、状态覆盖原理以及 Block-STM 并行执行的测量方式从而能够对新的功能开关、Gas 版本或 Move 代码变更在历史负载上做出性能与行为评估。工具概览与模块结构该工具的定义见 Cargo.toml包名aptos-replay-benchmark版本0.1.0描述为 “A tool to replay and locally benchmark on-chain transactions.”。它复用了仓库内的多个核心组件主要依赖包括aptos-block-executor提供 Block-STM 并行执行引擎aptos-vmAptos VM 与AptosVMBlockExecutoraptos-move-debuggeraptos_move_debugger基于 REST 客户端的链上调试/查询能力用于拉取交易与状态aptos-rest-clientfullnode REST API 客户端aptos-gas-scheduleGas 费用表与LATEST_GAS_FEATURE_VERSION。入口程序位于 main.rs用 clap 定义了四个子命令并分发到对应的实现pub enum Command { Download(DownloadCommand), Initialize(InitializeCommand), Diff(DiffCommand), Benchmark(BenchmarkCommand), }四个子命令的完整定义分别位于 commands/download.rs、commands/initialize.rs、commands/diff.rs 和 commands/benchmark.rs。其中download与initialize共享--rest-endpoint Efullnode 的 REST API 查询端点与可选的--api-key K两个参数其结构体定义在 commands/mod.rs。build_debugger函数会用这些参数构造AptosDebugger一个基于 REST 客户端的查询器API key 的作用是提升 HTTP 请求的速率限制配额。常见的 REST 端点示例devnet:https://api.devnet.aptoslabs.com/v1testnet:https://api.testnet.aptoslabs.com/v1mainnet:https://api.mainnet.aptoslabs.com/v1命令一download —— 下载历史交易download命令用于从链上按版本区间下载交易并保存到本地文件。参数说明参数含义--begin-version B版本区间起点含--end-version E版本区间终点不含半开区间[B, E)--transactions-file T交易保存的本地文件路径--rest-endpoint Efullnode REST API 端点--api-key K可选提升请求配额示例摘自 READMEaptos-replay-benchmark download \ --begin-version 2232125001 \ --end-version 2232125093 \ --rest-endpoint https://api.mainnet.aptoslabs.com/v1 \ --transactions-file transactions.file成功后输出Got 93/93 txns from RestApi. Downloaded 12 blocks with 93 transactions in total: versions [2232125001, 2232125093)为什么必须是整块区间下载的后续基准测试是按“块”为单位、由执行器逐个块执行的因此要求指定区间必须恰好覆盖若干完整的块不能只下载某块中的前几笔交易。从源码可以看到这一约束的两道校验download.rs区间第一笔交易必须是块起点txn.is_block_start()不成立则报 “First transaction … must be a block start”区间最后一笔end_version - 1之后必须紧跟块起点否则报 “All transactions in the block must be selected”。此外版本参数本身也要满足begin_version end_versiondownload.rs。下载完成后交易会被partition函数按块切分为TransactionBlock每个块记录begin_version、交易列表及其辅助信息并用 BCS 序列化写入文件download.rs。块切分逻辑有单元测试覆盖例如 download.rs 中的test_block_partition_1/2/3验证了以BlockMetadata交易为界正确切分块、并正确累计begin_version的行为。命令二initialize —— 初始化基准测试的输入状态要对历史交易做基准测试还需要准备每个块的“执行前状态”。initialize命令负责下载并生成这些输入状态。参数参数含义--transactions-file Tdownload生成的交易文件--inputs-file I输入状态保存的文件--rest-endpoint E必须与 download 使用同一网络的端点--api-key K可选提升请求配额--log-level L日志级别默认Error示例aptos-replay-benchmark initialize \ --rest-endpoint https://api.mainnet.aptoslabs.com/v1 \ --transactions-file transactions.file \ --inputs-file baseline-state.file输出逐块报告进度Generated inputs for block 1/12 in 8s Generated inputs for block 2/12 in 9s ... Generated inputs for block 12/12 in 25s读集捕获原理。输入状态为“每个块”生成一份当每个块被执行时它都运行在这份预计算的状态之上因此不存在块执行结果的 “commit”。具体实现在 generator.rsInputOutputDiffGenerator::generate为每个块派生一个阻塞任务并行生成输入块间相互独立单块内部的交易执行是顺序的。generate_inputsgenerator.rs的流程是通过debugger.state_view_at_version(begin_version)获取块执行前的链上状态视图应用状态覆盖如有见下一节先用原始状态执行一遍并检查链上输出是否会写被覆盖的键若写入被覆盖的状态则基准结果可能失真会打error!日志再在带覆盖的状态视图上执行一遍用ReadSetCapturingStateView记录所有读取到的StateKey - StateValue最终沉淀为ReadSet。ReadSet与捕获视图定义在 state_view.rsReadSet是一个HashMapStateKey, StateValue实现了TStateView接口命中键返回ColdOccupied槽位、未命中返回ColdVacantget_usage在基准场景下不可调用unreachable!。捕获视图ReadSetCapturingStateView在首次访问某个键时把状态值记入读集若 REST 拉取失败则直接 panic——注释中解释了原因读集一旦缺读基准结果就不再正确。另外视图初始化时会预加载aptos_cached_packages::head_release_bundle()中的框架模块以避免并行执行的投机读取在 VM 序言中找不到0x1::error等基础模块。关于 HTTP 429 限流。状态初始化通过执行交易来捕获每个块的读集读多时可能触发 REST API 的速率限制表现为大量HTTP error 429 Too Many Requests的错误日志如Failed to fetch state value for StateKey::AccessPath { ... }甚至线程 panicFailed to fetch state value ... receiving on a closed channel。解决办法是在 Aptos Build 中创建 API key 来提升配额然后给工具加--api-key K参数。覆盖状态在历史负载上试验新特性initialize命令支持四类状态覆盖参数定义见 initialize.rs强制启用功能开关--enable-features F1 F2 ...强制禁用功能开关--disable-features F1 F2 ...强制覆盖 Gas 特性版本--gas-feature-version V覆盖现有链上包--override-packages P1 P2 P3参数为 Move 包的源码目录路径。功能开关需使用大写名称例如ENABLE_LOADER_V2完整的功能开关列表定义在 aptos_features.rs。启用/禁用两个列表不能重叠overrides.rs 会显式校验--gas-feature-version若大于LATEST_GAS_FEATURE_VERSION会给出警告overrides.rs且源码注释说明目前只支持带 feature version 的 V2 Gas 费用表。覆盖的底层实现集中在 overrides.rs。OverrideConfig::get_state_override返回一个HashMapStateKey, StateValue作为状态视图的覆盖层功能开关读取链上Features配置资源逐条enable/disable后重新序列化替换对应状态键的值对已经处于目标状态的开关会打error!日志Gas 版本读取链上GasScheduleV2配置直接修改feature_version字段后写回包覆盖以BuildOptions::move_2()编译本地包按包地址找到链上PackageRegistry资源并替换/追加对应包的元数据再把每个模块的字节码序列化为StateKey::module(...)的覆盖值同一模块被重复覆盖会 panic。典型场景如果有一个新特性或新版 Move 代码能让 MoveVM 更快把它覆盖到历史交易的执行状态上就能在真实历史负载上观察执行性能与 Gas 使用的变化。示例——在 baseline 之外额外启用ENABLE_CALL_TREE_AND_INSTRUCTION_VM_CACHE开关生成一份实验状态aptos-replay-benchmark initialize \ --rest-endpoint https://api.mainnet.aptoslabs.com/v1 \ --transactions-file transactions.file --enable-features ENABLE_CALL_TREE_AND_INSTRUCTION_VM_CACHE \ --inputs-file experiment-state.file命令三diff —— 比较两种状态下的执行输出覆盖状态可能改变执行行为。diff命令把同一批交易分别在两个输入状态上执行并比较输出。参数参数含义 / 默认值--transactions-file T交易文件--inputs-file I1第一份输入状态文件--other-inputs-file I2第二份输入状态文件--concurrency-level L计算 diff 时 Block-STM 执行交易的线程数默认1顺序执行--allow-different-gas-usage为true时Gas 相关差异不计入比较diff 的实现要点commands/diff.rs对两份输入状态分别调用compute_outputs各自用AptosVMBlockExecutor::new_with_local_config(local_config(concurrency_level))执行所有块逐块打印 CSV 形式的 Gas 汇总block, {I1} (gas), {I2} (gas)对每笔交易用TransactionDiffBuilderallow_different_gas_usage决定是否忽略 Gas 差异构造 diff非空的以Non-empty output diff for transaction {version}:开头逐条打印。比较维度由 diff.rs 的Diff枚举界定分为四类GasUsedGas 用量、ExecutionStatus执行状态重放时应保持一致、Event事件、WriteSet写集按StateKey比较WriteOp。打印输出采用 BEFORE// AFTER的三行块格式并用彩色高亮区分前后值。示例aptos-replay-benchmark diff \ --transactions-file transactions.file \ --inputs-file baseline.state \ --other-inputs-file experiment-state.file \ --allow-different-gas-usage此时控制台以 CSV 形式打印两个状态的每块 Gas 用量block, baseline.state (gas), experiment.state (gas) 1, 35, 35 2, 26, 26 ... 11, 622, 622 12, 2076, 2071理想情况下差异应当很小说明覆盖没有改变历史交易的行为。如果覆盖让交易变便宜所有交易行为一致输出差异通常只体现在Gas 用量、交易费用事件FeeStatement、代币总供应量费用被烧毁、以及费用支付者余额。若不提供--allow-different-gas-usagediff 还会把每处差异完整打印出来例如Non-empty output diff for transaction 2232125041: BEFORE gas_used: 59 gas_used: 58 AFTER BEFORE event 0000000000000000000000000000000000000000000000000000000000000001::transaction_fee::FeeStatement data: [59, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] event 0000000000000000000000000000000000000000000000000000000000000001::transaction_fee::FeeStatement data: [58, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] AFTER BEFORE write StateKey::AccessPath { address: 0x68c7..., path: Resource(0x1::coin::CoinStore0x1::aptos_coin::AptosCoin) } op Modification(5ca5adc5..., metadata:StateValueMetadata { ... }) write StateKey::AccessPath { address: 0x68c7..., path: Resource(0x1::coin::CoinStore0x1::aptos_coin::AptosCoin) } op Modification(c0a5adc5..., metadata:StateValueMetadata { ... }) AFTER BEFORE write StateKey::TableItem { handle: 1b854694..., key: 0619dc29... } op Modification(aa8dd92120d693010000000000000000, metadata:StateValueMetadata { inner: None }) write StateKey::TableItem { handle: 1b854694..., key: 0619dc29... } op Modification(0e8ed92120d693010000000000000000, metadata:StateValueMetadata { inner: None }) AFTER Non-empty output diff for transaction 2232125042: ...上例中唯一差异是 Gas 相关覆盖让块执行变便宜配合--allow-different-gas-usage后即可确认行为等价。命令四benchmark —— 执行测量与统计benchmark命令在保存的状态上执行保存的交易并测量时间。参数定义见 commands/benchmark.rs参数含义 / 默认值--transactions-file T交易文件--inputs-file I每个块的输入状态文件--num-blocks-to-skip N前 N 个块不计入测量但仍会执行用作 warm-up默认0--concurrency-levels L1 L2 ...Block-STM 执行单个块的线程数列表必填且至少一个--num-repeats N每个并发级别重复执行的次数默认3最少3--measure-overall-timetrue时测量所有块的总时间否则逐块测量--disable-paranoid-modetrue时 Move VM 不做运行时类型检查可能更快--async-runtime-checkstrue时 Move VM 追踪执行、Block-STM 事后校验--log-level L日志级别默认Error测量机制的关键约束[commands/benchmark.rs](https://link.gitcode.com/i/a2bf5f6195cd8569190588a4d0e573ac#L19-L20, L88-L118)MIN_NUM_REPEATS常量固定为 3重复次数小于 3 直接报错 “Number of repeats must be at least 3”并发级别列表不能为空否则报 “At least one concurrency level must be provided”交易块数量与输入状态数量必须一致--num-blocks-to-skip不能大于等于总块数。从源码结构看每个并发级别下每一轮 repeat 都会新建一个AptosVMBlockExecutorrunner.rs逐块执行并用Instant::now()计时微秒。逐块模式下仅对idx num_blocks_to_skip的块输出统计对每块N次计时排序后打印median (us), mean (us), min (us), max (us)四列CSV 表头为concurrency level, block, median (us), mean (us), min (us), max (us)总时间模式则先执行前num_blocks_to_skip个块作 warm-up再对剩余块整体计时runner.rs。并发级别指定 Block-STM 执行一个块所用的线程数通常应接近 CPU 核心数提供多个级别时工具会为每个级别分别报告测量值便于观察并行度对执行时间的影响。执行引擎配置。无论 benchmark 还是 diff执行器都使用同一份本地配置execution.rsBlockExecutorLocalConfig { blockstm_v2: true, // 使用 Block-STM v2 concurrency_level, // 由命令行传入 allow_fallback: true, // 允许回退 discard_failed_blocks: false, module_cache_config: ..., enable_pre_write: true, // 启用预写 }执行时块执行配置使用BlockExecutorConfigFromOnchain::on_but_large_for_test()无块限制且execute_workload断言块执行不应失败——因为重放的是已经成功上链的历史交易。测量口径说明。两点值得注意一是基准测试中没有块执行输出的 “commit”状态每次都从预计算读集读取二是签名验证在执行之前完成不计入报告时间。另外--disable-paranoid-mode通过set_paranoid_type_checks(!disable_paranoid_mode)关闭 Move VM 的运行时类型检查commands/benchmark.rs可换取更快的执行速度。示例基线对比实验同一批交易ENABLE_CALL_TREE_AND_INSTRUCTION_VM_CACHE关闭aptos-replay-benchmark benchmark \ --transactions-file transactions.file \ --inputs-file baseline-state.file \ --num-blocks-to-skip 2 \ --concurrency-levels 4 \ --num-repeats 31打印 10 个块的测量结果跳过了前 2 个块concurrency level, block, median (us), mean (us), min (us), max (us) 4, 2, 10701, 11137.74, 10170, 22922 4, 3, 11678, 11949.84, 11459, 20218 4, 4, 5341, 5348.23, 5164, 5616 4, 5, 53871, 54126.52, 53237, 58044 4, 6, 16334, 16314.32, 15856, 16596 4, 7, 7845, 7844.77, 7634, 8032 4, 8, 13140, 13113.45, 12854, 13521 4, 9, 127062, 117830.45, 70342, 169842 4, 10, 6305, 6343.45, 5860, 7042 4, 11, 51917, 51963.16, 51508, 53646同一交易在启用ENABLE_CALL_TREE_AND_INSTRUCTION_VM_CACHE的状态experiment-state.file上重放aptos-replay-benchmark benchmark \ --transactions-file transactions.file \ --inputs-file experiment-state.file \ --num-blocks-to-skip 2 \ --concurrency-levels 4 \ --num-repeats 31可以看到部分块出现了加速如第 5 块中位时间从 53871us 降到 44129us第 11 块从 51917us 降到 42064usconcurrency level, block, median (us), mean (us), min (us), max (us) 4, 2, 11102, 12927.03, 10705, 42065 4, 3, 11733, 12226.06, 11494, 20036 4, 4, 5400, 5476.61, 5259, 6343 4, 5, 44129, 45534.39, 43544, 61366 4, 6, 16373, 16173.23, 10992, 23235 4, 7, 8086, 9900.55, 7799, 35909 4, 8, 12986, 13318.58, 9773, 25228 4, 9, 127551, 124062.03, 71639, 229356 4, 10, 6468, 6828.61, 5964, 11862 4, 11, 42064, 43327.74, 41656, 68311完整工作流小结将四个命令串联起来一次完整的“历史负载回放 实验对比”流程是download选定覆盖整块的版本区间从目标网络拉取交易到transactions.fileinitialize用同一网络端点生成 baseline 状态baseline-state.file如需实验再带--enable-features/--disable-features/--gas-feature-version/--override-packages生成experiment-state.filediff比较两份状态的执行输出用--allow-different-gas-usage过滤纯 Gas 差异确认覆盖没有改变交易行为benchmark分别对两份状态测量执行时间通过--concurrency-levels观察并行度影响通过--num-blocks-to-skip消除冷启动噪声通过--num-repeats≥3取得中位数/均值/最小/最大时间。需要牢记的适用前提与限制版本区间必须对齐整块initialize与download必须使用同一网络的 REST 端点基准测量不含块提交成本签名验证也在计时之外因此测得的是纯执行侧耗时若覆盖的状态键恰好被历史交易写入生成器会打错误日志提示基准结果可能失真。基于源码中的 TODOinitialize.rsGas 费用表覆盖与不同切块策略的实验支持仍在规划中。掌握以上用法与底层机制后你即可在aptos-core内对任何影响执行路径的改动功能开关、Gas 版本、包字节码建立可复现的历史负载性能基线。【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询