單元測試時間敏感可證明的智能合約
我目前正在使用 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_query
或provable_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 的社區經理