From a1cbaeb18a1be6207295e46c003701972c30f838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20D=C3=ADaz?= Date: Wed, 20 Mar 2024 18:20:04 +0100 Subject: [PATCH] chore: temporarily remove legacy tests (yet to be refactored) --- test/helpers/UsingWitnetTestHelper.sol | 71 -- test/helpers/WitnetRequestBoardTestHelper.sol | 51 -- test/helpers/WitnetRequestTestHelper.sol | 30 - test/using_witnet.test.js | 293 ------- test/wrb.test.js | 759 ------------------ test/wrb_proxy.test.js | 258 ------ 6 files changed, 1462 deletions(-) delete mode 100644 test/helpers/UsingWitnetTestHelper.sol delete mode 100644 test/helpers/WitnetRequestBoardTestHelper.sol delete mode 100644 test/helpers/WitnetRequestTestHelper.sol delete mode 100644 test/using_witnet.test.js delete mode 100644 test/wrb.test.js delete mode 100644 test/wrb_proxy.test.js diff --git a/test/helpers/UsingWitnetTestHelper.sol b/test/helpers/UsingWitnetTestHelper.sol deleted file mode 100644 index f5c2429e7..000000000 --- a/test/helpers/UsingWitnetTestHelper.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity >=0.7.0 <0.9.0; -pragma experimental ABIEncoderV2; - -import "../../contracts/UsingWitnet.sol"; - -/** - * @title Test Helper for the UsingWitnet contract - * @dev The aim of this contract is: - * 1. Raise the visibility modifier of UsingWitnet contract functions for testing purposes - * @author Witnet Foundation - */ -contract UsingWitnetTestHelper is UsingWitnet { - - Witnet.Result public result; - - constructor (WitnetRequestBoard _wrb) - UsingWitnet(_wrb) - {} - - receive() external payable {} - - function witnetPostRequest(IWitnetRequest _request) - external payable - returns(uint256 _id) - { - uint256 _reward; - (_id, _reward) = _witnetPostRequest(_request); - if (_reward < msg.value) { - payable(msg.sender).transfer(msg.value - _reward); - } - } - - function witnetUpgradeReward(uint256 _id) - external payable - { - uint256 _value = msg.value; - uint256 _used = _witnetUpgradeReward(_id); - if (_used < _value) { - payable(msg.sender).transfer(_value - _used); - } - } - - function witnetReadResult(uint256 _requestId) - external - returns (Witnet.Result memory) - { - result = _witnetReadResult(_requestId); - return result; - } - - function witnetCurrentReward(uint256 _requestId) - external view - returns (uint256) - { - return witnet.readRequestReward(_requestId); - } - - function witnetEstimateReward(uint256 _gasPrice) external view returns (uint256) { - return witnet.estimateReward(_gasPrice); - } - - function witnetAsUint64() external view returns (uint) { - return witnet.asUint64(result); - } - - function witnetCheckRequestResolved(uint256 _id) external view returns (bool) { - return _witnetCheckResultAvailability(_id); - } -} diff --git a/test/helpers/WitnetRequestBoardTestHelper.sol b/test/helpers/WitnetRequestBoardTestHelper.sol deleted file mode 100644 index ec3b05537..000000000 --- a/test/helpers/WitnetRequestBoardTestHelper.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity >=0.7.0 <0.9.0; -pragma experimental ABIEncoderV2; - -import "../../contracts/impls/boards/trustable/WitnetRequestBoardTrustableDefault.sol"; - -/** - * @title Witnet Requests Board Version 1 - * @notice Contract to bridge requests to Witnet - * @dev This contract enables posting requests that Witnet bridges will insert into the Witnet network - * The result of the requests will be posted back to this contract by the bridge nodes too. - * The contract has been created for testing purposes - * @author Witnet Foundation - */ -contract WitnetRequestBoardTestHelper - is - WitnetRequestBoardTrustableDefault -{ - address public witnet; - - constructor (address[] memory _committee, bool _upgradable) - WitnetRequestBoardTrustableDefault(_upgradable, "WitnetRequestBoardTestHelper", 120547) - { - witnet = msg.sender; - setReporters(_committee); - } - - /// @dev Estimate the amount of reward we need to insert for a given gas price. - /// @return The rewards to be included for the given gas price as inclusionReward, resultReward, blockReward. - function estimateReward(uint256) - public pure - override - returns(uint256) - { - return 0; - } - - /// @dev Posts a data request into the WRB, with immediate mock result. - /// @param _request The contract containing the Witnet Witnet data request actual bytecode. - /// @return _id The unique identifier of the data request. - function postRequest(IWitnetRequest _request) - public payable - override - returns(uint256 _id) - { - _id = super.postRequest(_request); - __storage().queries[_id].response.drTxHash = keccak256("hello"); - __storage().queries[_id].response.cborBytes = "hello"; - } -} diff --git a/test/helpers/WitnetRequestTestHelper.sol b/test/helpers/WitnetRequestTestHelper.sol deleted file mode 100644 index 66daf60ee..000000000 --- a/test/helpers/WitnetRequestTestHelper.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity >=0.7.0 <0.9.0; -import "../../contracts/libs/Witnet.sol"; - -/** - * @title The serialized form of a Witnet data request - */ -contract WitnetRequestTestHelper is IWitnetRequest { - - using Witnet for bytes; - - constructor(bytes memory _bytecode) { - bytecode = _bytecode; - } - - /// Contains a well-formed Witnet Data Request, encoded using Protocol Buffers. - bytes public override bytecode; - - /// Applies Witnet-compatible hash function over the `bytecode()` in order to - /// uniquely identify every possible well-formed Data Request. - function hash() public view override returns (bytes32) { - return bytecode.hash(); - } - - /// Modifies the Witnet Data Request bytecode. - function modifyBytecode(bytes memory _bytecode) public { - bytecode = _bytecode; - } -} diff --git a/test/using_witnet.test.js b/test/using_witnet.test.js deleted file mode 100644 index 24474478f..000000000 --- a/test/using_witnet.test.js +++ /dev/null @@ -1,293 +0,0 @@ -const settings = require("../migrations/witnet.settings") - -const { expectRevert } = require("@openzeppelin/test-helpers") - -const WRB = artifacts.require(settings.artifacts.default.WitnetRequestBoard) -const WRBProxy = artifacts.require(settings.artifacts.default.WitnetProxy) -const WitnetLib = artifacts.require(settings.artifacts.default.WitnetLib) - -const UsingWitnetTestHelper = artifacts.require("UsingWitnetTestHelper") -const WitnetRequest = artifacts.require("WitnetRequestTestHelper") - -const truffleAssert = require("truffle-assertions") - -contract("UsingWitnet", accounts => { - describe("UsingWitnet \"happy path\" test case. " + - "This covers pretty much all the life cycle of a Witnet request:", () => { - const requestHex = "0x01" - const resultHex = "0x1a002fefd8" - const resultDecimal = 3141592 - const drTxHash = "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - - let witnet, clientContract, wrb, proxy, request, requestId, result - let lastAccount1Balance, lastReward - - const ownerAccount = accounts[0] - const reporterAccount = accounts[1] - - before(async () => { - witnet = await WitnetLib.deployed() - await WRB.link(WitnetLib, witnet.address) - if (!proxy) { - // create one and only proxy contract: - proxy = await WRBProxy.new({ from: ownerAccount }) - // let 'wrb' artifact always point to proxy address - wrb = await WRB.at(proxy.address) - } - // notwithstanding, upgrade proxy on each iteration... - await proxy.upgradeTo( - // ...to new implementation instance: - (await WRB.new( - ...settings.constructorParams.default.WitnetRequestBoard, - { from: ownerAccount } - ) - ).address, - // ...resetting reporters ACL: - web3.eth.abi.encodeParameter("address[]", [reporterAccount]), - // ...from owner account. - { from: ownerAccount } - ) - await UsingWitnetTestHelper.link(WitnetLib, witnet.address) - clientContract = await UsingWitnetTestHelper.new(proxy.address) - lastAccount1Balance = await web3.eth.getBalance(accounts[1]) - }) - - it("should create a data request", async () => { - request = await WitnetRequest.new(requestHex) - const internalBytes = await request.bytecode() - assert.equal(internalBytes, requestHex) - }) - - it("should post a data request into the wrb", async () => { - const gasPrice = 1e9 - lastReward = await clientContract.witnetEstimateReward(gasPrice) - requestId = await returnData(clientContract.witnetPostRequest( - request.address, - { - from: accounts[1], - value: lastReward * 2, - gasPrice, - } - )) - assert.equal(requestId, 1) - }) - - it("should have posted and read the same bytes", async () => { - const internalBytes = await wrb.readRequestBytecode(requestId) - assert.equal(internalBytes, requestHex) - }) - - it("should have set the correct rewards", async () => { - // Retrieve rewards - const drInfo = await wrb.readRequest(requestId) - const drReward = drInfo.reward.toString() - assert.equal(drReward, lastReward) - }) - - it("requester balance should decrease", async () => { - const afterBalance = await web3.eth.getBalance(accounts[1]) - assert(parseInt(afterBalance) < parseInt(lastAccount1Balance)) - lastAccount1Balance = afterBalance - }) - - it("client contract balance should remain stable", async () => { - const usingWitnetBalance = await web3.eth.getBalance(clientContract.address) - assert.equal(usingWitnetBalance, 0) - }) - - it("WRB balance should have increased in the exact fare", async () => { - const wrbBalance = await web3.eth.getBalance(wrb.address) - assert.equal(wrbBalance, lastReward) - }) - - it("should upgrade the rewards of an existing data request", async () => { - const gasPrice = 2e9 - lastReward = await clientContract.witnetEstimateReward(gasPrice) - const currentReward = await clientContract.witnetCurrentReward.call(requestId) - await returnData(clientContract.witnetUpgradeReward(requestId, { - from: accounts[1], - value: (lastReward - currentReward) * 2, - gasPrice, - })) - }) - - it("should have upgraded the rewards correctly", async () => { - // Retrieve reward - const drInfo = await wrb.readRequest(requestId) - assert.equal(drInfo.reward.toString(), lastReward.toString()) - }) - - it("requester balance should decrease after rewards upgrade", async () => { - const afterBalance = await web3.eth.getBalance(accounts[1]) - assert(parseInt(afterBalance) < parseInt(lastAccount1Balance)) - lastAccount1Balance = afterBalance - }) - - it("client contract balance should remain stable after rewards upgrade", async () => { - const usingWitnetBalance = await web3.eth.getBalance(clientContract.address) - assert.equal(usingWitnetBalance, 0) - }) - - it("WRB balance should increase after rewards upgrade", async () => { - const wrbBalance = await web3.eth.getBalance(wrb.address) - assert.equal(wrbBalance, lastReward) - }) - - it("should fail if posting result from unauthorized reporter", async () => { - await expectRevert( - wrb.reportResult(requestId, drTxHash, resultHex, { from: ownerAccount }), - "unauthorized reporter" - ) - }) - - it("should post the result of the request into the WRB", async () => { - await returnData(wrb.reportResult(requestId, drTxHash, resultHex, { - from: reporterAccount, - })) - const result = await wrb.readResponseResult.call(requestId) - assert.equal(result.value.buffer.data, resultHex) - }) - - it("should check if the request is resolved", async () => { - assert.equal(await clientContract.witnetCheckRequestResolved(requestId), true) - }) - - it("should pull the result from the WRB back into the client contract", async () => { - await clientContract.witnetReadResult(requestId, { from: accounts[0] }) - result = await clientContract.result() - assert.equal(result.success, true) - assert.equal(result.value.buffer.data, resultHex) - }) - - it("should decode result successfully", async () => { - const actualResultDecimal = await clientContract.witnetAsUint64.call() - assert.equal(actualResultDecimal.toString(), resultDecimal.toString()) - }) - }) - - describe("UsingWitnet \"happy path\" test case with a false result:", () => { - const requestHex = "0x02" - const resultHex = "0xd82701" - const drTxHash = "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - - const reward = web3.utils.toWei("1", "ether") - - const ownerAccount = accounts[0] - const reporterAccount = accounts[1] - - const gasPrice = 1e9 - - let witnet, clientContract, wrb, proxy, request, requestId, result - - before(async () => { - witnet = await WitnetLib.deployed() - if (!proxy) { - // create one and only proxy contract: - proxy = await WRBProxy.new() - // let 'wrb' artifact always point to proxy address - wrb = await WRB.at(proxy.address) - // initialize 'wrb' artifact, - // setting 'ownerAccount' as owner - // and 'reporterAccount' as authorized reporter: - await proxy.upgradeTo( - (await WRB.new( - ...settings.constructorParams.default.WitnetRequestBoard - ) - ).address, - web3.eth.abi.encodeParameter("address[]", [reporterAccount]), - { from: ownerAccount } - ) - } - await UsingWitnetTestHelper.link(WitnetLib, witnet.address) - clientContract = await UsingWitnetTestHelper.new(wrb.address) - }) - - it("should create a data request", async () => { - request = await WitnetRequest.new(requestHex) - const internalBytes = await request.bytecode() - assert.equal(internalBytes, requestHex) - }) - - it("should pass the data request to the wrb", async () => { - requestId = await returnData(clientContract.witnetPostRequest( - request.address, - { - from: accounts[0], - value: reward, - gasPrice, - } - )) - assert.equal(requestId, 1) - }) - - it("should check the request is not yet resolved", async () => { - assert.equal(await clientContract.witnetCheckRequestResolved(requestId), false) - }) - - it("should fail if posting result from unauthorized reporter", async () => { - await expectRevert( - wrb.reportResult(requestId, drTxHash, resultHex, { from: ownerAccount }), - "unauthorized reporter" - ) - }) - - it("should report the result in the WRB", async () => { - await returnData(wrb.reportResult(requestId, drTxHash, resultHex, { - from: reporterAccount, - })) - const result = await wrb.readResponseResult(requestId) - assert.equal(result.value.buffer.data, resultHex) - }) - - it("should pull the result from the WRB back to the client contract", async () => { - await clientContract.witnetReadResult(requestId, { from: accounts[1] }) - result = await clientContract.result() - assert.equal(result.value.buffer.data, resultHex) - }) - - it("should detect the result is false", async () => { - await clientContract.witnetReadResult(requestId, { from: accounts[1] }) - result = await clientContract.result() - assert.equal(result.success, false) - }) - - it("should be able to estimate gas cost and post the DR", async () => { - const estimatedReward = await clientContract.witnetEstimateReward.call(gasPrice) - await truffleAssert.passes( - clientContract.witnetPostRequest(request.address, { - from: accounts[1], - value: estimatedReward, - gasPrice, - }), - "Estimated rewards should cover the gas costs" - ) - }) - }) -}) - -function waitForHash (tx) { - return new Promise((resolve, reject) => - tx.on("transactionHash", resolve).catch(reject) - ) -} - -async function returnData (tx) { - const txHash = await waitForHash(tx) - const txReceipt = await web3.eth.getTransactionReceipt(txHash) - if (txReceipt.logs && txReceipt.logs.length > 0) { - const decoded = web3.eth.abi.decodeLog( - [ - { - type: "uint256", - name: "id", - }, { - type: "address", - name: "from", - }, - ], - txReceipt.logs[0].data, - txReceipt.logs[0].topics - ) - return decoded.id - } -} diff --git a/test/wrb.test.js b/test/wrb.test.js deleted file mode 100644 index c993ae8a4..000000000 --- a/test/wrb.test.js +++ /dev/null @@ -1,759 +0,0 @@ -const settings = require("../migrations/witnet.settings") - -const { - BN, - expectEvent, - expectRevert, - balance, - ether, -} = require("@openzeppelin/test-helpers") -const { expect, assert } = require("chai") - -// Contracts -const WRB = artifacts.require(settings.artifacts.default.WitnetRequestBoard) -const WitnetLib = artifacts.require("WitnetLib") -const WitnetRequest = artifacts.require("WitnetRequestTestHelper") -const WitnetRequestTestHelper = artifacts.require("WitnetRequestTestHelper") - -// WitnetRequest definition -const queryId = new BN(1) -// eslint-disable-next-line no-multi-str -const requestHex = "0x0abb0108bd8cb8fa05123b122468747470733a2f2f7777772e6269747374616d702e6e65742f6170692f7469636b65722\ -f1a13841877821864646c6173748218571903e8185b125c123168747470733a2f2f6170692e636f696e6465736b2e636f6d2f76312f6270692f6375\ -7272656e7470726963652e6a736f6e1a2786187782186663627069821866635553448218646a726174655f666c6f61748218571903e8185b1a0d0a0\ -908051205fa3fc00000100322090a0508051201011003100a1804200128\ -46308094ebdc03" -const resultHex = "0x1a000702c8" -const drTxHash = "0x0000000000000000000000000000000000000000000000000000000000000001" - -contract("WitnetRequestBoard", ([ - requester, - owner, - committeeMember, - other, -]) => { - beforeEach(async () => { - await WRB.link(WitnetLib, WitnetLib.address) - this.WitnetRequestBoard = await WRB.new( - ...settings.constructorParams.default.WitnetRequestBoard, - { from: owner } - ) - await this.WitnetRequestBoard.initialize( - web3.eth.abi.encodeParameter("address[]", - [owner, committeeMember]), - { from: owner } - ) - this.WitnetRequest = await WitnetRequest.new(requestHex, { from: requester }) - }) - - describe("deployments", async () => { - it("deploys WitnetRequestBoard successfully", async () => { - expect(this.WitnetRequestBoard.address != null) - }) - }) - - describe("post data request", async () => { - it("creator can post a data request", async () => { - // Initial balance - const contractBalanceTracker = await balance.tracker(this.WitnetRequestBoard.address) - const contractInitialBalance = await contractBalanceTracker.get() - - // Post Data Request - const postDataRequestTx = await this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, - { - from: requester, - value: ether("1"), - } - ) - - // Check `PostedRequest` event - expectEvent( - postDataRequestTx, - "PostedRequest", - { - queryId, - } - ) - expect(postDataRequestTx.logs[0].args.queryId, "match data request id").to.be.bignumber.equal(queryId) - - // Check contract balance (increased by reward) - const contractFinalBalance = await contractBalanceTracker.get() - expect( - contractFinalBalance.eq(contractInitialBalance - .add(ether("1")) - ), - "contract balance should have increase after the request creation by 1 eth", - ).to.equal(true) - }) - it("creator can post data requests with sequential identifiers", async () => { - // Post Data Requests - const postDataRequestTx1 = await this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, - { - from: requester, - value: ether("1"), - }) - const postDataRequestTx2 = await this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, - { - from: requester, - value: ether("1"), - }) - - // Check `PostedRequest` events - expectEvent( - postDataRequestTx1, - "PostedRequest", - { - queryId, - }) - expect(postDataRequestTx1.logs[0].args.queryId, "match data request id").to.be.bignumber.equal(queryId) - // Check `PostedRequest` events - expectEvent( - postDataRequestTx2, - "PostedRequest", - { - queryId: queryId.add(new BN(1)), - }) - expect( - postDataRequestTx2.logs[0].args.queryId, - "match data request id" - ).to.be.bignumber.equal(queryId.add(new BN(1))) - }) - it("fails if creator is not covering DR reward", async () => { - // Transaction value < reward - await expectRevert( - this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, - { - from: requester, - value: ether("0"), - gasPrice: 1, - } - ), - "reward too low." - ) - }) - it("fails if creator is not covering DR result report gas cost", async () => { - // Tally reward < ESTIMATED_REPORT_RESULT_GAS - await expectRevert( - this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, - { - from: requester, - value: new BN("1"), - gasPrice: 1, - } - ), - "reward too low." - ) - }) - it("reading bytecode from unsolved query works if the request was not modified before being solved", async () => { - await this.WitnetRequestBoard.postRequest(this.WitnetRequest.address, { from: requester, value: ether("1") }) - assert.equal( - await this.WitnetRequest.bytecode.call(), - await this.WitnetRequestBoard.readRequestBytecode.call(1) - ) - }) - it("reading bytecode from unsolved query fails if the request gets modified before being solved", async () => { - await this.WitnetRequestBoard.postRequest(this.WitnetRequest.address, { from: requester, value: ether("1") }) - const newDrBytes = web3.utils.fromAscii("This is a different DR") - await this.WitnetRequest.modifyBytecode(newDrBytes) - await expectRevert( - this.WitnetRequestBoard.readRequestBytecode.call(1), - "bytecode changed after posting" - ) - }) - }) - - describe("upgrade data request", async () => { - beforeEach(async () => { - await this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, - { - from: requester, - value: ether("1"), - gasPrice: 1e9, - } - ) - }) - it("anyone can upgrade existing data request increasing the reward", async () => { - // Initial balance - const contractBalanceTracker = await balance.tracker(this.WitnetRequestBoard.address) - const contractInitialBalance = await contractBalanceTracker.get() - - // Update data request (increased reward) - await this.WitnetRequestBoard.upgradeReward(queryId, { - from: other, - value: ether("1"), - gasPrice: 2e9, - }) - - // Check contract balance (increased by reward) - const contractFinalBalance = await contractBalanceTracker.get() - expect( - contractFinalBalance.eq(contractInitialBalance - .add(ether("1")) - ), - "contract balance should have increased after request upgrade by 1 eth", - ).to.equal(true) - }) - it("anyone can upgrade existing data request gas price", async () => { - // Update data request (increased reward) - await this.WitnetRequestBoard.upgradeReward(queryId, { - from: other, - value: ether("1"), - gasPrice: 3e9, - }) - - // Read data request gas price from WitnetRequestBoard by `queryId` - const gasPrice = await this.WitnetRequestBoard.readRequestGasPrice.call(queryId, { from: other }) - - // Check that gas price has been updated to 3 wei - expect( - gasPrice.eq(new BN(3e9)), - "data request gas price should have been set to 3 gwei", - ).to.equal(true) - }) - it("creator cannot decrease existing data request gas price", async () => { - // Update data request (increased reward) - await this.WitnetRequestBoard.upgradeReward(queryId, { - from: requester, - value: ether("1"), - gasPrice: 3e9, - }) - // Read data request gas price from WitnetRequestBoard by `queryId` - const gasPrice = await this.WitnetRequestBoard.readRequestGasPrice.call(queryId, { from: other }) - // Check that gas price has not been updated to 1 wei - expect( - gasPrice.eq(new BN(3e9)), - "data request gas price should not have been set to 1 gwei", - ).to.equal(true) - }) - it("fails if anyone upgrades DR with new gas price that decreases reward below gas limit", async () => { - // Report result reward < ESTIMATED_REPORT_RESULT_GAS * newGasPrice - const newGasPrice = ether("0.01") - await expectRevert( - this.WitnetRequestBoard.upgradeReward(queryId, { - from: requester, - value: ether("0"), - gasPrice: newGasPrice, - }), - "reward too low" - ) - }) - it("fails if result is already reported", async () => { - await this.WitnetRequestBoard.reportResult( - queryId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ) - // Update data request (increased reward) - await expectRevert( - this.WitnetRequestBoard.upgradeReward(queryId, { - from: requester, - value: ether("1"), - gasPrice: 3e9, - }), - "not in Posted status" - ) - }) - }) - - describe("report data request result", async () => { - beforeEach(async () => { - // Post data request - await this.WitnetRequestBoard.postRequest(this.WitnetRequest.address, { - from: requester, - value: ether("1"), - gasPrice: 1e9, - }) - }) - it("committee members can report a request result from Witnet and it should receive the reward", async () => { - // Initial balances - const contractBalanceTracker = await balance.tracker(this.WitnetRequestBoard.address) - const ownerBalanceTracker = await balance.tracker(owner) - const contractInitialBalance = await contractBalanceTracker.get() - const ownerInitialBalance = await ownerBalanceTracker.get() - - // Report data request result from Witnet to WitnetRequestBoard - const reportResultTx = await this.WitnetRequestBoard.reportResult( - queryId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ) - - // Check `PostedRequest` event - expectEvent( - reportResultTx, - "PostedResult", - { - queryId, - }, - ) - expect(reportResultTx.logs[0].args.queryId, "match data request id").to.be.bignumber.equal(queryId) - - // Check balances (contract decreased and claimer increased) - const contractFinalBalance = await contractBalanceTracker.get() - const ownerFinalBalance = await ownerBalanceTracker.get() - - expect( - contractFinalBalance.eq(contractInitialBalance - .sub(ether("1")) - ), - "contract balance should have decreased after reporting dr request result by 1 eth", - ).to.equal(true) - expect( - ownerFinalBalance.gt(ownerInitialBalance), - "Owner balance should have increased after reporting result", - ).to.equal(true) - }) - it("fails if reporter is not a committee member", async () => { - await expectRevert( - this.WitnetRequestBoard.reportResult(queryId, drTxHash, resultHex, { - from: other, - gasPrice: 1e9, - }), - "unauthorized reporter" - ) - }) - it("fails if trying to report with zero as Witnet drTxHash", async () => { - await expectRevert( - this.WitnetRequestBoard.reportResult( - queryId, "0x0", resultHex, - { from: owner, gasPrice: 1e9 } - ), - "drTxHash cannot be zero" - ) - }) - it("fails if result was already reported", async () => { - // Report data request result from Witnet to WitnetRequestBoard - await this.WitnetRequestBoard.reportResult( - queryId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ) - - // Try to report the result of the previous data request - await expectRevert( - this.WitnetRequestBoard.reportResult(queryId, drTxHash, resultHex, { - from: committeeMember, - gasPrice: 1e9, - }), - "not in Posted status" - ) - }) - it("fails if data request has not been posted", async () => { - await expectRevert( - this.WitnetRequestBoard.reportResult( - queryId.add(new BN(1)), drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ), - "not in Posted status" - ) - }) - it("retrieves null array if trying to read bytecode from solved data request", async () => { - await this.WitnetRequestBoard.reportResult( - queryId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ) - const bytecode = await this.WitnetRequestBoard.readRequestBytecode.call(queryId) - assert(bytecode == null) - }) - }) - - describe("batch report multiple results", async () => { - beforeEach(async () => { - for (let j = 0; j < 3; j++) { - await this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, { - from: requester, - value: ether("1"), - gasPrice: 1e9, - } - ) - } - }) - it("fails if trying to batch report valid results from unauthorized address", async () => { - await expectRevert( - this.WitnetRequestBoard.reportResultBatch( - [ - [1, 0, drTxHash, resultHex], - [2, 0, drTxHash, resultHex], - [3, 0, drTxHash, resultHex], - ], - true, - { from: other, gasPrice: 1e9 } - ), - "unauthorized reporter" - ) - }) - it("committee member can batch report multiple results, and receive the sum of all rewards", async () => { - // Initial balances - const contractBalanceTracker = await balance.tracker(this.WitnetRequestBoard.address) - const ownerBalanceTracker = await balance.tracker(owner) - const contractInitialBalance = await contractBalanceTracker.get() - const ownerInitialBalance = await ownerBalanceTracker.get() - - // Report data request result from Witnet to WitnetRequestBoard - const tx = await this.WitnetRequestBoard.reportResultBatch( - [ - [1, 0, drTxHash, resultHex], - [2, 0, drTxHash, resultHex], - [3, 0, drTxHash, resultHex], - ], - false, - { from: owner, gasPrice: 1e9 } - ) - - // Check balances (contract decreased and claimer increased) - const contractFinalBalance = await contractBalanceTracker.get() - const ownerFinalBalance = await ownerBalanceTracker.get() - expect( - contractFinalBalance.eq(contractInitialBalance - .sub(ether("3")) - ), - "contract balance should have decreased after reporting dr request result by 3 eth", - ).to.equal(true) - expect( - ownerFinalBalance.gt(ownerInitialBalance), - "Owner balance should have increased after reporting result", - ).to.equal(true) - - // Check number of PostedResult events - expect( - tx.logs.filter(log => log.event === "PostedResult").length, - "PostedResult event should have been emitted three times" - ).to.equal(3) - }) - it( - "trying to verbose batch report same query twice, should pay reward once and emit error event once", - async () => { - // Initial balances - const contractBalanceTracker = await balance.tracker(this.WitnetRequestBoard.address) - const ownerBalanceTracker = await balance.tracker(owner) - const contractInitialBalance = await contractBalanceTracker.get() - const ownerInitialBalance = await ownerBalanceTracker.get() - - // Report data request result from Witnet to WitnetRequestBoard - const tx = await this.WitnetRequestBoard.reportResultBatch( - [ - [3, 0, drTxHash, resultHex], - [3, 0, drTxHash, resultHex], - ], - true, - { from: owner, gasPrice: 1e9 } - ) - - // Check balances (contract decreased and claimer increased) - const contractFinalBalance = await contractBalanceTracker.get() - const ownerFinalBalance = await ownerBalanceTracker.get() - expect( - contractFinalBalance.eq(contractInitialBalance - .sub(ether("1")) - ), - "contract balance should have decreased after reporting dr request result by 3 eth", - ).to.equal(true) - expect( - ownerFinalBalance.gt(ownerInitialBalance), - "Owner balance should have increased after reporting result", - ).to.equal(true) - - // Check number of emitted PostedResult events: - expect( - tx.logs.filter(log => log.event === "PostedResult").length, - "PostedResult event should have been emitted once" - ).to.equal(1) - - // Check number and quality of BatchReportError events: - const errors = tx.logs.filter(log => log.event === "BatchReportError") - expect( - errors.length, - "BatchReportResult event should have been emitted just once" - ).to.equal(1) - expect( - errors[0].args.queryId.toString(), - "BatchReportResult event refers unexpected query id" - ).to.equal("3") - expect( - errors[0].args.reason, - "BatchReportResult manifest wrong reason" - ).to.contain("bad queryId") - }) - it( - "reporting bad drTxHash within non-verbose batch, should pay rewards for valid results and emit no error event", - async () => { - // Initial balances - const contractBalanceTracker = await balance.tracker(this.WitnetRequestBoard.address) - const ownerBalanceTracker = await balance.tracker(owner) - const contractInitialBalance = await contractBalanceTracker.get() - const ownerInitialBalance = await ownerBalanceTracker.get() - - // Report data request result from Witnet to WitnetRequestBoard - const tx = await this.WitnetRequestBoard.reportResultBatch( - [ - [1, 0, drTxHash, resultHex], - [2, 0, "0x0000000000000000000000000000000000000000000000000000000000000000", resultHex], - [3, 0, drTxHash, resultHex], - ], - false, - { from: owner, gasPrice: 1e9 } - ) - - // Check balances (contract decreased and claimer increased) - const contractFinalBalance = await contractBalanceTracker.get() - const ownerFinalBalance = await ownerBalanceTracker.get() - expect( - contractFinalBalance.eq(contractInitialBalance - .sub(ether("2")) - ), - "contract balance should have decreased after reporting dr request result by 2 eth", - ).to.equal(true) - expect( - ownerFinalBalance.gt(ownerInitialBalance), - "Owner balance should have increased after reporting result", - ).to.equal(true) - - // Check number of emitted PostedResult events: - expect( - tx.logs.filter(log => log.event === "PostedResult").length, - "PostedResult event should have been emitted three times" - ).to.equal(2) - - // Check number of BatchReportError events: - const errors = tx.logs.filter(log => log.event === "BatchReportError") - expect( - errors.length, - "No BatchReportResult events should have been emitted" - ).to.equal(0) - }) - it( - "reporting bad results within verbose batch, should pay no reward and emit no PostedResult events", async () => { - // Initial balances - const contractBalanceTracker = await balance.tracker(this.WitnetRequestBoard.address) - const contractInitialBalance = await contractBalanceTracker.get() - - // Report data request result from Witnet to WitnetRequestBoard - const tx = await this.WitnetRequestBoard.reportResultBatch( - [ - [1, 0, drTxHash, "0x"], - [3, 0, "0x0000000000000000000000000000000000000000000000000000000000000000", resultHex], - [2, 4070905200 /* 2099-01-01 00:00:00 UTC */, drTxHash, resultHex], - ], - true, - { from: owner, gasPrice: 1e9 } - ) - - // Check balances (contract decreased and claimer increased) - const contractFinalBalance = await contractBalanceTracker.get() - expect( - contractFinalBalance.eq( - contractInitialBalance - ), - "contract balance should have not changed", - ).to.equal(true) - - // Check number of emitted PostedResult events: - expect( - tx.logs.filter(log => log.event === "PostedResult").length, - "Should have not emitted any PostedResult event" - ).to.equal(0) - - // Check number and quality of BatchReportError events: - const errors = tx.logs.filter(log => log.event === "BatchReportError") - expect( - errors.length, - "Three BatchReportResult events should have been emitted" - ).to.equal(3) - expect( - errors[0].args.queryId.toString(), - "First BatchReportResult event refers to unexpected query id" - ).to.equal("1") - expect( - errors[0].args.reason, - "First BatchReportResult manifests wrong reason" - ).to.contain("bad cborBytes") - expect( - errors[1].args.queryId.toString(), - "Second BatchReportResult event refers to unexpected query id" - ).to.equal("3") - expect( - errors[1].args.reason, - "Second BatchReportResult manifests wrong reason" - ).to.contain("bad drTxHash") - expect( - errors[2].args.queryId.toString(), - "Third BatchReportResult event refers to unexpected query id" - ).to.equal("2") - expect( - errors[2].args.reason, - "Third BatchReportResult manifests wrong reason" - ).to.contain("bad timestamp") - }) - }) - - describe("read data request result", async () => { - let requestTestHelper - beforeEach(async () => { - requestTestHelper = await WitnetRequestTestHelper.new(requestHex, { from: requester }) - // Post data request - await this.WitnetRequestBoard.postRequest(requestTestHelper.address, { - from: requester, - value: ether("1"), - }) - // Report data request result from Witnet to WitnetRequestBoard - await this.WitnetRequestBoard.reportResult(queryId, drTxHash, resultHex, { - from: committeeMember, - gasPrice: 1e9, - }) - }) - it("anyone can read the data request result", async () => { - // Read data request result from WitnetRequestBoard by `queryId` - const result = await this.WitnetRequestBoard.readResponseResult(queryId, { from: requester }) - expect(result.value.buffer.data).to.be.equal(resultHex) - }) - it("should revert reading data for non-existent Ids", async () => { - await expectRevert(this.WitnetRequestBoard.readRequestBytecode.call(200), "not yet posted") - await expectRevert(this.WitnetRequestBoard.readResponseDrTxHash.call(200), "not in Reported status") - await expectRevert(this.WitnetRequestBoard.readResponseResult.call(200), "not in Reported status") - }) - }) - - describe("read data request gas price", async () => { - beforeEach(async () => { - await this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, - { - from: requester, - value: ether("1"), - gasPrice: 1e9, - } - ) - }) - it("anyone can read data request gas price", async () => { - // Read data request gas price from WitnetRequestBoard by `queryId` - const gasPrice = await this.WitnetRequestBoard.readRequestGasPrice.call(queryId, { from: other }) - expect( - gasPrice.eq(new BN(1e9)), - "data request gas price should have been set to 1 gwei", - ).to.equal(true) - }) - }) - - describe("estimate gas cost", async () => { - it("anyone can estime a data request gas cost", async () => { - // Gas price = 1 - const maxResRe = new BN(135000) - const reward = await this.WitnetRequestBoard.estimateReward.call(1) - expect( - reward.lte(maxResRe), - `The estimated maximum gas cost for result reward should be less than ${maxResRe.toString()}` - ).to.equal(true) - } - ) - }) - - describe("delete data request", async () => { - let drId - beforeEach(async () => { - const tx = await this.WitnetRequestBoard.postRequest( - this.WitnetRequest.address, - { - from: requester, - value: ether("0.1"), - gasPrice: 1e9, - } - ) - drId = tx.logs[0].args[0] - }) - it("fails if trying to delete data request from non requester address", async () => { - await this.WitnetRequestBoard.reportResult( - drId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ) - await expectRevert( - this.WitnetRequestBoard.deleteQuery(drId, { from: other }), - "only requester" - ) - }) - it("unsolved data request cannot be deleted", async () => { - await expectRevert( - this.WitnetRequestBoard.deleteQuery(drId, { from: requester }), - "not in Reported status" - ) - }) - it("requester can delete solved data request", async () => { - await this.WitnetRequestBoard.reportResult( - drId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ) - await this.WitnetRequestBoard.deleteQuery(drId, { from: requester }) - }) - it("fails if reporting result on deleted data request", async () => { - await this.WitnetRequestBoard.reportResult( - drId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ) - await this.WitnetRequestBoard.deleteQuery(drId, { from: requester }) - await expectRevert( - this.WitnetRequestBoard.reportResult( - drId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ), - "not in Posted status" - ) - }) - it("retrieves null array if trying to read bytecode from deleted data request", async () => { - await this.WitnetRequestBoard.reportResult( - drId, drTxHash, resultHex, - { from: owner, gasPrice: 1e9 } - ) - await this.WitnetRequestBoard.deleteQuery(drId, { from: requester }) - const bytecode = await this.WitnetRequestBoard.readRequestBytecode.call(drId) - assert(bytecode == null) - }) - }) - - describe("interfaces", async () => { - describe("Upgradeable:", async () => { - it("initialization fails if called from non owner address", async () => { - await expectRevert( - this.WitnetRequestBoard.initialize( - web3.eth.abi.encodeParameter("address[]", [other]), - { from: other } - ), - "only owner" - ) - }) - it("cannot initialize same instance more than once", async () => { - await expectRevert( - this.WitnetRequestBoard.initialize( - web3.eth.abi.encodeParameter("address[]", [other]), - { from: owner } - ), - "already upgraded" - ) - }) - }) - - describe("Destructible:", async () => { - it("fails if trying to destruct from non owner address", async () => { - await expectRevert( - this.WitnetRequestBoard.destruct({ from: other }), - "not the owner" - ) - }) - it("instance gets actually destructed", async () => { - await this.WitnetRequestBoard.destruct({ from: owner }) - await expectRevert( - this.WitnetRequestBoard.getNextQueryId(), - "Out of Gas?" - ) - }) - it("fails if trying to delete unposted DR", async () => { - await expectRevert( - this.WitnetRequestBoard.deleteQuery(200, { from: owner }), - "not in Reported status" - ) - }) - }) - }) -}) diff --git a/test/wrb_proxy.test.js b/test/wrb_proxy.test.js deleted file mode 100644 index 5551efe52..000000000 --- a/test/wrb_proxy.test.js +++ /dev/null @@ -1,258 +0,0 @@ -const settings = require("../migrations/witnet.settings") - -const { assert } = require("chai") -const truffleAssert = require("truffle-assertions") - -const WitnetLib = artifacts.require(settings.artifacts.default.WitnetLib) - -const WitnetRequest = artifacts.require("WitnetRequestTestHelper") -const WitnetRequestBoard = artifacts.require("WitnetRequestBoardTestHelper") -const WrbProxyHelper = artifacts.require("WrbProxyTestHelper") -const TrojanHorseNotUpgradable = artifacts.require("WitnetRequestBoardTrojanHorseNotUpgradable") -const TrojanHorseBadProxiable = artifacts.require("WitnetRequestBoardTrojanHorseBadProxiable") - -contract("Witnet Requests Board Proxy", accounts => { - describe("Witnet Requests Board Proxy test suite:", () => { - const contractOwner = accounts[0] - const requestSender = accounts[1] - - let witnet - let wrbInstance1 - let wrbInstance2 - let wrbInstance3 - let proxy - let wrb - - before(async () => { - witnet = await WitnetLib.deployed() - await WitnetRequestBoard.link(WitnetLib, witnet.address) - wrbInstance1 = await WitnetRequestBoard.new([contractOwner], true) - wrbInstance2 = await WitnetRequestBoard.new([contractOwner], true) - wrbInstance3 = await WitnetRequestBoard.new([contractOwner], false) - proxy = await WrbProxyHelper.new({ from: accounts[2] }) - proxy.upgradeWitnetRequestBoard(wrbInstance1.address, { from: contractOwner }) - wrb = await WitnetRequestBoard.at(proxy.address) - }) - - it("should revert when inserting id 0", async () => { - // It should revert because of non-existent id 0 - await truffleAssert.reverts( - wrb.upgradeReward(0, { from: requestSender }), - "not in Posted" - ) - }) - - it("should post a data request and update the getNextQueryId meter", async () => { - // The data request to be posted - const drBytes = web3.utils.fromAscii("This is a DR") - const request = await WitnetRequest.new(drBytes) - - // Post the data request through the Proxy - const tx1 = wrb.postRequest(request.address, { - from: requestSender, - value: web3.utils.toWei("0.5", "ether"), - }) - const txHash1 = await waitForHash(tx1) - const txReceipt1 = await web3.eth.getTransactionReceipt(txHash1) - - // The id of the data request - const id1 = parseInt(decodeWitnetLogs(txReceipt1.logs, 0).id) - const nextId = await wrb.getNextQueryId.call() - - // check the nextId has been updated in the Proxy when posting the data request - assert.equal((id1 + 1).toString(), nextId.toString()) - }) - - it("fails if trying to upgrade to null contract", async () => { - await truffleAssert.reverts( - proxy.upgradeWitnetRequestBoard("0x0000000000000000000000000000000000000000", { from: contractOwner }), - "null implementation" - ) - }) - - it("fails if owner tries to upgrade to same implementation instance as current one", async () => { - await truffleAssert.reverts( - proxy.upgradeWitnetRequestBoard(await proxy.implementation.call(), { from: contractOwner }), - "nothing to upgrade" - ) - }) - - it("fails if owner tries to upgrade to non-Initializable implementation", async () => { - await truffleAssert.reverts( - proxy.upgradeWitnetRequestBoard(proxy.address, { from: contractOwner }), - "" - ) - }) - - it("fails if foreigner tries to upgrade to compliant new implementation", async () => { - await truffleAssert.reverts( - proxy.upgradeWitnetRequestBoard(wrbInstance2.address, { from: requestSender }), - "not authorized" - ) - }) - - it("fails if owner tries to upgrade to not Upgradeable-compliant implementation", async () => { - const troyHorse = await TrojanHorseNotUpgradable.new() - await truffleAssert.reverts( - proxy.upgradeWitnetRequestBoard(troyHorse.address, { from: contractOwner }), - "not compliant" - ) - }) - - it("fails if owner tries to upgrade to a bad Proxiable-compliant implementation", async () => { - const troyHorse = await TrojanHorseBadProxiable.new() - await truffleAssert.reverts( - proxy.upgradeWitnetRequestBoard(troyHorse.address, { from: contractOwner }), - "proxiableUUIDs mismatch" - ) - }) - - it("should upgrade proxy to compliant new implementation, if called from owner address", async () => { - // The data request to be posted - const drBytes = web3.utils.fromAscii("This is a DR") - const request = await WitnetRequest.new(drBytes) - - // Post the data request through the Proxy - const tx1 = wrb.postRequest(request.address, { - from: requestSender, - value: web3.utils.toWei("0.5", "ether"), - }) - const txHash1 = await waitForHash(tx1) - const txReceipt1 = await web3.eth.getTransactionReceipt(txHash1) - - // The id of the data request, it should be equal 2 since is the second DR - const id1 = decodeWitnetLogs(txReceipt1.logs, 0).id - assert.equal(id1, 2) - - // Upgrade the WRB address to wrbInstance2 (destroying wrbInstance1) - await proxy.upgradeWitnetRequestBoard(wrbInstance2.address, { from: contractOwner }) - - // The current wrb in the proxy should be equal to wrbInstance2 - assert.equal(await proxy.implementation.call(), wrbInstance2.address) - }) - - it("fails if foreigner tries to re-initialize current implementation", async () => { - await truffleAssert.reverts( - wrb.initialize(web3.eth.abi.encodeParameter("address[]", [requestSender]), { from: requestSender }), - "only owner" - ) - }) - - it("fails also if the owner tries to re-initialize current implementation", async () => { - await truffleAssert.reverts( - wrb.initialize(web3.eth.abi.encodeParameter("address[]", [requestSender]), { from: contractOwner }), - "already upgraded" - ) - }) - - it("should post a data request to new WRB and keep previous data request routes", async () => { - // The data request to be posted - const drBytes = web3.utils.fromAscii("This is a DR") - const request = await WitnetRequest.new(drBytes) - - // The id of the data request - const id2 = await wrb.postRequest.call(request.address, { - from: requestSender, - value: web3.utils.toWei("0.5", "ether"), - }) - assert.equal(id2, 3) - - // Post the data request through the Proxy - await waitForHash( - wrb.postRequest(request.address, { - from: requestSender, - value: web3.utils.toWei("0.5", "ether"), - }) - ) - - // Reading previous query (<3) should work: - await wrb.getQueryData.call(2) - }) - - it("should post a data request to WRB and read the result", async () => { - // The data request to be posted - const drBytes = web3.utils.fromAscii("This is a DR") - const request = await WitnetRequest.new(drBytes) - - // The id of the data request with result "hello" - const id2 = await wrb.postRequest.call(request.address, { - from: requestSender, - value: web3.utils.toWei("0.5", "ether"), - }) - assert.equal(id2, 4) - - // Post the data request through the Proxy - await waitForHash( - wrb.postRequest(request.address, { - from: requestSender, - value: web3.utils.toWei("0.5", "ether"), - }) - ) - - // Read the actual result of the DR - const result = await wrb.readResponseResult.call(id2) - assert.equal(result.value.buffer.data, web3.utils.fromAscii("hello")) - }) - - it("should read the result of a dr of an old wrb", async () => { - // Upgrade the WRB address to wrbInstance3 - await proxy.upgradeWitnetRequestBoard(wrbInstance3.address, { - from: contractOwner, - }) - - // Read the actual result of the DR - const result = await wrb.readResponseResult.call(4) - assert.equal(result.value.buffer.data, web3.utils.fromAscii("hello")) - }) - - it("a solved data request can only be deleted by actual requester", async () => { - // Read the result of the DR just before destruction: - const response = await wrb.deleteQuery.call(4, { from: requestSender }) - const result = await wrb.resultFromCborBytes.call(response.cborBytes) - assert.equal(result.value.buffer.data, web3.utils.fromAscii("hello")) - - await truffleAssert.reverts( - wrb.deleteQuery(4, { from: contractOwner }), - "only requester" - ) - const tx = await wrb.deleteQuery(4, { from: requestSender }) // should work - assert.equal(tx.logs[0].args[1], requestSender) - }) - - it("retrieves null array if trying to get bytecode from deleted DRs", async () => { - const bytecode = await wrb.readRequestBytecode.call(4) - assert(bytecode == null) - }) - - it("fails if trying to upgrade a non upgradable implementation", async () => { - // It should revert when trying to upgrade the wrb since wrbInstance3 is not upgradable - await truffleAssert.reverts( - proxy.upgradeWitnetRequestBoard(wrbInstance1.address, { from: contractOwner }), - "not upgradable" - ) - }) - }) -}) - -const waitForHash = txQ => - new Promise((resolve, reject) => - txQ.on("transactionHash", resolve).catch(reject) - ) - -function decodeWitnetLogs (logs, index) { - if (logs.length > index) { - return web3.eth.abi.decodeLog( - [ - { - type: "uint256", - name: "id", - }, { - type: "address", - name: "from", - }, - ], - logs[index].data, - logs[index].topcis - ) - } -}