Skip to content

Commit e3b8a8e

Browse files
authored
Opaque IDs for ethereum state machines (#270)
1 parent e0c8e43 commit e3b8a8e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+548
-602
lines changed

docs/pages/developers/polkadot/modules.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub mod pallet {
2222
use super::*;
2323
use frame_support::{pallet_prelude::*, PalletId};
2424
use pallet_ismp::ModuleId;
25-
use ismp::host::Ethereum;
25+
use ismp::host::ethereum;
2626

2727
pub const EXAMPLE_MODULE_ID: ModuleId = ModuleId::Pallet(PalletId(*b"EXPL-MOD"));
2828

docs/pages/developers/polkadot/rpc.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ This rpc method accepts a state machine id and returns the latest height of a st
158158
.await.unwrap();
159159
let consensus_state_id = *b"ETH0";
160160
let state_machine_id = StateMachineId {
161-
state_id: StateMachine::Ethereum(Ethereum::ExecutionLayer),
161+
state_id: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
162162
consensus_state_id
163163
};
164164
let params = rpc_params![state_machine_id];

evm/abi/src/generated/host_manager.rs

+2-2
Large diffs are not rendered by default.

evm/abi/src/generated/ping_module.rs

+2-2
Large diffs are not rendered by default.

evm/integration-tests/src/tests/get_response.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ethers::{
55
};
66
use forge_testsuite::Runner;
77
use ismp::{
8-
host::{Ethereum, StateMachine},
8+
host::{ethereum, StateMachine},
99
messaging::hash_request,
1010
router::{self, Request},
1111
};
@@ -32,7 +32,7 @@ async fn test_get_response() -> Result<(), anyhow::Error> {
3232
// create post request object
3333
let get = router::GetRequest {
3434
dest: StateMachine::Polkadot(2000),
35-
source: StateMachine::Ethereum(Ethereum::ExecutionLayer),
35+
source: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
3636
nonce: 0,
3737
from: destination.as_bytes().to_vec(),
3838
keys: vec![key.clone()],

evm/integration-tests/src/tests/get_timeout.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use ethers::abi::{Address, Tokenizable};
22
use forge_testsuite::Runner;
33
use ismp::{
4-
host::{Ethereum, StateMachine},
4+
host::{ethereum, StateMachine},
55
router,
66
};
77
use ismp_solidity_abi::shared_types::GetRequest;
@@ -20,7 +20,7 @@ async fn test_get_timeout() -> Result<(), anyhow::Error> {
2020
// create post request object
2121
let get = router::GetRequest {
2222
dest: StateMachine::Polkadot(2000),
23-
source: StateMachine::Ethereum(Ethereum::ExecutionLayer),
23+
source: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
2424
nonce: 0,
2525
from: destination.as_bytes().to_vec(),
2626
keys: vec![key.clone()],

evm/integration-tests/src/tests/host_manager.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use ethers::abi::Tokenizable;
22
use forge_testsuite::Runner;
33
use foundry_evm::executor::EvmError;
44
use ismp::{
5-
host::{Ethereum, StateMachine},
5+
host::{ethereum, StateMachine},
66
router,
77
};
88
use ismp_solidity_abi::{evm_host::HostParams, shared_types::PostRequest};
@@ -27,7 +27,7 @@ async fn test_host_manager_withdraw() -> Result<(), anyhow::Error> {
2727
// create post request object
2828
let post = router::PostRequest {
2929
source: StateMachine::Kusama(2000),
30-
dest: StateMachine::Ethereum(Ethereum::ExecutionLayer),
30+
dest: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
3131
nonce: 0,
3232
from: contract.runner.sender.as_bytes().to_vec(),
3333
to: vec![],
@@ -60,7 +60,7 @@ async fn test_host_manager_unauthorized_request() -> Result<(), anyhow::Error> {
6060
let post = router::PostRequest {
6161
// wrong source
6262
source: StateMachine::Polkadot(1000),
63-
dest: StateMachine::Ethereum(Ethereum::ExecutionLayer),
63+
dest: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
6464
nonce: 0,
6565
from: contract.runner.sender.as_bytes().to_vec(),
6666
to: vec![],
@@ -100,7 +100,7 @@ async fn test_host_manager_insufficient_balance() -> Result<(), anyhow::Error> {
100100
// create post request object
101101
let post = router::PostRequest {
102102
source: StateMachine::Kusama(2000),
103-
dest: StateMachine::Ethereum(Ethereum::ExecutionLayer),
103+
dest: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
104104
nonce: 0,
105105
from: contract.runner.sender.as_bytes().to_vec(),
106106
to: vec![],
@@ -170,7 +170,7 @@ async fn test_host_manager_set_host_params() -> Result<(), anyhow::Error> {
170170
// create post request object
171171
let post = router::PostRequest {
172172
source: StateMachine::Kusama(2000),
173-
dest: StateMachine::Ethereum(Ethereum::ExecutionLayer),
173+
dest: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
174174
nonce: 0,
175175
from: contract.runner.sender.as_bytes().to_vec(),
176176
to: vec![],

evm/integration-tests/src/tests/post_request.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ethers::{
55
};
66
use forge_testsuite::Runner;
77
use ismp::{
8-
host::{Ethereum, StateMachine},
8+
host::{ethereum, StateMachine},
99
router::{PostRequest, Request},
1010
};
1111
use ismp_solidity_abi::{
@@ -27,7 +27,7 @@ async fn test_post_request_proof() -> Result<(), anyhow::Error> {
2727
// create post request object
2828
let post = PostRequest {
2929
source: StateMachine::Polkadot(2000),
30-
dest: StateMachine::Ethereum(Ethereum::ExecutionLayer),
30+
dest: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
3131
nonce: 0,
3232
from: contract.runner.sender.as_bytes().to_vec(),
3333
to: destination.as_bytes().to_vec(),

evm/integration-tests/src/tests/post_response.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use ethers::{
99
use forge_testsuite::Runner;
1010
use hex_literal::hex;
1111
use ismp::{
12-
host::{Ethereum, StateMachine},
12+
host::{ethereum, StateMachine},
1313
messaging::hash_response,
1414
router::{self, Request, Response},
1515
};
@@ -37,7 +37,7 @@ async fn test_post_response_proof() -> Result<(), anyhow::Error> {
3737

3838
// create post request object
3939
let post = router::PostRequest {
40-
source: StateMachine::Ethereum(Ethereum::ExecutionLayer),
40+
source: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
4141
dest: StateMachine::Polkadot(2000),
4242
nonce: 0,
4343
from: module.as_bytes().to_vec(),
@@ -114,7 +114,7 @@ async fn test_post_response_timeout() -> Result<(), anyhow::Error> {
114114
// create post request object
115115
let post = router::PostRequest {
116116
source: StateMachine::Polkadot(2000),
117-
dest: StateMachine::Ethereum(Ethereum::ExecutionLayer),
117+
dest: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
118118
nonce: 0,
119119
from: contract.runner.sender.as_bytes().to_vec(),
120120
to: destination.as_bytes().to_vec(),
@@ -202,7 +202,7 @@ async fn test_post_response_malicious_timeout() -> Result<(), anyhow::Error> {
202202
// create post request object
203203
let post = router::PostRequest {
204204
source: StateMachine::Polkadot(2000),
205-
dest: StateMachine::Ethereum(Ethereum::ExecutionLayer),
205+
dest: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
206206
nonce: 0,
207207
from: contract.runner.sender.as_bytes().to_vec(),
208208
to: destination.as_bytes().to_vec(),

evm/integration-tests/src/tests/post_timeout.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use ethers::{
77
use forge_testsuite::Runner;
88
use hex_literal::hex;
99
use ismp::{
10-
host::{Ethereum, StateMachine},
10+
host::{ethereum, StateMachine},
1111
messaging::hash_request,
1212
router::{self, Request},
1313
};
@@ -30,7 +30,7 @@ async fn test_post_timeout_proof() -> Result<(), anyhow::Error> {
3030

3131
// create post request object
3232
let post = router::PostRequest {
33-
source: StateMachine::Ethereum(Ethereum::ExecutionLayer),
33+
source: StateMachine::Ethereum(ethereum::EXECUTION_LAYER),
3434
dest: StateMachine::Polkadot(2000),
3535
nonce: 0,
3636
from: module.as_bytes().to_vec(),

evm/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"license": "ISC",
1515
"description": "",
1616
"dependencies": {
17-
"@polytope-labs/ismp-solidity": "^0.3.0",
17+
"@polytope-labs/ismp-solidity": "^0.3.1",
1818
"@polytope-labs/solidity-merkle-trees": "^0.2.3",
1919
"@uniswap/v2-periphery": "^1.1.0-beta.0",
2020
"openzeppelin-solidity": "4.8.1",

evm/src/hosts/EvmHost.sol

+73-73
Original file line numberDiff line numberDiff line change
@@ -509,14 +509,6 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context {
509509
return _hostParams.stateCommitmentFee;
510510
}
511511

512-
/**
513-
* @dev Returns the fisherman responsible for vetoing the given state machine height.
514-
* @return the `fisherman` address
515-
*/
516-
function vetoes(uint256 paraId, uint256 height) external view returns (address) {
517-
return _vetoes[paraId][height];
518-
}
519-
520512
/**
521513
* @dev Returns the nonce immediately available for requests
522514
* @return the `nonce`
@@ -525,51 +517,6 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context {
525517
return _nonce;
526518
}
527519

528-
/**
529-
* @notice Charges the stateCommitmentFee to 3rd party applications.
530-
* If native tokens are provided, will attempt to swap them for the stateCommitmentFee.
531-
* If not enough native tokens are supplied, will revert.
532-
*
533-
* If no native tokens are provided then it will try to collect payment from the calling contract in
534-
* the IIsmpHost.feeToken.
535-
*
536-
* @param height - state machine height
537-
* @return the state commitment at `height`
538-
*/
539-
function stateMachineCommitment(
540-
StateMachineHeight memory height
541-
) external payable returns (StateCommitment memory) {
542-
address caller = _msgSender();
543-
if (caller != _hostParams.handler) {
544-
uint256 fee = _hostParams.stateCommitmentFee;
545-
if (msg.value > 0) {
546-
address[] memory path = new address[](2);
547-
address uniswapV2 = _hostParams.uniswapV2;
548-
path[0] = IUniswapV2Router02(uniswapV2).WETH();
549-
path[1] = feeToken();
550-
IUniswapV2Router02(uniswapV2).swapETHForExactTokens{value: msg.value}(
551-
fee,
552-
path,
553-
address(this),
554-
block.timestamp
555-
);
556-
} else {
557-
SafeERC20.safeTransferFrom(IERC20(feeToken()), caller, address(this), fee);
558-
}
559-
emit StateCommitmentRead({caller: caller, fee: fee});
560-
}
561-
562-
return _stateCommitments[height.stateMachineId][height.height];
563-
}
564-
565-
/**
566-
* @param height - state machine height
567-
* @return the state machine update time at `height`
568-
*/
569-
function stateMachineCommitmentUpdateTime(StateMachineHeight memory height) external view returns (uint256) {
570-
return _stateCommitmentsUpdateTime[height.stateMachineId][height.height];
571-
}
572-
573520
/**
574521
* @dev Should return a handle to the consensus client based on the id
575522
* @return the consensus client contract
@@ -599,6 +546,13 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context {
599546
return _hostParams.challengePeriod;
600547
}
601548

549+
/**
550+
* @return the unstaking period
551+
*/
552+
function unStakingPeriod() external view returns (uint256) {
553+
return _hostParams.unStakingPeriod;
554+
}
555+
602556
/**
603557
* @dev Check the response status for a given request.
604558
* @param commitment - commitment to the request
@@ -615,13 +569,6 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context {
615569
return _latestStateMachineHeight[id];
616570
}
617571

618-
/**
619-
* @return the unstaking period
620-
*/
621-
function unStakingPeriod() external view returns (uint256) {
622-
return _hostParams.unStakingPeriod;
623-
}
624-
625572
/**
626573
* @param commitment - commitment to the request
627574
* @return existence status of an incoming request commitment
@@ -654,6 +601,59 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context {
654601
return _responseCommitments[commitment];
655602
}
656603

604+
/**
605+
* @dev Returns the fisherman responsible for vetoing the given state machine height.
606+
* @return the `fisherman` address
607+
*/
608+
function vetoes(uint256 paraId, uint256 height) external view returns (address) {
609+
return _vetoes[paraId][height];
610+
}
611+
612+
/**
613+
* @param height - state machine height
614+
* @return the state machine update time at `height`
615+
*/
616+
function stateMachineCommitmentUpdateTime(StateMachineHeight memory height) external view returns (uint256) {
617+
return _stateCommitmentsUpdateTime[height.stateMachineId][height.height];
618+
}
619+
620+
/**
621+
* @notice Charges the stateCommitmentFee to 3rd party applications.
622+
* If native tokens are provided, will attempt to swap them for the stateCommitmentFee.
623+
* If not enough native tokens are supplied, will revert.
624+
*
625+
* If no native tokens are provided then it will try to collect payment from the calling contract in
626+
* the IIsmpHost.feeToken.
627+
*
628+
* @param height - state machine height
629+
* @return the state commitment at `height`
630+
*/
631+
function stateMachineCommitment(
632+
StateMachineHeight memory height
633+
) external payable returns (StateCommitment memory) {
634+
address caller = _msgSender();
635+
if (caller != _hostParams.handler) {
636+
uint256 fee = _hostParams.stateCommitmentFee;
637+
if (msg.value > 0) {
638+
address[] memory path = new address[](2);
639+
address uniswapV2 = _hostParams.uniswapV2;
640+
path[0] = IUniswapV2Router02(uniswapV2).WETH();
641+
path[1] = feeToken();
642+
IUniswapV2Router02(uniswapV2).swapETHForExactTokens{value: msg.value}(
643+
fee,
644+
path,
645+
address(this),
646+
block.timestamp
647+
);
648+
} else {
649+
SafeERC20.safeTransferFrom(IERC20(feeToken()), caller, address(this), fee);
650+
}
651+
emit StateCommitmentRead({caller: caller, fee: fee});
652+
}
653+
654+
return _stateCommitments[height.stateMachineId][height.height];
655+
}
656+
657657
/**
658658
* @dev Updates the HostParams, can only be called by cross-chain governance
659659
* @param params, the new host params.
@@ -705,7 +705,7 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context {
705705
address(params.consensusClient).code.length == 0 ||
706706
!IERC165(params.consensusClient).supportsInterface(type(IConsensusClient).interfaceId)
707707
) {
708-
// otherwise cannot process new datagrams
708+
// otherwise cannot process new consensus datagrams
709709
revert InvalidConsensusClient();
710710
}
711711
uint256 stateMachinesLen = params.stateMachines.length;
@@ -1189,6 +1189,18 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context {
11891189
* @return commitment - the request commitment
11901190
*/
11911191
function dispatch(DispatchPostResponse memory post) external payable notFrozen returns (bytes32 commitment) {
1192+
bytes32 receipt = post.request.hash();
1193+
address caller = _msgSender();
1194+
1195+
// known request?
1196+
if (_requestReceipts[receipt] == address(0)) revert UnknownRequest();
1197+
1198+
// check that the authorized application is issuing this response
1199+
if (_bytesToAddress(post.request.to) != caller) revert UnauthorizedResponse();
1200+
1201+
// check that request has not already been respond to
1202+
if (_responded[receipt]) revert DuplicateResponse();
1203+
11921204
// minimum charge is the size of one word
11931205
uint256 length = 32 > post.response.length ? 32 : post.response.length;
11941206
uint256 fee = (_hostParams.perByteFee * length) + post.fee;
@@ -1208,18 +1220,6 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context {
12081220
SafeERC20.safeTransferFrom(IERC20(feeToken()), _msgSender(), address(this), fee);
12091221
}
12101222

1211-
bytes32 receipt = post.request.hash();
1212-
address caller = _msgSender();
1213-
1214-
// known request?
1215-
if (_requestReceipts[receipt] == address(0)) revert UnknownRequest();
1216-
1217-
// check that the authorized application is issuing this response
1218-
if (_bytesToAddress(post.request.to) != caller) revert UnauthorizedResponse();
1219-
1220-
// check that request has not already been respond to
1221-
if (_responded[receipt]) revert DuplicateResponse();
1222-
12231223
// adjust the timeout
12241224
uint256 timeout = _hostParams.defaultTimeout > post.timeout ? _hostParams.defaultTimeout : post.timeout;
12251225
uint64 timeoutTimestamp = post.timeout == 0 ? 0 : uint64(block.timestamp) + uint64(timeout);

evm/yarn.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
# yarn lockfile v1
33

44

5-
"@polytope-labs/ismp-solidity@^0.3.0":
6-
version "0.3.0"
7-
resolved "https://registry.yarnpkg.com/@polytope-labs/ismp-solidity/-/ismp-solidity-0.3.0.tgz#6064554d958e88494586d3f68d4d53a037cc6506"
8-
integrity sha512-mXlfG9zXovVXvziWUMan81uwuvSGaot++YzsV4t3lKdAZqq/rZK2pqoPNW9frtSXHcBfUoXH8GaIxZuqd1D+Kw==
5+
"@polytope-labs/ismp-solidity@^0.3.1":
6+
version "0.3.1"
7+
resolved "https://registry.yarnpkg.com/@polytope-labs/ismp-solidity/-/ismp-solidity-0.3.1.tgz#80dd652eaacfb9c1764adc21dc31312c297ecd65"
8+
integrity sha512-/ZWT6W/egfHfUdQ22kjLlOHsIsMJAWDBp0x2Zru9fdWZ2DKdw7qHRcqZSHECo6JPvF40YA31wvdXbiU6KRAUzQ==
99
dependencies:
1010
"@polytope-labs/solidity-merkle-trees" "^0.2.3"
1111
openzeppelin-solidity "^4.8.1"

0 commit comments

Comments
 (0)