From d01452083919f5d25a9f0a23b8a1d612ed3d2ae0 Mon Sep 17 00:00:00 2001 From: Web3 Philosopher Date: Thu, 18 Jul 2024 15:18:44 +0100 Subject: [PATCH] UX Improvements (#258) Co-authored-by: David Salami --- Cargo.lock | 20 +- Cargo.toml | 9 +- .../developers/evm/contract-addresses.mdx | 60 +- docs/pages/developers/network/relayer.mdx | 4 +- evm/abi/src/conversions.rs | 69 +- evm/abi/src/generated/beefy.rs | 405 +++++++++- evm/abi/src/generated/evm_host.rs | 152 ++-- evm/abi/src/generated/host_manager.rs | 4 +- evm/abi/src/generated/ping_module.rs | 6 +- evm/integration-tests/Cargo.toml | 5 +- evm/integration-tests/src/tests/beefy_v1.rs | 6 +- .../src/tests/get_response.rs | 4 +- .../src/tests/get_timeout.rs | 4 +- .../src/tests/host_manager.rs | 24 +- .../src/tests/post_request.rs | 6 +- .../src/tests/post_response.rs | 15 +- .../src/tests/post_timeout.rs | 6 +- evm/script/DeployIsmp.s.sol | 8 +- evm/src/consensus/BeefyV1.sol | 206 +++-- evm/src/consensus/Codec.sol | 30 +- .../{ZkBeefy.sol => UltraPlonkBeefy.sol} | 185 +++-- .../consensus/verifiers/KusamaVerifier.sol | 718 +++++++++--------- .../consensus/verifiers/PolkadotVerifier.sol | 718 +++++++++--------- evm/src/hosts/Arbitrum.sol | 7 + evm/src/hosts/Base.sol | 7 + evm/src/hosts/Bsc.sol | 7 + evm/src/hosts/Ethereum.sol | 7 + evm/src/hosts/EvmHost.sol | 391 ++++++---- evm/src/hosts/Optimism.sol | 7 + evm/src/hosts/Polygon.sol | 7 + evm/src/interfaces/IUniswapV2Router.sol | 48 +- evm/src/modules/CallDispatcher.sol | 10 +- evm/src/modules/HandlerV1.sol | 153 ++-- evm/src/modules/HostManager.sol | 5 +- evm/src/modules/Registrar.sol | 46 +- evm/src/modules/TokenFaucet.sol | 16 +- evm/src/modules/TokenGateway.sol | 197 ++++- evm/test/Beefy.sol | 2 +- evm/test/EvmHostTest.sol | 4 +- evm/test/TokenGatewayTest.sol | 57 ++ .../{PlonkTest.sol => UltraPlonkTest.sol} | 3 +- .../beefy/prover/src/runtime/paseo.rs | 21 +- .../sync-committee/primitives/Cargo.toml | 4 +- .../primitives/src/consensus_types.rs | 94 +-- .../sync-committee/primitives/src/lib.rs | 2 - .../sync-committee/primitives/src/serde.rs | 142 ---- .../primitives/src/ssz/byte_list.rs | 2 +- .../primitives/src/ssz/byte_vector.rs | 2 +- modules/hyperclient/hyperclient.d.ts | 19 +- modules/hyperclient/src/any_client.rs | 15 + modules/hyperclient/src/indexing.rs | 15 + modules/hyperclient/src/interfaces.rs | 53 +- modules/hyperclient/src/internals.rs | 27 +- modules/hyperclient/src/lib.rs | 46 +- modules/hyperclient/src/providers/evm.rs | 19 +- .../hyperclient/src/providers/interface.rs | 19 +- modules/hyperclient/src/providers/mod.rs | 15 + .../hyperclient/src/providers/substrate.rs | 15 + modules/hyperclient/src/testing.rs | 40 +- modules/hyperclient/src/tests.rs | 27 +- modules/hyperclient/src/types.rs | 17 +- modules/hyperclient/tests/streams.rs | 15 + modules/ismp/core/Cargo.toml | 8 +- modules/ismp/core/src/consensus.rs | 2 + modules/ismp/core/src/events.rs | 10 +- modules/ismp/core/src/messaging.rs | 4 +- modules/ismp/core/src/module.rs | 2 +- modules/ismp/core/src/router.rs | 40 +- modules/ismp/pallets/asset-gateway/src/lib.rs | 6 +- modules/ismp/pallets/demo/src/lib.rs | 10 +- modules/ismp/pallets/hyperbridge/src/lib.rs | 6 +- modules/ismp/pallets/pallet/src/dispatcher.rs | 10 +- modules/ismp/pallets/pallet/src/host.rs | 9 + modules/ismp/pallets/pallet/src/weights.rs | 6 +- modules/ismp/pallets/testsuite/src/runtime.rs | 6 +- .../src/tests/pallet_asset_gateway.rs | 10 +- .../src/tests/pallet_call_decompressor.rs | 12 +- .../testsuite/src/tests/pallet_hyperbridge.rs | 18 +- .../testsuite/src/tests/pallet_ismp.rs | 10 +- .../src/tests/pallet_ismp_relayer.rs | 10 +- .../src/tests/xcm_integration_test.rs | 85 ++- .../ismp/pallets/token-governor/src/lib.rs | 7 +- .../state-machines/hyperbridge/src/lib.rs | 2 +- modules/ismp/testsuite/src/lib.rs | 50 +- modules/ismp/testsuite/src/mocks.rs | 13 +- modules/utils/serde/Cargo.toml | 23 + modules/utils/serde/src/lib.rs | 334 ++++++++ .../{subxt/utils => utils/subxt}/Cargo.toml | 0 .../utils => utils/subxt}/src/client.rs | 0 .../utils => utils/subxt}/src/gargantua.rs | 170 +++-- .../{subxt/utils => utils/subxt}/src/lib.rs | 6 +- parachain/node/Cargo.toml | 2 +- parachain/runtimes/gargantua/src/ismp.rs | 4 +- parachain/runtimes/gargantua/src/lib.rs | 2 +- parachain/runtimes/messier/src/ismp.rs | 4 +- parachain/runtimes/nexus/src/ismp.rs | 4 +- parachain/simtests/src/hyperbridge_client.rs | 18 +- parachain/simtests/src/pallet_ismp.rs | 6 +- tesseract/evm/src/gas_oracle.rs | 1 + tesseract/evm/src/lib.rs | 9 +- tesseract/evm/src/test.rs | 7 +- tesseract/evm/src/tx.rs | 3 +- tesseract/fees/src/lib.rs | 2 +- tesseract/fees/src/tests.rs | 42 +- tesseract/messaging/src/events.rs | 6 +- tesseract/primitives/src/lib.rs | 4 +- tesseract/relayer/Cargo.toml | 2 +- tesseract/substrate/src/calls.rs | 4 +- 108 files changed, 3306 insertions(+), 1930 deletions(-) rename evm/src/consensus/{ZkBeefy.sol => UltraPlonkBeefy.sol} (50%) rename evm/test/{PlonkTest.sol => UltraPlonkTest.sol} (99%) delete mode 100644 modules/consensus/sync-committee/primitives/src/serde.rs create mode 100644 modules/utils/serde/Cargo.toml create mode 100644 modules/utils/serde/src/lib.rs rename modules/{subxt/utils => utils/subxt}/Cargo.toml (100%) rename modules/{subxt/utils => utils/subxt}/src/client.rs (100%) rename modules/{subxt/utils => utils/subxt}/src/gargantua.rs (99%) rename modules/{subxt/utils => utils/subxt}/src/lib.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index fdb3ba9f3..64c96d1b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6707,7 +6707,7 @@ dependencies = [ [[package]] name = "hyperbridge" -version = "0.5.1" +version = "0.5.2" dependencies = [ "clap", "cumulus-client-cli", @@ -7286,12 +7286,14 @@ dependencies = [ name = "ismp" version = "0.1.2" dependencies = [ + "anyhow", "derive_more", "hex", "parity-scale-codec", "primitive-types", "scale-info", "serde", + "serde-utils", "serde_json", ] @@ -7418,6 +7420,7 @@ dependencies = [ "sp-runtime 31.0.1", "sp-trie 29.0.0", "subxt", + "subxt-utils", "tokio", "tracing", "tracing-subscriber 0.3.18", @@ -17534,6 +17537,18 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-utils" +version = "0.1.0" +dependencies = [ + "anyhow", + "hex", + "ismp", + "primitive-types", + "serde", + "serde_json", +] + [[package]] name = "serde-value" version = "0.7.0" @@ -20320,6 +20335,7 @@ dependencies = [ "parity-scale-codec", "primitive-types", "serde", + "serde-utils", "ssz-rs", ] @@ -20531,7 +20547,7 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "tesseract" -version = "0.3.6" +version = "0.3.7" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index df46f9f0f..2dc642504 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,8 +60,10 @@ members = [ # simnode "parachain/simtests", - # subxt subxt-utils - "modules/subxt/utils", + + # Utilities + "modules/utils/subxt", + "modules/utils/serde", # tesseract "tesseract/primitives", @@ -234,8 +236,9 @@ ismp = { version = "0.1.2", path = "./modules/ismp/core", default-features = fal ismp-testsuite = { path = "./modules/ismp/testsuite" } ismp-solidity-abi = { path = "./evm/abi", default-features = false } simnode-tests = { path = "parachain/simtests" } -subxt-utils = { path = "modules/subxt/utils", default-features = false } hyperclient = { path = "modules/hyperclient", default-features = false } +subxt-utils = { path = "modules/utils/subxt", default-features = false } +serde-utils = { path = "modules/utils/serde", default-features = false } # consensus provers & verifiers beefy-verifier-primitives = { path = "./modules/consensus/beefy/primitives", default-features = false } diff --git a/docs/pages/developers/evm/contract-addresses.mdx b/docs/pages/developers/evm/contract-addresses.mdx index 2aa3541dc..7a8e81cdc 100644 --- a/docs/pages/developers/evm/contract-addresses.mdx +++ b/docs/pages/developers/evm/contract-addresses.mdx @@ -3,11 +3,67 @@ The ISMP solidity contracts are deployed on the following networks: +## Gargantua V3 (Paseo) +The current testnet environment for the Hyperbridge network. -## Gargantua V2 (Paseo) +### Ethereum Sepolia -The current testnet environment for the Hyperbridge network. +| `HandlerV1` | [`0xc449D4bc3fD5A434aC9e11a53f60c7efc908e638`](https://sepolia.etherscan.io/address/0xc449D4bc3fD5A434aC9e11a53f60c7efc908e638) | +|:------------|:-----| +| `IsmpHost` | [`0x4175a96bd787a2C196e732a1244630650607fdC2`](https://sepolia.etherscan.io/address/0x4175a96bd787a2C196e732a1244630650607fdC2) | +| `PingModule` | [`0x8E4Ca395cfAa033A71fC618792Fce99106633B90`](https://sepolia.etherscan.io/address/0x8E4Ca395cfAa033A71fC618792Fce99106633B90) | +| `TokenGateway` | [`0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751`](https://sepolia.etherscan.io/address/0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751) | +| `TokenFaucet` | [`0x5b90b886d302c7DEbA10a2E02c521B3bE930070B`](https://sepolia.etherscan.io/address/0x5b90b886d302c7DEbA10a2E02c521B3bE930070B) | +| `FeeToken (USD.h)` | [`0x83311D74692ce1A8859F908880b3EdEC67f05997`](https://sepolia.etherscan.io/address/0x83311D74692ce1A8859F908880b3EdEC67f05997) | + +### Arbitrum Sepolia + + +| `HandlerV1` | [`0x47df392E8B8F80AFe8571159beA5D4904CdD2dd6`](https://sepolia.arbiscan.io/address/0x47df392E8B8F80AFe8571159beA5D4904CdD2dd6) | +|:------------|:-----| +| `IsmpHost` | [`0xC8A9288BF705A238c3d96C76499F4A4E1d96c800`](https://sepolia.arbiscan.io/address/0xC8A9288BF705A238c3d96C76499F4A4E1d96c800) | +| `PingModule` | [`0x8E4Ca395cfAa033A71fC618792Fce99106633B90`](https://sepolia.arbiscan.io/address/0x8E4Ca395cfAa033A71fC618792Fce99106633B90) | +| `TokenGateway` | [`0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751`](https://sepolia.arbiscan.io/address/0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751) | +| `TokenFaucet` | [`0x5b90b886d302c7DEbA10a2E02c521B3bE930070B`](https://sepolia.arbiscan.io/address/0x5b90b886d302c7DEbA10a2E02c521B3bE930070B) | +| `FeeToken (USD.h)` | [`0x83311D74692ce1A8859F908880b3EdEC67f05997`](https://sepolia.arbiscan.io/address/0x83311D74692ce1A8859F908880b3EdEC67f05997) | + +### Optimism Sepolia + + +| `HandlerV1` | [`0xB9Ffd43C720A695d40C14896494c1461f3fBb8A7`](https://sepolia-optimism.etherscan.io/address/0xB9Ffd43C720A695d40C14896494c1461f3fBb8A7) | +|:------------|:-----| +| `IsmpHost` | [`0x265FafEb401ac6491da7344F01E724c38bC68FED`](https://sepolia-optimism.etherscan.io/address/0x265FafEb401ac6491da7344F01E724c38bC68FED) | +| `PingModule` | [`0x8E4Ca395cfAa033A71fC618792Fce99106633B90`](https://sepolia-optimism.etherscan.io/address/0x8E4Ca395cfAa033A71fC618792Fce99106633B90) | +| `TokenGateway` | [`0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751`](https://sepolia-optimism.etherscan.io/address/0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751) | +| `TokenFaucet` | [`0x5b90b886d302c7DEbA10a2E02c521B3bE930070B`](https://sepolia-optimism.etherscan.io/address/0x5b90b886d302c7DEbA10a2E02c521B3bE930070B) | +| `FeeToken (USD.h)` | [`0x83311D74692ce1A8859F908880b3EdEC67f05997`](https://sepolia-optimism.etherscan.io/address/0x83311D74692ce1A8859F908880b3EdEC67f05997) | + +### Base Sepolia + + +| `HandlerV1` | [`0xc76c16539877C0c38c18E815E449Ff4855DA11d4`](https://sepolia.basescan.org/address/0xc76c16539877C0c38c18E815E449Ff4855DA11d4) | +|:------------|:-----| +| `IsmpHost` | [`0x42D2cd76413Df482156a135A54017c61AA612dA3`](https://sepolia.basescan.org/address/0x42D2cd76413Df482156a135A54017c61AA612dA3) | +| `PingModule` | [`0x8E4Ca395cfAa033A71fC618792Fce99106633B90`](https://sepolia.basescan.org/address/0x8E4Ca395cfAa033A71fC618792Fce99106633B90) | +| `TokenGateway` | [`0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751`](https://sepolia.basescan.org/address/0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751) | +| `TokenFaucet` | [`0x5b90b886d302c7DEbA10a2E02c521B3bE930070B`](https://sepolia.basescan.org/address/0x5b90b886d302c7DEbA10a2E02c521B3bE930070B) | +| `FeeToken (USD.h)` | [`0x83311D74692ce1A8859F908880b3EdEC67f05997`](https://sepolia.basescan.org/address/0x83311D74692ce1A8859F908880b3EdEC67f05997) | + +### Bsc Testnet + + +| `HandlerV1` | [`0x698Ea102d14dF1F9a4C3A76fE5DCEEeFcfd27f85`](https://testnet.bscscan.com/address/0x698Ea102d14dF1F9a4C3A76fE5DCEEeFcfd27f85) | +|:------------|:-----| +| `IsmpHost` | [`0x9494400D1A8285F81604AC04ACFD839385B3b843`](https://testnet.bscscan.com/address/0x9494400D1A8285F81604AC04ACFD839385B3b843) | +| `PingModule` | [`0x8E4Ca395cfAa033A71fC618792Fce99106633B90`](https://testnet.bscscan.com/address/0x8E4Ca395cfAa033A71fC618792Fce99106633B90) | +| `TokenGateway` | [`0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751`](https://testnet.bscscan.com/address/0x5B39F339c24c6645cc47FEeFBb01b1f7fBA59751) | +| `TokenFaucet` | [`0x5b90b886d302c7DEbA10a2E02c521B3bE930070B`](https://testnet.bscscan.com/address/0x5b90b886d302c7DEbA10a2E02c521B3bE930070B) | +| `FeeToken (USD.h)` | [`0x83311D74692ce1A8859F908880b3EdEC67f05997`](https://testnet.bscscan.com/address/0x83311D74692ce1A8859F908880b3EdEC67f05997) | + +## Gargantua V2 (Paseo) (Deprecated) + +Deprecated testnet environment for Gargantua V2 (Paseo). ### Ethereum Sepolia diff --git a/docs/pages/developers/network/relayer.mdx b/docs/pages/developers/network/relayer.mdx index a17729d0e..c6f6ed73c 100644 --- a/docs/pages/developers/network/relayer.mdx +++ b/docs/pages/developers/network/relayer.mdx @@ -208,8 +208,6 @@ consensus_state_id = "ETH0" # Bsc on the other hand uses the BNB token and would need its own API key # gotten from bscscan etherscan_api_key = "" -# The Handler contract address on this chain -handler = "" # The IsmpHost contract address on this chain ismp_host = "" # (Optional) @@ -238,7 +236,7 @@ gas_price_buffer = 1 # client_type = Geth # client_type = Erigon # If this field is not set, the default is Geth -client_type = Erigon +client_type = "Erigon" [substrate] type = "substrate" diff --git a/evm/abi/src/conversions.rs b/evm/abi/src/conversions.rs index 4eaf24456..7cf2ef34f 100644 --- a/evm/abi/src/conversions.rs +++ b/evm/abi/src/conversions.rs @@ -210,8 +210,8 @@ impl From for PostResponse { } } -impl From for PostRequest { - fn from(value: router::Post) -> Self { +impl From for PostRequest { + fn from(value: router::PostRequest) -> Self { PostRequest { source: value.source.to_string().as_bytes().to_vec().into(), dest: value.dest.to_string().as_bytes().to_vec().into(), @@ -219,15 +219,15 @@ impl From for PostRequest { from: value.from.into(), to: value.to.into(), timeout_timestamp: value.timeout_timestamp.into(), - body: value.data.into(), + body: value.body.into(), } } } -impl TryFrom for router::Post { +impl TryFrom for router::PostRequest { type Error = anyhow::Error; fn try_from(value: PostRequest) -> Result { - Ok(router::Post { + Ok(router::PostRequest { source: StateMachine::from_str(&String::from_utf8(value.source.to_vec())?) .map_err(|err| anyhow!("{err}"))?, dest: StateMachine::from_str(&String::from_utf8(value.dest.to_vec())?) @@ -236,7 +236,7 @@ impl TryFrom for router::Post { from: value.from.to_vec(), to: value.to.to_vec(), timeout_timestamp: value.timeout_timestamp.into(), - data: value.body.to_vec(), + body: value.body.to_vec(), }) } } @@ -269,11 +269,9 @@ impl TryFrom for ismp::events::Event { fn try_from(event: EvmHostEvents) -> Result { match event { EvmHostEvents::GetRequestEventFilter(get) => - Ok(ismp::events::Event::GetRequest(router::Get { - source: StateMachine::from_str(&String::from_utf8(get.source.0.into())?) - .map_err(|e| anyhow!("{}", e))?, - dest: StateMachine::from_str(&String::from_utf8(get.dest.0.into())?) - .map_err(|e| anyhow!("{}", e))?, + Ok(ismp::events::Event::GetRequest(router::GetRequest { + source: StateMachine::from_str(&get.source).map_err(|e| anyhow!("{}", e))?, + dest: StateMachine::from_str(&get.dest).map_err(|e| anyhow!("{}", e))?, nonce: get.nonce.low_u64(), from: get.from.0.into(), keys: get.keys.into_iter().map(|key| key.0.into()).collect(), @@ -284,19 +282,17 @@ impl TryFrom for ismp::events::Event { Ok(ismp::events::Event::PostRequest(post.try_into()?)), EvmHostEvents::PostResponseEventFilter(resp) => Ok(ismp::events::Event::PostResponse(router::PostResponse { - post: router::Post { - source: StateMachine::from_str(&String::from_utf8(resp.source.0.into())?) - .map_err(|e| anyhow!("{}", e))?, - dest: StateMachine::from_str(&String::from_utf8(resp.dest.0.into())?) - .map_err(|e| anyhow!("{}", e))?, + post: router::PostRequest { + source: StateMachine::from_str(&resp.dest).map_err(|e| anyhow!("{}", e))?, + dest: StateMachine::from_str(&resp.source).map_err(|e| anyhow!("{}", e))?, nonce: resp.nonce.low_u64(), - from: resp.from.0.into(), - to: resp.to.0.into(), + from: resp.to.0.into(), + to: resp.from.0.into(), timeout_timestamp: resp.timeout_timestamp.low_u64(), - data: resp.data.0.into(), + body: resp.body.0.into(), }, response: resp.response.0.into(), - timeout_timestamp: resp.res_timeout_timestamp.low_u64(), + timeout_timestamp: resp.response_timeout_timestamp.low_u64(), })), EvmHostEvents::PostRequestHandledFilter(handled) => Ok(ismp::events::Event::PostRequestHandled(ismp::events::RequestResponseHandled { @@ -317,17 +313,14 @@ impl TryFrom for ismp::events::Event { EvmHostEvents::StateMachineUpdatedFilter(filter) => Ok(ismp::events::Event::StateMachineUpdated(StateMachineUpdated { state_machine_id: ismp::consensus::StateMachineId { - state_id: StateMachine::from_str(&String::from_utf8( - filter.state_machine_id.to_vec(), - )?) - .map_err(|e| anyhow!("{}", e))?, + state_id: StateMachine::from_str(&filter.state_machine_id) + .map_err(|e| anyhow!("{}", e))?, consensus_state_id: Default::default(), }, latest_height: filter.height.low_u64(), })), EvmHostEvents::PostRequestTimeoutHandledFilter(handled) => { - let dest = StateMachine::from_str(&String::from_utf8(handled.dest.to_vec())?) - .map_err(|e| anyhow!("{}", e))?; + let dest = StateMachine::from_str(&handled.dest).map_err(|e| anyhow!("{}", e))?; Ok(ismp::events::Event::PostRequestTimeoutHandled(TimeoutHandled { commitment: handled.commitment.into(), dest: dest.clone(), @@ -335,8 +328,7 @@ impl TryFrom for ismp::events::Event { })) }, EvmHostEvents::PostResponseTimeoutHandledFilter(handled) => { - let dest = StateMachine::from_str(&String::from_utf8(handled.dest.to_vec())?) - .map_err(|e| anyhow!("{}", e))?; + let dest = StateMachine::from_str(&handled.dest).map_err(|e| anyhow!("{}", e))?; Ok(ismp::events::Event::PostResponseTimeoutHandled(TimeoutHandled { commitment: handled.commitment.into(), dest: dest.clone(), @@ -344,8 +336,7 @@ impl TryFrom for ismp::events::Event { })) }, EvmHostEvents::GetRequestTimeoutHandledFilter(handled) => { - let dest = StateMachine::from_str(&String::from_utf8(handled.dest.to_vec())?) - .map_err(|e| anyhow!("{}", e))?; + let dest = StateMachine::from_str(&handled.dest).map_err(|e| anyhow!("{}", e))?; Ok(ismp::events::Event::GetRequestTimeoutHandled(TimeoutHandled { commitment: handled.commitment.into(), dest: dest.clone(), @@ -356,10 +347,8 @@ impl TryFrom for ismp::events::Event { Ok(ismp::events::Event::StateCommitmentVetoed(StateCommitmentVetoed { height: ismp::consensus::StateMachineHeight { id: StateMachineId { - state_id: StateMachine::from_str(&String::from_utf8( - vetoed.state_machine_id.to_vec(), - )?) - .map_err(|e| anyhow!("{}", e))?, + state_id: StateMachine::from_str(&vetoed.state_machine_id) + .map_err(|e| anyhow!("{}", e))?, consensus_state_id: Default::default(), }, height: vetoed.height.low_u64(), @@ -375,20 +364,18 @@ impl TryFrom for ismp::events::Event { } } -impl TryFrom for router::Post { +impl TryFrom for router::PostRequest { type Error = anyhow::Error; fn try_from(post: PostRequestEventFilter) -> Result { - Ok(router::Post { - source: StateMachine::from_str(&String::from_utf8(post.source.0.into())?) - .map_err(|e| anyhow!("{}", e))?, - dest: StateMachine::from_str(&String::from_utf8(post.dest.0.into())?) - .map_err(|e| anyhow!("{}", e))?, + Ok(router::PostRequest { + source: StateMachine::from_str(&post.source).map_err(|e| anyhow!("{}", e))?, + dest: StateMachine::from_str(&post.dest).map_err(|e| anyhow!("{}", e))?, nonce: post.nonce.low_u64(), from: post.from.0.into(), to: post.to.0.into(), timeout_timestamp: post.timeout_timestamp.low_u64(), - data: post.data.0.into(), + body: post.body.0.into(), }) } } diff --git a/evm/abi/src/generated/beefy.rs b/evm/abi/src/generated/beefy.rs index ec8a6f605..db569d441 100644 --- a/evm/abi/src/generated/beefy.rs +++ b/evm/abi/src/generated/beefy.rs @@ -363,7 +363,99 @@ pub mod beefy { ), ]), events: ::std::collections::BTreeMap::new(), - errors: ::std::collections::BTreeMap::new(), + errors: ::core::convert::From::from([ + ( + ::std::borrow::ToOwned::to_owned("IllegalGenesisBlock"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "IllegalGenesisBlock", + ), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("InvalidAuthoritiesProof"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "InvalidAuthoritiesProof", + ), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("InvalidMmrProof"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned("InvalidMmrProof"), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("InvalidUltraPlonkProof"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "InvalidUltraPlonkProof", + ), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("MmrRootHashMissing"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned("MmrRootHashMissing"), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("StaleHeight"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned("StaleHeight"), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("SuperMajorityRequired"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "SuperMajorityRequired", + ), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("UnknownAuthoritySet"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "UnknownAuthoritySet", + ), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("UnknownParaId"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned("UnknownParaId"), + inputs: ::std::vec![], + }, + ], + ), + ]), receive: false, fallback: false, } @@ -470,6 +562,317 @@ pub mod beefy { Self::new(contract.address(), contract.client()) } } + ///Custom Error type `IllegalGenesisBlock` with signature `IllegalGenesisBlock()` and selector + /// `0xb4eb9e51` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "IllegalGenesisBlock", abi = "IllegalGenesisBlock()")] + pub struct IllegalGenesisBlock; + ///Custom Error type `InvalidAuthoritiesProof` with signature `InvalidAuthoritiesProof()` and + /// selector `0x528bd3ef` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "InvalidAuthoritiesProof", abi = "InvalidAuthoritiesProof()")] + pub struct InvalidAuthoritiesProof; + ///Custom Error type `InvalidMmrProof` with signature `InvalidMmrProof()` and selector + /// `0x5c90c348` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "InvalidMmrProof", abi = "InvalidMmrProof()")] + pub struct InvalidMmrProof; + ///Custom Error type `InvalidUltraPlonkProof` with signature `InvalidUltraPlonkProof()` and + /// selector `0x866dc22c` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "InvalidUltraPlonkProof", abi = "InvalidUltraPlonkProof()")] + pub struct InvalidUltraPlonkProof; + ///Custom Error type `MmrRootHashMissing` with signature `MmrRootHashMissing()` and selector + /// `0x8c6238e4` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "MmrRootHashMissing", abi = "MmrRootHashMissing()")] + pub struct MmrRootHashMissing; + ///Custom Error type `StaleHeight` with signature `StaleHeight()` and selector `0xbeda4fc3` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "StaleHeight", abi = "StaleHeight()")] + pub struct StaleHeight; + ///Custom Error type `SuperMajorityRequired` with signature `SuperMajorityRequired()` and + /// selector `0xeaa43dfc` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "SuperMajorityRequired", abi = "SuperMajorityRequired()")] + pub struct SuperMajorityRequired; + ///Custom Error type `UnknownAuthoritySet` with signature `UnknownAuthoritySet()` and selector + /// `0xe405cd0a` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "UnknownAuthoritySet", abi = "UnknownAuthoritySet()")] + pub struct UnknownAuthoritySet; + ///Custom Error type `UnknownParaId` with signature `UnknownParaId()` and selector `0xdbb2cc09` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[etherror(name = "UnknownParaId", abi = "UnknownParaId()")] + pub struct UnknownParaId; + ///Container type for all of the contract's custom errors + #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] + pub enum BeefyErrors { + IllegalGenesisBlock(IllegalGenesisBlock), + InvalidAuthoritiesProof(InvalidAuthoritiesProof), + InvalidMmrProof(InvalidMmrProof), + InvalidUltraPlonkProof(InvalidUltraPlonkProof), + MmrRootHashMissing(MmrRootHashMissing), + StaleHeight(StaleHeight), + SuperMajorityRequired(SuperMajorityRequired), + UnknownAuthoritySet(UnknownAuthoritySet), + UnknownParaId(UnknownParaId), + /// The standard solidity revert string, with selector + /// Error(string) -- 0x08c379a0 + RevertString(::std::string::String), + } + impl ::ethers::core::abi::AbiDecode for BeefyErrors { + fn decode( + data: impl AsRef<[u8]>, + ) -> ::core::result::Result { + let data = data.as_ref(); + if let Ok(decoded) = + <::std::string::String as ::ethers::core::abi::AbiDecode>::decode(data) + { + return Ok(Self::RevertString(decoded)); + } + if let Ok(decoded) = + ::decode(data) + { + return Ok(Self::IllegalGenesisBlock(decoded)); + } + if let Ok(decoded) = + ::decode(data) + { + return Ok(Self::InvalidAuthoritiesProof(decoded)); + } + if let Ok(decoded) = ::decode(data) { + return Ok(Self::InvalidMmrProof(decoded)); + } + if let Ok(decoded) = + ::decode(data) + { + return Ok(Self::InvalidUltraPlonkProof(decoded)); + } + if let Ok(decoded) = + ::decode(data) + { + return Ok(Self::MmrRootHashMissing(decoded)); + } + if let Ok(decoded) = ::decode(data) { + return Ok(Self::StaleHeight(decoded)); + } + if let Ok(decoded) = + ::decode(data) + { + return Ok(Self::SuperMajorityRequired(decoded)); + } + if let Ok(decoded) = + ::decode(data) + { + return Ok(Self::UnknownAuthoritySet(decoded)); + } + if let Ok(decoded) = ::decode(data) { + return Ok(Self::UnknownParaId(decoded)); + } + Err(::ethers::core::abi::Error::InvalidData.into()) + } + } + impl ::ethers::core::abi::AbiEncode for BeefyErrors { + fn encode(self) -> ::std::vec::Vec { + match self { + Self::IllegalGenesisBlock(element) => + ::ethers::core::abi::AbiEncode::encode(element), + Self::InvalidAuthoritiesProof(element) => + ::ethers::core::abi::AbiEncode::encode(element), + Self::InvalidMmrProof(element) => ::ethers::core::abi::AbiEncode::encode(element), + Self::InvalidUltraPlonkProof(element) => + ::ethers::core::abi::AbiEncode::encode(element), + Self::MmrRootHashMissing(element) => + ::ethers::core::abi::AbiEncode::encode(element), + Self::StaleHeight(element) => ::ethers::core::abi::AbiEncode::encode(element), + Self::SuperMajorityRequired(element) => + ::ethers::core::abi::AbiEncode::encode(element), + Self::UnknownAuthoritySet(element) => + ::ethers::core::abi::AbiEncode::encode(element), + Self::UnknownParaId(element) => ::ethers::core::abi::AbiEncode::encode(element), + Self::RevertString(s) => ::ethers::core::abi::AbiEncode::encode(s), + } + } + } + impl ::ethers::contract::ContractRevert for BeefyErrors { + fn valid_selector(selector: [u8; 4]) -> bool { + match selector { + [0x08, 0xc3, 0x79, 0xa0] => true, + _ if selector == + ::selector() => + true, + _ if selector == + ::selector() => + true, + _ if selector == ::selector() => + true, + _ if selector == + ::selector() => + true, + _ if selector == + ::selector() => + true, + _ if selector == ::selector() => true, + _ if selector == + ::selector() => + true, + _ if selector == + ::selector() => + true, + _ if selector == ::selector() => + true, + _ => false, + } + } + } + impl ::core::fmt::Display for BeefyErrors { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + Self::IllegalGenesisBlock(element) => ::core::fmt::Display::fmt(element, f), + Self::InvalidAuthoritiesProof(element) => ::core::fmt::Display::fmt(element, f), + Self::InvalidMmrProof(element) => ::core::fmt::Display::fmt(element, f), + Self::InvalidUltraPlonkProof(element) => ::core::fmt::Display::fmt(element, f), + Self::MmrRootHashMissing(element) => ::core::fmt::Display::fmt(element, f), + Self::StaleHeight(element) => ::core::fmt::Display::fmt(element, f), + Self::SuperMajorityRequired(element) => ::core::fmt::Display::fmt(element, f), + Self::UnknownAuthoritySet(element) => ::core::fmt::Display::fmt(element, f), + Self::UnknownParaId(element) => ::core::fmt::Display::fmt(element, f), + Self::RevertString(s) => ::core::fmt::Display::fmt(s, f), + } + } + } + impl ::core::convert::From<::std::string::String> for BeefyErrors { + fn from(value: String) -> Self { + Self::RevertString(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: IllegalGenesisBlock) -> Self { + Self::IllegalGenesisBlock(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: InvalidAuthoritiesProof) -> Self { + Self::InvalidAuthoritiesProof(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: InvalidMmrProof) -> Self { + Self::InvalidMmrProof(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: InvalidUltraPlonkProof) -> Self { + Self::InvalidUltraPlonkProof(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: MmrRootHashMissing) -> Self { + Self::MmrRootHashMissing(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: StaleHeight) -> Self { + Self::StaleHeight(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: SuperMajorityRequired) -> Self { + Self::SuperMajorityRequired(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: UnknownAuthoritySet) -> Self { + Self::UnknownAuthoritySet(value) + } + } + impl ::core::convert::From for BeefyErrors { + fn from(value: UnknownParaId) -> Self { + Self::UnknownParaId(value) + } + } ///Container type for all input parameters for the `AURA_CONSENSUS_ID` function with signature /// `AURA_CONSENSUS_ID()` and selector `0x4e9fdbec` #[derive( diff --git a/evm/abi/src/generated/evm_host.rs b/evm/abi/src/generated/evm_host.rs index a08198b03..c1467e379 100644 --- a/evm/abi/src/generated/evm_host.rs +++ b/evm/abi/src/generated/evm_host.rs @@ -1164,9 +1164,9 @@ pub mod evm_host { outputs: ::std::vec![ ::ethers::core::abi::ethabi::Param { name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes"), + ::std::borrow::ToOwned::to_owned("string"), ), }, ], @@ -1390,18 +1390,18 @@ pub mod evm_host { inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("source"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("dest"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("from"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, - indexed: false, + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("keys"), @@ -1413,14 +1413,14 @@ pub mod evm_host { indexed: false, }, ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("nonce"), + name: ::std::borrow::ToOwned::to_owned("height"), kind: ::ethers::core::abi::ethabi::ParamType::Uint( 256usize, ), - indexed: true, + indexed: false, }, ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("height"), + name: ::std::borrow::ToOwned::to_owned("nonce"), kind: ::ethers::core::abi::ethabi::ParamType::Uint( 256usize, ), @@ -1449,7 +1449,7 @@ pub mod evm_host { kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( 32usize, ), - indexed: false, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("relayer"), @@ -1474,11 +1474,11 @@ pub mod evm_host { kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( 32usize, ), - indexed: false, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("dest"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ], @@ -1600,18 +1600,18 @@ pub mod evm_host { inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("source"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("dest"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("from"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, - indexed: false, + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("to"), @@ -1623,7 +1623,7 @@ pub mod evm_host { kind: ::ethers::core::abi::ethabi::ParamType::Uint( 256usize, ), - indexed: true, + indexed: false, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("timeoutTimestamp"), @@ -1633,7 +1633,7 @@ pub mod evm_host { indexed: false, }, ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("data"), + name: ::std::borrow::ToOwned::to_owned("body"), kind: ::ethers::core::abi::ethabi::ParamType::Bytes, indexed: false, }, @@ -1660,7 +1660,7 @@ pub mod evm_host { kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( 32usize, ), - indexed: false, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("relayer"), @@ -1685,11 +1685,11 @@ pub mod evm_host { kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( 32usize, ), - indexed: false, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("dest"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ], @@ -1705,18 +1705,18 @@ pub mod evm_host { inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("source"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("dest"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("from"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, - indexed: false, + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("to"), @@ -1728,7 +1728,7 @@ pub mod evm_host { kind: ::ethers::core::abi::ethabi::ParamType::Uint( 256usize, ), - indexed: true, + indexed: false, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("timeoutTimestamp"), @@ -1738,7 +1738,7 @@ pub mod evm_host { indexed: false, }, ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("data"), + name: ::std::borrow::ToOwned::to_owned("body"), kind: ::ethers::core::abi::ethabi::ParamType::Bytes, indexed: false, }, @@ -1749,7 +1749,7 @@ pub mod evm_host { }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned( - "resTimeoutTimestamp", + "responseTimeoutTimestamp", ), kind: ::ethers::core::abi::ethabi::ParamType::Uint( 256usize, @@ -1806,7 +1806,7 @@ pub mod evm_host { kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( 32usize, ), - indexed: false, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("relayer"), @@ -1831,11 +1831,11 @@ pub mod evm_host { kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( 32usize, ), - indexed: false, + indexed: true, }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("dest"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ], @@ -1878,7 +1878,7 @@ pub mod evm_host { inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("stateMachineId"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ::ethers::core::abi::ethabi::EventParam { @@ -1902,7 +1902,7 @@ pub mod evm_host { ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("fisherman"), kind: ::ethers::core::abi::ethabi::ParamType::Address, - indexed: false, + indexed: true, }, ], anonymous: false, @@ -1919,7 +1919,7 @@ pub mod evm_host { inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("stateMachineId"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + kind: ::ethers::core::abi::ethabi::ParamType::String, indexed: false, }, ::ethers::core::abi::ethabi::EventParam { @@ -2384,7 +2384,7 @@ pub mod evm_host { pub fn state_machine_id( &self, id: ::ethers::core::types::U256, - ) -> ::ethers::contract::builders::ContractCall { + ) -> ::ethers::contract::builders::ContractCall { self.0 .method_hash([11, 73, 224, 76], id) .expect("method not found (this should never happen)") @@ -2460,7 +2460,8 @@ pub mod evm_host { ///Gets the contract's `GetRequestHandled` event pub fn get_request_handled_filter( &self, - ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, GetRequestHandledFilter> { + ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, GetRequestHandledFilter> + { self.0.event() } ///Gets the contract's `GetRequestTimeoutHandled` event @@ -2482,7 +2483,8 @@ pub mod evm_host { ///Gets the contract's `HostParamsUpdated` event pub fn host_params_updated_filter( &self, - ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, HostParamsUpdatedFilter> { + ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, HostParamsUpdatedFilter> + { self.0.event() } ///Gets the contract's `HostWithdrawal` event @@ -2500,7 +2502,8 @@ pub mod evm_host { ///Gets the contract's `PostRequestHandled` event pub fn post_request_handled_filter( &self, - ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, PostRequestHandledFilter> { + ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, PostRequestHandledFilter> + { self.0.event() } ///Gets the contract's `PostRequestTimeoutHandled` event @@ -2516,13 +2519,15 @@ pub mod evm_host { ///Gets the contract's `PostResponseEvent` event pub fn post_response_event_filter( &self, - ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, PostResponseEventFilter> { + ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, PostResponseEventFilter> + { self.0.event() } ///Gets the contract's `PostResponseFunded` event pub fn post_response_funded_filter( &self, - ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, PostResponseFundedFilter> { + ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, PostResponseFundedFilter> + { self.0.event() } ///Gets the contract's `PostResponseHandled` event @@ -2904,16 +2909,16 @@ pub mod evm_host { )] #[ethevent( name = "GetRequestEvent", - abi = "GetRequestEvent(bytes,bytes,bytes,bytes[],uint256,uint256,uint256)" + abi = "GetRequestEvent(string,string,address,bytes[],uint256,uint256,uint256)" )] pub struct GetRequestEventFilter { - pub source: ::ethers::core::types::Bytes, - pub dest: ::ethers::core::types::Bytes, - pub from: ::ethers::core::types::Bytes, - pub keys: ::std::vec::Vec<::ethers::core::types::Bytes>, + pub source: ::std::string::String, + pub dest: ::std::string::String, #[ethevent(indexed)] - pub nonce: ::ethers::core::types::U256, + pub from: ::ethers::core::types::Address, + pub keys: ::std::vec::Vec<::ethers::core::types::Bytes>, pub height: ::ethers::core::types::U256, + pub nonce: ::ethers::core::types::U256, pub timeout_timestamp: ::ethers::core::types::U256, } #[derive( @@ -2928,6 +2933,7 @@ pub mod evm_host { )] #[ethevent(name = "GetRequestHandled", abi = "GetRequestHandled(bytes32,address)")] pub struct GetRequestHandledFilter { + #[ethevent(indexed)] pub commitment: [u8; 32], pub relayer: ::ethers::core::types::Address, } @@ -2941,10 +2947,11 @@ pub mod evm_host { Eq, Hash, )] - #[ethevent(name = "GetRequestTimeoutHandled", abi = "GetRequestTimeoutHandled(bytes32,bytes)")] + #[ethevent(name = "GetRequestTimeoutHandled", abi = "GetRequestTimeoutHandled(bytes32,string)")] pub struct GetRequestTimeoutHandledFilter { + #[ethevent(indexed)] pub commitment: [u8; 32], - pub dest: ::ethers::core::types::Bytes, + pub dest: ::std::string::String, } #[derive( Clone, @@ -3005,17 +3012,17 @@ pub mod evm_host { )] #[ethevent( name = "PostRequestEvent", - abi = "PostRequestEvent(bytes,bytes,bytes,bytes,uint256,uint256,bytes,uint256)" + abi = "PostRequestEvent(string,string,address,bytes,uint256,uint256,bytes,uint256)" )] pub struct PostRequestEventFilter { - pub source: ::ethers::core::types::Bytes, - pub dest: ::ethers::core::types::Bytes, - pub from: ::ethers::core::types::Bytes, - pub to: ::ethers::core::types::Bytes, + pub source: ::std::string::String, + pub dest: ::std::string::String, #[ethevent(indexed)] + pub from: ::ethers::core::types::Address, + pub to: ::ethers::core::types::Bytes, pub nonce: ::ethers::core::types::U256, pub timeout_timestamp: ::ethers::core::types::U256, - pub data: ::ethers::core::types::Bytes, + pub body: ::ethers::core::types::Bytes, pub fee: ::ethers::core::types::U256, } #[derive( @@ -3030,6 +3037,7 @@ pub mod evm_host { )] #[ethevent(name = "PostRequestHandled", abi = "PostRequestHandled(bytes32,address)")] pub struct PostRequestHandledFilter { + #[ethevent(indexed)] pub commitment: [u8; 32], pub relayer: ::ethers::core::types::Address, } @@ -3045,11 +3053,12 @@ pub mod evm_host { )] #[ethevent( name = "PostRequestTimeoutHandled", - abi = "PostRequestTimeoutHandled(bytes32,bytes)" + abi = "PostRequestTimeoutHandled(bytes32,string)" )] pub struct PostRequestTimeoutHandledFilter { + #[ethevent(indexed)] pub commitment: [u8; 32], - pub dest: ::ethers::core::types::Bytes, + pub dest: ::std::string::String, } #[derive( Clone, @@ -3063,19 +3072,19 @@ pub mod evm_host { )] #[ethevent( name = "PostResponseEvent", - abi = "PostResponseEvent(bytes,bytes,bytes,bytes,uint256,uint256,bytes,bytes,uint256,uint256)" + abi = "PostResponseEvent(string,string,address,bytes,uint256,uint256,bytes,bytes,uint256,uint256)" )] pub struct PostResponseEventFilter { - pub source: ::ethers::core::types::Bytes, - pub dest: ::ethers::core::types::Bytes, - pub from: ::ethers::core::types::Bytes, - pub to: ::ethers::core::types::Bytes, + pub source: ::std::string::String, + pub dest: ::std::string::String, #[ethevent(indexed)] + pub from: ::ethers::core::types::Address, + pub to: ::ethers::core::types::Bytes, pub nonce: ::ethers::core::types::U256, pub timeout_timestamp: ::ethers::core::types::U256, - pub data: ::ethers::core::types::Bytes, + pub body: ::ethers::core::types::Bytes, pub response: ::ethers::core::types::Bytes, - pub res_timeout_timestamp: ::ethers::core::types::U256, + pub response_timeout_timestamp: ::ethers::core::types::U256, pub fee: ::ethers::core::types::U256, } #[derive( @@ -3105,6 +3114,7 @@ pub mod evm_host { )] #[ethevent(name = "PostResponseHandled", abi = "PostResponseHandled(bytes32,address)")] pub struct PostResponseHandledFilter { + #[ethevent(indexed)] pub commitment: [u8; 32], pub relayer: ::ethers::core::types::Address, } @@ -3120,11 +3130,12 @@ pub mod evm_host { )] #[ethevent( name = "PostResponseTimeoutHandled", - abi = "PostResponseTimeoutHandled(bytes32,bytes)" + abi = "PostResponseTimeoutHandled(bytes32,string)" )] pub struct PostResponseTimeoutHandledFilter { + #[ethevent(indexed)] pub commitment: [u8; 32], - pub dest: ::ethers::core::types::Bytes, + pub dest: ::std::string::String, } #[derive( Clone, @@ -3153,12 +3164,13 @@ pub mod evm_host { )] #[ethevent( name = "StateCommitmentVetoed", - abi = "StateCommitmentVetoed(bytes,uint256,(uint256,bytes32,bytes32),address)" + abi = "StateCommitmentVetoed(string,uint256,(uint256,bytes32,bytes32),address)" )] pub struct StateCommitmentVetoedFilter { - pub state_machine_id: ::ethers::core::types::Bytes, + pub state_machine_id: ::std::string::String, pub height: ::ethers::core::types::U256, pub state_commitment: StateCommitment, + #[ethevent(indexed)] pub fisherman: ::ethers::core::types::Address, } #[derive( @@ -3171,9 +3183,9 @@ pub mod evm_host { Eq, Hash, )] - #[ethevent(name = "StateMachineUpdated", abi = "StateMachineUpdated(bytes,uint256)")] + #[ethevent(name = "StateMachineUpdated", abi = "StateMachineUpdated(string,uint256)")] pub struct StateMachineUpdatedFilter { - pub state_machine_id: ::ethers::core::types::Bytes, + pub state_machine_id: ::std::string::String, pub height: ::ethers::core::types::U256, } ///Container type for all of the contract's events @@ -4932,7 +4944,7 @@ pub mod evm_host { Eq, Hash, )] - pub struct StateMachineIdReturn(pub ::ethers::core::types::Bytes); + pub struct StateMachineIdReturn(pub ::std::string::String); ///Container type for all return fields from the `timestamp` function with signature /// `timestamp()` and selector `0xb80777ea` #[derive( diff --git a/evm/abi/src/generated/host_manager.rs b/evm/abi/src/generated/host_manager.rs index a91e690ea..89efbc274 100644 --- a/evm/abi/src/generated/host_manager.rs +++ b/evm/abi/src/generated/host_manager.rs @@ -254,12 +254,12 @@ pub mod host_manager { pub static HOSTMANAGER_ABI: ::ethers::contract::Lazy<::ethers::core::abi::Abi> = ::ethers::contract::Lazy::new(__abi); #[rustfmt::skip] - const __BYTECODE: &[u8] = b"`\x80`@R4\x80\x15a\0\x10W`\0\x80\xFD[P`@Qa\x14X8\x03\x80a\x14X\x839\x81\x01`@\x81\x90Ra\0/\x91a\0\x83V[\x80Q`\0\x80T`\x01`\x01`\xA0\x1B\x03\x19\x90\x81\x16`\x01`\x01`\xA0\x1B\x03\x93\x84\x16\x17\x90\x91U` \x90\x92\x01Q`\x01\x80T\x90\x93\x16\x91\x16\x17\x90Ua\0\xEBV[\x80Q`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a\0~W`\0\x80\xFD[\x91\x90PV[`\0`@\x82\x84\x03\x12\x15a\0\x95W`\0\x80\xFD[`@\x80Q\x90\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\0\xC5WcNH{q`\xE0\x1B`\0R`A`\x04R`$`\0\xFD[`@Ra\0\xD1\x83a\0gV[\x81Ra\0\xDF` \x84\x01a\0gV[` \x82\x01R\x93\x92PPPV[a\x13^\x80a\0\xFA`\09`\0\xF3\xFE`\x80`@R4\x80\x15a\0\x10W`\0\x80\xFD[P`\x046\x10a\0\x88W`\x005`\xE0\x1C\x80c\xB5\xA9\x82K\x11a\0[W\x80c\xB5\xA9\x82K\x14a\0\xD6W\x80c\xBC\r\xD4G\x14a\0\xE9W\x80c\xC4\x92\xE4&\x14a\0\xFCW\x80c\xCF\xF0\xAB\x96\x14a\x01\nW`\0\x80\xFD[\x80c\x0B\xC3{\xAB\x14a\0\x8DW\x80c\x0E\x83$\xA2\x14a\0\xA2W\x80c\x0F\xEE2\xCE\x14a\0\xB5W\x80c\xB2\xA0\x1B\xF5\x14a\0\xC8W[`\0\x80\xFD[a\0\xA0a\0\x9B6`\x04a\t\nV[a\x01]V[\0[a\0\xA0a\0\xB06`\x04a\t]V[a\x01\xB9V[a\0\xA0a\0\xC36`\x04a\t\x7FV[a\x02`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01`\0`@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x02\xFBW=`\0\x80>=`\0\xFD[PPPP`@Q=`\0\x82>`\x1F=\x90\x81\x01`\x1F\x19\x16\x82\x01`@Ra\x03#\x91\x90\x81\x01\x90a\x0E\x14V[a\x03-\x83\x80a\x0E\x8AV[\x80\x80`\x1F\x01` \x80\x91\x04\x02` \x01`@Q\x90\x81\x01`@R\x80\x93\x92\x91\x90\x81\x81R` \x01\x83\x83\x80\x82\x847`\0\x92\x01\x91\x90\x91RP\x92\x93\x92PPa\x05\xF8\x90PV[a\x03\xADW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x14`$\x82\x01Rs\x15[\x98]]\x1A\x1B\xDC\x9A^\x99Y\x08\x1C\x99\\]Y\\\xDD`b\x1B`D\x82\x01R`d\x01a\x01\xB0V[`\0a\x03\xBC`\xC0\x83\x01\x83a\x0E\x8AV[`\0\x81\x81\x10a\x03\xCDWa\x03\xCDa\x0E\xD7V[\x91\x90\x91\x015`\xF8\x1C\x90P`\x01\x81\x11\x15a\x03\xE8Wa\x03\xE8a\x0E\xEDV[\x90P`\0\x81`\x01\x81\x11\x15a\x03\xFEWa\x03\xFEa\x0E\xEDV[\x03a\x04\xA1W`\0a\x04\x12`\xC0\x84\x01\x84a\x0E\x8AV[a\x04 \x91`\x01\x90\x82\x90a\x0F\x03V[\x81\x01\x90a\x04-\x91\x90a\x0F-V[`\x01T`@Qc=`\0\xFD[PPPPPPPPV[`\x01\x81`\x01\x81\x11\x15a\x04\xB5Wa\x04\xB5a\x0E\xEDV[\x03a\x05\x15W`\0a\x04\xC9`\xC0\x84\x01\x84a\x0E\x8AV[a\x04\xD7\x91`\x01\x90\x82\x90a\x0F\x03V[\x81\x01\x90a\x04\xE4\x91\x90a\x10@V[`\x01T`@Qc\x03\xCB\x07\xF5`\xE0\x1B\x81R\x91\x92P`\x01`\x01`\xA0\x1B\x03\x16\x90c\x03\xCB\x07\xF5\x90a\x04i\x90\x84\x90`\x04\x01a\x12\x1BV[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x0E`$\x82\x01Rm*\xB75\xB77\xBB\xB7\x100\xB1\xBA4\xB7\xB7`\x91\x1B`D\x82\x01R`d\x01a\x01\xB0V[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`$\x80\x82\x01R\x7FIsmpModule doesn't emit Get requ`D\x82\x01Rcests`\xE0\x1B`d\x82\x01R`\x84\x01a\x01\xB0V[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`%`$\x82\x01R\x7FIsmpModule doesn't emit Post req`D\x82\x01Rduests`\xD8\x1B`d\x82\x01R`\x84\x01a\x01\xB0V[`\0\x81Q\x83Q\x14a\x06\x0BWP`\0a\x06\x1FV[P\x81Q` \x82\x81\x01\x82\x90 \x90\x84\x01\x91\x90\x91 \x14[\x92\x91PPV[cNH{q`\xE0\x1B`\0R`A`\x04R`$`\0\xFD[`@Q`\xE0\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@R\x90V[`@\x80Q\x90\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@Qa\x01\x80\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@Q`\x1F\x82\x01`\x1F\x19\x16\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06\xD0Wa\x06\xD0a\x06%V[`@R\x91\x90PV[`\0`\x01`\x01`@\x1B\x03\x82\x11\x15a\x06\xF1Wa\x06\xF1a\x06%V[P`\x1F\x01`\x1F\x19\x16` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a\x07\x10W`\0\x80\xFD[\x815a\x07#a\x07\x1E\x82a\x06\xD8V[a\x06\xA8V[\x81\x81R\x84` \x83\x86\x01\x01\x11\x15a\x078W`\0\x80\xFD[\x81` \x85\x01` \x83\x017`\0\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[\x805`\x01`\x01`@\x1B\x03\x81\x16\x81\x14a\x07lW`\0\x80\xFD[\x91\x90PV[`\0`\xE0\x82\x84\x03\x12\x15a\x07\x83W`\0\x80\xFD[a\x07\x8Ba\x06;V[\x90P\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\x07\xA4W`\0\x80\xFD[a\x07\xB0\x85\x83\x86\x01a\x06\xFFV[\x83R` \x84\x015\x91P\x80\x82\x11\x15a\x07\xC6W`\0\x80\xFD[a\x07\xD2\x85\x83\x86\x01a\x06\xFFV[` \x84\x01Ra\x07\xE3`@\x85\x01a\x07UV[`@\x84\x01R``\x84\x015\x91P\x80\x82\x11\x15a\x07\xFCW`\0\x80\xFD[a\x08\x08\x85\x83\x86\x01a\x06\xFFV[``\x84\x01R`\x80\x84\x015\x91P\x80\x82\x11\x15a\x08!W`\0\x80\xFD[a\x08-\x85\x83\x86\x01a\x06\xFFV[`\x80\x84\x01Ra\x08>`\xA0\x85\x01a\x07UV[`\xA0\x84\x01R`\xC0\x84\x015\x91P\x80\x82\x11\x15a\x08WW`\0\x80\xFD[Pa\x08d\x84\x82\x85\x01a\x06\xFFV[`\xC0\x83\x01RP\x92\x91PPV[`\0``\x82\x84\x03\x12\x15a\x08\x82W`\0\x80\xFD[`@Q``\x81\x01`\x01`\x01`@\x1B\x03\x82\x82\x10\x81\x83\x11\x17\x15a\x08\xA5Wa\x08\xA5a\x06%V[\x81`@R\x82\x93P\x845\x91P\x80\x82\x11\x15a\x08\xBDW`\0\x80\xFD[a\x08\xC9\x86\x83\x87\x01a\x07qV[\x83R` \x85\x015\x91P\x80\x82\x11\x15a\x08\xDFW`\0\x80\xFD[Pa\x08\xEC\x85\x82\x86\x01a\x06\xFFV[` \x83\x01RPa\x08\xFE`@\x84\x01a\x07UV[`@\x82\x01RP\x92\x91PPV[`\0` \x82\x84\x03\x12\x15a\t\x1CW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\t2W`\0\x80\xFD[a\t>\x84\x82\x85\x01a\x08pV[\x94\x93PPPPV[\x805`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a\x07lW`\0\x80\xFD[`\0` \x82\x84\x03\x12\x15a\toW`\0\x80\xFD[a\tx\x82a\tFV[\x93\x92PPPV[`\0` \x82\x84\x03\x12\x15a\t\x91W`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\t\xA7W`\0\x80\xFD[\x82\x01`@\x81\x85\x03\x12\x15a\txW`\0\x80\xFD[`\0` \x82\x84\x03\x12\x15a\t\xCBW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\t\xE2W`\0\x80\xFD[\x90\x83\x01\x90`@\x82\x86\x03\x12\x15a\t\xF6W`\0\x80\xFD[a\t\xFEa\x06cV[\x825\x82\x81\x11\x15a\n\rW`\0\x80\xFD[a\n\x19\x87\x82\x86\x01a\x08pV[\x82RPa\n(` \x84\x01a\tFV[` \x82\x01R\x95\x94PPPPPV[`\0`\x01`\x01`@\x1B\x03\x82\x11\x15a\nOWa\nOa\x06%V[P`\x05\x1B` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a\njW`\0\x80\xFD[\x815` a\nza\x07\x1E\x83a\n6V[\x82\x81R`\x05\x92\x90\x92\x1B\x84\x01\x81\x01\x91\x81\x81\x01\x90\x86\x84\x11\x15a\n\x99W`\0\x80\xFD[\x82\x86\x01[\x84\x81\x10\x15a\n\xD8W\x805`\x01`\x01`@\x1B\x03\x81\x11\x15a\n\xBCW`\0\x80\x81\xFD[a\n\xCA\x89\x86\x83\x8B\x01\x01a\x06\xFFV[\x84RP\x91\x83\x01\x91\x83\x01a\n\x9DV[P\x96\x95PPPPPPV[`\0`\xE0\x82\x84\x03\x12\x15a\n\xF5W`\0\x80\xFD[a\n\xFDa\x06;V[\x90P\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\x0B\x16W`\0\x80\xFD[a\x0B\"\x85\x83\x86\x01a\x06\xFFV[\x83R` \x84\x015\x91P\x80\x82\x11\x15a\x0B8W`\0\x80\xFD[a\x0BD\x85\x83\x86\x01a\x06\xFFV[` \x84\x01Ra\x0BU`@\x85\x01a\x07UV[`@\x84\x01R``\x84\x015\x91P\x80\x82\x11\x15a\x0BnW`\0\x80\xFD[a\x0Bz\x85\x83\x86\x01a\x06\xFFV[``\x84\x01Ra\x0B\x8B`\x80\x85\x01a\x07UV[`\x80\x84\x01R`\xA0\x84\x015\x91P\x80\x82\x11\x15a\x0B\xA4W`\0\x80\xFD[Pa\x0B\xB1\x84\x82\x85\x01a\nYV[`\xA0\x83\x01RPa\x0B\xC3`\xC0\x83\x01a\x07UV[`\xC0\x82\x01R\x92\x91PPV[`\0` \x82\x84\x03\x12\x15a\x0B\xE0W`\0\x80\xFD[`\x01`\x01`@\x1B\x03\x80\x835\x11\x15a\x0B\xF6W`\0\x80\xFD[\x825\x83\x01`@\x81\x86\x03\x12\x15a\x0C\nW`\0\x80\xFD[a\x0C\x12a\x06cV[\x82\x825\x11\x15a\x0C W`\0\x80\xFD[\x815\x82\x01`@\x81\x88\x03\x12\x15a\x0C4W`\0\x80\xFD[a\x0C\x84\x82\x85\x01a\x07qV[`\0` \x82\x84\x03\x12\x15a\r\xAEW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\r\xC4W`\0\x80\xFD[a\t>\x84\x82\x85\x01a\n\xE3V[`\0\x825`\xDE\x19\x836\x03\x01\x81\x12a\r\xE6W`\0\x80\xFD[\x91\x90\x91\x01\x92\x91PPV[`\0[\x83\x81\x10\x15a\x0E\x0BW\x81\x81\x01Q\x83\x82\x01R` \x01a\r\xF3V[PP`\0\x91\x01RV[`\0` \x82\x84\x03\x12\x15a\x0E&W`\0\x80\xFD[\x81Q`\x01`\x01`@\x1B\x03\x81\x11\x15a\x0E`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01`\0`@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x02\xFBW=`\0\x80>=`\0\xFD[PPPP`@Q=`\0\x82>`\x1F=\x90\x81\x01`\x1F\x19\x16\x82\x01`@Ra\x03#\x91\x90\x81\x01\x90a\x0E\x14V[a\x03-\x83\x80a\x0E\x8AV[\x80\x80`\x1F\x01` \x80\x91\x04\x02` \x01`@Q\x90\x81\x01`@R\x80\x93\x92\x91\x90\x81\x81R` \x01\x83\x83\x80\x82\x847`\0\x92\x01\x91\x90\x91RP\x92\x93\x92PPa\x05\xF8\x90PV[a\x03\xADW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x14`$\x82\x01Rs\x15[\x98]]\x1A\x1B\xDC\x9A^\x99Y\x08\x1C\x99\\]Y\\\xDD`b\x1B`D\x82\x01R`d\x01a\x01\xB0V[`\0a\x03\xBC`\xC0\x83\x01\x83a\x0E\x8AV[`\0\x81\x81\x10a\x03\xCDWa\x03\xCDa\x0E\xD7V[\x91\x90\x91\x015`\xF8\x1C\x90P`\x01\x81\x11\x15a\x03\xE8Wa\x03\xE8a\x0E\xEDV[\x90P`\0\x81`\x01\x81\x11\x15a\x03\xFEWa\x03\xFEa\x0E\xEDV[\x03a\x04\xA1W`\0a\x04\x12`\xC0\x84\x01\x84a\x0E\x8AV[a\x04 \x91`\x01\x90\x82\x90a\x0F\x03V[\x81\x01\x90a\x04-\x91\x90a\x0F-V[`\x01T`@Qc=`\0\xFD[PPPPPPPPV[`\x01\x81`\x01\x81\x11\x15a\x04\xB5Wa\x04\xB5a\x0E\xEDV[\x03a\x05\x15W`\0a\x04\xC9`\xC0\x84\x01\x84a\x0E\x8AV[a\x04\xD7\x91`\x01\x90\x82\x90a\x0F\x03V[\x81\x01\x90a\x04\xE4\x91\x90a\x10@V[`\x01T`@Qc\x03\xCB\x07\xF5`\xE0\x1B\x81R\x91\x92P`\x01`\x01`\xA0\x1B\x03\x16\x90c\x03\xCB\x07\xF5\x90a\x04i\x90\x84\x90`\x04\x01a\x12\x1BV[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x0E`$\x82\x01Rm*\xB75\xB77\xBB\xB7\x100\xB1\xBA4\xB7\xB7`\x91\x1B`D\x82\x01R`d\x01a\x01\xB0V[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`$\x80\x82\x01R\x7FIsmpModule doesn't emit Get requ`D\x82\x01Rcests`\xE0\x1B`d\x82\x01R`\x84\x01a\x01\xB0V[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`%`$\x82\x01R\x7FIsmpModule doesn't emit Post req`D\x82\x01Rduests`\xD8\x1B`d\x82\x01R`\x84\x01a\x01\xB0V[`\0\x81Q\x83Q\x14a\x06\x0BWP`\0a\x06\x1FV[P\x81Q` \x82\x81\x01\x82\x90 \x90\x84\x01\x91\x90\x91 \x14[\x92\x91PPV[cNH{q`\xE0\x1B`\0R`A`\x04R`$`\0\xFD[`@Q`\xE0\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@R\x90V[`@\x80Q\x90\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@Qa\x01\x80\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@Q`\x1F\x82\x01`\x1F\x19\x16\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06\xD0Wa\x06\xD0a\x06%V[`@R\x91\x90PV[`\0`\x01`\x01`@\x1B\x03\x82\x11\x15a\x06\xF1Wa\x06\xF1a\x06%V[P`\x1F\x01`\x1F\x19\x16` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a\x07\x10W`\0\x80\xFD[\x815a\x07#a\x07\x1E\x82a\x06\xD8V[a\x06\xA8V[\x81\x81R\x84` \x83\x86\x01\x01\x11\x15a\x078W`\0\x80\xFD[\x81` \x85\x01` \x83\x017`\0\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[\x805`\x01`\x01`@\x1B\x03\x81\x16\x81\x14a\x07lW`\0\x80\xFD[\x91\x90PV[`\0`\xE0\x82\x84\x03\x12\x15a\x07\x83W`\0\x80\xFD[a\x07\x8Ba\x06;V[\x90P\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\x07\xA4W`\0\x80\xFD[a\x07\xB0\x85\x83\x86\x01a\x06\xFFV[\x83R` \x84\x015\x91P\x80\x82\x11\x15a\x07\xC6W`\0\x80\xFD[a\x07\xD2\x85\x83\x86\x01a\x06\xFFV[` \x84\x01Ra\x07\xE3`@\x85\x01a\x07UV[`@\x84\x01R``\x84\x015\x91P\x80\x82\x11\x15a\x07\xFCW`\0\x80\xFD[a\x08\x08\x85\x83\x86\x01a\x06\xFFV[``\x84\x01R`\x80\x84\x015\x91P\x80\x82\x11\x15a\x08!W`\0\x80\xFD[a\x08-\x85\x83\x86\x01a\x06\xFFV[`\x80\x84\x01Ra\x08>`\xA0\x85\x01a\x07UV[`\xA0\x84\x01R`\xC0\x84\x015\x91P\x80\x82\x11\x15a\x08WW`\0\x80\xFD[Pa\x08d\x84\x82\x85\x01a\x06\xFFV[`\xC0\x83\x01RP\x92\x91PPV[`\0``\x82\x84\x03\x12\x15a\x08\x82W`\0\x80\xFD[`@Q``\x81\x01`\x01`\x01`@\x1B\x03\x82\x82\x10\x81\x83\x11\x17\x15a\x08\xA5Wa\x08\xA5a\x06%V[\x81`@R\x82\x93P\x845\x91P\x80\x82\x11\x15a\x08\xBDW`\0\x80\xFD[a\x08\xC9\x86\x83\x87\x01a\x07qV[\x83R` \x85\x015\x91P\x80\x82\x11\x15a\x08\xDFW`\0\x80\xFD[Pa\x08\xEC\x85\x82\x86\x01a\x06\xFFV[` \x83\x01RPa\x08\xFE`@\x84\x01a\x07UV[`@\x82\x01RP\x92\x91PPV[`\0` \x82\x84\x03\x12\x15a\t\x1CW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\t2W`\0\x80\xFD[a\t>\x84\x82\x85\x01a\x08pV[\x94\x93PPPPV[\x805`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a\x07lW`\0\x80\xFD[`\0` \x82\x84\x03\x12\x15a\toW`\0\x80\xFD[a\tx\x82a\tFV[\x93\x92PPPV[`\0` \x82\x84\x03\x12\x15a\t\x91W`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\t\xA7W`\0\x80\xFD[\x82\x01`@\x81\x85\x03\x12\x15a\txW`\0\x80\xFD[`\0` \x82\x84\x03\x12\x15a\t\xCBW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\t\xE2W`\0\x80\xFD[\x90\x83\x01\x90`@\x82\x86\x03\x12\x15a\t\xF6W`\0\x80\xFD[a\t\xFEa\x06cV[\x825\x82\x81\x11\x15a\n\rW`\0\x80\xFD[a\n\x19\x87\x82\x86\x01a\x08pV[\x82RPa\n(` \x84\x01a\tFV[` \x82\x01R\x95\x94PPPPPV[`\0`\x01`\x01`@\x1B\x03\x82\x11\x15a\nOWa\nOa\x06%V[P`\x05\x1B` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a\njW`\0\x80\xFD[\x815` a\nza\x07\x1E\x83a\n6V[\x82\x81R`\x05\x92\x90\x92\x1B\x84\x01\x81\x01\x91\x81\x81\x01\x90\x86\x84\x11\x15a\n\x99W`\0\x80\xFD[\x82\x86\x01[\x84\x81\x10\x15a\n\xD8W\x805`\x01`\x01`@\x1B\x03\x81\x11\x15a\n\xBCW`\0\x80\x81\xFD[a\n\xCA\x89\x86\x83\x8B\x01\x01a\x06\xFFV[\x84RP\x91\x83\x01\x91\x83\x01a\n\x9DV[P\x96\x95PPPPPPV[`\0`\xE0\x82\x84\x03\x12\x15a\n\xF5W`\0\x80\xFD[a\n\xFDa\x06;V[\x90P\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\x0B\x16W`\0\x80\xFD[a\x0B\"\x85\x83\x86\x01a\x06\xFFV[\x83R` \x84\x015\x91P\x80\x82\x11\x15a\x0B8W`\0\x80\xFD[a\x0BD\x85\x83\x86\x01a\x06\xFFV[` \x84\x01Ra\x0BU`@\x85\x01a\x07UV[`@\x84\x01R``\x84\x015\x91P\x80\x82\x11\x15a\x0BnW`\0\x80\xFD[a\x0Bz\x85\x83\x86\x01a\x06\xFFV[``\x84\x01Ra\x0B\x8B`\x80\x85\x01a\x07UV[`\x80\x84\x01R`\xA0\x84\x015\x91P\x80\x82\x11\x15a\x0B\xA4W`\0\x80\xFD[Pa\x0B\xB1\x84\x82\x85\x01a\nYV[`\xA0\x83\x01RPa\x0B\xC3`\xC0\x83\x01a\x07UV[`\xC0\x82\x01R\x92\x91PPV[`\0` \x82\x84\x03\x12\x15a\x0B\xE0W`\0\x80\xFD[`\x01`\x01`@\x1B\x03\x80\x835\x11\x15a\x0B\xF6W`\0\x80\xFD[\x825\x83\x01`@\x81\x86\x03\x12\x15a\x0C\nW`\0\x80\xFD[a\x0C\x12a\x06cV[\x82\x825\x11\x15a\x0C W`\0\x80\xFD[\x815\x82\x01`@\x81\x88\x03\x12\x15a\x0C4W`\0\x80\xFD[a\x0C\x84\x82\x85\x01a\x07qV[`\0` \x82\x84\x03\x12\x15a\r\xAEW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\r\xC4W`\0\x80\xFD[a\t>\x84\x82\x85\x01a\n\xE3V[`\0\x825`\xDE\x19\x836\x03\x01\x81\x12a\r\xE6W`\0\x80\xFD[\x91\x90\x91\x01\x92\x91PPV[`\0[\x83\x81\x10\x15a\x0E\x0BW\x81\x81\x01Q\x83\x82\x01R` \x01a\r\xF3V[PP`\0\x91\x01RV[`\0` \x82\x84\x03\x12\x15a\x0E&W`\0\x80\xFD[\x81Q`\x01`\x01`@\x1B\x03\x81\x11\x15a\x0E`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01`\0`@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x02\xFBW=`\0\x80>=`\0\xFD[PPPP`@Q=`\0\x82>`\x1F=\x90\x81\x01`\x1F\x19\x16\x82\x01`@Ra\x03#\x91\x90\x81\x01\x90a\x0E\x14V[a\x03-\x83\x80a\x0E\x8AV[\x80\x80`\x1F\x01` \x80\x91\x04\x02` \x01`@Q\x90\x81\x01`@R\x80\x93\x92\x91\x90\x81\x81R` \x01\x83\x83\x80\x82\x847`\0\x92\x01\x91\x90\x91RP\x92\x93\x92PPa\x05\xF8\x90PV[a\x03\xADW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x14`$\x82\x01Rs\x15[\x98]]\x1A\x1B\xDC\x9A^\x99Y\x08\x1C\x99\\]Y\\\xDD`b\x1B`D\x82\x01R`d\x01a\x01\xB0V[`\0a\x03\xBC`\xC0\x83\x01\x83a\x0E\x8AV[`\0\x81\x81\x10a\x03\xCDWa\x03\xCDa\x0E\xD7V[\x91\x90\x91\x015`\xF8\x1C\x90P`\x01\x81\x11\x15a\x03\xE8Wa\x03\xE8a\x0E\xEDV[\x90P`\0\x81`\x01\x81\x11\x15a\x03\xFEWa\x03\xFEa\x0E\xEDV[\x03a\x04\xA1W`\0a\x04\x12`\xC0\x84\x01\x84a\x0E\x8AV[a\x04 \x91`\x01\x90\x82\x90a\x0F\x03V[\x81\x01\x90a\x04-\x91\x90a\x0F-V[`\x01T`@Qc=`\0\xFD[PPPPPPPPV[`\x01\x81`\x01\x81\x11\x15a\x04\xB5Wa\x04\xB5a\x0E\xEDV[\x03a\x05\x15W`\0a\x04\xC9`\xC0\x84\x01\x84a\x0E\x8AV[a\x04\xD7\x91`\x01\x90\x82\x90a\x0F\x03V[\x81\x01\x90a\x04\xE4\x91\x90a\x10@V[`\x01T`@Qc\x03\xCB\x07\xF5`\xE0\x1B\x81R\x91\x92P`\x01`\x01`\xA0\x1B\x03\x16\x90c\x03\xCB\x07\xF5\x90a\x04i\x90\x84\x90`\x04\x01a\x12\x1BV[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x0E`$\x82\x01Rm*\xB75\xB77\xBB\xB7\x100\xB1\xBA4\xB7\xB7`\x91\x1B`D\x82\x01R`d\x01a\x01\xB0V[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`$\x80\x82\x01R\x7FIsmpModule doesn't emit Get requ`D\x82\x01Rcests`\xE0\x1B`d\x82\x01R`\x84\x01a\x01\xB0V[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`%`$\x82\x01R\x7FIsmpModule doesn't emit Post req`D\x82\x01Rduests`\xD8\x1B`d\x82\x01R`\x84\x01a\x01\xB0V[`\0\x81Q\x83Q\x14a\x06\x0BWP`\0a\x06\x1FV[P\x81Q` \x82\x81\x01\x82\x90 \x90\x84\x01\x91\x90\x91 \x14[\x92\x91PPV[cNH{q`\xE0\x1B`\0R`A`\x04R`$`\0\xFD[`@Q`\xE0\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@R\x90V[`@\x80Q\x90\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@Qa\x01\x80\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@Q`\x1F\x82\x01`\x1F\x19\x16\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06\xD0Wa\x06\xD0a\x06%V[`@R\x91\x90PV[`\0`\x01`\x01`@\x1B\x03\x82\x11\x15a\x06\xF1Wa\x06\xF1a\x06%V[P`\x1F\x01`\x1F\x19\x16` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a\x07\x10W`\0\x80\xFD[\x815a\x07#a\x07\x1E\x82a\x06\xD8V[a\x06\xA8V[\x81\x81R\x84` \x83\x86\x01\x01\x11\x15a\x078W`\0\x80\xFD[\x81` \x85\x01` \x83\x017`\0\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[\x805`\x01`\x01`@\x1B\x03\x81\x16\x81\x14a\x07lW`\0\x80\xFD[\x91\x90PV[`\0`\xE0\x82\x84\x03\x12\x15a\x07\x83W`\0\x80\xFD[a\x07\x8Ba\x06;V[\x90P\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\x07\xA4W`\0\x80\xFD[a\x07\xB0\x85\x83\x86\x01a\x06\xFFV[\x83R` \x84\x015\x91P\x80\x82\x11\x15a\x07\xC6W`\0\x80\xFD[a\x07\xD2\x85\x83\x86\x01a\x06\xFFV[` \x84\x01Ra\x07\xE3`@\x85\x01a\x07UV[`@\x84\x01R``\x84\x015\x91P\x80\x82\x11\x15a\x07\xFCW`\0\x80\xFD[a\x08\x08\x85\x83\x86\x01a\x06\xFFV[``\x84\x01R`\x80\x84\x015\x91P\x80\x82\x11\x15a\x08!W`\0\x80\xFD[a\x08-\x85\x83\x86\x01a\x06\xFFV[`\x80\x84\x01Ra\x08>`\xA0\x85\x01a\x07UV[`\xA0\x84\x01R`\xC0\x84\x015\x91P\x80\x82\x11\x15a\x08WW`\0\x80\xFD[Pa\x08d\x84\x82\x85\x01a\x06\xFFV[`\xC0\x83\x01RP\x92\x91PPV[`\0``\x82\x84\x03\x12\x15a\x08\x82W`\0\x80\xFD[`@Q``\x81\x01`\x01`\x01`@\x1B\x03\x82\x82\x10\x81\x83\x11\x17\x15a\x08\xA5Wa\x08\xA5a\x06%V[\x81`@R\x82\x93P\x845\x91P\x80\x82\x11\x15a\x08\xBDW`\0\x80\xFD[a\x08\xC9\x86\x83\x87\x01a\x07qV[\x83R` \x85\x015\x91P\x80\x82\x11\x15a\x08\xDFW`\0\x80\xFD[Pa\x08\xEC\x85\x82\x86\x01a\x06\xFFV[` \x83\x01RPa\x08\xFE`@\x84\x01a\x07UV[`@\x82\x01RP\x92\x91PPV[`\0` \x82\x84\x03\x12\x15a\t\x1CW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\t2W`\0\x80\xFD[a\t>\x84\x82\x85\x01a\x08pV[\x94\x93PPPPV[\x805`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a\x07lW`\0\x80\xFD[`\0` \x82\x84\x03\x12\x15a\toW`\0\x80\xFD[a\tx\x82a\tFV[\x93\x92PPPV[`\0` \x82\x84\x03\x12\x15a\t\x91W`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\t\xA7W`\0\x80\xFD[\x82\x01`@\x81\x85\x03\x12\x15a\txW`\0\x80\xFD[`\0` \x82\x84\x03\x12\x15a\t\xCBW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\t\xE2W`\0\x80\xFD[\x90\x83\x01\x90`@\x82\x86\x03\x12\x15a\t\xF6W`\0\x80\xFD[a\t\xFEa\x06cV[\x825\x82\x81\x11\x15a\n\rW`\0\x80\xFD[a\n\x19\x87\x82\x86\x01a\x08pV[\x82RPa\n(` \x84\x01a\tFV[` \x82\x01R\x95\x94PPPPPV[`\0`\x01`\x01`@\x1B\x03\x82\x11\x15a\nOWa\nOa\x06%V[P`\x05\x1B` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a\njW`\0\x80\xFD[\x815` a\nza\x07\x1E\x83a\n6V[\x82\x81R`\x05\x92\x90\x92\x1B\x84\x01\x81\x01\x91\x81\x81\x01\x90\x86\x84\x11\x15a\n\x99W`\0\x80\xFD[\x82\x86\x01[\x84\x81\x10\x15a\n\xD8W\x805`\x01`\x01`@\x1B\x03\x81\x11\x15a\n\xBCW`\0\x80\x81\xFD[a\n\xCA\x89\x86\x83\x8B\x01\x01a\x06\xFFV[\x84RP\x91\x83\x01\x91\x83\x01a\n\x9DV[P\x96\x95PPPPPPV[`\0`\xE0\x82\x84\x03\x12\x15a\n\xF5W`\0\x80\xFD[a\n\xFDa\x06;V[\x90P\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\x0B\x16W`\0\x80\xFD[a\x0B\"\x85\x83\x86\x01a\x06\xFFV[\x83R` \x84\x015\x91P\x80\x82\x11\x15a\x0B8W`\0\x80\xFD[a\x0BD\x85\x83\x86\x01a\x06\xFFV[` \x84\x01Ra\x0BU`@\x85\x01a\x07UV[`@\x84\x01R``\x84\x015\x91P\x80\x82\x11\x15a\x0BnW`\0\x80\xFD[a\x0Bz\x85\x83\x86\x01a\x06\xFFV[``\x84\x01Ra\x0B\x8B`\x80\x85\x01a\x07UV[`\x80\x84\x01R`\xA0\x84\x015\x91P\x80\x82\x11\x15a\x0B\xA4W`\0\x80\xFD[Pa\x0B\xB1\x84\x82\x85\x01a\nYV[`\xA0\x83\x01RPa\x0B\xC3`\xC0\x83\x01a\x07UV[`\xC0\x82\x01R\x92\x91PPV[`\0` \x82\x84\x03\x12\x15a\x0B\xE0W`\0\x80\xFD[`\x01`\x01`@\x1B\x03\x80\x835\x11\x15a\x0B\xF6W`\0\x80\xFD[\x825\x83\x01`@\x81\x86\x03\x12\x15a\x0C\nW`\0\x80\xFD[a\x0C\x12a\x06cV[\x82\x825\x11\x15a\x0C W`\0\x80\xFD[\x815\x82\x01`@\x81\x88\x03\x12\x15a\x0C4W`\0\x80\xFD[a\x0C\x84\x82\x85\x01a\x07qV[`\0` \x82\x84\x03\x12\x15a\r\xAEW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\r\xC4W`\0\x80\xFD[a\t>\x84\x82\x85\x01a\n\xE3V[`\0\x825`\xDE\x19\x836\x03\x01\x81\x12a\r\xE6W`\0\x80\xFD[\x91\x90\x91\x01\x92\x91PPV[`\0[\x83\x81\x10\x15a\x0E\x0BW\x81\x81\x01Q\x83\x82\x01R` \x01a\r\xF3V[PP`\0\x91\x01RV[`\0` \x82\x84\x03\x12\x15a\x0E&W`\0\x80\xFD[\x81Q`\x01`\x01`@\x1B\x03\x81\x11\x15a\x0E`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01`\0`@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x02\xFBW=`\0\x80>=`\0\xFD[PPPP`@Q=`\0\x82>`\x1F=\x90\x81\x01`\x1F\x19\x16\x82\x01`@Ra\x03#\x91\x90\x81\x01\x90a\x0E\x14V[a\x03-\x83\x80a\x0E\x8AV[\x80\x80`\x1F\x01` \x80\x91\x04\x02` \x01`@Q\x90\x81\x01`@R\x80\x93\x92\x91\x90\x81\x81R` \x01\x83\x83\x80\x82\x847`\0\x92\x01\x91\x90\x91RP\x92\x93\x92PPa\x05\xF8\x90PV[a\x03\xADW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x14`$\x82\x01Rs\x15[\x98]]\x1A\x1B\xDC\x9A^\x99Y\x08\x1C\x99\\]Y\\\xDD`b\x1B`D\x82\x01R`d\x01a\x01\xB0V[`\0a\x03\xBC`\xC0\x83\x01\x83a\x0E\x8AV[`\0\x81\x81\x10a\x03\xCDWa\x03\xCDa\x0E\xD7V[\x91\x90\x91\x015`\xF8\x1C\x90P`\x01\x81\x11\x15a\x03\xE8Wa\x03\xE8a\x0E\xEDV[\x90P`\0\x81`\x01\x81\x11\x15a\x03\xFEWa\x03\xFEa\x0E\xEDV[\x03a\x04\xA1W`\0a\x04\x12`\xC0\x84\x01\x84a\x0E\x8AV[a\x04 \x91`\x01\x90\x82\x90a\x0F\x03V[\x81\x01\x90a\x04-\x91\x90a\x0F-V[`\x01T`@Qc=`\0\xFD[PPPPPPPPV[`\x01\x81`\x01\x81\x11\x15a\x04\xB5Wa\x04\xB5a\x0E\xEDV[\x03a\x05\x15W`\0a\x04\xC9`\xC0\x84\x01\x84a\x0E\x8AV[a\x04\xD7\x91`\x01\x90\x82\x90a\x0F\x03V[\x81\x01\x90a\x04\xE4\x91\x90a\x10@V[`\x01T`@Qc\x03\xCB\x07\xF5`\xE0\x1B\x81R\x91\x92P`\x01`\x01`\xA0\x1B\x03\x16\x90c\x03\xCB\x07\xF5\x90a\x04i\x90\x84\x90`\x04\x01a\x12\x1BV[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x0E`$\x82\x01Rm*\xB75\xB77\xBB\xB7\x100\xB1\xBA4\xB7\xB7`\x91\x1B`D\x82\x01R`d\x01a\x01\xB0V[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`$\x80\x82\x01R\x7FIsmpModule doesn't emit Get requ`D\x82\x01Rcests`\xE0\x1B`d\x82\x01R`\x84\x01a\x01\xB0V[`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`%`$\x82\x01R\x7FIsmpModule doesn't emit Post req`D\x82\x01Rduests`\xD8\x1B`d\x82\x01R`\x84\x01a\x01\xB0V[`\0\x81Q\x83Q\x14a\x06\x0BWP`\0a\x06\x1FV[P\x81Q` \x82\x81\x01\x82\x90 \x90\x84\x01\x91\x90\x91 \x14[\x92\x91PPV[cNH{q`\xE0\x1B`\0R`A`\x04R`$`\0\xFD[`@Q`\xE0\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@R\x90V[`@\x80Q\x90\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@Qa\x01\x80\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06]Wa\x06]a\x06%V[`@Q`\x1F\x82\x01`\x1F\x19\x16\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a\x06\xD0Wa\x06\xD0a\x06%V[`@R\x91\x90PV[`\0`\x01`\x01`@\x1B\x03\x82\x11\x15a\x06\xF1Wa\x06\xF1a\x06%V[P`\x1F\x01`\x1F\x19\x16` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a\x07\x10W`\0\x80\xFD[\x815a\x07#a\x07\x1E\x82a\x06\xD8V[a\x06\xA8V[\x81\x81R\x84` \x83\x86\x01\x01\x11\x15a\x078W`\0\x80\xFD[\x81` \x85\x01` \x83\x017`\0\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[\x805`\x01`\x01`@\x1B\x03\x81\x16\x81\x14a\x07lW`\0\x80\xFD[\x91\x90PV[`\0`\xE0\x82\x84\x03\x12\x15a\x07\x83W`\0\x80\xFD[a\x07\x8Ba\x06;V[\x90P\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\x07\xA4W`\0\x80\xFD[a\x07\xB0\x85\x83\x86\x01a\x06\xFFV[\x83R` \x84\x015\x91P\x80\x82\x11\x15a\x07\xC6W`\0\x80\xFD[a\x07\xD2\x85\x83\x86\x01a\x06\xFFV[` \x84\x01Ra\x07\xE3`@\x85\x01a\x07UV[`@\x84\x01R``\x84\x015\x91P\x80\x82\x11\x15a\x07\xFCW`\0\x80\xFD[a\x08\x08\x85\x83\x86\x01a\x06\xFFV[``\x84\x01R`\x80\x84\x015\x91P\x80\x82\x11\x15a\x08!W`\0\x80\xFD[a\x08-\x85\x83\x86\x01a\x06\xFFV[`\x80\x84\x01Ra\x08>`\xA0\x85\x01a\x07UV[`\xA0\x84\x01R`\xC0\x84\x015\x91P\x80\x82\x11\x15a\x08WW`\0\x80\xFD[Pa\x08d\x84\x82\x85\x01a\x06\xFFV[`\xC0\x83\x01RP\x92\x91PPV[`\0``\x82\x84\x03\x12\x15a\x08\x82W`\0\x80\xFD[`@Q``\x81\x01`\x01`\x01`@\x1B\x03\x82\x82\x10\x81\x83\x11\x17\x15a\x08\xA5Wa\x08\xA5a\x06%V[\x81`@R\x82\x93P\x845\x91P\x80\x82\x11\x15a\x08\xBDW`\0\x80\xFD[a\x08\xC9\x86\x83\x87\x01a\x07qV[\x83R` \x85\x015\x91P\x80\x82\x11\x15a\x08\xDFW`\0\x80\xFD[Pa\x08\xEC\x85\x82\x86\x01a\x06\xFFV[` \x83\x01RPa\x08\xFE`@\x84\x01a\x07UV[`@\x82\x01RP\x92\x91PPV[`\0` \x82\x84\x03\x12\x15a\t\x1CW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\t2W`\0\x80\xFD[a\t>\x84\x82\x85\x01a\x08pV[\x94\x93PPPPV[\x805`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a\x07lW`\0\x80\xFD[`\0` \x82\x84\x03\x12\x15a\toW`\0\x80\xFD[a\tx\x82a\tFV[\x93\x92PPPV[`\0` \x82\x84\x03\x12\x15a\t\x91W`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\t\xA7W`\0\x80\xFD[\x82\x01`@\x81\x85\x03\x12\x15a\txW`\0\x80\xFD[`\0` \x82\x84\x03\x12\x15a\t\xCBW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\t\xE2W`\0\x80\xFD[\x90\x83\x01\x90`@\x82\x86\x03\x12\x15a\t\xF6W`\0\x80\xFD[a\t\xFEa\x06cV[\x825\x82\x81\x11\x15a\n\rW`\0\x80\xFD[a\n\x19\x87\x82\x86\x01a\x08pV[\x82RPa\n(` \x84\x01a\tFV[` \x82\x01R\x95\x94PPPPPV[`\0`\x01`\x01`@\x1B\x03\x82\x11\x15a\nOWa\nOa\x06%V[P`\x05\x1B` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a\njW`\0\x80\xFD[\x815` a\nza\x07\x1E\x83a\n6V[\x82\x81R`\x05\x92\x90\x92\x1B\x84\x01\x81\x01\x91\x81\x81\x01\x90\x86\x84\x11\x15a\n\x99W`\0\x80\xFD[\x82\x86\x01[\x84\x81\x10\x15a\n\xD8W\x805`\x01`\x01`@\x1B\x03\x81\x11\x15a\n\xBCW`\0\x80\x81\xFD[a\n\xCA\x89\x86\x83\x8B\x01\x01a\x06\xFFV[\x84RP\x91\x83\x01\x91\x83\x01a\n\x9DV[P\x96\x95PPPPPPV[`\0`\xE0\x82\x84\x03\x12\x15a\n\xF5W`\0\x80\xFD[a\n\xFDa\x06;V[\x90P\x815`\x01`\x01`@\x1B\x03\x80\x82\x11\x15a\x0B\x16W`\0\x80\xFD[a\x0B\"\x85\x83\x86\x01a\x06\xFFV[\x83R` \x84\x015\x91P\x80\x82\x11\x15a\x0B8W`\0\x80\xFD[a\x0BD\x85\x83\x86\x01a\x06\xFFV[` \x84\x01Ra\x0BU`@\x85\x01a\x07UV[`@\x84\x01R``\x84\x015\x91P\x80\x82\x11\x15a\x0BnW`\0\x80\xFD[a\x0Bz\x85\x83\x86\x01a\x06\xFFV[``\x84\x01Ra\x0B\x8B`\x80\x85\x01a\x07UV[`\x80\x84\x01R`\xA0\x84\x015\x91P\x80\x82\x11\x15a\x0B\xA4W`\0\x80\xFD[Pa\x0B\xB1\x84\x82\x85\x01a\nYV[`\xA0\x83\x01RPa\x0B\xC3`\xC0\x83\x01a\x07UV[`\xC0\x82\x01R\x92\x91PPV[`\0` \x82\x84\x03\x12\x15a\x0B\xE0W`\0\x80\xFD[`\x01`\x01`@\x1B\x03\x80\x835\x11\x15a\x0B\xF6W`\0\x80\xFD[\x825\x83\x01`@\x81\x86\x03\x12\x15a\x0C\nW`\0\x80\xFD[a\x0C\x12a\x06cV[\x82\x825\x11\x15a\x0C W`\0\x80\xFD[\x815\x82\x01`@\x81\x88\x03\x12\x15a\x0C4W`\0\x80\xFD[a\x0C\x84\x82\x85\x01a\x07qV[`\0` \x82\x84\x03\x12\x15a\r\xAEW`\0\x80\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a\r\xC4W`\0\x80\xFD[a\t>\x84\x82\x85\x01a\n\xE3V[`\0\x825`\xDE\x19\x836\x03\x01\x81\x12a\r\xE6W`\0\x80\xFD[\x91\x90\x91\x01\x92\x91PPV[`\0[\x83\x81\x10\x15a\x0E\x0BW\x81\x81\x01Q\x83\x82\x01R` \x01a\r\xF3V[PP`\0\x91\x01RV[`\0` \x82\x84\x03\x12\x15a\x0E&W`\0\x80\xFD[\x81Q`\x01`\x01`@\x1B\x03\x81\x11\x15a\x0E ::ethers::contract::builders::Event<::std::sync::Arc, M, GetTimeoutReceivedFilter> { + ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, GetTimeoutReceivedFilter> + { self.0.event() } ///Gets the contract's `MessageDispatched` event pub fn message_dispatched_filter( &self, - ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, MessageDispatchedFilter> { + ) -> ::ethers::contract::builders::Event<::std::sync::Arc, M, MessageDispatchedFilter> + { self.0.event() } ///Gets the contract's `PostReceived` event diff --git a/evm/integration-tests/Cargo.toml b/evm/integration-tests/Cargo.toml index 4ea6bc971..191d74293 100644 --- a/evm/integration-tests/Cargo.toml +++ b/evm/integration-tests/Cargo.toml @@ -23,9 +23,8 @@ tracing = "0.1.34" tracing-subscriber = "0.3.11" serde = "1.0.188" envy = "0.4.2" -subxt = { workspace = true, features = [ - "substrate-compat", -], default-features = true } +subxt = { workspace = true, features = ["substrate-compat"], default-features = true } +subxt-utils = { workspace = true, default-features = true } # substrate trie-db = { workspace = true, default-features = true } diff --git a/evm/integration-tests/src/tests/beefy_v1.rs b/evm/integration-tests/src/tests/beefy_v1.rs index e41d3c376..bd8c45125 100644 --- a/evm/integration-tests/src/tests/beefy_v1.rs +++ b/evm/integration-tests/src/tests/beefy_v1.rs @@ -54,7 +54,7 @@ impl subxt::Config for HyperbridgeConfig { } fn default_para_id() -> u32 { - 2000 + 4009 } fn activation_block() -> u32 { 0 @@ -87,8 +87,8 @@ async fn beefy_consensus_client_test() -> Result<(), anyhow::Error> { let config = envy::from_env::()?; let Config { relay_ws_url, para_ws_url, para_id, activation_block } = config; - let relay = subxt::client::OnlineClient::::from_url(relay_ws_url).await?; - let para = subxt::client::OnlineClient::::from_url(para_ws_url).await?; + let relay = subxt_utils::client::ws_client::(&relay_ws_url, u32::MAX).await?; + let para = subxt_utils::client::ws_client::(¶_ws_url, u32::MAX).await?; para.blocks() .subscribe_best() diff --git a/evm/integration-tests/src/tests/get_response.rs b/evm/integration-tests/src/tests/get_response.rs index 02e93e9cf..d149a0693 100644 --- a/evm/integration-tests/src/tests/get_response.rs +++ b/evm/integration-tests/src/tests/get_response.rs @@ -7,7 +7,7 @@ use forge_testsuite::Runner; use ismp::{ host::{Ethereum, StateMachine}, messaging::hash_request, - router::{Get, Request}, + router::{self, Request}, }; use ismp_solidity_abi::{ beefy::{IntermediateState, StateCommitment, StateMachineHeight}, @@ -30,7 +30,7 @@ async fn test_get_response() -> Result<(), anyhow::Error> { let key = H256::random().as_bytes().to_vec(); // create post request object - let get = Get { + let get = router::GetRequest { dest: StateMachine::Polkadot(2000), source: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, diff --git a/evm/integration-tests/src/tests/get_timeout.rs b/evm/integration-tests/src/tests/get_timeout.rs index 296e64296..c430830ee 100644 --- a/evm/integration-tests/src/tests/get_timeout.rs +++ b/evm/integration-tests/src/tests/get_timeout.rs @@ -2,7 +2,7 @@ use ethers::abi::{Address, Tokenizable}; use forge_testsuite::Runner; use ismp::{ host::{Ethereum, StateMachine}, - router::Get, + router, }; use ismp_solidity_abi::shared_types::GetRequest; use primitive_types::H256; @@ -18,7 +18,7 @@ async fn test_get_timeout() -> Result<(), anyhow::Error> { let key = H256::random().as_bytes().to_vec(); // create post request object - let get = Get { + let get = router::GetRequest { dest: StateMachine::Polkadot(2000), source: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, diff --git a/evm/integration-tests/src/tests/host_manager.rs b/evm/integration-tests/src/tests/host_manager.rs index 33a5a0f9e..055108620 100644 --- a/evm/integration-tests/src/tests/host_manager.rs +++ b/evm/integration-tests/src/tests/host_manager.rs @@ -3,7 +3,7 @@ use forge_testsuite::Runner; use foundry_evm::executor::EvmError; use ismp::{ host::{Ethereum, StateMachine}, - router::Post, + router, }; use ismp_solidity_abi::shared_types::PostRequest; use pallet_ismp_host_executive::EvmHostParamsAbi; @@ -21,17 +21,17 @@ async fn test_host_manager_withdraw() -> Result<(), anyhow::Error> { beneficiary_address: H160::random().as_bytes().to_vec(), amount: U256::from(500_000_000_000_000_000_000u128), }; - let data = params.abi_encode(); + let body = params.abi_encode(); // create post request object - let post = Post { + let post = router::PostRequest { source: StateMachine::Kusama(2000), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, from: contract.runner.sender.as_bytes().to_vec(), to: vec![], timeout_timestamp: 100, - data, + body, }; let request: PostRequest = post.into(); @@ -52,10 +52,10 @@ async fn test_host_manager_unauthorized_request() -> Result<(), anyhow::Error> { beneficiary_address: H160::random().as_bytes().to_vec(), amount: U256::from(500_000_000_000_000_000_000u128), }; - let data = params.abi_encode(); + let body = params.abi_encode(); // create post request object - let post = Post { + let post = router::PostRequest { // wrong source source: StateMachine::Polkadot(1000), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), @@ -63,7 +63,7 @@ async fn test_host_manager_unauthorized_request() -> Result<(), anyhow::Error> { from: contract.runner.sender.as_bytes().to_vec(), to: vec![], timeout_timestamp: 100, - data, + body, }; let request: PostRequest = post.into(); @@ -92,17 +92,17 @@ async fn test_host_manager_insufficient_balance() -> Result<(), anyhow::Error> { beneficiary_address: H160::random().as_bytes().to_vec(), amount: U256::from(500_000_000_000_000_000_000u128), }; - let data = params.abi_encode(); + let body = params.abi_encode(); // create post request object - let post = Post { + let post = router::PostRequest { source: StateMachine::Kusama(2000), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, from: contract.runner.sender.as_bytes().to_vec(), to: vec![], timeout_timestamp: 100, - data, + body, }; let request: PostRequest = post.into(); @@ -135,14 +135,14 @@ async fn test_host_manager_set_host_params() -> Result<(), anyhow::Error> { }; // create post request object - let post = Post { + let post = router::PostRequest { source: StateMachine::Kusama(2000), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, from: contract.runner.sender.as_bytes().to_vec(), to: vec![], timeout_timestamp: 100, - data: params.encode(), + body: params.encode(), }; let request: PostRequest = post.into(); diff --git a/evm/integration-tests/src/tests/post_request.rs b/evm/integration-tests/src/tests/post_request.rs index d598d2d74..57029c490 100644 --- a/evm/integration-tests/src/tests/post_request.rs +++ b/evm/integration-tests/src/tests/post_request.rs @@ -6,7 +6,7 @@ use ethers::{ use forge_testsuite::Runner; use ismp::{ host::{Ethereum, StateMachine}, - router::{Post, Request}, + router::{PostRequest, Request}, }; use ismp_solidity_abi::{ beefy::IntermediateState, @@ -25,14 +25,14 @@ async fn test_post_request_proof() -> Result<(), anyhow::Error> { let destination = contract.call::<_, Address>("module", ()).await?; // create post request object - let post = Post { + let post = PostRequest { source: StateMachine::Polkadot(2000), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, from: contract.runner.sender.as_bytes().to_vec(), to: destination.as_bytes().to_vec(), timeout_timestamp: 100, - data: vec![], + body: vec![], }; let request = DataOrHash::Data(Leaf::Request(Request::Post(post.clone()))); let (overlay_root, proof, k_index) = initialize_mmr_tree(request, 10)?; diff --git a/evm/integration-tests/src/tests/post_response.rs b/evm/integration-tests/src/tests/post_response.rs index f3b2416e3..e392b2326 100644 --- a/evm/integration-tests/src/tests/post_response.rs +++ b/evm/integration-tests/src/tests/post_response.rs @@ -11,8 +11,7 @@ use hex_literal::hex; use ismp::{ host::{Ethereum, StateMachine}, messaging::hash_response, - router, - router::{Post, Request, Response}, + router::{self, Request, Response}, }; use ismp_solidity_abi::{ beefy::IntermediateState, @@ -37,14 +36,14 @@ async fn test_post_response_proof() -> Result<(), anyhow::Error> { let module = contract.call::<_, Address>("module", ()).await?; // create post request object - let post = Post { + let post = router::PostRequest { source: StateMachine::Ethereum(Ethereum::ExecutionLayer), dest: StateMachine::Polkadot(2000), nonce: 0, from: module.as_bytes().to_vec(), to: module.as_bytes().to_vec(), timeout_timestamp: 30, - data: vec![2u8; 32], + body: vec![2u8; 32], }; let post_response = @@ -113,14 +112,14 @@ async fn test_post_response_timeout() -> Result<(), anyhow::Error> { let destination = contract.call::<_, Address>("module", ()).await?; // create post request object - let post = Post { + let post = router::PostRequest { source: StateMachine::Polkadot(2000), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, from: contract.runner.sender.as_bytes().to_vec(), to: destination.as_bytes().to_vec(), timeout_timestamp: 100, - data: vec![], + body: vec![], }; let request = DataOrHash::Data(Leaf::Request(Request::Post(post.clone()))); let (overlay_root, proof, k_index) = initialize_mmr_tree(request, 10)?; @@ -201,14 +200,14 @@ async fn test_post_response_malicious_timeout() -> Result<(), anyhow::Error> { let destination = contract.call::<_, Address>("module", ()).await?; // create post request object - let post = Post { + let post = router::PostRequest { source: StateMachine::Polkadot(2000), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, from: contract.runner.sender.as_bytes().to_vec(), to: destination.as_bytes().to_vec(), timeout_timestamp: 100, - data: vec![], + body: vec![], }; let request = DataOrHash::Data(Leaf::Request(Request::Post(post.clone()))); let (overlay_root, proof, k_index) = initialize_mmr_tree(request, 10)?; diff --git a/evm/integration-tests/src/tests/post_timeout.rs b/evm/integration-tests/src/tests/post_timeout.rs index 1ebb35726..18ec70762 100644 --- a/evm/integration-tests/src/tests/post_timeout.rs +++ b/evm/integration-tests/src/tests/post_timeout.rs @@ -9,7 +9,7 @@ use hex_literal::hex; use ismp::{ host::{Ethereum, StateMachine}, messaging::hash_request, - router::{Post, Request}, + router::{self, Request}, }; use ismp_solidity_abi::{ beefy::IntermediateState, @@ -29,14 +29,14 @@ async fn test_post_timeout_proof() -> Result<(), anyhow::Error> { let storage_prefix = hex!("526571756573745265636569707473").to_vec(); // create post request object - let post = Post { + let post = router::PostRequest { source: StateMachine::Ethereum(Ethereum::ExecutionLayer), dest: StateMachine::Polkadot(2000), nonce: 0, from: module.as_bytes().to_vec(), to: module.as_bytes().to_vec(), timeout_timestamp: 10_000, - data: storage_prefix.clone(), + body: storage_prefix.clone(), }; let commitment = hash_request::(&Request::Post(post.clone())); diff --git a/evm/script/DeployIsmp.s.sol b/evm/script/DeployIsmp.s.sol index 67367f44a..278f57fa7 100644 --- a/evm/script/DeployIsmp.s.sol +++ b/evm/script/DeployIsmp.s.sol @@ -29,7 +29,7 @@ import {PingModule} from "../examples/PingModule.sol"; import {BscHost} from "../src/hosts/Bsc.sol"; import {PolygonHost} from "../src/hosts/Polygon.sol"; import {PolkadotVerifier} from "../src/consensus/verifiers/PolkadotVerifier.sol"; -import {ZkBeefyV1} from "../src/consensus/ZkBeefy.sol"; +import {UltraPlonkBeefy} from "../src/consensus/UltraPlonkBeefy.sol"; import {BeefyV1} from "../src/consensus/BeefyV1.sol"; import {StateMachine} from "ismp/StateMachine.sol"; import {FeeToken} from "../test/FeeToken.sol"; @@ -53,11 +53,11 @@ contract DeployScript is Script { ERC6160Ext20 feeToken = new ERC6160Ext20{salt: salt}(admin, "Hyper USD", "USD.h"); // mint $1b to the dispatcher for tests - feeToken.mint(pingDispatcher, 1000000000 * 1e18); + feeToken.mint(pingDispatcher, 1_000_000_000 * 1e18); // consensus client // PolkadotVerifier verifier = new PolkadotVerifier(); - // ZkBeefyV1 consensusClient = new ZkBeefyV1{salt: salt}(paraId, verifier); + // UltraPlonkBeefy consensusClient = new UltraPlonkBeefy{salt: salt}(paraId, verifier); BeefyV1 consensusClient = new BeefyV1{salt: salt}(paraId); // handler @@ -135,7 +135,7 @@ contract DeployScript is Script { feeToken.grantRole(BURNER_ROLE, address(gateway)); // and token faucet - TokenFaucet faucet = new TokenFaucet{salt: salt}(address(feeToken)); + TokenFaucet faucet = new TokenFaucet{salt: salt}(); feeToken.grantRole(MINTER_ROLE, address(faucet)); AssetMetadata[] memory assets = new AssetMetadata[](1); diff --git a/evm/src/consensus/BeefyV1.sol b/evm/src/consensus/BeefyV1.sol index 7952e9d65..9ad9ffda6 100644 --- a/evm/src/consensus/BeefyV1.sol +++ b/evm/src/consensus/BeefyV1.sol @@ -26,43 +26,89 @@ import "solidity-merkle-trees/trie/Bytes.sol"; import "openzeppelin/utils/cryptography/ECDSA.sol"; struct Vote { + // secp256k1 signature from a member of the authority set bytes signature; + // This member's index in the set uint256 authorityIndex; } +// The signed commitment holds a commitment to the latest +// finalized state as well as votes from a supermajority +// of the authority set which confirms this state struct SignedCommitment { + // A commitment to the finalized state Commitment commitment; + // The confirming votes Vote[] votes; } struct RelayChainProof { - /// Signed commitment + // Signed commitment SignedCommitment signedCommitment; - /// Latest leaf added to mmr + // Latest leaf added to mmr BeefyMmrLeaf latestMmrLeaf; - /// Proof for the latest mmr leaf + // Proof for the latest mmr leaf bytes32[] mmrProof; - /// Proof for authorities in current/next session + // Proof for authorities in current/next session Node[][] proof; } struct BeefyConsensusProof { + // The proof items for the relay chain consensus RelayChainProof relay; + // Proof items for parachain headers ParachainProof parachain; } +/** + * @title The BEEFY Consensus Client. + * @author Polytope Labs (hello@polytope.technology) + * + * @notice This verifies secp256k1 signatures and authority set membership merkle proofs + * in order to confirm newly finalized states of the Hyperbridge blockchain. + */ contract BeefyV1 is IConsensusClient { using HeaderImpl for Header; - /// Slot duration in milliseconds - uint256 public constant SLOT_DURATION = 12000; - /// The PayloadId for the mmr root. + // Slot duration in milliseconds + uint256 public constant SLOT_DURATION = 12_000; + + // The PayloadId for the mmr root. bytes2 public constant MMR_ROOT_PAYLOAD_ID = bytes2("mh"); - /// ChainId for ethereum + + // ChainId for ethereum bytes4 public constant ISMP_CONSENSUS_ID = bytes4("ISMP"); - /// ConsensusID for aura + + // ConsensusID for aura bytes4 public constant AURA_CONSENSUS_ID = bytes4("aura"); + // Provided paraId was unknown + error UnknownParaId(); + + // Provided authority set id was unknown + error UnknownAuthoritySet(); + + // Provided consensus proof height is stale + error StaleHeight(); + + // Provided ultra plonk proof was invalid + error InvalidUltraPlonkProof(); + + // Mmr root hash was not found in header digests + error MmrRootHashMissing(); + + // Provided Mmr Proof was invalid + error InvalidMmrProof(); + + // Genesis block should not be provided + error IllegalGenesisBlock(); + + // Supermajority not reached + error SuperMajorityRequired(); + + // Provided authorities proof was invalid + error InvalidAuthoritiesProof(); + // Authorized paraId. uint256 private _paraId; @@ -70,28 +116,30 @@ contract BeefyV1 is IConsensusClient { _paraId = paraId; } - function verifyConsensus(bytes memory encodedState, bytes memory encodedProof) - external - view - returns (bytes memory, IntermediateState memory) - { + function verifyConsensus( + bytes memory encodedState, + bytes memory encodedProof + ) external view returns (bytes memory, IntermediateState memory) { BeefyConsensusState memory consensusState = abi.decode(encodedState, (BeefyConsensusState)); - (RelayChainProof memory relay, ParachainProof memory parachain) = - abi.decode(encodedProof, (RelayChainProof, ParachainProof)); + (RelayChainProof memory relay, ParachainProof memory parachain) = abi.decode( + encodedProof, + (RelayChainProof, ParachainProof) + ); - (BeefyConsensusState memory newState, IntermediateState memory intermediate) = - this.verifyConsensus(consensusState, BeefyConsensusProof(relay, parachain)); + (BeefyConsensusState memory newState, IntermediateState memory intermediate) = this.verifyConsensus( + consensusState, + BeefyConsensusProof(relay, parachain) + ); return (abi.encode(newState), intermediate); } - /// Verify the consensus proof and return the new trusted consensus state and any intermediate states finalized - /// by this consensus proof. - function verifyConsensus(BeefyConsensusState memory trustedState, BeefyConsensusProof memory proof) - external - view - returns (BeefyConsensusState memory, IntermediateState memory) - { + // @dev Verify the consensus proof and return the new trusted consensus state and any intermediate states finalized + // by this consensus proof. + function verifyConsensus( + BeefyConsensusState memory trustedState, + BeefyConsensusProof memory proof + ) external view returns (BeefyConsensusState memory, IntermediateState memory) { // verify mmr root proofs (BeefyConsensusState memory state, bytes32 headsRoot) = verifyMmrUpdateProof(trustedState, proof.relay); @@ -101,32 +149,35 @@ contract BeefyV1 is IConsensusClient { return (state, intermediate); } - /// Verifies a new Mmmr root update, the relay chain accumulates its blocks into a merkle mountain range tree - /// which light clients can use as a source for log_2(n) ancestry proofs. This new mmr root hash is signed by - /// the relay chain authority set and we can verify the membership of the authorities who signed this new root - /// using a merkle multi proof and a merkle commitment to the total authorities. - function verifyMmrUpdateProof(BeefyConsensusState memory trustedState, RelayChainProof memory relayProof) - private - pure - returns (BeefyConsensusState memory, bytes32) - { + /** @dev Verifies a new Mmmr root update, the relay chain accumulates its blocks into a merkle mountain range tree + * which light clients can use as a source for log_2(n) ancestry proofs. This new mmr root hash is signed by + * the relay chain authority set and we can verify the membership of the authorities who signed this new root + * using a merkle multi proof and a merkle commitment to the total authorities. + */ + function verifyMmrUpdateProof( + BeefyConsensusState memory trustedState, + RelayChainProof memory relayProof + ) internal pure returns (BeefyConsensusState memory, bytes32) { uint256 signatures_length = relayProof.signedCommitment.votes.length; uint256 latestHeight = relayProof.signedCommitment.commitment.blockNumber; - require(latestHeight > trustedState.latestHeight, "consensus clients only accept proofs for new headers"); - require( - checkParticipationThreshold(signatures_length, trustedState.currentAuthoritySet.len) - || checkParticipationThreshold(signatures_length, trustedState.nextAuthoritySet.len), - "Super majority threshold not reached" - ); + if (trustedState.latestHeight >= latestHeight) revert StaleHeight(); + + if ( + !checkParticipationThreshold(signatures_length, trustedState.currentAuthoritySet.len) && + !checkParticipationThreshold(signatures_length, trustedState.nextAuthoritySet.len) + ) { + revert SuperMajorityRequired(); + } Commitment memory commitment = relayProof.signedCommitment.commitment; - require( - commitment.validatorSetId == trustedState.currentAuthoritySet.id - || commitment.validatorSetId == trustedState.nextAuthoritySet.id, - "Unknown authority set" - ); + if ( + commitment.validatorSetId != trustedState.currentAuthoritySet.id && + commitment.validatorSetId != trustedState.nextAuthoritySet.id + ) { + revert UnknownAuthoritySet(); + } bool is_current_authorities = commitment.validatorSetId == trustedState.currentAuthoritySet.id; @@ -139,7 +190,7 @@ contract BeefyV1 is IConsensusClient { } } - require(mmrRoot != bytes32(0), "Mmr root hash not found"); + if (mmrRoot == bytes32(0)) revert MmrRootHashMissing(); bytes32 commitment_hash = keccak256(Codec.Encode(commitment)); Node[] memory authorities = new Node[](signatures_length); @@ -151,18 +202,14 @@ contract BeefyV1 is IConsensusClient { authorities[i] = Node(vote.authorityIndex, keccak256(abi.encodePacked(authority))); } + bool valid; // check authorities proof if (is_current_authorities) { - require( - MerkleMultiProof.VerifyProof(trustedState.currentAuthoritySet.root, relayProof.proof, authorities), - "Invalid current authorities proof" - ); + valid = MerkleMultiProof.VerifyProof(trustedState.currentAuthoritySet.root, relayProof.proof, authorities); } else { - require( - MerkleMultiProof.VerifyProof(trustedState.nextAuthoritySet.root, relayProof.proof, authorities), - "Invalid next authorities proof" - ); + valid = MerkleMultiProof.VerifyProof(trustedState.nextAuthoritySet.root, relayProof.proof, authorities); } + if (!valid) revert InvalidAuthoritiesProof(); verifyMmrLeaf(trustedState, relayProof, mmrRoot); @@ -176,52 +223,57 @@ contract BeefyV1 is IConsensusClient { return (trustedState, relayProof.latestMmrLeaf.extra); } - /// Stack too deep, sigh solidity - function verifyMmrLeaf(BeefyConsensusState memory trustedState, RelayChainProof memory relay, bytes32 mmrRoot) - private - pure - { + // @dev Stack too deep, sigh solidity + function verifyMmrLeaf( + BeefyConsensusState memory trustedState, + RelayChainProof memory relay, + bytes32 mmrRoot + ) internal pure { bytes32 hash = keccak256(Codec.Encode(relay.latestMmrLeaf)); uint256 leafCount = leafIndex(trustedState.beefyActivationBlock, relay.latestMmrLeaf.parentNumber) + 1; MmrLeaf[] memory leaves = new MmrLeaf[](1); leaves[0] = MmrLeaf(relay.latestMmrLeaf.kIndex, relay.latestMmrLeaf.leafIndex, hash); - require(MerkleMountainRange.VerifyProof(mmrRoot, relay.mmrProof, leaves, leafCount), "Invalid Mmr Proof"); + bool valid = MerkleMountainRange.VerifyProof(mmrRoot, relay.mmrProof, leaves, leafCount); + + if (!valid) revert InvalidMmrProof(); } - /// Verifies that some parachain header has been finalized, given the current trusted consensus state. - function verifyParachainHeaderProof(bytes32 headsRoot, ParachainProof memory proof) - private - view - returns (IntermediateState memory) - { + // @dev Verifies that some parachain header has been finalized, given the current trusted consensus state. + function verifyParachainHeaderProof( + bytes32 headsRoot, + ParachainProof memory proof + ) internal view returns (IntermediateState memory) { Node[] memory leaves = new Node[](1); Parachain memory para = proof.parachain; - if (para.id != _paraId) { - revert("Unknown paraId"); - } + + if (para.id != _paraId) revert UnknownParaId(); Header memory header = Codec.DecodeHeader(para.header); - require(header.number != 0, "Genesis block should not be included"); + if (header.number == 0) revert IllegalGenesisBlock(); // verify header leaves[0] = Node( para.index, keccak256(bytes.concat(ScaleCodec.encode32(uint32(para.id)), ScaleCodec.encodeBytes(para.header))) ); - require(MerkleMultiProof.VerifyProof(headsRoot, proof.proof, leaves), "Invalid parachains heads proof"); + bool valid = MerkleMultiProof.VerifyProof(headsRoot, proof.proof, leaves); + if (!valid) revert InvalidMmrProof(); // extract the state commitment StateCommitment memory commitment = header.stateCommitment(); - IntermediateState memory intermediate = - IntermediateState({stateMachineId: para.id, height: header.number, commitment: commitment}); + IntermediateState memory intermediate = IntermediateState({ + stateMachineId: para.id, + height: header.number, + commitment: commitment + }); return intermediate; } - /// Calculates the mmr leaf index for a block whose parent number is given. - function leafIndex(uint256 activationBlock, uint256 parentNumber) private pure returns (uint256) { + // @dev Calculates the mmr leaf index for a block whose parent number is given. + function leafIndex(uint256 activationBlock, uint256 parentNumber) internal pure returns (uint256) { if (activationBlock == 0) { return parentNumber; } else { @@ -229,8 +281,8 @@ contract BeefyV1 is IConsensusClient { } } - /// Check for supermajority participation. - function checkParticipationThreshold(uint256 len, uint256 total) private pure returns (bool) { + // @dev Check for supermajority participation. + function checkParticipationThreshold(uint256 len, uint256 total) internal pure returns (bool) { return len >= ((2 * total) / 3) + 1; } } diff --git a/evm/src/consensus/Codec.sol b/evm/src/consensus/Codec.sol index 2cf61ad2b..cb7db9f4f 100644 --- a/evm/src/consensus/Codec.sol +++ b/evm/src/consensus/Codec.sol @@ -82,7 +82,7 @@ struct ParachainProof { Node[][] proof; } -/// type encoding stuff +// @dev type encoding stuff library Codec { uint8 internal constant DIGEST_ITEM_OTHER = 0; uint8 internal constant DIGEST_ITEM_CONSENSUS = 4; @@ -90,35 +90,45 @@ library Codec { uint8 internal constant DIGEST_ITEM_PRERUNTIME = 6; uint8 internal constant DIGEST_ITEM_RUNTIME_ENVIRONMENT_UPDATED = 8; + // @dev SCALE-encodes the BEEFY finality commitment function Encode(Commitment memory commitment) internal pure returns (bytes memory) { uint256 payloadLen = commitment.payload.length; bytes memory accumulator = bytes(""); for (uint256 i = 0; i < payloadLen; i++) { accumulator = bytes.concat( - abi.encodePacked(commitment.payload[i].id), ScaleCodec.encodeBytes(commitment.payload[i].data) + abi.encodePacked(commitment.payload[i].id), + ScaleCodec.encodeBytes(commitment.payload[i].data) ); } bytes memory payload = bytes.concat(ScaleCodec.encodeUintCompact(payloadLen), accumulator); bytes memory rest = bytes.concat( - ScaleCodec.encode32(uint32(commitment.blockNumber)), ScaleCodec.encode64(uint64(commitment.validatorSetId)) + ScaleCodec.encode32(uint32(commitment.blockNumber)), + ScaleCodec.encode64(uint64(commitment.validatorSetId)) ); return bytes.concat(payload, rest); } + // @dev SCALE-encodes the BEEFY Mmr leaf function Encode(BeefyMmrLeaf memory leaf) internal pure returns (bytes memory) { - bytes memory first = - bytes.concat(abi.encodePacked(uint8(leaf.version)), ScaleCodec.encode32(uint32(leaf.parentNumber))); - bytes memory second = - bytes.concat(bytes.concat(leaf.parentHash), ScaleCodec.encode64(uint64(leaf.nextAuthoritySet.id))); + bytes memory first = bytes.concat( + abi.encodePacked(uint8(leaf.version)), + ScaleCodec.encode32(uint32(leaf.parentNumber)) + ); + bytes memory second = bytes.concat( + bytes.concat(leaf.parentHash), + ScaleCodec.encode64(uint64(leaf.nextAuthoritySet.id)) + ); bytes memory third = bytes.concat( - ScaleCodec.encode32(uint32(leaf.nextAuthoritySet.len)), bytes.concat(leaf.nextAuthoritySet.root) + ScaleCodec.encode32(uint32(leaf.nextAuthoritySet.len)), + bytes.concat(leaf.nextAuthoritySet.root) ); return bytes.concat(bytes.concat(first, second), bytes.concat(third, bytes.concat(leaf.extra))); } + // @dev Deserializes a substrate header function DecodeHeader(bytes memory encoded) internal pure returns (Header memory) { ByteSlice memory slice = ByteSlice(encoded, 0); bytes32 parentHash = Bytes.toBytes32(Bytes.read(slice, 32)); @@ -179,7 +189,7 @@ library Codec { return b; } - // Decodes a SCALE encoded compact unsigned integer + // @dev Decodes a SCALE encoded compact unsigned integer function decodeUintCompact(ByteSlice memory data) internal pure returns (uint256 v) { uint8 b = readByte(data); // read the first byte uint8 mode = b & 3; // bitwise operation @@ -218,7 +228,7 @@ library Codec { return (value); } - // Convert the provided type to a bn254 field element + // @dev Convert the provided type to a bn254 field element function toFieldElements(bytes32 source) internal pure returns (bytes32, bytes32) { // is assembly cheaper? bytes32 left = bytes32(uint256(uint128(bytes16(source)))); diff --git a/evm/src/consensus/ZkBeefy.sol b/evm/src/consensus/UltraPlonkBeefy.sol similarity index 50% rename from evm/src/consensus/ZkBeefy.sol rename to evm/src/consensus/UltraPlonkBeefy.sol index a0f1640d8..9f6246f59 100644 --- a/evm/src/consensus/ZkBeefy.sol +++ b/evm/src/consensus/UltraPlonkBeefy.sol @@ -20,38 +20,48 @@ import "ismp/IConsensusClient.sol"; import "solidity-merkle-trees/MerkleMultiProof.sol"; import "solidity-merkle-trees/MerkleMountainRange.sol"; -import "solidity-merkle-trees/MerklePatricia.sol"; import "solidity-merkle-trees/trie/substrate/ScaleCodec.sol"; import "solidity-merkle-trees/trie/Bytes.sol"; -import "openzeppelin/utils/cryptography/ECDSA.sol"; import {IVerifier} from "./verifiers/IVerifier.sol"; -struct PlonkConsensusProof { - /// Commitment message +struct UltraPlonkConsensusProof { + // Commitment message Commitment commitment; - /// Latest leaf added to mmr + // Latest leaf added to mmr BeefyMmrLeaf latestMmrLeaf; - /// Proof for the latest mmr leaf + // Proof for the latest mmr leaf bytes32[] mmrProof; - /// Plonk proof for BEEFY consensus + // UltraPlonk proof for BEEFY consensus bytes proof; } struct BeefyConsensusProof { - PlonkConsensusProof relay; + // The proof items for the relay chain consensus + UltraPlonkConsensusProof relay; + // Proof items for parachain headers ParachainProof parachain; } -contract ZkBeefyV1 is IConsensusClient { +/** + * @title The UltraPlonk BEEFY Consensus Client. + * @author Polytope Labs (hello@polytope.technology) + * + * @notice Similar to the BeefyV1 client but delegates secp256k1 signature verification + * and authority set membership proof checks to an ultraplonk circuit. + */ +contract UltraPlonkBeefy is IConsensusClient { using HeaderImpl for Header; - /// Slot duration in milliseconds - uint256 public constant SLOT_DURATION = 12000; - /// The PayloadId for the mmr root. + // Slot duration in milliseconds + uint256 public constant SLOT_DURATION = 12_000; + + // The PayloadId for the mmr root. bytes2 public constant MMR_ROOT_PAYLOAD_ID = bytes2("mh"); - /// Digest Item ID + + // Digest Item ID bytes4 public constant ISMP_CONSENSUS_ID = bytes4("ISMP"); - /// ConsensusID for aura + + // ConsensusID for aura bytes4 public constant AURA_CONSENSUS_ID = bytes4("aura"); // Plonk verifier contract @@ -60,35 +70,56 @@ contract ZkBeefyV1 is IConsensusClient { // Authorized paraId. uint256 private _paraId; + // Provided paraId was unknown error UnknownParaId(); + // Provided authority set id was unknown + error UnknownAuthoritySet(); + + // Provided consensus proof height is stale + error StaleHeight(); + + // Provided ultra plonk proof was invalid + error InvalidUltraPlonkProof(); + + // Mmr root hash was not found in header digests + error MmrRootHashMissing(); + + // Provided Mmr Proof was invalid + error InvalidMmrProof(); + + // Genesis block should not be provided + error IllegalGenesisBlock(); + constructor(uint256 paraId, IVerifier verifier) { _paraId = paraId; _verifier = verifier; } - function verifyConsensus(bytes memory encodedState, bytes memory encodedProof) - external - view - returns (bytes memory, IntermediateState memory) - { + function verifyConsensus( + bytes memory encodedState, + bytes memory encodedProof + ) external view returns (bytes memory, IntermediateState memory) { BeefyConsensusState memory consensusState = abi.decode(encodedState, (BeefyConsensusState)); - (PlonkConsensusProof memory relay, ParachainProof memory parachain) = - abi.decode(encodedProof, (PlonkConsensusProof, ParachainProof)); + (UltraPlonkConsensusProof memory relay, ParachainProof memory parachain) = abi.decode( + encodedProof, + (UltraPlonkConsensusProof, ParachainProof) + ); - (BeefyConsensusState memory newState, IntermediateState memory intermediate) = - verifyConsensus(consensusState, BeefyConsensusProof(relay, parachain)); + (BeefyConsensusState memory newState, IntermediateState memory intermediate) = verifyConsensus( + consensusState, + BeefyConsensusProof(relay, parachain) + ); return (abi.encode(newState), intermediate); } - /// Verify the consensus proof and return the new trusted consensus state and any intermediate states finalized - /// by this consensus proof. - function verifyConsensus(BeefyConsensusState memory trustedState, BeefyConsensusProof memory proof) - internal - view - returns (BeefyConsensusState memory, IntermediateState memory) - { + // @dev Verify the consensus proof and return the new trusted consensus state and any intermediate states finalized + // by this consensus proof. + function verifyConsensus( + BeefyConsensusState memory trustedState, + BeefyConsensusProof memory proof + ) internal view returns (BeefyConsensusState memory, IntermediateState memory) { // verify mmr root proofs (BeefyConsensusState memory state, bytes32 headsRoot) = verifyMmrUpdateProof(trustedState, proof.relay); @@ -98,24 +129,27 @@ contract ZkBeefyV1 is IConsensusClient { return (state, intermediate); } - /// Verifies a new Mmmr root update, the relay chain accumulates its blocks into a merkle mountain range tree - /// which light clients can use as a source for log_2(n) ancestry proofs. This new mmr root hash is signed by - /// the relay chain authority set and we can verify the membership of the authorities who signed this new root - /// using a merkle multi proof and a merkle commitment to the total authorities. - function verifyMmrUpdateProof(BeefyConsensusState memory trustedState, PlonkConsensusProof memory relayProof) - internal - view - returns (BeefyConsensusState memory, bytes32) - { + /** @dev Verifies a new Mmmr root update, the relay chain accumulates its blocks into a merkle mountain range tree + * which light clients can use as a source for log_2(n) ancestry proofs. This new mmr root hash is signed by + * the relay chain authority set and we can verify the membership of the authorities who signed this new root + * using a merkle multi proof and a merkle commitment to the total authorities. + */ + function verifyMmrUpdateProof( + BeefyConsensusState memory trustedState, + UltraPlonkConsensusProof memory relayProof + ) internal view returns (BeefyConsensusState memory, bytes32) { uint256 latestHeight = relayProof.commitment.blockNumber; - require(latestHeight > trustedState.latestHeight, "consensus clients only accept proofs for new headers"); + + if (trustedState.latestHeight >= latestHeight) revert StaleHeight(); Commitment memory commitment = relayProof.commitment; - require( - commitment.validatorSetId == trustedState.currentAuthoritySet.id - || commitment.validatorSetId == trustedState.nextAuthoritySet.id, - "Unknown authority set" - ); + + if ( + commitment.validatorSetId != trustedState.currentAuthoritySet.id && + commitment.validatorSetId != trustedState.nextAuthoritySet.id + ) { + revert UnknownAuthoritySet(); + } bool is_current_authorities = commitment.validatorSetId == trustedState.currentAuthoritySet.id; uint256 payload_len = commitment.payload.length; @@ -126,27 +160,20 @@ contract ZkBeefyV1 is IConsensusClient { mmrRoot = Bytes.toBytes32(commitment.payload[i].data); } } - require(mmrRoot != bytes32(0), "Mmr root hash not found"); + if (mmrRoot == bytes32(0)) revert MmrRootHashMissing(); bytes32 commitment_hash = keccak256(Codec.Encode(commitment)); bytes32[] memory inputs = new bytes32[](4); - (bytes32 limb0, bytes32 limb1) = Codec.toFieldElements(commitment_hash); - inputs[0] = limb0; - inputs[1] = limb1; - + (inputs[0], inputs[1]) = Codec.toFieldElements(commitment_hash); if (is_current_authorities) { - (bytes32 limb2, bytes32 limb3) = Codec.toFieldElements(trustedState.currentAuthoritySet.root); - inputs[2] = limb2; - inputs[3] = limb3; + (inputs[2], inputs[3]) = Codec.toFieldElements(trustedState.currentAuthoritySet.root); } else { - (bytes32 limb2, bytes32 limb3) = Codec.toFieldElements(trustedState.nextAuthoritySet.root); - inputs[2] = limb2; - inputs[3] = limb3; + (inputs[2], inputs[3]) = Codec.toFieldElements(trustedState.nextAuthoritySet.root); } - // check BEEFY proof - require(_verifier.verify(relayProof.proof, inputs), "ZkBEEFY: Invalid plonk proof"); + // check ultraplonk proof + if (!_verifier.verify(relayProof.proof, inputs)) revert InvalidUltraPlonkProof(); verifyMmrLeaf(trustedState, relayProof, mmrRoot); @@ -160,46 +187,50 @@ contract ZkBeefyV1 is IConsensusClient { return (trustedState, relayProof.latestMmrLeaf.extra); } - /// Stack too deep, sigh solidity - function verifyMmrLeaf(BeefyConsensusState memory trustedState, PlonkConsensusProof memory relay, bytes32 mmrRoot) - internal - pure - { + // @dev Stack too deep, sigh solidity + function verifyMmrLeaf( + BeefyConsensusState memory trustedState, + UltraPlonkConsensusProof memory relay, + bytes32 mmrRoot + ) internal pure { bytes32 hash = keccak256(Codec.Encode(relay.latestMmrLeaf)); uint256 leafCount = leafIndex(trustedState.beefyActivationBlock, relay.latestMmrLeaf.parentNumber) + 1; MmrLeaf[] memory leaves = new MmrLeaf[](1); leaves[0] = MmrLeaf(relay.latestMmrLeaf.kIndex, relay.latestMmrLeaf.leafIndex, hash); + bool valid = MerkleMountainRange.VerifyProof(mmrRoot, relay.mmrProof, leaves, leafCount); - require(MerkleMountainRange.VerifyProof(mmrRoot, relay.mmrProof, leaves, leafCount), "Invalid Mmr Proof"); + if (!valid) revert InvalidMmrProof(); } - /// Verifies that some parachain header has been finalized, given the current trusted consensus state. - function verifyParachainHeaderProof(bytes32 headsRoot, ParachainProof memory proof) - internal - view - returns (IntermediateState memory) - { + // @dev Verifies that some parachain header has been finalized, given the current trusted consensus state. + function verifyParachainHeaderProof( + bytes32 headsRoot, + ParachainProof memory proof + ) internal view returns (IntermediateState memory) { Node[] memory leaves = new Node[](1); Parachain memory para = proof.parachain; - if (para.id != _paraId) { - revert UnknownParaId(); - } + if (para.id != _paraId) revert UnknownParaId(); Header memory header = Codec.DecodeHeader(para.header); - require(header.number != 0, "Genesis block should not be included"); + + if (header.number == 0) revert IllegalGenesisBlock(); + leaves[0] = Node( para.index, keccak256(bytes.concat(ScaleCodec.encode32(uint32(para.id)), ScaleCodec.encodeBytes(para.header))) ); - require(MerkleMultiProof.VerifyProof(headsRoot, proof.proof, leaves), "Invalid parachains heads proof"); + + bool valid = MerkleMultiProof.VerifyProof(headsRoot, proof.proof, leaves); + if (!valid) revert InvalidMmrProof(); + StateCommitment memory commitment = header.stateCommitment(); return IntermediateState({stateMachineId: para.id, height: header.number, commitment: commitment}); } - /// Calculates the mmr leaf index for a block whose parent number is given. - function leafIndex(uint256 activationBlock, uint256 parentNumber) private pure returns (uint256) { + // @dev Calculates the mmr leaf index for a block whose parent number is given. + function leafIndex(uint256 activationBlock, uint256 parentNumber) internal pure returns (uint256) { if (activationBlock == 0) { return parentNumber; } else { diff --git a/evm/src/consensus/verifiers/KusamaVerifier.sol b/evm/src/consensus/verifiers/KusamaVerifier.sol index 7b8ef72c3..e34d88f6c 100644 --- a/evm/src/consensus/verifiers/KusamaVerifier.sol +++ b/evm/src/consensus/verifiers/KusamaVerifier.sol @@ -642,7 +642,11 @@ abstract contract BaseUltraVerifier is IVerifier { let root_2 := mulmod(beta, 0x0c, p_clone) // @note 0x05 + 0x07 == 0x0c == external coset generator - for {} lt(public_inputs_ptr, endpoint_ptr) { public_inputs_ptr := add(public_inputs_ptr, 0x20) } { + for { + + } lt(public_inputs_ptr, endpoint_ptr) { + public_inputs_ptr := add(public_inputs_ptr, 0x20) + } { /** * input = public_input[i] * valid_inputs &= input < p @@ -683,7 +687,11 @@ abstract contract BaseUltraVerifier is IVerifier { { let exponent := mload(N_LOC) let count := 1 - for {} lt(count, exponent) { count := add(count, count) } { + for { + + } lt(count, exponent) { + count := add(count, count) + } { delta_numerator := mulmod(delta_numerator, delta_numerator, p) } } @@ -725,7 +733,11 @@ abstract contract BaseUltraVerifier is IVerifier { // pow_small let exponent := mload(N_LOC) let count := 1 - for {} lt(count, exponent) { count := add(count, count) } { + for { + + } lt(count, exponent) { + count := add(count, count) + } { vanishing_numerator := mulmod(vanishing_numerator, vanishing_numerator, p) } } @@ -741,8 +753,11 @@ abstract contract BaseUltraVerifier is IVerifier { vanishing_denominator := mulmod(vanishing_denominator, addmod(zeta, work_root, p), p) work_root := mulmod(work_root, accumulating_root, p) vanishing_denominator := mulmod(vanishing_denominator, addmod(zeta, work_root, p), p) - vanishing_denominator := - mulmod(vanishing_denominator, addmod(zeta, mulmod(work_root, accumulating_root, p), p), p) + vanishing_denominator := mulmod( + vanishing_denominator, + addmod(zeta, mulmod(work_root, accumulating_root, p), p), + p + ) work_root := mload(OMEGA_LOC) @@ -751,10 +766,11 @@ abstract contract BaseUltraVerifier is IVerifier { accumulating_root := mulmod(work_root, work_root, p) - let l_end_denominator := - addmod( - mulmod(mulmod(mulmod(accumulating_root, accumulating_root, p), work_root, p), zeta, p), sub(p, 1), p - ) + let l_end_denominator := addmod( + mulmod(mulmod(mulmod(accumulating_root, accumulating_root, p), work_root, p), zeta, p), + sub(p, 1), + p + ) /** * Compute inversions using Montgomery's batch inversion trick @@ -836,37 +852,32 @@ abstract contract BaseUltraVerifier is IVerifier { * t2 = (W2 + gamma + beta * sigma_3_eval) * (W3 + gamma + beta * sigma_4_eval) * result -= (alpha_base * z_omega_eval * t1 * t2) */ - let t1 := - mulmod( - add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(ID1_EVAL_LOC), p)), - add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(ID2_EVAL_LOC), p)), - p - ) - let t2 := - mulmod( - add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(ID3_EVAL_LOC), p)), - add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(ID4_EVAL_LOC), p)), - p - ) + let t1 := mulmod( + add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(ID1_EVAL_LOC), p)), + add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(ID2_EVAL_LOC), p)), + p + ) + let t2 := mulmod( + add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(ID3_EVAL_LOC), p)), + add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(ID4_EVAL_LOC), p)), + p + ) let result := mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_EVAL_LOC), mulmod(t1, t2, p), p), p) - t1 := - mulmod( - add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA1_EVAL_LOC), p)), - add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA2_EVAL_LOC), p)), - p - ) - t2 := - mulmod( - add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA3_EVAL_LOC), p)), - add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA4_EVAL_LOC), p)), - p - ) - result := - addmod( - result, - sub(p, mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_OMEGA_EVAL_LOC), mulmod(t1, t2, p), p), p)), - p - ) + t1 := mulmod( + add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA1_EVAL_LOC), p)), + add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA2_EVAL_LOC), p)), + p + ) + t2 := mulmod( + add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA3_EVAL_LOC), p)), + add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA4_EVAL_LOC), p)), + p + ) + result := addmod( + result, + sub(p, mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_OMEGA_EVAL_LOC), mulmod(t1, t2, p), p), p)), + p + ) /** * alpha_base *= alpha @@ -876,20 +887,19 @@ abstract contract BaseUltraVerifier is IVerifier { * alpha_Base *= alpha */ mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p)) - result := - addmod( - result, + result := addmod( + result, + mulmod( + mload(C_ALPHA_BASE_LOC), mulmod( - mload(C_ALPHA_BASE_LOC), - mulmod( - mload(L_END_LOC), - addmod(mload(Z_OMEGA_EVAL_LOC), sub(p, mload(PUBLIC_INPUT_DELTA_LOC)), p), - p - ), + mload(L_END_LOC), + addmod(mload(Z_OMEGA_EVAL_LOC), sub(p, mload(PUBLIC_INPUT_DELTA_LOC)), p), p ), p - ) + ), + p + ) mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p)) mstore( PERMUTATION_IDENTITY, @@ -920,46 +930,53 @@ abstract contract BaseUltraVerifier is IVerifier { * f += (w1(z) + q2.w1(zω)) */ let f := mulmod(mload(C_ETA_LOC), mload(Q3_EVAL_LOC), p) - f := - addmod(f, addmod(mload(W3_EVAL_LOC), mulmod(mload(QC_EVAL_LOC), mload(W3_OMEGA_EVAL_LOC), p), p), p) + f := addmod( + f, + addmod(mload(W3_EVAL_LOC), mulmod(mload(QC_EVAL_LOC), mload(W3_OMEGA_EVAL_LOC), p), p), + p + ) f := mulmod(f, mload(C_ETA_LOC), p) - f := - addmod(f, addmod(mload(W2_EVAL_LOC), mulmod(mload(QM_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p), p) + f := addmod( + f, + addmod(mload(W2_EVAL_LOC), mulmod(mload(QM_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p), + p + ) f := mulmod(f, mload(C_ETA_LOC), p) - f := - addmod(f, addmod(mload(W1_EVAL_LOC), mulmod(mload(Q2_EVAL_LOC), mload(W1_OMEGA_EVAL_LOC), p), p), p) + f := addmod( + f, + addmod(mload(W1_EVAL_LOC), mulmod(mload(Q2_EVAL_LOC), mload(W1_OMEGA_EVAL_LOC), p), p), + p + ) // t(z) = table4(z).η³ + table3(z).η² + table2(z).η + table1(z) - let t := + let t := addmod( addmod( addmod( - addmod( - mulmod(mload(TABLE4_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), - mulmod(mload(TABLE3_EVAL_LOC), mload(C_ETA_SQR_LOC), p), - p - ), - mulmod(mload(TABLE2_EVAL_LOC), mload(C_ETA_LOC), p), + mulmod(mload(TABLE4_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), + mulmod(mload(TABLE3_EVAL_LOC), mload(C_ETA_SQR_LOC), p), p ), - mload(TABLE1_EVAL_LOC), + mulmod(mload(TABLE2_EVAL_LOC), mload(C_ETA_LOC), p), p - ) + ), + mload(TABLE1_EVAL_LOC), + p + ) // t(zw) = table4(zw).η³ + table3(zw).η² + table2(zw).η + table1(zw) - let t_omega := + let t_omega := addmod( addmod( addmod( - addmod( - mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), - mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_ETA_SQR_LOC), p), - p - ), - mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_ETA_LOC), p), + mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), + mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_ETA_SQR_LOC), p), p ), - mload(TABLE1_OMEGA_EVAL_LOC), + mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_ETA_LOC), p), p - ) + ), + mload(TABLE1_OMEGA_EVAL_LOC), + p + ) /** * Goal: numerator = (TABLE_TYPE_EVAL * f(z) + γ) * (t(z) + βt(zω) + γ(β + 1)) * (β + 1) @@ -994,12 +1011,11 @@ abstract contract BaseUltraVerifier is IVerifier { * PLOOKUP_IDENTITY = (numerator - denominator).alpha_base * alpha_base *= alpha^3 */ - let denominator := - addmod( - addmod(mload(S_EVAL_LOC), mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_BETA_LOC), p), p), - gamma_beta_constant, - p - ) + let denominator := addmod( + addmod(mload(S_EVAL_LOC), mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_BETA_LOC), p), p), + gamma_beta_constant, + p + ) let temp1 := mulmod(mload(C_ALPHA_SQR_LOC), mload(L_END_LOC), p) denominator := addmod(denominator, sub(p, temp1), p) denominator := mulmod(denominator, mload(Z_LOOKUP_OMEGA_EVAL_LOC), p) @@ -1057,43 +1073,44 @@ abstract contract BaseUltraVerifier is IVerifier { // @todo - Add a explicit test that hits QARITH == 3 // w1w2qm := (w_1 . w_2 . q_m . (QARITH_EVAL_LOC - 3)) / 2 - let w1w2qm := + let w1w2qm := mulmod( mulmod( - mulmod( - mulmod(mulmod(mload(W1_EVAL_LOC), mload(W2_EVAL_LOC), p), mload(QM_EVAL_LOC), p), - addmod(mload(QARITH_EVAL_LOC), sub(p, 3), p), - p - ), - NEGATIVE_INVERSE_OF_2_MODULO_P, + mulmod(mulmod(mload(W1_EVAL_LOC), mload(W2_EVAL_LOC), p), mload(QM_EVAL_LOC), p), + addmod(mload(QARITH_EVAL_LOC), sub(p, 3), p), p - ) + ), + NEGATIVE_INVERSE_OF_2_MODULO_P, + p + ) // (w_1 . w_2 . q_m . (q_arith - 3)) / -2) + (w_1 . q_1) + (w_2 . q_2) + (w_3 . q_3) + (w_4 . q_4) + q_c - let identity := - addmod( - mload(QC_EVAL_LOC), addmod(w4q3, addmod(w3q3, addmod(w2q2, addmod(w1q1, w1w2qm, p), p), p), p), p - ) + let identity := addmod( + mload(QC_EVAL_LOC), + addmod(w4q3, addmod(w3q3, addmod(w2q2, addmod(w1q1, w1w2qm, p), p), p), p), + p + ) // if q_arith == 3 we evaluate an additional mini addition gate (on top of the regular one), where: // w_1 + w_4 - w_1_omega + q_m = 0 // we use this gate to save an addition gate when adding or subtracting non-native field elements // α * (q_arith - 2) * (w_1 + w_4 - w_1_omega + q_m) - let extra_small_addition_gate_identity := + let extra_small_addition_gate_identity := mulmod( + mload(C_ALPHA_LOC), mulmod( - mload(C_ALPHA_LOC), - mulmod( - addmod(mload(QARITH_EVAL_LOC), sub(p, 2), p), + addmod(mload(QARITH_EVAL_LOC), sub(p, 2), p), + addmod( + mload(QM_EVAL_LOC), addmod( - mload(QM_EVAL_LOC), - addmod( - sub(p, mload(W1_OMEGA_EVAL_LOC)), addmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), p - ), + sub(p, mload(W1_OMEGA_EVAL_LOC)), + addmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), p ), p ), p - ) + ), + p + ) // if q_arith == 2 OR q_arith == 3 we add the 4th wire of the NEXT gate into the arithmetic identity // N.B. if q_arith > 2, this wire value will be scaled by (q_arith - 1) relative to the other gate wires! @@ -1152,58 +1169,54 @@ abstract contract BaseUltraVerifier is IVerifier { let d3 := addmod(mload(W4_EVAL_LOC), sub(p, mload(W3_EVAL_LOC)), p) let d4 := addmod(mload(W1_OMEGA_EVAL_LOC), sub(p, mload(W4_EVAL_LOC)), p) - let range_accumulator := + let range_accumulator := mulmod( mulmod( - mulmod( - mulmod(addmod(mulmod(d1, d1, p), sub(p, d1), p), addmod(d1, minus_two, p), p), - addmod(d1, minus_three, p), - p - ), - mload(C_ALPHA_BASE_LOC), + mulmod(addmod(mulmod(d1, d1, p), sub(p, d1), p), addmod(d1, minus_two, p), p), + addmod(d1, minus_three, p), p - ) - range_accumulator := - addmod( - range_accumulator, + ), + mload(C_ALPHA_BASE_LOC), + p + ) + range_accumulator := addmod( + range_accumulator, + mulmod( mulmod( - mulmod( - mulmod(addmod(mulmod(d2, d2, p), sub(p, d2), p), addmod(d2, minus_two, p), p), - addmod(d2, minus_three, p), - p - ), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + mulmod(addmod(mulmod(d2, d2, p), sub(p, d2), p), addmod(d2, minus_two, p), p), + addmod(d2, minus_three, p), p ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), p - ) - range_accumulator := - addmod( - range_accumulator, + ), + p + ) + range_accumulator := addmod( + range_accumulator, + mulmod( mulmod( - mulmod( - mulmod(addmod(mulmod(d3, d3, p), sub(p, d3), p), addmod(d3, minus_two, p), p), - addmod(d3, minus_three, p), - p - ), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p), + mulmod(addmod(mulmod(d3, d3, p), sub(p, d3), p), addmod(d3, minus_two, p), p), + addmod(d3, minus_three, p), p ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p), p - ) - range_accumulator := - addmod( - range_accumulator, + ), + p + ) + range_accumulator := addmod( + range_accumulator, + mulmod( mulmod( - mulmod( - mulmod(addmod(mulmod(d4, d4, p), sub(p, d4), p), addmod(d4, minus_two, p), p), - addmod(d4, minus_three, p), - p - ), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p), + mulmod(addmod(mulmod(d4, d4, p), sub(p, d4), p), addmod(d4, minus_two, p), p), + addmod(d4, minus_three, p), p ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p), p - ) + ), + p + ) range_accumulator := mulmod(range_accumulator, mload(QSORT_EVAL_LOC), p) mstore(SORT_IDENTITY, range_accumulator) @@ -1235,38 +1248,39 @@ abstract contract BaseUltraVerifier is IVerifier { let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p) let y1y2 := mulmod(mulmod(mload(Y1_EVAL_LOC), mload(Y2_EVAL_LOC), p), mload(QSIGN_LOC), p) - let x_add_identity := - addmod( - mulmod( - addmod(mload(X3_EVAL_LOC), addmod(mload(X2_EVAL_LOC), mload(X1_EVAL_LOC), p), p), - mulmod(x_diff, x_diff, p), - p - ), - addmod(sub(p, addmod(y2_sqr, y1_sqr, p)), addmod(y1y2, y1y2, p), p), + let x_add_identity := addmod( + mulmod( + addmod(mload(X3_EVAL_LOC), addmod(mload(X2_EVAL_LOC), mload(X1_EVAL_LOC), p), p), + mulmod(x_diff, x_diff, p), p - ) - x_add_identity := - mulmod(mulmod(x_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), mload(C_ALPHA_BASE_LOC), p) + ), + addmod(sub(p, addmod(y2_sqr, y1_sqr, p)), addmod(y1y2, y1y2, p), p), + p + ) + x_add_identity := mulmod( + mulmod(x_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), + mload(C_ALPHA_BASE_LOC), + p + ) // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0 let y1_plus_y3 := addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p) let y_diff := addmod(mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p), sub(p, mload(Y1_EVAL_LOC)), p) - let y_add_identity := - addmod( - mulmod(y1_plus_y3, x_diff, p), - mulmod(addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), y_diff, p), - p - ) - y_add_identity := - mulmod( - mulmod(y_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), - p - ) + let y_add_identity := addmod( + mulmod(y1_plus_y3, x_diff, p), + mulmod(addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), y_diff, p), + p + ) + y_add_identity := mulmod( + mulmod(y_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + p + ) // ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL mstore( - ELLIPTIC_IDENTITY, mulmod(addmod(x_add_identity, y_add_identity, p), mload(QELLIPTIC_EVAL_LOC), p) + ELLIPTIC_IDENTITY, + mulmod(addmod(x_add_identity, y_add_identity, p), mload(QELLIPTIC_EVAL_LOC), p) ) } { @@ -1290,33 +1304,34 @@ abstract contract BaseUltraVerifier is IVerifier { let y1_sqr_mul_4 := mulmod(y1_sqr, 4, p) let x1_pow_4_mul_9 := mulmod(x_pow_4, 9, p) let x1_sqr_mul_3 := mulmod(x1_sqr, 3, p) - let x_double_identity := - addmod( - mulmod( - addmod(mload(X3_EVAL_LOC), addmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), p), - y1_sqr_mul_4, - p - ), - sub(p, x1_pow_4_mul_9), + let x_double_identity := addmod( + mulmod( + addmod(mload(X3_EVAL_LOC), addmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), p), + y1_sqr_mul_4, p - ) + ), + sub(p, x1_pow_4_mul_9), + p + ) // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0 - let y_double_identity := - addmod( - mulmod(x1_sqr_mul_3, addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p), - sub( - p, - mulmod( - addmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p), - addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p), - p - ) - ), - p - ) + let y_double_identity := addmod( + mulmod(x1_sqr_mul_3, addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p), + sub( + p, + mulmod( + addmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p), + addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p), + p + ) + ), + p + ) x_double_identity := mulmod(x_double_identity, mload(C_ALPHA_BASE_LOC), p) - y_double_identity := - mulmod(y_double_identity, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), p) + y_double_identity := mulmod( + y_double_identity, + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + p + ) x_double_identity := mulmod(x_double_identity, mload(QM_EVAL_LOC), p) y_double_identity := mulmod(y_double_identity, mload(QM_EVAL_LOC), p) // ELLIPTIC_IDENTITY += (x_double_identity + y_double_identity) * Q_DOUBLE_EVAL @@ -1357,52 +1372,50 @@ abstract contract BaseUltraVerifier is IVerifier { * non_native_field_gate_3 = (limb_subproduct + w_4 - (w_3_omega + w_4_omega)) * q_m * non_native_field_identity = (non_native_field_gate_1 + non_native_field_gate_2 + non_native_field_gate_3) * q_2 */ - let limb_subproduct := - addmod( - mulmod(mload(W1_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), - mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_EVAL_LOC), p), - p - ) + let limb_subproduct := addmod( + mulmod(mload(W1_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), + mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_EVAL_LOC), p), + p + ) - let non_native_field_gate_2 := + let non_native_field_gate_2 := addmod( addmod( - addmod( - mulmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), - mulmod(mload(W2_EVAL_LOC), mload(W3_EVAL_LOC), p), - p - ), - sub(p, mload(W3_OMEGA_EVAL_LOC)), + mulmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), + mulmod(mload(W2_EVAL_LOC), mload(W3_EVAL_LOC), p), p - ) + ), + sub(p, mload(W3_OMEGA_EVAL_LOC)), + p + ) non_native_field_gate_2 := mulmod(non_native_field_gate_2, LIMB_SIZE, p) non_native_field_gate_2 := addmod(non_native_field_gate_2, sub(p, mload(W4_OMEGA_EVAL_LOC)), p) non_native_field_gate_2 := addmod(non_native_field_gate_2, limb_subproduct, p) non_native_field_gate_2 := mulmod(non_native_field_gate_2, mload(Q4_EVAL_LOC), p) limb_subproduct := mulmod(limb_subproduct, LIMB_SIZE, p) - limb_subproduct := - addmod(limb_subproduct, mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p) - let non_native_field_gate_1 := - mulmod( - addmod(limb_subproduct, sub(p, addmod(mload(W3_EVAL_LOC), mload(W4_EVAL_LOC), p)), p), - mload(Q3_EVAL_LOC), - p - ) - let non_native_field_gate_3 := - mulmod( - addmod( - addmod(limb_subproduct, mload(W4_EVAL_LOC), p), - sub(p, addmod(mload(W3_OMEGA_EVAL_LOC), mload(W4_OMEGA_EVAL_LOC), p)), - p - ), - mload(QM_EVAL_LOC), - p - ) - let non_native_field_identity := - mulmod( - addmod(addmod(non_native_field_gate_1, non_native_field_gate_2, p), non_native_field_gate_3, p), - mload(Q2_EVAL_LOC), + limb_subproduct := addmod( + limb_subproduct, + mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), + p + ) + let non_native_field_gate_1 := mulmod( + addmod(limb_subproduct, sub(p, addmod(mload(W3_EVAL_LOC), mload(W4_EVAL_LOC), p)), p), + mload(Q3_EVAL_LOC), + p + ) + let non_native_field_gate_3 := mulmod( + addmod( + addmod(limb_subproduct, mload(W4_EVAL_LOC), p), + sub(p, addmod(mload(W3_OMEGA_EVAL_LOC), mload(W4_OMEGA_EVAL_LOC), p)), p - ) + ), + mload(QM_EVAL_LOC), + p + ) + let non_native_field_identity := mulmod( + addmod(addmod(non_native_field_gate_1, non_native_field_gate_2, p), non_native_field_gate_3, p), + mload(Q2_EVAL_LOC), + p + ) mstore(AUX_NON_NATIVE_FIELD_EVALUATION, non_native_field_identity) } @@ -1496,8 +1509,11 @@ abstract contract BaseUltraVerifier is IVerifier { let index_is_monotonically_increasing := mulmod(index_delta, addmod(index_delta, sub(p, 1), p), p) // adjacent_values_match_if_adjacent_indices_match = record_delta * (1 - index_delta) - let adjacent_values_match_if_adjacent_indices_match := - mulmod(record_delta, addmod(1, sub(p, index_delta), p), p) + let adjacent_values_match_if_adjacent_indices_match := mulmod( + record_delta, + addmod(1, sub(p, index_delta), p), + p + ) // AUX_ROM_CONSISTENCY_EVALUATION = ((adjacent_values_match_if_adjacent_indices_match * alpha) + index_is_monotonically_increasing) * alpha + partial_record_check mstore( @@ -1538,12 +1554,13 @@ abstract contract BaseUltraVerifier is IVerifier { let value_delta := addmod(mload(W3_OMEGA_EVAL_LOC), sub(p, mload(W3_EVAL_LOC)), p) // adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation = (1 - index_delta) * value_delta * (1 - next_gate_access_type); - let adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation := - mulmod( - addmod(1, sub(p, index_delta), p), - mulmod(value_delta, addmod(1, sub(p, next_gate_access_type), p), p), - p - ) + let + adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation + := mulmod( + addmod(1, sub(p, index_delta), p), + mulmod(value_delta, addmod(1, sub(p, next_gate_access_type), p), p), + p + ) // AUX_RAM_CONSISTENCY_EVALUATION @@ -1561,14 +1578,16 @@ abstract contract BaseUltraVerifier is IVerifier { */ let access_type := addmod(mload(W4_EVAL_LOC), sub(p, partial_record_check), p) let access_check := mulmod(access_type, addmod(access_type, sub(p, 1), p), p) - let next_gate_access_type_is_boolean := - mulmod(next_gate_access_type, addmod(next_gate_access_type, sub(p, 1), p), p) - let RAM_cci := - mulmod( - adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation, - mload(C_ALPHA_LOC), - p - ) + let next_gate_access_type_is_boolean := mulmod( + next_gate_access_type, + addmod(next_gate_access_type, sub(p, 1), p), + p + ) + let RAM_cci := mulmod( + adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation, + mload(C_ALPHA_LOC), + p + ) RAM_cci := addmod(RAM_cci, index_is_monotonically_increasing, p) RAM_cci := mulmod(RAM_cci, mload(C_ALPHA_LOC), p) RAM_cci := addmod(RAM_cci, next_gate_access_type_is_boolean, p) @@ -1583,10 +1602,11 @@ abstract contract BaseUltraVerifier is IVerifier { let timestamp_delta := addmod(mload(W2_OMEGA_EVAL_LOC), sub(p, mload(W2_EVAL_LOC)), p) // RAM_timestamp_check_identity = (1 - index_delta) * timestamp_delta - w_3 - let RAM_timestamp_check_identity := - addmod( - mulmod(timestamp_delta, addmod(1, sub(p, index_delta), p), p), sub(p, mload(W3_EVAL_LOC)), p - ) + let RAM_timestamp_check_identity := addmod( + mulmod(timestamp_delta, addmod(1, sub(p, index_delta), p), p), + sub(p, mload(W3_EVAL_LOC)), + p + ) /** * memory_identity = ROM_consistency_check_identity * q_2; @@ -1600,15 +1620,22 @@ abstract contract BaseUltraVerifier is IVerifier { * auxiliary_identity *= alpha_base; */ let memory_identity := mulmod(mload(AUX_ROM_CONSISTENCY_EVALUATION), mload(Q2_EVAL_LOC), p) - memory_identity := - addmod(memory_identity, mulmod(RAM_timestamp_check_identity, mload(Q4_EVAL_LOC), p), p) - memory_identity := - addmod(memory_identity, mulmod(mload(AUX_MEMORY_EVALUATION), mload(QM_EVAL_LOC), p), p) + memory_identity := addmod( + memory_identity, + mulmod(RAM_timestamp_check_identity, mload(Q4_EVAL_LOC), p), + p + ) + memory_identity := addmod( + memory_identity, + mulmod(mload(AUX_MEMORY_EVALUATION), mload(QM_EVAL_LOC), p), + p + ) memory_identity := mulmod(memory_identity, mload(Q1_EVAL_LOC), p) - memory_identity := - addmod( - memory_identity, mulmod(mload(AUX_RAM_CONSISTENCY_EVALUATION), mload(QARITH_EVAL_LOC), p), p - ) + memory_identity := addmod( + memory_identity, + mulmod(mload(AUX_RAM_CONSISTENCY_EVALUATION), mload(QARITH_EVAL_LOC), p), + p + ) let auxiliary_identity := addmod(memory_identity, mload(AUX_NON_NATIVE_FIELD_EVALUATION), p) auxiliary_identity := addmod(auxiliary_identity, mload(AUX_LIMB_ACCUMULATOR_EVALUATION), p) @@ -2305,72 +2332,65 @@ abstract contract BaseUltraVerifier is IVerifier { * batch_evaluation += v5 * (z_omega_eval * u + z_eval) * batch_evaluation += v6 * (z_lookup_omega_eval * u + z_lookup_eval) */ - let batch_evaluation := + let batch_evaluation := mulmod( + mload(C_V0_LOC), + addmod(mulmod(mload(W1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W1_EVAL_LOC), p), + p + ) + batch_evaluation := addmod( + batch_evaluation, mulmod( - mload(C_V0_LOC), - addmod(mulmod(mload(W1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W1_EVAL_LOC), p), - p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V1_LOC), - addmod(mulmod(mload(W2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W2_EVAL_LOC), p), - p - ), + mload(C_V1_LOC), + addmod(mulmod(mload(W2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W2_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V2_LOC), - addmod(mulmod(mload(W3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W3_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V2_LOC), + addmod(mulmod(mload(W3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W3_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V3_LOC), - addmod(mulmod(mload(W4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W4_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V3_LOC), + addmod(mulmod(mload(W4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W4_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V4_LOC), - addmod(mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(S_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V4_LOC), + addmod(mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(S_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V5_LOC), - addmod(mulmod(mload(Z_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V5_LOC), + addmod(mulmod(mload(Z_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V6_LOC), - addmod(mulmod(mload(Z_LOOKUP_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_LOOKUP_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V6_LOC), + addmod(mulmod(mload(Z_LOOKUP_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_LOOKUP_EVAL_LOC), p), p - ) + ), + p + ) /** * batch_evaluation += v7 * Q1_EVAL @@ -2415,46 +2435,42 @@ abstract contract BaseUltraVerifier is IVerifier { * batch_evaluation += v29 * id4_eval * batch_evaluation += quotient_eval */ - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V21_LOC), - addmod(mulmod(mload(TABLE1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE1_EVAL_LOC), p), - p - ), + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V21_LOC), + addmod(mulmod(mload(TABLE1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE1_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V22_LOC), - addmod(mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE2_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V22_LOC), + addmod(mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE2_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V23_LOC), - addmod(mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE3_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V23_LOC), + addmod(mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE3_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V24_LOC), - addmod(mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE4_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V24_LOC), + addmod(mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE4_EVAL_LOC), p), p - ) + ), + p + ) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V25_LOC), mload(TABLE_TYPE_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V26_LOC), mload(ID1_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V27_LOC), mload(ID2_EVAL_LOC), p), p) @@ -2616,12 +2632,10 @@ contract KusamaVerifier is BaseUltraVerifier { return UltraVerificationKey.verificationKeyHash(); } - function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) - internal - pure - virtual - override(BaseUltraVerifier) - { + function loadVerificationKey( + uint256 vk, + uint256 _omegaInverseLoc + ) internal pure virtual override(BaseUltraVerifier) { UltraVerificationKey.loadVerificationKey(vk, _omegaInverseLoc); } } diff --git a/evm/src/consensus/verifiers/PolkadotVerifier.sol b/evm/src/consensus/verifiers/PolkadotVerifier.sol index e99cfb085..7077f0fcc 100644 --- a/evm/src/consensus/verifiers/PolkadotVerifier.sol +++ b/evm/src/consensus/verifiers/PolkadotVerifier.sol @@ -844,7 +844,11 @@ abstract contract BaseUltraVerifier is IVerifier { let root_2 := mulmod(beta, 0x0c, p_clone) // @note 0x05 + 0x07 == 0x0c == external coset generator - for {} lt(public_inputs_ptr, endpoint_ptr) { public_inputs_ptr := add(public_inputs_ptr, 0x20) } { + for { + + } lt(public_inputs_ptr, endpoint_ptr) { + public_inputs_ptr := add(public_inputs_ptr, 0x20) + } { /** * input = public_input[i] * valid_inputs &= input < p @@ -885,7 +889,11 @@ abstract contract BaseUltraVerifier is IVerifier { { let exponent := mload(N_LOC) let count := 1 - for {} lt(count, exponent) { count := add(count, count) } { + for { + + } lt(count, exponent) { + count := add(count, count) + } { delta_numerator := mulmod(delta_numerator, delta_numerator, p) } } @@ -927,7 +935,11 @@ abstract contract BaseUltraVerifier is IVerifier { // pow_small let exponent := mload(N_LOC) let count := 1 - for {} lt(count, exponent) { count := add(count, count) } { + for { + + } lt(count, exponent) { + count := add(count, count) + } { vanishing_numerator := mulmod(vanishing_numerator, vanishing_numerator, p) } } @@ -943,8 +955,11 @@ abstract contract BaseUltraVerifier is IVerifier { vanishing_denominator := mulmod(vanishing_denominator, addmod(zeta, work_root, p), p) work_root := mulmod(work_root, accumulating_root, p) vanishing_denominator := mulmod(vanishing_denominator, addmod(zeta, work_root, p), p) - vanishing_denominator := - mulmod(vanishing_denominator, addmod(zeta, mulmod(work_root, accumulating_root, p), p), p) + vanishing_denominator := mulmod( + vanishing_denominator, + addmod(zeta, mulmod(work_root, accumulating_root, p), p), + p + ) work_root := mload(OMEGA_LOC) @@ -953,10 +968,11 @@ abstract contract BaseUltraVerifier is IVerifier { accumulating_root := mulmod(work_root, work_root, p) - let l_end_denominator := - addmod( - mulmod(mulmod(mulmod(accumulating_root, accumulating_root, p), work_root, p), zeta, p), sub(p, 1), p - ) + let l_end_denominator := addmod( + mulmod(mulmod(mulmod(accumulating_root, accumulating_root, p), work_root, p), zeta, p), + sub(p, 1), + p + ) /** * Compute inversions using Montgomery's batch inversion trick @@ -1038,37 +1054,32 @@ abstract contract BaseUltraVerifier is IVerifier { * t2 = (W2 + gamma + beta * sigma_3_eval) * (W3 + gamma + beta * sigma_4_eval) * result -= (alpha_base * z_omega_eval * t1 * t2) */ - let t1 := - mulmod( - add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(ID1_EVAL_LOC), p)), - add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(ID2_EVAL_LOC), p)), - p - ) - let t2 := - mulmod( - add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(ID3_EVAL_LOC), p)), - add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(ID4_EVAL_LOC), p)), - p - ) + let t1 := mulmod( + add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(ID1_EVAL_LOC), p)), + add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(ID2_EVAL_LOC), p)), + p + ) + let t2 := mulmod( + add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(ID3_EVAL_LOC), p)), + add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(ID4_EVAL_LOC), p)), + p + ) let result := mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_EVAL_LOC), mulmod(t1, t2, p), p), p) - t1 := - mulmod( - add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA1_EVAL_LOC), p)), - add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA2_EVAL_LOC), p)), - p - ) - t2 := - mulmod( - add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA3_EVAL_LOC), p)), - add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA4_EVAL_LOC), p)), - p - ) - result := - addmod( - result, - sub(p, mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_OMEGA_EVAL_LOC), mulmod(t1, t2, p), p), p)), - p - ) + t1 := mulmod( + add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA1_EVAL_LOC), p)), + add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA2_EVAL_LOC), p)), + p + ) + t2 := mulmod( + add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA3_EVAL_LOC), p)), + add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA4_EVAL_LOC), p)), + p + ) + result := addmod( + result, + sub(p, mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_OMEGA_EVAL_LOC), mulmod(t1, t2, p), p), p)), + p + ) /** * alpha_base *= alpha @@ -1078,20 +1089,19 @@ abstract contract BaseUltraVerifier is IVerifier { * alpha_Base *= alpha */ mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p)) - result := - addmod( - result, + result := addmod( + result, + mulmod( + mload(C_ALPHA_BASE_LOC), mulmod( - mload(C_ALPHA_BASE_LOC), - mulmod( - mload(L_END_LOC), - addmod(mload(Z_OMEGA_EVAL_LOC), sub(p, mload(PUBLIC_INPUT_DELTA_LOC)), p), - p - ), + mload(L_END_LOC), + addmod(mload(Z_OMEGA_EVAL_LOC), sub(p, mload(PUBLIC_INPUT_DELTA_LOC)), p), p ), p - ) + ), + p + ) mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p)) mstore( PERMUTATION_IDENTITY, @@ -1122,46 +1132,53 @@ abstract contract BaseUltraVerifier is IVerifier { * f += (w1(z) + q2.w1(zω)) */ let f := mulmod(mload(C_ETA_LOC), mload(Q3_EVAL_LOC), p) - f := - addmod(f, addmod(mload(W3_EVAL_LOC), mulmod(mload(QC_EVAL_LOC), mload(W3_OMEGA_EVAL_LOC), p), p), p) + f := addmod( + f, + addmod(mload(W3_EVAL_LOC), mulmod(mload(QC_EVAL_LOC), mload(W3_OMEGA_EVAL_LOC), p), p), + p + ) f := mulmod(f, mload(C_ETA_LOC), p) - f := - addmod(f, addmod(mload(W2_EVAL_LOC), mulmod(mload(QM_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p), p) + f := addmod( + f, + addmod(mload(W2_EVAL_LOC), mulmod(mload(QM_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p), + p + ) f := mulmod(f, mload(C_ETA_LOC), p) - f := - addmod(f, addmod(mload(W1_EVAL_LOC), mulmod(mload(Q2_EVAL_LOC), mload(W1_OMEGA_EVAL_LOC), p), p), p) + f := addmod( + f, + addmod(mload(W1_EVAL_LOC), mulmod(mload(Q2_EVAL_LOC), mload(W1_OMEGA_EVAL_LOC), p), p), + p + ) // t(z) = table4(z).η³ + table3(z).η² + table2(z).η + table1(z) - let t := + let t := addmod( addmod( addmod( - addmod( - mulmod(mload(TABLE4_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), - mulmod(mload(TABLE3_EVAL_LOC), mload(C_ETA_SQR_LOC), p), - p - ), - mulmod(mload(TABLE2_EVAL_LOC), mload(C_ETA_LOC), p), + mulmod(mload(TABLE4_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), + mulmod(mload(TABLE3_EVAL_LOC), mload(C_ETA_SQR_LOC), p), p ), - mload(TABLE1_EVAL_LOC), + mulmod(mload(TABLE2_EVAL_LOC), mload(C_ETA_LOC), p), p - ) + ), + mload(TABLE1_EVAL_LOC), + p + ) // t(zw) = table4(zw).η³ + table3(zw).η² + table2(zw).η + table1(zw) - let t_omega := + let t_omega := addmod( addmod( addmod( - addmod( - mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), - mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_ETA_SQR_LOC), p), - p - ), - mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_ETA_LOC), p), + mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_ETA_CUBE_LOC), p), + mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_ETA_SQR_LOC), p), p ), - mload(TABLE1_OMEGA_EVAL_LOC), + mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_ETA_LOC), p), p - ) + ), + mload(TABLE1_OMEGA_EVAL_LOC), + p + ) /** * Goal: numerator = (TABLE_TYPE_EVAL * f(z) + γ) * (t(z) + βt(zω) + γ(β + 1)) * (β + 1) @@ -1196,12 +1213,11 @@ abstract contract BaseUltraVerifier is IVerifier { * PLOOKUP_IDENTITY = (numerator - denominator).alpha_base * alpha_base *= alpha^3 */ - let denominator := - addmod( - addmod(mload(S_EVAL_LOC), mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_BETA_LOC), p), p), - gamma_beta_constant, - p - ) + let denominator := addmod( + addmod(mload(S_EVAL_LOC), mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_BETA_LOC), p), p), + gamma_beta_constant, + p + ) let temp1 := mulmod(mload(C_ALPHA_SQR_LOC), mload(L_END_LOC), p) denominator := addmod(denominator, sub(p, temp1), p) denominator := mulmod(denominator, mload(Z_LOOKUP_OMEGA_EVAL_LOC), p) @@ -1259,43 +1275,44 @@ abstract contract BaseUltraVerifier is IVerifier { // @todo - Add a explicit test that hits QARITH == 3 // w1w2qm := (w_1 . w_2 . q_m . (QARITH_EVAL_LOC - 3)) / 2 - let w1w2qm := + let w1w2qm := mulmod( mulmod( - mulmod( - mulmod(mulmod(mload(W1_EVAL_LOC), mload(W2_EVAL_LOC), p), mload(QM_EVAL_LOC), p), - addmod(mload(QARITH_EVAL_LOC), sub(p, 3), p), - p - ), - NEGATIVE_INVERSE_OF_2_MODULO_P, + mulmod(mulmod(mload(W1_EVAL_LOC), mload(W2_EVAL_LOC), p), mload(QM_EVAL_LOC), p), + addmod(mload(QARITH_EVAL_LOC), sub(p, 3), p), p - ) + ), + NEGATIVE_INVERSE_OF_2_MODULO_P, + p + ) // (w_1 . w_2 . q_m . (q_arith - 3)) / -2) + (w_1 . q_1) + (w_2 . q_2) + (w_3 . q_3) + (w_4 . q_4) + q_c - let identity := - addmod( - mload(QC_EVAL_LOC), addmod(w4q3, addmod(w3q3, addmod(w2q2, addmod(w1q1, w1w2qm, p), p), p), p), p - ) + let identity := addmod( + mload(QC_EVAL_LOC), + addmod(w4q3, addmod(w3q3, addmod(w2q2, addmod(w1q1, w1w2qm, p), p), p), p), + p + ) // if q_arith == 3 we evaluate an additional mini addition gate (on top of the regular one), where: // w_1 + w_4 - w_1_omega + q_m = 0 // we use this gate to save an addition gate when adding or subtracting non-native field elements // α * (q_arith - 2) * (w_1 + w_4 - w_1_omega + q_m) - let extra_small_addition_gate_identity := + let extra_small_addition_gate_identity := mulmod( + mload(C_ALPHA_LOC), mulmod( - mload(C_ALPHA_LOC), - mulmod( - addmod(mload(QARITH_EVAL_LOC), sub(p, 2), p), + addmod(mload(QARITH_EVAL_LOC), sub(p, 2), p), + addmod( + mload(QM_EVAL_LOC), addmod( - mload(QM_EVAL_LOC), - addmod( - sub(p, mload(W1_OMEGA_EVAL_LOC)), addmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), p - ), + sub(p, mload(W1_OMEGA_EVAL_LOC)), + addmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), p ), p ), p - ) + ), + p + ) // if q_arith == 2 OR q_arith == 3 we add the 4th wire of the NEXT gate into the arithmetic identity // N.B. if q_arith > 2, this wire value will be scaled by (q_arith - 1) relative to the other gate wires! @@ -1354,58 +1371,54 @@ abstract contract BaseUltraVerifier is IVerifier { let d3 := addmod(mload(W4_EVAL_LOC), sub(p, mload(W3_EVAL_LOC)), p) let d4 := addmod(mload(W1_OMEGA_EVAL_LOC), sub(p, mload(W4_EVAL_LOC)), p) - let range_accumulator := + let range_accumulator := mulmod( mulmod( - mulmod( - mulmod(addmod(mulmod(d1, d1, p), sub(p, d1), p), addmod(d1, minus_two, p), p), - addmod(d1, minus_three, p), - p - ), - mload(C_ALPHA_BASE_LOC), + mulmod(addmod(mulmod(d1, d1, p), sub(p, d1), p), addmod(d1, minus_two, p), p), + addmod(d1, minus_three, p), p - ) - range_accumulator := - addmod( - range_accumulator, + ), + mload(C_ALPHA_BASE_LOC), + p + ) + range_accumulator := addmod( + range_accumulator, + mulmod( mulmod( - mulmod( - mulmod(addmod(mulmod(d2, d2, p), sub(p, d2), p), addmod(d2, minus_two, p), p), - addmod(d2, minus_three, p), - p - ), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + mulmod(addmod(mulmod(d2, d2, p), sub(p, d2), p), addmod(d2, minus_two, p), p), + addmod(d2, minus_three, p), p ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), p - ) - range_accumulator := - addmod( - range_accumulator, + ), + p + ) + range_accumulator := addmod( + range_accumulator, + mulmod( mulmod( - mulmod( - mulmod(addmod(mulmod(d3, d3, p), sub(p, d3), p), addmod(d3, minus_two, p), p), - addmod(d3, minus_three, p), - p - ), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p), + mulmod(addmod(mulmod(d3, d3, p), sub(p, d3), p), addmod(d3, minus_two, p), p), + addmod(d3, minus_three, p), p ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p), p - ) - range_accumulator := - addmod( - range_accumulator, + ), + p + ) + range_accumulator := addmod( + range_accumulator, + mulmod( mulmod( - mulmod( - mulmod(addmod(mulmod(d4, d4, p), sub(p, d4), p), addmod(d4, minus_two, p), p), - addmod(d4, minus_three, p), - p - ), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p), + mulmod(addmod(mulmod(d4, d4, p), sub(p, d4), p), addmod(d4, minus_two, p), p), + addmod(d4, minus_three, p), p ), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p), p - ) + ), + p + ) range_accumulator := mulmod(range_accumulator, mload(QSORT_EVAL_LOC), p) mstore(SORT_IDENTITY, range_accumulator) @@ -1437,38 +1450,39 @@ abstract contract BaseUltraVerifier is IVerifier { let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p) let y1y2 := mulmod(mulmod(mload(Y1_EVAL_LOC), mload(Y2_EVAL_LOC), p), mload(QSIGN_LOC), p) - let x_add_identity := - addmod( - mulmod( - addmod(mload(X3_EVAL_LOC), addmod(mload(X2_EVAL_LOC), mload(X1_EVAL_LOC), p), p), - mulmod(x_diff, x_diff, p), - p - ), - addmod(sub(p, addmod(y2_sqr, y1_sqr, p)), addmod(y1y2, y1y2, p), p), + let x_add_identity := addmod( + mulmod( + addmod(mload(X3_EVAL_LOC), addmod(mload(X2_EVAL_LOC), mload(X1_EVAL_LOC), p), p), + mulmod(x_diff, x_diff, p), p - ) - x_add_identity := - mulmod(mulmod(x_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), mload(C_ALPHA_BASE_LOC), p) + ), + addmod(sub(p, addmod(y2_sqr, y1_sqr, p)), addmod(y1y2, y1y2, p), p), + p + ) + x_add_identity := mulmod( + mulmod(x_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), + mload(C_ALPHA_BASE_LOC), + p + ) // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0 let y1_plus_y3 := addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p) let y_diff := addmod(mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p), sub(p, mload(Y1_EVAL_LOC)), p) - let y_add_identity := - addmod( - mulmod(y1_plus_y3, x_diff, p), - mulmod(addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), y_diff, p), - p - ) - y_add_identity := - mulmod( - mulmod(y_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), - p - ) + let y_add_identity := addmod( + mulmod(y1_plus_y3, x_diff, p), + mulmod(addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), y_diff, p), + p + ) + y_add_identity := mulmod( + mulmod(y_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + p + ) // ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL mstore( - ELLIPTIC_IDENTITY, mulmod(addmod(x_add_identity, y_add_identity, p), mload(QELLIPTIC_EVAL_LOC), p) + ELLIPTIC_IDENTITY, + mulmod(addmod(x_add_identity, y_add_identity, p), mload(QELLIPTIC_EVAL_LOC), p) ) } { @@ -1492,33 +1506,34 @@ abstract contract BaseUltraVerifier is IVerifier { let y1_sqr_mul_4 := mulmod(y1_sqr, 4, p) let x1_pow_4_mul_9 := mulmod(x_pow_4, 9, p) let x1_sqr_mul_3 := mulmod(x1_sqr, 3, p) - let x_double_identity := - addmod( - mulmod( - addmod(mload(X3_EVAL_LOC), addmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), p), - y1_sqr_mul_4, - p - ), - sub(p, x1_pow_4_mul_9), + let x_double_identity := addmod( + mulmod( + addmod(mload(X3_EVAL_LOC), addmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), p), + y1_sqr_mul_4, p - ) + ), + sub(p, x1_pow_4_mul_9), + p + ) // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0 - let y_double_identity := - addmod( - mulmod(x1_sqr_mul_3, addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p), - sub( - p, - mulmod( - addmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p), - addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p), - p - ) - ), - p - ) + let y_double_identity := addmod( + mulmod(x1_sqr_mul_3, addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p), + sub( + p, + mulmod( + addmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p), + addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p), + p + ) + ), + p + ) x_double_identity := mulmod(x_double_identity, mload(C_ALPHA_BASE_LOC), p) - y_double_identity := - mulmod(y_double_identity, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), p) + y_double_identity := mulmod( + y_double_identity, + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + p + ) x_double_identity := mulmod(x_double_identity, mload(QM_EVAL_LOC), p) y_double_identity := mulmod(y_double_identity, mload(QM_EVAL_LOC), p) // ELLIPTIC_IDENTITY += (x_double_identity + y_double_identity) * Q_DOUBLE_EVAL @@ -1559,52 +1574,50 @@ abstract contract BaseUltraVerifier is IVerifier { * non_native_field_gate_3 = (limb_subproduct + w_4 - (w_3_omega + w_4_omega)) * q_m * non_native_field_identity = (non_native_field_gate_1 + non_native_field_gate_2 + non_native_field_gate_3) * q_2 */ - let limb_subproduct := - addmod( - mulmod(mload(W1_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), - mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_EVAL_LOC), p), - p - ) + let limb_subproduct := addmod( + mulmod(mload(W1_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), + mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_EVAL_LOC), p), + p + ) - let non_native_field_gate_2 := + let non_native_field_gate_2 := addmod( addmod( - addmod( - mulmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), - mulmod(mload(W2_EVAL_LOC), mload(W3_EVAL_LOC), p), - p - ), - sub(p, mload(W3_OMEGA_EVAL_LOC)), + mulmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), + mulmod(mload(W2_EVAL_LOC), mload(W3_EVAL_LOC), p), p - ) + ), + sub(p, mload(W3_OMEGA_EVAL_LOC)), + p + ) non_native_field_gate_2 := mulmod(non_native_field_gate_2, LIMB_SIZE, p) non_native_field_gate_2 := addmod(non_native_field_gate_2, sub(p, mload(W4_OMEGA_EVAL_LOC)), p) non_native_field_gate_2 := addmod(non_native_field_gate_2, limb_subproduct, p) non_native_field_gate_2 := mulmod(non_native_field_gate_2, mload(Q4_EVAL_LOC), p) limb_subproduct := mulmod(limb_subproduct, LIMB_SIZE, p) - limb_subproduct := - addmod(limb_subproduct, mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p) - let non_native_field_gate_1 := - mulmod( - addmod(limb_subproduct, sub(p, addmod(mload(W3_EVAL_LOC), mload(W4_EVAL_LOC), p)), p), - mload(Q3_EVAL_LOC), - p - ) - let non_native_field_gate_3 := - mulmod( - addmod( - addmod(limb_subproduct, mload(W4_EVAL_LOC), p), - sub(p, addmod(mload(W3_OMEGA_EVAL_LOC), mload(W4_OMEGA_EVAL_LOC), p)), - p - ), - mload(QM_EVAL_LOC), - p - ) - let non_native_field_identity := - mulmod( - addmod(addmod(non_native_field_gate_1, non_native_field_gate_2, p), non_native_field_gate_3, p), - mload(Q2_EVAL_LOC), + limb_subproduct := addmod( + limb_subproduct, + mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), + p + ) + let non_native_field_gate_1 := mulmod( + addmod(limb_subproduct, sub(p, addmod(mload(W3_EVAL_LOC), mload(W4_EVAL_LOC), p)), p), + mload(Q3_EVAL_LOC), + p + ) + let non_native_field_gate_3 := mulmod( + addmod( + addmod(limb_subproduct, mload(W4_EVAL_LOC), p), + sub(p, addmod(mload(W3_OMEGA_EVAL_LOC), mload(W4_OMEGA_EVAL_LOC), p)), p - ) + ), + mload(QM_EVAL_LOC), + p + ) + let non_native_field_identity := mulmod( + addmod(addmod(non_native_field_gate_1, non_native_field_gate_2, p), non_native_field_gate_3, p), + mload(Q2_EVAL_LOC), + p + ) mstore(AUX_NON_NATIVE_FIELD_EVALUATION, non_native_field_identity) } @@ -1698,8 +1711,11 @@ abstract contract BaseUltraVerifier is IVerifier { let index_is_monotonically_increasing := mulmod(index_delta, addmod(index_delta, sub(p, 1), p), p) // adjacent_values_match_if_adjacent_indices_match = record_delta * (1 - index_delta) - let adjacent_values_match_if_adjacent_indices_match := - mulmod(record_delta, addmod(1, sub(p, index_delta), p), p) + let adjacent_values_match_if_adjacent_indices_match := mulmod( + record_delta, + addmod(1, sub(p, index_delta), p), + p + ) // AUX_ROM_CONSISTENCY_EVALUATION = ((adjacent_values_match_if_adjacent_indices_match * alpha) + index_is_monotonically_increasing) * alpha + partial_record_check mstore( @@ -1740,12 +1756,13 @@ abstract contract BaseUltraVerifier is IVerifier { let value_delta := addmod(mload(W3_OMEGA_EVAL_LOC), sub(p, mload(W3_EVAL_LOC)), p) // adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation = (1 - index_delta) * value_delta * (1 - next_gate_access_type); - let adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation := - mulmod( - addmod(1, sub(p, index_delta), p), - mulmod(value_delta, addmod(1, sub(p, next_gate_access_type), p), p), - p - ) + let + adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation + := mulmod( + addmod(1, sub(p, index_delta), p), + mulmod(value_delta, addmod(1, sub(p, next_gate_access_type), p), p), + p + ) // AUX_RAM_CONSISTENCY_EVALUATION @@ -1763,14 +1780,16 @@ abstract contract BaseUltraVerifier is IVerifier { */ let access_type := addmod(mload(W4_EVAL_LOC), sub(p, partial_record_check), p) let access_check := mulmod(access_type, addmod(access_type, sub(p, 1), p), p) - let next_gate_access_type_is_boolean := - mulmod(next_gate_access_type, addmod(next_gate_access_type, sub(p, 1), p), p) - let RAM_cci := - mulmod( - adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation, - mload(C_ALPHA_LOC), - p - ) + let next_gate_access_type_is_boolean := mulmod( + next_gate_access_type, + addmod(next_gate_access_type, sub(p, 1), p), + p + ) + let RAM_cci := mulmod( + adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation, + mload(C_ALPHA_LOC), + p + ) RAM_cci := addmod(RAM_cci, index_is_monotonically_increasing, p) RAM_cci := mulmod(RAM_cci, mload(C_ALPHA_LOC), p) RAM_cci := addmod(RAM_cci, next_gate_access_type_is_boolean, p) @@ -1785,10 +1804,11 @@ abstract contract BaseUltraVerifier is IVerifier { let timestamp_delta := addmod(mload(W2_OMEGA_EVAL_LOC), sub(p, mload(W2_EVAL_LOC)), p) // RAM_timestamp_check_identity = (1 - index_delta) * timestamp_delta - w_3 - let RAM_timestamp_check_identity := - addmod( - mulmod(timestamp_delta, addmod(1, sub(p, index_delta), p), p), sub(p, mload(W3_EVAL_LOC)), p - ) + let RAM_timestamp_check_identity := addmod( + mulmod(timestamp_delta, addmod(1, sub(p, index_delta), p), p), + sub(p, mload(W3_EVAL_LOC)), + p + ) /** * memory_identity = ROM_consistency_check_identity * q_2; @@ -1802,15 +1822,22 @@ abstract contract BaseUltraVerifier is IVerifier { * auxiliary_identity *= alpha_base; */ let memory_identity := mulmod(mload(AUX_ROM_CONSISTENCY_EVALUATION), mload(Q2_EVAL_LOC), p) - memory_identity := - addmod(memory_identity, mulmod(RAM_timestamp_check_identity, mload(Q4_EVAL_LOC), p), p) - memory_identity := - addmod(memory_identity, mulmod(mload(AUX_MEMORY_EVALUATION), mload(QM_EVAL_LOC), p), p) + memory_identity := addmod( + memory_identity, + mulmod(RAM_timestamp_check_identity, mload(Q4_EVAL_LOC), p), + p + ) + memory_identity := addmod( + memory_identity, + mulmod(mload(AUX_MEMORY_EVALUATION), mload(QM_EVAL_LOC), p), + p + ) memory_identity := mulmod(memory_identity, mload(Q1_EVAL_LOC), p) - memory_identity := - addmod( - memory_identity, mulmod(mload(AUX_RAM_CONSISTENCY_EVALUATION), mload(QARITH_EVAL_LOC), p), p - ) + memory_identity := addmod( + memory_identity, + mulmod(mload(AUX_RAM_CONSISTENCY_EVALUATION), mload(QARITH_EVAL_LOC), p), + p + ) let auxiliary_identity := addmod(memory_identity, mload(AUX_NON_NATIVE_FIELD_EVALUATION), p) auxiliary_identity := addmod(auxiliary_identity, mload(AUX_LIMB_ACCUMULATOR_EVALUATION), p) @@ -2425,72 +2452,65 @@ abstract contract BaseUltraVerifier is IVerifier { * batch_evaluation += v5 * (z_omega_eval * u + z_eval) * batch_evaluation += v6 * (z_lookup_omega_eval * u + z_lookup_eval) */ - let batch_evaluation := + let batch_evaluation := mulmod( + mload(C_V0_LOC), + addmod(mulmod(mload(W1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W1_EVAL_LOC), p), + p + ) + batch_evaluation := addmod( + batch_evaluation, mulmod( - mload(C_V0_LOC), - addmod(mulmod(mload(W1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W1_EVAL_LOC), p), - p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V1_LOC), - addmod(mulmod(mload(W2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W2_EVAL_LOC), p), - p - ), + mload(C_V1_LOC), + addmod(mulmod(mload(W2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W2_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V2_LOC), - addmod(mulmod(mload(W3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W3_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V2_LOC), + addmod(mulmod(mload(W3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W3_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V3_LOC), - addmod(mulmod(mload(W4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W4_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V3_LOC), + addmod(mulmod(mload(W4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W4_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V4_LOC), - addmod(mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(S_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V4_LOC), + addmod(mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(S_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V5_LOC), - addmod(mulmod(mload(Z_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V5_LOC), + addmod(mulmod(mload(Z_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V6_LOC), - addmod(mulmod(mload(Z_LOOKUP_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_LOOKUP_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V6_LOC), + addmod(mulmod(mload(Z_LOOKUP_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_LOOKUP_EVAL_LOC), p), p - ) + ), + p + ) /** * batch_evaluation += v7 * Q1_EVAL @@ -2535,46 +2555,42 @@ abstract contract BaseUltraVerifier is IVerifier { * batch_evaluation += v29 * id4_eval * batch_evaluation += quotient_eval */ - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V21_LOC), - addmod(mulmod(mload(TABLE1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE1_EVAL_LOC), p), - p - ), + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V21_LOC), + addmod(mulmod(mload(TABLE1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE1_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V22_LOC), - addmod(mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE2_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V22_LOC), + addmod(mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE2_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V23_LOC), - addmod(mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE3_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V23_LOC), + addmod(mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE3_EVAL_LOC), p), p - ) - batch_evaluation := - addmod( - batch_evaluation, - mulmod( - mload(C_V24_LOC), - addmod(mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE4_EVAL_LOC), p), - p - ), + ), + p + ) + batch_evaluation := addmod( + batch_evaluation, + mulmod( + mload(C_V24_LOC), + addmod(mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE4_EVAL_LOC), p), p - ) + ), + p + ) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V25_LOC), mload(TABLE_TYPE_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V26_LOC), mload(ID1_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V27_LOC), mload(ID2_EVAL_LOC), p), p) @@ -2744,12 +2760,10 @@ contract PolkadotVerifier is BaseUltraVerifier { return UltraVerificationKey.verificationKeyHash(); } - function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) - internal - pure - virtual - override(BaseUltraVerifier) - { + function loadVerificationKey( + uint256 vk, + uint256 _omegaInverseLoc + ) internal pure virtual override(BaseUltraVerifier) { UltraVerificationKey.loadVerificationKey(vk, _omegaInverseLoc); } } diff --git a/evm/src/hosts/Arbitrum.sol b/evm/src/hosts/Arbitrum.sol index 1b1377772..f43d80729 100644 --- a/evm/src/hosts/Arbitrum.sol +++ b/evm/src/hosts/Arbitrum.sol @@ -17,6 +17,13 @@ pragma solidity 0.8.17; import "./EvmHost.sol"; import "ismp/StateMachine.sol"; +/** + * @title The ArbitrumHost + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The IsmpHost and IsmpDispatcher implementation for the Arbitrum state machine. + * Refer to the official ISMP specification. https://docs.hyperbridge.network/protocol/ismp + */ contract ArbitrumHost is EvmHost { constructor(HostParams memory params) EvmHost(params) {} diff --git a/evm/src/hosts/Base.sol b/evm/src/hosts/Base.sol index 1e073bc67..539e38f25 100644 --- a/evm/src/hosts/Base.sol +++ b/evm/src/hosts/Base.sol @@ -17,6 +17,13 @@ pragma solidity 0.8.17; import "./EvmHost.sol"; import "ismp/StateMachine.sol"; +/** + * @title The BaseHost + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The IsmpHost and IsmpDispatcher implementation for the Base state machine. + * Refer to the official ISMP specification. https://docs.hyperbridge.network/protocol/ismp + */ contract BaseHost is EvmHost { constructor(HostParams memory params) EvmHost(params) {} diff --git a/evm/src/hosts/Bsc.sol b/evm/src/hosts/Bsc.sol index 592b9ad50..cb22acb0f 100644 --- a/evm/src/hosts/Bsc.sol +++ b/evm/src/hosts/Bsc.sol @@ -17,6 +17,13 @@ pragma solidity 0.8.17; import "./EvmHost.sol"; import "ismp/StateMachine.sol"; +/** + * @title The BscHost + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The IsmpHost and IsmpDispatcher implementation for the Binance state machine. + * Refer to the official ISMP specification. https://docs.hyperbridge.network/protocol/ismp + */ contract BscHost is EvmHost { constructor(HostParams memory params) EvmHost(params) {} diff --git a/evm/src/hosts/Ethereum.sol b/evm/src/hosts/Ethereum.sol index 3bffc744d..9860b5a05 100644 --- a/evm/src/hosts/Ethereum.sol +++ b/evm/src/hosts/Ethereum.sol @@ -17,6 +17,13 @@ pragma solidity 0.8.17; import "./EvmHost.sol"; import "ismp/StateMachine.sol"; +/** + * @title The EthereumHost + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The IsmpHost and IsmpDispatcher implementation for the Ethereum state machine. + * Refer to the official ISMP specification. https://docs.hyperbridge.network/protocol/ismp + */ contract EthereumHost is EvmHost { constructor(HostParams memory params) EvmHost(params) {} diff --git a/evm/src/hosts/EvmHost.sol b/evm/src/hosts/EvmHost.sol index 7b60faa71..3fc6aee90 100644 --- a/evm/src/hosts/EvmHost.sol +++ b/evm/src/hosts/EvmHost.sol @@ -30,10 +30,10 @@ import {PostRequest, PostResponse, GetRequest, GetResponse, PostTimeout, Message // The EvmHost protocol parameters struct HostParams { - // The default timeout in seconds for requests. If requests are dispatched + // The default timeout in seconds for messages. If messages are dispatched // with a timeout value lower than this this value will be used instead uint256 defaultTimeout; - // The cost of cross-chain requests in the feetoken per-byte, + // The cost of cross-chain requests in the feeToken per byte, // this is charged to the application initiating a request or response uint256 perByteFee; // The fee token contract address. This will typically be DAI. @@ -56,7 +56,7 @@ struct HostParams { address consensusClient; // State machines whose state commitments are accepted uint256[] stateMachines; - // Priviledged set of fishermen accounts + // Privileged set of fishermen accounts address[] fishermen; // The state machine identifier for hyperbridge bytes hyperbridge; @@ -82,7 +82,7 @@ interface IHostManager { function withdraw(WithdrawParams memory params) external; } -// Withdraw parameters +// FeeToken withdrawal parameters struct WithdrawParams { // The beneficiary address address beneficiary; @@ -91,10 +91,13 @@ struct WithdrawParams { } /** - * @title EvmHost. IsmpHost and IsmpDispatcher implementation for EVM-compatible chains + * @title The EvmHost + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The IsmpHost and IsmpDispatcher implementation for EVM-compatible chains * Refer to the official ISMP specification. https://docs.hyperbridge.network/protocol/ismp * - * @dev The IsmpHost provides the neccessary storage interface for the ISMP handlers to process + * @dev The IsmpHost provides the necessary storage interface for the ISMP handlers to process * ISMP messages, the IsmpDispatcher provides the interfaces applications use for dispatching requests * and responses. This host implementation delegates all verification logic to the IHandler contract. * It is only responsible for dispatching incoming & outgoing requests/responses. As well as managing @@ -145,98 +148,185 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // Parameters for the host HostParams private _hostParams; - // monotonically increasing nonce for outgoing requests + // Monotonically increasing nonce for outgoing requests uint256 private _nonce; - // emergency shutdown button, only the admin can do this + // Emergency shutdown button, only the admin or handler can push this. bool private _frozen; - // current verified state of the consensus client; + // Current verified state of the consensus client; bytes private _consensusState; - // timestamp for when the consensus was most recently updated + // Timestamp for when the consensus was most recently updated uint256 private _consensusUpdateTimestamp; // Emitted when an incoming POST request is handled - event PostRequestHandled(bytes32 commitment, address relayer); + event PostRequestHandled( + // Commitment of the incoming request + bytes32 indexed commitment, + // Relayer responsible for the delivery + address relayer + ); // Emitted when an outgoing POST request timeout is handled, `dest` refers // to the destination for the request - event PostRequestTimeoutHandled(bytes32 commitment, bytes dest); + event PostRequestTimeoutHandled( + // Commitment of the timed out request + bytes32 indexed commitment, + // Destination chain for this request + string dest + ); // Emitted when an incoming POST response is handled - event PostResponseHandled(bytes32 commitment, address relayer); + event PostResponseHandled( + // Commitment of the incoming response + bytes32 indexed commitment, + // Relayer responsible for the delivery + address relayer + ); // Emitted when an outgoing POST response timeout is handled, `dest` refers // to the destination for the response - event PostResponseTimeoutHandled(bytes32 commitment, bytes dest); + event PostResponseTimeoutHandled( + // Commitment of the timed out response + bytes32 indexed commitment, + // Destination chain for this response + string dest + ); // Emitted when an outgoing GET request is handled - event GetRequestHandled(bytes32 commitment, address relayer); + event GetRequestHandled( + // Commitment of the GET request + bytes32 indexed commitment, + // Relayer responsible for the delivery + address relayer + ); // Emitted when an outgoing GET request timeout is handled, `dest` refers // to the destination for the request - event GetRequestTimeoutHandled(bytes32 commitment, bytes dest); + event GetRequestTimeoutHandled( + // Commitment of the GET request + bytes32 indexed commitment, + // Destination chain for this request + string dest + ); // Emitted when new heights are finalized - event StateMachineUpdated(bytes stateMachineId, uint256 height); + event StateMachineUpdated( + // The state machine that was just updated + string stateMachineId, + // The newly updated height + uint256 height + ); // Emitted when a state commitment is vetoed by a fisherman event StateCommitmentVetoed( - bytes stateMachineId, uint256 height, StateCommitment stateCommitment, address fisherman + // The state machine identifier for the vetoed state commitment + string stateMachineId, + // The height that was vetoed + uint256 height, + // The state commitment that was vetoed + StateCommitment stateCommitment, + // The fisherman responsible for the veto + address indexed fisherman ); // Emitted when a new POST request is dispatched event PostRequestEvent( - bytes source, - bytes dest, - bytes from, + // Source of this request, included for convenience sake + string source, + // The destination chain for this request + string dest, + // The contract that initiated this request + address indexed from, + // The intended recipient module of this request bytes to, - uint256 indexed nonce, + // Monotonically increasing nonce + uint256 nonce, + // The timestamp at which this request will be considered as timed out uint256 timeoutTimestamp, - bytes data, + // The serialized request body + bytes body, + // The associated relayer fee uint256 fee ); // Emitted when a new POST response is dispatched event PostResponseEvent( - bytes source, - bytes dest, - bytes from, + // Source of this response, included for convenience sake + string source, + // The destination chain for this response + string dest, + // The contract that initiated this response + address indexed from, + // The intended recipient module of this response bytes to, - uint256 indexed nonce, + // Monotonically increasing nonce + uint256 nonce, + // The timestamp at which this request will be considered as timed out uint256 timeoutTimestamp, - bytes data, + // The serialized request body + bytes body, + // The serialized response body bytes response, - uint256 resTimeoutTimestamp, + // The timestamp at which this response will be considered as timed out + uint256 responseTimeoutTimestamp, + // The associated relayer fee uint256 fee ); // Emitted when a new GET request is dispatched event GetRequestEvent( - bytes source, - bytes dest, - bytes from, + // Source of this response, included for convenience sake + string source, + // The destination chain for this response + string dest, + // The contract that initiated this response + address indexed from, + // The requested storage keys bytes[] keys, - uint256 indexed nonce, + // The height for the requested keys uint256 height, + // Monotonically increasing nonce + uint256 nonce, + // The timestamp at which this response will be considered as timed out uint256 timeoutTimestamp ); // Emitted when a POST or GET request is funded - event RequestFunded(bytes32 commitment, uint256 newFee); + event RequestFunded( + // Commitment of the request + bytes32 commitment, + // The updated fee available for relayers + uint256 newFee + ); // Emitted when a POST response is funded - event PostResponseFunded(bytes32 commitment, uint256 newFee); + event PostResponseFunded( + // Commitment of the response + bytes32 commitment, + // The updated fee available for relayers + uint256 newFee + ); // Emitted when the host has either been frozen or unfrozen event HostFrozen(bool frozen); // Emitted when the host params is updated - event HostParamsUpdated(HostParams oldParams, HostParams newParams); + event HostParamsUpdated( + // The old host parameters + HostParams oldParams, + // The new host parameters + HostParams newParams + ); // Emitted when the host processes a withdrawal - event HostWithdrawal(uint256 amount, address beneficiary); + event HostWithdrawal( + // Amount that was withdrawn from the host's feeToken balance + uint256 amount, + // The beneficiary address for this withdrawal + address beneficiary + ); // Account is unauthorized to perform requested action error UnauthorizedAccount(); @@ -302,14 +392,14 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { function chainId() public virtual returns (uint256); /** - * @return the address of the fee token ERC-20 contract on this state machine + * @return the address of the ERC-20 fee token contract on this state machine */ function feeToken() public view returns (address) { return _hostParams.feeToken; } /** - * @return the per-byte fee for outgoing requests. + * @return the per-byte fee for outgoing requests/responses. */ function perByteFee() external view returns (uint256) { return _hostParams.perByteFee; @@ -447,9 +537,7 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { * @param params, the new host params. Can only be called by admin on testnets. */ function setHostParamsAdmin(HostParams memory params) public restrict(_hostParams.admin) { - if (chainId() == block.chainid) { - revert UnauthorizedAction(); - } + if (chainId() == block.chainid) revert UnauthorizedAction(); uint256 whitelistLength = params.stateMachines.length; for (uint256 i = 0; i < whitelistLength; ++i) { @@ -459,10 +547,10 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { } /** - * @dev Updates the HostParams + * @dev Updates the HostParams. Will reset all fishermen accounts and initialize any new state machines. * @param params, the new host params. */ - function updateHostParamsInternal(HostParams memory params) private { + function updateHostParamsInternal(HostParams memory params) internal { // check if the provided host manager is a contract if (params.hostManager == address(0) || address(params.hostManager).code.length == 0) { revert InvalidHostManagerAddress(); @@ -470,11 +558,9 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // we can only have a maximum of 100 fishermen uint256 newFishermenLength = params.fishermen.length; - if (newFishermenLength > 100) { - revert MaxFishermanCountExceeded(newFishermenLength); - } + if (newFishermenLength > 100) revert MaxFishermanCountExceeded(newFishermenLength); - // delete old fishermen + // reset old fishermen uint256 fishermenLength = _hostParams.fishermen.length; for (uint256 i = 0; i < fishermenLength; ++i) { delete _fishermen[_hostParams.fishermen[i]]; @@ -519,12 +605,13 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { } /** - * @dev Store the state commitment at given state height alongside relevant metadata. Assumes the state commitment is of the latest height. + * @dev Store the state commitment at given state height alongside relevant metadata. + * Assumes the state commitment is of the latest height. */ - function storeStateMachineCommitment(StateMachineHeight memory height, StateCommitment memory commitment) - external - restrict(_hostParams.handler) - { + function storeStateMachineCommitment( + StateMachineHeight memory height, + StateCommitment memory commitment + ) external restrict(_hostParams.handler) { _stateCommitments[height.stateMachineId][height.height] = commitment; _stateCommitmentsUpdateTime[height.stateMachineId][height.height] = block.timestamp; _latestStateMachineHeight[height.stateMachineId] = height.height; @@ -535,10 +622,10 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { /** * @dev Delete the state commitment at given state height. */ - function deleteStateMachineCommitment(StateMachineHeight memory height, address fisherman) - external - restrict(_hostParams.handler) - { + function deleteStateMachineCommitment( + StateMachineHeight memory height, + address fisherman + ) external restrict(_hostParams.handler) { deleteStateMachineCommitmentInternal(height, fisherman); } @@ -556,7 +643,7 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { /** * @dev Delete the state commitment at given state height. */ - function deleteStateMachineCommitmentInternal(StateMachineHeight memory height, address fisherman) private { + function deleteStateMachineCommitmentInternal(StateMachineHeight memory height, address fisherman) internal { StateCommitment memory stateCommitment = _stateCommitments[height.stateMachineId][height.height]; delete _stateCommitments[height.stateMachineId][height.height]; delete _stateCommitmentsUpdateTime[height.stateMachineId][height.height]; @@ -579,10 +666,10 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { /** * @dev Get the state machine id for a parachain */ - function stateMachineId(uint256 id) public view returns (bytes memory) { + function stateMachineId(uint256 id) public view returns (string memory) { bytes memory hyperbridgeId = _hostParams.hyperbridge; uint256 offset = hyperbridgeId.length - 4; - return bytes.concat(hyperbridgeId.substr(0, offset), bytes(Strings.toString(id))); + return string.concat(string(hyperbridgeId.substr(0, offset)), Strings.toString(id)); } /** @@ -601,10 +688,11 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { * @dev sets the initial consensus state * @param state initial consensus state */ - function setConsensusState(bytes memory state, StateMachineHeight memory height, StateCommitment memory commitment) - public - restrict(_hostParams.admin) - { + function setConsensusState( + bytes memory state, + StateMachineHeight memory height, + StateCommitment memory commitment + ) public restrict(_hostParams.admin) { // if we're on mainnet, then consensus state can only be initialized once // and updated subsequently through consensus proofs require(chainId() == block.chainid ? _consensusState.equals(new bytes(0)) : true, "Unauthorized action"); @@ -636,7 +724,7 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { bytes32 commitment = request.hash(); _requestReceipts[commitment] = relayer; - (bool success,) = address(destination).call( + (bool success, ) = address(destination).call( abi.encodeWithSelector(IIsmpModule.onAccept.selector, IncomingPostRequest(request, relayer)) ); @@ -658,10 +746,12 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // replay protection bytes32 requestCommitment = response.request.hash(); bytes32 responseCommitment = response.hash(); - _responseReceipts[requestCommitment] = - ResponseReceipt({relayer: relayer, responseCommitment: responseCommitment}); + _responseReceipts[requestCommitment] = ResponseReceipt({ + relayer: relayer, + responseCommitment: responseCommitment + }); - (bool success,) = address(origin).call( + (bool success, ) = address(origin).call( abi.encodeWithSelector(IIsmpModule.onPostResponse.selector, IncomingPostResponse(response, relayer)) ); @@ -685,7 +775,7 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // don't commit the full response object, it's unused. _responseReceipts[commitment] = ResponseReceipt({relayer: relayer, responseCommitment: bytes32(0)}); - (bool success,) = address(origin).call( + (bool success, ) = address(origin).call( abi.encodeWithSelector(IIsmpModule.onGetResponse.selector, IncomingGetResponse(response, relayer)) ); @@ -695,22 +785,24 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { return; } - emit PostResponseHandled({commitment: commitment, relayer: relayer}); + emit GetRequestHandled({commitment: commitment, relayer: relayer}); } /** - * @dev Dispatch an incoming GET timeout to the source module + * @dev Dispatch an incoming GET timeout to the source module. + * @notice Does not refund any protocol fees. * @param request - get request */ - function dispatchIncoming(GetRequest memory request, FeeMetadata memory meta, bytes32 commitment) - external - restrict(_hostParams.handler) - { + function dispatchIncoming( + GetRequest memory request, + FeeMetadata memory meta, + bytes32 commitment + ) external restrict(_hostParams.handler) { address origin = _bytesToAddress(request.from); // replay protection, delete memory of this request delete _requestCommitments[commitment]; - (bool success,) = address(origin).call(abi.encodeWithSelector(IIsmpModule.onGetTimeout.selector, request)); + (bool success, ) = address(origin).call(abi.encodeWithSelector(IIsmpModule.onGetTimeout.selector, request)); if (!success) { // so that it can be retried @@ -718,23 +810,25 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { return; } - emit GetRequestTimeoutHandled({commitment: commitment, dest: request.dest}); + emit GetRequestTimeoutHandled({commitment: commitment, dest: string(request.dest)}); } /** * @dev Dispatch an incoming POST timeout to the source module * @param request - post timeout */ - function dispatchIncoming(PostRequest memory request, FeeMetadata memory meta, bytes32 commitment) - external - restrict(_hostParams.handler) - { + function dispatchIncoming( + PostRequest memory request, + FeeMetadata memory meta, + bytes32 commitment + ) external restrict(_hostParams.handler) { address origin = _bytesToAddress(request.from); // replay protection, delete memory of this request delete _requestCommitments[commitment]; - (bool success,) = - address(origin).call(abi.encodeWithSelector(IIsmpModule.onPostRequestTimeout.selector, request)); + (bool success, ) = address(origin).call( + abi.encodeWithSelector(IIsmpModule.onPostRequestTimeout.selector, request) + ); if (!success) { // so that it can be retried @@ -745,25 +839,27 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { if (meta.fee != 0) { SafeERC20.safeTransfer(IERC20(feeToken()), meta.sender, meta.fee); } - emit PostRequestTimeoutHandled({commitment: commitment, dest: request.dest}); + emit PostRequestTimeoutHandled({commitment: commitment, dest: string(request.dest)}); } /** * @dev Dispatch an incoming POST response timeout to the source module * @param response - timed-out post response */ - function dispatchIncoming(PostResponse memory response, FeeMetadata memory meta, bytes32 commitment) - external - restrict(_hostParams.handler) - { + function dispatchIncoming( + PostResponse memory response, + FeeMetadata memory meta, + bytes32 commitment + ) external restrict(_hostParams.handler) { address origin = _bytesToAddress(response.request.to); // replay protection, delete memory of this response bytes32 reqCommitment = response.request.hash(); delete _responseCommitments[commitment]; delete _responded[reqCommitment]; - (bool success,) = - address(origin).call(abi.encodeWithSelector(IIsmpModule.onPostResponseTimeout.selector, response)); + (bool success, ) = address(origin).call( + abi.encodeWithSelector(IIsmpModule.onPostResponseTimeout.selector, response) + ); if (!success) { // so that it can be retried @@ -776,7 +872,7 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // refund relayer fee SafeERC20.safeTransfer(IERC20(feeToken()), meta.sender, meta.fee); } - emit PostResponseTimeoutHandled({commitment: commitment, dest: response.request.source}); + emit PostResponseTimeoutHandled({commitment: commitment, dest: string(response.request.source)}); } /** @@ -790,7 +886,7 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // adjust the timeout uint64 timeout = post.timeout == 0 ? 0 - : uint64(this.timestamp()) + uint64(Math.max(_hostParams.defaultTimeout, post.timeout)); + : uint64(block.timestamp) + uint64(Math.max(_hostParams.defaultTimeout, post.timeout)); PostRequest memory request = PostRequest({ source: host(), dest: post.dest, @@ -804,16 +900,16 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // make the commitment commitment = request.hash(); _requestCommitments[commitment] = FeeMetadata({sender: post.payer, fee: post.fee}); - emit PostRequestEvent( - request.source, - request.dest, - request.from, - abi.encodePacked(request.to), - request.nonce, - request.timeoutTimestamp, - request.body, - post.fee - ); + emit PostRequestEvent({ + source: string(request.source), + dest: string(request.dest), + from: _msgSender(), + to: abi.encodePacked(request.to), + nonce: request.nonce, + timeoutTimestamp: request.timeoutTimestamp, + body: request.body, + fee: post.fee + }); } /** @@ -826,8 +922,9 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { } // adjust the timeout - uint64 timeout = - get.timeout == 0 ? 0 : uint64(this.timestamp()) + uint64(Math.max(_hostParams.defaultTimeout, get.timeout)); + uint64 timeout = get.timeout == 0 + ? 0 + : uint64(block.timestamp) + uint64(Math.max(_hostParams.defaultTimeout, get.timeout)); GetRequest memory request = GetRequest({ source: host(), @@ -842,15 +939,15 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // make the commitment commitment = request.hash(); _requestCommitments[commitment] = FeeMetadata({sender: get.sender, fee: get.fee}); - emit GetRequestEvent( - request.source, - request.dest, - request.from, - request.keys, - request.nonce, - request.height, - request.timeoutTimestamp - ); + emit GetRequestEvent({ + source: string(request.source), + dest: string(request.dest), + from: _msgSender(), + keys: request.keys, + nonce: request.nonce, + height: request.height, + timeoutTimestamp: request.timeoutTimestamp + }); } /** @@ -859,21 +956,16 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { */ function dispatch(DispatchPostResponse memory post) external returns (bytes32 commitment) { bytes32 receipt = post.request.hash(); + address caller = _msgSender(); // known request? - if (_requestReceipts[receipt] == address(0)) { - revert UnknownRequest(); - } + if (_requestReceipts[receipt] == address(0)) revert UnknownRequest(); // check that the authorized application is issuing this response - if (_bytesToAddress(post.request.to) != _msgSender()) { - revert UnauthorizedResponse(); - } + if (_bytesToAddress(post.request.to) != caller) revert UnauthorizedResponse(); - // check that request has not already been responed to - if (_responded[receipt]) { - revert DuplicateResponse(); - } + // check that request has not already been respond to + if (_responded[receipt]) revert DuplicateResponse(); // collect fees uint256 fee = (_hostParams.perByteFee * post.response.length) + post.fee; @@ -882,28 +974,32 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { // adjust the timeout uint64 timeout = post.timeout == 0 ? 0 - : uint64(this.timestamp()) + uint64(Math.max(_hostParams.defaultTimeout, post.timeout)); + : uint64(block.timestamp) + uint64(Math.max(_hostParams.defaultTimeout, post.timeout)); - PostResponse memory response = - PostResponse({request: post.request, response: post.response, timeoutTimestamp: timeout}); + PostResponse memory response = PostResponse({ + request: post.request, + response: post.response, + timeoutTimestamp: timeout + }); commitment = response.hash(); FeeMetadata memory meta = FeeMetadata({fee: post.fee, sender: post.payer}); _responseCommitments[commitment] = meta; _responded[receipt] = true; - emit PostResponseEvent( - response.request.source, - response.request.dest, - response.request.from, - abi.encodePacked(response.request.to), - response.request.nonce, - response.request.timeoutTimestamp, - response.request.body, - response.response, - response.timeoutTimestamp, - meta.fee // sigh solidity - ); + // note the swapped fields + emit PostResponseEvent({ + source: string(response.request.dest), + dest: string(response.request.source), + from: caller, + to: response.request.from, + nonce: response.request.nonce, + timeoutTimestamp: response.request.timeoutTimestamp, + body: response.request.body, + response: response.response, + responseTimeoutTimestamp: response.timeoutTimestamp, + fee: meta.fee // sigh solidity + }); } /** @@ -917,9 +1013,8 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { function fundRequest(bytes32 commitment, uint256 amount) public { FeeMetadata memory metadata = _requestCommitments[commitment]; - if (metadata.sender == address(0)) { - revert UnknownRequest(); - } + if (metadata.sender == address(0)) revert UnknownRequest(); + SafeERC20.safeTransferFrom(IERC20(feeToken()), _msgSender(), address(this), amount); metadata.fee += amount; @@ -939,9 +1034,8 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { function fundResponse(bytes32 commitment, uint256 amount) public { FeeMetadata memory metadata = _responseCommitments[commitment]; - if (metadata.sender == address(0)) { - revert UnknownResponse(); - } + if (metadata.sender == address(0)) revert UnknownResponse(); + SafeERC20.safeTransferFrom(IERC20(feeToken()), _msgSender(), address(this), amount); metadata.fee += amount; @@ -953,7 +1047,7 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { /** * @dev Get next available nonce for outgoing requests. */ - function _nextNonce() private returns (uint256) { + function _nextNonce() internal returns (uint256) { uint256 _nonce_copy = _nonce; unchecked { @@ -968,10 +1062,9 @@ abstract contract EvmHost is IIsmpHost, IHostManager, Context { * @param _bytes bytes value to be converted * @return addr returns the address */ - function _bytesToAddress(bytes memory _bytes) private pure returns (address addr) { - if (_bytes.length != 20) { - revert InvalidAddressLength(); - } + function _bytesToAddress(bytes memory _bytes) internal pure returns (address addr) { + if (_bytes.length != 20) revert InvalidAddressLength(); + assembly { addr := mload(add(_bytes, 20)) } diff --git a/evm/src/hosts/Optimism.sol b/evm/src/hosts/Optimism.sol index 60f447453..a8b43bcd6 100644 --- a/evm/src/hosts/Optimism.sol +++ b/evm/src/hosts/Optimism.sol @@ -17,6 +17,13 @@ pragma solidity 0.8.17; import "./EvmHost.sol"; import "ismp/StateMachine.sol"; +/** + * @title The OptimismHost + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The IsmpHost and IsmpDispatcher implementation for the Optimism state machine. + * Refer to the official ISMP specification. https://docs.hyperbridge.network/protocol/ismp + */ contract OptimismHost is EvmHost { constructor(HostParams memory params) EvmHost(params) {} diff --git a/evm/src/hosts/Polygon.sol b/evm/src/hosts/Polygon.sol index 290eff70c..4650334ae 100644 --- a/evm/src/hosts/Polygon.sol +++ b/evm/src/hosts/Polygon.sol @@ -17,6 +17,13 @@ pragma solidity 0.8.17; import "./EvmHost.sol"; import "ismp/StateMachine.sol"; +/** + * @title The PolygonHost + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The IsmpHost and IsmpDispatcher implementation for the Polygon state machine. + * Refer to the official ISMP specification. https://docs.hyperbridge.network/protocol/ismp + */ contract PolygonHost is EvmHost { constructor(HostParams memory params) EvmHost(params) {} diff --git a/evm/src/interfaces/IUniswapV2Router.sol b/evm/src/interfaces/IUniswapV2Router.sol index 8acfa0ec0..53bfc2a59 100644 --- a/evm/src/interfaces/IUniswapV2Router.sol +++ b/evm/src/interfaces/IUniswapV2Router.sol @@ -78,10 +78,12 @@ interface IUniswapV2Router { address to, uint256 deadline ) external returns (uint256[] memory amounts); - function swapExactETHForTokens(uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) - external - payable - returns (uint256[] memory amounts); + function swapExactETHForTokens( + uint256 amountOutMin, + address[] calldata path, + address to, + uint256 deadline + ) external payable returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, @@ -96,28 +98,26 @@ interface IUniswapV2Router { address to, uint256 deadline ) external returns (uint256[] memory amounts); - function swapETHForExactTokens(uint256 amountOut, address[] calldata path, address to, uint256 deadline) - external - payable - returns (uint256[] memory amounts); + function swapETHForExactTokens( + uint256 amountOut, + address[] calldata path, + address to, + uint256 deadline + ) external payable returns (uint256[] memory amounts); function quote(uint256 amountA, uint256 reserveA, uint256 reserveB) external pure returns (uint256 amountB); - function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut) - external - pure - returns (uint256 amountOut); - function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut) - external - pure - returns (uint256 amountIn); - function getAmountsOut(uint256 amountIn, address[] calldata path) - external - view - returns (uint256[] memory amounts); - function getAmountsIn(uint256 amountOut, address[] calldata path) - external - view - returns (uint256[] memory amounts); + function getAmountOut( + uint256 amountIn, + uint256 reserveIn, + uint256 reserveOut + ) external pure returns (uint256 amountOut); + function getAmountIn( + uint256 amountOut, + uint256 reserveIn, + uint256 reserveOut + ) external pure returns (uint256 amountIn); + function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); + function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); function removeLiquidityETHSupportingFeeOnTransferTokens( address token, diff --git a/evm/src/modules/CallDispatcher.sol b/evm/src/modules/CallDispatcher.sol index fa0fcd7e4..a2612307e 100644 --- a/evm/src/modules/CallDispatcher.sol +++ b/evm/src/modules/CallDispatcher.sol @@ -16,9 +16,14 @@ pragma solidity 0.8.17; import {ICallDispatcher, CallDispatcherParams} from "../interfaces/ICallDispatcher.sol"; -/// @notice This contract is used to dispatch calls to other contracts. +/** + * @title The CallDispatcher + * @author Polytope Labs (hello@polytope.technology) + * + * @notice This contract is used to dispatch calls to other contracts. + */ contract CallDispatcher is ICallDispatcher { - /// @dev funtion returns `success = false` if the target is not a contract and reverts if the call to the target contract fails. + // @dev function returns `success = false` if the target is not a contract and reverts if the call to the target contract fails. function dispatch(CallDispatcherParams memory params) external returns (bytes memory result, bool success) { uint32 size; address target = params.target; @@ -27,6 +32,7 @@ contract CallDispatcher is ICallDispatcher { } if (size > 0) { + // unchecked call, this is safe because this contract does not control any funds (success, result) = target.call(params.data); if (!success) revert(string(result)); return (result, success); diff --git a/evm/src/modules/HandlerV1.sol b/evm/src/modules/HandlerV1.sol index 612327788..952ba9161 100644 --- a/evm/src/modules/HandlerV1.sol +++ b/evm/src/modules/HandlerV1.sol @@ -36,19 +36,22 @@ import { // Storage prefix for request receipts in the pallet-ismp child trie bytes constant REQUEST_RECEIPTS_STORAGE_PREFIX = hex"526571756573745265636569707473"; -// Storage prefix for request receipts in the pallet-ismp child trie +// Storage prefix for response receipts in the pallet-ismp child trie bytes constant RESPONSE_RECEIPTS_STORAGE_PREFIX = hex"526573706f6e73655265636569707473"; /** - * @title The ISMP Message Handler. Responsible for verifying the cryptographic proofs - * needed to confirm the validity of incoming requests/responses. + * @title The ISMP Message Handler. + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The Handler is responsible for verifying the cryptographic proofs needed + * to confirm the validity of incoming requests/responses. + * Refer to the official ISMP specification. https://docs.hyperbridge.network/protocol/ismp */ contract HandlerV1 is IHandler, Context { using Bytes for bytes; using Message for PostResponse; using Message for PostRequest; using Message for GetRequest; - // using Message for GetResponse; // The cosensus client has now expired to mitigate // long fork attacks, this is unrecoverable. @@ -96,19 +99,19 @@ contract HandlerV1 is IHandler, Context { function handleConsensus(IIsmpHost host, bytes calldata proof) external notFrozen(host) { uint256 delay = block.timestamp - host.consensusUpdateTime(); - if (delay >= host.unStakingPeriod()) { - revert ConsensusClientExpired(); - } + if (delay >= host.unStakingPeriod()) revert ConsensusClientExpired(); - (bytes memory verifiedState, IntermediateState memory intermediate) = - IConsensusClient(host.consensusClient()).verifyConsensus(host.consensusState(), proof); + (bytes memory verifiedState, IntermediateState memory intermediate) = IConsensusClient(host.consensusClient()) + .verifyConsensus(host.consensusState(), proof); host.storeConsensusState(verifiedState); // check that we know this state machine and it's a new update uint256 latestHeight = host.latestStateMachineHeight(intermediate.stateMachineId); if (latestHeight != 0 && intermediate.height > latestHeight) { - StateMachineHeight memory stateMachineHeight = - StateMachineHeight({stateMachineId: intermediate.stateMachineId, height: intermediate.height}); + StateMachineHeight memory stateMachineHeight = StateMachineHeight({ + stateMachineId: intermediate.stateMachineId, + height: intermediate.height + }); host.storeStateMachineCommitment(stateMachineHeight, intermediate.commitment); } } @@ -122,9 +125,7 @@ contract HandlerV1 is IHandler, Context { uint256 timestamp = block.timestamp; uint256 delay = timestamp - host.stateMachineCommitmentUpdateTime(request.proof.height); uint256 challengePeriod = host.challengePeriod(); - if (challengePeriod != 0 && challengePeriod > delay) { - revert ChallengePeriodNotElapsed(); - } + if (challengePeriod != 0 && challengePeriod > delay) revert ChallengePeriodNotElapsed(); uint256 requestsLen = request.requests.length; MmrLeaf[] memory leaves = new MmrLeaf[](requestsLen); @@ -132,26 +133,18 @@ contract HandlerV1 is IHandler, Context { for (uint256 i = 0; i < requestsLen; ++i) { PostRequestLeaf memory leaf = request.requests[i]; // check destination - if (!leaf.request.dest.equals(host.host())) { - revert InvalidMessageDestination(); - } + if (!leaf.request.dest.equals(host.host())) revert InvalidMessageDestination(); // check time-out - if (timestamp > leaf.request.timeout()) { - revert MessageTimedOut(); - } + if (timestamp >= leaf.request.timeout()) revert MessageTimedOut(); // duplicate request? bytes32 commitment = leaf.request.hash(); - if (host.requestReceipts(commitment) != address(0)) { - revert DuplicateMessage(); - } + if (host.requestReceipts(commitment) != address(0)) revert DuplicateMessage(); leaves[i] = MmrLeaf(leaf.kIndex, leaf.index, commitment); } bytes32 root = host.stateMachineCommitment(request.proof.height).overlayRoot; - if (root == bytes32(0)) { - revert StateCommitmentNotFound(); - } + if (root == bytes32(0)) revert StateCommitmentNotFound(); if (!MerkleMountainRange.VerifyProof(root, request.proof.multiproof, leaves, request.proof.leafCount)) { revert InvalidProof(); } @@ -172,9 +165,7 @@ contract HandlerV1 is IHandler, Context { uint256 delay = timestamp - host.stateMachineCommitmentUpdateTime(response.proof.height); uint256 challengePeriod = host.challengePeriod(); - if (challengePeriod != 0 && challengePeriod > delay) { - revert ChallengePeriodNotElapsed(); - } + if (challengePeriod != 0 && challengePeriod > delay) revert ChallengePeriodNotElapsed(); uint256 responsesLength = response.responses.length; MmrLeaf[] memory leaves = new MmrLeaf[](responsesLength); @@ -182,27 +173,19 @@ contract HandlerV1 is IHandler, Context { for (uint256 i = 0; i < responsesLength; ++i) { PostResponseLeaf memory leaf = response.responses[i]; // check time-out - if (timestamp > leaf.response.timeout()) { - revert MessageTimedOut(); - } + if (timestamp >= leaf.response.timeout()) revert MessageTimedOut(); // known request? also serves as a source check bytes32 requestCommitment = leaf.response.request.hash(); FeeMetadata memory meta = host.requestCommitments(requestCommitment); - if (meta.sender == address(0)) { - revert InvalidProof(); - } + if (meta.sender == address(0)) revert InvalidProof(); // duplicate response? - if (host.responseReceipts(leaf.response.hash()).relayer != address(0)) { - revert DuplicateMessage(); - } + if (host.responseReceipts(leaf.response.hash()).relayer != address(0)) revert DuplicateMessage(); leaves[i] = MmrLeaf(leaf.kIndex, leaf.index, leaf.response.hash()); } bytes32 root = host.stateMachineCommitment(response.proof.height).overlayRoot; - if (root == bytes32(0)) { - revert StateCommitmentNotFound(); - } + if (root == bytes32(0)) revert StateCommitmentNotFound(); if (!MerkleMountainRange.VerifyProof(root, response.proof.multiproof, leaves, response.proof.leafCount)) { revert InvalidProof(); } @@ -218,29 +201,23 @@ contract HandlerV1 is IHandler, Context { * @param host - IsmpHost * @param message - batch post request timeouts */ - function handlePostRequestTimeouts(IIsmpHost host, PostRequestTimeoutMessage calldata message) - external - notFrozen(host) - { + function handlePostRequestTimeouts( + IIsmpHost host, + PostRequestTimeoutMessage calldata message + ) external notFrozen(host) { uint256 delay = block.timestamp - host.stateMachineCommitmentUpdateTime(message.height); uint256 challengePeriod = host.challengePeriod(); - if (challengePeriod != 0 && challengePeriod > delay) { - revert ChallengePeriodNotElapsed(); - } + if (challengePeriod != 0 && challengePeriod > delay) revert ChallengePeriodNotElapsed(); // fetch the state commitment StateCommitment memory state = host.stateMachineCommitment(message.height); - if (state.stateRoot == bytes32(0)) { - revert StateCommitmentNotFound(); - } + if (state.stateRoot == bytes32(0)) revert StateCommitmentNotFound(); uint256 timeoutsLength = message.timeouts.length; for (uint256 i = 0; i < timeoutsLength; ++i) { PostRequest memory request = message.timeouts[i]; // timed-out? - if (request.timeout() > state.timestamp) { - revert MessageNotTimedOut(); - } + if (request.timeout() > state.timestamp) revert MessageNotTimedOut(); // known request? also serves as source check bytes32 requestCommitment = request.hash(); @@ -252,9 +229,7 @@ contract HandlerV1 is IHandler, Context { // verify state trie non-membership proofs StorageValue memory entry = MerklePatricia.VerifySubstrateProof(state.stateRoot, message.proof, keys)[0]; - if (entry.value.length != 0) { - revert InvalidProof(); - } + if (entry.value.length != 0) revert InvalidProof(); host.dispatchIncoming(request, meta, requestCommitment); } @@ -265,45 +240,35 @@ contract HandlerV1 is IHandler, Context { * @param host - Ismp host * @param message - batch post response timeouts */ - function handlePostResponseTimeouts(IIsmpHost host, PostResponseTimeoutMessage calldata message) - external - notFrozen(host) - { + function handlePostResponseTimeouts( + IIsmpHost host, + PostResponseTimeoutMessage calldata message + ) external notFrozen(host) { uint256 delay = block.timestamp - host.stateMachineCommitmentUpdateTime(message.height); uint256 challengePeriod = host.challengePeriod(); - if (challengePeriod != 0 && challengePeriod > delay) { - revert ChallengePeriodNotElapsed(); - } + if (challengePeriod != 0 && challengePeriod > delay) revert ChallengePeriodNotElapsed(); // fetch the state commitment StateCommitment memory state = host.stateMachineCommitment(message.height); - if (state.stateRoot == bytes32(0)) { - revert StateCommitmentNotFound(); - } + if (state.stateRoot == bytes32(0)) revert StateCommitmentNotFound(); uint256 timeoutsLength = message.timeouts.length; for (uint256 i = 0; i < timeoutsLength; ++i) { PostResponse memory response = message.timeouts[i]; // timed-out? - if (response.timeout() > state.timestamp) { - revert MessageNotTimedOut(); - } + if (response.timeout() > state.timestamp) revert MessageNotTimedOut(); // known response? also serves as source check bytes32 responseCommitment = response.hash(); FeeMetadata memory meta = host.responseCommitments(responseCommitment); - if (meta.sender == address(0)) { - revert UnknownMessage(); - } + if (meta.sender == address(0)) revert UnknownMessage(); bytes[] memory keys = new bytes[](1); keys[i] = bytes.concat(RESPONSE_RECEIPTS_STORAGE_PREFIX, bytes.concat(responseCommitment)); // verify state trie non-membership proofs StorageValue memory entry = MerklePatricia.VerifySubstrateProof(state.stateRoot, message.proof, keys)[0]; - if (entry.value.length != 0) { - revert InvalidProof(); - } + if (entry.value.length != 0) revert InvalidProof(); host.dispatchIncoming(response, meta, responseCommitment); } @@ -318,14 +283,10 @@ contract HandlerV1 is IHandler, Context { uint256 timestamp = block.timestamp; uint256 delay = timestamp - host.stateMachineCommitmentUpdateTime(message.height); uint256 challengePeriod = host.challengePeriod(); - if (challengePeriod != 0 && challengePeriod > delay) { - revert ChallengePeriodNotElapsed(); - } + if (challengePeriod != 0 && challengePeriod > delay) revert ChallengePeriodNotElapsed(); bytes32 root = host.stateMachineCommitment(message.height).stateRoot; - if (root == bytes32(0)) { - revert StateCommitmentNotFound(); - } + if (root == bytes32(0)) revert StateCommitmentNotFound(); uint256 responsesLength = message.requests.length; bytes[] memory proof = message.proof; @@ -333,23 +294,21 @@ contract HandlerV1 is IHandler, Context { for (uint256 i = 0; i < responsesLength; ++i) { GetRequest memory request = message.requests[i]; // timed-out? - if (timestamp > request.timeout()) { - revert MessageTimedOut(); - } + if (timestamp >= request.timeout()) revert MessageTimedOut(); // known request? also serves as source check bytes32 requestCommitment = request.hash(); FeeMetadata memory meta = host.requestCommitments(requestCommitment); - if (meta.sender == address(0)) { - revert UnknownMessage(); - } + if (meta.sender == address(0)) revert UnknownMessage(); // duplicate response? - if (host.responseReceipts(requestCommitment).relayer != address(0)) { - revert DuplicateMessage(); - } - StorageValue[] memory values = - MerklePatricia.ReadChildProofCheck(root, proof, request.keys, bytes.concat(requestCommitment)); + if (host.responseReceipts(requestCommitment).relayer != address(0)) revert DuplicateMessage(); + StorageValue[] memory values = MerklePatricia.ReadChildProofCheck( + root, + proof, + request.keys, + bytes.concat(requestCommitment) + ); GetResponse memory response = GetResponse({request: request, values: values}); host.dispatchIncoming(response, _msgSender()); @@ -369,13 +328,9 @@ contract HandlerV1 is IHandler, Context { GetRequest memory request = message.timeouts[i]; bytes32 requestCommitment = request.hash(); FeeMetadata memory meta = host.requestCommitments(requestCommitment); - if (meta.sender == address(0)) { - revert InvalidProof(); - } + if (meta.sender == address(0)) revert InvalidProof(); - if (request.timeout() > timestamp) { - revert MessageNotTimedOut(); - } + if (request.timeout() > timestamp) revert MessageNotTimedOut(); host.dispatchIncoming(request, meta, requestCommitment); } } diff --git a/evm/src/modules/HostManager.sol b/evm/src/modules/HostManager.sol index b97731986..5b855df1a 100644 --- a/evm/src/modules/HostManager.sol +++ b/evm/src/modules/HostManager.sol @@ -31,7 +31,10 @@ struct HostManagerParams { } /** - * @title The ISMP Host Manager. Allows cross-chain governance actions + * @title The ISMP HostManager. + * @author Polytope Labs (hello@polytope.technology) + * + * @notice Allows cross-chain governance actions * for updating the ISMP Host parameters or withdrawing bridge revenue. */ contract HostManager is BaseIsmpModule { diff --git a/evm/src/modules/Registrar.sol b/evm/src/modules/Registrar.sol index a86b4ccce..056cff668 100644 --- a/evm/src/modules/Registrar.sol +++ b/evm/src/modules/Registrar.sol @@ -52,8 +52,11 @@ struct RegistrarParams { } /** - * @title The Token Registrar. Serves as a form of gas abstraction for token - * registration. By collecting fees on any chain and permitting token creation on the + * @title The TokenRegistrar. + * @author Polytope Labs (hello@polytope.technology) + * + * @notice Serves as a form of gas abstraction for token registration. + * By collecting fees on any chain and permitting token creation on the * Hyperbridge chain. */ contract TokenRegistrar is BaseIsmpModule { @@ -70,13 +73,13 @@ contract TokenRegistrar is BaseIsmpModule { // Requested action is unauthorized error UnauthorizedAction(); - // A user has initiated the asset registration process + // @notice A user has initiated the asset registration process event RegistrationBegun(bytes32 indexed assetId, address indexed owner); - // Governance has updated the registrar parameters + // @notice Governance has updated the registrar parameters event ParamsUpdated(RegistrarParams oldParams, RegistrarParams newParams); - // restricts call to the provided `caller` + // @dev restricts call to the provided `caller` modifier restrict(address caller) { if (msg.sender != caller) revert UnauthorizedAction(); _; @@ -86,22 +89,23 @@ contract TokenRegistrar is BaseIsmpModule { _admin = admin; } + // @notice Initializes the registrar. Can only be called by the admin function init(RegistrarParams memory p) public restrict(_admin) { _params = p; _admin = address(0); } - // Returns the set params + // @notice Returns the set params function params() public view returns (RegistrarParams memory) { return _params; } - // This serves as gas abstraction for registering assets on Hyperbridge + // @notice This serves as gas abstraction for registering assets on Hyperbridge // by collecting fees here. The asset metadata still needs to be provided // on Hyperbridge, but by paying here. It can be provided as an unsigned // extrinsic. // - // Collects the registration fees in any token that can be swapped for the + // @dev Collects the registration fees in any token that can be swapped for the // IIsmpHost.feeToken using the local UniswapV2 router. Any request must be // relayed to Hyperbridge as this module provides no refunds. function registerAsset(AssetRegistration memory registration) public payable { @@ -111,31 +115,43 @@ contract TokenRegistrar is BaseIsmpModule { if (feeToken != registration.feeToken) { if (msg.value != 0) { - (bool sent,) = _params.erc20NativeToken.call{value: msg.value}(""); + (bool sent, ) = _params.erc20NativeToken.call{value: msg.value}(""); if (!sent) revert InconsistentState(); registration.feeToken = _params.erc20NativeToken; registration.amountToSwap = msg.value; } else { SafeERC20.safeTransferFrom( - IERC20(registration.feeToken), msg.sender, address(this), registration.amountToSwap + IERC20(registration.feeToken), + msg.sender, + address(this), + registration.amountToSwap ); } - SafeERC20.safeIncreaseAllowance(IERC20(registration.feeToken), _params.uniswapV2, registration.amountToSwap); + SafeERC20.safeIncreaseAllowance( + IERC20(registration.feeToken), + _params.uniswapV2, + registration.amountToSwap + ); address[] memory path = new address[](2); path[0] = registration.feeToken; path[1] = feeToken; IUniswapV2Router(_params.uniswapV2).swapTokensForExactTokens( - fee, registration.amountToSwap, path, address(this), block.timestamp + fee, + registration.amountToSwap, + path, + address(this), + block.timestamp ); SafeERC20.safeTransfer(IERC20(feeToken), _params.host, _params.baseFee); } else { SafeERC20.safeTransferFrom(IERC20(feeToken), msg.sender, _params.host, _params.baseFee); SafeERC20.safeTransferFrom(IERC20(feeToken), msg.sender, address(this), messagingFee); } - bytes memory data = - abi.encode(RequestBody({owner: msg.sender, assetId: registration.assetId, baseFee: _params.baseFee})); + bytes memory data = abi.encode( + RequestBody({owner: msg.sender, assetId: registration.assetId, baseFee: _params.baseFee}) + ); // approve the host with the exact amount SafeERC20.safeIncreaseAllowance(IERC20(feeToken), _params.host, fee); @@ -152,7 +168,7 @@ contract TokenRegistrar is BaseIsmpModule { emit RegistrationBegun({assetId: registration.assetId, owner: msg.sender}); } - // Governance parameter updates + // @notice Governance parameter updates function onAccept(IncomingPostRequest calldata incoming) external override restrict(_params.host) { // only hyperbridge can do this if (!incoming.request.source.equals(IIsmpHost(_params.host).hyperbridge())) revert UnauthorizedAction(); diff --git a/evm/src/modules/TokenFaucet.sol b/evm/src/modules/TokenFaucet.sol index b21ef4867..b37b70089 100644 --- a/evm/src/modules/TokenFaucet.sol +++ b/evm/src/modules/TokenFaucet.sol @@ -16,17 +16,17 @@ pragma solidity 0.8.17; import {IERC6160Ext20} from "ERC6160/interfaces/IERC6160Ext20.sol"; -/// Allows access to a fixed amount of tokens to users on a daily basis +/** + * @title The TokenFaucet. + * @author Polytope Labs (hello@polytope.technology) + * + * @notice Allows access to a fixed amount of tokens to users on a daily basis + */ contract TokenFaucet { mapping(address => uint256) private consumers; - address private token; - constructor(address _token) { - token = _token; - } - - /// Will only drip tokens, once per day - function drip() public { + // @dev Will only drip tokens, once per day + function drip(address token) public { uint256 lastDrip = consumers[msg.sender]; uint256 delay = block.timestamp - lastDrip; diff --git a/evm/src/modules/TokenGateway.sol b/evm/src/modules/TokenGateway.sol index 4986edb38..f005ee9d3 100644 --- a/evm/src/modules/TokenGateway.sol +++ b/evm/src/modules/TokenGateway.sol @@ -14,7 +14,7 @@ // limitations under the License. pragma solidity 0.8.17; -import {IDispatcher, DispatchPost} from "ismp/IDispatcher.sol"; +import {DispatchPost} from "ismp/IDispatcher.sol"; import {IIsmpHost} from "ismp/IIsmpHost.sol"; import {Message} from "ismp/Message.sol"; import {StateMachine} from "ismp/StateMachine.sol"; @@ -101,6 +101,13 @@ struct Asset { bytes32 identifier; } +struct ContractInstance { + // The state machine identifier for this chain + bytes chain; + // The token gateway contract address on this chain + address moduleId; +} + enum OnAcceptActions { // Incoming asset from a chain IncomingAsset, @@ -111,7 +118,9 @@ enum OnAcceptActions { // Remove an asset from the registry DeregisterAsset, // Change the admin of an asset - ChangeAssetAdmin + ChangeAssetAdmin, + // Add a new pre-approved address + NewContractInstance } struct AssetMetadata { @@ -161,12 +170,13 @@ struct LiquidityBid { uint256 fee; } - /** - * @title The TokenGateway. Allows users send either ERC20 or ERC6160 tokens - * using Hyperbridge as a message-passing layer. + * @title The TokenGateway. + * @author Polytope Labs (hello@polytope.technology) + * + * @notice Allows users send either ERC20 or ERC6160 tokens using Hyperbridge as a message-passing layer. * - * If ERC20 tokens are sent then fillers step in to provide the ERC20 token on the destination chain. + * @dev If ERC20 tokens are sent then fillers step in to provide the ERC20 token on the destination chain. * Otherwise if ERC6160 tokens are sent, then it simply performs a burn-and-mint. */ contract TokenGateway is BaseIsmpModule { @@ -188,27 +198,82 @@ contract TokenGateway is BaseIsmpModule { // mapping of a request commitment to a corresponding bid mapping(bytes32 => LiquidityBid) private _bids; + // mapping of keccak256(source chain) to the token gateway contract address + mapping(bytes32 => address) private _instances; + // A filler has just placed a bid to fulfil some request - event BidPlaced(bytes32 commitment, bytes32 indexed assetId, uint256 bid, address indexed bidder); + event BidPlaced( + // The associated request commitment + bytes32 commitment, + // The liquidity fee for the bid + uint256 bid, + // The assetId for the bid + bytes32 indexed assetId, + // The bidder's address + address indexed bidder + ); // The request associated with a bid has timed out and the bid refunded - event BidRefunded(bytes32 commitment, bytes32 indexed assetId, address indexed bidder); + event BidRefunded( + // The associated request commitment + bytes32 commitment, + // The assetId for the bid + bytes32 indexed assetId, + // The bidder's address + address indexed bidder + ); // Filler fulfilled some liquidity request - event RequestFulfilled(address indexed bidder, uint256 amount, bytes32 indexed assetId); + event RequestFulfilled( + // The amount that was provided to the user + uint256 amount, + // The bidder's address + address indexed bidder, + // The provided assetId + bytes32 indexed assetId + ); // User has received some assets event AssetReceived( - bytes32 commitment, bytes32 indexed from, address indexed beneficiary, uint256 amount, bytes32 indexed assetId + // The amount that was provided to the user + uint256 amount, + // The associated request commitment + bytes32 commitment, + // The source of the funds + bytes32 indexed from, + // The beneficiary of the funds + address indexed beneficiary, + // The provided assetId + bytes32 indexed assetId ); // User has sent some assets event AssetTeleported( - bytes32 commitment, address indexed from, bytes32 to, uint256 amount, bytes32 indexed assetId, bool redeem + // The beneficiary of the funds + bytes32 to, + // The amount that was requested to be sent + uint256 amount, + // The associated request commitment + bytes32 commitment, + // The source of the funds + address indexed from, + // The provided assetId + bytes32 indexed assetId, + // Flag to redeem funds from the TokenGateway + bool redeem ); // User assets could not be delivered and have been refunded. - event AssetRefunded(bytes32 commitment, address indexed beneficiary, uint256 amount, bytes32 indexed assetId); + event AssetRefunded( + // The amount that was requested to be sent + uint256 amount, + // The associated request commitment + bytes32 commitment, + // The beneficiary of the funds + address indexed beneficiary, + // The provided assetId + bytes32 indexed assetId + ); // A new asset has been registered event AssetRegistered( @@ -228,21 +293,36 @@ contract TokenGateway is BaseIsmpModule { address beneficiary ); + // A new contract instance has been registered + event NewContractInstance( + // The chain for this new contract instance + string chain, + // The address for token gateway on this chain + address moduleId + ); + // Contract parameters have been updated by Hyperbridge governance - event ParamsUpdated(TokenGatewayParams oldParams, TokenGatewayParams newParams); + event ParamsUpdated( + // The old token gateway params + TokenGatewayParams oldParams, + // The new token gateway params + TokenGatewayParams newParams + ); // An asset has been deregistered event AssetRemoved(bytes32 assetId); // An asset owner has requested to change the admin of their asset - event AssetAdminChanged(address asset, address newAdmin); + event AssetAdminChanged( + // The ERC6160 token contract address + address asset, + // The new admin + address newAdmin + ); // Action is unauthorized error UnauthorizedAction(); - // Request is not intended for this host - error InvalidDestination(); - // Provided request has timed out error RequestTimedOut(); @@ -270,6 +350,9 @@ contract TokenGateway is BaseIsmpModule { // Protocol invariant violated error InconsistentState(); + // Provided address didn't fit address type size + error InvalidAddressLength(); + // restricts call to the provided `caller` modifier restrict(address caller) { if (msg.sender != caller) revert UnauthorizedAction(); @@ -280,40 +363,42 @@ contract TokenGateway is BaseIsmpModule { _admin = admin; } - // initialize required parameters + // @dev initialize required parameters function init(TokenGatewayParamsExt memory teleportParams) public restrict(_admin) { _params = teleportParams.params; createAssets(teleportParams.assets); // infinite approval to save on gas SafeERC20.safeIncreaseAllowance( - IERC20(IIsmpHost(_params.host).feeToken()), teleportParams.params.host, type(uint256).max + IERC20(IIsmpHost(_params.host).feeToken()), + teleportParams.params.host, + type(uint256).max ); // admin can only call this once _admin = address(0); } - // Read the protocol parameters + // @dev Read the protocol parameters function params() external view returns (TokenGatewayParams memory) { return _params; } - // Fetch the address for an ERC20 asset + // @dev Fetch the address for an ERC20 asset function erc20(bytes32 assetId) external view returns (address) { return _erc20s[assetId]; } - // Fetch the address for an ERC6160 asset + // @dev Fetch the address for an ERC6160 asset function erc6160(bytes32 assetId) external view returns (address) { return _erc6160s[assetId]; } - // Teleports a local ERC20/ERC6160 asset to the destination chain. Allows users to pay + // @dev Teleports a local ERC20/ERC6160 asset to the destination chain. Allows users to pay // the Hyperbridge fees in any ERC20 token that can be swapped for the swapped for the // `IIsmpHost.feeToken` using the local UniswapV2 router. // - // If a request times out, users can request a refund permissionlessly through + // @notice If a request times out, users can request a refund permissionlessly through // `HandlerV1.handlePostRequestTimeouts`. function teleport(TeleportParams memory teleportParams) public { if (teleportParams.to == bytes32(0)) revert ZeroAddress(); @@ -360,9 +445,16 @@ contract TokenGateway is BaseIsmpModule { uint256 fee = (IIsmpHost(_params.host).perByteFee() * data.length) + teleportParams.relayerFee; // only swap if the feeToken is not the token intended for fee if (feeToken != teleportParams.feeToken) { - SafeERC20.safeTransferFrom(IERC20(teleportParams.feeToken), from, address(this), teleportParams.amountInMax); + SafeERC20.safeTransferFrom( + IERC20(teleportParams.feeToken), + from, + address(this), + teleportParams.amountInMax + ); SafeERC20.safeIncreaseAllowance( - IERC20(teleportParams.feeToken), _params.uniswapV2, teleportParams.amountInMax + IERC20(teleportParams.feeToken), + _params.uniswapV2, + teleportParams.amountInMax ); address[] memory path = new address[](2); @@ -370,7 +462,11 @@ contract TokenGateway is BaseIsmpModule { path[1] = feeToken; IUniswapV2Router(_params.uniswapV2).swapTokensForExactTokens( - fee, teleportParams.amountInMax, path, address(this), block.timestamp + fee, + teleportParams.amountInMax, + path, + address(this), + block.timestamp ); } else { SafeERC20.safeTransferFrom(IERC20(feeToken), from, address(this), fee); @@ -384,7 +480,7 @@ contract TokenGateway is BaseIsmpModule { fee: teleportParams.relayerFee, payer: msg.sender }); - bytes32 commitment = IDispatcher(_params.host).dispatch(request); + bytes32 commitment = IIsmpHost(_params.host).dispatch(request); emit AssetTeleported({ from: from, @@ -396,11 +492,11 @@ contract TokenGateway is BaseIsmpModule { }); } - // Bid to fulfil an incoming asset. This will displace any pre-existing bid + // @dev Bid to fulfil an incoming asset. This will displace any pre-existing bid // if the liquidity fee is lower than said bid. This effectively creates a // race to the bottom for fees. // - // The request must not have expired, and must not have already been fulfilled. + // @notice The request must not have expired, and must not have already been fulfilled. function bid(PostRequest calldata request, uint256 fee) public { // TokenGateway only accepts incoming assets from it's instances on other chains. if (!request.from.equals(abi.encodePacked(address(this)))) revert UnauthorizedAction(); @@ -456,7 +552,7 @@ contract TokenGateway is BaseIsmpModule { emit BidPlaced({commitment: commitment, assetId: body.assetId, bid: fee, bidder: msg.sender}); } - // This allows the bidder to refund their bids in the event that the request timed-out before + // @dev This allows the bidder to refund their bids in the event that the request timed-out before // the bid could be fulfilled. function refundBid(PostRequest calldata request) public { // TokenGateway only accepts incoming assets from it's instances on other chains. @@ -518,11 +614,13 @@ contract TokenGateway is BaseIsmpModule { deregisterAssets(incoming.request); } else if (action == OnAcceptActions.ChangeAssetAdmin) { changeAssetAdmin(incoming.request); + } else if (action == OnAcceptActions.NewContractInstance) { + handleNewContractInstance(incoming.request); } } - // Triggered when a previously sent out request is confirmed to be timed-out by the IsmpHost. - // This means the funds could not be sent, we simply refund the user's assets here. + // @dev Triggered when a previously sent out request is confirmed to be timed-out by the IsmpHost. + // @notice This means the funds could not be sent, we simply refund the user's assets here. function onPostRequestTimeout(PostRequest calldata request) external override restrict(_params.host) { Body memory body; if (request.body.length > BODY_BYTES_SIZE) { @@ -556,7 +654,12 @@ contract TokenGateway is BaseIsmpModule { function handleIncomingAssetWithoutCall(IncomingPostRequest calldata incoming) private { // TokenGateway only accepts incoming assets from it's instances on other chains. - if (!incoming.request.from.equals(abi.encodePacked(address(this)))) revert UnauthorizedAction(); + if (!incoming.request.from.equals(abi.encodePacked(address(this)))) { + // Check if known address + if (_instances[keccak256(incoming.request.source)] != bytesToAddress(incoming.request.from)) { + revert UnauthorizedAction(); + } + } Body memory body = abi.decode(incoming.request.body[1:], (Body)); bytes32 commitment = incoming.request.hash(); @@ -573,7 +676,12 @@ contract TokenGateway is BaseIsmpModule { function handleIncomingAssetWithCall(IncomingPostRequest calldata incoming) private { // TokenGateway only accepts incoming assets from it's instances on other chains. - if (!incoming.request.from.equals(abi.encodePacked(address(this)))) revert UnauthorizedAction(); + if (!incoming.request.from.equals(abi.encodePacked(address(this)))) { + // Check if known address + if (_instances[keccak256(incoming.request.source)] != bytesToAddress(incoming.request.from)) { + revert UnauthorizedAction(); + } + } BodyWithCall memory body = abi.decode(incoming.request.body[1:], (BodyWithCall)); bytes32 commitment = incoming.request.hash(); @@ -675,6 +783,16 @@ contract TokenGateway is BaseIsmpModule { emit AssetAdminChanged({asset: erc6160Address, newAdmin: asset.newAdmin}); } + function handleNewContractInstance(PostRequest calldata request) private { + if (!request.source.equals(IIsmpHost(_params.host).hyperbridge())) revert UnauthorizedAction(); + + ContractInstance memory instance = abi.decode(request.body[1:], (ContractInstance)); + + _instances[keccak256(instance.chain)] = instance.moduleId; + + emit NewContractInstance({chain: string(instance.chain), moduleId: instance.moduleId}); + } + // Creates a new entry for the provided asset in the mappings. If there's no existing // ERC6160 address provided, then a contract for the asset is created. function createAssets(AssetMetadata[] memory assets) private { @@ -715,4 +833,13 @@ contract TokenGateway is BaseIsmpModule { function bytes32ToAddress(bytes32 _bytes) internal pure returns (address) { return address(uint160(uint256(_bytes))); } + + function bytesToAddress(bytes memory _bytes) internal pure returns (address addr) { + if (_bytes.length != 20) { + revert InvalidAddressLength(); + } + assembly { + addr := mload(add(_bytes, 20)) + } + } } diff --git a/evm/test/Beefy.sol b/evm/test/Beefy.sol index 27a266c22..2e21ce60d 100644 --- a/evm/test/Beefy.sol +++ b/evm/test/Beefy.sol @@ -24,7 +24,7 @@ contract BeefyConsensusClientTest is Test { BeefyV1 internal beefy; function setUp() public virtual { - beefy = new BeefyV1(2000); + beefy = new BeefyV1(4009); } function testFieldElementConversion() public pure { diff --git a/evm/test/EvmHostTest.sol b/evm/test/EvmHostTest.sol index 560948b20..fe1c8b955 100644 --- a/evm/test/EvmHostTest.sol +++ b/evm/test/EvmHostTest.sol @@ -218,13 +218,13 @@ contract EvmHostTest is BaseTest { } function testHostStateMachineId() public { - assert(StateMachine.kusama(3000).equals(host.stateMachineId(3000))); + assert(StateMachine.kusama(3000).equals(bytes(host.stateMachineId(3000)))); HostParams memory params = host.hostParams(); params.hyperbridge = StateMachine.polkadot(3367); vm.prank(params.admin); host.setHostParamsAdmin(params); - assert(StateMachine.polkadot(3000).equals(host.stateMachineId(3000))); + assert(StateMachine.polkadot(3000).equals(bytes(host.stateMachineId(3000)))); } } diff --git a/evm/test/TokenGatewayTest.sol b/evm/test/TokenGatewayTest.sol index 7e2089431..a74bde5d1 100644 --- a/evm/test/TokenGatewayTest.sol +++ b/evm/test/TokenGatewayTest.sol @@ -32,6 +32,7 @@ import { CallDispatcherParams, TokenGateway, DeregsiterAsset, + ContractInstance, AssetMetadata } from "../src/modules/TokenGateway.sol"; import {StateMachine} from "ismp/StateMachine.sol"; @@ -650,6 +651,62 @@ contract TokenGatewayTest is BaseTest { vm.expectRevert(NotRoleAdmin.selector); feeToken.changeAdmin(msg.sender); } + + function testCanAddNewContractInstance() public { + // set gateway as the admin + feeToken.changeAdmin(address(gateway)); + + bytes memory chain = bytes("MNTL"); + ContractInstance memory instance = ContractInstance({chain: chain, moduleId: address(this)}); + + bytes memory hyperbridge = host.hyperbridge(); + vm.prank(address(host)); + gateway.onAccept( + IncomingPostRequest({ + request: PostRequest({ + to: abi.encodePacked(address(0)), + from: abi.encodePacked(address(gateway)), + dest: new bytes(0), + body: bytes.concat(hex"05", abi.encode(instance)), + nonce: 0, + source: hyperbridge, + timeoutTimestamp: 0 + }), + relayer: address(0) + }) + ); + + // can now receive assets from new instance + + assert(feeToken.balanceOf(address(this)) == 0); + + Body memory body = Body({ + assetId: keccak256("USD.h"), + to: addressToBytes32(address(this)), + redeem: false, + maxFee: 0, + amount: 1_000 * 1e18, + from: addressToBytes32(address(this)) + }); + + vm.prank(address(host)); + gateway.onAccept( + IncomingPostRequest({ + request: PostRequest({ + to: abi.encodePacked(address(0)), + from: abi.encodePacked(address(this)), + dest: new bytes(0), + body: bytes.concat(hex"00", abi.encode(body)), + nonce: 0, + source: chain, + timeoutTimestamp: 0 + }), + relayer: address(0) + }) + ); + + assert(feeToken.balanceOf(address(this)) == 1_000 * 1e18); + } } function addressToBytes32(address _address) pure returns (bytes32) { diff --git a/evm/test/PlonkTest.sol b/evm/test/UltraPlonkTest.sol similarity index 99% rename from evm/test/PlonkTest.sol rename to evm/test/UltraPlonkTest.sol index 6405db6cf..2d5aa90e2 100644 --- a/evm/test/PlonkTest.sol +++ b/evm/test/UltraPlonkTest.sol @@ -17,9 +17,8 @@ pragma solidity 0.8.17; import "forge-std/Test.sol"; import {KusamaVerifier} from "../src/consensus/verifiers/KusamaVerifier.sol"; import {PolkadotVerifier} from "../src/consensus/verifiers/PolkadotVerifier.sol"; -import {ZkBeefyV1} from "../src/consensus/ZkBeefy.sol"; -contract PlonkTest is Test { +contract UltraPlonkTest is Test { KusamaVerifier internal kusama; PolkadotVerifier internal polkadot; diff --git a/modules/consensus/beefy/prover/src/runtime/paseo.rs b/modules/consensus/beefy/prover/src/runtime/paseo.rs index 6f66b6552..41a1d8dd0 100644 --- a/modules/consensus/beefy/prover/src/runtime/paseo.rs +++ b/modules/consensus/beefy/prover/src/runtime/paseo.rs @@ -526,7 +526,8 @@ pub mod api { pub fn pending_rewards( &self, who: ::subxt::utils::AccountId32, - ) -> ::subxt::runtime_api::Payload { + ) -> ::subxt::runtime_api::Payload + { ::subxt::runtime_api::Payload::new_static( "NominationPoolsApi", "pending_rewards", @@ -2246,7 +2247,8 @@ pub mod api { #[doc = " Get current GRANDPA authority set id."] pub fn current_set_id( &self, - ) -> ::subxt::runtime_api::Payload { + ) -> ::subxt::runtime_api::Payload + { ::subxt::runtime_api::Payload::new_static( "GrandpaApi", "current_set_id", @@ -2683,7 +2685,8 @@ pub mod api { pub fn account_nonce( &self, account: ::subxt::utils::AccountId32, - ) -> ::subxt::runtime_api::Payload { + ) -> ::subxt::runtime_api::Payload + { ::subxt::runtime_api::Payload::new_static( "AccountNonceApi", "account_nonce", @@ -4395,7 +4398,8 @@ pub mod api { #[doc = " The maximum length of a block (in bytes)."] pub fn block_length( &self, - ) -> ::subxt::constants::Address { + ) -> ::subxt::constants::Address + { ::subxt::constants::Address::new_static( "System", "BlockLength", @@ -12685,7 +12689,8 @@ pub mod api { #[doc = " Maximum amount of funds that should be placed in a deposit for making a proposal."] pub fn proposal_bond_maximum( &self, - ) -> ::subxt::constants::Address<::core::option::Option<::core::primitive::u128>> { + ) -> ::subxt::constants::Address<::core::option::Option<::core::primitive::u128>> + { ::subxt::constants::Address::new_static( "Treasury", "ProposalBondMaximum", @@ -18649,7 +18654,8 @@ pub mod api { #[doc = " Maximum amount of funds that should be placed in a deposit for making a proposal."] pub fn curator_deposit_max( &self, - ) -> ::subxt::constants::Address<::core::option::Option<::core::primitive::u128>> { + ) -> ::subxt::constants::Address<::core::option::Option<::core::primitive::u128>> + { ::subxt::constants::Address::new_static( "Bounties", "CuratorDepositMax", @@ -18664,7 +18670,8 @@ pub mod api { #[doc = " Minimum amount of funds that should be placed in a deposit for making a proposal."] pub fn curator_deposit_min( &self, - ) -> ::subxt::constants::Address<::core::option::Option<::core::primitive::u128>> { + ) -> ::subxt::constants::Address<::core::option::Option<::core::primitive::u128>> + { ::subxt::constants::Address::new_static( "Bounties", "CuratorDepositMin", diff --git a/modules/consensus/sync-committee/primitives/Cargo.toml b/modules/consensus/sync-committee/primitives/Cargo.toml index b7b76ffb3..8de4fb467 100644 --- a/modules/consensus/sync-committee/primitives/Cargo.toml +++ b/modules/consensus/sync-committee/primitives/Cargo.toml @@ -20,6 +20,7 @@ anyhow = {workspace = true, default-features = false} ark-ec = { version = "0.4.2", default-features = false } ark-bls12-381 = { version = "0.4.0", default-features = false } bls_on_arkworks = { version = "0.2.2", default-features = false } +serde-utils = { workspace = true, default-features = false } [features] default = ["std"] @@ -33,6 +34,7 @@ std = [ "bls_on_arkworks/std", "ark-bls12-381/std", "primitive-types/std", - "serde" + "serde", + "serde-utils/std" ] diff --git a/modules/consensus/sync-committee/primitives/src/consensus_types.rs b/modules/consensus/sync-committee/primitives/src/consensus_types.rs index 59e236160..06edd6090 100644 --- a/modules/consensus/sync-committee/primitives/src/consensus_types.rs +++ b/modules/consensus/sync-committee/primitives/src/consensus_types.rs @@ -13,9 +13,9 @@ use ssz_rs::{prelude::*, Deserialize, List, Vector}; #[derive(Default, Debug, SimpleSerialize, Clone, PartialEq, Eq, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct BeaconBlockHeader { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub slot: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub proposer_index: u64, pub parent_root: Root, pub state_root: Root, @@ -25,7 +25,7 @@ pub struct BeaconBlockHeader { #[derive(Default, Clone, Debug, SimpleSerialize, PartialEq, Eq, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct Checkpoint { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub epoch: u64, pub root: Root, } @@ -34,7 +34,7 @@ pub struct Checkpoint { #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct Eth1Data { pub deposit_root: Root, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub deposit_count: u64, pub block_hash: Hash32, } @@ -45,17 +45,17 @@ pub struct Validator { #[cfg_attr(feature = "std", serde(rename = "pubkey"))] pub public_key: BlsPublicKey, pub withdrawal_credentials: Bytes32, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub effective_balance: Gwei, pub slashed: bool, // Status epochs - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub activation_eligibility_epoch: Epoch, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub activation_epoch: Epoch, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub exit_epoch: Epoch, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub withdrawable_epoch: Epoch, } @@ -76,7 +76,7 @@ pub struct SignedBeaconBlockHeader { #[derive(Default, Debug, SimpleSerialize, Clone, PartialEq, Eq, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct IndexedAttestation { - #[cfg_attr(feature = "std", serde(with = "crate::serde::seq_of_str"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::seq_of_str"))] pub attesting_indices: List, pub data: AttestationData, pub signature: BlsSignature, @@ -85,9 +85,9 @@ pub struct IndexedAttestation { #[derive(Default, Clone, Debug, SimpleSerialize, PartialEq, Eq, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct AttestationData { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub slot: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub index: u64, pub beacon_block_root: Root, pub source: Checkpoint, @@ -122,7 +122,7 @@ pub struct DepositData { #[cfg_attr(feature = "std", serde(rename = "pubkey"))] pub public_key: BlsPublicKey, pub withdrawal_credentials: Hash32, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub amount: u64, pub signature: BlsSignature, } @@ -130,9 +130,9 @@ pub struct DepositData { #[derive(Default, Debug, SimpleSerialize, codec::Encode, codec::Decode, Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct VoluntaryExit { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub epoch: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub validator_index: u64, } @@ -162,19 +162,19 @@ pub struct SyncCommittee { #[derive(Default, Debug, Clone, SimpleSerialize, PartialEq, Eq, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct Withdrawal { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub index: WithdrawalIndex, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub validator_index: ValidatorIndex, pub address: ExecutionAddress, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub amount: Gwei, } #[derive(Default, Debug, Clone, SimpleSerialize, PartialEq, Eq, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct BlsToExecutionChange { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub validator_index: ValidatorIndex, #[cfg_attr(feature = "std", serde(rename = "from_bls_pubkey"))] pub from_bls_public_key: BlsPublicKey, @@ -205,22 +205,22 @@ pub struct ExecutionPayload< pub receipts_root: Bytes32, pub logs_bloom: ByteVector, pub prev_randao: Bytes32, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub block_number: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub gas_limit: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub gas_used: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub timestamp: u64, pub extra_data: ByteList, pub base_fee_per_gas: U256, pub block_hash: Hash32, pub transactions: List, MAX_TRANSACTIONS_PER_PAYLOAD>, pub withdrawals: List, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub blob_gas_used: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub excess_blob_gas: u64, } @@ -236,22 +236,22 @@ pub struct ExecutionPayloadHeader< pub receipts_root: Bytes32, pub logs_bloom: ByteVector, pub prev_randao: Bytes32, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub block_number: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub gas_limit: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub gas_used: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub timestamp: u64, pub extra_data: ByteList, pub base_fee_per_gas: U256, pub block_hash: Hash32, pub transactions_root: Root, pub withdrawals_root: Root, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub blob_gas_used: u64, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub excess_blob_gas: u64, } @@ -312,9 +312,9 @@ pub struct BeaconBlock< const MAX_BLS_TO_EXECUTION_CHANGES: usize, const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, > { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub slot: Slot, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub proposer_index: ValidatorIndex, pub parent_root: Root, pub state_root: Root, @@ -338,18 +338,18 @@ pub struct BeaconBlock< #[derive(Default, Debug, SimpleSerialize, Clone, PartialEq, Eq, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct Fork { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_hex"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_hex"))] pub previous_version: Version, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_hex"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_hex"))] pub current_version: Version, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub epoch: Epoch, } #[derive(Default, Debug, SimpleSerialize, Clone, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct ForkData { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_hex"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_hex"))] pub current_version: Version, pub genesis_validators_root: Root, } @@ -375,10 +375,10 @@ pub struct BeaconState< const BYTES_PER_LOGS_BLOOM: usize, const MAX_EXTRA_DATA_BYTES: usize, > { - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub genesis_time: u64, pub genesis_validators_root: Root, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub slot: Slot, pub fork: Fork, pub latest_block_header: BeaconBlockHeader, @@ -387,31 +387,31 @@ pub struct BeaconState< pub historical_roots: List, pub eth1_data: Eth1Data, pub eth1_data_votes: List, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub eth1_deposit_index: u64, pub validators: List, - #[cfg_attr(feature = "std", serde(with = "crate::serde::seq_of_str"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::seq_of_str"))] pub balances: List, pub randao_mixes: Vector, - #[cfg_attr(feature = "std", serde(with = "crate::serde::seq_of_str"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::seq_of_str"))] pub slashings: Vector, - #[cfg_attr(feature = "std", serde(with = "crate::serde::seq_of_str"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::seq_of_str"))] pub previous_epoch_participation: List, - #[cfg_attr(feature = "std", serde(with = "crate::serde::seq_of_str"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::seq_of_str"))] pub current_epoch_participation: List, pub justification_bits: Bitvector, pub previous_justified_checkpoint: Checkpoint, pub current_justified_checkpoint: Checkpoint, pub finalized_checkpoint: Checkpoint, - #[cfg_attr(feature = "std", serde(with = "crate::serde::seq_of_str"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::seq_of_str"))] pub inactivity_scores: List, pub current_sync_committee: SyncCommittee, pub next_sync_committee: SyncCommittee, pub latest_execution_payload_header: ExecutionPayloadHeader, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub next_withdrawal_index: WithdrawalIndex, - #[cfg_attr(feature = "std", serde(with = "crate::serde::as_string"))] + #[cfg_attr(feature = "std", serde(with = "serde_utils::as_string"))] pub next_withdrawal_validator_index: ValidatorIndex, pub historical_summaries: List, } diff --git a/modules/consensus/sync-committee/primitives/src/lib.rs b/modules/consensus/sync-committee/primitives/src/lib.rs index a1d14ea16..ec32c12cf 100644 --- a/modules/consensus/sync-committee/primitives/src/lib.rs +++ b/modules/consensus/sync-committee/primitives/src/lib.rs @@ -10,8 +10,6 @@ pub mod constants; pub mod deneb; pub mod domains; pub mod error; -#[cfg(feature = "std")] -pub mod serde; mod ssz; pub mod types; pub mod util; diff --git a/modules/consensus/sync-committee/primitives/src/serde.rs b/modules/consensus/sync-committee/primitives/src/serde.rs deleted file mode 100644 index cf3e87abf..000000000 --- a/modules/consensus/sync-committee/primitives/src/serde.rs +++ /dev/null @@ -1,142 +0,0 @@ -use core::fmt::{Display, Formatter}; -use hex::FromHexError; - -const HEX_ENCODING_PREFIX: &str = "0x"; - -#[cfg_attr(feature = "serde", derive(Debug))] -pub enum HexError { - Hex, - MissingPrefix, -} - -impl From for HexError { - fn from(_: FromHexError) -> Self { - HexError::Hex - } -} - -impl Display for HexError { - fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - match self { - HexError::Hex => write!(f, ""), - HexError::MissingPrefix => write!(f, "missing prefix when deserializing hex data"), - } - } -} - -pub fn try_bytes_from_hex_str(s: &str) -> Result, HexError> { - let target = s.strip_prefix(HEX_ENCODING_PREFIX).ok_or(HexError::MissingPrefix)?; - let data = hex::decode(target)?; - Ok(data) -} - -pub mod as_hex { - use super::*; - use alloc::format; - use serde::de::Deserialize; - - pub fn serialize>(data: T, serializer: S) -> Result - where - S: serde::Serializer, - { - let encoding = hex::encode(data.as_ref()); - let output = format!("{HEX_ENCODING_PREFIX}{encoding}"); - serializer.collect_str(&output) - } - - pub fn deserialize<'de, D, T>(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - T: TryFrom>, - { - let s = ::deserialize(deserializer)?; - - let data = try_bytes_from_hex_str(&s).map_err(serde::de::Error::custom)?; - - let inner = T::try_from(data) - .map_err(|_| serde::de::Error::custom("type failed to parse bytes from hex data"))?; - Ok(inner) - } -} - -pub mod as_string { - use alloc::format; - use core::{fmt, str::FromStr}; - use serde::de::Deserialize; - - pub fn serialize(data: T, serializer: S) -> Result - where - S: serde::Serializer, - { - let output = format!("{data}"); - serializer.collect_str(&output) - } - - pub fn deserialize<'de, D, T: FromStr>(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let s: String = ::deserialize(deserializer)?; - let inner: T = s - .parse() - .map_err(|_| serde::de::Error::custom("failure to parse string data"))?; - Ok(inner) - } -} - -pub mod seq_of_str { - use serde::{ - de::{Deserializer, Error}, - ser::SerializeSeq, - }; - use std::{fmt, marker::PhantomData, str::FromStr}; - - pub fn serialize(data: T, serializer: S) -> Result - where - S: serde::Serializer, - T: AsRef<[U]>, - U: fmt::Display, - { - let mut seq = serializer.serialize_seq(None)?; - for elem in data.as_ref().iter() { - let rendered_elem = format!("{elem}"); - seq.serialize_element(&rendered_elem)?; - } - seq.end() - } - - struct Visitor(PhantomData>); - - impl<'de, T: FromStr> serde::de::Visitor<'de> for Visitor { - type Value = Vec; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("sequence of string") - } - - fn visit_seq(self, mut access: S) -> Result - where - S: serde::de::SeqAccess<'de>, - { - let mut coll = Vec::with_capacity(access.size_hint().unwrap_or(0)); - - while let Some(elem) = access.next_element()? { - let recovered_elem = T::from_str(elem).map_err(|_| { - Error::custom("failure to parse element of sequence from string") - })?; - coll.push(recovered_elem); - } - Ok(coll) - } - } - - pub fn deserialize<'de, D, T, U>(deserializer: D) -> Result - where - D: Deserializer<'de>, - T: TryFrom>, - U: FromStr, - { - let data = deserializer.deserialize_seq(Visitor(PhantomData))?; - T::try_from(data).map_err(|_| serde::de::Error::custom("failure to parse collection")) - } -} diff --git a/modules/consensus/sync-committee/primitives/src/ssz/byte_list.rs b/modules/consensus/sync-committee/primitives/src/ssz/byte_list.rs index a22b2c1b4..6ba165723 100644 --- a/modules/consensus/sync-committee/primitives/src/ssz/byte_list.rs +++ b/modules/consensus/sync-committee/primitives/src/ssz/byte_list.rs @@ -10,7 +10,7 @@ use ssz_rs::prelude::*; #[derive(Default, Clone, Eq, SimpleSerialize, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct ByteList( - #[cfg_attr(feature = "serde", serde(with = "crate::serde::as_hex"))] List, + #[cfg_attr(feature = "serde", serde(with = "serde_utils::as_hex"))] List, ); impl TryFrom<&[u8]> for ByteList { diff --git a/modules/consensus/sync-committee/primitives/src/ssz/byte_vector.rs b/modules/consensus/sync-committee/primitives/src/ssz/byte_vector.rs index 1b1b5ba7d..bb2dcfa5e 100644 --- a/modules/consensus/sync-committee/primitives/src/ssz/byte_vector.rs +++ b/modules/consensus/sync-committee/primitives/src/ssz/byte_vector.rs @@ -10,7 +10,7 @@ use ssz_rs::prelude::*; #[derive(Default, Clone, Eq, SimpleSerialize, codec::Encode, codec::Decode)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct ByteVector( - #[cfg_attr(feature = "serde", serde(with = "crate::serde::as_hex"))] Vector, + #[cfg_attr(feature = "serde", serde(with = "serde_utils::as_hex"))] Vector, ); impl TryFrom<&[u8]> for ByteVector { diff --git a/modules/hyperclient/hyperclient.d.ts b/modules/hyperclient/hyperclient.d.ts index d8b1a3ab8..58fcd68cf 100644 --- a/modules/hyperclient/hyperclient.d.ts +++ b/modules/hyperclient/hyperclient.d.ts @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + /* tslint:disable */ /* eslint-disable */ /** @@ -47,7 +62,7 @@ interface IPostRequest { // Encoded request body. data: string; // Timestamp which this request expires in seconds. - timeout_timestamp: bigint; + timeoutTimestamp: bigint; // Height at which this request was emitted on the source height: bigint; } @@ -58,7 +73,7 @@ interface IPostResponse { // The response message. response: Uint8Array; // Timestamp at which this response expires in seconds. - timeout_timestamp: bigint; + timeoutTimestamp: bigint; } type MessageStatus = diff --git a/modules/hyperclient/src/any_client.rs b/modules/hyperclient/src/any_client.rs index 9eda240aa..bb1efe671 100644 --- a/modules/hyperclient/src/any_client.rs +++ b/modules/hyperclient/src/any_client.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use subxt_utils::{BlakeSubstrateChain, Hyperbridge}; use crate::providers::{evm::EvmClient, interface::Client, substrate::SubstrateClient}; diff --git a/modules/hyperclient/src/indexing.rs b/modules/hyperclient/src/indexing.rs index ec0af4971..f461f7574 100644 --- a/modules/hyperclient/src/indexing.rs +++ b/modules/hyperclient/src/indexing.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #![allow(non_camel_case_types)] use crate::{ internals::{encode_request_call_data, encode_response_call_data}, diff --git a/modules/hyperclient/src/interfaces.rs b/modules/hyperclient/src/interfaces.rs index 73e8aa392..6e342597b 100644 --- a/modules/hyperclient/src/interfaces.rs +++ b/modules/hyperclient/src/interfaces.rs @@ -1,9 +1,24 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use crate::types::{ChainConfig, ClientConfig, EvmConfig, HashAlgorithm, SubstrateConfig}; use anyhow::anyhow; use core::str::FromStr; use ismp::{ host::StateMachine, - router::{Post, PostResponse}, + router::{PostRequest, PostResponse}, }; use primitive_types::H160; use serde::{Deserialize, Serialize}; @@ -14,7 +29,6 @@ pub struct JsChainConfig { pub rpc_url: String, pub state_machine: String, pub host_address: String, - pub handler_address: String, pub consensus_state_id: String, } @@ -36,7 +50,7 @@ impl TryFrom for ClientConfig { fn try_from(value: JsClientConfig) -> Result { let to_config = |val: &JsChainConfig| { - if !val.host_address.is_empty() && !val.handler_address.is_empty() { + if !val.host_address.is_empty() { let conf = EvmConfig { rpc_url: val.rpc_url.clone(), state_machine: StateMachine::from_str(&val.state_machine) @@ -48,14 +62,6 @@ impl TryFrom for ClientConfig { } H160::from_slice(&address) }, - handler_address: { - let address = from_hex(&val.handler_address)?; - - if address.len() != 20 { - Err(anyhow!("Invalid handler address"))? - } - H160::from_slice(&address) - }, consensus_state_id: { if val.consensus_state_id.len() != 4 { Err(anyhow!("Invalid consensus state id"))? @@ -122,14 +128,15 @@ pub struct JsPost { /// Module ID of the receiving module pub to: String, /// Timestamp which this request expires in seconds. + #[serde(rename = "timeoutTimestamp")] pub timeout_timestamp: u64, /// Encoded Request. - pub data: String, + pub body: String, /// Height at which this request was emitted on the source chain pub height: u64, } -impl TryFrom for Post { +impl TryFrom for PostRequest { type Error = anyhow::Error; fn try_from(value: JsPost) -> Result { @@ -147,14 +154,14 @@ impl TryFrom for Post { StateMachine::from_str(&value.dest).map_err(|e| anyhow!("{e:?}"))? }; - let post = Post { + let post = PostRequest { source, dest, nonce: value.nonce, from: from_hex(&value.from)?, to: from_hex(&value.to)?, timeout_timestamp: value.timeout_timestamp, - data: from_hex(&value.data)?, + body: from_hex(&value.body)?, }; Ok(post) } @@ -167,6 +174,7 @@ pub struct JsPostResponse { /// The response message. pub response: Vec, /// Timestamp at which this response expires in seconds. + #[serde(rename = "timeoutTimestamp")] pub timeout_timestamp: u64, } @@ -194,19 +202,17 @@ mod tests { use hex_literal::hex; use ismp::{ host::{Ethereum, StateMachine}, - router::{Post, PostResponse}, + router::{PostRequest, PostResponse}, }; const OP_HOST: H160 = H160(hex!("1B58A47e61Ca7604b634CBB00b4e275cCd7c9E95")); const BSC_HOST: H160 = H160(hex!("022DDE07A21d8c553978b006D93CDe68ac83e677")); - const OP_HANDLER: H160 = H160(hex!("a25151598Dc180fc03635858f37bDF8427f47845")); - const BSC_HANDLER: H160 = H160(hex!("43a0BcC347894303f93905cE137CB3b804bE990d")); + #[test] fn test_chain_config_conversion() { let source_chain = EvmConfig { rpc_url: "https://127.0.0.1:9990".to_string(), state_machine: StateMachine::Bsc, host_address: BSC_HOST, - handler_address: BSC_HANDLER, consensus_state_id: *b"BSC0", }; @@ -214,7 +220,6 @@ mod tests { rpc_url: "https://127.0.0.1:9990".to_string(), state_machine: StateMachine::Ethereum(Ethereum::Optimism), host_address: OP_HOST, - handler_address: OP_HANDLER, consensus_state_id: *b"ETH0", }; @@ -234,7 +239,6 @@ mod tests { rpc_url: "https://127.0.0.1:9990".to_string(), state_machine: "BSC".to_string(), host_address: hex::encode(&BSC_HOST.0), - handler_address: hex::encode(&BSC_HANDLER.0), consensus_state_id: "BSC0".to_string(), }; @@ -242,7 +246,6 @@ mod tests { rpc_url: "https://127.0.0.1:9990".to_string(), state_machine: "OPTI".to_string(), host_address: hex::encode(&OP_HOST.0), - handler_address: hex::encode(&OP_HANDLER.0), consensus_state_id: "ETH0".to_string(), }; @@ -261,14 +264,14 @@ mod tests { #[test] fn test_post_conversion() { let post_response = PostResponse { - post: Post { + post: PostRequest { source: StateMachine::Bsc, dest: StateMachine::Kusama(2000), nonce: 100, from: vec![30; 20], to: vec![15; 20], timeout_timestamp: 1_600_000, - data: vec![40; 256], + body: vec![40; 256], }, response: vec![80; 256], timeout_timestamp: 4_500_000, @@ -282,7 +285,7 @@ mod tests { from: hex::encode(vec![30; 20]), to: hex::encode(vec![15; 20]), timeout_timestamp: 1_600_000, - data: hex::encode(vec![40; 256]), + body: hex::encode(vec![40; 256]), height: 0, }, response: vec![80; 256], diff --git a/modules/hyperclient/src/internals.rs b/modules/hyperclient/src/internals.rs index fbeebe506..ffa1fa144 100644 --- a/modules/hyperclient/src/internals.rs +++ b/modules/hyperclient/src/internals.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + ///! This module contains the internal implementation of HyperClient. use crate::{ any_client::AnyClient, @@ -15,7 +30,7 @@ use futures::{stream, StreamExt}; use ismp::{ consensus::StateMachineHeight, messaging::{hash_request, Message, Proof, RequestMessage, ResponseMessage, TimeoutMessage}, - router::{Post, PostResponse, Request, Response}, + router::{PostRequest, PostResponse, Request, Response}, }; use sp_core::H256; use subxt_utils::Hyperbridge; @@ -28,7 +43,7 @@ use std::time::Duration; /// checks the status of a message pub async fn query_request_status_internal( client: &HyperClient, - post: Post, + post: PostRequest, ) -> Result { let destination_current_timestamp = client.dest.query_timestamp().await?; let req = Request::Post(post.clone()); @@ -127,7 +142,7 @@ pub enum TimeoutStreamState { /// you have confirmed the request timeout status using `query_request_status` pub async fn timeout_request_stream( hyperclient: &HyperClient, - post: Post, + post: PostRequest, ) -> Result, anyhow::Error> { let dest_client = hyperclient.dest.clone(); let hyperbridge_client = hyperclient.hyperbridge.clone(); @@ -364,7 +379,7 @@ pub async fn timeout_request_stream( /// returns the query stream for a post pub async fn request_status_stream( hyperclient: &HyperClient, - post: Post, + post: PostRequest, post_request_height: u64, ) -> BoxStream { let source_client = hyperclient.source.clone(); @@ -894,7 +909,7 @@ pub async fn request_timeout_stream( pub async fn encode_request_call_data( hyperbridge: &SubstrateClient, dest_client: &AnyClient, - post: Post, + post: PostRequest, commitment: H256, height: u64, ) -> Result, anyhow::Error> { @@ -946,7 +961,7 @@ pub async fn encode_response_call_data( pub async fn encode_request_message_and_wait_for_challenge_period( hyperbridge: &SubstrateClient, dest_client: &AnyClient, - post: Post, + post: PostRequest, commitment: H256, height: u64, ) -> Result, anyhow::Error> { diff --git a/modules/hyperclient/src/lib.rs b/modules/hyperclient/src/lib.rs index b14af1faf..56261fb0c 100644 --- a/modules/hyperclient/src/lib.rs +++ b/modules/hyperclient/src/lib.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + //! The hyperclient. Allows clients of hyperbridge manage their in-flight ISMP requests. pub mod internals; @@ -22,7 +37,7 @@ use crate::{ }; use ethers::{types::H256, utils::keccak256}; use futures::StreamExt; -use ismp::router::{Post, PostResponse}; +use ismp::router::{PostRequest, PostResponse}; use subxt_utils::Hyperbridge; use wasm_bindgen::prelude::*; use wasm_streams::ReadableStream; @@ -94,7 +109,13 @@ interface IPostResponse { timeout_timestamp: bigint; } -type MessageStatus = Pending | SourceFinalized | HyperbridgeDelivered | HyperbridgeFinalized | DestinationDelivered | Timeout; +type MessageStatus = + | Pending + | SourceFinalized + | HyperbridgeDelivered + | HyperbridgeFinalized + | DestinationDelivered + | Timeout; // This transaction is still pending on the source chain interface Pending { @@ -143,10 +164,21 @@ interface HyperbridgeTimedout { } // The possible states of an inflight request -type MessageStatusWithMeta = SourceFinalizedWithMetadata | HyperbridgeDeliveredWithMetadata | HyperbridgeFinalizedWithMetadata | DestinationDeliveredWithMetadata | Timeout | ErrorWithMetadata; +type MessageStatusWithMeta = + | SourceFinalizedWithMetadata + | HyperbridgeDeliveredWithMetadata + | HyperbridgeFinalizedWithMetadata + | DestinationDeliveredWithMetadata + | Timeout + | ErrorWithMetadata; // The possible states of a timed-out request -type TimeoutStatusWithMeta = DestinationFinalizedWithMetadata | HyperbridgeTimedoutWithMetadata | HyperbridgeFinalizedWithMetadata | TimeoutMessage | ErrorWithMetadata; +type TimeoutStatusWithMeta = + | DestinationFinalizedWithMetadata + | HyperbridgeTimedoutWithMetadata + | HyperbridgeFinalizedWithMetadata + | TimeoutMessage + | ErrorWithMetadata; // This event is emitted on hyperbridge @@ -299,7 +331,7 @@ impl HyperClient { pub async fn query_request_status(&self, request: IPostRequest) -> Result { let lambda = || async move { let post = serde_wasm_bindgen::from_value::(request.into()).unwrap(); - let post: Post = post.try_into()?; + let post: PostRequest = post.try_into()?; let status = internals::query_request_status_internal(&self, post).await?; Ok(serde_wasm_bindgen::to_value(&status).expect("Infallible")) }; @@ -340,7 +372,7 @@ impl HyperClient { let lambda = || async move { let post = serde_wasm_bindgen::from_value::(request.into()).unwrap(); let height = post.height; - let post: Post = post.try_into()?; + let post: PostRequest = post.try_into()?; // Obtaining the request stream and the timeout stream let timed_out = @@ -380,7 +412,7 @@ impl HyperClient { ) -> Result { let lambda = || async move { let post = serde_wasm_bindgen::from_value::(request.into()).unwrap(); - let post: Post = post.try_into()?; + let post: PostRequest = post.try_into()?; let stream = internals::timeout_request_stream(&self, post).await?.map(|value| { value diff --git a/modules/hyperclient/src/providers/evm.rs b/modules/hyperclient/src/providers/evm.rs index c46c766aa..7df9a91ad 100644 --- a/modules/hyperclient/src/providers/evm.rs +++ b/modules/hyperclient/src/providers/evm.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use crate::{ providers::interface::{Client, RequestOrResponse}, types::BoxStream, @@ -65,10 +80,12 @@ impl EvmClient { rpc_url: String, consensus_state_id: ConsensusStateId, host_address: H160, - handler_address: H160, state_machine: StateMachine, ) -> Result { let client = Arc::new(Provider::::connect(&rpc_url.clone()).await); + let host = EvmHost::new(host_address, client.clone()); + let handler_address = host.host_params().await?.handler; + Ok(Self { rpc_url, client, diff --git a/modules/hyperclient/src/providers/interface.rs b/modules/hyperclient/src/providers/interface.rs index 15319ced0..a37748473 100644 --- a/modules/hyperclient/src/providers/interface.rs +++ b/modules/hyperclient/src/providers/interface.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #![allow(async_fn_in_trait)] use crate::types::{BoxStream, EventMetadata}; @@ -8,7 +23,7 @@ use ismp::{ events::{Event, StateMachineUpdated}, host::StateMachine, messaging::Message, - router::{Post, PostResponse}, + router::{PostRequest, PostResponse}, }; use ismp_solidity_abi::evm_host::PostRequestHandledFilter; use serde::{Deserialize, Serialize}; @@ -16,7 +31,7 @@ use std::ops::RangeInclusive; #[derive(Eq, PartialEq, Clone)] pub enum RequestOrResponse { - Request(Post), + Request(PostRequest), Response(PostResponse), } diff --git a/modules/hyperclient/src/providers/mod.rs b/modules/hyperclient/src/providers/mod.rs index fadad2e0c..2ed811bb9 100644 --- a/modules/hyperclient/src/providers/mod.rs +++ b/modules/hyperclient/src/providers/mod.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub mod evm; pub mod interface; pub mod substrate; diff --git a/modules/hyperclient/src/providers/substrate.rs b/modules/hyperclient/src/providers/substrate.rs index 7b3042c61..83af3689a 100644 --- a/modules/hyperclient/src/providers/substrate.rs +++ b/modules/hyperclient/src/providers/substrate.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use crate::{ providers::interface::{Client, RequestOrResponse, WithMetadata}, runtime::{self}, diff --git a/modules/hyperclient/src/testing.rs b/modules/hyperclient/src/testing.rs index 916ee4919..064c57067 100644 --- a/modules/hyperclient/src/testing.rs +++ b/modules/hyperclient/src/testing.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use anyhow::Context; use ethers::{ contract::parse_log, @@ -35,16 +50,11 @@ use ismp_solidity_abi::{ }; use std::sync::Arc; -const OP_HOST: H160 = H160(hex!("0D811D581D615AA44A36aa638825403F9b434E18")); -const OP_HANDLER: H160 = H160(hex!("6DbcA7CAEBd47D377E230ec3EFaBDdf0A7afA395")); - -const SEPOLIA_HOST: H160 = H160(hex!("bDFa473d7E483e088348e071480B624A248b2fC4")); -const SEPOLIA_HANDLER: H160 = H160(hex!("7fa6f643A1a522D35058FEE753DA027d25Ea601f")); - -const BSC_HOST: H160 = H160(hex!("E6bd95737DD35Fd0e5f134771A832405671f06e9")); -const BSC_HANDLER: H160 = H160(hex!("BA82A7c413BfbE26ee025DA221088319b895A8E6")); - -const PING_MODULE: H160 = H160(hex!("9Cc29770F3d643F4094Ee591f3D2E3c98C349761")); +const OP_HOST: H160 = H160(hex!("265FafEb401ac6491da7344F01E724c38bC68FED")); +const SEPOLIA_HOST: H160 = H160(hex!("4175a96bd787a2C196e732a1244630650607fdC2")); +const BSC_HOST: H160 = H160(hex!("9494400D1A8285F81604AC04ACFD839385B3b843")); +const BSC_HANDLER: H160 = H160(hex!("698Ea102d14dF1F9a4C3A76fE5DCEEeFcfd27f85")); +const PING_MODULE: H160 = H160(hex!("8E4Ca395cfAa033A71fC618792Fce99106633B90")); pub async fn subscribe_to_request_status() -> Result<(), anyhow::Error> { tracing::info!("\n\n\n\nStarting request status subscription\n\n\n\n"); @@ -57,7 +67,6 @@ pub async fn subscribe_to_request_status() -> Result<(), anyhow::Error> { rpc_url: bsc_url.clone(), state_machine: StateMachine::Bsc, host_address: BSC_HOST, - handler_address: BSC_HANDLER, consensus_state_id: *b"BSC0", }; @@ -65,7 +74,6 @@ pub async fn subscribe_to_request_status() -> Result<(), anyhow::Error> { rpc_url: op_url, state_machine: StateMachine::Ethereum(Ethereum::Optimism), host_address: OP_HOST, - handler_address: OP_HANDLER, consensus_state_id: *b"ETH0", }; @@ -121,7 +129,7 @@ pub async fn subscribe_to_request_status() -> Result<(), anyhow::Error> { .context(format!("Error in {chain:?}"))? .unwrap(); - let post: router::Post = receipt + let post: router::PostRequest = receipt .logs .into_iter() .find_map(|log| parse_log::(log).ok()) @@ -157,7 +165,6 @@ pub async fn test_timeout_request() -> Result<(), anyhow::Error> { rpc_url: bsc_url.clone(), state_machine: StateMachine::Bsc, host_address: BSC_HOST, - handler_address: BSC_HANDLER, consensus_state_id: *b"BSC0", }; @@ -165,7 +172,6 @@ pub async fn test_timeout_request() -> Result<(), anyhow::Error> { rpc_url: sepolia_url, state_machine: StateMachine::Ethereum(Ethereum::ExecutionLayer), host_address: SEPOLIA_HOST, - handler_address: SEPOLIA_HANDLER, consensus_state_id: *b"ETH0", }; @@ -245,7 +251,7 @@ pub async fn test_timeout_request() -> Result<(), anyhow::Error> { let block = receipt.block_number.unwrap(); tracing::info!("\n\nTx block: {block}\n\n"); - let post: router::Post = receipt + let post: router::PostRequest = receipt .logs .into_iter() .find_map(|log| parse_log::(log).ok()) @@ -292,7 +298,7 @@ pub async fn test_timeout_request() -> Result<(), anyhow::Error> { let pending = client .send_transaction( TypedTransaction::Legacy(TransactionRequest { - to: Some(NameOrAddress::Address(source_chain.handler_address)), + to: Some(NameOrAddress::Address(BSC_HANDLER)), gas_price: Some(gas_price * 5), // experiment with higher? data: Some(calldata.0.into()), ..Default::default() diff --git a/modules/hyperclient/src/tests.rs b/modules/hyperclient/src/tests.rs index d98804390..07b39aaa4 100644 --- a/modules/hyperclient/src/tests.rs +++ b/modules/hyperclient/src/tests.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #![cfg(not(target_arch = "wasm32"))] use std::str::FromStr; @@ -41,7 +56,7 @@ async fn hyperclient_integration_tests() -> Result<(), anyhow::Error> { #[tokio::test] #[ignore] async fn test_query_status_from_indexer() -> Result<(), anyhow::Error> { - let post = ismp::router::Post { + let post = ismp::router::PostRequest { source: StateMachine::from_str( &String::from_utf8(hex::decode("42415345".to_string()).unwrap()).unwrap(), ) @@ -54,7 +69,7 @@ async fn test_query_status_from_indexer() -> Result<(), anyhow::Error> { from: hex::decode("9cc29770f3d643f4094ee591f3d2e3c98c349761".to_string()).unwrap(), to: hex::decode("9cc29770f3d643f4094ee591f3d2e3c98c349761".to_string()).unwrap(), timeout_timestamp: 1716240884, - data: hex::decode("68656c6c6f2066726f6d2042415345".to_string()).unwrap(), + body: hex::decode("68656c6c6f2066726f6d2042415345".to_string()).unwrap(), }; let request = Request::Post(post); @@ -63,7 +78,6 @@ async fn test_query_status_from_indexer() -> Result<(), anyhow::Error> { rpc_url: "https://bsc-testnet.blockpi.network/v1/rpc/public".to_string(), state_machine: StateMachine::Bsc, host_address: Default::default(), - handler_address: Default::default(), consensus_state_id: *b"BSC0", }; @@ -71,7 +85,6 @@ async fn test_query_status_from_indexer() -> Result<(), anyhow::Error> { rpc_url: "https://optimism-sepolia.blockpi.network/v1/rpc/public".to_string(), state_machine: StateMachine::Ethereum(Ethereum::Optimism), host_address: Default::default(), - handler_address: Default::default(), consensus_state_id: *b"ETH0", }; @@ -117,7 +130,7 @@ async fn test_query_status_from_indexer() -> Result<(), anyhow::Error> { #[tokio::test] #[ignore] async fn test_query_response_status_from_indexer() -> Result<(), anyhow::Error> { - let post = ismp::router::Post { + let post = ismp::router::PostRequest { source: StateMachine::from_str( &String::from_utf8(hex::decode("425343".to_string()).unwrap()).unwrap(), ) @@ -130,7 +143,7 @@ async fn test_query_response_status_from_indexer() -> Result<(), anyhow::Error> from: hex::decode("9cc29770f3d643f4094ee591f3d2e3c98c349761".to_string()).unwrap(), to: hex::decode("9cc29770f3d643f4094ee591f3d2e3c98c349761".to_string()).unwrap(), timeout_timestamp: 1716240473, - data: hex::decode("68656c6c6f2066726f6d20425343".to_string()).unwrap(), + body: hex::decode("68656c6c6f2066726f6d20425343".to_string()).unwrap(), }; let response = PostResponse { @@ -143,7 +156,6 @@ async fn test_query_response_status_from_indexer() -> Result<(), anyhow::Error> rpc_url: "https://bsc-testnet.blockpi.network/v1/rpc/public".to_string(), state_machine: StateMachine::Bsc, host_address: Default::default(), - handler_address: Default::default(), consensus_state_id: *b"BSC0", }; @@ -151,7 +163,6 @@ async fn test_query_response_status_from_indexer() -> Result<(), anyhow::Error> rpc_url: "https://optimism-sepolia.blockpi.network/v1/rpc/public".to_string(), state_machine: StateMachine::Ethereum(Ethereum::Optimism), host_address: Default::default(), - handler_address: Default::default(), consensus_state_id: *b"ETH0", }; diff --git a/modules/hyperclient/src/types.rs b/modules/hyperclient/src/types.rs index 34ffa16a8..6092cb032 100644 --- a/modules/hyperclient/src/types.rs +++ b/modules/hyperclient/src/types.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use crate::{ any_client::AnyClient, providers::{evm::EvmClient, substrate::SubstrateClient}, @@ -26,7 +41,6 @@ pub struct EvmConfig { pub rpc_url: String, pub state_machine: StateMachine, pub host_address: H160, - pub handler_address: H160, pub consensus_state_id: ConsensusStateId, } @@ -36,7 +50,6 @@ impl EvmConfig { self.rpc_url.clone(), self.consensus_state_id, self.host_address, - self.handler_address, self.state_machine, ) .await?; diff --git a/modules/hyperclient/tests/streams.rs b/modules/hyperclient/tests/streams.rs index 8bd3f8763..52108d79e 100644 --- a/modules/hyperclient/tests/streams.rs +++ b/modules/hyperclient/tests/streams.rs @@ -1,3 +1,18 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #![cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; diff --git a/modules/ismp/core/Cargo.toml b/modules/ismp/core/Cargo.toml index 1953e38e5..f35bcb7d1 100644 --- a/modules/ismp/core/Cargo.toml +++ b/modules/ismp/core/Cargo.toml @@ -14,12 +14,14 @@ readme = "./README.md" [dependencies] # crates.io codec = { workspace = true } -primitive-types = { workspace = true, features = ["codec", "scale-info"] } +primitive-types = { workspace = true, features = ["codec", "scale-info", "serde_no_std"] } serde = { workspace = true, features = ["derive"] } scale-info = { workspace = true, features = ["derive"] } derive_more = { version = "0.99.17", default-features = false, features = ["from", "into", "display"] } serde_json = { version = "1.0.99", default-features = false, features = ["alloc"] } hex = { version = "0.4.3", features = ["alloc"], default-features = false } +anyhow = {workspace = true, default-features = false} +serde-utils = { workspace = true, default-features = false } [features] default = ["std"] @@ -29,6 +31,8 @@ std = [ "primitive-types/serde", "scale-info/std", "serde/std", + "anyhow/std", "hex/std", - "serde_json/std" + "serde_json/std", + "serde-utils/std" ] diff --git a/modules/ismp/core/src/consensus.rs b/modules/ismp/core/src/consensus.rs index 7b94c0c9b..7b5ef3e39 100644 --- a/modules/ismp/core/src/consensus.rs +++ b/modules/ismp/core/src/consensus.rs @@ -94,8 +94,10 @@ pub struct IntermediateState { )] pub struct StateMachineId { /// The state machine identifier + #[serde(with = "serde_utils::as_string")] pub state_id: StateMachine, /// It's consensus state identifier + #[serde(with = "serde_utils::as_utf8_string")] pub consensus_state_id: ConsensusStateId, } diff --git a/modules/ismp/core/src/events.rs b/modules/ismp/core/src/events.rs index 6586af440..f15a7dcfa 100644 --- a/modules/ismp/core/src/events.rs +++ b/modules/ismp/core/src/events.rs @@ -18,7 +18,7 @@ use crate::{ consensus::{StateMachineHeight, StateMachineId}, host::StateMachine, - router::{Get, Post, PostResponse, Request, Response}, + router::{GetRequest, PostRequest, PostResponse, Request, Response}, }; use alloc::vec::Vec; use codec::{Decode, Encode}; @@ -41,6 +41,7 @@ pub struct StateCommitmentVetoed { /// The state commitment identifier pub height: StateMachineHeight, /// The account responsible + #[serde(with = "serde_utils::as_hex")] pub fisherman: Vec, } @@ -52,6 +53,7 @@ pub struct RequestResponseHandled { /// The commitment to the request or response pub commitment: H256, /// The address of the relayer responsible for relaying the request + #[serde(with = "serde_utils::as_hex")] pub relayer: Vec, } @@ -63,8 +65,10 @@ pub struct TimeoutHandled { /// The commitment to the request or response pub commitment: H256, /// The source chain of the message + #[serde(with = "serde_utils::as_string")] pub source: StateMachine, /// The destination chain of the message + #[serde(with = "serde_utils::as_string")] pub dest: StateMachine, } @@ -78,11 +82,11 @@ pub enum Event { /// a fisherman. StateCommitmentVetoed(StateCommitmentVetoed), /// An event that is emitted when a post request is dispatched - PostRequest(Post), + PostRequest(PostRequest), /// An event that is emitted when a post response is dispatched PostResponse(PostResponse), /// An event that is emitted when a get request is dispatched - GetRequest(Get), + GetRequest(GetRequest), /// Emitted when a post request is handled PostRequestHandled(RequestResponseHandled), /// Emitted when a post response is handled diff --git a/modules/ismp/core/src/messaging.rs b/modules/ismp/core/src/messaging.rs index a11a9d743..4404fe9fe 100644 --- a/modules/ismp/core/src/messaging.rs +++ b/modules/ismp/core/src/messaging.rs @@ -23,7 +23,7 @@ use crate::{ ConsensusClientId, ConsensusStateId, StateCommitment, StateMachineHeight, StateMachineId, }, error::Error, - router::{Post, PostResponse, Request, RequestResponse, Response}, + router::{PostRequest, PostResponse, Request, RequestResponse, Response}, }; use alloc::{string::ToString, vec::Vec}; use codec::{Decode, Encode}; @@ -82,7 +82,7 @@ pub struct CreateConsensusState { #[derive(Debug, Clone, Encode, Decode, scale_info::TypeInfo, PartialEq, Eq)] pub struct RequestMessage { /// Requests from source chain - pub requests: Vec, + pub requests: Vec, /// Membership batch proof for these requests pub proof: Proof, /// Signer information. Ideally should be their account identifier diff --git a/modules/ismp/core/src/module.rs b/modules/ismp/core/src/module.rs index 0623ceaa9..44c6e855d 100644 --- a/modules/ismp/core/src/module.rs +++ b/modules/ismp/core/src/module.rs @@ -18,7 +18,7 @@ use crate::{ error::Error, events::Event, - router::{Post as PostRequest, Response, Timeout}, + router::{PostRequest, Response, Timeout}, }; /// A type alias for dispatch results diff --git a/modules/ismp/core/src/router.rs b/modules/ismp/core/src/router.rs index 56926ba0d..e8f1027dd 100644 --- a/modules/ismp/core/src/router.rs +++ b/modules/ismp/core/src/router.rs @@ -32,24 +32,29 @@ use core::{fmt::Formatter, time::Duration}; serde::Deserialize, serde::Serialize, )] -pub struct Post { +pub struct PostRequest { /// The source state machine of this request. + #[serde(with = "serde_utils::as_string")] pub source: StateMachine, /// The destination state machine of this request. + #[serde(with = "serde_utils::as_string")] pub dest: StateMachine, /// The nonce of this request on the source chain pub nonce: u64, /// Module identifier of the sending module + #[serde(with = "serde_utils::as_hex")] pub from: Vec, /// Module identifier of the receiving module + #[serde(with = "serde_utils::as_hex")] pub to: Vec, /// Timestamp which this request expires in seconds. pub timeout_timestamp: u64, /// Encoded request body - pub data: Vec, + #[serde(with = "serde_utils::as_hex")] + pub body: Vec, } -impl core::fmt::Display for Post { +impl core::fmt::Display for PostRequest { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { writeln!(f, "Post {{")?; writeln!(f, " source: {:?}", self.source)?; @@ -58,7 +63,7 @@ impl core::fmt::Display for Post { writeln!(f, " from: {}", hex::encode(&self.from))?; writeln!(f, " to: {}", hex::encode(&self.to))?; writeln!(f, " timeout_timestamp: {}", self.timeout_timestamp)?; - writeln!(f, " data: {}", hex::encode(&self.data))?; + writeln!(f, " data: {}", hex::encode(&self.body))?; writeln!(f, "}}")?; Ok(()) } @@ -76,14 +81,17 @@ impl core::fmt::Display for Post { serde::Deserialize, serde::Serialize, )] -pub struct Get { +pub struct GetRequest { /// The source state machine of this request. + #[serde(with = "serde_utils::as_string")] pub source: StateMachine, /// The destination state machine of this request. + #[serde(with = "serde_utils::as_string")] pub dest: StateMachine, /// The nonce of this request on the source chain pub nonce: u64, /// Module identifier of the sending module + #[serde(with = "serde_utils::as_hex")] pub from: Vec, /// Raw Storage keys that would be used to fetch the values from the counterparty /// For deriving storage keys for ink contract fields follow the guide in the link below @@ -96,6 +104,7 @@ pub struct Get { /// `` /// For fetching keys from EVM contracts each key should be 52 bytes /// This should be a concatenation of contract address and slot hash + #[serde(with = "serde_utils::seq_of_hex")] pub keys: Vec>, /// Height at which to read the state machine. pub height: u64, @@ -103,7 +112,7 @@ pub struct Get { pub timeout_timestamp: u64, } -impl Get { +impl GetRequest { /// Get the timeout for this request pub fn timeout(&self) -> Duration { get_timeout(self.timeout_timestamp) @@ -136,10 +145,10 @@ fn get_timeout(timeout_timestamp: u64) -> Duration { pub enum Request { /// A post request allows a module on a state machine to send arbitrary bytes to another module /// living in another state machine. - Post(Post), + Post(PostRequest), /// A get request allows a module on a state machine to read the storage of another module /// living in another state machine. - Get(Get), + Get(GetRequest), } impl Request { @@ -184,10 +193,10 @@ impl Request { } /// Get the POST request data - pub fn data(&self) -> Option> { + pub fn body(&self) -> Option> { match self { Request::Get(_) => None, - Request::Post(post) => Some(post.data.clone()), + Request::Post(post) => Some(post.body.clone()), } } @@ -214,7 +223,7 @@ impl Request { } /// Returns a get request or an error - pub fn get_request(&self) -> Result { + pub fn get_request(&self) -> Result { match self { Request::Post(_) => Err(Error::Custom("Expected Get request".to_string())), Request::Get(get) => Ok(get.clone()), @@ -232,7 +241,7 @@ impl Request { buf.extend_from_slice(&post.timeout_timestamp.to_be_bytes()); buf.extend_from_slice(&post.from); buf.extend_from_slice(&post.to); - buf.extend_from_slice(&post.data); + buf.extend_from_slice(&post.body); buf }, Request::Get(get) => { @@ -264,8 +273,9 @@ impl Request { )] pub struct PostResponse { /// The request that triggered this response. - pub post: Post, + pub post: PostRequest, /// The response message. + #[serde(with = "serde_utils::as_hex")] pub response: Vec, /// Timestamp at which this response expires in seconds. pub timeout_timestamp: u64, @@ -322,7 +332,7 @@ impl PostResponse { buf.extend_from_slice(&req.timeout_timestamp.to_be_bytes()); buf.extend_from_slice(&req.from); buf.extend_from_slice(&req.to); - buf.extend_from_slice(&req.data); + buf.extend_from_slice(&req.body); buf.extend_from_slice(&self.response); buf.extend_from_slice(&self.timeout_timestamp.to_be_bytes()); buf @@ -343,7 +353,7 @@ impl PostResponse { )] pub struct GetResponse { /// The Get request that triggered this response. - pub get: Get, + pub get: GetRequest, /// Values derived from the state proof pub values: BTreeMap, Option>>, } diff --git a/modules/ismp/pallets/asset-gateway/src/lib.rs b/modules/ismp/pallets/asset-gateway/src/lib.rs index 687c74cb4..5fda4de1b 100644 --- a/modules/ismp/pallets/asset-gateway/src/lib.rs +++ b/modules/ismp/pallets/asset-gateway/src/lib.rs @@ -305,7 +305,7 @@ where >::AssetId: From, T::AccountId: Into<[u8; 32]> + From<[u8; 32]>, { - fn on_accept(&self, post: ismp::router::Post) -> Result<(), ismp::error::Error> { + fn on_accept(&self, post: ismp::router::PostRequest) -> Result<(), ismp::error::Error> { let request = Request::Post(post.clone()); // Check that source module is equal to the known token gateway deployment address ensure!( @@ -339,7 +339,7 @@ where } ); - let body = Body::abi_decode(&mut &post.data[1..], true).map_err(|_| { + let body = Body::abi_decode(&mut &post.body[1..], true).map_err(|_| { ismp::error::Error::ModuleDispatchError { msg: "Token Gateway: Failed to decode request body".to_string(), meta: Meta { @@ -444,7 +444,7 @@ where }, })?; let beneficiary = fee_metadata.fee.payer; - let body = Body::abi_decode(&mut &post.data[1..], true).map_err(|_| { + let body = Body::abi_decode(&mut &post.body[1..], true).map_err(|_| { ismp::error::Error::ModuleDispatchError { msg: "Token Gateway: Failed to decode request body".to_string(), meta: Meta { diff --git a/modules/ismp/pallets/demo/src/lib.rs b/modules/ismp/pallets/demo/src/lib.rs index 68904a288..2782510fb 100644 --- a/modules/ismp/pallets/demo/src/lib.rs +++ b/modules/ismp/pallets/demo/src/lib.rs @@ -29,7 +29,7 @@ use ismp::{ error::Error as IsmpError, host::StateMachine, module::IsmpModule, - router::{Post, Request, Response, Timeout}, + router::{PostRequest, Request, Response, Timeout}, }; pub use pallet::*; use pallet_ismp::ModuleId; @@ -312,18 +312,18 @@ impl Default for IsmpModuleCallback { } impl IsmpModule for IsmpModuleCallback { - fn on_accept(&self, request: Post) -> Result<(), IsmpError> { + fn on_accept(&self, request: PostRequest) -> Result<(), IsmpError> { let source_chain = request.source; match source_chain { StateMachine::Ethereum(_) => Pallet::::deposit_event(Event::Request { source: source_chain, - data: unsafe { String::from_utf8_unchecked(request.data) }, + data: unsafe { String::from_utf8_unchecked(request.body) }, }), StateMachine::Polkadot(_) | StateMachine::Kusama(_) => { let payload = ::Balance> as codec::Decode>::decode( - &mut &*request.data, + &mut &*request.body, ) .map_err(|_| IsmpError::Custom("Failed to decode request data".to_string()))?; >::mint_into( @@ -365,7 +365,7 @@ impl IsmpModule for IsmpModuleCallback { let source_chain = request.source_chain(); let payload = ::Balance> as codec::Decode>::decode( - &mut &*request.data().expect("Request has been checked; qed"), + &mut &*request.body().expect("Request has been checked; qed"), ) .map_err(|_| IsmpError::Custom("Failed to decode request data".to_string()))?; >::mint_into( diff --git a/modules/ismp/pallets/hyperbridge/src/lib.rs b/modules/ismp/pallets/hyperbridge/src/lib.rs index d4bb91503..706c78f89 100644 --- a/modules/ismp/pallets/hyperbridge/src/lib.rs +++ b/modules/ismp/pallets/hyperbridge/src/lib.rs @@ -67,7 +67,7 @@ use frame_support::{ use ismp::{ dispatcher::{DispatchRequest, FeeMetadata, IsmpDispatcher}, module::IsmpModule, - router::{Post, PostResponse, Response, Timeout}, + router::{PostRequest, PostResponse, Response, Timeout}, }; use pallet_ismp::RELAYER_FEE_ACCOUNT; use primitive_types::H256; @@ -267,7 +267,7 @@ where T: Config, T::Balance: Into + From, { - fn on_accept(&self, request: Post) -> Result<(), ismp::Error> { + fn on_accept(&self, request: PostRequest) -> Result<(), ismp::Error> { // this of course assumes that hyperbridge is configured as the coprocessor. let source = request.source; if Some(source) != T::Coprocessor::get() { @@ -275,7 +275,7 @@ where } let message = - Message::::decode(&mut &request.data[..]).map_err(|err| { + Message::::decode(&mut &request.body[..]).map_err(|err| { ismp::Error::Custom(format!("Failed to decode per-byte fee: {err:?}")) })?; diff --git a/modules/ismp/pallets/pallet/src/dispatcher.rs b/modules/ismp/pallets/pallet/src/dispatcher.rs index d03b275de..8d00081e9 100644 --- a/modules/ismp/pallets/pallet/src/dispatcher.rs +++ b/modules/ismp/pallets/pallet/src/dispatcher.rs @@ -31,7 +31,7 @@ use ismp::{ host::IsmpHost, messaging::{hash_post_response, hash_request}, module::IsmpModule, - router::{Get, IsmpRouter, Post, PostResponse, Request, Response, Timeout}, + router::{GetRequest, IsmpRouter, PostRequest, PostResponse, Request, Response, Timeout}, }; use sp_core::H256; use sp_runtime::traits::{AccountIdConversion, Zero}; @@ -83,7 +83,7 @@ where let request = match request { DispatchRequest::Get(dispatch_get) => { - let get = Get { + let get = GetRequest { source: self.host_state_machine(), dest: dispatch_get.dest, nonce: self.next_nonce(), @@ -99,7 +99,7 @@ where Request::Get(get) }, DispatchRequest::Post(dispatch_post) => { - let post = Post { + let post = PostRequest { source: self.host_state_machine(), dest: dispatch_post.dest, nonce: self.next_nonce(), @@ -112,7 +112,7 @@ where .as_secs() .saturating_add(dispatch_post.timeout) }, - data: dispatch_post.body, + body: dispatch_post.body, }; Request::Post(post) }, @@ -198,7 +198,7 @@ impl RefundingModule { } impl IsmpModule for RefundingModule { - fn on_accept(&self, request: Post) -> Result<(), IsmpError> { + fn on_accept(&self, request: PostRequest) -> Result<(), IsmpError> { self.inner.on_accept(request) } diff --git a/modules/ismp/pallets/pallet/src/host.rs b/modules/ismp/pallets/pallet/src/host.rs index 9806bcc96..9e7ed457d 100644 --- a/modules/ismp/pallets/pallet/src/host.rs +++ b/modules/ismp/pallets/pallet/src/host.rs @@ -192,6 +192,15 @@ impl IsmpHost for Pallet { fn delete_state_commitment(&self, height: StateMachineHeight) -> Result<(), Error> { StateCommitments::::remove(height); + + // technically any state commitment can be vetoed, + // safety check that it's the latest before resetting it. + if let Some(latest) = LatestStateMachineHeight::::get(height.id) { + if latest == height.height { + // Reset back to the initial height to allow for honest updates + LatestStateMachineHeight::::insert(height.id, 1); + } + } Ok(()) } diff --git a/modules/ismp/pallets/pallet/src/weights.rs b/modules/ismp/pallets/pallet/src/weights.rs index 7229d380c..1b156ae15 100644 --- a/modules/ismp/pallets/pallet/src/weights.rs +++ b/modules/ismp/pallets/pallet/src/weights.rs @@ -20,14 +20,14 @@ use alloc::boxed::Box; use frame_support::weights::Weight; use ismp::{ messaging::{Message, TimeoutMessage}, - router::{GetResponse, Post, Request, RequestResponse, Response, Timeout}, + router::{GetResponse, PostRequest, Request, RequestResponse, Response, Timeout}, }; /// Interface for providing the weight information about [`IsmpModule`](ismp::module::IsmpModule) /// callbacks pub trait IsmpModuleWeight { /// Should return the weight used in processing this request - fn on_accept(&self, request: &Post) -> Weight; + fn on_accept(&self, request: &PostRequest) -> Weight; /// Should return the weight used in processing this timeout fn on_timeout(&self, request: &Timeout) -> Weight; /// Should return the weight used in processing this response @@ -35,7 +35,7 @@ pub trait IsmpModuleWeight { } impl IsmpModuleWeight for () { - fn on_accept(&self, _request: &Post) -> Weight { + fn on_accept(&self, _request: &PostRequest) -> Weight { Weight::zero() } fn on_timeout(&self, _request: &Timeout) -> Weight { diff --git a/modules/ismp/pallets/testsuite/src/runtime.rs b/modules/ismp/pallets/testsuite/src/runtime.rs index 7cb11c0af..f184d502b 100644 --- a/modules/ismp/pallets/testsuite/src/runtime.rs +++ b/modules/ismp/pallets/testsuite/src/runtime.rs @@ -34,7 +34,7 @@ use ismp::{ host::{Ethereum, IsmpHost, StateMachine}, messaging::{CreateConsensusState, Proof, StateCommitmentHeight}, module::IsmpModule, - router::{IsmpRouter, Post, RequestResponse, Response, Timeout}, + router::{IsmpRouter, PostRequest, RequestResponse, Response, Timeout}, Error, }; use ismp_sync_committee::constants::sepolia::Sepolia; @@ -238,7 +238,7 @@ impl pallet_call_decompressor::Config for Test { pub struct ErrorModule; impl IsmpModule for ErrorModule { - fn on_accept(&self, _request: Post) -> Result<(), Error> { + fn on_accept(&self, _request: PostRequest) -> Result<(), Error> { Err(Error::InsufficientProofHeight) } @@ -285,7 +285,7 @@ where pub struct MockModule; impl IsmpModule for MockModule { - fn on_accept(&self, _request: Post) -> Result<(), ismp::error::Error> { + fn on_accept(&self, _request: PostRequest) -> Result<(), ismp::error::Error> { Ok(()) } diff --git a/modules/ismp/pallets/testsuite/src/tests/pallet_asset_gateway.rs b/modules/ismp/pallets/testsuite/src/tests/pallet_asset_gateway.rs index cacdc582e..7da439ec7 100644 --- a/modules/ismp/pallets/testsuite/src/tests/pallet_asset_gateway.rs +++ b/modules/ismp/pallets/testsuite/src/tests/pallet_asset_gateway.rs @@ -10,7 +10,7 @@ use frame_support::{assert_ok, traits::fungibles::Inspect}; use ismp::{ host::{Ethereum, StateMachine}, module::IsmpModule, - router::{Post, Request, Timeout}, + router::{PostRequest, Request, Timeout}, }; use pallet_asset_gateway::{convert_to_erc20, Body, Module}; use sp_core::{ByteArray, H160}; @@ -151,14 +151,14 @@ fn should_process_on_accept_module_callback_correctly() { from: alloy_primitives::B256::from_slice(ALICE.as_slice()), to: alloy_primitives::B256::from_slice(ALICE.as_slice()), }; - let post = Post { + let post = PostRequest { source: StateMachine::Bsc, dest: StateMachine::Kusama(100), nonce: 0, from: H160::zero().0.to_vec(), to: H160::zero().0.to_vec(), timeout_timestamp: 0, - data: { + body: { let mut encoded = Body::abi_encode(&body); // Prefix with zero encoded.insert(0, 0); @@ -261,14 +261,14 @@ fn should_process_on_timeout_module_callback_correctly() { from: alloy_primitives::FixedBytes::<32>::from_slice(ALICE.as_slice()), to: alloy_primitives::FixedBytes::<32>::from_slice(ALICE.as_slice()), }; - let post = Post { + let post = PostRequest { source: StateMachine::Kusama(100), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: 0, from: H160::zero().0.to_vec(), to: H160::zero().0.to_vec(), timeout_timestamp: 1000 + (60 * 60), - data: { + body: { let mut encoded = Body::abi_encode(&body); // Prefix with zero encoded.insert(0, 0); diff --git a/modules/ismp/pallets/testsuite/src/tests/pallet_call_decompressor.rs b/modules/ismp/pallets/testsuite/src/tests/pallet_call_decompressor.rs index 09281ca25..695b58143 100644 --- a/modules/ismp/pallets/testsuite/src/tests/pallet_call_decompressor.rs +++ b/modules/ismp/pallets/testsuite/src/tests/pallet_call_decompressor.rs @@ -103,7 +103,7 @@ fn should_decompress_and_execute_pallet_ismp_get_response_calls_correctly() { let requests = (0..100) .into_iter() .map(|i| { - let get = ismp::router::Get { + let get = ismp::router::GetRequest { source: host.host_state_machine(), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: i, @@ -168,7 +168,7 @@ fn should_decompress_and_execute_pallet_ismp_get_time_out_calls_correctly() { let requests = (0..100) .into_iter() .map(|i| { - let get = ismp::router::Get { + let get = ismp::router::GetRequest { source: host.host_state_machine(), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: i, @@ -220,7 +220,7 @@ fn should_decompress_and_execute_pallet_ismp_post_request_calls_correctly() { let requests = (0..1000) .into_iter() .map(|i| { - let post = ismp::router::Post { + let post = ismp::router::PostRequest { source: host.host_state_machine(), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: i, @@ -228,7 +228,7 @@ fn should_decompress_and_execute_pallet_ismp_post_request_calls_correctly() { to: H256::random().0.to_vec(), timeout_timestamp: Duration::from_millis(Timestamp::now()).as_secs() + 2_000_000_000, - data: H512::random().0.to_vec(), + body: H512::random().0.to_vec(), }; post }) @@ -285,7 +285,7 @@ fn should_decompress_and_execute_pallet_ismp_post_response_calls_correctly() { let responses = (0..1000) .into_iter() .map(|i| { - let post = ismp::router::Post { + let post = ismp::router::PostRequest { source: host.host_state_machine(), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: i, @@ -293,7 +293,7 @@ fn should_decompress_and_execute_pallet_ismp_post_response_calls_correctly() { to: H256::random().0.to_vec(), timeout_timestamp: Duration::from_millis(Timestamp::now()).as_secs() + 2_000_000_000, - data: H512::random().0.to_vec(), + body: H512::random().0.to_vec(), }; ismp::router::Response::Post(PostResponse { post, diff --git a/modules/ismp/pallets/testsuite/src/tests/pallet_hyperbridge.rs b/modules/ismp/pallets/testsuite/src/tests/pallet_hyperbridge.rs index adc5b4a30..3fbffd474 100644 --- a/modules/ismp/pallets/testsuite/src/tests/pallet_hyperbridge.rs +++ b/modules/ismp/pallets/testsuite/src/tests/pallet_hyperbridge.rs @@ -23,7 +23,7 @@ use ismp::{ dispatcher::{DispatchPost, DispatchRequest, FeeMetadata, IsmpDispatcher}, host::{Ethereum, StateMachine}, module::IsmpModule, - router::Post, + router::PostRequest, }; use pallet_hyperbridge::{Message, VersionedHostParams, WithdrawalRequest, PALLET_HYPERBRIDGE}; use pallet_ismp::RELAYER_FEE_ACCOUNT; @@ -38,7 +38,7 @@ fn test_dispatch_fees() { ext.execute_with(|| { hyperbridge - .on_accept(Post { + .on_accept(PostRequest { // not the coprocessor so this should fail source: StateMachine::Polkadot(3368), dest: StateMachine::Polkadot(2001), @@ -46,7 +46,7 @@ fn test_dispatch_fees() { from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }) .unwrap_err(); @@ -54,7 +54,7 @@ fn test_dispatch_fees() { let params = VersionedHostParams::V1(10 * UNIT); let data = Message::::UpdateHostParams(params.clone()).encode(); hyperbridge - .on_accept(Post { + .on_accept(PostRequest { // source: Coprocessor::get().unwrap(), dest: StateMachine::Polkadot(2001), @@ -62,7 +62,7 @@ fn test_dispatch_fees() { from: vec![], to: vec![], timeout_timestamp: 0, - data, + body: data, }) .unwrap(); @@ -118,14 +118,14 @@ fn test_can_withdraw_relayer_and_protocol_revenue() { let data = Message::::WithdrawProtocolFees(withdrawal.clone()).encode(); hyperbridge - .on_accept(Post { + .on_accept(PostRequest { source: Coprocessor::get().unwrap(), dest: StateMachine::Polkadot(2001), nonce: 0, from: vec![], to: vec![], timeout_timestamp: 0, - data, + body: data, }) .unwrap(); @@ -134,14 +134,14 @@ fn test_can_withdraw_relayer_and_protocol_revenue() { let data = Message::::WithdrawRelayerFees(withdrawal.clone()).encode(); hyperbridge - .on_accept(Post { + .on_accept(PostRequest { source: Coprocessor::get().unwrap(), dest: StateMachine::Polkadot(2001), nonce: 0, from: vec![], to: vec![], timeout_timestamp: 0, - data, + body: data, }) .unwrap(); diff --git a/modules/ismp/pallets/testsuite/src/tests/pallet_ismp.rs b/modules/ismp/pallets/testsuite/src/tests/pallet_ismp.rs index 8cf839833..bf6d2d883 100644 --- a/modules/ismp/pallets/testsuite/src/tests/pallet_ismp.rs +++ b/modules/ismp/pallets/testsuite/src/tests/pallet_ismp.rs @@ -27,7 +27,7 @@ use ismp::{ dispatcher::{DispatchGet, DispatchRequest, FeeMetadata, IsmpDispatcher}, host::{Ethereum, IsmpHost, StateMachine}, messaging::{hash_request, Message, Proof, ResponseMessage, TimeoutMessage}, - router::{GetResponse, Post, Request, RequestResponse, Response, Timeout}, + router::{GetResponse, PostRequest, Request, RequestResponse, Response, Timeout}, }; use ismp_testsuite::{ check_challenge_period, check_client_expiry, missing_state_commitment_check, @@ -54,14 +54,14 @@ fn dispatcher_should_write_receipts_for_outgoing_requests_and_responses() { ext.execute_with(|| { set_timestamp(Some(1)); let host = Ismp::default(); - let post = Post { + let post = PostRequest { source: StateMachine::Kusama(2000), dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request_commitment = hash_request::(&Request::Post(post.clone())); @@ -154,7 +154,7 @@ fn should_handle_get_request_timeouts_correctly() { FeeMetadata { payer: [0u8; 32].into(), fee: Default::default() }, ) .unwrap(); - let get = ismp::router::Get { + let get = ismp::router::GetRequest { source: host.host_state_machine(), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: i, @@ -203,7 +203,7 @@ fn should_handle_get_request_responses_correctly() { FeeMetadata { payer: [0u8; 32].into(), fee: Default::default() }, ) .unwrap(); - let get = ismp::router::Get { + let get = ismp::router::GetRequest { source: host.host_state_machine(), dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), nonce: i, diff --git a/modules/ismp/pallets/testsuite/src/tests/pallet_ismp_relayer.rs b/modules/ismp/pallets/testsuite/src/tests/pallet_ismp_relayer.rs index 86a72251b..d1b5a2dc4 100644 --- a/modules/ismp/pallets/testsuite/src/tests/pallet_ismp_relayer.rs +++ b/modules/ismp/pallets/testsuite/src/tests/pallet_ismp_relayer.rs @@ -24,7 +24,7 @@ use ismp::{ consensus::{StateCommitment, StateMachineHeight, StateMachineId}, host::{IsmpHost, StateMachine}, messaging::{hash_post_response, hash_request, Proof}, - router::{Post, Request}, + router::{PostRequest, Request}, }; use pallet_ismp::{ child_trie::{RequestCommitments, RequestReceipts, ResponseCommitments, ResponseReceipts}, @@ -59,14 +59,14 @@ fn test_withdrawal_proof() { let requests = (0u64..10) .into_iter() .map(|nonce| { - let post = Post { + let post = PostRequest { source: StateMachine::Kusama(2000), dest: StateMachine::Kusama(2001), nonce, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; hash_request::(&Request::Post(post)) }) @@ -75,14 +75,14 @@ fn test_withdrawal_proof() { let responses = (0u64..10) .into_iter() .map(|nonce| { - let post = Post { + let post = PostRequest { source: StateMachine::Kusama(2001), dest: StateMachine::Kusama(2000), nonce, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; let response = ismp::router::PostResponse { post: post.clone(), diff --git a/modules/ismp/pallets/testsuite/src/tests/xcm_integration_test.rs b/modules/ismp/pallets/testsuite/src/tests/xcm_integration_test.rs index 31a02cc5b..ccf1ba28f 100644 --- a/modules/ismp/pallets/testsuite/src/tests/xcm_integration_test.rs +++ b/modules/ismp/pallets/testsuite/src/tests/xcm_integration_test.rs @@ -88,43 +88,56 @@ async fn should_dispatch_ismp_request_when_xcm_is_received() -> anyhow::Result<( call.encode(), ); - send_extrinsic(&client, signer, ext).await?; - - let sub = para_client.rpc().subscribe_finalized_block_headers().await?; - // Give enough time for the message to be processed - let block = sub - .take(8) - .collect::>() - .await - .into_iter() - .collect::, _>>()?; - let current_block = block - .last() - .cloned() - .ok_or_else(|| anyhow!("Finalized heads missing"))? + let init_block = para_client + .rpc() + .header(None) + .await? + .ok_or_else(|| anyhow!("Failed to fetch latest header"))? .number(); - let params = rpc_params![ - BlockNumberOrHash::::Number(1), - BlockNumberOrHash::::Number(current_block) - ]; - let response: HashMap> = - para_client.rpc().request("ismp_queryEvents", params).await?; + send_extrinsic(&client, signer, ext).await?; - let events = response.values().into_iter().cloned().flatten().collect::>(); - let post = events - .into_iter() - .find_map(|ev| match ev { - ismp::events::Event::PostRequest(post) => Some(post), - _ => None, - }) - .ok_or_else(|| anyhow!("Ismp Event should exist"))?; - - dbg!(&post); - - // Assert that this is the post we sent - assert_eq!(post.nonce, 0); - assert_eq!(post.dest, StateMachine::Ethereum(ismp::host::Ethereum::ExecutionLayer)); - assert_eq!(post.source, StateMachine::Kusama(2000)); - Ok(()) + let mut sub = para_client.rpc().subscribe_finalized_block_headers().await?; + + while let Some(res) = sub.next().await { + match res { + Ok(header) => { + // Break if we've waited too long + if header.number().saturating_sub(init_block) >= 500 { + Err(anyhow!("XCM Integration test failed: Post request event was not found"))? + } + + let params = rpc_params![ + BlockNumberOrHash::::Number(init_block), + BlockNumberOrHash::::Number(header.number()) + ]; + + let response: HashMap> = + para_client.rpc().request("ismp_queryEvents", params).await?; + + let events = response.values().into_iter().cloned().flatten().collect::>(); + if let Some(post) = events.into_iter().find_map(|ev| match ev { + ismp::events::Event::PostRequest(post) => Some(post), + _ => None, + }) { + dbg!(&post); + + // Assert that this is the post we sent + assert_eq!(post.nonce, 0); + assert_eq!( + post.dest, + StateMachine::Ethereum(ismp::host::Ethereum::ExecutionLayer) + ); + assert_eq!(post.source, StateMachine::Kusama(2000)); + return Ok(()); + } + }, + + Err(err) => { + println!("{err:?}") + }, + } + } + + Err(anyhow!("XCM Integration test failed")) } diff --git a/modules/ismp/pallets/token-governor/src/lib.rs b/modules/ismp/pallets/token-governor/src/lib.rs index 34db0f49e..c7539e8ca 100644 --- a/modules/ismp/pallets/token-governor/src/lib.rs +++ b/modules/ismp/pallets/token-governor/src/lib.rs @@ -23,7 +23,7 @@ mod impls; mod types; use alloy_sol_types::SolValue; use frame_support::pallet_prelude::Weight; -use ismp::router::{Post, Response, Timeout}; +use ismp::router::{PostRequest, Response, Timeout}; pub use types::*; use alloc::{format, vec}; @@ -381,7 +381,10 @@ pub mod pallet { } impl IsmpModule for Pallet { - fn on_accept(&self, Post { data, from, .. }: Post) -> Result<(), ismp::error::Error> { + fn on_accept( + &self, + PostRequest { body: data, from, .. }: PostRequest, + ) -> Result<(), ismp::error::Error> { let Params { token_registrar_address, .. } = ProtocolParams::::get() .ok_or_else(|| ismp::error::Error::Custom(format!("Pallet is not initialized")))?; if from != token_registrar_address.as_bytes().to_vec() { diff --git a/modules/ismp/state-machines/hyperbridge/src/lib.rs b/modules/ismp/state-machines/hyperbridge/src/lib.rs index 3f22cf76b..758547649 100644 --- a/modules/ismp/state-machines/hyperbridge/src/lib.rs +++ b/modules/ismp/state-machines/hyperbridge/src/lib.rs @@ -91,7 +91,7 @@ where ( RequestCommitments::::storage_key(commitment), RequestPayments::storage_key(commitment), - request.data().unwrap_or_default().len() as u128, + request.body().unwrap_or_default().len() as u128, ) }) .collect::>(), diff --git a/modules/ismp/testsuite/src/lib.rs b/modules/ismp/testsuite/src/lib.rs index 3098667fe..27f13e457 100644 --- a/modules/ismp/testsuite/src/lib.rs +++ b/modules/ismp/testsuite/src/lib.rs @@ -29,7 +29,7 @@ use ismp::{ hash_post_response, hash_request, ConsensusMessage, FraudProofMessage, Message, Proof, RequestMessage, ResponseMessage, TimeoutMessage, }, - router::{Post, PostResponse, Request, RequestResponse, Response}, + router::{PostRequest, PostResponse, Request, RequestResponse, Response}, }; use crate::mocks::{Host, MOCK_CONSENSUS_CLIENT_ID, MOCK_PROXY_CONSENSUS_CLIENT_ID}; @@ -112,14 +112,14 @@ pub fn check_challenge_period(host: &H) -> Result<(), &'static str> host.store_state_machine_update_time(intermediate_state.height, previous_update_time) .unwrap(); - let post = Post { + let post = PostRequest { source: intermediate_state.height.id.state_id, dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request = Request::Post(post.clone()); // Request message handling check @@ -189,14 +189,14 @@ pub fn frozen_consensus_client_check(host: &H) -> Result<(), &'stat .unwrap(); host.freeze_consensus_client(mock_consensus_state_id()).unwrap(); - let post = Post { + let post = PostRequest { source: intermediate_state.height.id.state_id, dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; // Request message handling check let request_message = Message::Request(RequestMessage { @@ -223,14 +223,14 @@ pub fn missing_state_commitment_check(host: &H) -> Result<(), &'sta .unwrap(); host.delete_state_commitment(intermediate_state.height).unwrap(); - let post = Post { + let post = PostRequest { source: intermediate_state.height.id.state_id, dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request = Request::Post(post.clone()); // Request message handling check @@ -291,14 +291,14 @@ where timeout: intermediate_state.commitment.timestamp, body: vec![0u8; 64], }; - let post = Post { + let post = PostRequest { source: host.host_state_machine(), dest: intermediate_state.height.id.state_id, nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: intermediate_state.commitment.timestamp, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request = Request::Post(post); let dispatch_request = DispatchRequest::Post(dispatch_post); @@ -358,14 +358,14 @@ where host.store_state_machine_update_time(intermediate_state.height, previous_update_time) .unwrap(); - let request = Post { + let request = PostRequest { source: intermediate_state.height.id.state_id, dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request_message = Message::Request(RequestMessage { @@ -426,27 +426,27 @@ where ) .map_err(|_| "Dispatcher failed to dispatch request")?; // Fetch commitment from storage - let post = Post { + let post = PostRequest { source: host.host_state_machine(), dest: StateMachine::Kusama(2000), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request = Request::Post(post); let commitment = hash_request::(&request); host.request_commitment(commitment) .map_err(|_| "Expected Request commitment to be found in storage")?; - let post = Post { + let post = PostRequest { source: StateMachine::Kusama(2000), dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let response = PostResponse { post, response: vec![], timeout_timestamp: 0 }; // Dispatch the outgoing response for the first time @@ -521,14 +521,14 @@ pub fn prevent_request_timeout_on_proxy_with_known_state_machine( body: vec![0u8; 64], }; - let post = Post { + let post = PostRequest { source: host.host_state_machine(), dest: direct_conn_state_machine, nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: proxy.commitment.timestamp, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request = Request::Post(post.clone()); @@ -601,14 +601,14 @@ pub fn prevent_response_timeout_on_proxy_with_known_state_machine( assert_ne!(proxy_consensus_client_id, destination_consensus_client_id); - let request = Post { + let request = PostRequest { source: direct_conn_state_machine, dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request_message = Message::Request(RequestMessage { @@ -683,14 +683,14 @@ pub fn prevent_request_processing_on_proxy_with_known_state_machine( assert_ne!(proxy_consensus_client_id, destination_consensus_client_id); - let request = Post { + let request = PostRequest { source: direct_conn_state_machine, dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request_message = Message::Request(RequestMessage { @@ -721,14 +721,14 @@ pub fn check_request_source_and_destination() -> Result<(), &'static str> { // Assert that No proxy is configured assert!(host.allowed_proxy().is_none()); - let request = Post { + let request = PostRequest { source: StateMachine::Kusama(13000), dest: host.host_state_machine(), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let request_message = Message::Request(RequestMessage { @@ -759,14 +759,14 @@ pub fn check_response_source() -> Result<(), &'static str> { // We assert that no proxy is configured assert!(host.allowed_proxy().is_none()); - let post = Post { + let post = PostRequest { source: host.host_state_machine(), dest: StateMachine::Polkadot(900), nonce: 0, from: vec![0u8; 32], to: vec![0u8; 32], timeout_timestamp: 0, - data: vec![0u8; 64], + body: vec![0u8; 64], }; let dispatch_post = DispatchPost { diff --git a/modules/ismp/testsuite/src/mocks.rs b/modules/ismp/testsuite/src/mocks.rs index 51efe65cf..0ae647a74 100644 --- a/modules/ismp/testsuite/src/mocks.rs +++ b/modules/ismp/testsuite/src/mocks.rs @@ -19,7 +19,10 @@ use ismp::{ host::{Ethereum, IsmpHost, StateMachine}, messaging::{hash_post_response, hash_request, hash_response, Keccak256, Proof}, module::IsmpModule, - router::{Get, IsmpRouter, Post, PostResponse, Request, RequestResponse, Response, Timeout}, + router::{ + GetRequest, IsmpRouter, PostRequest, PostResponse, Request, RequestResponse, Response, + Timeout, + }, }; #[derive(Default)] @@ -402,7 +405,7 @@ impl Keccak256 for Host { pub struct MockModule; impl IsmpModule for MockModule { - fn on_accept(&self, _request: Post) -> Result<(), Error> { + fn on_accept(&self, _request: PostRequest) -> Result<(), Error> { Ok(()) } @@ -437,7 +440,7 @@ impl IsmpDispatcher for Host { let host = self.clone(); let request = match request { DispatchRequest::Get(dispatch_get) => { - let get = Get { + let get = GetRequest { source: host.host_state_machine(), dest: dispatch_get.dest, nonce: host.next_nonce(), @@ -449,14 +452,14 @@ impl IsmpDispatcher for Host { Request::Get(get) }, DispatchRequest::Post(dispatch_post) => { - let post = Post { + let post = PostRequest { source: host.host_state_machine(), dest: dispatch_post.dest, nonce: host.next_nonce(), from: dispatch_post.from, to: dispatch_post.to, timeout_timestamp: dispatch_post.timeout, - data: dispatch_post.body, + body: dispatch_post.body, }; Request::Post(post) }, diff --git a/modules/utils/serde/Cargo.toml b/modules/utils/serde/Cargo.toml new file mode 100644 index 000000000..3c8d439f2 --- /dev/null +++ b/modules/utils/serde/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "serde-utils" +version = "0.1.0" +edition = "2021" + +[dependencies] +# crates.io +serde = { workspace = true, features = ["derive"] } +hex = { version = "0.4.3", features = ["alloc"], default-features = false } +anyhow = {workspace = true, default-features = false} + +[features] +default = ["std"] +std = [ + "serde/std", + "anyhow/std", + "hex/std" +] + +[dev-dependencies] +ismp = { workspace = true, default-features = true } +primitive-types = { workspace = true, features = ["codec", "scale-info", "serde_no_std"] } +serde_json = { version = "1.0.99", default-features = false, features = ["alloc"] } diff --git a/modules/utils/serde/src/lib.rs b/modules/utils/serde/src/lib.rs new file mode 100644 index 000000000..cbdfef535 --- /dev/null +++ b/modules/utils/serde/src/lib.rs @@ -0,0 +1,334 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Utilities for serde serialization and deserialization + +#![cfg_attr(not(feature = "std"), no_std)] +#![deny(missing_docs)] + +extern crate alloc; +use alloc::{format, vec::Vec}; +use anyhow::anyhow; + +const HEX_ENCODING_PREFIX: &str = "0x"; + +/// Vec from Hex string +pub fn try_bytes_from_hex_str(s: &str) -> Result, anyhow::Error> { + let target = s.replace(HEX_ENCODING_PREFIX, ""); + let data = hex::decode(target).map_err(|e| anyhow!("{e:?}"))?; + Ok(data) +} + +/// Hex serializer and Deserializer for Vec +pub mod as_hex { + use super::*; + use alloc::string::String; + use serde::de::Deserialize; + + /// Serialize Vec into hex string + pub fn serialize>(data: T, serializer: S) -> Result + where + S: serde::Serializer, + { + let encoding = hex::encode(data.as_ref()); + let output = format!("{HEX_ENCODING_PREFIX}{encoding}"); + serializer.collect_str(&output) + } + + /// Deserialize hex string into Vec + pub fn deserialize<'de, D, T>(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + T: TryFrom>, + { + let s = ::deserialize(deserializer)?; + + let data = try_bytes_from_hex_str(&s).map_err(serde::de::Error::custom)?; + + let inner = T::try_from(data) + .map_err(|_| serde::de::Error::custom("type failed to parse bytes from hex data"))?; + Ok(inner) + } +} + +/// Hex serializer and Deserializer for utf8 bytes +pub mod as_utf8_string { + use super::*; + use alloc::string::String; + use serde::de::Deserialize; + + /// Serialize [u8;4] into a utf8 string + pub fn serialize>(data: T, serializer: S) -> Result + where + S: serde::Serializer, + { + let output = + String::from_utf8(data.as_ref().to_vec()).map_err(serde::ser::Error::custom)?; + serializer.collect_str(&output) + } + + /// Deserialize a string into utf8 bytes + pub fn deserialize<'de, D, T>(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + T: From<[u8; 4]>, + { + let s = ::deserialize(deserializer)?; + + let mut bytes = [0u8; 4]; + bytes.copy_from_slice(s.as_bytes()); + Ok(bytes.into()) + } +} + +/// Hex serializer and Deserializer for Vec> +pub mod seq_of_hex { + use super::*; + use core::{fmt, marker::PhantomData}; + use serde::{de::Deserializer, ser::SerializeSeq}; + + /// Serialize Vec> into an array of hex string + pub fn serialize(data: T, serializer: S) -> Result + where + S: serde::Serializer, + T: AsRef<[Vec]>, + { + let mut seq = serializer.serialize_seq(None)?; + for elem in data.as_ref().iter() { + let encoding = hex::encode(elem); + let output = format!("{HEX_ENCODING_PREFIX}{encoding}"); + seq.serialize_element(&output)?; + } + seq.end() + } + + struct Visitor(PhantomData>>); + + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = Vec>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("sequence of string") + } + + fn visit_seq(self, mut access: S) -> Result + where + S: serde::de::SeqAccess<'de>, + { + let mut coll = Vec::with_capacity(access.size_hint().unwrap_or(0)); + + while let Some(elem) = access.next_element()? { + let recovered_elem = + try_bytes_from_hex_str(elem).map_err(serde::de::Error::custom)?; + coll.push(recovered_elem); + } + Ok(coll) + } + } + + /// Deserialize for an array of hex strings into Vec> + pub fn deserialize<'de, D>(deserializer: D) -> Result>, D::Error> + where + D: Deserializer<'de>, + { + let data = deserializer.deserialize_seq(Visitor(PhantomData))?; + Ok(data) + } +} + +/// String serializer and deserializer +pub mod as_string { + use alloc::{format, string::String}; + use core::{fmt, str::FromStr}; + use serde::de::Deserialize; + + /// Serialize into a string + pub fn serialize(data: T, serializer: S) -> Result + where + S: serde::Serializer, + { + let output = format!("{data}"); + serializer.collect_str(&output) + } + + /// Deserialize from string + pub fn deserialize<'de, D, T: FromStr>(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s: String = ::deserialize(deserializer)?; + let inner: T = s + .parse() + .map_err(|_| serde::de::Error::custom("failure to parse string data"))?; + Ok(inner) + } +} + +/// Serializing a sequence of any generic types into a sequence of strings +pub mod seq_of_str { + use super::*; + use core::{fmt, marker::PhantomData, str::FromStr}; + use serde::{ + de::{Deserializer, Error}, + ser::SerializeSeq, + }; + + /// Serialize generic type into a sequence of strings + pub fn serialize(data: T, serializer: S) -> Result + where + S: serde::Serializer, + T: AsRef<[U]>, + U: fmt::Display, + { + let mut seq = serializer.serialize_seq(None)?; + for elem in data.as_ref().iter() { + let rendered_elem = format!("{elem}"); + seq.serialize_element(&rendered_elem)?; + } + seq.end() + } + + struct Visitor(PhantomData>); + + impl<'de, T: FromStr> serde::de::Visitor<'de> for Visitor { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("sequence of string") + } + + fn visit_seq(self, mut access: S) -> Result + where + S: serde::de::SeqAccess<'de>, + { + let mut coll = Vec::with_capacity(access.size_hint().unwrap_or(0)); + + while let Some(elem) = access.next_element()? { + let recovered_elem = T::from_str(elem).map_err(|_| { + Error::custom("failure to parse element of sequence from string") + })?; + coll.push(recovered_elem); + } + Ok(coll) + } + } + + /// Deserialize generic type from a sequence of strings + pub fn deserialize<'de, D, T, U>(deserializer: D) -> Result + where + D: Deserializer<'de>, + T: TryFrom>, + U: FromStr, + { + let data = deserializer.deserialize_seq(Visitor(PhantomData))?; + T::try_from(data).map_err(|_| serde::de::Error::custom("failure to parse collection")) + } +} + +#[cfg(test)] +mod test { + use primitive_types::{H256, H512}; + + use ismp::router::{GetRequest, PostRequest, PostResponse}; + + #[test] + fn serialize_and_deserialize_post_request() { + let post = PostRequest { + source: ismp::host::StateMachine::Polkadot(100), + dest: ismp::host::StateMachine::Polkadot(2000), + nonce: 300, + from: H256::random().0.to_vec(), + to: H256::random().0.to_vec(), + timeout_timestamp: 0, + body: H512::random().0.to_vec(), + }; + + let serialized = serde_json::to_string(&post).unwrap(); + + println!("{serialized:?}\n"); + + let deserialized: PostRequest = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(post, deserialized); + } + + #[test] + fn serialize_and_deserialize_post_response() { + let post = PostRequest { + source: ismp::host::StateMachine::Polkadot(100), + dest: ismp::host::StateMachine::Polkadot(2000), + nonce: 300, + from: H256::random().0.to_vec(), + to: H256::random().0.to_vec(), + timeout_timestamp: 0, + body: H512::random().0.to_vec(), + }; + + let response = + PostResponse { post, response: H512::random().0.to_vec(), timeout_timestamp: 30000 }; + + let serialized = serde_json::to_string(&response).unwrap(); + + println!("{serialized:?}\n"); + + let deserialized: PostResponse = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(response, deserialized); + } + + #[test] + fn serialize_and_deserialize_get_request() { + let get = GetRequest { + source: ismp::host::StateMachine::Polkadot(100), + dest: ismp::host::StateMachine::Polkadot(2000), + nonce: 300, + from: H256::random().0.to_vec(), + keys: vec![ + H256::random().0.to_vec(), + H256::random().0.to_vec(), + H256::random().0.to_vec(), + ], + timeout_timestamp: 40000, + height: 289900, + }; + + let serialized = serde_json::to_string(&get).unwrap(); + + println!("{serialized:?}\n"); + + let deserialized: GetRequest = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(get, deserialized); + } + + #[test] + fn serialize_state_machine_id() { + use ismp::{ + consensus::StateMachineId, + host::{Ethereum, StateMachine}, + }; + let state_machine_updated = StateMachineId { + state_id: StateMachine::Ethereum(Ethereum::ExecutionLayer), + consensus_state_id: *b"ETH0", + }; + let serialized = serde_json::to_string(&state_machine_updated).unwrap(); + + println!("{serialized:?}\n"); + + let deserialized: StateMachineId = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(state_machine_updated, deserialized); + } +} diff --git a/modules/subxt/utils/Cargo.toml b/modules/utils/subxt/Cargo.toml similarity index 100% rename from modules/subxt/utils/Cargo.toml rename to modules/utils/subxt/Cargo.toml diff --git a/modules/subxt/utils/src/client.rs b/modules/utils/subxt/src/client.rs similarity index 100% rename from modules/subxt/utils/src/client.rs rename to modules/utils/subxt/src/client.rs diff --git a/modules/subxt/utils/src/gargantua.rs b/modules/utils/subxt/src/gargantua.rs similarity index 99% rename from modules/subxt/utils/src/gargantua.rs rename to modules/utils/subxt/src/gargantua.rs index 7af3d024b..358b8724a 100644 --- a/modules/subxt/utils/src/gargantua.rs +++ b/modules/utils/subxt/src/gargantua.rs @@ -245,7 +245,8 @@ pub mod api { &self, included_hash: ::subxt::utils::H256, slot: runtime_types::sp_consensus_slots::Slot, - ) -> ::subxt::runtime_api::Payload { + ) -> ::subxt::runtime_api::Payload + { ::subxt::runtime_api::Payload::new_static( "AuraUnincludedSegmentApi", "can_build_upon", @@ -853,7 +854,8 @@ pub mod api { pub fn account_nonce( &self, account: ::subxt::utils::AccountId32, - ) -> ::subxt::runtime_api::Payload { + ) -> ::subxt::runtime_api::Payload + { ::subxt::runtime_api::Payload::new_static( "AccountNonceApi", "account_nonce", @@ -1054,10 +1056,10 @@ pub mod api { "query_call_info", types::QueryCallInfo { call, len }, [ - 144u8, 96u8, 80u8, 104u8, 119u8, 76u8, 155u8, 142u8, 104u8, 157u8, - 228u8, 64u8, 127u8, 181u8, 82u8, 220u8, 67u8, 62u8, 86u8, 254u8, 142u8, - 243u8, 167u8, 254u8, 215u8, 183u8, 61u8, 194u8, 24u8, 142u8, 204u8, - 121u8, + 75u8, 200u8, 231u8, 50u8, 131u8, 102u8, 164u8, 238u8, 110u8, 42u8, + 72u8, 75u8, 27u8, 126u8, 197u8, 112u8, 138u8, 2u8, 211u8, 148u8, 20u8, + 233u8, 244u8, 84u8, 188u8, 162u8, 89u8, 19u8, 168u8, 115u8, 121u8, + 192u8, ], ) } @@ -1077,9 +1079,10 @@ pub mod api { "query_call_fee_details", types::QueryCallFeeDetails { call, len }, [ - 99u8, 245u8, 14u8, 121u8, 197u8, 66u8, 66u8, 195u8, 126u8, 91u8, 139u8, - 144u8, 144u8, 220u8, 93u8, 126u8, 20u8, 157u8, 91u8, 9u8, 186u8, 78u8, - 68u8, 97u8, 35u8, 242u8, 45u8, 87u8, 121u8, 168u8, 238u8, 52u8, + 183u8, 237u8, 22u8, 155u8, 167u8, 74u8, 194u8, 193u8, 79u8, 186u8, + 121u8, 155u8, 104u8, 185u8, 44u8, 118u8, 215u8, 25u8, 155u8, 105u8, + 142u8, 248u8, 144u8, 62u8, 22u8, 1u8, 55u8, 26u8, 3u8, 81u8, 101u8, + 200u8, ], ) } @@ -1382,10 +1385,10 @@ pub mod api { "generate_proof", types::GenerateProof { commitments }, [ - 245u8, 234u8, 143u8, 97u8, 132u8, 81u8, 177u8, 36u8, 110u8, 62u8, 9u8, - 95u8, 94u8, 232u8, 109u8, 133u8, 178u8, 155u8, 118u8, 56u8, 169u8, - 232u8, 248u8, 104u8, 211u8, 118u8, 54u8, 48u8, 160u8, 47u8, 10u8, - 121u8, + 195u8, 59u8, 24u8, 130u8, 146u8, 41u8, 244u8, 115u8, 22u8, 204u8, 12u8, + 238u8, 78u8, 228u8, 250u8, 182u8, 97u8, 66u8, 131u8, 113u8, 119u8, + 224u8, 39u8, 101u8, 92u8, 162u8, 249u8, 36u8, 173u8, 169u8, 20u8, + 204u8, ], ) } @@ -1401,9 +1404,10 @@ pub mod api { "block_events", types::BlockEvents {}, [ - 35u8, 81u8, 104u8, 132u8, 54u8, 143u8, 116u8, 169u8, 126u8, 5u8, 130u8, - 250u8, 168u8, 126u8, 178u8, 8u8, 167u8, 124u8, 11u8, 208u8, 125u8, - 239u8, 10u8, 143u8, 191u8, 0u8, 217u8, 149u8, 244u8, 151u8, 17u8, 47u8, + 117u8, 117u8, 10u8, 114u8, 126u8, 138u8, 41u8, 13u8, 44u8, 180u8, + 220u8, 185u8, 50u8, 144u8, 58u8, 232u8, 120u8, 130u8, 129u8, 69u8, + 145u8, 6u8, 189u8, 255u8, 184u8, 204u8, 97u8, 41u8, 83u8, 127u8, 191u8, + 247u8, ], ) } @@ -1422,9 +1426,9 @@ pub mod api { "block_events_with_metadata", types::BlockEventsWithMetadata {}, [ - 48u8, 80u8, 19u8, 88u8, 188u8, 127u8, 45u8, 31u8, 60u8, 69u8, 75u8, - 204u8, 32u8, 142u8, 2u8, 241u8, 231u8, 18u8, 189u8, 31u8, 82u8, 51u8, - 86u8, 42u8, 115u8, 105u8, 113u8, 204u8, 141u8, 3u8, 67u8, 93u8, + 22u8, 59u8, 32u8, 3u8, 104u8, 73u8, 250u8, 52u8, 57u8, 109u8, 84u8, + 218u8, 81u8, 125u8, 85u8, 158u8, 110u8, 208u8, 129u8, 32u8, 97u8, 60u8, + 61u8, 214u8, 51u8, 37u8, 218u8, 161u8, 25u8, 41u8, 58u8, 197u8, ], ) } @@ -1517,9 +1521,9 @@ pub mod api { "requests", types::Requests { request_commitments }, [ - 192u8, 240u8, 138u8, 217u8, 75u8, 178u8, 17u8, 55u8, 205u8, 83u8, 32u8, - 214u8, 19u8, 7u8, 227u8, 96u8, 122u8, 1u8, 43u8, 80u8, 153u8, 208u8, - 231u8, 93u8, 11u8, 122u8, 159u8, 151u8, 87u8, 151u8, 217u8, 90u8, + 241u8, 12u8, 67u8, 122u8, 104u8, 91u8, 182u8, 225u8, 151u8, 222u8, + 59u8, 119u8, 211u8, 216u8, 32u8, 180u8, 171u8, 37u8, 4u8, 103u8, 209u8, + 16u8, 0u8, 234u8, 115u8, 251u8, 113u8, 105u8, 81u8, 205u8, 243u8, 30u8, ], ) } @@ -1536,9 +1540,10 @@ pub mod api { "responses", types::Responses { response_commitments }, [ - 86u8, 149u8, 42u8, 253u8, 51u8, 235u8, 51u8, 181u8, 186u8, 9u8, 81u8, - 200u8, 7u8, 18u8, 241u8, 183u8, 105u8, 255u8, 47u8, 81u8, 31u8, 250u8, - 143u8, 3u8, 8u8, 183u8, 237u8, 209u8, 24u8, 172u8, 240u8, 115u8, + 15u8, 124u8, 147u8, 173u8, 119u8, 27u8, 148u8, 229u8, 110u8, 88u8, + 236u8, 126u8, 29u8, 187u8, 220u8, 183u8, 134u8, 118u8, 117u8, 111u8, + 54u8, 30u8, 222u8, 96u8, 113u8, 70u8, 207u8, 121u8, 147u8, 252u8, 28u8, + 239u8, ], ) } @@ -1937,9 +1942,10 @@ pub mod api { "create_transaction", types::CreateTransaction { account, call }, [ - 97u8, 82u8, 52u8, 42u8, 107u8, 240u8, 4u8, 113u8, 127u8, 188u8, 66u8, - 204u8, 129u8, 70u8, 54u8, 181u8, 120u8, 223u8, 178u8, 17u8, 135u8, - 38u8, 167u8, 95u8, 0u8, 80u8, 163u8, 41u8, 46u8, 215u8, 98u8, 169u8, + 124u8, 37u8, 251u8, 205u8, 181u8, 207u8, 31u8, 209u8, 44u8, 171u8, + 118u8, 86u8, 188u8, 169u8, 101u8, 246u8, 202u8, 203u8, 148u8, 80u8, + 71u8, 66u8, 155u8, 239u8, 35u8, 143u8, 123u8, 102u8, 236u8, 196u8, + 59u8, 50u8, ], ) } @@ -2146,9 +2152,9 @@ pub mod api { .hash(); runtime_metadata_hash == [ - 88u8, 211u8, 43u8, 185u8, 52u8, 81u8, 20u8, 222u8, 37u8, 128u8, 143u8, 3u8, 237u8, - 182u8, 19u8, 123u8, 57u8, 233u8, 219u8, 227u8, 34u8, 229u8, 180u8, 126u8, 166u8, - 248u8, 197u8, 167u8, 77u8, 227u8, 238u8, 239u8, + 132u8, 81u8, 91u8, 210u8, 0u8, 171u8, 141u8, 128u8, 137u8, 181u8, 25u8, 210u8, + 65u8, 16u8, 152u8, 235u8, 8u8, 81u8, 250u8, 148u8, 195u8, 149u8, 72u8, 198u8, + 121u8, 214u8, 1u8, 114u8, 169u8, 66u8, 72u8, 134u8, ] } pub mod system { @@ -3251,7 +3257,8 @@ pub mod api { #[doc = " The maximum length of a block (in bytes)."] pub fn block_length( &self, - ) -> ::subxt::constants::Address { + ) -> ::subxt::constants::Address + { ::subxt::constants::Address::new_static( "System", "BlockLength", @@ -4507,9 +4514,9 @@ pub mod api { "batch", types::Batch { calls }, [ - 255u8, 35u8, 12u8, 149u8, 48u8, 170u8, 206u8, 26u8, 49u8, 25u8, 103u8, - 61u8, 38u8, 171u8, 113u8, 17u8, 93u8, 179u8, 129u8, 242u8, 198u8, - 185u8, 9u8, 55u8, 232u8, 136u8, 130u8, 28u8, 87u8, 1u8, 154u8, 206u8, + 225u8, 186u8, 6u8, 231u8, 131u8, 149u8, 225u8, 47u8, 144u8, 113u8, + 222u8, 195u8, 79u8, 145u8, 217u8, 199u8, 219u8, 130u8, 40u8, 8u8, 49u8, + 1u8, 56u8, 208u8, 25u8, 187u8, 71u8, 29u8, 193u8, 76u8, 146u8, 63u8, ], ) } @@ -4524,10 +4531,9 @@ pub mod api { "as_derivative", types::AsDerivative { index, call: ::std::boxed::Box::new(call) }, [ - 76u8, 85u8, 59u8, 189u8, 51u8, 252u8, 254u8, 156u8, 183u8, 76u8, 184u8, - 204u8, 204u8, 16u8, 215u8, 250u8, 134u8, 234u8, 131u8, 19u8, 226u8, - 11u8, 237u8, 234u8, 204u8, 254u8, 163u8, 73u8, 35u8, 139u8, 137u8, - 51u8, + 137u8, 236u8, 115u8, 51u8, 11u8, 184u8, 213u8, 92u8, 243u8, 231u8, + 133u8, 30u8, 236u8, 8u8, 168u8, 218u8, 63u8, 128u8, 74u8, 238u8, 88u8, + 7u8, 69u8, 111u8, 154u8, 16u8, 62u8, 10u8, 4u8, 211u8, 163u8, 191u8, ], ) } @@ -4541,10 +4547,10 @@ pub mod api { "batch_all", types::BatchAll { calls }, [ - 211u8, 23u8, 61u8, 109u8, 28u8, 211u8, 10u8, 198u8, 222u8, 151u8, - 178u8, 1u8, 56u8, 39u8, 219u8, 121u8, 164u8, 39u8, 135u8, 242u8, 29u8, - 94u8, 67u8, 216u8, 180u8, 128u8, 165u8, 74u8, 170u8, 177u8, 193u8, - 208u8, + 163u8, 161u8, 186u8, 214u8, 130u8, 246u8, 73u8, 172u8, 162u8, 6u8, + 204u8, 93u8, 24u8, 40u8, 109u8, 214u8, 240u8, 139u8, 213u8, 23u8, 85u8, + 249u8, 90u8, 187u8, 194u8, 33u8, 185u8, 133u8, 106u8, 50u8, 199u8, + 84u8, ], ) } @@ -4562,9 +4568,9 @@ pub mod api { call: ::std::boxed::Box::new(call), }, [ - 237u8, 100u8, 33u8, 137u8, 68u8, 246u8, 27u8, 180u8, 22u8, 184u8, 7u8, - 160u8, 144u8, 70u8, 170u8, 63u8, 63u8, 102u8, 36u8, 234u8, 107u8, 71u8, - 110u8, 7u8, 174u8, 175u8, 61u8, 63u8, 244u8, 109u8, 150u8, 233u8, + 184u8, 116u8, 58u8, 207u8, 147u8, 176u8, 1u8, 32u8, 88u8, 80u8, 42u8, + 179u8, 70u8, 28u8, 19u8, 197u8, 213u8, 126u8, 192u8, 56u8, 221u8, 52u8, + 189u8, 191u8, 61u8, 36u8, 129u8, 193u8, 138u8, 40u8, 167u8, 200u8, ], ) } @@ -4578,9 +4584,9 @@ pub mod api { "force_batch", types::ForceBatch { calls }, [ - 179u8, 100u8, 46u8, 110u8, 57u8, 184u8, 153u8, 15u8, 118u8, 196u8, - 37u8, 249u8, 213u8, 104u8, 42u8, 254u8, 172u8, 37u8, 43u8, 119u8, 8u8, - 193u8, 78u8, 150u8, 229u8, 113u8, 221u8, 236u8, 98u8, 94u8, 82u8, 90u8, + 93u8, 111u8, 10u8, 172u8, 54u8, 231u8, 75u8, 97u8, 121u8, 138u8, 245u8, + 50u8, 248u8, 119u8, 243u8, 42u8, 13u8, 84u8, 36u8, 160u8, 235u8, 114u8, + 2u8, 134u8, 136u8, 135u8, 39u8, 217u8, 30u8, 233u8, 95u8, 11u8, ], ) } @@ -4595,10 +4601,10 @@ pub mod api { "with_weight", types::WithWeight { call: ::std::boxed::Box::new(call), weight }, [ - 6u8, 75u8, 32u8, 225u8, 9u8, 30u8, 251u8, 15u8, 95u8, 37u8, 122u8, - 130u8, 119u8, 24u8, 71u8, 109u8, 239u8, 221u8, 33u8, 127u8, 40u8, - 229u8, 255u8, 140u8, 238u8, 114u8, 71u8, 39u8, 102u8, 147u8, 177u8, - 133u8, + 232u8, 112u8, 135u8, 31u8, 182u8, 103u8, 98u8, 203u8, 131u8, 185u8, + 29u8, 98u8, 207u8, 249u8, 75u8, 139u8, 114u8, 170u8, 165u8, 207u8, + 241u8, 59u8, 221u8, 153u8, 250u8, 209u8, 106u8, 217u8, 192u8, 5u8, + 93u8, 145u8, ], ) } @@ -7376,9 +7382,9 @@ pub mod api { "sudo", types::Sudo { call: ::std::boxed::Box::new(call) }, [ - 93u8, 34u8, 53u8, 147u8, 141u8, 165u8, 14u8, 23u8, 191u8, 42u8, 29u8, - 160u8, 208u8, 154u8, 217u8, 177u8, 148u8, 162u8, 149u8, 45u8, 17u8, - 35u8, 34u8, 144u8, 162u8, 33u8, 212u8, 84u8, 33u8, 127u8, 169u8, 14u8, + 59u8, 172u8, 143u8, 207u8, 182u8, 60u8, 222u8, 219u8, 73u8, 100u8, 2u8, + 131u8, 0u8, 216u8, 137u8, 92u8, 226u8, 51u8, 37u8, 174u8, 109u8, 177u8, + 238u8, 120u8, 125u8, 250u8, 180u8, 153u8, 255u8, 19u8, 127u8, 195u8, ], ) } @@ -7393,10 +7399,10 @@ pub mod api { "sudo_unchecked_weight", types::SudoUncheckedWeight { call: ::std::boxed::Box::new(call), weight }, [ - 203u8, 172u8, 2u8, 36u8, 119u8, 222u8, 143u8, 187u8, 165u8, 38u8, - 153u8, 115u8, 253u8, 126u8, 154u8, 155u8, 90u8, 90u8, 255u8, 114u8, - 0u8, 135u8, 2u8, 25u8, 80u8, 10u8, 55u8, 23u8, 172u8, 113u8, 220u8, - 21u8, + 225u8, 195u8, 26u8, 229u8, 229u8, 227u8, 122u8, 137u8, 62u8, 153u8, + 93u8, 83u8, 162u8, 167u8, 5u8, 41u8, 8u8, 231u8, 239u8, 112u8, 239u8, + 123u8, 17u8, 121u8, 50u8, 66u8, 104u8, 80u8, 132u8, 123u8, 165u8, + 194u8, ], ) } @@ -7427,9 +7433,9 @@ pub mod api { "sudo_as", types::SudoAs { who, call: ::std::boxed::Box::new(call) }, [ - 27u8, 32u8, 111u8, 117u8, 158u8, 56u8, 144u8, 38u8, 16u8, 189u8, 236u8, - 108u8, 46u8, 50u8, 151u8, 231u8, 221u8, 60u8, 230u8, 123u8, 101u8, - 50u8, 114u8, 181u8, 230u8, 68u8, 89u8, 229u8, 9u8, 214u8, 154u8, 161u8, + 140u8, 129u8, 204u8, 238u8, 72u8, 61u8, 23u8, 3u8, 121u8, 129u8, 243u8, + 224u8, 103u8, 117u8, 86u8, 14u8, 35u8, 59u8, 16u8, 164u8, 30u8, 94u8, + 144u8, 38u8, 84u8, 247u8, 119u8, 237u8, 107u8, 157u8, 71u8, 227u8, ], ) } @@ -9784,9 +9790,9 @@ pub mod api { "IntermediateLeaves", vec![::subxt::storage::address::make_static_storage_map_key(_0.borrow())], [ - 91u8, 140u8, 225u8, 205u8, 25u8, 219u8, 7u8, 146u8, 157u8, 73u8, 224u8, - 33u8, 99u8, 231u8, 94u8, 80u8, 230u8, 9u8, 17u8, 45u8, 243u8, 233u8, - 125u8, 194u8, 115u8, 124u8, 217u8, 33u8, 217u8, 85u8, 51u8, 63u8, + 222u8, 45u8, 165u8, 55u8, 14u8, 85u8, 78u8, 242u8, 11u8, 44u8, 255u8, + 47u8, 112u8, 59u8, 26u8, 87u8, 194u8, 209u8, 223u8, 199u8, 39u8, 122u8, + 177u8, 100u8, 112u8, 167u8, 54u8, 66u8, 180u8, 127u8, 104u8, 122u8, ], ) } @@ -9805,9 +9811,9 @@ pub mod api { "IntermediateLeaves", Vec::new(), [ - 91u8, 140u8, 225u8, 205u8, 25u8, 219u8, 7u8, 146u8, 157u8, 73u8, 224u8, - 33u8, 99u8, 231u8, 94u8, 80u8, 230u8, 9u8, 17u8, 45u8, 243u8, 233u8, - 125u8, 194u8, 115u8, 124u8, 217u8, 33u8, 217u8, 85u8, 51u8, 63u8, + 222u8, 45u8, 165u8, 55u8, 14u8, 85u8, 78u8, 242u8, 11u8, 44u8, 255u8, + 47u8, 112u8, 59u8, 26u8, 87u8, 194u8, 209u8, 223u8, 199u8, 39u8, 122u8, + 177u8, 100u8, 112u8, 167u8, 54u8, 66u8, 180u8, 127u8, 104u8, 122u8, ], ) } @@ -10012,9 +10018,9 @@ pub mod api { "handle_unsigned", types::HandleUnsigned { messages }, [ - 162u8, 61u8, 203u8, 66u8, 47u8, 157u8, 234u8, 37u8, 65u8, 117u8, 46u8, - 84u8, 215u8, 162u8, 97u8, 5u8, 20u8, 244u8, 87u8, 199u8, 69u8, 24u8, - 42u8, 52u8, 210u8, 1u8, 163u8, 40u8, 240u8, 224u8, 143u8, 141u8, + 197u8, 89u8, 197u8, 57u8, 62u8, 108u8, 239u8, 217u8, 36u8, 190u8, 86u8, + 48u8, 164u8, 4u8, 114u8, 184u8, 30u8, 114u8, 98u8, 88u8, 53u8, 42u8, + 104u8, 20u8, 81u8, 179u8, 211u8, 187u8, 76u8, 130u8, 94u8, 121u8, ], ) } @@ -16997,11 +17003,11 @@ pub mod api { #[codec(index = 1)] StateCommitmentVetoed(runtime_types::ismp::events::StateCommitmentVetoed), #[codec(index = 2)] - PostRequest(runtime_types::ismp::router::Post), + PostRequest(runtime_types::ismp::router::PostRequest), #[codec(index = 3)] PostResponse(runtime_types::ismp::router::PostResponse), #[codec(index = 4)] - GetRequest(runtime_types::ismp::router::Get), + GetRequest(runtime_types::ismp::router::GetRequest), #[codec(index = 5)] PostRequestHandled(runtime_types::ismp::events::RequestResponseHandled), #[codec(index = 6)] @@ -17284,7 +17290,7 @@ pub mod api { #[decode_as_type(crate_path = ":: subxt :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt :: ext :: scale_encode")] pub struct RequestMessage { - pub requests: ::std::vec::Vec, + pub requests: ::std::vec::Vec, pub proof: runtime_types::ismp::messaging::Proof, pub signer: ::std::vec::Vec<::core::primitive::u8>, } @@ -17366,7 +17372,7 @@ pub mod api { # [codec (crate = :: subxt :: ext :: codec)] #[decode_as_type(crate_path = ":: subxt :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt :: ext :: scale_encode")] - pub struct Get { + pub struct GetRequest { pub source: runtime_types::ismp::host::StateMachine, pub dest: runtime_types::ismp::host::StateMachine, pub nonce: ::core::primitive::u64, @@ -17389,7 +17395,7 @@ pub mod api { #[decode_as_type(crate_path = ":: subxt :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt :: ext :: scale_encode")] pub struct GetResponse { - pub get: runtime_types::ismp::router::Get, + pub get: runtime_types::ismp::router::GetRequest, pub values: ::subxt::utils::KeyedVec< ::std::vec::Vec<::core::primitive::u8>, ::core::option::Option<::std::vec::Vec<::core::primitive::u8>>, @@ -17408,14 +17414,14 @@ pub mod api { # [codec (crate = :: subxt :: ext :: codec)] #[decode_as_type(crate_path = ":: subxt :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt :: ext :: scale_encode")] - pub struct Post { + pub struct PostRequest { pub source: runtime_types::ismp::host::StateMachine, pub dest: runtime_types::ismp::host::StateMachine, pub nonce: ::core::primitive::u64, pub from: ::std::vec::Vec<::core::primitive::u8>, pub to: ::std::vec::Vec<::core::primitive::u8>, pub timeout_timestamp: ::core::primitive::u64, - pub data: ::std::vec::Vec<::core::primitive::u8>, + pub body: ::std::vec::Vec<::core::primitive::u8>, } #[derive( :: subxt :: ext :: codec :: Decode, @@ -17431,7 +17437,7 @@ pub mod api { #[decode_as_type(crate_path = ":: subxt :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt :: ext :: scale_encode")] pub struct PostResponse { - pub post: runtime_types::ismp::router::Post, + pub post: runtime_types::ismp::router::PostRequest, pub response: ::std::vec::Vec<::core::primitive::u8>, pub timeout_timestamp: ::core::primitive::u64, } @@ -17450,9 +17456,9 @@ pub mod api { #[encode_as_type(crate_path = ":: subxt :: ext :: scale_encode")] pub enum Request { #[codec(index = 0)] - Post(runtime_types::ismp::router::Post), + Post(runtime_types::ismp::router::PostRequest), #[codec(index = 1)] - Get(runtime_types::ismp::router::Get), + Get(runtime_types::ismp::router::GetRequest), } #[derive( :: subxt :: ext :: codec :: Decode, diff --git a/modules/subxt/utils/src/lib.rs b/modules/utils/subxt/src/lib.rs similarity index 98% rename from modules/subxt/utils/src/lib.rs rename to modules/utils/subxt/src/lib.rs index 064da639b..3c4506dc1 100644 --- a/modules/subxt/utils/src/lib.rs +++ b/modules/utils/subxt/src/lib.rs @@ -149,8 +149,8 @@ mod gargantua_conversion { } } - impl From for runtime_types::ismp::router::Post { - fn from(post: ismp::router::Post) -> Self { + impl From for runtime_types::ismp::router::PostRequest { + fn from(post: ismp::router::PostRequest) -> Self { Self { source: post.source.into(), dest: post.dest.into(), @@ -158,7 +158,7 @@ mod gargantua_conversion { from: post.from, to: post.to, timeout_timestamp: post.timeout_timestamp, - data: post.data, + body: post.body, } } } diff --git a/parachain/node/Cargo.toml b/parachain/node/Cargo.toml index d719c818e..6ac71e102 100644 --- a/parachain/node/Cargo.toml +++ b/parachain/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyperbridge" -version = "0.5.1" +version = "0.5.2" authors = ["Polytope Labs "] description = "The Hyperbridge coprocessor node" repository = "https://github.com/polytope-labs/hyperbridge" diff --git a/parachain/runtimes/gargantua/src/ismp.rs b/parachain/runtimes/gargantua/src/ismp.rs index 7b191e6f2..51fd2f42c 100644 --- a/parachain/runtimes/gargantua/src/ismp.rs +++ b/parachain/runtimes/gargantua/src/ismp.rs @@ -29,7 +29,7 @@ use ismp::{ error::Error, host::StateMachine, module::IsmpModule, - router::{IsmpRouter, Post, Request, Response}, + router::{IsmpRouter, PostRequest, Request, Response}, }; use pallet_asset_gateway::TokenGatewayParams; #[cfg(feature = "runtime-benchmarks")] @@ -178,7 +178,7 @@ impl pallet_assets::Config for Runtime { } impl IsmpModule for ProxyModule { - fn on_accept(&self, request: Post) -> Result<(), Error> { + fn on_accept(&self, request: PostRequest) -> Result<(), Error> { if request.dest != HostStateMachine::get() { let meta = FeeMetadata:: { payer: [0u8; 32].into(), fee: Default::default() }; Ismp::dispatch_request(Request::Post(request), meta)?; diff --git a/parachain/runtimes/gargantua/src/lib.rs b/parachain/runtimes/gargantua/src/lib.rs index fbc9cfe3b..45eacfca8 100644 --- a/parachain/runtimes/gargantua/src/lib.rs +++ b/parachain/runtimes/gargantua/src/lib.rs @@ -214,7 +214,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("gargantua"), impl_name: create_runtime_str!("gargantua"), authoring_version: 1, - spec_version: 331, + spec_version: 340, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/parachain/runtimes/messier/src/ismp.rs b/parachain/runtimes/messier/src/ismp.rs index 5bcd5056d..264a1451a 100644 --- a/parachain/runtimes/messier/src/ismp.rs +++ b/parachain/runtimes/messier/src/ismp.rs @@ -29,7 +29,7 @@ use ismp::{ error::Error, host::StateMachine, module::IsmpModule, - router::{IsmpRouter, Post, Request, Response}, + router::{IsmpRouter, PostRequest, Request, Response}, }; use pallet_asset_gateway::TokenGatewayParams; #[cfg(feature = "runtime-benchmarks")] @@ -166,7 +166,7 @@ impl pallet_assets::Config for Runtime { } impl IsmpModule for ProxyModule { - fn on_accept(&self, request: Post) -> Result<(), Error> { + fn on_accept(&self, request: PostRequest) -> Result<(), Error> { if request.dest != HostStateMachine::get() { let meta = FeeMetadata:: { payer: [0u8; 32].into(), fee: Default::default() }; Ismp::dispatch_request(Request::Post(request), meta)?; diff --git a/parachain/runtimes/nexus/src/ismp.rs b/parachain/runtimes/nexus/src/ismp.rs index d0598902c..c2fb6757c 100644 --- a/parachain/runtimes/nexus/src/ismp.rs +++ b/parachain/runtimes/nexus/src/ismp.rs @@ -30,7 +30,7 @@ use ismp::{ error::Error, host::StateMachine, module::IsmpModule, - router::{IsmpRouter, Post, Request, Response}, + router::{IsmpRouter, PostRequest, Request, Response}, }; use pallet_asset_gateway::TokenGatewayParams; #[cfg(feature = "runtime-benchmarks")] @@ -172,7 +172,7 @@ impl pallet_assets::Config for Runtime { } impl IsmpModule for ProxyModule { - fn on_accept(&self, request: Post) -> Result<(), Error> { + fn on_accept(&self, request: PostRequest) -> Result<(), Error> { if request.dest != HostStateMachine::get() { let meta = FeeMetadata:: { payer: [0u8; 32].into(), fee: Default::default() }; Ismp::dispatch_request(Request::Post(request), meta)?; diff --git a/parachain/simtests/src/hyperbridge_client.rs b/parachain/simtests/src/hyperbridge_client.rs index ebf367189..9313d8359 100644 --- a/parachain/simtests/src/hyperbridge_client.rs +++ b/parachain/simtests/src/hyperbridge_client.rs @@ -6,7 +6,7 @@ use codec::Encode; use ismp::{ host::StateMachine, messaging::hash_request, - router::{Post, Request}, + router::{PostRequest, Request}, }; use primitive_types::H256; use sc_consensus_manual_seal::CreatedBlock; @@ -103,14 +103,14 @@ async fn test_will_accept_paid_requests() -> Result<(), anyhow::Error> { progress.wait_for_finalized_success().await?; } - let post = Post { + let post = PostRequest { source: StateMachine::Polkadot(para_id), dest: StateMachine::Polygon, nonce: 0, from: H256::random().as_bytes().to_vec(), to: H256::random().as_bytes().to_vec(), timeout_timestamp: 0, - data: H256::random().as_bytes().to_vec(), + body: H256::random().as_bytes().to_vec(), }; let request = Request::Post(post.clone()); @@ -121,7 +121,7 @@ async fn test_will_accept_paid_requests() -> Result<(), anyhow::Error> { let commitment_key = pallet_ismp::child_trie::request_commitment_storage_key(commitment); let payment_key = pallet_hyperbridge::child_trie::request_payment_storage_key(commitment); let commitment_value = H256::random().as_bytes().to_vec(); - let payment_value = (post.data.len() as u128 * per_byte_fee).encode(); + let payment_value = (post.body.len() as u128 * per_byte_fee).encode(); trie.insert(&commitment_key, &commitment_value).unwrap(); trie.insert(&payment_key, &payment_value).unwrap(); @@ -294,14 +294,14 @@ async fn test_will_reject_unpaid_requests() -> Result<(), anyhow::Error> { progress.wait_for_finalized_success().await?; } - let post = Post { + let post = PostRequest { source: StateMachine::Polkadot(para_id), dest: StateMachine::Polygon, nonce: 0, from: H256::random().as_bytes().to_vec(), to: H256::random().as_bytes().to_vec(), timeout_timestamp: 0, - data: H256::random().as_bytes().to_vec(), + body: H256::random().as_bytes().to_vec(), }; let request = Request::Post(post.clone()); @@ -479,14 +479,14 @@ async fn test_will_reject_partially_paid_requests() -> Result<(), anyhow::Error> progress.wait_for_finalized_success().await?; } - let post = Post { + let post = PostRequest { source: StateMachine::Polkadot(para_id), dest: StateMachine::Polygon, nonce: 0, from: H256::random().as_bytes().to_vec(), to: H256::random().as_bytes().to_vec(), timeout_timestamp: 0, - data: H256::random().as_bytes().to_vec(), + body: H256::random().as_bytes().to_vec(), }; let request = Request::Post(post.clone()); @@ -496,7 +496,7 @@ async fn test_will_reject_partially_paid_requests() -> Result<(), anyhow::Error> let commitment_key = pallet_ismp::child_trie::request_commitment_storage_key(commitment); let payment_key = pallet_hyperbridge::child_trie::request_payment_storage_key(commitment); let commitment_value = H256::random().as_bytes().to_vec(); - let len = post.data.len() as u128 / 2; + let len = post.body.len() as u128 / 2; let payment_value = (len * per_byte_fee).encode(); { let mut trie = TrieDBMutBuilder::>::new(&mut db, &mut root).build(); diff --git a/parachain/simtests/src/pallet_ismp.rs b/parachain/simtests/src/pallet_ismp.rs index a90abcd3d..b84e25445 100644 --- a/parachain/simtests/src/pallet_ismp.rs +++ b/parachain/simtests/src/pallet_ismp.rs @@ -18,7 +18,7 @@ use trie_db::{Recorder, Trie, TrieDBBuilder, TrieDBMutBuilder, TrieMut}; use ismp::{ host::StateMachine, messaging::hash_request, - router::{Post, Request}, + router::{PostRequest, Request}, }; use pallet_ismp::child_trie; use primitive_types::H256; @@ -117,14 +117,14 @@ async fn test_txpool_should_reject_duplicate_requests() -> Result<(), anyhow::Er progress.wait_for_finalized_success().await?; } - let post = Post { + let post = PostRequest { source: StateMachine::Polkadot(para_id), dest: StateMachine::Polygon, nonce: 0, from: H256::random().as_bytes().to_vec(), to: H256::random().as_bytes().to_vec(), timeout_timestamp: 0, - data: H256::random().as_bytes().to_vec(), + body: H256::random().as_bytes().to_vec(), }; let request = Request::Post(post.clone()); diff --git a/tesseract/evm/src/gas_oracle.rs b/tesseract/evm/src/gas_oracle.rs index 8b687132c..af5f574f0 100644 --- a/tesseract/evm/src/gas_oracle.rs +++ b/tesseract/evm/src/gas_oracle.rs @@ -23,6 +23,7 @@ use tesseract_primitives::Cost; #[serde(rename_all = "PascalCase")] pub struct GasResult { pub safe_gas_price: String, + #[allow(dead_code)] pub fast_gas_price: String, pub usd_price: String, } diff --git a/tesseract/evm/src/lib.rs b/tesseract/evm/src/lib.rs index cd521ebf2..63936cce8 100644 --- a/tesseract/evm/src/lib.rs +++ b/tesseract/evm/src/lib.rs @@ -64,8 +64,6 @@ pub struct EvmConfig { pub consensus_state_id: String, /// Ismp Host contract address pub ismp_host: H160, - /// Ismp Handler contract address - pub handler: H160, /// Relayer account private key pub signer: String, /// Etherscan API key @@ -103,7 +101,6 @@ impl Default for EvmConfig { state_machine: StateMachine::Ethereum(Ethereum::ExecutionLayer), consensus_state_id: Default::default(), ismp_host: Default::default(), - handler: Default::default(), signer: Default::default(), etherscan_api_key: Default::default(), tracing_batch_size: Default::default(), @@ -274,6 +271,12 @@ impl EvmClient { let params = contract.host_params().call().await?; Ok(params.host_manager) } + + pub async fn handler(&self) -> Result { + let contract = EvmHost::new(self.config.ismp_host, self.client.clone()); + let params = contract.host_params().call().await?; + Ok(params.handler) + } } pub fn derive_map_key(mut key: Vec, slot: u64) -> H256 { diff --git a/tesseract/evm/src/test.rs b/tesseract/evm/src/test.rs index 6d5456426..0e8bfd171 100644 --- a/tesseract/evm/src/test.rs +++ b/tesseract/evm/src/test.rs @@ -9,7 +9,7 @@ use ismp::{ consensus::{StateCommitment, StateMachineHeight, StateMachineId}, host::{Ethereum, StateMachine}, messaging::{hash_request, Proof}, - router::{Post, RequestResponse}, + router::{PostRequest, RequestResponse}, }; use ismp_solidity_abi::evm_host::EvmHost; use ismp_testsuite::mocks::{Host, Keccak256Hasher}; @@ -45,14 +45,13 @@ async fn test_ismp_state_proof() { state_machine: StateMachine::Ethereum(Ethereum::ExecutionLayer), consensus_state_id: "SYNC".to_string(), ismp_host: ISMP_HOST, - handler: H160::from(hex!("139722d03a6f449048D732cdd05628F4D8cE536d")), signer: "2e0834786285daccd064ca17f1654f67b4aef298acbb82cef9ec422fb4975622".to_string(), ..Default::default() }; let client = EvmClient::new(config).await.expect("Host creation failed"); - let post = Post { + let post = PostRequest { source: StateMachine::from_str( &String::from_utf8(hex::decode("45544845").unwrap()).unwrap(), ) @@ -63,7 +62,7 @@ async fn test_ismp_state_proof() { from: hex::decode("D21C7893BD7A96732E65CEB2B9E6DD9CA95846C9").unwrap(), to: hex::decode("66819E1BBB03760D227745C71FE76C5783A5F810").unwrap(), timeout_timestamp: 1707167196, - data: hex::decode("68656C6C6F2066726F6D2045544845").unwrap(), + body: hex::decode("68656C6C6F2066726F6D2045544845").unwrap(), }; let req = ismp::router::Request::Post(post.clone()); diff --git a/tesseract/evm/src/tx.rs b/tesseract/evm/src/tx.rs index 801772114..5538735f1 100644 --- a/tesseract/evm/src/tx.rs +++ b/tesseract/evm/src/tx.rs @@ -215,7 +215,8 @@ pub async fn generate_contract_calls( messages: Vec, debug_trace: bool, ) -> anyhow::Result> { - let contract = IsmpHandler::new(client.config.handler, client.signer.clone()); + let handler = client.handler().await?; + let contract = IsmpHandler::new(handler, client.signer.clone()); let ismp_host = client.config.ismp_host; let mut calls = Vec::new(); // If debug trace is false or the client type is erigon, then the gas price must be set diff --git a/tesseract/fees/src/lib.rs b/tesseract/fees/src/lib.rs index f8515c920..71574ca83 100644 --- a/tesseract/fees/src/lib.rs +++ b/tesseract/fees/src/lib.rs @@ -14,7 +14,7 @@ use ismp::{ consensus::StateMachineHeight, host::StateMachine, messaging::{hash_request, hash_response, Keccak256, Message, Proof}, - router::{Post, Request, RequestResponse}, + router::{PostRequest, Request, RequestResponse}, }; use itertools::Itertools; use pallet_ismp_relayer::withdrawal::{Key, WithdrawalProof}; diff --git a/tesseract/fees/src/tests.rs b/tesseract/fees/src/tests.rs index c91ab9b9a..075002d12 100644 --- a/tesseract/fees/src/tests.rs +++ b/tesseract/fees/src/tests.rs @@ -3,7 +3,7 @@ use ismp::{ consensus::{StateMachineHeight, StateMachineId}, host::{Ethereum, StateMachine}, messaging::{hash_request, hash_response, Message, Proof, RequestMessage, ResponseMessage}, - router::{Post, PostResponse, Request, RequestResponse, Response}, + router::{PostRequest, PostResponse, Request, RequestResponse, Response}, }; use std::sync::Arc; use tesseract_primitives::{mocks::MockHost, Hasher, Query, TxReceipt}; @@ -12,14 +12,14 @@ use tesseract_primitives::{mocks::MockHost, Hasher, Query, TxReceipt}; async fn transaction_payments_flow() { let tx_payment = TransactionPayment::initialize("./dev.db").await.unwrap(); let receipts = (0..500).into_iter().map(|i| { - let post = Post { + let post = PostRequest { source: StateMachine::Bsc, dest: StateMachine::Polygon, nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; let req = Request::Post(post); let commitment = hash_request::(&req); @@ -36,14 +36,14 @@ async fn transaction_payments_flow() { let response_receipts = (0..500).into_iter().map(|i| { let resp = Response::Post(PostResponse { - post: Post { + post: PostRequest { source: StateMachine::Polygon, dest: StateMachine::Bsc, nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }, response: vec![0u8; 64], timeout_timestamp: i, @@ -96,14 +96,14 @@ async fn transaction_payments_flow() { async fn test_unique_deliveries() -> anyhow::Result<()> { let tx_payment = TransactionPayment::initialize("./dev2.db").await.unwrap(); let receipts = (0..5).into_iter().map(|i| { - let post = Post { + let post = PostRequest { source: StateMachine::Bsc, dest: StateMachine::Polygon, nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; let req = Request::Post(post); let commitment = hash_request::(&req); @@ -120,14 +120,14 @@ async fn test_unique_deliveries() -> anyhow::Result<()> { let response_receipts = (0..5).into_iter().map(|i| { let resp = Response::Post(PostResponse { - post: Post { + post: PostRequest { source: StateMachine::Polygon, dest: StateMachine::Bsc, nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }, response: vec![0u8; 64], timeout_timestamp: i, @@ -149,14 +149,14 @@ async fn test_unique_deliveries() -> anyhow::Result<()> { }); let receipts2 = (0..5).into_iter().map(|i| { - let post = Post { + let post = PostRequest { source: StateMachine::Ethereum(Ethereum::ExecutionLayer), dest: StateMachine::Polygon, nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; let req = Request::Post(post); let commitment = hash_request::(&req); @@ -172,14 +172,14 @@ async fn test_unique_deliveries() -> anyhow::Result<()> { }); let receipts3 = (0..5).into_iter().map(|i| { - let post = Post { + let post = PostRequest { dest: StateMachine::Ethereum(Ethereum::ExecutionLayer), source: StateMachine::Polygon, nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; let req = Request::Post(post); let commitment = hash_request::(&req); @@ -195,14 +195,14 @@ async fn test_unique_deliveries() -> anyhow::Result<()> { }); let receipts4 = (0..5).into_iter().map(|i| { - let post = Post { + let post = PostRequest { dest: StateMachine::Ethereum(Ethereum::Optimism), source: StateMachine::Ethereum(Ethereum::Base), nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; let req = Request::Post(post); let commitment = hash_request::(&req); @@ -218,14 +218,14 @@ async fn test_unique_deliveries() -> anyhow::Result<()> { }); let receipts5 = (0..5).into_iter().map(|i| { - let post = Post { + let post = PostRequest { source: StateMachine::Ethereum(Ethereum::Optimism), dest: StateMachine::Ethereum(Ethereum::Base), nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; let req = Request::Post(post); let commitment = hash_request::(&req); @@ -265,14 +265,14 @@ async fn test_unique_deliveries() -> anyhow::Result<()> { async fn highest_delivery_height() { let tx_payment = TransactionPayment::initialize("./dev_2.db").await.unwrap(); let receipts = (0..500).into_iter().map(|i| { - let post = Post { + let post = PostRequest { source: StateMachine::Bsc, dest: StateMachine::Polygon, nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }; let req = Request::Post(post); let commitment = hash_request::(&req); @@ -289,14 +289,14 @@ async fn highest_delivery_height() { let response_receipts = (0..500).into_iter().map(|i| { let resp = Response::Post(PostResponse { - post: Post { + post: PostRequest { source: StateMachine::Polygon, dest: StateMachine::Bsc, nonce: i, from: vec![], to: vec![], timeout_timestamp: 0, - data: vec![], + body: vec![], }, response: vec![0u8; 64], timeout_timestamp: i, diff --git a/tesseract/messaging/src/events.rs b/tesseract/messaging/src/events.rs index 2d7a9d5d2..38dd036d0 100644 --- a/tesseract/messaging/src/events.rs +++ b/tesseract/messaging/src/events.rs @@ -8,7 +8,7 @@ use ismp::{ }, host::StateMachine, messaging::{hash_request, hash_response, Message, Proof, RequestMessage, ResponseMessage}, - router::{Post, Request, RequestResponse, Response}, + router::{PostRequest, Request, RequestResponse, Response}, }; use sp_core::{H160, U256}; use std::{collections::HashMap, sync::Arc}; @@ -253,7 +253,7 @@ pub async fn translate_events_to_messages( unprofitable.extend(post_request_queries_to_push_with_option.retriable_messages); - let post_request_to_push: Vec = post_requests + let post_request_to_push: Vec = post_requests .into_iter() .zip(post_request_queries_to_push_with_option.queries.iter()) .filter_map( @@ -452,7 +452,7 @@ pub async fn return_successful_queries( _ => unreachable!("Relayer should only ever debug trace request or response messages") }; - if relayer == H160::zero().0.to_vec() { + if relayer == H160::zero().0.to_vec() && coprocessor != sink.state_machine_id().state_id { return Ok((None, Some(msg))) } else { return Ok((None, None)) diff --git a/tesseract/primitives/src/lib.rs b/tesseract/primitives/src/lib.rs index 7cb9d36a6..984900705 100644 --- a/tesseract/primitives/src/lib.rs +++ b/tesseract/primitives/src/lib.rs @@ -26,7 +26,7 @@ use ismp::{ events::Event, host::StateMachine, messaging::{CreateConsensusState, Keccak256, Message}, - router::Post, + router::PostRequest, }; use pallet_ismp_host_executive::HostParam; use pallet_ismp_relayer::withdrawal::Key; @@ -383,7 +383,7 @@ pub trait HyperbridgeClaim { #[derive(Encode, Decode, Clone)] pub struct WithdrawFundsResult { /// Post request emitted by the withdraw request - pub post: Post, + pub post: PostRequest, /// Block height at which the post request was emitted pub block: u64, } diff --git a/tesseract/relayer/Cargo.toml b/tesseract/relayer/Cargo.toml index 45fdadec0..dc1fd4712 100644 --- a/tesseract/relayer/Cargo.toml +++ b/tesseract/relayer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tesseract" -version = "0.3.6" +version = "0.3.7" edition = "2021" description = "Chain agnostic relayer implementation for Hyperbridge" authors = ["Polytope Labs "] diff --git a/tesseract/substrate/src/calls.rs b/tesseract/substrate/src/calls.rs index 9912237ad..f27417fce 100644 --- a/tesseract/substrate/src/calls.rs +++ b/tesseract/substrate/src/calls.rs @@ -182,7 +182,7 @@ where StateMachine::Polkadot(_) | StateMachine::Grandpa(_) | StateMachine::Beefy(_) => { - if let Ok(decoded_data) = WithdrawalParams::decode(&mut &*post.data) { + if let Ok(decoded_data) = WithdrawalParams::decode(&mut &*post.body) { decoded_data.beneficiary_address == counterparty.address() && condition } else { @@ -190,7 +190,7 @@ where } }, StateMachine::Ethereum(_) | StateMachine::Polygon | StateMachine::Bsc => { - let address = &post.data[1..33].to_vec(); + let address = &post.body[1..33].to_vec(); // abi encoding will pad address with 12 bytes address.ends_with(&counterparty.address()) && condition },