From 8fe4fa1cefbc9b125a2a73e82166263755430ce9 Mon Sep 17 00:00:00 2001 From: Farhad Shabani Date: Wed, 17 Apr 2024 12:59:35 -0700 Subject: [PATCH] imp: use `ibc-client-cw` for CosmWasm contract implementation (#142) * imp: use ibc-client-cw for CW contract implementation * chore: use generic hasher for verify_client_message * chore: update basecoin rev * deps: update ibc revision * chore: update basecoin rev + clean-ups * deps: update ibc rev * chore: update basecoin rev + deny unused_variables * fix: update Nix hashes * chore: format cargo.toml + add comment for cosmwasm deps --- .cargo/config.toml | 23 +- .vscode/settings.json | 2 +- Cargo.lock | 94 +++--- Cargo.toml | 5 +- clients/sov-celestia-cw/Cargo.toml | 59 ---- .../sov-celestia-cw/src/context/client_ctx.rs | 177 ----------- .../sov-celestia-cw/src/context/custom_ctx.rs | 76 ----- clients/sov-celestia-cw/src/context/mod.rs | 269 ---------------- clients/sov-celestia-cw/src/handlers.rs | 207 ------------ clients/sov-celestia-cw/src/lib.rs | 21 -- clients/sov-celestia-cw/src/types/error.rs | 39 --- clients/sov-celestia-cw/src/types/helper.rs | 30 -- clients/sov-celestia-cw/src/types/mod.rs | 11 - clients/sov-celestia-cw/src/types/msgs.rs | 300 ------------------ clients/sov-celestia-cw/src/types/response.rs | 70 ---- clients/sov-celestia-cw/src/utils/codec.rs | 25 -- clients/sov-celestia-cw/src/utils/mod.rs | 17 - clients/sov-celestia/Cargo.toml | 36 +-- clients/sov-celestia/cw-contract/Cargo.toml | 47 +++ .../cw-contract/src}/client_type.rs | 12 +- .../cw-contract/src/entrypoint.rs} | 17 +- clients/sov-celestia/cw-contract/src/lib.rs | 8 + .../cw-contract}/src/tests/fixture.rs | 18 +- .../cw-contract}/src/tests/mod.rs | 15 +- .../src/client_state/execution.rs | 43 ++- .../src/client_state/misbehaviour.rs | 21 +- .../src/client_state/update_client.rs | 37 +-- .../src/client_state/validation.rs | 41 +-- clients/sov-celestia/src/context.rs | 67 ---- clients/sov-celestia/src/lib.rs | 1 - .../types/src/client_message/header.rs | 8 +- .../types/src/client_message/misbehaviour.rs | 8 +- clients/sov-types/Cargo.toml | 20 +- mocks/src/cosmos/configs.rs | 5 +- modules/sov-ibc-transfer/src/context.rs | 12 +- modules/sov-ibc/src/clients/context.rs | 39 +-- modules/sov-ibc/src/context.rs | 6 +- modules/sov-ibc/src/rpc/context.rs | 2 +- modules/sov-ibc/src/rpc/methods.rs | 18 +- nix/sov-celestia-cw.nix | 4 +- 40 files changed, 294 insertions(+), 1616 deletions(-) delete mode 100644 clients/sov-celestia-cw/Cargo.toml delete mode 100644 clients/sov-celestia-cw/src/context/client_ctx.rs delete mode 100644 clients/sov-celestia-cw/src/context/custom_ctx.rs delete mode 100644 clients/sov-celestia-cw/src/context/mod.rs delete mode 100644 clients/sov-celestia-cw/src/handlers.rs delete mode 100644 clients/sov-celestia-cw/src/lib.rs delete mode 100644 clients/sov-celestia-cw/src/types/error.rs delete mode 100644 clients/sov-celestia-cw/src/types/helper.rs delete mode 100644 clients/sov-celestia-cw/src/types/mod.rs delete mode 100644 clients/sov-celestia-cw/src/types/msgs.rs delete mode 100644 clients/sov-celestia-cw/src/types/response.rs delete mode 100644 clients/sov-celestia-cw/src/utils/codec.rs delete mode 100644 clients/sov-celestia-cw/src/utils/mod.rs create mode 100644 clients/sov-celestia/cw-contract/Cargo.toml rename clients/{sov-celestia-cw/src/types => sov-celestia/cw-contract/src}/client_type.rs (77%) rename clients/{sov-celestia-cw/src/entrypoints.rs => sov-celestia/cw-contract/src/entrypoint.rs} (64%) create mode 100644 clients/sov-celestia/cw-contract/src/lib.rs rename clients/{sov-celestia-cw => sov-celestia/cw-contract}/src/tests/fixture.rs (95%) rename clients/{sov-celestia-cw => sov-celestia/cw-contract}/src/tests/mod.rs (90%) delete mode 100644 clients/sov-celestia/src/context.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 9fd88696..b6799ab2 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,18 +6,19 @@ sov-ibc-transfer = { path = "modules/sov-ibc-transfer" } sov-consensus-state-tracker = { path = "modules/sov-consensus-state-tracker" } sov-celestia-client = { path = "clients/sov-celestia" } -ibc = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-core = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-core-client = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-core-host-cosmos = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-client-tendermint = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-client-wasm-types = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-app-transfer = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-primitives = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-query = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } -ibc-testkit = { git = "https://github.com/cosmos/ibc-rs.git", rev = "c579628c67" } +ibc = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-core = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-core-client = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-core-host-cosmos = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-client-tendermint = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-client-wasm-types = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-client-cw = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-app-transfer = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-primitives = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-query = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } +ibc-testkit = { git = "https://github.com/cosmos/ibc-rs.git", rev = "d5e3887770" } -basecoin = { git = "https://github.com/informalsystems/basecoin-rs.git", rev = "c996c41" } +basecoin = { git = "https://github.com/informalsystems/basecoin-rs.git", rev = "bedac3f" } jmt = { git = "https://github.com/penumbra-zone/jmt.git", rev = "1d007e11cb68aa5ca13e9a5af4a12e6439d5f7b6" } sov-modules-api = { path = "vendor/sovereign-sdk/module-system/sov-modules-api" } diff --git a/.vscode/settings.json b/.vscode/settings.json index 99a293ab..419935d5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "rust-analyzer.linkedProjects": [ - "./clients/sov-celestia-cw/Cargo.toml", + "./clients/sov-celestia/cw-contract/Cargo.toml", "./ci/risc0-check/methods/guest/Cargo.toml", "./ci/risc0-check/host/Cargo.toml", ], diff --git a/Cargo.lock b/Cargo.lock index b5b0d787..12bbf940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -569,7 +569,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "basecoin" version = "0.1.0" -source = "git+https://github.com/informalsystems/basecoin-rs.git?rev=c996c41#c996c41b990b544dcdcea6d3cc4f67637105f283" +source = "git+https://github.com/informalsystems/basecoin-rs.git?rev=bedac3f#bedac3ff77407ceb47c48700ad3ff39107f4ceb2" dependencies = [ "basecoin-app", "basecoin-modules", @@ -591,7 +591,7 @@ dependencies = [ [[package]] name = "basecoin-app" version = "0.1.0" -source = "git+https://github.com/informalsystems/basecoin-rs.git?rev=c996c41#c996c41b990b544dcdcea6d3cc4f67637105f283" +source = "git+https://github.com/informalsystems/basecoin-rs.git?rev=bedac3f#bedac3ff77407ceb47c48700ad3ff39107f4ceb2" dependencies = [ "basecoin-modules", "basecoin-store", @@ -610,7 +610,7 @@ dependencies = [ [[package]] name = "basecoin-modules" version = "0.1.0" -source = "git+https://github.com/informalsystems/basecoin-rs.git?rev=c996c41#c996c41b990b544dcdcea6d3cc4f67637105f283" +source = "git+https://github.com/informalsystems/basecoin-rs.git?rev=bedac3f#bedac3ff77407ceb47c48700ad3ff39107f4ceb2" dependencies = [ "base64 0.21.7", "basecoin-store", @@ -637,7 +637,7 @@ dependencies = [ [[package]] name = "basecoin-store" version = "0.1.0" -source = "git+https://github.com/informalsystems/basecoin-rs.git?rev=c996c41#c996c41b990b544dcdcea6d3cc4f67637105f283" +source = "git+https://github.com/informalsystems/basecoin-rs.git?rev=bedac3f#bedac3ff77407ceb47c48700ad3ff39107f4ceb2" dependencies = [ "displaydoc", "ics23", @@ -2530,7 +2530,7 @@ dependencies = [ [[package]] name = "ibc" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-apps", "ibc-clients", @@ -2543,7 +2543,7 @@ dependencies = [ [[package]] name = "ibc-app-nft-transfer" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-app-nft-transfer-types", "ibc-core", @@ -2553,7 +2553,7 @@ dependencies = [ [[package]] name = "ibc-app-nft-transfer-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "base64 0.21.7", "borsh", @@ -2573,7 +2573,7 @@ dependencies = [ [[package]] name = "ibc-app-transfer" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-app-transfer-types", "ibc-core", @@ -2583,7 +2583,7 @@ dependencies = [ [[package]] name = "ibc-app-transfer-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2599,16 +2599,30 @@ dependencies = [ [[package]] name = "ibc-apps" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-app-nft-transfer", "ibc-app-transfer", ] +[[package]] +name = "ibc-client-cw" +version = "0.51.0" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "derive_more", + "ibc-client-wasm-types", + "ibc-core", + "prost", + "serde", +] + [[package]] name = "ibc-client-tendermint" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "derive_more", "ibc-client-tendermint-types", @@ -2625,7 +2639,7 @@ dependencies = [ [[package]] name = "ibc-client-tendermint-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "displaydoc", @@ -2643,7 +2657,7 @@ dependencies = [ [[package]] name = "ibc-client-wasm-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "base64 0.21.7", "cosmwasm-schema", @@ -2658,7 +2672,7 @@ dependencies = [ [[package]] name = "ibc-clients" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-client-tendermint", "ibc-client-wasm-types", @@ -2667,7 +2681,7 @@ dependencies = [ [[package]] name = "ibc-core" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-core-channel", "ibc-core-client", @@ -2683,7 +2697,7 @@ dependencies = [ [[package]] name = "ibc-core-channel" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-core-channel-types", "ibc-core-client", @@ -2698,7 +2712,7 @@ dependencies = [ [[package]] name = "ibc-core-channel-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2721,7 +2735,7 @@ dependencies = [ [[package]] name = "ibc-core-client" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-core-client-context", "ibc-core-client-types", @@ -2734,7 +2748,7 @@ dependencies = [ [[package]] name = "ibc-core-client-context" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "derive_more", "displaydoc", @@ -2750,7 +2764,7 @@ dependencies = [ [[package]] name = "ibc-core-client-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2770,7 +2784,7 @@ dependencies = [ [[package]] name = "ibc-core-commitment-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2788,7 +2802,7 @@ dependencies = [ [[package]] name = "ibc-core-connection" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-core-client", "ibc-core-connection-types", @@ -2800,7 +2814,7 @@ dependencies = [ [[package]] name = "ibc-core-connection-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2821,7 +2835,7 @@ dependencies = [ [[package]] name = "ibc-core-handler" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "ibc-core-channel", "ibc-core-client", @@ -2836,7 +2850,7 @@ dependencies = [ [[package]] name = "ibc-core-handler-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2860,7 +2874,7 @@ dependencies = [ [[package]] name = "ibc-core-host" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "derive_more", "displaydoc", @@ -2878,7 +2892,7 @@ dependencies = [ [[package]] name = "ibc-core-host-cosmos" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2902,7 +2916,7 @@ dependencies = [ [[package]] name = "ibc-core-host-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2917,7 +2931,7 @@ dependencies = [ [[package]] name = "ibc-core-router" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "derive_more", "displaydoc", @@ -2931,7 +2945,7 @@ dependencies = [ [[package]] name = "ibc-core-router-types" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -2950,7 +2964,7 @@ dependencies = [ [[package]] name = "ibc-derive" version = "0.6.1" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "proc-macro2", "quote", @@ -2960,7 +2974,7 @@ dependencies = [ [[package]] name = "ibc-primitives" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "borsh", "derive_more", @@ -3000,7 +3014,7 @@ dependencies = [ [[package]] name = "ibc-query" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "displaydoc", "ibc", @@ -3013,7 +3027,7 @@ dependencies = [ [[package]] name = "ibc-testkit" version = "0.51.0" -source = "git+https://github.com/cosmos/ibc-rs.git?rev=c579628c67#c579628c672bdb384ae4ef3cb02a7455c9d03386" +source = "git+https://github.com/cosmos/ibc-rs.git?rev=d5e3887770#d5e3887770d3579d49942569833499b57c09af18" dependencies = [ "derive_more", "displaydoc", @@ -4194,7 +4208,7 @@ checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.12.1", + "itertools 0.10.5", "log", "multimap", "once_cell", @@ -4214,7 +4228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.58", @@ -5495,17 +5509,11 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cosmwasm-vm", - "derive_more", + "ibc-client-cw", "ibc-client-tendermint", - "ibc-client-wasm-types", "ibc-core", - "prost", - "serde", "sov-celestia-client", "tendermint-testgen", - "test-log", - "thiserror", - "tracing-subscriber 0.3.18", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c158f7bc..b3f5d941 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ "clients/sov-types", "clients/sov-celestia/types", "clients/sov-celestia", - "clients/sov-celestia-cw", + "clients/sov-celestia/cw-contract", "modules/sov-ibc-transfer", "modules/sov-ibc", "modules/sov-consensus-state-tracker", @@ -33,7 +33,7 @@ dead_code = "deny" rust_2018_idioms = "deny" trivial_casts = "deny" unused_import_braces = "deny" -unused_variables = "allow" +unused_variables = "deny" [workspace.lints.clippy] debug_assert_with_mut_call = "deny" @@ -72,6 +72,7 @@ ibc-core-client = { version = "0.51.0", default-features = false } ibc-core-host-cosmos = { version = "0.51.0", default-features = false } ibc-client-tendermint = { version = "0.51.0", default-features = false } ibc-client-wasm-types = { version = "0.51.0", default-features = false } +ibc-client-cw = { version = "0.51.0", default-features = false } ibc-app-transfer = { version = "0.51.0", default-features = false } ibc-primitives = { version = "0.51.0", default-features = false } ibc-query = { version = "0.51.0", default-features = false, features = ["schema"] } diff --git a/clients/sov-celestia-cw/Cargo.toml b/clients/sov-celestia-cw/Cargo.toml deleted file mode 100644 index 3745f359..00000000 --- a/clients/sov-celestia-cw/Cargo.toml +++ /dev/null @@ -1,59 +0,0 @@ -[package] -name = "sov-celestia-client-cw" -authors = { workspace = true } -edition = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } -version = { workspace = true } -keywords = ["rollup", "sovereign", "ibc", "light-client", "CosmWasm"] -readme = "./../README.md" -description = """ - Contains the CosmWasm contract implementation of the `sov-celesita` light client. -""" - -[lints] -workspace = true - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -# external dependencies -derive_more = { workspace = true } -prost = { workspace = true, default-features = false } -serde = { workspace = true, features = ["derive"] } -thiserror = { version = "1.0.31" } - -# ibc dependencies -ibc-core = { workspace = true } -ibc-client-tendermint = { workspace = true } -ibc-client-wasm-types = { workspace = true, features = ["cosmwasm"] } -sov-celestia-client = { path = "../sov-celestia", default-features = false, features = ["serde"] } - -# cosmwasm dependencies -cosmwasm-schema = "1.4.1" -cosmwasm-std = "1.4.1" - -[dev-dependencies] -cosmwasm-vm = "1.4.1" -sov-celestia-client = { path = "../sov-celestia", default-features = false, features = ["test-util"] } -tendermint-testgen = { workspace = true } -test-log = { version = "0.2.14", default-features = false, features = ["trace"] } -tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] } - -[features] -default = ["std"] -std = [ - "ibc-core/std", - "ibc-client-wasm-types/std", - "ibc-client-tendermint/std", - "sov-celestia-client/std", - "prost/std", - "serde/std", -] -test = [ - "std" -] -# use library feature to disable entry points -library = [] diff --git a/clients/sov-celestia-cw/src/context/client_ctx.rs b/clients/sov-celestia-cw/src/context/client_ctx.rs deleted file mode 100644 index df6714a9..00000000 --- a/clients/sov-celestia-cw/src/context/client_ctx.rs +++ /dev/null @@ -1,177 +0,0 @@ -use ibc_client_wasm_types::client_state::ClientState as WasmClientState; -use ibc_client_wasm_types::consensus_state::ConsensusState as WasmConsensusState; -use ibc_core::client::context::{ClientExecutionContext, ClientValidationContext}; -use ibc_core::client::types::error::ClientError; -use ibc_core::client::types::Height; -use ibc_core::handler::types::error::ContextError; -use ibc_core::host::types::identifiers::ClientId; -use ibc_core::host::types::path::{iteration_key, ClientConsensusStatePath, ClientStatePath}; -use ibc_core::primitives::proto::{Any, Protobuf}; -use ibc_core::primitives::Timestamp; - -use super::Context; -use crate::types::ClientType; -use crate::utils::AnyCodec; - -impl<'a, C: ClientType<'a>> ClientValidationContext for Context<'a, C> { - type ClientStateRef = C::ClientState; - type ConsensusStateRef = C::ConsensusState; - - fn client_state(&self, _client_id: &ClientId) -> Result { - let client_state_value = self.retrieve(ClientStatePath::leaf())?; - - let any_wasm: WasmClientState = Protobuf::::decode(client_state_value.as_slice()) - .map_err(|e| ClientError::Other { - description: e.to_string(), - })?; - - let sov_client_state = C::ClientState::decode_thru_any(any_wasm.data)?; - - Ok(sov_client_state) - } - - fn consensus_state( - &self, - client_cons_state_path: &ClientConsensusStatePath, - ) -> Result { - let consensus_state_value = self.retrieve(client_cons_state_path.leaf())?; - - let any_wasm: WasmConsensusState = - C::ConsensusState::decode_thru_any(consensus_state_value)?; - - let consensus_state = C::ConsensusState::decode_thru_any(any_wasm.data)?; - - Ok(consensus_state) - } - - fn client_update_meta( - &self, - _client_id: &ClientId, - height: &Height, - ) -> Result<(Timestamp, Height), ContextError> { - let time_key = self.client_update_time_key(height); - - let time_vec = self.retrieve(time_key)?; - - let time = u64::from_be_bytes(time_vec.try_into().expect("invalid timestamp")); - - let timestamp = - Timestamp::from_nanoseconds(time).map_err(ClientError::InvalidPacketTimestamp)?; - - let height_key = self.client_update_height_key(height); - - let revision_height_vec = self.retrieve(height_key)?; - - let revision_height = - u64::from_be_bytes(revision_height_vec.try_into().expect("invalid height")); - - let height = Height::new(0, revision_height)?; - - Ok((timestamp, height)) - } -} - -impl<'a, C: ClientType<'a>> ClientExecutionContext for Context<'a, C> { - type ClientStateMut = C::ClientState; - - fn store_client_state( - &mut self, - _client_state_path: ClientStatePath, - client_state: Self::ClientStateMut, - ) -> Result<(), ContextError> { - let prefixed_key = self.prefixed_key(ClientStatePath::leaf()); - - let encoded_client_state = self.encode_client_state(client_state)?; - - self.insert(prefixed_key, encoded_client_state); - - Ok(()) - } - - fn store_consensus_state( - &mut self, - consensus_state_path: ClientConsensusStatePath, - consensus_state: Self::ConsensusStateRef, - ) -> Result<(), ContextError> { - let prefixed_key = self.prefixed_key(consensus_state_path.leaf()); - - let encoded_consensus_state = C::ConsensusState::encode_thru_any(consensus_state); - - let wasm_consensus_state = WasmConsensusState { - data: encoded_consensus_state, - }; - - let encoded_wasm_consensus_state = C::ConsensusState::encode_thru_any(wasm_consensus_state); - - self.insert(prefixed_key, encoded_wasm_consensus_state); - - Ok(()) - } - - fn delete_consensus_state( - &mut self, - consensus_state_path: ClientConsensusStatePath, - ) -> Result<(), ContextError> { - let prefixed_key = self.prefixed_key(consensus_state_path.leaf()); - - self.remove(prefixed_key); - - Ok(()) - } - - fn store_update_meta( - &mut self, - _client_id: ClientId, - height: Height, - host_timestamp: Timestamp, - host_height: Height, - ) -> Result<(), ContextError> { - let time_key = self.client_update_time_key(&height); - - let prefixed_time_key = self.prefixed_key(time_key); - - let time_vec: [u8; 8] = host_timestamp.nanoseconds().to_be_bytes(); - - self.insert(prefixed_time_key, time_vec); - - let height_key = self.client_update_height_key(&height); - - let prefixed_height_key = self.prefixed_key(height_key); - - let revision_height_vec: [u8; 8] = host_height.revision_height().to_be_bytes(); - - self.insert(prefixed_height_key, revision_height_vec); - - let iteration_key = iteration_key(height.revision_number(), height.revision_height()); - - let height_vec = height.to_string().into_bytes(); - - self.insert(iteration_key, height_vec); - - Ok(()) - } - - fn delete_update_meta( - &mut self, - _client_id: ClientId, - height: Height, - ) -> Result<(), ContextError> { - let time_key = self.client_update_time_key(&height); - - let prefixed_time_key = self.prefixed_key(time_key); - - self.remove(prefixed_time_key); - - let height_key = self.client_update_height_key(&height); - - let prefixed_height_key = self.prefixed_key(height_key); - - self.remove(prefixed_height_key); - - let iteration_key = iteration_key(height.revision_number(), height.revision_height()); - - self.remove(iteration_key); - - Ok(()) - } -} diff --git a/clients/sov-celestia-cw/src/context/custom_ctx.rs b/clients/sov-celestia-cw/src/context/custom_ctx.rs deleted file mode 100644 index 9b066d79..00000000 --- a/clients/sov-celestia-cw/src/context/custom_ctx.rs +++ /dev/null @@ -1,76 +0,0 @@ -use ibc_core::client::context::ClientValidationContext; -use ibc_core::client::types::Height; -use ibc_core::handler::types::error::ContextError; -use ibc_core::host::types::identifiers::ClientId; -use ibc_core::host::types::path::ClientConsensusStatePath; -use ibc_core::primitives::Timestamp; -use sov_celestia_client::context::{ - ConsensusStateConverter, ValidationContext as SovValidationContext, -}; - -use super::Context; -use crate::types::{ClientType, HeightTravel}; - -impl<'a, C: ClientType<'a>> SovValidationContext for Context<'a, C> -where - >::ConsensusState: ConsensusStateConverter, -{ - fn host_timestamp(&self) -> Result { - let time = self.env().block.time; - - let host_timestamp = Timestamp::from_nanoseconds(time.nanos()).expect("invalid timestamp"); - - Ok(host_timestamp) - } - - fn host_height(&self) -> Result { - let host_height = Height::new(0, self.env().block.height)?; - - Ok(host_height) - } - - fn consensus_state_heights(&self, _client_id: &ClientId) -> Result, ContextError> { - let heights = self.get_heights()?; - - Ok(heights) - } - fn next_consensus_state( - &self, - client_id: &ClientId, - height: &Height, - ) -> Result, ContextError> { - let next_height = self.get_adjacent_height(height, HeightTravel::Next)?; - - match next_height { - Some(h) => { - let cons_state_path = ClientConsensusStatePath::new( - client_id.clone(), - h.revision_number(), - h.revision_height(), - ); - self.consensus_state(&cons_state_path).map(Some) - } - None => Ok(None), - } - } - - fn prev_consensus_state( - &self, - client_id: &ClientId, - height: &Height, - ) -> Result, ContextError> { - let prev_height = self.get_adjacent_height(height, HeightTravel::Prev)?; - - match prev_height { - Some(prev_height) => { - let cons_state_path = ClientConsensusStatePath::new( - client_id.clone(), - prev_height.revision_number(), - prev_height.revision_height(), - ); - self.consensus_state(&cons_state_path).map(Some) - } - None => Ok(None), - } - } -} diff --git a/clients/sov-celestia-cw/src/context/mod.rs b/clients/sov-celestia-cw/src/context/mod.rs deleted file mode 100644 index d44f15ec..00000000 --- a/clients/sov-celestia-cw/src/context/mod.rs +++ /dev/null @@ -1,269 +0,0 @@ -pub mod client_ctx; -pub mod custom_ctx; - -use std::str::FromStr; - -use cosmwasm_std::{Deps, DepsMut, Env, Order, Storage}; -use ibc_client_wasm_types::client_state::ClientState as WasmClientState; -use ibc_core::client::context::client_state::ClientStateCommon; -use ibc_core::client::types::error::ClientError; -use ibc_core::client::types::Height; -use ibc_core::host::types::identifiers::ClientId; -use ibc_core::host::types::path::{ - iteration_key, ClientStatePath, ClientUpdateHeightPath, ClientUpdateTimePath, - ITERATE_CONSENSUS_STATE_PREFIX, -}; -use ibc_core::primitives::proto::{Any, Protobuf}; -use prost::Message; - -use crate::types::{ClientType, ContractError, GenesisMetadata, HeightTravel, MigrationPrefix}; -use crate::utils::{parse_height, AnyCodec}; - -type Checksum = Vec; - -/// Context is a wrapper around the deps and env that gives access to the -/// methods under the ibc-rs Validation and Execution traits. -pub struct Context<'a, C: ClientType<'a>> { - deps: Option>, - deps_mut: Option>, - env: Env, - client_id: ClientId, - checksum: Option, - migration_prefix: MigrationPrefix, - client_type: std::marker::PhantomData, -} - -impl<'a, C: ClientType<'a>> Context<'a, C> { - pub fn new_ref(deps: Deps<'a>, env: Env) -> Result { - let client_id = ClientId::from_str(env.contract.address.as_str())?; - - Ok(Self { - deps: Some(deps), - deps_mut: None, - env, - client_id, - checksum: None, - migration_prefix: MigrationPrefix::None, - client_type: std::marker::PhantomData::, - }) - } - - pub fn new_mut(deps: DepsMut<'a>, env: Env) -> Result { - let client_id = ClientId::from_str(env.contract.address.as_str())?; - - Ok(Self { - deps: None, - deps_mut: Some(deps), - env, - client_id, - checksum: None, - migration_prefix: MigrationPrefix::None, - client_type: std::marker::PhantomData::, - }) - } - - pub fn env(&self) -> &Env { - &self.env - } - - pub fn log(&self, msg: &str) -> Option<()> { - self.deps.map(|deps| deps.api.debug(msg)) - } - - pub fn client_id(&self) -> ClientId { - self.client_id.clone() - } - - pub fn set_checksum(&mut self, checksum: Checksum) { - self.checksum = Some(checksum); - } - - pub fn set_subject_prefix(&mut self) { - self.migration_prefix = MigrationPrefix::Subject; - } - - pub fn set_substitute_prefix(&mut self) { - self.migration_prefix = MigrationPrefix::Substitute; - } - - pub fn prefixed_key(&self, key: impl AsRef<[u8]>) -> Vec { - let mut prefixed_key = Vec::new(); - prefixed_key.extend_from_slice(self.migration_prefix.key()); - prefixed_key.extend_from_slice(key.as_ref()); - - prefixed_key - } - - pub fn retrieve(&self, key: impl AsRef<[u8]>) -> Result, ClientError> { - let prefixed_key = self.prefixed_key(key); - - let value = self - .storage_ref() - .get(prefixed_key.as_ref()) - .ok_or(ClientError::Other { - description: "key not found".to_string(), - })?; - - Ok(value) - } - - pub fn insert(&mut self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) { - self.storage_mut().set(key.as_ref(), value.as_ref()); - } - - pub fn remove(&mut self, key: impl AsRef<[u8]>) { - self.storage_mut().remove(key.as_ref()); - } - - pub fn get_heights(&self) -> Result, ClientError> { - let iterator = self.storage_ref().range(None, None, Order::Ascending); - - iterator.map(|(_, height)| parse_height(height)).collect() - } - - /// Searches for either the earliest next or latest previous height based on - /// the given height and travel direction. - pub fn get_adjacent_height( - &self, - height: &Height, - travel: HeightTravel, - ) -> Result, ClientError> { - let iteration_key = iteration_key(height.revision_number(), height.revision_height()); - - let mut iterator = match travel { - HeightTravel::Prev => { - self.storage_ref() - .range(None, Some(&iteration_key), Order::Descending) - } - HeightTravel::Next => { - self.storage_ref() - .range(Some(&iteration_key), None, Order::Ascending) - } - }; - - iterator - .next() - .map(|(_, height)| parse_height(height)) - .transpose() - } - - pub fn client_update_time_key(&self, height: &Height) -> Vec { - let client_update_time_path = ClientUpdateTimePath::new( - self.client_id(), - height.revision_number(), - height.revision_height(), - ); - - client_update_time_path.leaf().into_bytes() - } - - pub fn client_update_height_key(&self, height: &Height) -> Vec { - let client_update_height_path = ClientUpdateHeightPath::new( - self.client_id(), - height.revision_number(), - height.revision_height(), - ); - - client_update_height_path.leaf().into_bytes() - } - - pub fn get_metadata(&self) -> Result>, ContractError> { - let mut metadata = Vec::::new(); - - let start_key = ITERATE_CONSENSUS_STATE_PREFIX.to_string().into_bytes(); - - let iterator = self - .storage_ref() - .range(Some(&start_key), None, Order::Ascending); - - for (_, encoded_height) in iterator { - let height = parse_height(encoded_height); - - match height { - Ok(height) => { - let processed_height_key = self.client_update_height_key(&height); - metadata.push(GenesisMetadata { - key: processed_height_key.clone(), - value: self.retrieve(&processed_height_key)?, - }); - let processed_time_key = self.client_update_time_key(&height); - metadata.push(GenesisMetadata { - key: processed_time_key.clone(), - value: self.retrieve(&processed_time_key)?, - }); - } - Err(_) => break, - } - } - - let iterator = self - .storage_ref() - .range(Some(&start_key), None, Order::Ascending); - - for (key, height) in iterator { - metadata.push(GenesisMetadata { key, value: height }); - } - - Ok(Some(metadata)) - } - - pub fn obtain_checksum(&self) -> Result { - match &self.checksum { - Some(checksum) => Ok(checksum.clone()), - None => { - let client_state_value = self.retrieve(ClientStatePath::leaf())?; - - let wasm_client_state: WasmClientState = - Protobuf::::decode(client_state_value.as_slice()).map_err(|e| { - ClientError::Other { - description: e.to_string(), - } - })?; - - Ok(wasm_client_state.checksum) - } - } - } - - pub fn encode_client_state( - &self, - client_state: C::ClientState, - ) -> Result, ClientError> { - let wasm_client_state = WasmClientState { - data: C::ClientState::encode_thru_any(client_state.clone()), - checksum: self.obtain_checksum()?, - latest_height: client_state.latest_height(), - }; - - Ok(Any::from(wasm_client_state).encode_to_vec()) - } -} - -pub trait StorageRef { - fn storage_ref(&self) -> &dyn Storage; -} - -impl<'a, C: ClientType<'a>> StorageRef for Context<'a, C> { - fn storage_ref(&self) -> &dyn Storage { - match self.deps { - Some(ref deps) => deps.storage, - None => match self.deps_mut { - Some(ref deps) => deps.storage, - None => panic!("storage should be available"), - }, - } - } -} - -pub trait StorageMut: StorageRef { - fn storage_mut(&mut self) -> &mut dyn Storage; -} - -impl<'a, C: ClientType<'a>> StorageMut for Context<'a, C> { - fn storage_mut(&mut self) -> &mut dyn Storage { - match self.deps_mut { - Some(ref mut deps) => deps.storage, - None => panic!("storage should be available"), - } - } -} diff --git a/clients/sov-celestia-cw/src/handlers.rs b/clients/sov-celestia-cw/src/handlers.rs deleted file mode 100644 index e4cb7e31..00000000 --- a/clients/sov-celestia-cw/src/handlers.rs +++ /dev/null @@ -1,207 +0,0 @@ -use cosmwasm_std::{to_json_binary, Binary}; -use ibc_core::client::context::prelude::*; -use ibc_core::host::types::path::ClientConsensusStatePath; -use ibc_core::primitives::proto::Any; -use prost::Message; -use sov_celestia_client::types::client_message::ClientMessage; - -use crate::context::Context; -use crate::types::{ - CheckForMisbehaviourMsg, ClientType, ContractError, ContractResult, ExportMetadataMsg, - InstantiateMsg, QueryMsg, QueryResponse, StatusMsg, SudoMsg, UpdateStateMsg, - UpdateStateOnMisbehaviourMsg, VerifyClientMessageMsg, VerifyMembershipMsg, - VerifyNonMembershipMsg, VerifyUpgradeAndUpdateStateMsg, -}; - -impl<'a, C: ClientType<'a>> Context<'a, C> { - pub fn instantiate(&mut self, msg: InstantiateMsg) -> Result { - let any = Any::decode(&mut msg.client_state.as_slice())?; - - let client_state = C::ClientState::try_from(any)?; - - let any_consensus_state = Any::decode(&mut msg.consensus_state.as_slice())?; - - self.set_checksum(msg.checksum); - - client_state.initialise(self, &self.client_id(), any_consensus_state)?; - - Ok(to_json_binary(&ContractResult::success())?) - } - - pub fn sudo(&mut self, msg: SudoMsg) -> Result { - let client_id = self.client_id(); - - if let SudoMsg::MigrateClientStore(_) = msg { - self.set_subject_prefix(); - }; - - let client_state = self.client_state(&client_id)?; - - let result = match msg { - SudoMsg::UpdateState(msg_raw) => { - let msg = UpdateStateMsg::try_from(msg_raw)?; - - let any_client_msg = match msg.client_message { - ClientMessage::Header(header) => (*header).into(), - ClientMessage::Misbehaviour(misbehaviour) => (*misbehaviour).into(), - }; - - let heights = client_state.update_state(self, &client_id, any_client_msg)?; - - ContractResult::success().heights(heights) - } - SudoMsg::UpdateStateOnMisbehaviour(msg_raw) => { - let msg: UpdateStateOnMisbehaviourMsg = - UpdateStateOnMisbehaviourMsg::try_from(msg_raw)?; - - let any_client_msg = match msg.client_message { - ClientMessage::Header(header) => (*header).into(), - ClientMessage::Misbehaviour(misbehaviour) => (*misbehaviour).into(), - }; - - client_state.update_state_on_misbehaviour(self, &client_id, any_client_msg)?; - - ContractResult::success() - } - SudoMsg::VerifyMembership(msg) => { - let msg = VerifyMembershipMsg::try_from(msg)?; - - let client_cons_state_path = ClientConsensusStatePath::new( - self.client_id(), - msg.height.revision_number(), - msg.height.revision_height(), - ); - - let consensus_state = self.consensus_state(&client_cons_state_path)?; - - client_state.verify_membership( - &msg.prefix, - &msg.proof, - consensus_state.root(), - msg.path, - msg.value, - )?; - - ContractResult::success() - } - SudoMsg::VerifyNonMembership(msg) => { - let msg = VerifyNonMembershipMsg::try_from(msg)?; - - let client_cons_state_path = ClientConsensusStatePath::new( - client_id.clone(), - msg.height.revision_number(), - msg.height.revision_height(), - ); - - let consensus_state = self.consensus_state(&client_cons_state_path)?; - - client_state.verify_non_membership( - &msg.prefix, - &msg.proof, - consensus_state.root(), - msg.path, - )?; - - ContractResult::success() - } - SudoMsg::VerifyUpgradeAndUpdateState(msg) => { - let msg = VerifyUpgradeAndUpdateStateMsg::try_from(msg)?; - - let client_cons_state_path = ClientConsensusStatePath::new( - client_id.clone(), - client_state.latest_height().revision_number(), - client_state.latest_height().revision_height(), - ); - - let consensus_state = self.consensus_state(&client_cons_state_path)?; - - client_state.verify_upgrade_client( - msg.upgrade_client_state.clone(), - msg.upgrade_consensus_state.clone(), - msg.proof_upgrade_client, - msg.proof_upgrade_consensus_state, - consensus_state.root(), - )?; - - client_state.update_state_on_upgrade( - self, - &client_id, - msg.upgrade_client_state, - msg.upgrade_consensus_state, - )?; - - ContractResult::success() - } - SudoMsg::MigrateClientStore(_) => { - self.set_substitute_prefix(); - let substitute_client_state = self.client_state(&client_id)?; - - self.set_subject_prefix(); - client_state.check_substitute(self, substitute_client_state.clone().into())?; - - client_state.update_on_recovery( - self, - &self.client_id(), - substitute_client_state.into(), - )?; - - ContractResult::success() - } - }; - Ok(to_json_binary(&result)?) - } - - pub fn query(&self, msg: QueryMsg) -> Result { - let client_id = self.client_id(); - - let client_state = self.client_state(&client_id)?; - - let resp = match msg { - QueryMsg::Status(StatusMsg {}) => match client_state.status(self, &client_id) { - Ok(status) => QueryResponse::success().status(status.to_string()), - Err(err) => QueryResponse::success().status(err.to_string()), - }, - QueryMsg::ExportMetadata(ExportMetadataMsg {}) => { - QueryResponse::success().genesis_metadata(self.get_metadata()?) - } - QueryMsg::TimestampAtHeight(msg) => { - let client_cons_state_path = ClientConsensusStatePath::new( - client_id, - msg.height.revision_number(), - msg.height.revision_height(), - ); - - let consensus_state = self.consensus_state(&client_cons_state_path)?; - - QueryResponse::success().timestamp(consensus_state.timestamp().nanoseconds()) - } - QueryMsg::VerifyClientMessage(msg) => { - let msg = VerifyClientMessageMsg::try_from(msg)?; - - let any_client_msg: Any = match msg.client_message { - ClientMessage::Header(header) => (*header).into(), - ClientMessage::Misbehaviour(misbehaviour) => (*misbehaviour).into(), - }; - - client_state.verify_client_message(self, &client_id, any_client_msg)?; - - QueryResponse::success() - } - QueryMsg::CheckForMisbehaviour(msg) => { - let msg = CheckForMisbehaviourMsg::try_from(msg)?; - - let any_client_msg: Any = match msg.client_message { - ClientMessage::Header(header) => (*header).into(), - ClientMessage::Misbehaviour(misbehaviour) => (*misbehaviour).into(), - }; - - let result = - client_state.check_for_misbehaviour(self, &client_id, any_client_msg)?; - - QueryResponse::success().misbehaviour(result) - } - }; - - Ok(to_json_binary(&resp)?) - } -} diff --git a/clients/sov-celestia-cw/src/lib.rs b/clients/sov-celestia-cw/src/lib.rs deleted file mode 100644 index 91de4b6b..00000000 --- a/clients/sov-celestia-cw/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![cfg_attr(not(test), deny(clippy::unwrap_used))] -#![deny( - warnings, - trivial_casts, - trivial_numeric_casts, - unused_import_braces, - unused_qualifications, - rust_2018_idioms -)] -#![forbid(unsafe_code)] - -extern crate alloc; - -pub mod context; -pub mod entrypoints; -pub mod handlers; -pub mod types; -pub mod utils; - -#[cfg(test)] -pub mod tests; diff --git a/clients/sov-celestia-cw/src/types/error.rs b/clients/sov-celestia-cw/src/types/error.rs deleted file mode 100644 index b177cd7c..00000000 --- a/clients/sov-celestia-cw/src/types/error.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::error::Error; - -use cosmwasm_std::StdError; -use derive_more::{Display, From}; -use ibc_core::client::types::error::ClientError; -use ibc_core::commitment_types::error::CommitmentError; -use ibc_core::handler::types::error::ContextError; -use ibc_core::host::types::error::IdentifierError; -use ibc_core::host::types::path::PathError; -use sov_celestia_client::types::sovereign::Error as SovCelestiaClientError; - -#[derive(From, Display, Debug)] -pub enum ContractError { - Std(StdError), - #[display(fmt = "invalid message: {_0}")] - InvalidMsg(String), - #[display(fmt = "IBC validation/execution context error: {_0}")] - Context(ContextError), - #[display(fmt = "IBC 02-client error: {_0}")] - Ics02ClientError(ClientError), - #[display(fmt = "sov-celestia client error: {_0}")] - SovCelestiaClientError(SovCelestiaClientError), - #[display(fmt = "IBC commitment error: {_0}")] - Commitment(CommitmentError), - #[display(fmt = "IBC identifier error: {_0}")] - Identifier(IdentifierError), - #[display(fmt = "IBC path error: {_0}")] - Path(PathError), - #[display(fmt = "Proto decode error: {_0}")] - ProtoDecode(prost::DecodeError), -} - -impl Error for ContractError {} - -impl From for StdError { - fn from(err: ContractError) -> StdError { - StdError::generic_err(err.to_string()) - } -} diff --git a/clients/sov-celestia-cw/src/types/helper.rs b/clients/sov-celestia-cw/src/types/helper.rs deleted file mode 100644 index 104dda6f..00000000 --- a/clients/sov-celestia-cw/src/types/helper.rs +++ /dev/null @@ -1,30 +0,0 @@ -use ibc_client_wasm_types::{SUBJECT_PREFIX, SUBSTITUTE_PREFIX}; - -/// The MigrationPrefix enumerates the prefix type used during migration mode. -/// The migration mode is activated when there is an incoming -/// `MigrateClientStore` message. It specifies the prefix key for either the -/// subject or substitute store, or none if the migration is not active. -#[derive(Clone, Debug)] -pub enum MigrationPrefix { - Subject, - Substitute, - None, -} - -impl MigrationPrefix { - pub fn key(&self) -> &[u8] { - match self { - MigrationPrefix::Subject => SUBJECT_PREFIX, - MigrationPrefix::Substitute => SUBSTITUTE_PREFIX, - MigrationPrefix::None => b"", - } - } -} - -/// Travel is an enum to represent the direction of travel in the context of -/// height. -#[derive(Clone, Debug)] -pub enum HeightTravel { - Next, - Prev, -} diff --git a/clients/sov-celestia-cw/src/types/mod.rs b/clients/sov-celestia-cw/src/types/mod.rs deleted file mode 100644 index 9a5de9ae..00000000 --- a/clients/sov-celestia-cw/src/types/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod client_type; -mod error; -mod helper; -mod msgs; -mod response; - -pub use client_type::*; -pub use error::*; -pub use helper::*; -pub use msgs::*; -pub use response::*; diff --git a/clients/sov-celestia-cw/src/types/msgs.rs b/clients/sov-celestia-cw/src/types/msgs.rs deleted file mode 100644 index 32fd4db5..00000000 --- a/clients/sov-celestia-cw/src/types/msgs.rs +++ /dev/null @@ -1,300 +0,0 @@ -//! Contains the definition of the messages that can be sent to the CosmWasm contract. -use std::str::FromStr; - -use cosmwasm_schema::cw_serde; -use ibc_client_wasm_types::serializer::Base64; -use ibc_core::client::types::error::ClientError; -use ibc_core::client::types::proto::v1::Height as RawHeight; -use ibc_core::client::types::Height; -use ibc_core::commitment_types::commitment::{CommitmentPrefix, CommitmentProofBytes}; -use ibc_core::handler::types::error::ContextError; -use ibc_core::host::types::path::Path; -use ibc_core::primitives::proto::Any; -use prost::Message; -use sov_celestia_client::types::client_message::SovTmClientMessage; - -use super::error::ContractError; - -pub type Bytes = Vec; - -// ------------------------------------------------------------ -// Implementation of the InstantiateMsg struct -// ------------------------------------------------------------ - -#[cw_serde] -pub struct InstantiateMsg { - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub client_state: Bytes, - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub consensus_state: Bytes, - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub checksum: Bytes, -} - -// ------------------------------------------------------------ -// Implementation of the SudoMsg enum and its variants -// ------------------------------------------------------------ - -#[derive(derive_more::From)] -#[cw_serde] -pub enum SudoMsg { - UpdateState(UpdateStateMsgRaw), - UpdateStateOnMisbehaviour(UpdateStateOnMisbehaviourMsgRaw), - VerifyUpgradeAndUpdateState(VerifyUpgradeAndUpdateStateMsgRaw), - VerifyMembership(VerifyMembershipMsgRaw), - VerifyNonMembership(VerifyNonMembershipMsgRaw), - MigrateClientStore(MigrateClientStoreMsg), -} - -#[cw_serde] -pub struct UpdateStateOnMisbehaviourMsgRaw { - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub client_message: Bytes, -} - -pub struct UpdateStateOnMisbehaviourMsg { - pub client_message: SovTmClientMessage, -} - -impl TryFrom for UpdateStateOnMisbehaviourMsg { - type Error = ContractError; - - fn try_from(raw: UpdateStateOnMisbehaviourMsgRaw) -> Result { - let client_message = SovTmClientMessage::decode(raw.client_message)?; - - Ok(Self { client_message }) - } -} - -#[cw_serde] -pub struct UpdateStateMsgRaw { - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub client_message: Bytes, -} - -pub struct UpdateStateMsg { - pub client_message: SovTmClientMessage, -} - -impl TryFrom for UpdateStateMsg { - type Error = ContractError; - - fn try_from(raw: UpdateStateMsgRaw) -> Result { - let client_message = SovTmClientMessage::decode(raw.client_message)?; - Ok(Self { client_message }) - } -} - -#[cw_serde] -pub struct CheckSubstituteAndUpdateStateMsg {} - -#[cw_serde] -pub struct VerifyUpgradeAndUpdateStateMsgRaw { - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub upgrade_client_state: Bytes, - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub upgrade_consensus_state: Bytes, - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub proof_upgrade_client: Bytes, - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub proof_upgrade_consensus_state: Bytes, -} - -pub struct VerifyUpgradeAndUpdateStateMsg { - pub upgrade_client_state: Any, - pub upgrade_consensus_state: Any, - pub proof_upgrade_client: CommitmentProofBytes, - pub proof_upgrade_consensus_state: CommitmentProofBytes, -} - -impl TryFrom for VerifyUpgradeAndUpdateStateMsg { - type Error = ContractError; - - fn try_from(raw: VerifyUpgradeAndUpdateStateMsgRaw) -> Result { - let upgrade_client_state = Any::decode(&mut raw.upgrade_client_state.as_slice())?; - - let upgrade_consensus_state = Any::decode(&mut raw.upgrade_consensus_state.as_slice())?; - - Ok(VerifyUpgradeAndUpdateStateMsg { - upgrade_client_state, - upgrade_consensus_state, - proof_upgrade_client: CommitmentProofBytes::try_from(raw.proof_upgrade_client)?, - proof_upgrade_consensus_state: CommitmentProofBytes::try_from( - raw.proof_upgrade_consensus_state, - )?, - }) - } -} - -#[cw_serde] -pub struct MerklePath { - pub key_path: Vec, -} - -#[cw_serde] -pub struct VerifyMembershipMsgRaw { - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub proof: Bytes, - pub path: MerklePath, - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub value: Bytes, - pub height: RawHeight, - pub delay_block_period: u64, - pub delay_time_period: u64, -} - -pub struct VerifyMembershipMsg { - pub prefix: CommitmentPrefix, - pub proof: CommitmentProofBytes, - pub path: Path, - pub value: Vec, - pub height: Height, - pub delay_block_period: u64, - pub delay_time_period: u64, -} - -impl TryFrom for VerifyMembershipMsg { - type Error = ContractError; - - fn try_from(mut raw: VerifyMembershipMsgRaw) -> Result { - let proof = CommitmentProofBytes::try_from(raw.proof)?; - let prefix = raw.path.key_path.remove(0).into_bytes(); - let path_str = raw.path.key_path.join(""); - let path = Path::from_str(&path_str)?; - let height = Height::try_from(raw.height).map_err(|e| { - ContractError::Context(ContextError::ClientError(ClientError::Other { - description: e.to_string(), - })) - })?; - Ok(Self { - proof, - path, - value: raw.value, - height, - prefix: CommitmentPrefix::try_from(prefix)?, - delay_block_period: raw.delay_block_period, - delay_time_period: raw.delay_time_period, - }) - } -} - -#[cw_serde] -pub struct VerifyNonMembershipMsgRaw { - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub proof: Bytes, - pub path: MerklePath, - pub height: RawHeight, - pub delay_block_period: u64, - pub delay_time_period: u64, -} - -pub struct VerifyNonMembershipMsg { - pub prefix: CommitmentPrefix, - pub proof: CommitmentProofBytes, - pub path: Path, - pub height: Height, - pub delay_block_period: u64, - pub delay_time_period: u64, -} - -impl TryFrom for VerifyNonMembershipMsg { - type Error = ContractError; - - fn try_from(mut raw: VerifyNonMembershipMsgRaw) -> Result { - let proof = CommitmentProofBytes::try_from(raw.proof)?; - let prefix = raw.path.key_path.remove(0).into_bytes(); - let path_str = raw.path.key_path.join(""); - let path = Path::from_str(&path_str)?; - let height = raw.height.try_into().expect("invalid height"); - Ok(Self { - proof, - path, - height, - prefix: CommitmentPrefix::try_from(prefix)?, - delay_block_period: raw.delay_block_period, - delay_time_period: raw.delay_time_period, - }) - } -} - -#[cw_serde] -pub struct MigrateClientStoreMsg {} - -// ------------------------------------------------------------ -// Implementation of the QueryMsg enum and its variants -// ------------------------------------------------------------ - -#[derive(derive_more::From)] -#[cw_serde] -pub enum QueryMsg { - Status(StatusMsg), - ExportMetadata(ExportMetadataMsg), - TimestampAtHeight(TimestampAtHeightMsg), - VerifyClientMessage(VerifyClientMessageRaw), - CheckForMisbehaviour(CheckForMisbehaviourMsgRaw), -} - -#[cw_serde] -pub struct StatusMsg {} - -#[cw_serde] -pub struct ExportMetadataMsg {} - -#[cw_serde] -pub struct TimestampAtHeightMsg { - pub height: Height, -} - -#[cw_serde] -pub struct VerifyClientMessageRaw { - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub client_message: Bytes, -} - -pub struct VerifyClientMessageMsg { - pub client_message: SovTmClientMessage, -} - -impl TryFrom for VerifyClientMessageMsg { - type Error = ContractError; - - fn try_from(raw: VerifyClientMessageRaw) -> Result { - let client_message = SovTmClientMessage::decode(raw.client_message)?; - - Ok(Self { client_message }) - } -} - -#[cw_serde] -pub struct CheckForMisbehaviourMsgRaw { - #[schemars(with = "String")] - #[serde(with = "Base64", default)] - pub client_message: Bytes, -} - -pub struct CheckForMisbehaviourMsg { - pub client_message: SovTmClientMessage, -} - -impl TryFrom for CheckForMisbehaviourMsg { - type Error = ContractError; - - fn try_from(raw: CheckForMisbehaviourMsgRaw) -> Result { - let client_message = SovTmClientMessage::decode(raw.client_message)?; - - Ok(Self { client_message }) - } -} diff --git a/clients/sov-celestia-cw/src/types/response.rs b/clients/sov-celestia-cw/src/types/response.rs deleted file mode 100644 index 6b814cd1..00000000 --- a/clients/sov-celestia-cw/src/types/response.rs +++ /dev/null @@ -1,70 +0,0 @@ -use cosmwasm_schema::cw_serde; -use ibc_core::client::types::Height; - -#[cw_serde] -pub struct GenesisMetadata { - pub key: Vec, - pub value: Vec, -} - -#[cw_serde] -pub struct QueryResponse { - pub is_valid: bool, - #[serde(skip_serializing_if = "Option::is_none")] - pub status: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub genesis_metadata: Option>, - #[serde(skip_serializing_if = "Option::is_none")] - pub found_misbehaviour: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub timestamp: Option, -} - -impl QueryResponse { - pub fn success() -> Self { - Self { - is_valid: true, - status: None, - genesis_metadata: None, - found_misbehaviour: None, - timestamp: None, - } - } - - pub fn status(mut self, status: String) -> Self { - self.status = Some(status); - self - } - - pub fn genesis_metadata(mut self, genesis_metadata: Option>) -> Self { - self.genesis_metadata = genesis_metadata; - self - } - - pub fn misbehaviour(mut self, found_misbehavior: bool) -> Self { - self.found_misbehaviour = Some(found_misbehavior); - self - } - - pub fn timestamp(mut self, timestamp: u64) -> Self { - self.timestamp = Some(timestamp); - self - } -} - -#[cw_serde] -pub struct ContractResult { - #[serde(skip_serializing_if = "Option::is_none")] - pub heights: Option>, -} - -impl ContractResult { - pub fn success() -> Self { - Self { heights: None } - } - - pub fn heights(mut self, heights: Vec) -> Self { - self.heights = Some(heights); - self - } -} diff --git a/clients/sov-celestia-cw/src/utils/codec.rs b/clients/sov-celestia-cw/src/utils/codec.rs deleted file mode 100644 index 20faf8c4..00000000 --- a/clients/sov-celestia-cw/src/utils/codec.rs +++ /dev/null @@ -1,25 +0,0 @@ -use ibc_core::client::types::error::ClientError; -use ibc_core::primitives::proto::Any; -use prost::Message; - -pub trait AnyCodec { - fn decode_thru_any(data: Vec) -> Result - where - C: TryFrom, - { - let raw = Any::decode(&mut data.as_slice()).map_err(|e| ClientError::Other { - description: e.to_string(), - })?; - - C::try_from(raw) - } - - fn encode_thru_any(value: C) -> Vec - where - C: Into, - { - value.into().encode_to_vec() - } -} - -impl AnyCodec for T where T: TryFrom + Into {} diff --git a/clients/sov-celestia-cw/src/utils/mod.rs b/clients/sov-celestia-cw/src/utils/mod.rs deleted file mode 100644 index 31d99d61..00000000 --- a/clients/sov-celestia-cw/src/utils/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -mod codec; - -pub use codec::*; -use ibc_core::client::types::error::ClientError; -use ibc_core::client::types::Height; - -/// Decodes a `Height` from a UTF-8 encoded byte array. -pub fn parse_height(encoded_height: Vec) -> Result { - let height_str = - alloc::str::from_utf8(encoded_height.as_slice()).map_err(|e| ClientError::Other { - description: e.to_string(), - })?; - - Height::try_from(height_str).map_err(|e| ClientError::Other { - description: e.to_string(), - }) -} diff --git a/clients/sov-celestia/Cargo.toml b/clients/sov-celestia/Cargo.toml index b30a61be..fb4f887d 100644 --- a/clients/sov-celestia/Cargo.toml +++ b/clients/sov-celestia/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "sov-celestia-client" -authors = { workspace = true } -edition = { workspace = true } -license = { workspace = true } +name = "sov-celestia-client" +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } repository = { workspace = true } rust-version = { workspace = true } version = { workspace = true } @@ -22,7 +22,7 @@ borsh = { workspace = true } derive_more = { workspace = true } prost = { workspace = true } jmt = { workspace = true } -sha2 = { workspace = true } +sha2 = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"], optional = true } typed-builder = { version = "0.18.0", optional = true } @@ -34,27 +34,27 @@ sov-celestia-client-types = { path = "./types", default-features = false } # DA layer dependencies tendermint = { workspace = true } -tendermint-proto = { workspace = true } +tendermint-proto = { workspace = true } tendermint-light-client-verifier = { workspace = true } [features] default = ["std"] std = [ - "ibc-core/std", - "ibc-client-tendermint/std", - "sov-celestia-client-types/std", - "prost/std", - "serde/std", - "tendermint/std" + "ibc-core/std", + "ibc-client-tendermint/std", + "sov-celestia-client-types/std", + "prost/std", + "serde/std", + "tendermint/std" ] serde = [ - "ibc-core/serde", - "ibc-client-tendermint/serde", - "sov-celestia-client-types/serde", - "dep:serde", + "ibc-core/serde", + "ibc-client-tendermint/serde", + "sov-celestia-client-types/serde", + "dep:serde", ] json-schema = [ - "ibc-core/schema", - "dep:schemars", + "ibc-core/schema", + "dep:schemars", ] test-util = ["sov-celestia-client-types/test-util"] diff --git a/clients/sov-celestia/cw-contract/Cargo.toml b/clients/sov-celestia/cw-contract/Cargo.toml new file mode 100644 index 00000000..420aad08 --- /dev/null +++ b/clients/sov-celestia/cw-contract/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "sov-celestia-client-cw" +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } +version = { workspace = true } +keywords = ["sovereign-sdk", "rollup", "ibc", "light-client", "CosmWasm"] +readme = "./../../README.md" +description = """ + Contains the CosmWasm contract implementation for the `sov-celestia` light client. +""" + +[lints] +workspace = true + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +# ibc dependencies +ibc-core = { workspace = true } +ibc-client-cw = { workspace = true } +sov-celestia-client = { path = "./../", default-features = false, features = ["serde"] } + +# cosmwasm dependencies +### Note: Kept at the following version to match the CosmWasm module version +### used by chains supporting the wasm-enabled version of ibc-go v7.3 +### (This is the min version of `ibc-go` that supports `08-wasm` light clients) +cosmwasm-schema = "1.5.2" +cosmwasm-std = "1.5.2" + +[dev-dependencies] +cosmwasm-vm = "1.5.2" +ibc-client-tendermint = { workspace = true } +sov-celestia-client = { path = "./../", default-features = false, features = ["test-util"] } +tendermint-testgen = { workspace = true } + +[features] +default = ["std"] +std = [ + "ibc-core/std", + "ibc-client-tendermint/std", + "sov-celestia-client/std", +] + diff --git a/clients/sov-celestia-cw/src/types/client_type.rs b/clients/sov-celestia/cw-contract/src/client_type.rs similarity index 77% rename from clients/sov-celestia-cw/src/types/client_type.rs rename to clients/sov-celestia/cw-contract/src/client_type.rs index c87fdfd0..8164764b 100644 --- a/clients/sov-celestia-cw/src/types/client_type.rs +++ b/clients/sov-celestia/cw-contract/src/client_type.rs @@ -1,5 +1,4 @@ -use ibc_core::client::context::client_state::ClientStateExecution; -use ibc_core::client::context::consensus_state::ConsensusState as ConsensusStateTrait; +use ibc_client_cw::api::ClientType; use ibc_core::client::types::error::ClientError; use ibc_core::derive::ConsensusState as ConsensusStateDerive; use ibc_core::primitives::proto::Any; @@ -9,8 +8,6 @@ use sov_celestia_client::types::consensus_state::{ SovTmConsensusState, SOV_TENDERMINT_CONSENSUS_STATE_TYPE_URL, }; -use crate::context::Context; - pub struct SovTmClient; impl<'a> ClientType<'a> for SovTmClient { @@ -18,13 +15,6 @@ impl<'a> ClientType<'a> for SovTmClient { type ConsensusState = AnyConsensusState; } -/// Enables the introduction of custom client and consensus state types tailored -/// for Sovereign light clients. -pub trait ClientType<'a>: Sized { - type ClientState: ClientStateExecution> + Clone; - type ConsensusState: ConsensusStateTrait + Into + TryFrom; -} - #[derive(Clone, Debug, ConsensusStateDerive)] pub enum AnyConsensusState { Sovereign(ConsensusState), diff --git a/clients/sov-celestia-cw/src/entrypoints.rs b/clients/sov-celestia/cw-contract/src/entrypoint.rs similarity index 64% rename from clients/sov-celestia-cw/src/entrypoints.rs rename to clients/sov-celestia/cw-contract/src/entrypoint.rs index 3b634b9e..4ce7cac5 100644 --- a/clients/sov-celestia-cw/src/entrypoints.rs +++ b/clients/sov-celestia/cw-contract/src/entrypoint.rs @@ -1,13 +1,14 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult}; +use cosmwasm_std::{ + entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, +}; +use ibc_client_cw::context::Context; +use ibc_client_cw::types::{ContractError, InstantiateMsg, QueryMsg, SudoMsg}; -use crate::context::Context; -use crate::types::{ContractError, InstantiateMsg, QueryMsg, SovTmClient, SudoMsg}; +use crate::client_type::SovTmClient; pub type SovTmContext<'a> = Context<'a, SovTmClient>; -#[cfg_attr(not(feature = "library"), entry_point)] +#[entry_point] pub fn instantiate( deps: DepsMut<'_>, env: Env, @@ -21,7 +22,7 @@ pub fn instantiate( Ok(Response::default().set_data(data)) } -#[cfg_attr(not(feature = "library"), entry_point)] +#[entry_point] pub fn sudo(deps: DepsMut<'_>, env: Env, msg: SudoMsg) -> Result { let mut ctx = SovTmContext::new_mut(deps, env)?; @@ -30,7 +31,7 @@ pub fn sudo(deps: DepsMut<'_>, env: Env, msg: SudoMsg) -> Result, env: Env, msg: QueryMsg) -> StdResult { let ctx = SovTmContext::new_ref(deps, env)?; diff --git a/clients/sov-celestia/cw-contract/src/lib.rs b/clients/sov-celestia/cw-contract/src/lib.rs new file mode 100644 index 00000000..fcbb2d23 --- /dev/null +++ b/clients/sov-celestia/cw-contract/src/lib.rs @@ -0,0 +1,8 @@ +//! Contains the CosmWasm contract implementation for the `sov-celestia` light +//! client. + +pub mod client_type; +pub mod entrypoint; + +#[cfg(test)] +pub mod tests; diff --git a/clients/sov-celestia-cw/src/tests/fixture.rs b/clients/sov-celestia/cw-contract/src/tests/fixture.rs similarity index 95% rename from clients/sov-celestia-cw/src/tests/fixture.rs rename to clients/sov-celestia/cw-contract/src/tests/fixture.rs index 8faaca95..61fb5d72 100644 --- a/clients/sov-celestia-cw/src/tests/fixture.rs +++ b/clients/sov-celestia/cw-contract/src/tests/fixture.rs @@ -3,6 +3,11 @@ use std::time::Duration; use cosmwasm_std::testing::{mock_env, mock_info}; use cosmwasm_std::{coins, from_json, Deps, DepsMut, Empty, MessageInfo, StdError}; +use ibc_client_cw::types::{ + CheckForMisbehaviourMsgRaw, ExportMetadataMsg, GenesisMetadata, InstantiateMsg, QueryMsg, + QueryResponse, StatusMsg, VerifyClientMessageRaw, +}; +use ibc_client_cw::utils::AnyCodec; use ibc_client_tendermint::types::Header; use ibc_core::client::types::{Height, Status}; use ibc_core::host::types::identifiers::ChainId; @@ -18,12 +23,7 @@ use sov_celestia_client::types::consensus_state::SovTmConsensusState; use sov_celestia_client::types::sovereign::{Root, SovereignParamsConfig}; use tendermint_testgen::{Generator, Validator}; -use crate::entrypoints::SovTmContext; -use crate::types::{ - CheckForMisbehaviourMsgRaw, ExportMetadataMsg, GenesisMetadata, InstantiateMsg, QueryMsg, - QueryResponse, StatusMsg, VerifyClientMessageRaw, -}; -use crate::utils::AnyCodec; +use crate::entrypoint::SovTmContext; /// Test fixture #[derive(Clone, Debug)] @@ -107,8 +107,8 @@ impl Fixture { let sov_consensus_state = dummy_sov_consensus_state(self.trusted_timestamp); InstantiateMsg { - client_state: SovTmClientState::encode_thru_any(sov_client_state), - consensus_state: SovTmConsensusState::encode_thru_any(sov_consensus_state), + client_state: SovTmClientState::encode_to_any_vec(sov_client_state), + consensus_state: SovTmConsensusState::encode_to_any_vec(sov_consensus_state), checksum: dummy_checksum(), } } @@ -152,7 +152,7 @@ impl Fixture { Root::from([0; 32]), ); - SovTmHeader::encode_thru_any(sov_header) + SovTmHeader::encode_to_any_vec(sov_header) } pub fn dummy_client_message(&self) -> Vec { diff --git a/clients/sov-celestia-cw/src/tests/mod.rs b/clients/sov-celestia/cw-contract/src/tests/mod.rs similarity index 90% rename from clients/sov-celestia-cw/src/tests/mod.rs rename to clients/sov-celestia/cw-contract/src/tests/mod.rs index 67ee7c0e..d2e8625e 100644 --- a/clients/sov-celestia-cw/src/tests/mod.rs +++ b/clients/sov-celestia/cw-contract/src/tests/mod.rs @@ -2,13 +2,13 @@ pub mod fixture; use cosmwasm_std::from_json; use cosmwasm_std::testing::{mock_dependencies, mock_env}; +use ibc_client_cw::types::{ + ContractResult, MigrateClientStoreMsg, UpdateStateMsgRaw, UpdateStateOnMisbehaviourMsgRaw, +}; use ibc_core::client::types::Status; -use crate::entrypoints::{instantiate, sudo}; +use crate::entrypoint::{instantiate, sudo}; use crate::tests::fixture::{dummy_msg_info, Fixture}; -use crate::types::{ - ContractResult, MigrateClientStoreMsg, UpdateStateMsgRaw, UpdateStateOnMisbehaviourMsgRaw, -}; #[test] fn happy_cw_create_client() { @@ -77,7 +77,7 @@ fn happy_cw_recovery_client() { let instantiate_msg = fxt.dummy_instantiate_msg(); - let data = ctx.instantiate(instantiate_msg.clone()).unwrap(); + ctx.instantiate(instantiate_msg.clone()).unwrap(); // ------------------- Freeze subject client ------------------- @@ -87,15 +87,14 @@ fn happy_cw_recovery_client() { let mut ctx = fxt.ctx_mut(deps.as_mut()); - let data = ctx - .sudo(UpdateStateOnMisbehaviourMsgRaw { client_message }.into()) + ctx.sudo(UpdateStateOnMisbehaviourMsgRaw { client_message }.into()) .unwrap(); // ------------------- Create substitute client ------------------- ctx.set_substitute_prefix(); - let data = ctx.instantiate(instantiate_msg).unwrap(); + ctx.instantiate(instantiate_msg).unwrap(); // ------------------- Recover subject client ------------------- diff --git a/clients/sov-celestia/src/client_state/execution.rs b/clients/sov-celestia/src/client_state/execution.rs index 56e8e881..a408922d 100644 --- a/clients/sov-celestia/src/client_state/execution.rs +++ b/clients/sov-celestia/src/client_state/execution.rs @@ -1,4 +1,7 @@ use ibc_core::client::context::client_state::ClientStateExecution; +use ibc_core::client::context::{ + Convertible, ExtClientExecutionContext, ExtClientValidationContext, +}; use ibc_core::client::types::error::ClientError; use ibc_core::client::types::Height; use ibc_core::host::types::identifiers::ClientId; @@ -14,16 +17,12 @@ use sov_celestia_client_types::sovereign::SovereignConsensusParams; use super::ClientState; use crate::consensus_state::ConsensusState; -use crate::context::{ - ConsensusStateConverter, ExecutionContext as SovExecutionContext, - ValidationContext as SovValidationContext, -}; impl ClientStateExecution for ClientState where - E: SovExecutionContext, + E: ExtClientExecutionContext, E::ClientStateRef: From, - E::ConsensusStateRef: ConsensusStateConverter, + E::ConsensusStateRef: Convertible, { fn initialise( &self, @@ -91,12 +90,12 @@ pub fn initialise( consensus_state: Any, ) -> Result<(), ClientError> where - E: SovExecutionContext, + E: ExtClientExecutionContext, E::ClientStateRef: From, - E::ConsensusStateRef: ConsensusStateConverter, + E::ConsensusStateRef: Convertible, { - let host_timestamp = SovValidationContext::host_timestamp(ctx)?; - let host_height = SovValidationContext::host_height(ctx)?; + let host_timestamp = ExtClientValidationContext::host_timestamp(ctx)?; + let host_height = ExtClientValidationContext::host_height(ctx)?; let sov_consensus_state = SovTmConsensusState::try_from(consensus_state)?; @@ -131,9 +130,9 @@ pub fn update_state( header: Any, ) -> Result, ClientError> where - E: SovExecutionContext, + E: ExtClientExecutionContext, E::ClientStateRef: From, - E::ConsensusStateRef: ConsensusStateConverter, + E::ConsensusStateRef: Convertible, { let header = Header::try_from(header)?; let header_height = header.height(); @@ -156,8 +155,8 @@ where // // Do nothing. } else { - let host_timestamp = SovValidationContext::host_timestamp(ctx)?; - let host_height = SovValidationContext::host_height(ctx)?; + let host_timestamp = ExtClientValidationContext::host_timestamp(ctx)?; + let host_height = ExtClientValidationContext::host_height(ctx)?; let new_consensus_state = ConsensusStateType::from(header.clone()); let new_client_state = client_state.clone().with_da_header(header.da_header)?; @@ -192,9 +191,9 @@ pub fn update_state_on_misbehaviour( _client_message: Any, ) -> Result<(), ClientError> where - E: SovExecutionContext, + E: ExtClientExecutionContext, E::ClientStateRef: From, - E::ConsensusStateRef: ConsensusStateConverter, + E::ConsensusStateRef: Convertible, { let frozen_client_state = client_state.clone().with_frozen_height(Height::min(0)); @@ -214,9 +213,9 @@ pub fn update_state_on_upgrade( upgraded_consensus_state: Any, ) -> Result where - E: SovExecutionContext, + E: ExtClientExecutionContext, E::ClientStateRef: From, - E::ConsensusStateRef: ConsensusStateConverter, + E::ConsensusStateRef: Convertible, { let mut upgraded_client_state = SovTmClientState::try_from(upgraded_client_state)?; let upgraded_consensus_state = ConsensusState::try_from(upgraded_consensus_state)?; @@ -264,8 +263,8 @@ where SovTmConsensusState::new(new_sovereign_consensus_params, new_tm_consensus_params); let latest_height = new_client_state.latest_height_in_sov(); - let host_timestamp = SovValidationContext::host_timestamp(ctx)?; - let host_height = SovValidationContext::host_height(ctx)?; + let host_timestamp = ExtClientValidationContext::host_timestamp(ctx)?; + let host_height = ExtClientValidationContext::host_height(ctx)?; ctx.store_client_state( ClientStatePath::new(client_id.clone()), @@ -300,9 +299,9 @@ pub fn update_on_recovery( substitute_client_state: Any, ) -> Result<(), ClientError> where - E: SovExecutionContext, + E: ExtClientExecutionContext, E::ClientStateRef: From, - E::ConsensusStateRef: ConsensusStateConverter, + E::ConsensusStateRef: Convertible, { let substitute_client_state = ClientState::try_from(substitute_client_state)?.into_inner(); diff --git a/clients/sov-celestia/src/client_state/misbehaviour.rs b/clients/sov-celestia/src/client_state/misbehaviour.rs index 731814a4..e323502b 100644 --- a/clients/sov-celestia/src/client_state/misbehaviour.rs +++ b/clients/sov-celestia/src/client_state/misbehaviour.rs @@ -1,16 +1,18 @@ use ibc_client_tendermint::client_state::verify_misbehaviour_header; -use ibc_client_tendermint::context::TmVerifier; +use ibc_core::client::context::{Convertible, ExtClientValidationContext}; use ibc_core::client::types::error::ClientError; use ibc_core::host::types::identifiers::ClientId; use ibc_core::host::types::path::ClientConsensusStatePath; use sov_celestia_client_types::client_message::SovTmMisbehaviour; use sov_celestia_client_types::client_state::SovTmClientState; - -use crate::context::{ConsensusStateConverter, ValidationContext as SovValidationContext}; +use sov_celestia_client_types::consensus_state::SovTmConsensusState; +use tendermint::crypto::Sha256; +use tendermint::merkle::MerkleHash; +use tendermint_light_client_verifier::Verifier as TmVerifier; /// Determines whether or not two conflicting headers at the same height would /// have convinced the light client. -pub fn verify_misbehaviour( +pub fn verify_misbehaviour( ctx: &V, client_state: &SovTmClientState, misbehaviour: &SovTmMisbehaviour, @@ -18,10 +20,11 @@ pub fn verify_misbehaviour( verifier: &impl TmVerifier, ) -> Result<(), ClientError> where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, + H: MerkleHash + Sha256 + Default, { - misbehaviour.validate_basic()?; + misbehaviour.validate_basic::()?; let header_1 = misbehaviour.header_1(); let trusted_consensus_state_1 = { @@ -49,7 +52,7 @@ where let current_timestamp = ctx.host_timestamp()?; - verify_misbehaviour_header( + verify_misbehaviour_header::( &header_1.da_header, client_state.chain_id(), &client_state.as_light_client_options()?, @@ -59,7 +62,7 @@ where verifier, )?; - verify_misbehaviour_header( + verify_misbehaviour_header::( &header_2.da_header, client_state.chain_id(), &client_state.as_light_client_options()?, diff --git a/clients/sov-celestia/src/client_state/update_client.rs b/clients/sov-celestia/src/client_state/update_client.rs index 4e4a1542..04f849e3 100644 --- a/clients/sov-celestia/src/client_state/update_client.rs +++ b/clients/sov-celestia/src/client_state/update_client.rs @@ -1,6 +1,6 @@ -use ibc_client_tendermint::context::TmVerifier; use ibc_client_tendermint::types::error::IntoResult; use ibc_client_tendermint::types::Header as TmHeader; +use ibc_core::client::context::{Convertible, ExtClientValidationContext}; use ibc_core::client::types::error::ClientError; use ibc_core::client::types::Height; use ibc_core::host::types::identifiers::ClientId; @@ -9,14 +9,14 @@ use sov_celestia_client_types::client_message::SovTmHeader; use sov_celestia_client_types::client_state::SovTmClientState; use sov_celestia_client_types::consensus_state::SovTmConsensusState; use sov_celestia_client_types::sovereign::{AggregatedProof, CodeCommitment, Root}; +use tendermint::crypto::Sha256; +use tendermint::merkle::MerkleHash; use tendermint_light_client_verifier::types::{TrustedBlockState, UntrustedBlockState}; -use tendermint_light_client_verifier::Verifier; - -use crate::context::{ConsensusStateConverter, ValidationContext as SovValidationContext}; +use tendermint_light_client_verifier::Verifier as TmVerifier; /// Verifies the IBC header type for the Sovereign SDK rollups, which consists /// of the DA header and the aggregated proof date validation. -pub fn verify_header( +pub fn verify_header( ctx: &V, client_state: &SovTmClientState, header: &SovTmHeader, @@ -24,18 +24,19 @@ pub fn verify_header( verifier: &impl TmVerifier, ) -> Result<(), ClientError> where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, + H: MerkleHash + Sha256 + Default, { // Checks the sanity of the fields in the header. - header.validate_basic()?; + header.validate_basic::()?; header.validate_da_height_offset( client_state.genesis_da_height(), client_state.latest_height_in_sov(), )?; - verify_da_header(ctx, client_state, &header.da_header, client_id, verifier)?; + verify_da_header::(ctx, client_state, &header.da_header, client_id, verifier)?; verify_aggregated_proof( ctx, @@ -49,7 +50,7 @@ where /// Verifies the DA header type for the Sovereign SDK rollups against the /// trusted state. -pub fn verify_da_header( +pub fn verify_da_header( ctx: &V, client_state: &SovTmClientState, da_header: &TmHeader, @@ -57,8 +58,9 @@ pub fn verify_da_header( verifier: &impl TmVerifier, ) -> Result<(), ClientError> where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, + H: MerkleHash + Sha256 + Default, { let chain_id = client_state.chain_id(); @@ -82,7 +84,7 @@ where .consensus_state(&trusted_client_cons_state_path)? .try_into()?; - da_header.check_trusted_next_validator_set( + da_header.check_trusted_next_validator_set::( &trusted_consensus_state.da_params.next_validators_hash, )?; @@ -122,7 +124,6 @@ where // main header verification, delegated to the tendermint-light-client crate. verifier - .verifier() .verify_update_header( untrusted_state, trusted_state, @@ -141,8 +142,8 @@ pub fn verify_aggregated_proof( aggregated_proof: &AggregatedProof, ) -> Result<(), ClientError> where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, { if !genesis_state_root.matches(aggregated_proof.genesis_state_root()) { return Err(ClientError::Other { @@ -171,8 +172,8 @@ pub fn check_da_misbehaviour_on_update( client_latest_height: &Height, ) -> Result where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, { let maybe_existing_consensus_state = { let path_at_header_height = ClientConsensusStatePath::new( diff --git a/clients/sov-celestia/src/client_state/validation.rs b/clients/sov-celestia/src/client_state/validation.rs index 59543513..8f1521d2 100644 --- a/clients/sov-celestia/src/client_state/validation.rs +++ b/clients/sov-celestia/src/client_state/validation.rs @@ -1,6 +1,6 @@ use ibc_client_tendermint::client_state::check_for_misbehaviour_on_misbehavior; -use ibc_client_tendermint::context::{DefaultVerifier, TmVerifier}; use ibc_core::client::context::client_state::ClientStateValidation; +use ibc_core::client::context::{Convertible, ExtClientValidationContext}; use ibc_core::client::types::error::ClientError; use ibc_core::client::types::Status; use ibc_core::host::types::identifiers::ClientId; @@ -12,15 +12,19 @@ use sov_celestia_client_types::client_message::{ SOV_TENDERMINT_MISBEHAVIOUR_TYPE_URL, }; use sov_celestia_client_types::client_state::SovTmClientState; +use sov_celestia_client_types::consensus_state::SovTmConsensusState; +use tendermint::crypto::default::Sha256 as DefaultSha256; +use tendermint::crypto::Sha256; +use tendermint::merkle::MerkleHash; +use tendermint_light_client_verifier::{ProdVerifier, Verifier as TmVerifier}; use super::ClientState; use crate::client_state::{check_da_misbehaviour_on_update, verify_header, verify_misbehaviour}; -use crate::context::{ConsensusStateConverter, ValidationContext as SovValidationContext}; impl ClientStateValidation for ClientState where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, { fn verify_client_message( &self, @@ -28,12 +32,12 @@ where client_id: &ClientId, client_message: Any, ) -> Result<(), ClientError> { - verify_client_message( + verify_client_message::( self.inner(), ctx, client_id, client_message, - &DefaultVerifier, + &ProdVerifier::default(), ) } @@ -50,14 +54,14 @@ where status(self.inner(), ctx, client_id) } - fn check_substitute(&self, ctx: &V, substitute_client_state: Any) -> Result<(), ClientError> { + fn check_substitute(&self, _ctx: &V, substitute_client_state: Any) -> Result<(), ClientError> { check_substitute::(self.inner(), substitute_client_state) } } /// Verify the client message as part of the validation process during the /// update client flow. -pub fn verify_client_message( +pub fn verify_client_message( client_state: &SovTmClientState, ctx: &V, client_id: &ClientId, @@ -65,17 +69,18 @@ pub fn verify_client_message( verifier: &impl TmVerifier, ) -> Result<(), ClientError> where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, + H: MerkleHash + Sha256 + Default, { match client_message.type_url.as_str() { SOV_TENDERMINT_HEADER_TYPE_URL => { let header = SovTmHeader::try_from(client_message)?; - verify_header(ctx, client_state, &header, client_id, verifier) + verify_header::(ctx, client_state, &header, client_id, verifier) } SOV_TENDERMINT_MISBEHAVIOUR_TYPE_URL => { let misbehaviour = SovTmMisbehaviour::try_from(client_message)?; - verify_misbehaviour(ctx, client_state, &misbehaviour, client_id, verifier) + verify_misbehaviour::(ctx, client_state, &misbehaviour, client_id, verifier) } _ => Err(ClientError::InvalidUpdateClientMessage), } @@ -90,8 +95,8 @@ pub fn check_for_misbehaviour( client_message: Any, ) -> Result where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, { match client_message.type_url.as_str() { SOV_TENDERMINT_HEADER_TYPE_URL => { @@ -125,8 +130,8 @@ pub fn status( client_id: &ClientId, ) -> Result where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, { if client_state.is_frozen() { return Ok(Status::Frozen); @@ -170,8 +175,8 @@ pub fn check_substitute( substitute_client_state: Any, ) -> Result<(), ClientError> where - V: SovValidationContext, - V::ConsensusStateRef: ConsensusStateConverter, + V: ExtClientValidationContext, + V::ConsensusStateRef: Convertible, { let substitute_client_state = SovTmClientState::try_from(substitute_client_state)?; diff --git a/clients/sov-celestia/src/context.rs b/clients/sov-celestia/src/context.rs deleted file mode 100644 index 7d970e00..00000000 --- a/clients/sov-celestia/src/context.rs +++ /dev/null @@ -1,67 +0,0 @@ -use ibc_core::client::context::{ClientExecutionContext, ClientValidationContext}; -use ibc_core::client::types::error::ClientError; -use ibc_core::client::types::Height; -use ibc_core::handler::types::error::ContextError; -use ibc_core::host::types::identifiers::ClientId; -use ibc_core::primitives::prelude::*; -use ibc_core::primitives::Timestamp; -use sov_celestia_client_types::consensus_state::SovTmConsensusState; - -/// Enables conversion (`TryInto` and `From`) between the consensus state type -/// used by the host and the one specific to the Sovereign light client, which -/// is `SovTmConsensusState`. -pub trait ConsensusStateConverter: - TryInto + From -{ -} - -impl ConsensusStateConverter for C where - C: TryInto + From -{ -} - -/// Client's context required during validation -pub trait ValidationContext: ClientValidationContext -where - Self::ConsensusStateRef: ConsensusStateConverter, -{ - /// Returns the current timestamp of the local chain. - fn host_timestamp(&self) -> Result; - - /// Returns the current height of the local chain. - fn host_height(&self) -> Result; - - /// Returns all the heights at which a consensus state is stored - fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; - - /// Search for the lowest consensus state higher than `height`. - fn next_consensus_state( - &self, - client_id: &ClientId, - height: &Height, - ) -> Result, ContextError>; - - /// Search for the highest consensus state lower than `height`. - fn prev_consensus_state( - &self, - client_id: &ClientId, - height: &Height, - ) -> Result, ContextError>; -} - -/// Client's context required during execution. -/// -/// This trait is automatically implemented for all types that implement -/// [`ValidationContext`] and [`ClientExecutionContext`] -pub trait ExecutionContext: ValidationContext + ClientExecutionContext -where - Self::ConsensusStateRef: ConsensusStateConverter, -{ -} - -impl ExecutionContext for T -where - T: ValidationContext + ClientExecutionContext, - T::ConsensusStateRef: ConsensusStateConverter, -{ -} diff --git a/clients/sov-celestia/src/lib.rs b/clients/sov-celestia/src/lib.rs index ecefbee0..49224185 100644 --- a/clients/sov-celestia/src/lib.rs +++ b/clients/sov-celestia/src/lib.rs @@ -1,6 +1,5 @@ pub mod client_state; pub mod consensus_state; -pub mod context; /// Re-exports `sov-celestia` light client data structures from the /// `sov-celestia-client-types` crate. diff --git a/clients/sov-celestia/types/src/client_message/header.rs b/clients/sov-celestia/types/src/client_message/header.rs index c80b76b9..9d4d0798 100644 --- a/clients/sov-celestia/types/src/client_message/header.rs +++ b/clients/sov-celestia/types/src/client_message/header.rs @@ -6,6 +6,8 @@ use ibc_core::client::types::Height; use ibc_core::primitives::proto::{Any, Protobuf}; use ibc_core::primitives::Timestamp; use tendermint::chain::Id as TmChainId; +use tendermint::crypto::Sha256; +use tendermint::merkle::MerkleHash; use tendermint_light_client_verifier::types::TrustedBlockState; use crate::consensus_state::SovTmConsensusState; @@ -59,8 +61,10 @@ impl SovTmHeader { } /// Performs sanity checks on header to ensure the consistency of fields. - pub fn validate_basic(&self) -> Result<(), Error> { - self.da_header.validate_basic().map_err(Error::source)?; + pub fn validate_basic(&self) -> Result<(), Error> { + self.da_header + .validate_basic::() + .map_err(Error::source)?; self.aggregated_proof.validate_basic()?; diff --git a/clients/sov-celestia/types/src/client_message/misbehaviour.rs b/clients/sov-celestia/types/src/client_message/misbehaviour.rs index 13e1b86c..8c629490 100644 --- a/clients/sov-celestia/types/src/client_message/misbehaviour.rs +++ b/clients/sov-celestia/types/src/client_message/misbehaviour.rs @@ -7,6 +7,8 @@ use ibc_client_tendermint::types::{Header as TmHeader, Misbehaviour as TmMisbeha use ibc_core::client::types::error::ClientError; use ibc_core::host::types::identifiers::ClientId; use ibc_core::primitives::proto::{Any, Protobuf}; +use tendermint::crypto::Sha256; +use tendermint::merkle::MerkleHash; use super::header::{Header, SovTmHeader}; use crate::proto::v1::Misbehaviour as RawSovTmMisbehaviour; @@ -70,9 +72,9 @@ impl SovTmMisbehaviour { Protobuf::::decode(&mut value.as_slice()).map_err(Error::source) } - pub fn validate_basic(&self) -> Result<(), Error> { - self.header_1.validate_basic()?; - self.header_2.validate_basic()?; + pub fn validate_basic(&self) -> Result<(), Error> { + self.header_1.validate_basic::()?; + self.header_2.validate_basic::()?; if self.header_1.da_header.signed_header.header.chain_id != self.header_2.da_header.signed_header.header.chain_id diff --git a/clients/sov-types/Cargo.toml b/clients/sov-types/Cargo.toml index 664176ed..c0b29bc9 100644 --- a/clients/sov-types/Cargo.toml +++ b/clients/sov-types/Cargo.toml @@ -34,20 +34,20 @@ sov-ibc-proto = { path = "./../../proto" } [features] default = ["std"] std = [ - "ibc-core/std", - "sov-ibc-proto/std", - "prost/std", - "serde/std", + "ibc-core/std", + "sov-ibc-proto/std", + "prost/std", + "serde/std", ] serde = [ - "ibc-core/serde", - "sov-ibc-proto/serde", - "dep:serde", + "ibc-core/serde", + "sov-ibc-proto/serde", + "dep:serde", ] json-schema = [ - "ibc-core/schema", - "dep:schemars", + "ibc-core/schema", + "dep:schemars", ] test-util = [ - "typed-builder", + "typed-builder", ] diff --git a/mocks/src/cosmos/configs.rs b/mocks/src/cosmos/configs.rs index eec7d8c3..c40bc984 100644 --- a/mocks/src/cosmos/configs.rs +++ b/mocks/src/cosmos/configs.rs @@ -9,7 +9,10 @@ use ibc_testkit::fixtures::clients::tendermint::ClientStateConfig; use ibc_testkit::fixtures::core::signer::dummy_bech32_account; use tendermint::{Hash, Time}; pub fn basecoin_proof_specs() -> ProofSpecs { - [get_proof_spec(), get_proof_spec()].to_vec().into() + [get_proof_spec(), get_proof_spec()] + .to_vec() + .try_into() + .expect("should convert successfully") } pub fn dummy_tm_client_state(chain_id: ChainId, latest_height: Height) -> ClientState { diff --git a/modules/sov-ibc-transfer/src/context.rs b/modules/sov-ibc-transfer/src/context.rs index 7cd8f78e..05c25825 100644 --- a/modules/sov-ibc-transfer/src/context.rs +++ b/modules/sov-ibc-transfer/src/context.rs @@ -92,7 +92,7 @@ impl<'ws, S: Spec> IbcTransferContext<'ws, S> { port_id: &PortId, channel_id: &ChannelId, ) -> Result { - let token_id = TokenId::from_str(&coin.denom.to_string()).map_err(|e| { + let token_id = TokenId::from_str(&coin.denom.to_string()).map_err(|_| { TokenTransferError::InvalidCoin { coin: coin.to_string(), } @@ -104,7 +104,9 @@ impl<'ws, S: Spec> IbcTransferContext<'ws, S> { .get(&token_id, *self.working_set.borrow_mut()) { let prefixed_denom = PrefixedDenom::from_str(&token_name).map_err(|e| { - TokenTransferError::Other(format!("Failed to parse token name: {token_name}")) + TokenTransferError::Other(format!( + "Failed to parse token name: {token_name} with error: {e}" + )) })?; let trace_prefix = TracePrefix::new(port_id.clone(), channel_id.clone()); @@ -357,7 +359,7 @@ where let escrow_address = self.obtain_escrow_address(port_id, channel_id); - let escrow_balance = self.validate_balance(token_id, escrow_address, coin.amount)?; + self.validate_balance(token_id, escrow_address, coin.amount)?; Ok(()) } @@ -439,7 +441,7 @@ impl<'ws, S: Spec> TokenTransferExecutionContext for IbcTransferContext<'ws, S> // The token name on the Sovereign SDK chains is not guaranteed to be // unique, and hence we must use the token ID (which is guaranteed to be // unique) as the ICS-20 denom to ensure uniqueness. - let token_id = TokenId::from_str(&coin.denom.to_string()).map_err(|e| { + let token_id = TokenId::from_str(&coin.denom.to_string()).map_err(|_| { TokenTransferError::InvalidCoin { coin: coin.to_string(), } @@ -468,7 +470,7 @@ impl<'ws, S: Spec> TokenTransferExecutionContext for IbcTransferContext<'ws, S> channel_id: &ChannelId, coin: &PrefixedCoin, ) -> Result<(), TokenTransferError> { - let token_id = TokenId::from_str(&coin.denom.to_string()).map_err(|e| { + let token_id = TokenId::from_str(&coin.denom.to_string()).map_err(|_| { TokenTransferError::InvalidCoin { coin: coin.to_string(), } diff --git a/modules/sov-ibc/src/clients/context.rs b/modules/sov-ibc/src/clients/context.rs index a2e3a4bc..06e041e4 100644 --- a/modules/sov-ibc/src/clients/context.rs +++ b/modules/sov-ibc/src/clients/context.rs @@ -1,4 +1,3 @@ -use ibc_client_tendermint::context::ValidationContext as TmValidationContext; use ibc_core::client::context::prelude::*; use ibc_core::client::types::error::ClientError; use ibc_core::client::types::Height; @@ -7,7 +6,6 @@ use ibc_core::host::types::identifiers::ClientId; use ibc_core::host::types::path::{ClientConsensusStatePath, ClientStatePath}; use ibc_core::host::ValidationContext; use ibc_core::primitives::Timestamp; -use sov_celestia_client::context::ValidationContext as SovValidationContext; use sov_modules_api::Spec; use super::{AnyClientState, AnyConsensusState}; @@ -146,42 +144,7 @@ impl<'a, S: Spec> ClientExecutionContext for IbcContext<'a, S> { } } -impl<'a, S: Spec> TmValidationContext for IbcContext<'a, S> { - fn host_timestamp(&self) -> Result { - ::host_timestamp(self) - } - - fn host_height(&self) -> Result { - ::host_height(self) - } - - fn consensus_state_heights(&self, _client_id: &ClientId) -> Result, ContextError> { - let heights = self - .ibc - .client_update_heights_vec - .iter(*self.working_set.borrow_mut()) - .collect::>(); - Ok(heights) - } - - fn next_consensus_state( - &self, - client_id: &ClientId, - height: &Height, - ) -> Result, ContextError> { - next_consensus_state(self, client_id, height) - } - - fn prev_consensus_state( - &self, - client_id: &ClientId, - height: &Height, - ) -> Result, ContextError> { - prev_consensus_state(self, client_id, height) - } -} - -impl<'a, S: Spec> SovValidationContext for IbcContext<'a, S> { +impl<'a, S: Spec> ExtClientValidationContext for IbcContext<'a, S> { fn host_timestamp(&self) -> Result { ::host_timestamp(self) } diff --git a/modules/sov-ibc/src/context.rs b/modules/sov-ibc/src/context.rs index d54f6814..7c445fde 100644 --- a/modules/sov-ibc/src/context.rs +++ b/modules/sov-ibc/src/context.rs @@ -179,7 +179,7 @@ where fn validate_self_client( &self, - client_state_of_host_on_counterparty: Self::HostClientState, + _client_state_of_host_on_counterparty: Self::HostClientState, ) -> Result<(), ContextError> { // Note: We can optionally implement this. // It would require having a Protobuf definition of the chain's `ClientState` that other chains would use. @@ -327,7 +327,7 @@ where Duration::ZERO } - fn validate_message_signer(&self, signer: &Signer) -> Result<(), ContextError> { + fn validate_message_signer(&self, _signer: &Signer) -> Result<(), ContextError> { Ok(()) } } @@ -581,7 +581,7 @@ where /// FIXME: To implement this method there should be a way for IBC module to /// insert logs into the transaction receipts upon execution - fn log_message(&mut self, message: String) -> Result<(), ContextError> { + fn log_message(&mut self, _message: String) -> Result<(), ContextError> { Ok(()) } } diff --git a/modules/sov-ibc/src/rpc/context.rs b/modules/sov-ibc/src/rpc/context.rs index 8d802662..d7ecec88 100644 --- a/modules/sov-ibc/src/rpc/context.rs +++ b/modules/sov-ibc/src/rpc/context.rs @@ -383,7 +383,7 @@ where Ok(consensus_states) } - fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError> { + fn consensus_state_heights(&self, _client_id: &ClientId) -> Result, ContextError> { let heights: Vec = self .ibc .client_update_heights_vec diff --git a/modules/sov-ibc/src/rpc/methods.rs b/modules/sov-ibc/src/rpc/methods.rs index 5fe6ea11..f2249836 100644 --- a/modules/sov-ibc/src/rpc/methods.rs +++ b/modules/sov-ibc/src/rpc/methods.rs @@ -5,9 +5,9 @@ use std::rc::Rc; use ibc_core::client::context::client_state::ClientStateCommon; use ibc_core::host::ValidationContext; use ibc_query::core::channel::{ - query_channel_consensus_state, query_channels, query_connection_channels, - query_packet_acknowledgements, query_packet_commitments, query_unreceived_acks, - query_unreceived_packets, QueryChannelClientStateRequest, QueryChannelClientStateResponse, + query_channels, query_connection_channels, query_packet_acknowledgements, + query_packet_commitments, query_unreceived_acks, query_unreceived_packets, + QueryChannelClientStateRequest, QueryChannelClientStateResponse, QueryChannelConsensusStateRequest, QueryChannelConsensusStateResponse, QueryChannelRequest, QueryChannelResponse, QueryChannelsRequest, QueryChannelsResponse, QueryConnectionChannelsRequest, QueryConnectionChannelsResponse, @@ -536,7 +536,17 @@ impl Ibc { client_latest_height.revision_height(), )?; - query_channel_consensus_state(&ibc_ctx, &request).map_err(to_jsonrpsee_error) + Ok(QueryChannelConsensusStateResponse::new( + consensus_state + .ok_or(to_jsonrpsee_error(format!( + "Consensus state not found for channel {:?}", + request.channel_id + )))? + .into(), + connection_end.client_id().clone(), + proof, + proof_height, + )) } #[rpc_method(name = "packetCommitment")] diff --git a/nix/sov-celestia-cw.nix b/nix/sov-celestia-cw.nix index f94d5a70..bb3a0769 100644 --- a/nix/sov-celestia-cw.nix +++ b/nix/sov-celestia-cw.nix @@ -31,9 +31,9 @@ let cargoLock = { lockFile = ../Cargo.lock; outputHashes = { - "basecoin-0.1.0" = "sha256-NCjfbrtxo7NZ/pW2FxAf+bB9kmluQLuI0zekwX2lypY="; + "basecoin-0.1.0" = "sha256-jOW6ppKkpH4GK/c/+UzkHih40PCzeKCdd9rVc4RDSQM="; "celestia-proto-0.1.0" = "sha256-iUgrctxdJUyhfrEQ0zoVj5AKIqgj/jQVNli5/K2nxK0="; - "ibc-0.51.0" = "sha256-6HcMSTcKx4y1hfKcXnzgiNM9FWdqUuUNnemAgS36Z1A="; + "ibc-0.51.0" = "sha256-vKcqk6VqL0D842Z1rMfVTSTmQ9MO2USi9t7ZrwJcxSE="; "jmt-0.9.0" = "sha256-pq1v6FXS//6Dh+fdysQIVp+RVLHdXrW5aDx3263O1rs="; "nmt-rs-0.1.0" = "sha256-jcHbqyIKk8ZDDjSz+ot5YDxROOnrpM4TRmNFVfNniwU="; "risc0-cycle-utils-0.3.0" = "sha256-5dA62v1eqfyZBny4s3YlC2Tty7Yfd/OAVGfTlLBgypk=";