From 5fbc672058d64f57c1df72def95677cf07e80629 Mon Sep 17 00:00:00 2001 From: Gas One Cent <86567384+gas1cent@users.noreply.github.com> Date: Wed, 22 Nov 2023 13:24:52 +0400 Subject: [PATCH] feat: provide IPFS hash to create requests --- solidity/contracts/Oracle.sol | 16 ++++++++++------ solidity/interfaces/IOracle.sol | 14 +++++++++++--- solidity/test/integration/ResponseDispute.t.sol | 4 ++-- solidity/test/unit/Oracle.t.sol | 15 ++++++++++----- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/solidity/contracts/Oracle.sol b/solidity/contracts/Oracle.sol index bdf9242..e4fd462 100644 --- a/solidity/contracts/Oracle.sol +++ b/solidity/contracts/Oracle.sol @@ -53,17 +53,20 @@ contract Oracle is IOracle { uint256 public totalRequestCount; /// @inheritdoc IOracle - function createRequest(Request calldata _request) external returns (bytes32 _requestId) { - _requestId = _createRequest(_request); + function createRequest(Request calldata _request, bytes32 _ipfsHash) external returns (bytes32 _requestId) { + _requestId = _createRequest(_request, _ipfsHash); } /// @inheritdoc IOracle - function createRequests(Request[] calldata _requestsData) external returns (bytes32[] memory _batchRequestsIds) { + function createRequests( + Request[] calldata _requestsData, + bytes32[] calldata _ipfsHashes + ) external returns (bytes32[] memory _batchRequestsIds) { uint256 _requestsAmount = _requestsData.length; _batchRequestsIds = new bytes32[](_requestsAmount); for (uint256 _i = 0; _i < _requestsAmount;) { - _batchRequestsIds[_i] = _createRequest(_requestsData[_i]); + _batchRequestsIds[_i] = _createRequest(_requestsData[_i], _ipfsHashes[_i]); unchecked { ++_i; } @@ -372,9 +375,10 @@ contract Oracle is IOracle { * @notice Stores a request in the contract and configures it in the modules * * @param _request The request to be created + * @param _ipfsHash The hashed IPFS CID of the metadata json * @return _requestId The id of the created request */ - function _createRequest(Request calldata _request) internal returns (bytes32 _requestId) { + function _createRequest(Request calldata _request, bytes32 _ipfsHash) internal returns (bytes32 _requestId) { uint256 _requestNonce = totalRequestCount++; // @audit what about removing nonces? or how we avoid nonce clashing? @@ -396,7 +400,7 @@ contract Oracle is IOracle { _participants[_requestId] = abi.encodePacked(_participants[_requestId], msg.sender); IRequestModule(_request.requestModule).createRequest(_requestId, _request.requestModuleData, msg.sender); - emit RequestCreated(_requestId, _request, block.number); + emit RequestCreated(_requestId, _request, _ipfsHash, block.number); } /** diff --git a/solidity/interfaces/IOracle.sol b/solidity/interfaces/IOracle.sol index d50e714..abacfd1 100644 --- a/solidity/interfaces/IOracle.sol +++ b/solidity/interfaces/IOracle.sol @@ -13,8 +13,11 @@ interface IOracle { /** * @notice Emitted when a request is created * @param _requestId The id of the created request + * @param _request The request that has been created + * @param _ipfsHash The hashed IPFS CID of the metadata json + * @param _blockNumber The current block number */ - event RequestCreated(bytes32 indexed _requestId, Request _request, uint256 _blockNumber); + event RequestCreated(bytes32 indexed _requestId, Request _request, bytes32 _ipfsHash, uint256 _blockNumber); /** * @notice Emitted when a response is proposed @@ -279,17 +282,22 @@ interface IOracle { * * @dev The modules must be real contracts following the IModule interface * @param _request The request data + * @param _ipfsHash The hashed IPFS CID of the metadata json * @return _requestId The id of the request, can be used to propose a response or query results */ - function createRequest(Request memory _request) external returns (bytes32 _requestId); + function createRequest(Request memory _request, bytes32 _ipfsHash) external returns (bytes32 _requestId); /** * @notice Creates multiple requests, the same way as createRequest * * @param _requestsData The array of calldata for each request * @return _batchRequestsIds The array of request IDs + * @param _ipfsHashes The array of hashed IPFS CIDs of the metadata files */ - function createRequests(Request[] calldata _requestsData) external returns (bytes32[] memory _batchRequestsIds); + function createRequests( + Request[] calldata _requestsData, + bytes32[] calldata _ipfsHashes + ) external returns (bytes32[] memory _batchRequestsIds); /** * @notice Returns the list of request IDs diff --git a/solidity/test/integration/ResponseDispute.t.sol b/solidity/test/integration/ResponseDispute.t.sol index 85a3230..8a0d258 100644 --- a/solidity/test/integration/ResponseDispute.t.sol +++ b/solidity/test/integration/ResponseDispute.t.sol @@ -92,7 +92,7 @@ contract Integration_ResponseDispute is IntegrationBase { }); vm.prank(requester); - _requestId = oracle.createRequest(_request); + _requestId = oracle.createRequest(_request, _ipfsHash); IOracle.Response memory _response = IOracle.Response({requestId: _requestId, response: abi.encode('testResponse'), proposer: proposer}); @@ -190,7 +190,7 @@ contract Integration_ResponseDispute is IntegrationBase { // ipfsHash: _ipfsHash // }); // vm.prank(requester); - // bytes32 _secondRequest = oracle.createRequest(_request); + // bytes32 _secondRequest = oracle.createRequest(_request, _ipfsHash); // vm.prank(proposer); // bytes32 _secondResponseId = oracle.proposeResponse(_secondRequest, _responseData, _responseModuleData); diff --git a/solidity/test/unit/Oracle.t.sol b/solidity/test/unit/Oracle.t.sol index 60b6920..4057117 100644 --- a/solidity/test/unit/Oracle.t.sol +++ b/solidity/test/unit/Oracle.t.sol @@ -80,8 +80,11 @@ contract BaseTest is Test, Helpers { IResolutionModule public resolutionModule = IResolutionModule(_mockContract('resolutionModule')); IFinalityModule public finalityModule = IFinalityModule(_mockContract('finalityModule')); + // Mock IPFS hash + bytes32 internal _ipfsHash = bytes32('QmR4uiJH654k3Ta2uLLQ8r'); + // Events - event RequestCreated(bytes32 indexed _requestId, IOracle.Request _request, uint256 _blockNumber); + event RequestCreated(bytes32 indexed _requestId, IOracle.Request _request, bytes32 _ipfsHash, uint256 _blockNumber); event ResponseProposed( bytes32 indexed _requestId, bytes32 indexed _responseId, IOracle.Response _response, uint256 _blockNumber ); @@ -150,11 +153,11 @@ contract Unit_CreateRequest is BaseTest { // Check: emits RequestCreated event? _expectEmit(address(oracle)); - emit RequestCreated(_getId(mockRequest), mockRequest, block.number); + emit RequestCreated(_getId(mockRequest), mockRequest, _ipfsHash, block.number); // Test: create the request vm.prank(requester); - bytes32 _requestId = oracle.createRequest(mockRequest); + bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash); // Check: Adds the requester to the list of participants assertTrue(oracle.isParticipant(_requestId, requester)); @@ -197,6 +200,7 @@ contract Unit_CreateRequests is BaseTest { IOracle.Request[] memory _requests = new IOracle.Request[](_requestsAmount); bytes32[] memory _precalculatedIds = new bytes32[](_requestsAmount); bool _useResolutionAndFinality = _requestData.length % 2 == 0; + bytes32[] memory _ipfsHashes = new bytes32[](_requestsAmount); // Generate requests batch for (uint256 _i = 0; _i < _requestsAmount; _i++) { @@ -209,14 +213,15 @@ contract Unit_CreateRequests is BaseTest { bytes32 _theoreticalRequestId = _getId(mockRequest); _requests[_i] = mockRequest; _precalculatedIds[_i] = _theoreticalRequestId; + _ipfsHashes[_i] = keccak256(abi.encode(_theoreticalRequestId, mockRequest.nonce)); // Check: emits RequestCreated event? _expectEmit(address(oracle)); - emit RequestCreated(_theoreticalRequestId, mockRequest, block.number); + emit RequestCreated(_theoreticalRequestId, mockRequest, _ipfsHashes[_i], block.number); } vm.prank(requester); - bytes32[] memory _requestsIds = oracle.createRequests(_requests); + bytes32[] memory _requestsIds = oracle.createRequests(_requests, _ipfsHashes); for (uint256 _i = 0; _i < _requestsIds.length; _i++) { assertEq(_requestsIds[_i], _precalculatedIds[_i]);