Anoma 透明交易执行报 “Root does not exist“ 怎么排查?

Anoma 透明交易执行报 “Root does not exist“ 怎么排查? Anoma 透明交易执行报 Root does not exist 怎么排查【免费下载链接】anoma-archiveReference implementation of Anoma项目地址: https://gitcode.com/GitHub_Trending/an/anoma-archive当你在 Anoma 节点上用 transparent_resource 后端执行一笔透明交易日志中出现Transaction verification failed. Reason: Root does not exist: ...这类错误时说明这笔交易引用了节点中不存在的 root。这篇文章基于 anoma-archive 仓库的真实代码与自带示例说明这个报错的产生位置、如何复现、如何对照存储中的 roots 列表定位问题以及如何与相邻的几种执行错误区分开。前提是你已经能按 USAGE.md 的方式用iex -S mix启动项目mix.exs 要求 Elixir~ 1.17。这个报错从哪里来报错字符串只在 backends.ex 中产生。执行入口是execute/4先把交易代码跑在 Anoma VM 上再按后端类型走backend_logic/4其中:transparent_resource进入transparent_resource_tx/3。该函数依次做TTransaction.from_noun(result)还原交易并TTransaction.verify(tx)校验从三个透明命名空间读当前状态[anoma, transparent, commitments]、[anoma, transparent, nullifiers]、[anoma, transparent, roots]读不到时分别默认为空集合和空列表read_with_default/4storage_check/3检查 nullifier 与 commitment 是否与已存储的重复verify_tx_root/2检查 root 是否存在。verify_tx_root/2调用roots_exist?/2见 backends.ex遍历交易的每个 action把其中每个 compliance unit 的TCU.roots/1汇总成集合再要求每个 root 都能在存储的 roots 列表里找到按Noun.equal?/2比较。任何一个找不到就返回{:error, Root #{inspect(root)} is absent}最终包装成{:error, Root does not exist: msg}见 backends.ex。校验失败时transparent_resource_tx/3通过Logging.log_event/3打出一条:error级别事件消息形如Transaction verification failed. Reason: Root does not exist: Root ... is absentbackends.ex随后该交易以:error结束并写入CompleteEvent。两个直接推论完整错误消息里带inspect(root)可以直接看出缺的是哪一个 root存储的 roots 列表初始为空列表每笔成功提交的透明交易会把自己的 commitment 累积器值TAcc.value(...)追加写回[anoma, transparent, roots]backends.ex。所以交易引用的 root 必须由此前已提交的透明交易产生过否则本次校验必然失败。复现用仓库自带的失败示例lib/examples/e_transaction.ex 里的submit_failed_trivial_swap/1就是针对这个报错的复现路径启动交易模块后提交trivial_transparent_transaction_no_eph()即ENock.transparent_core(ENock.trivial_swap_no_eph())执行并断言日志中出现Root does not existspec submit_failed_trivial_swap(String.t()) :: String.t() def submit_failed_trivial_swap(node_id \\ Node.example_random_id()) do start_tx_module(node_id) code trivial_transparent_transaction_no_eph() EventBroker.subscribe_me([]) log capture_log(fn - Mempool.tx(node_id, code) Mempool.execute(node_id, Mempool.tx_dump(node_id)) recieve_logger_failure(node_id, Root does not exist) end) assert log ~ Root does not exist || log node_id end对照的成功路径是同文件的submit_successful_trivial_swap/1e_transaction.ex提交trivial_transparent_transaction()ENock.transparent_core(ENock.trivial_swap())后不报错并能从存储中读出 roots、nullifiers、commitments。运行方式有两条均来自仓库文档按 USAGE.md 的节点启动方式在仓库根目录执行iex -S mix然后调用Anoma.Node.Examples.ETransaction.submit_failed_trivial_swap()。它内部会自行创建节点start_tx_module/1调用ENode.start_node(node_id: node_id)默认生成随机node_id。注意node_id、grpc_port等每次启动都会变化USAGE.md 里展示的结构%Anoma.Node.Examples.ENode{grpc_port: 58447, pid: ..., node_id: 2615099}只是文档示例输出。跑测试Makefile 的test目标就是mix test而 test/transaction_test.exs 通过TestHelper.GenerateExampleTests, for: Anoma.Node.Examples.ETransaction把上面所有示例函数逐个生成测试用例因此mix test test/transaction_test.exs会覆盖submit_failed_trivial_swap。一个容易误判的细节源码注释原样说明日志可能为空因为Anoma.Node.Logging尚未写完日志条目所以断言是log ~ Root does not exist || log 。复现时如果没看到这条日志先确认节点已执行完该轮Mempool.execute/2不要立刻下结论说没有触发。排查对照存储中的 roots 列表定位思路就是让交易引用的 root和节点里实际存储的 root两者对得上从错误消息里取出缺失的 rootRoot ... is absent中的值是inspect/1的结果。用 e_transaction.ex 示例里的reserve_and_do/4模式读存储先Ordering.reserve/3登记读集再Ordering.read/2。成功路径示例中读取 roots 键的断言是assert {:ok, [Anoma.RM.Transparent.Primitive.CommitmentAccumulator.value(cms)]} reserve_and_do(:read, node_id, id2, key: [anoma, transparent, roots] )这是示例代码片段取自submit_successful_trivial_swap/1首笔成功的 trivial swap 之后roots 列表中应恰好包含该交易 commitment 集合的CommitmentAccumulator.value。把交易每个 action 中各 compliance unit 的TCU.roots/1汇总与读出的列表逐一比对。凡是引用了列表中不存在的 root 的就是触发本错误的位置该 root 需要由此前已提交的透明交易产生并写入[anoma, transparent, roots]后才可能被引用。注意读取要按示例的 tx 流程走Ordering.reserve/3Ordering.read/2读用的tx_id要选在水位之后的交易示例中成功 swap 用 id1、bluf 用 id2读取统一挂在 id2 上这与示例的断言方式保持一致。与相邻错误的区分执行失败不止这一种按消息区分可以避免查错方向以下消息均来自 e_transaction.ex 中的对应示例及其断言现象消息/结果对应示例含义root 缺失Root does not exist: Root ... is absentsubmit_failed_trivial_swap/1本文场景roots_exist?/2未通过重复提交日志含already existresubmit_trivial_swap/1storage_check/3报Commitments ... already exist或Nullifiers ... already existbackends.ex非法 keyspaceCould not process keyspace evaluationsubmit_error_keyspace/1提交代码[0 \| 0]交易代码本身不是合法结构VM 执行失败无日志消息vm_result: :vm_error、tx_result: :errorbluf_transaction_errors/1nock/3直接失败未进入后端校验另外如果你用的是 cairo_resource 后端而不是 transparent_resourceroot 检查走的是root_existence_check/2backends.ex消息是A submitted root dose not exist in storage源码原文含拼写错误与本文的Root does not exist不是同一处校验。验证与限制修复或调整交易后验证方式就是上面两条路径mix test test/transaction_test.exs全部通过其中submit_failed_trivial_swap断言Root does not exist、submit_successful_trivial_swap断言成功后能从 roots/nullifiers/commitments 键读出预期值或者在iex -S mix中重新执行对应示例函数并观察日志。限制说明本文只覆盖:transparent_resource后端的 root 存在性校验:read_only、:debug_term_storage后端不做该校验:cairo_resource的 root 检查是另一处代码、另一条消息。示例断言允许日志为空异步日志时序这是 e_transaction.ex 注释中明示的行为不要把这一次没看到日志当作交易执行成功的证据。节点是临时的按 USAGE.md 说明每次start_node()都是干净状态存储中的 roots 列表不会跨会话保留。【免费下载链接】anoma-archiveReference implementation of Anoma项目地址: https://gitcode.com/GitHub_Trending/an/anoma-archive创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考