测试已完成的链链接 oracle 请求以太/安全帽的最佳实践是啥?

Posted

技术标签:

【中文标题】测试已完成的链链接 oracle 请求以太/安全帽的最佳实践是啥?【英文标题】:What is best practice for for testing fulfilled chainlink oracle requests ethers/hardhat?测试已完成的链链接 oracle 请求以太/安全帽的最佳实践是什么? 【发布时间】:2021-10-23 05:51:14 【问题描述】:

我在 rinkeby 上使用带以太币的安全帽来测试向本地链链接节点发出获取请求的智能合约。我可以在节点仪表板上观察到请求已完成。

我正在努力编写一个等待第二个履行交易被确认的测试。

我在SmartContractKit/chainlink repo tests看到了类似的测试

 it("logs the data given to it by the oracle", async () => 
  const tx = await oc.connect(roles.oracleNode).fulfillOracleRequest(...convertFufillParams(request, response));
  const receipt = await tx.wait();

  assert.equal(2, receipt?.logs?.length);
  const log = receipt?.logs?.[1];

  assert.equal(log?.topics[2], response);
);

我看不到这会等待已完成的交易。在consumer.sol这个函数调用中有一个事件RequestFulfilled,就是emit,但是这个测试好像没有在监听。

我发现的另一个示例ocean protocol request test 通过在轮询测试中创建请求 ID、访问器和 while 循环的映射来完成此操作,直到找到请求 ID。

 it("create a request and send to Chainlink", async () => 
  let tx = await ocean.createRequest(jobId, url, path, times);
  request = h.decodeRunRequest(tx.receipt.rawLogs[3]);
  console.log("request has been sent. request id :=" + request.id)

  let data = 0
  let timer = 0
  while(data == 0)
    data = await ocean.getRequestResult(request.id)
    if(data != 0) 
      console.log("Request is fulfilled. data := " + data)
    
    wait(1000)
    timer = timer + 1
    console.log("waiting for " + timer + " second")
  

);

这是有道理的,我知道它是如何工作的。但是,当我认为必须有更优化的方式时,我想避免创建映射和访问器。

【问题讨论】:

【参考方案1】:

您需要查看 hardhat-starter-kit 以查看使用 Chainlink/oracle API 响应的示例。

对于单元测试,您只需 mock 来自 Chainlink 节点的 API 响应。

对于集成测试(例如,在测试网上),您需要为返回添加一些等待参数。在示例 hardhat-starter-kit 中,它只等待 x 秒,但您也可以编写测试代码以侦听事件以了解预言机何时响应。这确实使用事件来获取 requestId,但是,您实际上不必自己创建事件,因为 Chainlink 核心代码已经有了这个。

    it('Should successfully make an external API request and get a result', async () => 
      const transaction = await apiConsumer.requestVolumeData()
      const tx_receipt = await transaction.wait()
      const requestId = tx_receipt.events[0].topics[1]

      //wait 30 secs for oracle to callback
      await new Promise(resolve => setTimeout(resolve, 30000))

      //Now check the result
      const result = await apiConsumer.volume()
      console.log("API Consumer Volume: ", new web3.utils.BN(result._hex).toString())
      expect(new web3.utils.BN(result._hex)).to.be.a.bignumber.that.is.greaterThan(new web3.utils.BN(0))
    )

【讨论】:

以上是关于测试已完成的链链接 oracle 请求以太/安全帽的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Chainlist-以太坊兼容链在线配置工具

Web3.js 1.0构建以太坊Oracle

JMeter测试,提高Tomca性能,链接池

以太坊系节点RPC端口开放被攻击的网络安全配置

以太坊系节点RPC端口开放被攻击的网络安全配置

以太坊开发利用Oraclize开发一个投注合约:原理介绍