From 7ffc17df2cd0e35bc90c62625a924a7c7ed81011 Mon Sep 17 00:00:00 2001 From: Web3 Philosopher Date: Wed, 28 Feb 2024 14:55:59 +0100 Subject: [PATCH] API refactor (#16) * some api changes * add missing files --- src/IDispatcher.sol | 71 ++++++++++++++++++++++++++++++++++ src/IHandler.sol | 2 +- src/IIsmpHost.sol | 38 ++++++++++-------- src/IIsmpModule.sol | 29 +++++++++++++- src/{IIsmp.sol => Message.sol} | 68 +------------------------------- src/StateMachine.sol | 16 ++++---- 6 files changed, 131 insertions(+), 93 deletions(-) create mode 100644 src/IDispatcher.sol rename src/{IIsmp.sol => Message.sol} (72%) diff --git a/src/IDispatcher.sol b/src/IDispatcher.sol new file mode 100644 index 0000000..3c2b47f --- /dev/null +++ b/src/IDispatcher.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.17; + +import {StateMachineHeight} from "./IConsensusClient.sol"; +import {PostRequest} from "./Message.sol"; + +// An object for dispatching post requests to the IsmpDispatcher +struct DispatchPost { + // bytes representation of the destination state machine + bytes dest; + // the destination module + bytes to; + // the request body + bytes body; + // timeout for this request in seconds + uint64 timeout; + // gas limit for executing this request on destination & its response (if any) on the source. + uint64 gaslimit; + // the amount put up to be paid to the relayer, this is in $DAI and charged to tx.origin + uint256 fee; +} + +// An object for dispatching get requests to the IsmpDispatcher +struct DispatchGet { + // bytes representation of the destination state machine + bytes dest; + // height at which to read the state machine + uint64 height; + // Storage keys to read + bytes[] keys; + // timeout for this request in seconds + uint64 timeout; + // gas limit for executing this request on destination & its response (if any) on the source. + uint64 gaslimit; + // the amount put up to be paid to the relayer, this is in $DAI and charged to tx.origin + uint256 fee; +} + +struct DispatchPostResponse { + // The request that initiated this response + PostRequest request; + // bytes for post response + bytes response; + // timeout for this response in seconds + uint64 timeout; + // gas limit for executing this response on destination which is the source of the request. + uint64 gaslimit; + // the amount put up to be paid to the relayer, this is in $DAI and charged to tx.origin + uint256 fee; +} + +// The core ISMP API, IIsmpModules use this interface to send outgoing get/post requests & responses +interface IDispatcher { + /** + * @dev Dispatch a post request to the ISMP router. + * @param request - post request + */ + function dispatch(DispatchPost memory request) external; + + /** + * @dev Dispatch a GET request to the ISMP router. + * @param request - get request + */ + function dispatch(DispatchGet memory request) external; + + /** + * @dev Provide a response to a previously received request. + * @param response - post response + */ + function dispatch(DispatchPostResponse memory response) external; +} diff --git a/src/IHandler.sol b/src/IHandler.sol index 76f0fdf..2104682 100644 --- a/src/IHandler.sol +++ b/src/IHandler.sol @@ -9,7 +9,7 @@ import { PostRequestTimeoutMessage, PostResponseTimeoutMessage, GetTimeoutMessage -} from "./IIsmp.sol"; +} from "./Message.sol"; /* The IHandler interface serves as the entry point for ISMP datagrams, i.e consensus, requests & response messages. diff --git a/src/IIsmpHost.sol b/src/IIsmpHost.sol index 769b114..a7917f1 100644 --- a/src/IIsmpHost.sol +++ b/src/IIsmpHost.sol @@ -2,7 +2,8 @@ pragma solidity 0.8.17; import {StateCommitment, StateMachineHeight} from "./IConsensusClient.sol"; -import {IIsmp, PostRequest, PostResponse, GetResponse, PostTimeout, GetRequest} from "./IIsmp.sol"; +import {IDispatcher} from "./IDispatcher.sol"; +import {PostRequest, PostResponse, GetResponse, PostTimeout, GetRequest} from "./Message.sol"; // Some metadata about the request struct FeeMetadata { @@ -19,7 +20,7 @@ struct ResponseReceipt { address relayer; } -interface IIsmpHost is IIsmp { +interface IIsmpHost is IDispatcher { /** * @return the host admin */ @@ -28,22 +29,27 @@ interface IIsmpHost is IIsmp { /** * @return the address of the DAI ERC-20 contract on this state machine */ - function dai() external returns (address); + function dai() external view returns (address); + + /** + * @return the per-byte fee for outgoing requests. + */ + function perByteFee() external view returns (uint256); /** * @return the host state machine id */ - function host() external returns (bytes memory); + function host() external view returns (bytes memory); /** * @return the host timestamp */ - function timestamp() external returns (uint256); + function timestamp() external view returns (uint256); /** * @return the `frozen` status */ - function frozen() external returns (bool); + function frozen() external view returns (bool); /** * @param height - state machine height @@ -61,56 +67,56 @@ interface IIsmpHost is IIsmp { * @dev Should return a handle to the consensus client based on the id * @return the consensus client contract */ - function consensusClient() external returns (address); + function consensusClient() external view returns (address); /** * @return the last updated time of the consensus client */ - function consensusUpdateTime() external returns (uint256); + function consensusUpdateTime() external view returns (uint256); /** * @return the latest state machine height */ - function latestStateMachineHeight() external returns (uint256); + function latestStateMachineHeight() external view returns (uint256); /** * @return the state of the consensus client */ - function consensusState() external returns (bytes memory); + function consensusState() external view returns (bytes memory); /** * @param commitment - commitment to the request * @return relayer address */ - function requestReceipts(bytes32 commitment) external returns (address); + function requestReceipts(bytes32 commitment) external view returns (address); /** * @param commitment - commitment to the request of the response * @return response receipt */ - function responseReceipts(bytes32 commitment) external returns (ResponseReceipt memory); + function responseReceipts(bytes32 commitment) external view returns (ResponseReceipt memory); /** * @param commitment - commitment to the request * @return existence status of an outgoing request commitment */ - function requestCommitments(bytes32 commitment) external returns (FeeMetadata memory); + function requestCommitments(bytes32 commitment) external view returns (FeeMetadata memory); /** * @param commitment - commitment to the response * @return existence status of an outgoing response commitment */ - function responseCommitments(bytes32 commitment) external returns (FeeMetadata memory); + function responseCommitments(bytes32 commitment) external view returns (FeeMetadata memory); /** * @return the challenge period */ - function challengePeriod() external returns (uint256); + function challengePeriod() external view returns (uint256); /** * @return the unstaking period */ - function unStakingPeriod() external returns (uint256); + function unStakingPeriod() external view returns (uint256); /** * @dev Store an encoded consensus state diff --git a/src/IIsmpModule.sol b/src/IIsmpModule.sol index 5c231b0..99f234d 100644 --- a/src/IIsmpModule.sol +++ b/src/IIsmpModule.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17; -import {PostRequest, PostResponse, GetResponse, GetRequest} from "./IIsmp.sol"; +import {PostRequest, PostResponse, GetResponse, GetRequest} from "./Message.sol"; interface IIsmpModule { /** @@ -40,3 +40,30 @@ interface IIsmpModule { */ function onGetTimeout(GetRequest memory request) external; } + +/// Abstract contract to make implementing `IIsmpModule` easier. +abstract contract BaseIsmpModule is IIsmpModule { + function onAccept(PostRequest calldata) external virtual { + revert("IsmpModule doesn't expect Post requests"); + } + + function onPostRequestTimeout(PostRequest memory) external virtual { + revert("IsmpModule doesn't emit Post requests"); + } + + function onPostResponse(PostResponse memory) external virtual { + revert("IsmpModule doesn't emit Post responses"); + } + + function onPostResponseTimeout(PostResponse memory) external virtual { + revert("IsmpModule doesn't emit Post responses"); + } + + function onGetResponse(GetResponse memory) external virtual { + revert("IsmpModule doesn't emit Get requests"); + } + + function onGetTimeout(GetRequest memory) external virtual { + revert("IsmpModule doesn't emit Get requests"); + } +} diff --git a/src/IIsmp.sol b/src/Message.sol similarity index 72% rename from src/IIsmp.sol rename to src/Message.sol index 74e686c..51f00ce 100644 --- a/src/IIsmp.sol +++ b/src/Message.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17; -import {StorageValue} from "solidity-merkle-trees/MerklePatricia.sol"; import {StateMachineHeight} from "./IConsensusClient.sol"; +import {StorageValue} from "solidity-merkle-trees/MerklePatricia.sol"; struct PostRequest { // the source state machine of this request @@ -143,72 +143,6 @@ struct PostResponseMessage { PostResponseLeaf[] responses; } -// An object for dispatching post requests to the IsmpDispatcher -struct DispatchPost { - // bytes representation of the destination state machine - bytes dest; - // the destination module - bytes to; - // the request body - bytes body; - // timeout for this request in seconds - uint64 timeout; - // gas limit for executing this request on destination & its response (if any) on the source. - uint64 gaslimit; - // the amount put up to be paid to the relayer, this is in $DAI and charged to tx.origin - uint256 fee; -} - -// An object for dispatching get requests to the IsmpDispatcher -struct DispatchGet { - // bytes representation of the destination state machine - bytes dest; - // height at which to read the state machine - uint64 height; - // Storage keys to read - bytes[] keys; - // timeout for this request in seconds - uint64 timeout; - // gas limit for executing this request on destination & its response (if any) on the source. - uint64 gaslimit; - // the amount put up to be paid to the relayer, this is in $DAI and charged to tx.origin - uint256 fee; -} - -struct DispatchPostResponse { - // The request that initiated this response - PostRequest request; - // bytes for post response - bytes response; - // timeout for this response in seconds - uint64 timeout; - // gas limit for executing this response on destination which is the source of the request. - uint64 gaslimit; - // the amount put up to be paid to the relayer, this is in $DAI and charged to tx.origin - uint256 fee; -} - -// The core ISMP API, IIsmpModules use this interface to send outgoing get/post requests & responses -interface IIsmp { - /** - * @dev Dispatch a post request to the ISMP router. - * @param request - post request - */ - function dispatch(DispatchPost memory request) external; - - /** - * @dev Dispatch a GET request to the ISMP router. - * @param request - get request - */ - function dispatch(DispatchGet memory request) external; - - /** - * @dev Provide a response to a previously received request. - * @param response - post response - */ - function dispatch(DispatchPostResponse memory response) external; -} - library Message { function timeout(PostRequest memory req) internal pure returns (uint64) { if (req.timeoutTimestamp == 0) { diff --git a/src/StateMachine.sol b/src/StateMachine.sol index 4755725..487e295 100644 --- a/src/StateMachine.sol +++ b/src/StateMachine.sol @@ -8,42 +8,42 @@ library StateMachine { uint256 public constant RELAY_CHAIN = 0; // Address a state machine on the polkadot relay chain - function polkadot(uint256 id) public pure returns (bytes memory) { + function polkadot(uint256 id) internal pure returns (bytes memory) { return bytes(string.concat("POLKADOT-", Strings.toString(id))); } // Address a state machine on the kusama relay chain - function kusama(uint256 id) public pure returns (bytes memory) { + function kusama(uint256 id) internal pure returns (bytes memory) { return bytes(string.concat("KUSAMA-", Strings.toString(id))); } // Address the ethereum "execution layer" - function ethereum() public pure returns (bytes memory) { + function ethereum() internal pure returns (bytes memory) { return bytes("ETHE"); } // Address the Arbitrum state machine - function arbitrum() public pure returns (bytes memory) { + function arbitrum() internal pure returns (bytes memory) { return bytes("ARBI"); } // Address the Optimism state machine - function optimism() public pure returns (bytes memory) { + function optimism() internal pure returns (bytes memory) { return bytes("OPTI"); } // Address the Base state machine - function base() public pure returns (bytes memory) { + function base() internal pure returns (bytes memory) { return bytes("BASE"); } // Address the Polygon POS state machine - function polygon() public pure returns (bytes memory) { + function polygon() internal pure returns (bytes memory) { return bytes("POLY"); } // Address the Binance smart chain state machine - function bsc() public pure returns (bytes memory) { + function bsc() internal pure returns (bytes memory) { return bytes("BSC"); } }