6 分钟
使用分叉快速轻松地调试子图
与许多处理大量数据的系统一样,The Graph的索引人(Graph Nodes)可能需要相当长的时间才能将您的子图与目标区块链同步。以调试为目的的快速更改和索引所需的长等待时间之间的差异,是极其适得其反的,我们对此非常清楚。这就是为什么我们引入了由LimeChain开发的子图分叉,在本文中,我将向您展示如何使用此功能来大大加快子图调试!
好的,那是什么?
子图分叉是从另一个子图的存储(通常是远程存储)中缓慢获取实体的过程。
在调试时,子图分叉允许您在固定的区块X中调试失败的子图,而无需等待区块同步X。
什么?! 如何处理?
当您将子图部署到远程Graph节点进行索引时,它在块X处失败,好消息是Graph节点仍将使用其存储服务GraphQL查询,该存储同步到块X。这太棒了!这意味着我们可以利用这个“最新”存储来修复索引块X时出现的错误。
简而言之,我们将从远程 Graph 节点 分叉失败的子图,保证子图索引更新至区块X的数据, 以便基于更新至区块 X 的数据在本地部署的子图进行调试,以反映索引数据的最新状态。
请给我看一些代码!
为了专注于子图调试,让我们保持简单,并与索引 Ethereum Gravity 智能合约的 示例子图 一起运行。
以下是索引 Gravatar
定义的处理程序,没有任何错误:
1export function handleNewGravatar(event: NewGravatar): void {2 let gravatar = new Gravatar(event.params.id.toHex().toString())3 gravatar.owner = event.params.owner4 gravatar.displayName = event.params.displayName5 gravatar.imageUrl = event.params.imageUrl6 gravatar.save()7}89export function handleUpdatedGravatar(event: UpdatedGravatar): void {10 let gravatar = Gravatar.load(event.params.id.toI32().toString())11 if (gravatar == null) {12 log.critical('Gravatar not found!', [])13 return14 }15 gravatar.owner = event.params.owner16 gravatar.displayName = event.params.displayName17 gravatar.imageUrl = event.params.imageUrl18 gravatar.save()19}
糟糕,不幸的是,当我将完美的子图部署到Subgraph Studio时,它会报“未找到 Gravatar!” 的错误。
尝试修复的常用方法是:
- 在映射源中进行更改,你认为这将解决问题(但我知道它不会)。
- 将子图重新部署到subgraph Studio(或另一个远程图形节点)。
- 等待同步。
- 如果它再次中断,则返回 第1步,否则:搞定!
对于一个普通的调试过程来说很常见,但是有一个步骤会严重减缓这个过程:3。 等待同步。
使用 子图分叉 我们可以从根本上解决这个问题。 如下:
- 使用适当的子分叉设置启动本地 Graph 节点。
- 按照你认为可以解决问题的方法,在映射源中进行更改。
- 部署到本地 Graph 节点,分叉失败的子图并从有问题的区块开始。
- 如果它再次中断,则返回 第1步,否则:搞定!
现在,你可能有 2 个问题:
- 子分叉集是什么???
- 分叉什么?!
回答如下:
分叉基础
是“基础”URL,例如将 子图 id 添加到结果 URL (<fork-base>/<subgraph-id>
),就是一个合法的子图GraphQL访问端口。- 分叉容易,不要紧张:
1$ graph 部署 <subgraph-name> --调试分叉 <subgraph-id> --ipfs地址 http://localhost:5001 --node http://localhost:8020
另外,不要忘记将子图中的 dataSources.source.startBlock
字段设置为有问题的区块编号,这样您就可以跳过索引不必要的区块并利用分叉!
所以,我是这么做的:
- 我启动一个本地Graph节点,(这里是如何做到的) 将
分叉基础
选项设为:https://api.thegraph.com/subgraphs/id/
,因为我将从Subgraph Studio分叉子图,即之前部署有问题的子图。
1$ cargo run -p graph-node --release -- \2 --postgres-url postgresql://USERNAME[:PASSWORD]@localhost:5432/graph-node \3 --ethereum-rpc NETWORK_NAME:[CAPABILITIES]:URL \4 --ipfs 127.0.0.1:50015 --fork-base https://api.thegraph.com/subgraphs/id/
- 经过仔细检查,我注意到在我的两个处理程序中索引
Gravatar
时使用的id
不匹配。handleNewGravatar
将其转换为十六进制 (event.params.id.toHex()
),而handleUpdatedGravatar
使用 int32格式 (event. params.id.toI32()
) 这会导致handleUpdatedGravatar
出现“未找到 Gravatar!”的错误。 于是我将他们都id
转换为十六进制。 - 更改后,我将子图部署到本地 Graph 节点,分叉失败的子图并设置 subgraph.yaml 中的
dataSources.source.startBlock
到6190343
:
1$ graph deploy gravity --debug-fork QmNp169tKvomnH3cPXTfGg4ZEhAHA6kEq5oy1XDqAxqHmW --ipfs http://localhost:5001 --node http://localhost:8020
- 我检查了本地 Graph 节点生成的日志,万岁!一切正常。
- 我将没有问题的子图部署到远程 Graph 节点上,从此过上幸福的生活! (不担心缺衣少粮)