Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: optimize RootVerificationModule #7

Merged
merged 8 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions docs/src/content/modules/dispute/root_verification_module.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ The Root Verification Module is a pre-dispute module that allows disputers to ca

### Key Methods

- `decodeRequestData(bytes32 _requestId)`: Returns the decoded data for a request.
- `disputeResponse(bytes32 _requestId, bytes32 _responseId, address _disputer, address _proposer)`: Calculates the correct root and compares it to the proposed one. Updates the dispute status after checking if the disputed response is indeed wrong.
- `onDisputeStatusChange(bytes32 _requestId, IOracle.Dispute memory _dispute)`: Updates the status of the dispute and resolves it by proposing the correct root as a response and finalizing the request.
- `disputeEscalated(bytes32 _disputeId)`: This function is present to comply with the module interface but it is not implemented since this is a pre-dispute module.
- `decodeRequestData`: Returns the decoded data for a request.
- `disputeResponse`: Calculates the correct root and compares it to the proposed one. Updates the dispute status after checking if the disputed response is indeed wrong.
- `onDisputeStatusChange`: Updates the status of the dispute and resolves it by proposing the correct root as a response and finalizing the request.

### Request Parameters

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"package.json": "sort-package-json"
},
"dependencies": {
"@defi-wonderland/prophet-core-contracts": "0.0.0-d05a00d0",
"@defi-wonderland/prophet-core-contracts": "0.0.0-a1d2cc55",
"@defi-wonderland/solidity-utils": "0.0.0-3e9c8e8b",
"@openzeppelin/contracts": "^4.9.3",
"ds-test": "https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0",
Expand Down
189 changes: 95 additions & 94 deletions solidity/contracts/modules/dispute/RootVerificationModule.sol
Original file line number Diff line number Diff line change
@@ -1,94 +1,95 @@
// // SPDX-License-Identifier: MIT
// pragma solidity ^0.8.19;

// // solhint-disable-next-line no-unused-import
// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol';
// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol';

// import {IRootVerificationModule} from '../../../interfaces/modules/dispute/IRootVerificationModule.sol';
// import {MerkleLib} from '../../libraries/MerkleLib.sol';

// contract RootVerificationModule is Module, IRootVerificationModule {
// using MerkleLib for MerkleLib.Tree;

// /**
// * @notice The calculated correct root for a given request
// */
// mapping(bytes32 _requestId => bytes32 _correctRoot) internal _correctRoots;

// constructor(IOracle _oracle) Module(_oracle) {}

// /// @inheritdoc IModule
// function moduleName() external pure returns (string memory _moduleName) {
// return 'RootVerificationModule';
// }

// /// @inheritdoc IRootVerificationModule
// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) {
// _params = abi.decode(requestData[_requestId], (RequestParameters));
// }

// /// @inheritdoc IRootVerificationModule
// function disputeEscalated(bytes32 _disputeId) external onlyOracle {}

// /// @inheritdoc IRootVerificationModule
// function onDisputeStatusChange(bytes32, IOracle.Dispute memory _dispute) external onlyOracle {
// RequestParameters memory _params = decodeRequestData(_dispute.requestId);

// IOracle.Response memory _response = ORACLE.getResponse(_dispute.responseId);

// bool _won = abi.decode(_response.response, (bytes32)) != _correctRoots[_dispute.requestId];

// if (_won) {
// _params.accountingExtension.pay({
// _requestId: _dispute.requestId,
// _payer: _dispute.proposer,
// _receiver: _dispute.disputer,
// _token: _params.bondToken,
// _amount: _params.bondSize
// });
// bytes32 _correctResponseId =
// ORACLE.proposeResponse(_dispute.disputer, _dispute.requestId, abi.encode(_correctRoots[_dispute.requestId]));
// ORACLE.finalize(_dispute.requestId, _correctResponseId);
// } else {
// ORACLE.finalize(_dispute.requestId, _dispute.responseId);
// }

// delete _correctRoots[_dispute.requestId];

// emit DisputeStatusChanged({
// _requestId: _dispute.requestId,
// _responseId: _dispute.responseId,
// _disputer: _dispute.disputer,
// _proposer: _dispute.proposer,
// _status: _dispute.status
// });
// }

// /// @inheritdoc IRootVerificationModule
// function disputeResponse(
// bytes32 _requestId,
// bytes32 _responseId,
// address _disputer,
// address _proposer
// ) external onlyOracle returns (IOracle.Dispute memory _dispute) {
// IOracle.Response memory _response = ORACLE.getResponse(_responseId);
// RequestParameters memory _params = decodeRequestData(_requestId);

// bytes32 _correctRoot = _params.treeVerifier.calculateRoot(_params.treeData, _params.leavesToInsert);
// _correctRoots[_requestId] = _correctRoot;

// bool _won = abi.decode(_response.response, (bytes32)) != _correctRoot;

// _dispute = IOracle.Dispute({
// disputer: _disputer,
// responseId: _responseId,
// proposer: _proposer,
// requestId: _requestId,
// status: _won ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost,
// createdAt: block.timestamp
// });

// emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer);
// }
// }
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

// solhint-disable-next-line no-unused-import
import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol';
import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol';

import {IRootVerificationModule} from '../../../interfaces/modules/dispute/IRootVerificationModule.sol';
import {MerkleLib} from '../../libraries/MerkleLib.sol';

contract RootVerificationModule is Module, IRootVerificationModule {
using MerkleLib for MerkleLib.Tree;

/**
* @notice The calculated correct root for a given request
*/
mapping(bytes32 _requestId => bytes32 _correctRoot) internal _correctRoots;

constructor(IOracle _oracle) Module(_oracle) {}

/// @inheritdoc IModule
function moduleName() external pure returns (string memory _moduleName) {
return 'RootVerificationModule';
}

/// @inheritdoc IRootVerificationModule
function decodeRequestData(bytes calldata _data) public pure returns (RequestParameters memory _params) {
_params = abi.decode(_data, (RequestParameters));
}

/// @inheritdoc IRootVerificationModule
function onDisputeStatusChange(
bytes32 _disputeId,
IOracle.Request calldata _request,
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) external onlyOracle {
// TODO: Call `disputeStatus` to check the current status
RequestParameters memory _params = decodeRequestData(_request.disputeModuleData);

bytes32 _correctRoot = _correctRoots[_dispute.requestId];
bool _won = abi.decode(_response.response, (bytes32)) != _correctRoot;

if (_won) {
_params.accountingExtension.pay({
_requestId: _dispute.requestId,
_payer: _dispute.proposer,
_receiver: _dispute.disputer,
_token: _params.bondToken,
_amount: _params.bondSize
});

IOracle.Response memory _newResponse = IOracle.Response({
requestId: _dispute.requestId,
proposer: _dispute.disputer,
response: abi.encode(_correctRoot)
});

emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Won});

ORACLE.proposeResponse(_request, _newResponse);
ORACLE.finalize(_request, _newResponse);
} else {
emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Lost});
ORACLE.finalize(_request, _response);
}

delete _correctRoots[_dispute.requestId];
}

/// @inheritdoc IRootVerificationModule
function disputeResponse(
IOracle.Request calldata _request,
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) external onlyOracle {
RequestParameters memory _params = decodeRequestData(_request.disputeModuleData);

bytes32 _correctRoot = _params.treeVerifier.calculateRoot(_params.treeData, _params.leavesToInsert);
_correctRoots[_response.requestId] = _correctRoot;

IOracle.DisputeStatus _status =
abi.decode(_response.response, (bytes32)) != _correctRoot ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost;

emit ResponseDisputed({
_requestId: _response.requestId,
_responseId: _dispute.responseId,
_disputeId: _getId(_dispute),
_dispute: _dispute,
_blockNumber: block.number
});

ORACLE.updateDisputeStatus(_request, _response, _dispute, _status);
}
}
Loading