Solidity
與時間相關的測試第一次嘗試時的意外行為,第二次嘗試時的預期行為
我正在嘗試測試一個契約,其中的功能應該需要某些時間戳。為了便於閱讀,部分程式碼被刪除:
這是契約有問題的部分:
PCE_Contract.sol
pragma solidity ^0.7.0; contract PCE_Contract{ constructor(uint256 newStartTime, uint256 PERIOD) { _PERIOD = PERIOD * 1 days ; initiation = newStartTime ; } function enter() payable public { require(( block.timestamp < (initiation + _PERIOD) ), "Period for this function has ended." ); // do stuff } }
我正在使用本文中的資訊來模擬時間。
PCE_Contract_test.js
const expected_period = 7 ; const SECONDS_IN_DAY = 86400 ; const Mon_01_Jun_00_00_UTC_2020 = 1590969600; // 06-01-2020 @ 12.00 am (UTC) const Mon_09_Jun_13_00_UTC_2020 = 1591660800; // 06-09-2020 @ 01.00 pm (UTC) contract('PCE_Contract', async (accounts) => { before( async () => { instance_1 = await PCE_Contract.new(Mon_01_Jun_00_00_UTC_2020 ,expected_period ); instance_2 = await PCE_Contract.new(Mon_09_Jun_13_00_UTC_2020 ,expected_period ); }); const expected_address = accounts[1]; // more tests using instance_1 it("No entry after period is over, OK", async() => { await test_helper.advanceTimeAndBlock(SECONDS_IN_DAY * (expected_period )); await instance_2.enter({ from: expected_address, value: String(1e18)}); }); }
我預計測試會失敗,因為自 instance_1 以來已經過去了 _PERIOD 時間。但是,在第一次測試執行中,測試通過了。有趣的是,當我第二次執行測試時(將從第一次測試結束的時間戳開始)測試失敗(預期行為)。
為什麼第一個測試的時間模擬失敗,即使我可以看到時間已經過去了 ganache-cli ? 我該如何解決這個問題,以便我可以在兩個時間段內測試功能?
兩個具有時間跳躍的測試的 ganache-cli 輸出:
Transaction: 0xbb9e5b0e3ee1bc266d79ebe169061259c4832cbbc175b63ff1719aa125cf06a3 Gas usage: 40655 Block Number: 10 Block Time: Mon Jun 01 2020 03:00:24 GMT+0300 (GMT+03:00) Runtime Error: revert Revert reason: ERROR eth_call eth_blockNumber evm_increaseTime evm_mine eth_getBlockByNumber eth_getBlockByNumber eth_getBlockByNumber eth_sendTransaction Transaction: 0x43578162490a3edf734c17462056f2090b3775a2a90228a0097da53c42319afb Gas usage: 112357 Block Number: 12 Block Time: Tue Jun 09 2020 03:00:24 GMT+0300 (GMT+03:00)
Truffle v5.1.49
Ganache CLI v6.12.1 (ganache-core: 2.13.1)
節點 v12.18.4
程式碼將
instance_1
啟動設置為 6 月 1 日,instance_2
啟動設置為 6 月 9 日。在日誌中,時間已經提前到 6 月 9 日。所以測試應該失敗,
instance_1
但成功instance_2
。由於測試檢查
instance_2
它是正確的,因此測試成功。