Web3js

單元測試時間敏感可證明的智能合約

  • April 7, 2020

我目前正在使用 Provable(以前稱為 Oraclize)來完成 CRON 工作:

constructor() public payable {
   OAR = OracleAddrResolverI(0x6F486C8BD6fc43eA212E93CCF8ce047C7f1Cb475);
   provable_query(7 days, "URL", "");
}

為了測試(松露、摩卡、柴),我導入了以下內容:

const Web3 = require("web3");
const { waitForEvent } = require("./utils");
const { time } = require("@openzeppelin/test-helpers");
const web3 = new Web3(
   new Web3.providers.WebsocketProvider("ws://localhost:9545")

除了time來自 OpenZeppelin,那些來自 Provable truffle box

waitForEvent特別是,當從 Solidity 觸發時,可以返回事件名稱及其描述。)

為了測試這一點,我進行了以下測試:

it("Should have logged a new Provable query after the contract creation + cooldown", async () => {
   console.log(await time.latest());
   await time.increase(TIME_BETWEEN_TWO_QUERIES);
   console.log(await time.latest());
   const {
       returnValues: { description },
   } = await waitForEvent(contractEvents[PROVABLE_QUERY_EVENT]);
   assert(
       description === PROVABLE_QUERY_STRING,
       "Provable query incorrectly logged!"
   );
});

時間增加似乎有效,但waitForEvent承諾仍在等待 TIME_BETWEEN_TWO_QUERIES 完成,這是有問題的。

有誰知道我如何正確測試那些對時間敏感的問題?如何“提前”時間讓 Provable 能夠檢測到它?

好的,所以我從 Provable 的 gitter 那裡得到了答案。它的工作方式如下:

  • 每當進行可證明的查詢時(通過provable_queryprovable_newRandomDSQuery例如),即使在測試環境中,請求也會立即發送到 Provable 的伺服器
  • 在 Provable 查詢中作為參數傳遞的延遲作為參數傳遞給 a setTimeout(或等價物),因此 Provable 的伺服器“知道”何時__callback從智能合約向函式發出請求

因此,由於 Provable 的伺服器時間完全獨立於 evm,使用time.increase來自 OpenZeppelin-test-helpers 或 evm 增加時間功能不會有任何效果。到目前為止,還沒有辦法增加 Provable 的伺服器在測試環境中的時間,因為它不是使用虛擬機,而是使用它們的實際伺服器。

替代解決方案

為了解決這個問題,一個簡單的想法是使用provable_query函式在智能合約的頂部聲明常量,以使這些成為合理的等待延遲,並為生產進行更改。

查看 OpenZeppelin 測試助手文件:https ://docs.openzeppelin.com/test-helpers/0.5/configuration#provider

包括時間相關操作: https ://docs.openzeppelin.com/test-helpers/0.5/api#time

如果您對使用 OpenZeppelin 有任何疑問,可以在社區論壇中提問:https ://forum.openzeppelin.com/

披露:我是 OpenZeppelin 的社區經理

引用自:https://ethereum.stackexchange.com/questions/82128