diff --git a/.cargo/config b/.cargo/config deleted file mode 100644 index 7e36d9af..00000000 --- a/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --workspace --exclude test-utils --release --lib --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --bin schema" diff --git a/Cargo.lock b/Cargo.lock index 0818a2f9..cd2a6fba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - [[package]] name = "ahash" version = "0.7.6" @@ -34,57 +19,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anyhow" version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" -[[package]] -name = "arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base16ct" version = "0.1.1" @@ -97,12 +43,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base32" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" - [[package]] name = "base64" version = "0.11.0" @@ -121,12 +61,6 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "base64ct" version = "1.6.0" @@ -169,63 +103,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" -[[package]] -name = "borsh" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" -dependencies = [ - "borsh-derive", - "hashbrown 0.12.3", -] - -[[package]] -name = "borsh-derive" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" -dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", - "proc-macro-crate 0.1.5", - "proc-macro2 1.0.70", - "syn 1.0.109", -] - -[[package]] -name = "borsh-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" -dependencies = [ - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 1.0.109", -] - -[[package]] -name = "borsh-schema-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" -dependencies = [ - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 1.0.109", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - [[package]] name = "byteorder" version = "1.4.3" @@ -241,31 +118,12 @@ dependencies = [ "serde", ] -[[package]] -name = "bytes-lit" -version = "0.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0adabf37211a5276e46335feabcbb1530c95eb3fdf85f324c7db942770aa025d" -dependencies = [ - "num-bigint", - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", -] - [[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -[[package]] -name = "centralized-connection" -version = "0.0.0" -dependencies = [ - "soroban-sdk", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -279,10 +137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", - "iana-time-zone", "num-traits", - "serde", - "winapi", ] [[package]] @@ -299,7 +154,7 @@ dependencies = [ "displaydoc", "dyn-clone", "hex", - "hex-literal 0.3.4", + "hex-literal", "ibc-proto", "ics23", "pbjson", @@ -325,12 +180,6 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - [[package]] name = "cosmwasm" version = "0.7.2" @@ -432,23 +281,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crate-git-revision" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c521bf1f43d31ed2f73441775ed31935d77901cb3451e44b38a1c1612fcbaf98" -dependencies = [ - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -483,16 +315,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "ctor" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" -dependencies = [ - "quote 1.0.33", - "syn 2.0.42", -] - [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -507,134 +329,7 @@ dependencies = [ ] [[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", -] - -[[package]] -name = "curve25519-dalek-ng" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.6.4", - "subtle-ng", - "zeroize", -] - -[[package]] -name = "cw-centralized-connection" -version = "0.1.0" -dependencies = [ - "common", - "cosmwasm", - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.1.0", - "cw-xcall-lib 0.1.0", - "cw2 1.0.1", - "getrandom", - "hex", - "schemars 0.8.12", - "serde", - "serde-json-wasm 0.5.2", - "thiserror", -] - -[[package]] -name = "cw-common" -version = "0.1.1" -source = "git+https://github.com/icon-project/IBC-Integration.git?branch=main#9a9095926b9141217473745d21ad06c277313015" -dependencies = [ - "bech32", - "bytes", - "common", - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.1.0", - "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", - "debug_print", - "hex", - "hex-buffer-serde", - "ibc-proto", - "prost 0.11.9", - "schemars 0.8.12", - "serde", - "serde-json-wasm 0.5.2", - "serde_json", -] - -[[package]] -name = "cw-integration" -version = "0.2.1" -dependencies = [ - "anyhow", - "common", - "cosmwasm-schema", - "cosmwasm-std", - "cw-common", - "cw-mock-dapp", - "cw-mock-dapp-multi", - "cw-mock-ibc-core", - "cw-multi-test 0.15.1", - "cw-storage-plus 1.1.0", - "cw-xcall 0.2.1", - "cw-xcall-ibc-connection", - "cw-xcall-lib 0.1.0", - "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", - "hex", - "ibc", - "prost 0.11.9", - "strum", - "strum_macros", -] - -[[package]] -name = "cw-mock-dapp" -version = "0.1.0" -dependencies = [ - "common", - "cosmwasm", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test 0.16.4", - "cw-storage-plus 1.1.0", - "cw-xcall-lib 0.1.0", - "cw2 1.0.1", - "getrandom", - "schemars 0.8.12", - "serde", - "serde-json-wasm 0.5.2", - "thiserror", -] - -[[package]] -name = "cw-mock-dapp-multi" +name = "cw-intents-v1" version = "0.1.0" dependencies = [ "common", @@ -642,52 +337,16 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cosmwasm-storage", - "cw-multi-test 0.16.4", + "cw-multi-test", "cw-storage-plus 1.1.0", - "cw-xcall-lib 0.1.0", - "cw2 1.0.1", + "cw2", + "cw20", + "cw20-base", "getrandom", - "schemars 0.8.12", - "serde", - "serde-json-wasm 0.5.2", - "thiserror", -] - -[[package]] -name = "cw-mock-ibc-core" -version = "0.1.1" -source = "git+https://github.com/icon-project/IBC-Integration.git?branch=main#9a9095926b9141217473745d21ad06c277313015" -dependencies = [ - "common", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-common", - "cw-storage-plus 1.1.0", - "cw-xcall 0.2.0", - "cw2 1.0.1", "hex", "schemars 0.8.12", "serde", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e81b4a7821d5eeba0d23f737c16027b39a600742ca8c32eb980895ffd270f4" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.15.1", - "cw-utils 0.15.1", - "derivative", - "itertools 0.10.5", - "prost 0.9.0", - "schemars 0.8.12", - "serde", + "serde-json-wasm 0.5.2", "thiserror", ] @@ -700,9 +359,9 @@ dependencies = [ "anyhow", "cosmwasm-std", "cw-storage-plus 1.0.1", - "cw-utils 1.0.1", + "cw-utils", "derivative", - "itertools 0.10.5", + "itertools", "k256 0.11.6", "prost 0.9.0", "schemars 0.8.12", @@ -710,17 +369,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw-storage-plus" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6cf70ef7686e2da9ad7b067c5942cd3e88dd9453f7af42f54557f8af300fb0" -dependencies = [ - "cosmwasm-std", - "schemars 0.8.12", - "serde", -] - [[package]] name = "cw-storage-plus" version = "1.0.1" @@ -744,13 +392,13 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.15.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae0b69fa7679de78825b4edeeec045066aa2b2c4b6e063d80042e565bb4da5c" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 0.15.1", + "cw2", "schemars 0.8.12", "semver", "serde", @@ -758,211 +406,47 @@ dependencies = [ ] [[package]] -name = "cw-utils" +name = "cw2" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.0.1", + "cw-storage-plus 1.0.1", "schemars 0.8.12", - "semver", "serde", - "thiserror", ] [[package]] -name = "cw-xcall" -version = "0.1.0" -source = "git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5#7f250bc9c6560591ccc16289cb8159dd100bbe76" +name = "cw20" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" dependencies = [ - "common", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", - "cw2 1.0.1", - "debug_print", + "cw-utils", "schemars 0.8.12", "serde", - "thiserror", ] [[package]] -name = "cw-xcall" -version = "0.2.0" -source = "git+https://github.com/icon-project/xCall.git?branch=main#1b64d8d3b932842bdc68d7fabc3842a7695860ed" -dependencies = [ - "common", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?branch=main)", - "cw2 1.0.1", - "debug_print", - "schemars 0.8.12", - "serde", - "thiserror", -] - -[[package]] -name = "cw-xcall" -version = "0.2.1" -dependencies = [ - "anyhow", - "common", - "cosmwasm", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw-xcall-lib 0.1.0", - "cw2 1.0.1", - "debug_print", - "getrandom", - "hex", - "schemars 0.8.12", - "serde", - "test-utils", - "thiserror", -] - -[[package]] -name = "cw-xcall-ibc-connection" -version = "0.1.1" -source = "git+https://github.com/icon-project/IBC-Integration.git?branch=main#9a9095926b9141217473745d21ad06c277313015" -dependencies = [ - "common", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-common", - "cw-storage-plus 1.1.0", - "cw-xcall 0.1.0", - "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", - "cw2 1.0.1", - "debug_print", - "hex", - "schemars 0.8.12", - "serde", - "thiserror", -] - -[[package]] -name = "cw-xcall-lib" -version = "0.1.0" -dependencies = [ - "anyhow", - "common", - "cosmwasm", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw2 1.0.1", - "debug_print", - "getrandom", - "hex", - "schemars 0.8.12", - "serde", - "test-utils", - "thiserror", -] - -[[package]] -name = "cw-xcall-lib" -version = "0.1.0" -source = "git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5#7f250bc9c6560591ccc16289cb8159dd100bbe76" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw2 1.0.1", - "debug_print", - "schemars 0.8.12", - "serde", - "thiserror", -] - -[[package]] -name = "cw-xcall-lib" -version = "0.1.0" -source = "git+https://github.com/icon-project/xCall.git?branch=main#1b64d8d3b932842bdc68d7fabc3842a7695860ed" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw2 1.0.1", - "debug_print", - "schemars 0.8.12", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5abb8ecea72e09afff830252963cb60faf945ce6cef2c20a43814516082653da" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.15.1", - "schemars 0.8.12", - "serde", -] - -[[package]] -name = "cw2" +name = "cw20-base" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" +checksum = "afcd279230b08ed8afd8be5828221622bd5b9ce25d0b01d58bad626c6ce0169c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.0.1", + "cw-utils", + "cw2", + "cw20", "schemars 0.8.12", + "semver", "serde", -] - -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2 1.0.70", - "quote 1.0.33", - "strsim", - "syn 2.0.42", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core", - "quote 1.0.33", - "syn 2.0.42", + "thiserror", ] [[package]] @@ -1002,17 +486,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" -dependencies = [ - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -1062,12 +535,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - [[package]] name = "dyn-clone" version = "1.0.11" @@ -1109,52 +576,14 @@ dependencies = [ "signature 1.6.4", ] -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", -] - -[[package]] -name = "ed25519-consensus" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" -dependencies = [ - "curve25519-dalek-ng", - "hex", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek 4.1.3", - "ed25519 2.2.3", - "rand_core 0.6.4", - "serde", - "sha2 0.10.8", - "subtle", - "zeroize", -] - [[package]] name = "ed25519-zebra" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ - "curve25519-dalek 3.2.0", - "hashbrown 0.12.3", + "curve25519-dalek", + "hashbrown", "hex", "rand_core 0.6.4", "serde", @@ -1207,21 +636,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" -dependencies = [ - "serde", -] - [[package]] name = "errno" version = "0.3.1" @@ -1243,18 +657,6 @@ dependencies = [ "libc", ] -[[package]] -name = "escape-bytes" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfcf67fea2815c2fc3b90873fae90957be12ff417335dfadc7f52927feb03b2" - -[[package]] -name = "ethnum" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" - [[package]] name = "fastrand" version = "1.9.0" @@ -1284,21 +686,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "static_assertions", -] - [[package]] name = "fixedbitset" version = "0.4.2" @@ -1314,12 +701,6 @@ dependencies = [ "paste", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "forward_ref" version = "1.0.0" @@ -1405,18 +786,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" - [[package]] name = "group" version = "0.12.1" @@ -1448,12 +821,6 @@ dependencies = [ "ahash", ] -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - [[package]] name = "heck" version = "0.4.1" @@ -1471,19 +838,6 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hex-buffer-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e84645a601cf4a58f40673d51c111d1b5f847b711559c076ebcb779606a6d0" -dependencies = [ - "hex", - "serde", -] [[package]] name = "hex-literal" @@ -1491,12 +845,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - [[package]] name = "hmac" version = "0.12.1" @@ -1506,62 +854,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ibc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030b54b02c3f35ea7265da2beedf0d7d22492208919a6582f980ff3eae82c2d0" -dependencies = [ - "bytes", - "cfg-if", - "derive_more", - "displaydoc", - "dyn-clone", - "erased-serde", - "ibc-proto", - "ics23", - "num-traits", - "parity-scale-codec", - "primitive-types", - "prost 0.11.9", - "safe-regex", - "scale-info", - "serde", - "serde_derive", - "serde_json", - "sha2 0.10.8", - "subtle-encoding", - "tendermint", - "tendermint-light-client-verifier", - "tendermint-proto", - "time", - "tracing", - "uint", -] - [[package]] name = "ibc-proto" version = "0.26.0" @@ -1569,12 +861,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9303a1308c886aea769ef0667c5caa422a78b01e9f8177fea8b91b08a4ff50c" dependencies = [ "base64 0.13.1", - "borsh", "bytes", "flex-error", - "parity-scale-codec", "prost 0.11.9", - "scale-info", "serde", "subtle-encoding", "tendermint-proto", @@ -1596,59 +885,15 @@ dependencies = [ ] [[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 1.0.109", -] - -[[package]] -name = "indexmap" -version = "1.9.3" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" -dependencies = [ - "equivalent", - "hashbrown 0.14.3", - "serde", + "hashbrown", ] -[[package]] -name = "indexmap-nostd" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" - [[package]] name = "instant" version = "0.1.12" @@ -1678,30 +923,12 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "k256" version = "0.11.6" @@ -1749,12 +976,6 @@ version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -1767,47 +988,12 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" -[[package]] -name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mock-dapp-multi" -version = "0.0.0" -dependencies = [ - "soroban-rlp", - "soroban-sdk", - "soroban-xcall-lib", - "xcall", -] - [[package]] name = "multimap" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - [[package]] name = "num-derive" version = "0.3.3" @@ -1819,26 +1005,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -1848,15 +1014,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.18.0" @@ -1869,42 +1026,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", - "primeorder", - "sha2 0.10.8", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" -dependencies = [ - "arrayvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" -dependencies = [ - "proc-macro-crate 2.0.1", - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 1.0.109", -] - [[package]] name = "paste" version = "1.0.12" @@ -1928,7 +1049,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdbb7b706f2afc610f3853550cdbbf6372fd324824a087806bd4480ea4996e24" dependencies = [ "heck", - "itertools 0.10.5", + "itertools", "prost 0.11.9", "prost-types", ] @@ -1955,7 +1076,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap", ] [[package]] @@ -1990,15 +1111,6 @@ dependencies = [ "spki 0.7.3", ] -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - [[package]] name = "prettyplease" version = "0.1.25" @@ -2009,65 +1121,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "prettyplease" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" -dependencies = [ - "proc-macro2 1.0.70", - "syn 2.0.42", -] - -[[package]] -name = "primeorder" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" -dependencies = [ - "elliptic-curve 0.13.8", -] - -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-serde", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" -dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", -] - [[package]] name = "proc-macro2" version = "0.4.30" @@ -2114,12 +1167,12 @@ checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", "heck", - "itertools 0.10.5", + "itertools", "lazy_static", "log", "multimap", "petgraph", - "prettyplease 0.1.25", + "prettyplease", "prost 0.11.9", "prost-types", "regex", @@ -2135,7 +1188,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools", "proc-macro2 1.0.70", "quote 1.0.33", "syn 1.0.109", @@ -2148,7 +1201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools", "proc-macro2 1.0.70", "quote 1.0.33", "syn 1.0.109", @@ -2181,27 +1234,6 @@ dependencies = [ "proc-macro2 1.0.70", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_core" version = "0.5.1" @@ -2282,27 +1314,12 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "rustc-hex" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - [[package]] name = "rustix" version = "0.37.19" @@ -2317,12 +1334,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - [[package]] name = "ryu" version = "1.0.13" @@ -2376,30 +1387,6 @@ dependencies = [ "safe-regex-compiler", ] -[[package]] -name = "scale-info" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" -dependencies = [ - "cfg-if", - "derive_more", - "parity-scale-codec", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 1.0.109", -] - [[package]] name = "schemars" version = "0.5.1" @@ -2572,36 +1559,6 @@ dependencies = [ "syn 2.0.42", ] -[[package]] -name = "serde_with" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.1.0", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" -dependencies = [ - "darling", - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", -] - [[package]] name = "sha2" version = "0.9.9" @@ -2656,12 +1613,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - [[package]] name = "snafu" version = "0.5.0" @@ -2684,308 +1635,46 @@ dependencies = [ ] [[package]] -name = "soroban-builtin-sdk-macros" -version = "21.2.1" +name = "spki" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f57a68ef8777e28e274de0f3a88ad9a5a41d9a2eb461b4dd800b086f0e83b80" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ - "itertools 0.11.0", - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", + "base64ct", + "der 0.6.1", ] [[package]] -name = "soroban-env-common" -version = "21.2.1" +name = "spki" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1c89463835fe6da996318156d39f424b4f167c725ec692e5a7a2d4e694b3d" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ - "arbitrary", - "crate-git-revision", - "ethnum", - "num-derive 0.4.2", - "num-traits", - "serde", - "soroban-env-macros", - "soroban-wasmi", - "static_assertions", - "stellar-xdr", - "wasmparser", + "base64ct", + "der 0.7.9", ] [[package]] -name = "soroban-env-guest" -version = "21.2.1" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bfb2536811045d5cd0c656a324cbe9ce4467eb734c7946b74410d90dea5d0ce" -dependencies = [ - "soroban-env-common", - "static_assertions", -] +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "soroban-env-host" -version = "21.2.1" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b7a32c28f281c423189f1298960194f0e0fc4eeb72378028171e556d8cd6160" -dependencies = [ - "backtrace", - "curve25519-dalek 4.1.3", - "ecdsa 0.16.9", - "ed25519-dalek", - "elliptic-curve 0.13.8", - "generic-array", - "getrandom", - "hex-literal 0.4.1", - "hmac", - "k256 0.13.1", - "num-derive 0.4.2", - "num-integer", - "num-traits", - "p256", - "rand", - "rand_chacha", - "sec1 0.7.3", - "sha2 0.10.8", - "sha3", - "soroban-builtin-sdk-macros", - "soroban-env-common", - "soroban-wasmi", - "static_assertions", - "stellar-strkey", - "wasmparser", -] +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "soroban-env-macros" -version = "21.2.1" +name = "subtle-encoding" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "242926fe5e0d922f12d3796cd7cd02dd824e5ef1caa088f45fce20b618309f64" -dependencies = [ - "itertools 0.11.0", - "proc-macro2 1.0.70", - "quote 1.0.33", - "serde", - "serde_json", - "stellar-xdr", - "syn 2.0.42", -] - -[[package]] -name = "soroban-ledger-snapshot" -version = "21.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15263ad07a3e0ec3f2ee3aea83b7c1a0610ad26ba76819f5092afcfaf0f3a3ed" -dependencies = [ - "serde", - "serde_json", - "serde_with", - "soroban-env-common", - "soroban-env-host", - "thiserror", -] - -[[package]] -name = "soroban-rlp" -version = "0.1.0" -dependencies = [ - "soroban-sdk", -] - -[[package]] -name = "soroban-sdk" -version = "21.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e995a8604a01ec7a8c1e1f60a890981eb00f1cd25c3b15f5194364f27993cc" -dependencies = [ - "arbitrary", - "bytes-lit", - "ctor", - "ed25519-dalek", - "rand", - "serde", - "serde_json", - "soroban-env-guest", - "soroban-env-host", - "soroban-ledger-snapshot", - "soroban-sdk-macros", - "stellar-strkey", -] - -[[package]] -name = "soroban-sdk-macros" -version = "21.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eda569fe4c3aa2b45f2366e07d9476127e141c7f376d625b6a8217ee99f81f" -dependencies = [ - "crate-git-revision", - "darling", - "itertools 0.11.0", - "proc-macro2 1.0.70", - "quote 1.0.33", - "rustc_version", - "sha2 0.10.8", - "soroban-env-common", - "soroban-spec", - "soroban-spec-rust", - "stellar-xdr", - "syn 2.0.42", -] - -[[package]] -name = "soroban-spec" -version = "21.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cfbe92fbabaea20517dc76fc89227735ffda2f19a10e2fe96db0ecb19b72b1" -dependencies = [ - "base64 0.13.1", - "stellar-xdr", - "thiserror", - "wasmparser", -] - -[[package]] -name = "soroban-spec-rust" -version = "21.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6569ea39d9f4d8cafadd0a2a77fc94991f7870d4d3c2a1fa401db9cb02d6082b" -dependencies = [ - "prettyplease 0.2.15", - "proc-macro2 1.0.70", - "quote 1.0.33", - "sha2 0.10.8", - "soroban-spec", - "stellar-xdr", - "syn 2.0.42", - "thiserror", -] - -[[package]] -name = "soroban-wasmi" -version = "0.31.1-soroban.20.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710403de32d0e0c35375518cb995d4fc056d0d48966f2e56ea471b8cb8fc9719" -dependencies = [ - "smallvec", - "spin", - "wasmi_arena", - "wasmi_core", - "wasmparser-nostd", -] - -[[package]] -name = "soroban-xcall-lib" -version = "0.1.0" -dependencies = [ - "soroban-sdk", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.9", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "stellar-strkey" -version = "0.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d2bf45e114117ea91d820a846fd1afbe3ba7d717988fee094ce8227a3bf8bd" -dependencies = [ - "base32", - "crate-git-revision", - "thiserror", -] - -[[package]] -name = "stellar-xdr" -version = "21.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2675a71212ed39a806e415b0dbf4702879ff288ec7f5ee996dda42a135512b50" -dependencies = [ - "arbitrary", - "base64 0.13.1", - "crate-git-revision", - "escape-bytes", - "hex", - "serde", - "serde_with", - "stellar-strkey", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck", - "proc-macro2 1.0.70", - "quote 1.0.33", - "rustversion", - "syn 1.0.109", -] - -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" dependencies = [ "zeroize", ] -[[package]] -name = "subtle-ng" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" - [[package]] name = "syn" version = "0.15.44" @@ -3040,8 +1729,7 @@ checksum = "cda53c85447577769cdfc94c10a56f34afef2c00e4108badb57fce6b1a0c75eb" dependencies = [ "bytes", "digest 0.10.7", - "ed25519 1.5.3", - "ed25519-consensus", + "ed25519", "flex-error", "futures", "num-traits", @@ -3052,7 +1740,6 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.8", "signature 1.6.4", "subtle", "subtle-encoding", @@ -3061,19 +1748,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "tendermint-light-client-verifier" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c3dc3c75f7a5708ac0bf98374b2b1a2cf17b3a45ddfd5faab3c111aff7fc0e" -dependencies = [ - "derive_more", - "flex-error", - "serde", - "tendermint", - "time", -] - [[package]] name = "tendermint-proto" version = "0.29.1" @@ -3082,7 +1756,7 @@ checksum = "c943f78c929cdf14553842f705f2c30324bc35b9179caaa5c9b80620f60652e6" dependencies = [ "bytes", "flex-error", - "num-derive 0.3.3", + "num-derive", "num-traits", "prost 0.11.9", "prost-types", @@ -3092,22 +1766,6 @@ dependencies = [ "time", ] -[[package]] -name = "test-utils" -version = "0.1.0" -source = "git+https://github.com/icon-project/IBC-Integration.git?branch=main#9a9095926b9141217473745d21ad06c277313015" -dependencies = [ - "common", - "cosmwasm-std", - "cw-multi-test 0.16.4", - "hex", - "hex-literal 0.3.4", - "ibc-proto", - "prost 0.11.9", - "serde", - "serde_json", -] - [[package]] name = "thiserror" version = "1.0.40" @@ -3134,8 +1792,6 @@ version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" dependencies = [ - "itoa", - "serde", "time-core", "time-macros", ] @@ -3155,77 +1811,12 @@ dependencies = [ "time-core", ] -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" -dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" - [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicode-ident" version = "1.0.9" @@ -3256,98 +1847,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" -dependencies = [ - "cfg-if", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote 1.0.33", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" - -[[package]] -name = "wasmi_arena" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "104a7f73be44570cac297b3035d76b169d6599637631cf37a1703326a0727073" - -[[package]] -name = "wasmi_core" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf1a7db34bff95b85c261002720c00c3a6168256dcb93041d3fa2054d19856a" -dependencies = [ - "downcast-rs", - "libm", - "num-traits", - "paste", -] - -[[package]] -name = "wasmparser" -version = "0.116.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" -dependencies = [ - "indexmap 2.1.0", - "semver", -] - -[[package]] -name = "wasmparser-nostd" -version = "0.100.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5a015fe95f3504a94bb1462c717aae75253e39b9dd6c3fb1062c934535c64aa" -dependencies = [ - "indexmap-nostd", -] - [[package]] name = "which" version = "4.4.0" @@ -3359,37 +1858,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -3438,22 +1906,6 @@ dependencies = [ "windows_x86_64_msvc 0.48.0", ] -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -3466,12 +1918,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -3484,12 +1930,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -3502,18 +1942,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -3526,12 +1954,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -3544,12 +1966,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -3562,12 +1978,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -3580,51 +1990,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.5.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b5c3db89721d50d0e2a673f5043fc4722f76dcc352d7b1ab8b8288bed4ed2c5" -dependencies = [ - "memchr", -] - -[[package]] -name = "xcall" -version = "0.1.0" -dependencies = [ - "soroban-rlp", - "soroban-sdk", - "soroban-xcall-lib", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2 1.0.70", - "quote 1.0.33", - "syn 2.0.42", -] - [[package]] name = "zeroize" version = "1.8.1" diff --git a/Cargo.toml b/Cargo.toml index 8ee82d52..25ea8802 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,6 @@ [workspace] members = [ "contracts/cosmwasm-vm/*", - "contracts/soroban/contracts/*", - "contracts/soroban/libs/*" ] [workspace.package] @@ -28,15 +26,11 @@ bytes = { version = "1.4.0", default-features = false } thiserror = { version = "1.0.39" } hex ={ version = "0.4.3", default-features = false } debug_print = "1.0.0" -cw-xcall-lib = { path="contracts/cosmwasm-vm/cw-xcall-lib" } -cw-xcall={ path="contracts/cosmwasm-vm/cw-xcall" } -cw-xcall-ibc-connection = { git="https://github.com/icon-project/IBC-Integration.git", branch = "main" } -cw-mock-ibc-core = { git="https://github.com/icon-project/IBC-Integration.git", branch = "main"} + common = { git="https://github.com/icon-project/IBC-Integration.git", branch = "main" } cw-common={ git="https://github.com/icon-project/IBC-Integration.git", branch = "main" } cw-mock-dapp = {path="contracts/cosmwasm-vm/cw-mock-dapp"} -cw-mock-dapp-multi = { path="contracts/cosmwasm-vm/cw-mock-dapp-multi"} soroban-sdk = "21.6.0" diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/Cargo.toml b/contracts/cosmwasm-vm/cw-centralized-connection/Cargo.toml deleted file mode 100644 index 2fe703c7..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/Cargo.toml +++ /dev/null @@ -1,45 +0,0 @@ -[package] -name = "cw-centralized-connection" -version = "0.1.0" -edition = "2021" - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -library = [] - -[package.metadata.scripts] -optimize = """docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ - --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.10 -""" - -[dependencies] -cosmwasm-schema = {workspace=true} -cosmwasm-std = { workspace=true} -cw-storage-plus = {workspace=true} -cw2 = {workspace=true} -schemars = {workspace=true} -serde = { workspace=true} -thiserror = { workspace=true} -common ={ workspace=true} -cw-xcall-lib = { path="../cw-xcall-lib" } -hex = "0.4.3" -serde-json-wasm = {workspace=true} - -[dev-dependencies] -cosmwasm = "0.7.2" -getrandom = {version = "0.2", default-features = false, features = ["custom"]} - diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/src/contract.rs b/contracts/cosmwasm-vm/cw-centralized-connection/src/contract.rs deleted file mode 100644 index a50561c8..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/src/contract.rs +++ /dev/null @@ -1,216 +0,0 @@ -use cosmwasm_std::{coins, Addr, BankMsg, Event, SubMsgResult, Uint128}; -use cw_xcall_lib::network_address::NetId; - -use super::*; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw-mock-dapp"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -impl<'a> CwCentralizedConnection<'a> { - pub fn instantiate( - &mut self, - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, - ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - let relayer = deps.api.addr_validate(&msg.relayer)?; - self.store_admin(deps.storage, relayer)?; - - let xcall_address = deps.api.addr_validate(&msg.xcall_address)?; - self.store_xcall(deps.storage, xcall_address)?; - self.store_denom(deps.storage, msg.denom)?; - - let _ = self.store_conn_sn(deps.storage, 0); - - Ok(Response::new() - .add_attribute("action", "instantiate") - .add_attribute("relayer", msg.relayer) - .add_attribute("xcall_address", msg.xcall_address)) - } - - pub fn send_message( - &mut self, - deps: DepsMut, - info: MessageInfo, - to: NetId, - sn: i64, - msg: Vec, - ) -> Result { - self.ensure_xcall(deps.storage, info.sender)?; - - let next_conn_sn = self.get_next_conn_sn(deps.storage)?; - - let mut fee = 0; - - if sn >= 0 { - fee = self.get_fee(deps.storage, to.clone(), sn > 0)?.into(); - } - - let value = self.get_amount_for_denom(&info.funds, self.denom(deps.storage)); - - if fee > value { - return Err(ContractError::InsufficientFunds); - } - - Ok(Response::new() - .add_attribute("action", "send_message") - .add_event( - Event::new("Message") - .add_attribute("targetNetwork", to.to_string()) - .add_attribute("connSn", next_conn_sn.to_string()) - .add_attribute("msg", self.hex_encode(msg)), - )) - } - - pub fn recv_message( - &mut self, - deps: DepsMut, - info: MessageInfo, - src_network: NetId, - conn_sn: u128, - msg: String, - ) -> Result { - self.ensure_admin(deps.storage, info.sender)?; - - let hex_string_trimmed = msg.trim_start_matches("0x"); - let bytes = hex::decode(hex_string_trimmed).expect("Failed to decode to vec"); - - let vec_msg: Vec = Binary(bytes).into(); - if self.get_receipt(deps.as_ref().storage, src_network.clone(), conn_sn) { - return Err(ContractError::DuplicateMessage); - } - self.store_receipt(deps.storage, src_network.clone(), conn_sn)?; - - let xcall_submessage = - self.call_xcall_handle_message(deps.storage, &src_network, vec_msg)?; - - Ok(Response::new().add_submessage(xcall_submessage)) - } - - pub fn claim_fees( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - ) -> Result { - self.ensure_admin(deps.storage, info.sender)?; - let contract_balance = self.get_balance(&deps, env, self.denom(deps.storage)); - let msg = BankMsg::Send { - to_address: self.query_admin(deps.storage)?.to_string(), - amount: coins(contract_balance, self.denom(deps.storage)), - }; - Ok(Response::new() - .add_attribute("action", "claim fees") - .add_message(msg)) - } - - pub fn revert_message( - &self, - deps: DepsMut, - info: MessageInfo, - sn: u128, - ) -> Result { - self.ensure_admin(deps.storage, info.sender)?; - let xcall_submessage = self.call_xcall_handle_error(deps.storage, sn)?; - - Ok(Response::new().add_submessage(xcall_submessage)) - } - - pub fn set_admin( - &mut self, - deps: DepsMut, - info: MessageInfo, - address: Addr, - ) -> Result { - self.ensure_admin(deps.storage, info.sender)?; - let admin = deps.api.addr_validate(address.as_str())?; - let _ = self.store_admin(deps.storage, admin); - Ok(Response::new().add_attribute("action", "set_admin")) - } - - pub fn set_fee( - &mut self, - deps: DepsMut, - info: MessageInfo, - network_id: NetId, - message_fee: u128, - response_fee: u128, - ) -> Result { - self.ensure_admin(deps.storage, info.sender)?; - self.store_fee(deps.storage, network_id, message_fee, response_fee)?; - Ok(Response::new().add_attribute("action", "set_fee")) - } - - pub fn get_fee( - &self, - store: &dyn Storage, - network_id: NetId, - response: bool, - ) -> Result { - let mut fee = self.query_message_fee(store, network_id.clone()); - if response { - fee += self.query_response_fee(store, network_id); - } - Ok(fee.into()) - } - - fn xcall_handle_message_reply( - &self, - _deps: DepsMut, - message: Reply, - ) -> Result { - println!("Reply From Forward XCall"); - match message.result { - SubMsgResult::Ok(_) => Ok(Response::new() - .add_attribute("action", "call_message") - .add_attribute("method", "xcall_handle_message_reply")), - SubMsgResult::Err(error) => Err(ContractError::ReplyError { - code: message.id, - msg: error, - }), - } - } - - fn xcall_handle_error_reply( - &self, - _deps: DepsMut, - message: Reply, - ) -> Result { - println!("Reply From Forward XCall"); - match message.result { - SubMsgResult::Ok(_) => Ok(Response::new() - .add_attribute("action", "call_message") - .add_attribute("method", "xcall_handle_error_reply")), - SubMsgResult::Err(error) => Err(ContractError::ReplyError { - code: message.id, - msg: error, - }), - } - } - - pub fn reply(&self, deps: DepsMut, _env: Env, msg: Reply) -> Result { - match msg.id { - XCALL_HANDLE_MESSAGE_REPLY_ID => self.xcall_handle_message_reply(deps, msg), - XCALL_HANDLE_ERROR_REPLY_ID => self.xcall_handle_error_reply(deps, msg), - _ => Err(ContractError::ReplyError { - code: msg.id, - msg: "Unknown".to_string(), - }), - } - } - - pub fn migrate( - &self, - deps: DepsMut, - _env: Env, - _msg: MigrateMsg, - ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION) - .map_err(ContractError::Std)?; - Ok(Response::default().add_attribute("migrate", "successful")) - } -} diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/src/errors.rs b/contracts/cosmwasm-vm/cw-centralized-connection/src/errors.rs deleted file mode 100644 index 25760e19..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/src/errors.rs +++ /dev/null @@ -1,21 +0,0 @@ -use super::*; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - #[error("Unauthorized")] - Unauthorized {}, - #[error("Invalid Address {address}")] - InvalidAddress { address: String }, - #[error("Only Relayer(Admin)")] - OnlyAdmin, - #[error("Only XCall")] - OnlyXCall, - #[error("Duplicate Message")] - DuplicateMessage, - #[error("InsufficientFunds")] - InsufficientFunds, - #[error("ERR_REPLY_ERROR|{code:?}|{msg:?}")] - ReplyError { code: u64, msg: String }, -} diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/src/helper.rs b/contracts/cosmwasm-vm/cw-centralized-connection/src/helper.rs deleted file mode 100644 index 496a16dc..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/src/helper.rs +++ /dev/null @@ -1,85 +0,0 @@ -use cosmwasm_std::{ensure_eq, Addr, BalanceResponse, BankQuery, Coin}; -use cw_xcall_lib::network_address::NetId; - -pub const XCALL_HANDLE_MESSAGE_REPLY_ID: u64 = 1; -pub const XCALL_HANDLE_ERROR_REPLY_ID: u64 = 2; -use super::*; - -impl<'a> CwCentralizedConnection<'a> { - pub fn ensure_admin(&self, store: &dyn Storage, address: Addr) -> Result<(), ContractError> { - let admin = self.query_admin(store)?; - ensure_eq!(admin, address, ContractError::OnlyAdmin); - - Ok(()) - } - - pub fn ensure_xcall(&self, store: &dyn Storage, address: Addr) -> Result<(), ContractError> { - let xcall = self.query_xcall(store)?; - ensure_eq!(xcall, address, ContractError::OnlyXCall); - - Ok(()) - } - - pub fn get_amount_for_denom(&self, funds: &Vec, target_denom: String) -> u128 { - for coin in funds.iter() { - if coin.denom == target_denom { - return coin.amount.into(); - } - } - 0 - } - - pub fn get_balance(&self, deps: &DepsMut, env: Env, denom: String) -> u128 { - let address = env.contract.address.to_string(); - let balance_query = BankQuery::Balance { denom, address }; - let balance_response: BalanceResponse = deps.querier.query(&balance_query.into()).unwrap(); - - balance_response.amount.amount.u128() - } - - pub fn hex_encode(&self, data: Vec) -> String { - if data.is_empty() { - "null".to_string() - } else { - hex::encode(data) - } - } - - pub fn call_xcall_handle_message( - &self, - store: &dyn Storage, - nid: &NetId, - msg: Vec, - ) -> Result { - let xcall_host = self.query_xcall(store)?; - let xcall_msg = cw_xcall_lib::xcall_msg::ExecuteMsg::HandleMessage { - from_nid: nid.clone(), - msg, - }; - let call_message: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: xcall_host.to_string(), - msg: to_json_binary(&xcall_msg).unwrap(), - funds: vec![], - }); - let sub_msg: SubMsg = SubMsg::reply_always(call_message, XCALL_HANDLE_MESSAGE_REPLY_ID); - Ok(sub_msg) - } - - pub fn call_xcall_handle_error( - &self, - store: &dyn Storage, - sn: u128, - ) -> Result { - let xcall_host = self.query_xcall(store)?; - let xcall_msg = cw_xcall_lib::xcall_msg::ExecuteMsg::HandleError { - sn: sn.try_into().unwrap(), - }; - let call_message: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: xcall_host.to_string(), - msg: to_json_binary(&xcall_msg).unwrap(), - funds: vec![], - }); - let sub_msg: SubMsg = SubMsg::reply_always(call_message, XCALL_HANDLE_ERROR_REPLY_ID); - Ok(sub_msg) - } -} diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/src/lib.rs b/contracts/cosmwasm-vm/cw-centralized-connection/src/lib.rs deleted file mode 100644 index 7122325a..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/src/lib.rs +++ /dev/null @@ -1,97 +0,0 @@ -pub mod contract; -pub mod errors; -pub mod helper; -pub mod msg; -pub mod state; -pub mod types; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - entry_point, to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Reply, - Response, StdError, StdResult, Storage, SubMsg, WasmMsg, -}; - -use cw2::set_contract_version; -use cw_storage_plus::{Item, Map}; -pub use errors::*; -pub use helper::*; -use msg::{ExecuteMsg, MigrateMsg, QueryMsg}; -use state::CwCentralizedConnection; -use thiserror::Error; -pub use types::*; - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - let mut centralized_connection = CwCentralizedConnection::default(); - - centralized_connection.instantiate(deps, env, info, msg) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let mut centralized_connection = CwCentralizedConnection::default(); - match msg { - ExecuteMsg::SendMessage { to, sn, msg } => { - centralized_connection.send_message(deps, info, to, sn, msg) - } - ExecuteMsg::RecvMessage { - src_network, - conn_sn, - msg, - } => centralized_connection.recv_message(deps, info, src_network, conn_sn, msg), - ExecuteMsg::ClaimFees {} => centralized_connection.claim_fees(deps, env, info), - ExecuteMsg::RevertMessage { sn } => centralized_connection.revert_message(deps, info, sn), - ExecuteMsg::SetAdmin { address } => centralized_connection.set_admin(deps, info, address), - ExecuteMsg::SetFee { - network_id, - message_fee, - response_fee, - } => centralized_connection.set_fee(deps, info, network_id, message_fee, response_fee), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - let centralized_connection = CwCentralizedConnection::default(); - match msg { - QueryMsg::GetFee { nid, response } => to_json_binary( - ¢ralized_connection - .get_fee(deps.storage, nid, response) - .unwrap(), - ), - - QueryMsg::GetReceipt { - src_network, - conn_sn, - } => { - to_json_binary(¢ralized_connection.get_receipt(deps.storage, src_network, conn_sn)) - } - - QueryMsg::Admin {} => { - to_json_binary(¢ralized_connection.admin().load(deps.storage).unwrap()) - } - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result { - let centralized_connection = CwCentralizedConnection::default(); - - centralized_connection.reply(deps, env, msg) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - let centralized_connection = CwCentralizedConnection::default(); - centralized_connection.migrate(deps, _env, _msg) -} diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/src/msg.rs b/contracts/cosmwasm-vm/cw-centralized-connection/src/msg.rs deleted file mode 100644 index bc205bf8..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/src/msg.rs +++ /dev/null @@ -1,49 +0,0 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Addr; -use cw_xcall_lib::network_address::NetId; - -#[cw_serde] -pub enum ExecuteMsg { - SetFee { - network_id: NetId, - message_fee: u128, - response_fee: u128, - }, - SendMessage { - to: NetId, - sn: i64, - msg: Vec, - }, - - RecvMessage { - src_network: NetId, - conn_sn: u128, - msg: String, - }, - - ClaimFees {}, - RevertMessage { - sn: u128, - }, - SetAdmin { - address: Addr, - }, -} - -#[cw_serde] -#[derive(QueryResponses)] -/// This is a Rust enum representing different types of queries that can be made to the contract. Each -/// variant of the enum corresponds to a specific query and has a return type specified using the -/// `#[returns]` attribute. -pub enum QueryMsg { - #[returns(u64)] - GetFee { nid: NetId, response: bool }, - #[returns(bool)] - GetReceipt { src_network: NetId, conn_sn: u128 }, - //return address of admin - #[returns(Addr)] - Admin {}, -} - -#[cw_serde] -pub struct MigrateMsg {} diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/src/state.rs b/contracts/cosmwasm-vm/cw-centralized-connection/src/state.rs deleted file mode 100644 index d4d6fd97..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/src/state.rs +++ /dev/null @@ -1,113 +0,0 @@ -use cosmwasm_std::Addr; -use cw_xcall_lib::network_address::NetId; - -use crate::types::StorageKey; - -use super::*; - -pub struct CwCentralizedConnection<'a> { - message_fee: Map<'a, NetId, u128>, - response_fee: Map<'a, NetId, u128>, - admin: Item<'a, Addr>, - conn_sn: Item<'a, u128>, - receipts: Map<'a, (String, u128), bool>, - xcall: Item<'a, Addr>, - denom: Item<'a, String>, -} - -impl<'a> Default for CwCentralizedConnection<'a> { - fn default() -> Self { - Self::new() - } -} - -impl<'a> CwCentralizedConnection<'a> { - pub fn new() -> Self { - Self { - message_fee: Map::new(StorageKey::MessageFee.as_str()), - response_fee: Map::new(StorageKey::ResponseFee.as_str()), - admin: Item::new(StorageKey::Admin.as_str()), - conn_sn: Item::new(StorageKey::ConnSn.as_str()), - receipts: Map::new(StorageKey::Receipts.as_str()), - xcall: Item::new(StorageKey::XCall.as_str()), - denom: Item::new(StorageKey::Denom.as_str()), - } - } - - pub fn get_next_conn_sn(&self, store: &mut dyn Storage) -> Result { - let mut connsn = self.conn_sn.load(store).unwrap_or(0); - connsn += 1; - self.conn_sn.save(store, &connsn)?; - Ok(connsn) - } - - pub fn store_conn_sn(&mut self, store: &mut dyn Storage, sn: u128) -> StdResult<()> { - self.conn_sn.save(store, &sn)?; - Ok(()) - } - - pub fn store_fee( - &mut self, - store: &mut dyn Storage, - to: NetId, - message_fee: u128, - response_fee: u128, - ) -> StdResult<()> { - self.message_fee.save(store, to.clone(), &message_fee)?; - self.response_fee.save(store, to, &response_fee)?; - Ok(()) - } - pub fn query_message_fee(&self, store: &dyn Storage, to: NetId) -> u128 { - self.message_fee.load(store, to).unwrap_or(0) - } - - pub fn query_response_fee(&self, store: &dyn Storage, to: NetId) -> u128 { - self.response_fee.load(store, to).unwrap_or(0) - } - - pub fn store_receipt( - &mut self, - store: &mut dyn Storage, - src_network: NetId, - connsn: u128, - ) -> StdResult<()> { - self.receipts - .save(store, (src_network.to_string(), connsn), &true)?; - Ok(()) - } - - pub fn get_receipt(&self, store: &dyn Storage, src_network: NetId, sn: u128) -> bool { - self.receipts - .load(store, (src_network.to_string(), sn)) - .unwrap_or(false) - } - - pub fn store_xcall(&mut self, store: &mut dyn Storage, address: Addr) -> StdResult<()> { - self.xcall.save(store, &address)?; - Ok(()) - } - - pub fn store_admin(&mut self, store: &mut dyn Storage, address: Addr) -> StdResult<()> { - self.admin.save(store, &address)?; - Ok(()) - } - - pub fn store_denom(&mut self, store: &mut dyn Storage, denom: String) -> StdResult<()> { - self.denom.save(store, &denom)?; - Ok(()) - } - - pub fn query_admin(&self, store: &dyn Storage) -> Result { - Ok(self.admin.load(store)?) - } - - pub fn query_xcall(&self, store: &dyn Storage) -> Result { - Ok(self.xcall.load(store)?) - } - pub fn denom(&self, store: &dyn Storage) -> String { - self.denom.load(store).unwrap() - } - pub fn admin(&self) -> &Item<'a, Addr> { - &self.admin - } -} diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/src/types.rs b/contracts/cosmwasm-vm/cw-centralized-connection/src/types.rs deleted file mode 100644 index ccd3765f..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/src/types.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::*; - -#[cw_serde] -pub struct InstantiateMsg { - pub relayer: String, - pub xcall_address: String, - pub denom: String, -} - -#[cw_serde] -pub enum StorageKey { - MessageFee, - ResponseFee, - Receipts, - XCall, - Admin, - ConnSn, - Denom, -} - -impl StorageKey { - pub fn as_str(&self) -> &'static str { - match self { - StorageKey::MessageFee => "message_fee", - StorageKey::ResponseFee => "response_fee", - StorageKey::Receipts => "receipts", - StorageKey::XCall => "xcall", - StorageKey::Admin => "admin", - StorageKey::ConnSn => "conn_sn", - StorageKey::Denom => "denom", - } - } -} diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/tests/test.rs b/contracts/cosmwasm-vm/cw-centralized-connection/tests/test.rs deleted file mode 100644 index 6c906d20..00000000 --- a/contracts/cosmwasm-vm/cw-centralized-connection/tests/test.rs +++ /dev/null @@ -1,219 +0,0 @@ -pub mod setup; -use cosmwasm_std::{testing::mock_env, Env}; -use cosmwasm_std::{ - testing::{mock_dependencies, mock_info, MockApi, MockQuerier}, - Addr, MemoryStorage, OwnedDeps, Uint128, -}; -use cosmwasm_std::{Coin, Event}; -use cw_centralized_connection::{ - execute, msg::ExecuteMsg, state::CwCentralizedConnection, types::InstantiateMsg, -}; -use cw_xcall_lib::network_address::NetId; -use std::str::FromStr; - -const XCALL: &str = "xcall"; -const DENOM: &str = "denom"; -const RELAYER: &str = "relayer"; -const OWNER: &str = "owner"; - -fn instantiate( - sender: &str, -) -> ( - OwnedDeps, - Env, - CwCentralizedConnection<'_>, -) { - let mut deps: OwnedDeps = mock_dependencies(); - let mut ctx: CwCentralizedConnection<'_> = CwCentralizedConnection::default(); - let env = mock_env(); - let info = mock_info(sender, &[]); - let msg = InstantiateMsg { - relayer: RELAYER.to_string(), - xcall_address: XCALL.to_string(), - denom: DENOM.to_string(), - }; - let res = ctx.instantiate(deps.as_mut(), env.clone(), info, msg); - assert!(res.is_ok()); - - (deps, env, ctx) -} - -#[test] -fn test_initialization() { - instantiate(OWNER); -} - -#[test] -fn test_set_admin() { - let (mut deps, env, ctx) = instantiate("sender"); - let msg = ExecuteMsg::SetAdmin { - address: Addr::unchecked("admin"), - }; - - let info = mock_info(OWNER, &[]); - - let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); - assert!(res.is_err()); - - let info = mock_info(RELAYER, &[]); - - let res = execute(deps.as_mut(), env, info, msg); - assert!(res.is_ok()); - - let admin = ctx.query_admin(deps.as_mut().storage).unwrap(); - assert_eq!(admin, Addr::unchecked("admin")); -} - -#[test] -fn test_set_fee() { - let (mut deps, env, ctx) = instantiate(OWNER); - let nid = NetId::from_str("test").unwrap(); - let message_fee: u128 = 200; - let response_fee: u128 = 100; - let msg = ExecuteMsg::SetFee { - network_id: nid.clone(), - message_fee, - response_fee, - }; - - let info = mock_info(OWNER, &[]); - - let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); - assert!(res.is_err()); - - let info = mock_info(RELAYER, &[]); - - let res = execute(deps.as_mut(), env, info, msg); - assert!(res.is_ok()); - - let res = ctx - .get_fee(deps.as_mut().storage, nid.clone(), false) - .unwrap(); - assert_eq!(res, Uint128::from(message_fee)); - - let res = ctx.get_fee(deps.as_mut().storage, nid, true).unwrap(); - assert_eq!(res, Uint128::from(message_fee + response_fee)); -} - -#[test] -pub fn test_send_message() { - let (mut deps, env, _ctx) = instantiate(OWNER); - let msg = ExecuteMsg::SendMessage { - to: NetId::from_str("nid").unwrap(), - sn: 0, - msg: vec![], - }; - - let info = mock_info(OWNER, &[]); - - let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); - - assert!(res.is_err()); - - let info: cosmwasm_std::MessageInfo = mock_info(XCALL, &[]); - - let res = execute(deps.as_mut(), env, info, msg); - let event = Event::new("Message") - .add_attribute("targetNetwork", "nid") - .add_attribute("connSn", 1.to_string()) - .add_attribute("msg", "null"); - assert_eq!(res.unwrap().events[0], event); -} - -#[test] -pub fn test_recv_message() { - let (mut deps, env, mut _ctx) = instantiate(OWNER); - let src_network = NetId::from_str("nid").unwrap(); - let msg = ExecuteMsg::RecvMessage { - src_network, - conn_sn: 1, - msg: "".to_string(), - }; - - let info = mock_info(OWNER, &[]); - - let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); - - assert!(res.is_err()); - assert_eq!("Only Relayer(Admin)", res.unwrap_err().to_string()); - - let info = mock_info(RELAYER, &[]); - - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()); - - assert!(res.is_ok()); - - let res = execute(deps.as_mut(), env, info, msg); - - assert!(res.is_err()); - - assert_eq!("Duplicate Message", res.unwrap_err().to_string()); -} - -#[test] - -pub fn test_revert_message() { - let (mut deps, env, mut _ctx) = instantiate(OWNER); - let msg = ExecuteMsg::RevertMessage { sn: 1 }; - - let info = mock_info(OWNER, &[]); - - let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); - - assert!(res.is_err()); - - let info = mock_info(RELAYER, &[]); - - let res = execute(deps.as_mut(), env, info, msg); - - assert!(res.is_ok()); -} - -#[test] - -pub fn test_get_receipts() { - let (mut deps, env, ctx) = instantiate(OWNER); - let src_network = NetId::from_str("nid").unwrap(); - let msg = ExecuteMsg::RecvMessage { - src_network: src_network.clone(), - conn_sn: 1, - msg: "".to_string(), - }; - - let receipt = ctx.get_receipt(deps.as_mut().storage, src_network.clone(), 1); - assert!(!receipt); - - let _ = execute(deps.as_mut(), env, mock_info(RELAYER, &[]), msg); - - let receipt = ctx.get_receipt(deps.as_mut().storage, src_network, 1); - assert!(receipt); -} - -#[test] -pub fn test_claim_fees() { - let (mut deps, env, _ctx) = instantiate(OWNER); - let claim_msg = ExecuteMsg::ClaimFees {}; - let info = mock_info(OWNER, &[]); - let res = execute(deps.as_mut(), env.clone(), info, claim_msg.clone()); - assert!(res.is_err()); - assert_eq!("Only Relayer(Admin)", res.unwrap_err().to_string()); - - let msg = ExecuteMsg::SendMessage { - to: NetId::from_str("nid").unwrap(), - sn: 0, - msg: vec![], - }; - - let info = mock_info(XCALL, &[]); - - let _ = execute(deps.as_mut(), env.clone(), info, msg); - - let amount: u128 = 100; - let coin: Coin = Coin { - denom: DENOM.to_string(), - amount: Uint128::from(amount), - }; - let info = mock_info(RELAYER, &[coin]); - let res = execute(deps.as_mut(), env, info, claim_msg); - assert!(res.is_ok()); -} diff --git a/contracts/cosmwasm-vm/cw-integration/Cargo.toml b/contracts/cosmwasm-vm/cw-integration/Cargo.toml deleted file mode 100644 index fcc9572d..00000000 --- a/contracts/cosmwasm-vm/cw-integration/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "cw-integration" -version.workspace = true -authors.workspace = true -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-schema = {workspace=true} -cosmwasm-std = {workspace=true} -cw-storage-plus = {workspace=true} -cw-common={workspace=true} -common = { workspace=true, default-features = false } -ibc = { version = "0.32.0", default-features = false, features = ["parity-scale-codec", "mocks-no-std", "serde"]} -prost = { workspace=true} -strum="*" -strum_macros = "0.24" -cw-xcall-lib={package = "cw-xcall-lib",workspace=true} - -[dev-dependencies] -hex = "0.4.3" -cw-multi-test = "0.15.1" -cw-xcall-ibc-connection = { workspace=true } -cw-mock-ibc-core = { workspace=true } -cw-mock-dapp = { workspace=true} -cw-mock-dapp-multi = { workspace=true } -## xcall connection uses the alpha tag need to update -xcall-lib={package="cw-xcall-lib", git="https://github.com/icon-project/xCall.git", tag="v0.1.0-alpha.5"} - -cw-xcall = {workspace=true} -anyhow="*" - - diff --git a/contracts/cosmwasm-vm/cw-integration/tests/setup.rs b/contracts/cosmwasm-vm/cw-integration/tests/setup.rs deleted file mode 100644 index a326167f..00000000 --- a/contracts/cosmwasm-vm/cw-integration/tests/setup.rs +++ /dev/null @@ -1,277 +0,0 @@ -use std::collections::HashMap; - -use cosmwasm_std::{ - coins, - testing::{mock_dependencies, mock_info, MockApi, MockQuerier, MockStorage}, - Addr, Attribute, Empty, Event, IbcEndpoint, MessageInfo, OwnedDeps, -}; -use cw_common::ibc_types::IbcEventType; -use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; -use cw_xcall_ibc_connection::state::IbcConfig; - -pub const PORT: &str = "xcall"; -pub const COUNTERPARTY_NID: &str = "0x3.icon"; - -#[derive(Debug, PartialEq, Eq, Hash)] -pub enum TestApps { - Dapp, - XcallApp, - IbcCore, - XcallIbcConnection, -} - -pub struct TestContext { - pub app: App, - pub contracts: HashMap, - pub sender: Addr, - pub admin: Option, - pub caller: Option, -} - -impl TestContext { - pub fn get_dapp(&self) -> Addr { - return self.contracts.get(&TestApps::Dapp).unwrap().clone(); - } - pub fn get_ibc_core(&self) -> Addr { - return self.contracts.get(&TestApps::IbcCore).unwrap().clone(); - } - - pub fn get_xcall_app(&self) -> Addr { - return self.contracts.get(&TestApps::XcallApp).unwrap().clone(); - } - pub fn get_xcall_ibc_connection(&self) -> Addr { - return self - .contracts - .get(&TestApps::XcallIbcConnection) - .unwrap() - .clone(); - } - - pub fn set_dapp(&mut self, addr: Addr) -> Option { - self.contracts.insert(TestApps::Dapp, addr) - } - pub fn set_ibc_core(&mut self, addr: Addr) -> Option { - self.contracts.insert(TestApps::IbcCore, addr) - } - - pub fn set_xcall_app(&mut self, addr: Addr) -> Option { - self.contracts.insert(TestApps::XcallApp, addr) - } - pub fn set_xcall_ibc_connection(&mut self, addr: Addr) -> Option { - self.contracts.insert(TestApps::XcallIbcConnection, addr) - } - - pub fn list_contracts(&self) { - println!("IbcHost {}", self.get_ibc_core()); - println!("IbcConnection {}", self.get_xcall_ibc_connection()); - println!("Xcall {}", self.get_xcall_app()); - println!("Dapp {}", self.get_dapp()) - } -} - -pub fn create_mock_info(creator: &str, denom: &str, amount: u128) -> MessageInfo { - let funds = coins(amount, denom); - mock_info(creator, &funds) -} - -pub fn deps() -> OwnedDeps { - mock_dependencies() -} - -pub fn mock_ibc_config() -> IbcConfig { - let src = IbcEndpoint { - port_id: "xcall".to_string(), - channel_id: "our-channel-id".to_string(), - }; - - let dst = IbcEndpoint { - port_id: "xcall".to_string(), - channel_id: "their-channel-id".to_string(), - }; - - IbcConfig::new(src, dst) -} - -pub fn mock_dapp_contract() -> Box> { - let contract = ContractWrapper::new( - cw_mock_dapp::execute, - cw_mock_dapp::instantiate, - cw_mock_dapp::query, - ); - Box::new(contract) -} - -pub fn mock_dapp_multi_contract() -> Box> { - let contract = ContractWrapper::new( - cw_mock_dapp_multi::execute, - cw_mock_dapp_multi::instantiate, - cw_mock_dapp_multi::query, - ); - Box::new(contract) -} - -pub fn init_mock_dapp_multi_contract(mut ctx: TestContext) -> TestContext { - let code_id = ctx.app.store_code(mock_dapp_multi_contract()); - let contract_addr = ctx - .app - .instantiate_contract( - code_id, - ctx.sender.clone(), - &cw_mock_dapp_multi::types::InstantiateMsg { - address: ctx.get_xcall_app().to_string(), - }, - &[], - "MockApp", - Some(ctx.sender.clone().to_string()), - ) - .unwrap(); - ctx.set_dapp(contract_addr); - - ctx -} - -pub fn init_mock_dapp_contract(mut ctx: TestContext) -> TestContext { - let code_id = ctx.app.store_code(mock_dapp_contract()); - let contract_addr = ctx - .app - .instantiate_contract( - code_id, - ctx.sender.clone(), - &cw_mock_dapp::types::InstantiateMsg { - address: "someaddr".to_string(), - }, - &[], - "MockApp", - Some(ctx.sender.clone().to_string()), - ) - .unwrap(); - ctx.set_dapp(contract_addr); - - ctx -} - -pub fn init_mock_ibc_core_contract(mut ctx: TestContext) -> TestContext { - let ibc_core_code_id = ctx.app.store_code(mock_ibc_core_contract()); - let ibc_core_addr = ctx - .app - .instantiate_contract( - ibc_core_code_id, - ctx.sender.clone(), - &cw_common::core_msg::InstantiateMsg {}, - &[], - "IBCCore", - Some(ctx.sender.clone().to_string()), - ) - .unwrap(); - - ctx.set_ibc_core(ibc_core_addr); - ctx -} - -pub fn ibc_connection_contract() -> Box> { - let contract = ContractWrapper::new( - cw_xcall_ibc_connection::execute, - cw_xcall_ibc_connection::instantiate, - cw_xcall_ibc_connection::query, - ) - .with_reply(cw_xcall_ibc_connection::reply); - Box::new(contract) -} - -pub fn mock_ibc_core_contract() -> Box> { - let contract = ContractWrapper::new( - cw_mock_ibc_core::contract::execute, - cw_mock_ibc_core::contract::instantiate, - cw_mock_ibc_core::contract::query, - ) - .with_reply(cw_mock_ibc_core::contract::reply); - Box::new(contract) -} - -pub fn xcall_app_contract() -> Box> { - let contract = ContractWrapper::new(cw_xcall::execute, cw_xcall::instantiate, cw_xcall::query) - .with_reply(cw_xcall::reply); - Box::new(contract) -} - -pub fn init_xcall_app_contract(mut ctx: TestContext) -> TestContext { - let xcall_app_contractcode_id = ctx.app.store_code(xcall_app_contract()); - let xcall_app_contract_addr = ctx - .app - .instantiate_contract( - xcall_app_contractcode_id, - ctx.sender.clone(), - &cw_xcall::msg::InstantiateMsg { - network_id: "nid".to_string(), - denom: "uarch".to_string(), - }, - &[], - "XCallApp", - Some(ctx.sender.clone().to_string()), - ) - .unwrap(); - - ctx.set_xcall_app(xcall_app_contract_addr); - ctx -} - -pub fn init_xcall_ibc_connection_contract(mut ctx: TestContext) -> TestContext { - let ibc_connection_contract_code_id = ctx.app.store_code(ibc_connection_contract()); - let ibc_connection_contract_addr = ctx - .app - .instantiate_contract( - ibc_connection_contract_code_id, - ctx.sender.clone(), - &cw_xcall_ibc_connection::msg::InstantiateMsg { - ibc_host: ctx.get_ibc_core(), - denom: "uarch".to_string(), - port_id: PORT.to_string(), - xcall_address: ctx.get_xcall_app(), - }, - &[], - "IBCConnection", - Some(ctx.sender.clone().to_string()), - ) - .unwrap(); - - ctx.set_xcall_ibc_connection(ibc_connection_contract_addr); - ctx -} - -pub fn setup_context() -> TestContext { - let router = App::default(); - let sender = Addr::unchecked("sender"); - - TestContext { - app: router, - contracts: HashMap::new(), - sender, - admin: None, - caller: None, - } -} - -pub fn get_event(res: &AppResponse, event: &str) -> Option> { - let event = res - .events - .iter() - .filter(|e| e.ty == event) - .collect::>(); - if !event.is_empty() { - let map = to_attribute_map(&event[0].attributes); - return Some(map); - } - None -} - -pub fn get_event_name(event_type: IbcEventType) -> String { - format!("wasm-{}", event_type.as_str()) -} - -pub fn to_attribute_map(attrs: &Vec) -> HashMap { - let mut map = HashMap::new(); - for attr in attrs { - map.insert(attr.key.clone(), attr.value.clone()); - } - map -} diff --git a/contracts/cosmwasm-vm/cw-integration/tests/test_xcall.rs b/contracts/cosmwasm-vm/cw-integration/tests/test_xcall.rs deleted file mode 100644 index cae79564..00000000 --- a/contracts/cosmwasm-vm/cw-integration/tests/test_xcall.rs +++ /dev/null @@ -1,494 +0,0 @@ -mod setup; -use std::str::FromStr; - -use anyhow::Error as AppError; - -use common::rlp::Nullable; - -use cosmwasm_std::Addr; -use cosmwasm_std::IbcChannel; - -use cw_common::raw_types::channel::RawPacket; - -use cw_multi_test::AppResponse; - -use cw_multi_test::Executor; - -use cw_xcall::types::message::CSMessage; -use cw_xcall::types::request::CSMessageRequest; -use cw_xcall::types::result::CSMessageResult; -use cw_xcall::types::result::CallServiceResponseType; -use cw_xcall_ibc_connection::types::message::Message; -use cw_xcall_lib::message::call_message_rollback::CallMessageWithRollback; -use cw_xcall_lib::message::envelope::Envelope; -use cw_xcall_lib::message::AnyMessage; - -use cw_common::ProstMessage; -use cw_xcall_lib::message::msg_type::MessageType; -use cw_xcall_lib::network_address::NetworkAddress; -use setup::init_mock_dapp_multi_contract; -use setup::{ - init_mock_ibc_core_contract, init_xcall_app_contract, init_xcall_ibc_connection_contract, - TestContext, -}; -use xcall_lib::network_address::NetId; - -use crate::setup::get_event; -use crate::setup::mock_ibc_config; -use crate::setup::setup_context; -const MOCK_CONTRACT_TO_ADDR: &str = "cosmoscontract"; - -fn setup_contracts(mut ctx: TestContext) -> TestContext { - ctx = init_mock_ibc_core_contract(ctx); - // ctx.set_ibc_core(ctx.sender.clone()); - ctx = init_xcall_app_contract(ctx); - ctx = init_xcall_ibc_connection_contract(ctx); - ctx = init_mock_dapp_multi_contract(ctx); - ctx -} - -fn setup_test() -> TestContext { - let mut context = setup_context(); - context = setup_contracts(context); - context -} - -pub fn call_send_call_message( - ctx: &mut TestContext, - to: &str, - sources: Vec, - destinations: Vec, - data: Vec, - rollback: Option>, -) -> Result { - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_xcall_app(), - &xcall_lib::xcall_msg::ExecuteMsg::SendCallMessage { - to: xcall_lib::network_address::NetworkAddress::from_str(to).unwrap(), - data, - rollback, - sources: Some(sources), - destinations: Some(destinations), - }, - &[], - ) -} - -pub fn call_execute_call_message( - ctx: &mut TestContext, - request_id: u128, - data: Vec, -) -> Result { - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_xcall_app(), - &xcall_lib::xcall_msg::ExecuteMsg::ExecuteCall { request_id, data }, - &[], - ) -} - -pub fn call_dapp_send_call( - ctx: &mut TestContext, - to: String, - envelope: Envelope, -) -> Result { - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_dapp(), - &cw_mock_dapp_multi::msg::ExecuteMsg::SendMessageAny { - to: cw_xcall_lib::network_address::NetworkAddress::from_str(&to).unwrap(), - envelope, - }, - &[], - ) -} - -pub fn call_dapp_add_connection( - ctx: &mut TestContext, - src_endpoint: String, - dest_endpoint: String, - network_id: String, -) -> Result { - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_dapp(), - &cw_mock_dapp_multi::msg::ExecuteMsg::AddConnection { - src_endpoint, - dest_endpoint, - network_id, - }, - &[], - ) -} - -pub fn call_set_xcall_host(ctx: &mut TestContext) -> Result { - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_xcall_ibc_connection(), - &cw_common::xcall_connection_msg::ExecuteMsg::SetXCallHost { - address: ctx.get_xcall_app().to_string(), - }, - &[], - ) -} - -pub fn call_set_default_connection( - ctx: &mut TestContext, - nid: String, -) -> Result { - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_xcall_app(), - &xcall_lib::xcall_msg::ExecuteMsg::SetDefaultConnection { - nid: NetId::from(nid), - address: ctx.get_xcall_ibc_connection(), - }, - &[], - ) -} - -pub fn call_configure_connection( - ctx: &mut TestContext, - connection_id: String, - nid: String, - client_id: String, -) -> Result { - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_xcall_ibc_connection(), - &cw_common::xcall_connection_msg::ExecuteMsg::ConfigureConnection { - connection_id, - counterparty_port_id: "xcall".to_string(), - counterparty_nid: NetId::from_str(&nid).unwrap(), - client_id, - timeout_height: 10, - }, - &[], - ) -} - -pub fn call_ibc_channel_connect(ctx: &mut TestContext) -> Result { - let ibc_config = mock_ibc_config(); - let channel = IbcChannel::new( - ibc_config.src_endpoint().clone(), - ibc_config.dst_endpoint().clone(), - cosmwasm_std::IbcOrder::Unordered, - "ics-20", - "connection-1", - ); - - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_ibc_core(), - &cw_mock_ibc_core::msg::ExecuteMsg::IbcConfig { - msg: cosmwasm_std::IbcChannelConnectMsg::OpenConfirm { channel }, - }, - &[], - ) -} - -pub fn call_ibc_receive_packet( - ctx: &mut TestContext, - msg: Vec, -) -> Result { - let ibc_config = mock_ibc_config(); - let packet = RawPacket { - sequence: 1, - source_port: ibc_config.dst_endpoint().port_id.to_string(), - source_channel: ibc_config.dst_endpoint().channel_id.to_string(), - destination_port: ibc_config.src_endpoint().port_id.to_string(), - destination_channel: ibc_config.src_endpoint().channel_id.to_string(), - data: msg, - timeout_height: Some(cw_common::raw_types::RawHeight { - revision_number: 0, - revision_height: 12345, - }), - timeout_timestamp: 17747483838282, - }; - let packet_bytes = hex::encode(packet.encode_to_vec()); - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_ibc_core(), - &cw_mock_ibc_core::msg::ExecuteMsg::ReceivePacket { - message: packet_bytes, - }, - &[], - ) -} - -pub fn call_register_connection(ctx: &mut TestContext) -> Result { - ctx.app.execute_contract( - ctx.sender.clone(), - ctx.get_ibc_core(), - &cw_mock_ibc_core::msg::ExecuteMsg::RegisterXcall { - address: ctx.get_xcall_ibc_connection(), - }, - &[], - ) -} - -#[test] -fn test_xcall_send_call_message() { - let mut ctx = setup_test(); - call_set_xcall_host(&mut ctx).unwrap(); - call_register_connection(&mut ctx).unwrap(); - let src = ctx.get_xcall_ibc_connection().to_string(); - - let nid = "0x3.icon"; - call_configure_connection( - &mut ctx, - "connection-1".to_string(), - nid.to_string(), - "client-1".to_string(), - ) - .unwrap(); - call_ibc_channel_connect(&mut ctx).unwrap(); - let result = call_send_call_message( - &mut ctx, - &format!("{nid}/{MOCK_CONTRACT_TO_ADDR}"), - vec![src], - vec!["somedestination".to_string()], - vec![1, 2, 3], - None, - ); - println!("{result:?}"); - assert!(result.is_ok()); - let result = result.unwrap(); - let event = get_event(&result, "wasm-CallMessageSent").unwrap(); - println!("{event:?}"); - assert_eq!( - &format!("{nid}/{MOCK_CONTRACT_TO_ADDR}"), - event.get("to").unwrap() - ); -} - -#[test] -fn test_xcall_send_call() { - let mut ctx = setup_test(); - call_set_xcall_host(&mut ctx).unwrap(); - call_register_connection(&mut ctx).unwrap(); - let src = ctx.get_xcall_ibc_connection().to_string(); - let dapp = ctx.get_dapp().to_string(); - - let nid = "0x3.icon"; - call_configure_connection( - &mut ctx, - "connection-1".to_string(), - nid.to_string(), - "client-1".to_string(), - ) - .unwrap(); - call_ibc_channel_connect(&mut ctx).unwrap(); - let message = AnyMessage::CallMessageWithRollback(CallMessageWithRollback { - data: vec![1, 2, 3], - rollback: "rollback-reply".as_bytes().to_vec(), - }); - let envelope = Envelope::new(message, vec![src], vec!["somedestination".to_string()]); - let result = call_dapp_send_call(&mut ctx, format!("{nid}/{dapp}"), envelope); - println!("{result:?}"); - assert!(result.is_ok()); - let result = result.unwrap(); - let event = get_event(&result, "wasm-CallMessageSent").unwrap(); - println!("{event:?}"); - assert_eq!(&format!("{nid}/{dapp}"), event.get("to").unwrap()); -} - -#[test] -fn test_rollback_reply() { - let mut ctx = setup_test(); - call_set_xcall_host(&mut ctx).unwrap(); - call_register_connection(&mut ctx).unwrap(); - let src = ctx.get_xcall_ibc_connection().to_string(); - let _dapp = ctx.get_dapp().to_string(); - - let nid = "0x3.icon"; - call_configure_connection( - &mut ctx, - "connection-1".to_string(), - nid.to_string(), - "client-1".to_string(), - ) - .unwrap(); - call_ibc_channel_connect(&mut ctx).unwrap(); - call_dapp_add_connection(&mut ctx, src, "somedest".to_string(), nid.to_string()).unwrap(); - let data = "reply-response".as_bytes().to_vec(); - let msg = CSMessageRequest::new( - NetworkAddress::from_str(&format!("{nid}/{MOCK_CONTRACT_TO_ADDR}")).unwrap(), - ctx.get_dapp(), - 1, - MessageType::CallMessageWithRollback, - data.clone(), - vec![ctx.get_xcall_ibc_connection().to_string()], - ); - let request = CSMessage { - message_type: cw_xcall::types::message::CSMessageType::CSMessageRequest, - payload: msg.as_bytes(), - }; - - let msg = Message { - sn: Nullable::new(Some(1_i64)), - fee: 0_u128, - data: request.as_bytes(), - }; - let bytes: Vec = common::rlp::encode(&msg).to_vec(); - - call_ibc_receive_packet(&mut ctx, bytes).unwrap(); - let expected_reply = CSMessageRequest::new( - NetworkAddress::from_str("nid/contract3").unwrap(), - Addr::unchecked(MOCK_CONTRACT_TO_ADDR), - 1, - MessageType::CallMessage, - vec![1, 2, 3], - vec!["somedest".to_string()], - ); - let reply_message = CSMessageResult::new( - expected_reply.sequence_no(), - CallServiceResponseType::CallServiceResponseSuccess, - Some(expected_reply.as_bytes()), - ); - let message: CSMessage = reply_message.into(); - let expected_hex = hex::encode(message.as_bytes()); - - let result = call_execute_call_message(&mut ctx, 1, data); - println!("{result:?}"); - assert!(result.is_ok()); - let result = result.unwrap(); - let event = get_event(&result, "wasm-write_acknowledgement").unwrap(); - println!("{event:?}"); - assert_eq!(&expected_hex, event.get("data").unwrap()); -} - -fn test_call_message( - ctx: &mut TestContext, - data: Vec, - msg_type: MessageType, -) -> Result { - call_set_xcall_host(ctx).unwrap(); - call_register_connection(ctx).unwrap(); - let src = ctx.get_xcall_ibc_connection().to_string(); - let _dapp = ctx.get_dapp().to_string(); - - let nid = "0x3.icon"; - call_configure_connection( - ctx, - "connection-1".to_string(), - nid.to_string(), - "client-1".to_string(), - ) - .unwrap(); - call_ibc_channel_connect(ctx).unwrap(); - call_dapp_add_connection(ctx, src, "somedest".to_string(), nid.to_string()).unwrap(); - let msg = CSMessageRequest::new( - NetworkAddress::from_str(&format!("{nid}/{MOCK_CONTRACT_TO_ADDR}")).unwrap(), - ctx.get_dapp(), - 1, - msg_type, - data.clone(), - vec![ctx.get_xcall_ibc_connection().to_string()], - ); - let request = CSMessage { - message_type: cw_xcall::types::message::CSMessageType::CSMessageRequest, - payload: msg.as_bytes(), - }; - - let msg = Message { - sn: Nullable::new(Some(1_i64)), - fee: 0_u128, - data: request.as_bytes(), - }; - let bytes: Vec = common::rlp::encode(&msg).to_vec(); - - call_ibc_receive_packet(ctx, bytes).unwrap(); - call_execute_call_message(ctx, 1, data) -} - -#[test] -fn test_call_message_failed() { - let mut ctx = setup_test(); - - let data = "rollback".as_bytes().to_vec(); - let resp = test_call_message(&mut ctx, data, MessageType::CallMessage); - assert!(resp.is_ok()); - - let event = get_event(&resp.unwrap(), "wasm-CallExecuted").unwrap(); - let expected_code: u8 = CallServiceResponseType::CallServiceResponseFailure.into(); - assert_eq!(event.get("code").unwrap(), &expected_code.to_string()); -} - -#[test] -fn test_call_message_success() { - let mut ctx = setup_test(); - - let data = "test".as_bytes().to_vec(); - let resp = test_call_message(&mut ctx, data, MessageType::CallMessage); - assert!(resp.is_ok()); - let result = resp.unwrap(); - let event = get_event(&result, "wasm-CallExecuted").unwrap(); - let ack_event = get_event(&result, "wasm-write_acknowledgement"); - assert!(ack_event.is_none()); - - let expected_code: u8 = CallServiceResponseType::CallServiceResponseSuccess.into(); - assert_eq!(event.get("code").unwrap(), &expected_code.to_string()); -} - -#[test] -#[should_panic(expected = "NotFound { kind: \"cw_xcall::types::request::CSMessageRequest\"")] -fn test_call_message_re_execute() { - let mut ctx = setup_test(); - - let data = "rollback".as_bytes().to_vec(); - let resp = test_call_message(&mut ctx, data.clone(), MessageType::CallMessage); - assert!(resp.is_ok()); - // CallRequest should have been removed even though call failed - let _ = call_execute_call_message(&mut ctx, 1, data); -} - -#[test] -fn test_persistent_call_message_success() { - let mut ctx = setup_test(); - - let data = "test".as_bytes().to_vec(); - let resp = test_call_message(&mut ctx, data, MessageType::CallMessagePersisted); - assert!(resp.is_ok()); - - let result = resp.unwrap(); - let event = get_event(&result, "wasm-CallExecuted").unwrap(); - let ack_event = get_event(&result, "wasm-write_acknowledgement"); - assert!(ack_event.is_none()); - - let expected_code: u8 = CallServiceResponseType::CallServiceResponseSuccess.into(); - assert_eq!(event.get("code").unwrap(), &expected_code.to_string()); -} - -#[test] -#[should_panic(expected = "NotFound { kind: \"cw_xcall::types::request::CSMessageRequest\"")] -fn test_persistent_call_message_re_execute() { - let mut ctx = setup_test(); - - let data = "test".as_bytes().to_vec(); - let resp = test_call_message(&mut ctx, data.clone(), MessageType::CallMessagePersisted); - assert!(resp.is_ok()); - - let result = resp.unwrap(); - let event = get_event(&result, "wasm-CallExecuted").unwrap(); - - let expected_code: u8 = CallServiceResponseType::CallServiceResponseSuccess.into(); - assert_eq!(event.get("code").unwrap(), &expected_code.to_string()); - - // removed after a successful execution - let _ = call_execute_call_message(&mut ctx, 1, data); -} - -#[test] -fn test_persistent_call_message_retry() { - let mut ctx = setup_test(); - - let data = "rollback".as_bytes().to_vec(); - let resp = test_call_message(&mut ctx, data.clone(), MessageType::CallMessagePersisted); - assert!(resp.is_err()); - - // can retry - let resp = call_execute_call_message(&mut ctx, 1, data); - assert!(resp.is_err()); -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/Cargo.toml b/contracts/cosmwasm-vm/cw-intents-v1/Cargo.toml similarity index 94% rename from contracts/cosmwasm-vm/cw-mock-dapp/Cargo.toml rename to contracts/cosmwasm-vm/cw-intents-v1/Cargo.toml index e80fcc03..b550a142 100644 --- a/contracts/cosmwasm-vm/cw-mock-dapp/Cargo.toml +++ b/contracts/cosmwasm-vm/cw-intents-v1/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "cw-mock-dapp" +name = "cw-intents-v1" version = "0.1.0" edition = "2021" @@ -36,11 +36,13 @@ schemars = {workspace=true} serde = { workspace=true} thiserror = { workspace=true} common ={ git = "https://github.com/icon-project/IBC-Integration.git",branch="main" } -cw-xcall-lib = { workspace=true } serde-json-wasm = {workspace=true} +hex="*" +cw20="*" +cw20-base="*" [dev-dependencies] cosmwasm = "0.7.2" -cw-multi-test = "0.16.2" +cw-multi-test = "*" getrandom = {version = "0.2", default-features = false, features = ["custom"]} diff --git a/contracts/cosmwasm-vm/cw-intents-v1/src/contract.rs b/contracts/cosmwasm-vm/cw-intents-v1/src/contract.rs new file mode 100644 index 00000000..e3796f76 --- /dev/null +++ b/contracts/cosmwasm-vm/cw-intents-v1/src/contract.rs @@ -0,0 +1,337 @@ +use crate::events::create_swap_order_event; +use common::{ + rlp::{self, Encodable}, + utils::keccak256, +}; +use cosmwasm_std::{Addr, BankMsg, Coin}; +use cw20::Cw20ExecuteMsg; +use events::{ + create_order_cancelled_event, create_order_closed_event, create_order_fill_event, + create_send_message_event, +}; + +use super::*; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:cw-mock-dapp"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +impl<'a> CwIntentV1Service<'a> { + pub fn instantiate( + &self, + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + self.set_nid(deps.storage, msg.nid)?; + self.set_fee_handler(deps.storage, deps.api.addr_validate(&msg.fee_handler)?)?; + self.set_deposit_id(deps.storage, 0)?; + let relayer = deps.api.addr_validate(&msg.relayer)?; + self.set_relayer(deps.storage, relayer)?; + + Ok(Response::new()) + } + + pub fn swap( + &self, + order: SwapOrder, + deps: DepsMut, + env: Env, + info: MessageInfo, + ) -> Result { + let event = create_swap_order_event(&order); + self.set_order(deps.storage, order.id, &order)?; + let mut res = self.receive_payment(deps.as_ref(), env, info, order.amount, order.token)?; + res = res.add_event(event); + Ok(res) + } + + pub fn fill( + &self, + order: SwapOrder, + solver: String, + deps: DepsMut, + env: Env, + info: MessageInfo, + ) -> Result { + let self_nid = self.get_nid(deps.storage)?; + + if order.dst_nid != self_nid { + return Err(ContractError::InvalidDstNId); + } + let order_bytes = order.rlp_bytes(); + let order_hash = keccak256(&order_bytes); + if self.is_order_finished(deps.storage, &order_hash) { + return Err(ContractError::OrderAlreadyComplete); + } + self.set_order_finished(deps.storage, &keccak256(&order.rlp_bytes()), true) + .unwrap(); + let mut response = self.receive_payment( + deps.as_ref(), + env.clone(), + info, + order.to_amount, + order.to_token.clone(), + )?; + + let protocol_fee = self.get_protocol_fee(deps.storage).unwrap_or(0); + let fee = (order.to_amount * protocol_fee as u128) / 10000; + let fee_handler = self.get_fee_handler(deps.storage)?; + + let fee_transfer = self.try_transfer( + deps.as_ref(), + env.contract.address.to_string(), + fee_handler.to_string(), + fee, + &order.to_token, + ); + + let receiver_transfer = self.try_transfer( + deps.as_ref(), + env.contract.address.to_string(), + order.destination_address.clone(), + order.to_amount - fee, + &order.to_token, + ); + + let order_fill = OrderFill { + id: order.id, + order_bytes: order.rlp_bytes().to_vec(), + solver_address: solver, + }; + + let order_fill_event = create_order_fill_event(&order_fill, fee, order.to_amount); + + if order.src_nid == order.dst_nid { + response = self.resolve_fill(deps, env, order.src_nid, order_fill)?; + } else { + let msg = OrderMsg { + msg_type: ORDER_FILL, + message: order_fill.rlp_bytes().to_vec(), + }; + let sn = self.get_next_conn_sn(deps.storage)?; + let event = create_send_message_event(order.src_nid, sn, msg.rlp_bytes().to_vec()); + response = response.add_event(event); + } + + response = response.add_message(receiver_transfer); + if fee > 0 { + response = response.add_message(fee_transfer); + } + response = response.add_event(order_fill_event); + + Ok(response) + } + + pub fn receive_msg( + &self, + deps: DepsMut, + env: Env, + info: MessageInfo, + src_network: String, + conn_sn: u128, + order_msg: OrderMsg, + ) -> Result { + let relayer = self.get_relayer(deps.storage)?; + if info.sender != relayer { + return Err(ContractError::Unauthorized {}); + } + + if self.have_received(deps.storage, (src_network.clone(), conn_sn)) { + return Err(ContractError::MessageAlreadyReceived); + } + self.set_received(deps.storage, (src_network.clone(), conn_sn), true)?; + match order_msg.msg_type { + ORDER_FILL => { + let fill = rlp::decode::(&order_msg.message).map_err(|e| { + ContractError::DecodeError { + error: e.to_string(), + } + })?; + self.resolve_fill(deps, env, src_network, fill) + } + ORDER_CANCEL => { + let cancel = rlp::decode::(&order_msg.message).map_err(|e| { + ContractError::DecodeError { + error: e.to_string(), + } + })?; + self.resolve_cancel(deps, src_network, cancel.order_bytes) + } + _ => Err(ContractError::InvalidMessageType), + } + } + + fn resolve_fill( + &self, + deps: DepsMut, + env: Env, + src_nid: String, + fill: OrderFill, + ) -> Result { + let order = self.get_order(deps.storage, fill.id)?; + if fill.order_bytes != order.rlp_bytes().to_vec() { + return Err(ContractError::InvalidFillOrder); + } + + if order.dst_nid != src_nid { + return Err(ContractError::InvalidFillOrder); + } + let mut response = Response::new(); + + let transfer = self.try_transfer( + deps.as_ref(), + env.contract.address.to_string(), + fill.solver_address, + order.amount, + &order.token, + ); + response = response + .add_message(transfer) + .add_event(create_order_closed_event(fill.id)); + Ok(response) + } + + fn resolve_cancel( + &self, + deps: DepsMut, + src_nid: String, + order_bytes: Vec, + ) -> Result { + let order_hash = keccak256(&order_bytes); + if self.is_order_finished(deps.storage, &order_hash) { + return Err(ContractError::OrderAlreadyComplete); + } + let mut response = Response::new(); + let order: SwapOrder = + rlp::decode(&order_bytes).map_err(|e| ContractError::DecodeError { + error: e.to_string(), + })?; + if order.src_nid != src_nid { + return Err(ContractError::InvalidCancellation); + } + + self.set_order_finished(deps.storage, &order_hash, true)?; + let fill = OrderFill { + id: order.id, + order_bytes, + solver_address: order.creator.clone(), + }; + let msg = OrderMsg { + msg_type: ORDER_CANCEL, + message: fill.rlp_bytes().to_vec(), + }; + let conn_sn = self.get_next_conn_sn(deps.storage)?; + let send_event = + create_send_message_event(order.src_nid.clone(), conn_sn, msg.rlp_bytes().to_vec()); + let cancelled_event = create_order_cancelled_event(&order); + response = response.add_event(cancelled_event); + response = response.add_event(send_event); + + Ok(response) + } + + fn receive_payment( + &self, + deps: Deps, + env: Env, + info: MessageInfo, + amount: u128, + denom: String, + ) -> Result { + let mut response = Response::new(); + if self.is_native(deps, &denom) { + let sum: u128 = info.funds.into_iter().fold(0, |mut a, c| { + if c.denom == denom { + a += Into::::into(c.amount); + } + a + }); + if sum < amount { + return Err(ContractError::InsufficientFunds); + } + } else { + let msg = self.token_transfer( + denom, + info.sender.to_string(), + env.contract.address.to_string(), + amount, + ); + response = response.add_message(msg); + } + + Ok(response) + } + + fn token_transfer( + &self, + token_address: String, + from: String, + to: String, + amount: u128, + ) -> CosmosMsg { + let transfer_msg = Cw20ExecuteMsg::TransferFrom { + owner: from, + recipient: to, + amount: amount.into(), + }; + + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: token_address, + msg: to_json_binary(&transfer_msg).unwrap(), + funds: vec![], + }) + } + + fn try_transfer( + &self, + deps: Deps, + from: String, + to: String, + amount: u128, + denom: &String, + ) -> CosmosMsg { + if self.is_native(deps, denom) { + let msg = BankMsg::Send { + to_address: deps.api.addr_validate(&to).unwrap().to_string(), + amount: vec![Coin { + denom: denom.to_string(), + amount: amount.into(), + }], + }; + CosmosMsg::Bank(msg) + } else { + self.token_transfer(denom.to_string(), from, to, amount) + } + } + + pub fn is_contract(&self, deps: Deps, address: &Addr) -> bool { + deps.querier + .query_wasm_contract_info(address) + .map(|r| true) + .unwrap_or(false) + } + + pub fn is_native(&self, deps: Deps, denom: &String) -> bool { + if let Ok(addr) = deps.api.addr_validate(denom) { + return !self.is_contract(deps, &addr); + } + true + } + + pub fn get_next_deposit_id(&self, storage: &mut dyn Storage) -> StdResult { + let id = self.get_deposit_id(storage); + let new_id = id + 1; + self.set_deposit_id(storage, new_id)?; + Ok(new_id) + } + + pub fn get_next_conn_sn(&self, storage: &mut dyn Storage) -> StdResult { + let id = self.get_conn_sn(storage); + let new_id = id + 1; + self.set_conn_sn(storage, new_id)?; + Ok(new_id) + } +} diff --git a/contracts/cosmwasm-vm/cw-intents-v1/src/errors.rs b/contracts/cosmwasm-vm/cw-intents-v1/src/errors.rs new file mode 100644 index 00000000..8541eb75 --- /dev/null +++ b/contracts/cosmwasm-vm/cw-intents-v1/src/errors.rs @@ -0,0 +1,30 @@ +use super::*; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + #[error("Unauthorized")] + Unauthorized {}, + #[error("DecodeError {error}")] + DecodeError { error: String }, + #[error("RollBackMessageMismatch {sequence}")] + RollBackMismatch { sequence: u64 }, + #[error("InsufficientFunds")] + InsufficientFunds, + #[error("OrderAlreadyComplete")] + OrderAlreadyComplete, + + #[error("PayoutGreaterThanRemaining")] + PayoutGreaterThanRemaining, + #[error("InvalidFillOrder")] + InvalidFillOrder, + #[error("InvalidCancellation")] + InvalidCancellation, + #[error("InvalidMessageType")] + InvalidMessageType, + #[error("MessageAlreadyReceived")] + MessageAlreadyReceived, + #[error("InvalidDstNId")] + InvalidDstNId, +} diff --git a/contracts/cosmwasm-vm/cw-intents-v1/src/events.rs b/contracts/cosmwasm-vm/cw-intents-v1/src/events.rs new file mode 100644 index 00000000..7a6458fb --- /dev/null +++ b/contracts/cosmwasm-vm/cw-intents-v1/src/events.rs @@ -0,0 +1,46 @@ +use cosmwasm_std::Event; + +use crate::{OrderFill, SwapOrder}; +use common::rlp::Encodable; + +pub fn create_swap_order_event(order: &SwapOrder) -> Event { + Event::new("SwapOrder") + .add_attribute("id", order.id.to_string()) + .add_attribute("amount", order.amount.to_string()) + .add_attribute("creator", order.creator.to_string()) + .add_attribute("data", hex::encode(&order.data)) + .add_attribute("destination_address", order.destination_address.to_string()) + .add_attribute("dst_nid", order.dst_nid.to_string()) + .add_attribute("emitter", order.emitter.to_string()) + .add_attribute("to_amount", order.to_amount.to_string()) + .add_attribute("src_nid", order.src_nid.to_string()) + .add_attribute("to_token", order.to_token.to_string()) + .add_attribute("token", order.token.to_string()) +} + +pub fn create_order_fill_event(fill: &OrderFill, fee: u128, to_amount: u128) -> Event { + Event::new("OrderFill") + .add_attribute("id", fill.id.to_string()) + .add_attribute("solver_address", fill.solver_address.to_string()) + .add_attribute("order_bytes", hex::encode(&fill.order_bytes)) + .add_attribute("fee", fee.to_string()) + .add_attribute("to_amount", to_amount.to_string()) +} + +pub fn create_send_message_event(nid: String, conn_sn: u128, msg: Vec) -> Event { + Event::new("SendMessage") + .add_attribute("sn", conn_sn.to_string()) + .add_attribute("to", nid.to_string()) + .add_attribute("msg", hex::encode(msg)) +} + +pub fn create_order_closed_event(id: u128) -> Event { + Event::new("OrderClosed").add_attribute("id", id.to_string()) +} + +pub fn create_order_cancelled_event(order: &SwapOrder) -> Event { + Event::new("OrderCancelled") + .add_attribute("id", order.id.to_string()) + .add_attribute("src_nid", order.src_nid.to_string()) + .add_attribute("order", hex::encode(order.rlp_bytes())) +} diff --git a/contracts/cosmwasm-vm/cw-intents-v1/src/lib.rs b/contracts/cosmwasm-vm/cw-intents-v1/src/lib.rs new file mode 100644 index 00000000..2f1492e6 --- /dev/null +++ b/contracts/cosmwasm-vm/cw-intents-v1/src/lib.rs @@ -0,0 +1,125 @@ +pub mod contract; +pub mod errors; +pub mod events; +pub mod msg; +pub mod state; +pub mod types; + +use common::rlp; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{ + entry_point, to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, + Response, StdError, StdResult, Storage, WasmMsg, +}; + +use cw2::set_contract_version; +use cw_storage_plus::{Item, Map}; +pub use errors::*; +use msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use state::CwIntentV1Service; +use thiserror::Error; +pub use types::*; + +#[entry_point] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let call_service = CwIntentV1Service::default(); + + call_service.instantiate(deps, env, info, msg) +} + +#[entry_point] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let call_service = CwIntentV1Service::default(); + match msg { + ExecuteMsg::Swap { + dst_nid, + token, + amount, + to_token, + destination_address, + min_receive, + data, + } => { + let id = call_service.get_next_deposit_id(deps.storage)?; + let src_nid = call_service.get_nid(deps.storage)?; + let order = SwapOrder::new( + id, + env.contract.address.to_string(), + src_nid, + dst_nid, + info.sender.to_string(), + destination_address, + token, + amount, + to_token, + min_receive, + data, + ); + call_service.swap(order, deps, env, info) + } + ExecuteMsg::Fill { + id, + emitter, + src_nid, + dst_nid, + creator, + destination_address, + token, + amount, + to_token, + to_amount, + data, + solver_address, + } => { + let order = SwapOrder { + id, + emitter, + src_nid, + dst_nid, + creator, + destination_address, + token, + amount, + to_token, + to_amount, + data, + }; + call_service.fill(order, solver_address, deps, env, info) + } + ExecuteMsg::RecvMessage { + src_network, + conn_sn, + msg, + } => { + let order_msg = + rlp::decode::(&msg).map_err(|e| ContractError::DecodeError { + error: e.to_string(), + })?; + call_service.receive_msg(deps, env, info, src_network, conn_sn, order_msg) + } + } +} + +#[entry_point] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + let call_service = CwIntentV1Service::default(); + match msg { + QueryMsg::GetOrder { id } => { + to_json_binary(&call_service.get_order(deps.storage, id).unwrap()) + } + QueryMsg::GetDepositId {} => to_json_binary(&call_service.get_deposit_id(deps.storage)), + QueryMsg::GetFeeHandler {} => { + to_json_binary(&call_service.get_fee_handler(deps.storage).unwrap()) + } + } +} diff --git a/contracts/cosmwasm-vm/cw-intents-v1/src/msg.rs b/contracts/cosmwasm-vm/cw-intents-v1/src/msg.rs new file mode 100644 index 00000000..7dd0afb2 --- /dev/null +++ b/contracts/cosmwasm-vm/cw-intents-v1/src/msg.rs @@ -0,0 +1,56 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; + +#[cw_serde] +pub struct InstantiateMsg { + pub fee_handler: String, + pub nid: String, + pub fee: u8, + pub relayer: String, +} + +#[cw_serde] +pub enum ExecuteMsg { + Swap { + dst_nid: String, + token: String, + amount: u128, + to_token: String, + destination_address: String, + min_receive: u128, + data: Vec, + }, + Fill { + id: u128, + emitter: String, + src_nid: String, + dst_nid: String, + creator: String, + destination_address: String, + token: String, + amount: u128, + to_token: String, + to_amount: u128, + data: Vec, + solver_address: String, + }, + RecvMessage { + src_network: String, + conn_sn: u128, + msg: Vec, + }, +} + +#[cw_serde] +#[derive(QueryResponses)] +/// This is a Rust enum representing different types of queries that can be made to the contract. Each +/// variant of the enum corresponds to a specific query and has a return type specified using the +/// `#[returns]` attribute. +pub enum QueryMsg { + #[returns(u64)] + GetOrder { id: u128 }, + + #[returns(u64)] + GetDepositId {}, + #[returns(String)] + GetFeeHandler {}, +} diff --git a/contracts/cosmwasm-vm/cw-intents-v1/src/state.rs b/contracts/cosmwasm-vm/cw-intents-v1/src/state.rs new file mode 100644 index 00000000..a3bd2475 --- /dev/null +++ b/contracts/cosmwasm-vm/cw-intents-v1/src/state.rs @@ -0,0 +1,133 @@ +use cosmwasm_std::Addr; + +use crate::types::StorageKey; + +use super::*; + +pub struct CwIntentV1Service<'a> { + deposit_id: Item<'a, u128>, + nid: Item<'a, String>, + protocol_fee: Item<'a, u8>, + fee_handler: Item<'a, Addr>, + orders: Map<'a, u128, SwapOrder>, + finished_orders: Map<'a, Vec, bool>, + conn_sn: Item<'a, u128>, + receipts: Map<'a, (String, u128), bool>, + relayer: Item<'a, Addr>, +} + +impl<'a> Default for CwIntentV1Service<'a> { + fn default() -> Self { + Self::new() + } +} + +impl<'a> CwIntentV1Service<'a> { + pub fn new() -> Self { + Self { + deposit_id: Item::new(StorageKey::DepositId.as_str()), + nid: Item::new(StorageKey::Nid.as_str()), + protocol_fee: Item::new(StorageKey::ProtocolFee.as_str()), + fee_handler: Item::new(StorageKey::FeeHandler.as_str()), + orders: Map::new(StorageKey::Orders.as_str()), + finished_orders: Map::new(StorageKey::FinishedOrders.as_str()), + conn_sn: Item::new(StorageKey::ConnectionSN.as_str()), + receipts: Map::new(StorageKey::Receipts.as_str()), + relayer: Item::new(StorageKey::Relayer.as_str()), + } + } + + pub fn get_deposit_id(&self, storage: &dyn Storage) -> u128 { + self.deposit_id.load(storage).unwrap_or(0) + } + + pub fn get_relayer(&self, storage: &dyn Storage) -> StdResult { + self.relayer.load(storage) + } + + pub fn get_nid(&self, storage: &dyn Storage) -> StdResult { + self.nid.load(storage) + } + + pub fn get_protocol_fee(&self, storage: &dyn Storage) -> StdResult { + self.protocol_fee.load(storage) + } + + pub fn get_fee_handler(&self, storage: &dyn Storage) -> StdResult { + self.fee_handler.load(storage) + } + + pub fn get_order(&self, storage: &dyn Storage, key: u128) -> StdResult { + self.orders.load(storage, key) + } + + pub fn get_conn_sn(&self, storage: &dyn Storage) -> u128 { + self.conn_sn.load(storage).unwrap_or(0) + } + + pub fn is_order_finished(&self, storage: &dyn Storage, key: &[u8]) -> bool { + self.finished_orders + .load(storage, key.to_vec()) + .unwrap_or(false) + } + + pub fn have_received(&self, storage: &dyn Storage, key: (String, u128)) -> bool { + self.receipts.load(storage, key).unwrap_or(false) + } + + // Setters + pub fn set_deposit_id(&self, storage: &mut dyn Storage, value: u128) -> StdResult<()> { + self.deposit_id.save(storage, &value) + } + + pub fn set_relayer(&self, storage: &mut dyn Storage, value: Addr) -> StdResult<()> { + self.relayer.save(storage, &value) + } + + pub fn set_conn_sn(&self, storage: &mut dyn Storage, value: u128) -> StdResult<()> { + self.conn_sn.save(storage, &value) + } + + pub fn set_nid(&self, storage: &mut dyn Storage, value: String) -> StdResult<()> { + self.nid.save(storage, &value) + } + + pub fn set_protocol_fee(&self, storage: &mut dyn Storage, value: u8) -> StdResult<()> { + self.protocol_fee.save(storage, &value) + } + + pub fn set_fee_handler(&self, storage: &mut dyn Storage, value: Addr) -> StdResult<()> { + self.fee_handler.save(storage, &value) + } + + pub fn set_order( + &self, + storage: &mut dyn Storage, + key: u128, + value: &SwapOrder, + ) -> StdResult<()> { + self.orders.save(storage, key, value) + } + + pub fn remove_order(&self, storage: &mut dyn Storage, key: u128) { + self.orders.remove(storage, key) + } + + pub fn set_order_finished( + &self, + storage: &mut dyn Storage, + key: &[u8], + value: bool, + ) -> StdResult<()> { + self.finished_orders.save(storage, key.to_vec(), &value) + } + + pub fn set_received( + &self, + storage: &mut dyn Storage, + key: (String, u128), + val: bool, + ) -> StdResult<()> { + self.receipts.save(storage, key, &val) + } +} diff --git a/contracts/cosmwasm-vm/cw-intents-v1/src/types.rs b/contracts/cosmwasm-vm/cw-intents-v1/src/types.rs new file mode 100644 index 00000000..dfde0d39 --- /dev/null +++ b/contracts/cosmwasm-vm/cw-intents-v1/src/types.rs @@ -0,0 +1,276 @@ +use super::*; +use common::rlp::{self, Decodable, DecoderError, Encodable, RlpStream}; + +pub const ORDER_FILL: u8 = 1; +pub const ORDER_CANCEL: u8 = 2; + +#[cw_serde] +pub enum StorageKey { + DepositId, + Nid, + ProtocolFee, + FeeHandler, + Orders, + PendingOrderAmount, + PendingFills, + FinishedOrders, + ConnectionSN, + Receipts, + Relayer, +} + +impl StorageKey { + pub fn as_str(&self) -> &'static str { + match self { + StorageKey::DepositId => "deposit_id", + StorageKey::Nid => "nid", + StorageKey::ProtocolFee => "protocol_fee", + StorageKey::FeeHandler => "fee_handler", + StorageKey::Orders => "orders", + StorageKey::PendingOrderAmount => "pending_order_amount", + StorageKey::PendingFills => "pending_fills", + StorageKey::FinishedOrders => "finished_orders", + StorageKey::ConnectionSN => "conn_sn", + StorageKey::Receipts => "receipts", + StorageKey::Relayer => "relayer", + } + } +} + +#[cw_serde] +pub struct SwapOrder { + pub id: u128, + pub emitter: String, + pub src_nid: String, + pub dst_nid: String, + pub creator: String, + pub destination_address: String, + pub token: String, + pub amount: u128, + pub to_token: String, + pub to_amount: u128, + pub data: Vec, +} + +impl SwapOrder { + pub fn new( + id: u128, + emitter: String, + src_nid: String, + dst_nid: String, + creator: String, + destination_address: String, + token: String, + amount: u128, + to_token: String, + to_amount: u128, + data: Vec, + ) -> Self { + Self { + id, + emitter, + src_nid, + dst_nid, + creator, + destination_address, + token, + amount, + to_token, + to_amount, + data, + } + } +} + +impl Encodable for SwapOrder { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(11); + s.append(&self.id); + s.append(&self.emitter); + s.append(&self.src_nid); + s.append(&self.dst_nid); + s.append(&self.creator); + s.append(&self.destination_address); + s.append(&self.token); + s.append(&self.amount); + s.append(&self.to_token); + s.append(&self.to_amount); + s.append(&self.data); + } +} + +impl Decodable for SwapOrder { + fn decode(rlp: &rlp::Rlp) -> Result { + Ok(SwapOrder { + id: rlp.val_at(0)?, + emitter: rlp.val_at(1)?, + src_nid: rlp.val_at(2)?, + dst_nid: rlp.val_at(3)?, + creator: rlp.val_at(4)?, + destination_address: rlp.val_at(5)?, + token: rlp.val_at(6)?, + amount: rlp.val_at(7)?, + to_token: rlp.val_at(8)?, + to_amount: rlp.val_at(9)?, + data: rlp.val_at(10)?, + }) + } +} + +pub struct OrderMsg { + pub msg_type: u8, + pub message: Vec, +} + +impl Encodable for OrderMsg { + fn rlp_append(&self, stream: &mut RlpStream) { + stream.begin_list(2); + stream.append(&Into::::into(self.msg_type)); + stream.append(&self.message); + } +} + +impl Decodable for OrderMsg { + fn decode(rlp: &rlp::Rlp) -> Result { + let msg_type: u8 = rlp.val_at(0)?; + let message: Vec = rlp.val_at(1)?; + Ok(OrderMsg { msg_type, message }) + } +} + +pub struct OrderFill { + pub id: u128, + pub order_bytes: Vec, + pub solver_address: String, +} + +impl Encodable for OrderFill { + fn rlp_append(&self, stream: &mut RlpStream) { + stream.begin_list(3); + stream.append(&self.id); + stream.append(&self.order_bytes); + stream.append(&self.solver_address); + } +} + +impl Decodable for OrderFill { + fn decode(rlp: &rlp::Rlp) -> Result { + Ok(OrderFill { + id: rlp.val_at(0)?, + order_bytes: rlp.val_at(1)?, + solver_address: rlp.val_at(2)?, + }) + } +} + +pub struct OrderCancel { + pub order_bytes: Vec, +} + +impl Encodable for OrderCancel { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(1); + s.append(&self.order_bytes); + } +} + +impl Decodable for OrderCancel { + fn decode(rlp: &rlp::Rlp) -> Result { + Ok(OrderCancel { + order_bytes: rlp.val_at(0)?, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_order_msg_encoding_fill() { + let msg = OrderMsg { + msg_type: ORDER_FILL, + message: hex::decode("6c449988e2f33302803c93f8287dc1d8cb33848a").unwrap(), + }; + assert!( + msg.rlp_bytes() + == hex::decode("d601946c449988e2f33302803c93f8287dc1d8cb33848a").unwrap() + ) + } + + #[test] + fn test_order_msg_encoding_cancel() { + let msg = OrderMsg { + msg_type: ORDER_CANCEL, + message: hex::decode("6c449988e2f33302803c93f8287dc1d8cb33848a").unwrap(), + }; + assert!( + msg.rlp_bytes() + == hex::decode("d602946c449988e2f33302803c93f8287dc1d8cb33848a").unwrap() + ) + } + + #[test] + fn test_order_fill_encoding() { + let fill = OrderFill { + id: 1, + order_bytes: hex::decode("6c449988e2f33302803c93f8287dc1d8cb33848a").unwrap(), + solver_address: "0xcb0a6bbccfccde6be9f10ae781b9d9b00d6e63".to_string(), + }; + assert!(fill.rlp_bytes()==hex::decode("f83f01946c449988e2f33302803c93f8287dc1d8cb33848aa830786362306136626263636663636465366265396631306165373831623964396230306436653633").unwrap()); + } + + #[test] + fn test_order_fill_encoding2() { + let fill = OrderFill { + id: 2, + order_bytes: hex::decode("cb0a6bbccfccde6be9f10ae781b9d9b00d6e63").unwrap(), + solver_address: "0x6c449988e2f33302803c93f8287dc1d8cb33848a".to_string(), + }; + assert!(fill.rlp_bytes()==hex::decode("f8400293cb0a6bbccfccde6be9f10ae781b9d9b00d6e63aa307836633434393938386532663333333032383033633933663832383764633164386362333338343861").unwrap()); + } + + #[test] + fn test_order_cancel_encoding() { + let cancel = OrderCancel { + order_bytes: hex::decode("6c449988e2f33302803c93f8287dc1d8cb33848a").unwrap(), + }; + assert!( + cancel.rlp_bytes() + == hex::decode("d5946c449988e2f33302803c93f8287dc1d8cb33848a").unwrap() + ); + } + + #[test] + fn test_swap_order_encoding() { + let order = SwapOrder { + id: 1, + emitter: "0xbe6452d4d6c61cee97d3".to_string(), + src_nid: "Ethereum".to_string(), + dst_nid: "Polygon".to_string(), + creator: "0x3e36eddd65e239222e7e67".to_string(), + destination_address: "0xd2c6218b875457a41b6fb7964e".to_string(), + token: "0x14355340e857912188b7f202d550222487".to_string(), + amount: 1000, + to_token: "0x91a4728b517484f0f610de7b".to_string(), + to_amount: 900, + data: vec![], + }; + assert!(order.rlp_bytes()==hex::decode("f8a601963078626536343532643464366336316365653937643388457468657265756d87506f6c79676f6e983078336533366564646436356532333932323265376536379c30786432633632313862383735343537613431623666623739363465a43078313433353533343065383537393132313838623766323032643535303232323438378203e89a307839316134373238623531373438346630663631306465376282038480").unwrap()); + + let order = SwapOrder { + id: 1, + emitter: "0xbe6452d4d6c61cee97d3".to_string(), + src_nid: "Ethereum".to_string(), + dst_nid: "Polygon".to_string(), + creator: "0x3e36eddd65e239222e7e67".to_string(), + destination_address: "0xd2c6218b875457a41b6fb7964e".to_string(), + token: "0x14355340e857912188b7f202d550222487".to_string(), + amount: 100000 * 10000000000000000000000, + to_token: "0x91a4728b517484f0f610de7b".to_string(), + to_amount: 900 * 10000000, + data: hex::decode("6c449988e2f33302803c93f8287dc1d8cb33848a").unwrap(), + }; + assert!(order.rlp_bytes()==hex::decode("f8c701963078626536343532643464366336316365653937643388457468657265756d87506f6c79676f6e983078336533366564646436356532333932323265376536379c30786432633632313862383735343537613431623666623739363465a43078313433353533343065383537393132313838623766323032643535303232323438378c033b2e3c9fd0803ce80000009a3078393161343732386235313734383466306636313064653762850218711a00946c449988e2f33302803c93f8287dc1d8cb33848a").unwrap()); + } +} diff --git a/contracts/cosmwasm-vm/cw-centralized-connection/tests/setup.rs b/contracts/cosmwasm-vm/cw-intents-v1/tests/setup.rs similarity index 100% rename from contracts/cosmwasm-vm/cw-centralized-connection/tests/setup.rs rename to contracts/cosmwasm-vm/cw-intents-v1/tests/setup.rs diff --git a/contracts/cosmwasm-vm/cw-intents-v1/tests/test_contract.rs b/contracts/cosmwasm-vm/cw-intents-v1/tests/test_contract.rs new file mode 100644 index 00000000..0431fe33 --- /dev/null +++ b/contracts/cosmwasm-vm/cw-intents-v1/tests/test_contract.rs @@ -0,0 +1,528 @@ +use common::rlp::Encodable; +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info}, + Addr, Coin, Uint128, +}; +use cw_intents_v1::{ + execute, instantiate, + msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, + query, + state::CwIntentV1Service, + types::{OrderFill, OrderMsg, SwapOrder}, + OrderCancel, +}; +use cw_multi_test::{App, ContractWrapper, Executor}; + +const MOCK_CONTRACT_ADDR: &str = "contract"; +const USER1: &str = "user1"; +const USER2: &str = "user2"; +const FEE_HANDLER: &str = "fee_handler"; +const NATIVE_DENOM: &str = "uatom"; +const CW20_TOKEN: &str = "cw20_token"; + +fn mock_app() -> App { + App::default() +} + +fn store_code(app: &mut App) -> u64 { + let contract = ContractWrapper::new(execute, instantiate, query); + app.store_code(Box::new(contract)) +} + +fn instantiate_contract(app: &mut App, code_id: u64, sender: &str) -> Addr { + app.instantiate_contract( + code_id, + Addr::unchecked(sender), + &InstantiateMsg { + nid: "src-nid".to_string(), + fee_handler: FEE_HANDLER.to_string(), + fee: 1, + relayer: sender.to_string(), + }, + &[], + "CwIntentV1", + None, + ) + .unwrap() +} + +#[test] +fn proper_initialization() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + + // Query the deposit ID + let deposit_id: u128 = app + .wrap() + .query_wasm_smart(contract_addr, &QueryMsg::GetDepositId {}) + .unwrap(); + assert_eq!(deposit_id, 0); +} + +fn fund_account(app: &mut App, account: String, amount: u128, denom: String) { + app.sudo(cw_multi_test::SudoMsg::Bank( + cw_multi_test::BankSudo::Mint { + to_address: account, + amount: vec![Coin { + denom, + amount: Uint128::new(amount), + }], + }, + )) + .unwrap(); +} + +fn to_swap_msg(order: &SwapOrder) -> ExecuteMsg { + ExecuteMsg::Swap { + dst_nid: order.dst_nid.clone(), + token: order.token.clone(), + amount: order.amount, + to_token: order.to_token.clone(), + destination_address: order.destination_address.clone(), + min_receive: order.to_amount, + data: order.data.clone(), + } +} + +#[test] +fn test_swap_native_token() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + + // Fund USER1 with native tokens + fund_account(&mut app, USER1.to_string(), 1000, NATIVE_DENOM.to_string()); + + // Execute swap + let swap_msg = ExecuteMsg::Swap { + dst_nid: "dst-nid".to_string(), + token: NATIVE_DENOM.to_string(), + amount: 100, + to_token: "to_token".to_string(), + destination_address: USER2.to_string(), + min_receive: 90, + data: hex::decode("deadbeef").unwrap(), + }; + + let res = app.execute_contract( + Addr::unchecked(USER1), + contract_addr.clone(), + &swap_msg, + &[Coin { + denom: NATIVE_DENOM.to_string(), + amount: Uint128::new(100), + }], + ); + println!("{:?}", res); + let response = res.unwrap(); + + // Check if the swap event is emitted + assert!(response.events.iter().any( + |e| e.ty == "wasm-SwapOrder" && e.attributes.iter().any(|attr| attr.key == "to_token") + )); + + // Query the deposit ID (should be incremented) + let deposit_id: u128 = app + .wrap() + .query_wasm_smart(contract_addr, &QueryMsg::GetDepositId {}) + .unwrap(); + assert_eq!(deposit_id, 1); +} + +fn init_cw20_contract(app: &mut App, owner: String, denom: String) -> Addr { + let cw20_code_id = app.store_code(Box::new(ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ))); + + app.instantiate_contract( + cw20_code_id, + Addr::unchecked(owner.clone()), + &cw20_base::msg::InstantiateMsg { + name: "Test Token".to_string(), + symbol: denom, + decimals: 6, + initial_balances: vec![cw20::Cw20Coin { + address: owner.to_string(), + amount: Uint128::new(1000), + }], + mint: None, + marketing: None, + }, + &[], + "Test Token", + None, + ) + .unwrap() +} +#[test] +fn test_swap_cw20_token() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + + let cw20_addr = init_cw20_contract(&mut app, USER1.to_string(), "test".to_owned()); + + // Approve the contract to spend USER1's tokens + app.execute_contract( + Addr::unchecked(USER1), + cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::IncreaseAllowance { + spender: contract_addr.to_string(), + amount: Uint128::new(100), + expires: None, + }, + &[], + ) + .unwrap(); + + // Execute swap + let swap_msg = ExecuteMsg::Swap { + dst_nid: "dst-nid".to_string(), + token: cw20_addr.to_string(), + amount: 100, + to_token: "to_token".to_string(), + destination_address: USER2.to_string(), + min_receive: 90, + data: hex::decode("deadbeef").unwrap(), + }; + + let res = app + .execute_contract( + Addr::unchecked(USER1), + contract_addr.clone(), + &swap_msg, + &[], + ) + .unwrap(); + + // Check if the swap event is emitted + assert!(res + .events + .iter() + .any(|e| e.ty == "wasm-SwapOrder" && e.attributes.iter().any(|attr| attr.key == "amount"))); + + // Query the deposit ID (should be incremented) + let deposit_id: u128 = app + .wrap() + .query_wasm_smart(contract_addr, &QueryMsg::GetDepositId {}) + .unwrap(); + assert_eq!(deposit_id, 1); +} + +#[test] +fn test_fill_order() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + fund_account(&mut app, USER2.to_string(), 200, "to_token".to_string()); + // Fill the order + let fill_msg = ExecuteMsg::Fill { + id: 1, + emitter: contract_addr.to_string(), + src_nid: "dst-nid".to_string(), + dst_nid: "src-nid".to_string(), + creator: USER1.to_string(), + destination_address: USER2.to_string(), + token: NATIVE_DENOM.to_string(), + amount: 100, + to_token: "to_token".to_string(), + to_amount: 90, + data: hex::decode("deadbeef").unwrap(), + solver_address: USER2.to_string(), + }; + + let res = app.execute_contract( + Addr::unchecked(USER2), + contract_addr.clone(), + &fill_msg, + &[Coin { + denom: "to_token".to_string(), + amount: Uint128::new(100), + }], + ); + assert!(res.is_ok()); +} + +#[test] +fn test_receive_msg() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + + let order = SwapOrder { + id: 1, + emitter: contract_addr.to_string(), + src_nid: "src-nid".to_string(), + dst_nid: "src-nid".to_string(), + creator: USER1.to_string(), + destination_address: USER2.to_string(), + token: NATIVE_DENOM.to_string(), + amount: 100, + to_token: "to_token".to_string(), + to_amount: 10, + data: hex::decode("deadbeef").unwrap(), + }; + fund_account(&mut app, USER1.to_string(), 200, NATIVE_DENOM.to_string()); + fund_account( + &mut app, + contract_addr.to_string(), + 200, + "to_token".to_string(), + ); + let swap_msg = to_swap_msg(&order); + + app.execute_contract( + Addr::unchecked(USER1), + contract_addr.clone(), + &swap_msg, + &[Coin { + denom: NATIVE_DENOM.to_string(), + amount: Uint128::new(100), + }], + ) + .unwrap(); + + // Create a mock OrderFill + let order_fill = OrderFill { + id: 1, + order_bytes: order.rlp_bytes().to_vec(), + solver_address: USER2.to_string(), + }; + + // Create a mock OrderMsg + let order_msg = OrderMsg { + msg_type: 1, // ORDER_FILL + message: order_fill.rlp_bytes().to_vec(), + }; + + // Execute RecvMessage + let recv_msg = ExecuteMsg::RecvMessage { + src_network: "src-nid".to_string(), + conn_sn: 1, + msg: order_msg.rlp_bytes().to_vec(), + }; + + let result = app.execute_contract( + Addr::unchecked(USER1), + contract_addr.clone(), + &recv_msg, + &[], + ); + println!("{:?}", &result); + let res = result.unwrap(); + + assert!(res.events.iter().any(|e| e.ty == "transfer" + && e.attributes + .iter() + .any(|attr| attr.key == "recipient" && attr.value == "user2"))); +} + +#[test] +#[should_panic(expected = "InsufficientFunds")] +fn test_insufficient_native_funds() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + + // Test insufficient funds error + let swap_msg = ExecuteMsg::Swap { + dst_nid: "dst-nid".to_string(), + token: NATIVE_DENOM.to_string(), + amount: 1000, + to_token: "to_token".to_string(), + destination_address: USER2.to_string(), + min_receive: 900, + data: vec![], + }; + fund_account(&mut app, USER1.to_string(), 200, NATIVE_DENOM.to_string()); + let err = app + .execute_contract( + Addr::unchecked(USER1), + contract_addr.clone(), + &swap_msg, + &[Coin { + denom: NATIVE_DENOM.to_string(), + amount: Uint128::new(100), + }], + ) + .unwrap(); +} + +#[test] +#[should_panic(expected = "InvalidMessageType")] +fn test_invalid_message_type_panics() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + + // Test invalid message type error + let invalid_order_msg = OrderMsg { + msg_type: 5, // Invalid message type + message: vec![], + }; + + let recv_msg = ExecuteMsg::RecvMessage { + src_network: "src-nid".to_string(), + conn_sn: 1, + msg: invalid_order_msg.rlp_bytes().to_vec(), + }; + + let err = app + .execute_contract( + Addr::unchecked(USER1), + contract_addr.clone(), + &recv_msg, + &[], + ) + .unwrap(); +} + +#[test] +#[should_panic(expected = "OrderAlreadyComplete")] +fn test_fill_already_finished_order() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + + fund_account(&mut app, USER2.to_string(), 200, "to_token".to_string()); + + let fill_msg = ExecuteMsg::Fill { + id: 1, + emitter: contract_addr.to_string(), + src_nid: "test-nid".to_string(), + dst_nid: "src-nid".to_string(), + creator: USER1.to_string(), + destination_address: USER2.to_string(), + token: NATIVE_DENOM.to_string(), + amount: 100, + to_token: "to_token".to_string(), + to_amount: 90, + data: hex::decode("deadbeef").unwrap(), + solver_address: USER2.to_string(), + }; + + app.execute_contract( + Addr::unchecked(USER2), + contract_addr.clone(), + &fill_msg, + &[Coin { + denom: "to_token".to_string(), + amount: Uint128::new(90), + }], + ) + .unwrap(); + + // Try to fill the same order again + let err = app + .execute_contract( + Addr::unchecked(USER2), + contract_addr.clone(), + &fill_msg, + &[Coin { + denom: "to_token".to_string(), + amount: Uint128::new(90), + }], + ) + .unwrap(); +} + +#[test] +#[should_panic(expected = "OrderAlreadyComplete")] +fn test_cancel_already_finished_order() { + let mut app = mock_app(); + let code_id = store_code(&mut app); + let contract_addr = instantiate_contract(&mut app, code_id, USER1); + + fund_account(&mut app, USER2.to_string(), 100, "to_token".to_string()); + let fill_msg = ExecuteMsg::Fill { + id: 1, + emitter: contract_addr.to_string(), + src_nid: "dst-nid".to_string(), + dst_nid: "src-nid".to_string(), + creator: USER1.to_string(), + destination_address: USER2.to_string(), + token: NATIVE_DENOM.to_string(), + amount: 100, + to_token: "to_token".to_string(), + to_amount: 90, + data: hex::decode("deadbeef").unwrap(), + solver_address: USER2.to_string(), + }; + + app.execute_contract( + Addr::unchecked(USER2), + contract_addr.clone(), + &fill_msg, + &[Coin { + denom: "to_token".to_string(), + amount: Uint128::new(90), + }], + ) + .unwrap(); + + // Try to cancel the already finished order + let cancel_order = SwapOrder { + id: 1, + emitter: contract_addr.to_string(), + src_nid: "dst-nid".to_string(), + dst_nid: "src-nid".to_string(), + creator: USER1.to_string(), + destination_address: USER2.to_string(), + token: NATIVE_DENOM.to_string(), + amount: 100, + to_token: "to_token".to_string(), + to_amount: 90, + data: hex::decode("deadbeef").unwrap(), + }; + + let cancel_msg = OrderMsg { + msg_type: 2, // ORDER_CANCEL + message: OrderCancel { + order_bytes: cancel_order.rlp_bytes().to_vec(), + } + .rlp_bytes() + .to_vec(), + }; + + let recv_msg = ExecuteMsg::RecvMessage { + src_network: "dst-nid".to_string(), + conn_sn: 1, + msg: cancel_msg.rlp_bytes().to_vec(), + }; + + let err = app + .execute_contract( + Addr::unchecked(USER1), + contract_addr.clone(), + &recv_msg, + &[], + ) + .unwrap(); +} + +#[test] +fn test_internal_functions() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let info = mock_info(USER1, &[]); + let service = CwIntentV1Service::default(); + + // Test is_contract + assert!(!service.is_contract(deps.as_ref(), &Addr::unchecked(USER1))); + + // Test is_native + assert!(service.is_native(deps.as_ref(), &NATIVE_DENOM.to_string())); + + // Test get_next_deposit_id + service.set_deposit_id(deps.as_mut().storage, 5).unwrap(); + let next_id = service.get_next_deposit_id(deps.as_mut().storage).unwrap(); + assert_eq!(next_id, 6); + + // Test get_next_conn_sn + service.set_conn_sn(deps.as_mut().storage, 10).unwrap(); + let next_sn = service.get_next_conn_sn(deps.as_mut().storage).unwrap(); + assert_eq!(next_sn, 11); +} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/Cargo.toml b/contracts/cosmwasm-vm/cw-mock-dapp-multi/Cargo.toml deleted file mode 100644 index 624e8888..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/Cargo.toml +++ /dev/null @@ -1,46 +0,0 @@ -[package] -name = "cw-mock-dapp-multi" -version = "0.1.0" -edition = "2021" - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -library = [] - -[package.metadata.scripts] -optimize = """docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ - --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.10 -""" - -[dependencies] -cosmwasm-schema = {workspace=true} -cosmwasm-std = { workspace=true, features = ["iterator"] } -cosmwasm-storage = {workspace=true} -cw-storage-plus = {workspace=true} -cw2 = {workspace=true} -schemars = {workspace=true} -serde = { workspace=true} -thiserror = { workspace=true} -common ={ git = "https://github.com/icon-project/IBC-Integration.git",branch="main" } -cw-xcall-lib = { workspace=true} -serde-json-wasm = {workspace=true} - -[dev-dependencies] -cosmwasm = "0.7.2" -cw-multi-test = "0.16.2" -getrandom = {version = "0.2", default-features = false, features = ["custom"]} - diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/contract.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/contract.rs deleted file mode 100644 index e55dad62..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/contract.rs +++ /dev/null @@ -1,199 +0,0 @@ -use std::str::from_utf8; - -use cosmwasm_std::SubMsg; -use cw_xcall_lib::message::call_message_persisted::CallMessagePersisted; -use cw_xcall_lib::message::msg_type::MessageType; -use cw_xcall_lib::message::AnyMessage; -use cw_xcall_lib::message::{ - call_message::CallMessage, call_message_rollback::CallMessageWithRollback, envelope::Envelope, -}; -use cw_xcall_lib::{network_address::NetworkAddress, xcall_msg::ExecuteMsg}; - -use super::*; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw-mock-dapp-multi"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -impl<'a> CwMockService<'a> { - pub fn instantiate( - &self, - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, - ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let sequence = u64::default(); - self.sequence().save(deps.storage, &sequence)?; - self.xcall_address().save(deps.storage, &msg.address)?; - - Ok(Response::new()) - } - - pub fn send_call_message( - &self, - deps: DepsMut, - info: MessageInfo, - to: NetworkAddress, - data: Vec, - rollback: Option>, - ) -> Result { - let _sequence = self.increment_sequence(deps.storage)?; - let address = self - .xcall_address() - .load(deps.storage) - .map_err(|_e| ContractError::ModuleAddressNotFound)?; - - let network_id = to.nid().to_string(); - let connections = self.get_connections(deps.storage, network_id)?; - let (sources, destinations) = - connections - .into_iter() - .fold((Vec::new(), Vec::new()), |mut acc, x| { - acc.0.push(x.src_endpoint); - acc.1.push(x.dest_endpoint); - acc - }); - let msg = ExecuteMsg::SendCallMessage { - to, - data, - sources: Some(sources), - destinations: Some(destinations), - rollback, - }; - let message: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: address, - msg: to_json_binary(&msg).unwrap(), - funds: info.funds, - }); - let submessage = SubMsg { - id: 1, - msg: message, - gas_limit: None, - reply_on: cosmwasm_std::ReplyOn::Never, - }; - - println!("{:?}", submessage); - - Ok(submessage) - } - - pub fn send_new_call_message( - &self, - deps: DepsMut, - info: MessageInfo, - to: NetworkAddress, - data: Vec, - message_type: u64, - rollback: Option>, - ) -> Result { - let _sequence = self.increment_sequence(deps.storage)?; - let address = self - .xcall_address() - .load(deps.storage) - .map_err(|_e| ContractError::ModuleAddressNotFound)?; - - let network_id = to.nid().to_string(); - let connections = self.get_connections(deps.storage, network_id)?; - let (sources, destinations) = - connections - .into_iter() - .fold((Vec::new(), Vec::new()), |mut acc, x| { - acc.0.push(x.src_endpoint); - acc.1.push(x.dest_endpoint); - acc - }); - - let msg = if message_type == MessageType::CallMessagePersisted as u64 { - AnyMessage::CallMessagePersisted(CallMessagePersisted { data }) - } else if message_type == MessageType::CallMessageWithRollback as u64 { - if let Some(rollback) = rollback { - AnyMessage::CallMessageWithRollback(CallMessageWithRollback { data, rollback }) - } else { - return Err(ContractError::InvalidRollbackMessage); - } - } else if message_type == MessageType::CallMessage as u64 { - AnyMessage::CallMessage(CallMessage { data }) - } else { - return Err(ContractError::InvalidMessageType); - }; - let envelope = Envelope::new(msg, sources, destinations); - - let msg = ExecuteMsg::SendCall { envelope, to }; - let message: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: address, - msg: to_json_binary(&msg).unwrap(), - funds: info.funds, - }); - - let submessage = SubMsg { - id: 1, - msg: message, - gas_limit: None, - reply_on: cosmwasm_std::ReplyOn::Never, - }; - - Ok(Response::new() - .add_attribute("Action", "SendNewMessage") - .add_submessage(submessage)) - } - - pub fn send_call( - &self, - deps: DepsMut, - info: MessageInfo, - to: NetworkAddress, - envelope: Envelope, - ) -> Result { - let address = self - .xcall_address() - .load(deps.storage) - .map_err(|_e| ContractError::ModuleAddressNotFound)?; - - let msg = ExecuteMsg::SendCall { to, envelope }; - let message: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: address, - msg: to_json_binary(&msg).unwrap(), - funds: info.funds, - }); - - println!("{:?}", message); - - Ok(Response::new() - .add_attribute("Action", "SendMessage") - .add_message(message)) - } - - pub fn handle_call_message( - &self, - deps: DepsMut, - info: MessageInfo, - from: NetworkAddress, - data: Vec, - _protocols: Vec, - ) -> Result { - if info.sender == from.account() { - Ok(Response::new() - .add_attribute("action", "RollbackDataReceived") - .add_attribute("from", from.to_string())) - } else { - let mut res = Response::new(); - let msg_data = from_utf8(&data).map_err(|e| ContractError::DecodeError { - error: e.to_string(), - })?; - if "rollback" == msg_data { - return Err(ContractError::RevertFromDAPP); - } - if "reply-response" == msg_data { - let submsg = self - .send_call_message(deps, info, from.clone(), vec![1, 2, 3], None) - .unwrap(); - res = res.add_submessage(submsg) - } - Ok(res - .add_attribute("from", from.to_string()) - .add_attribute("data", msg_data)) - } - } -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/errors.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/errors.rs deleted file mode 100644 index a22aa68a..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/errors.rs +++ /dev/null @@ -1,27 +0,0 @@ -use super::*; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - #[error("Unauthorized")] - Unauthorized {}, - #[error("DecodeError {error}")] - DecodeError { error: String }, - #[error("RollBackMessageMismatch {sequence}")] - RollBackMismatch { sequence: u64 }, - #[error("RevertFromDAPP")] - RevertFromDAPP, - #[error("ModuleAddressNotFound")] - ModuleAddressNotFound, - #[error("MisiingRollBack {sequence}")] - MisiingRollBack { sequence: u64 }, - #[error("Connection Not Found {network_id}")] - ConnectionNotFound { network_id: String }, - #[error("Invalid Address {address}")] - InvalidAddress { address: String }, - #[error("Invalid Rollback Message")] - InvalidRollbackMessage, - #[error("Invalid Message Type")] - InvalidMessageType, -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/helper.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/helper.rs deleted file mode 100644 index 9c6d3832..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/helper.rs +++ /dev/null @@ -1,25 +0,0 @@ -use super::*; - -impl<'a> CwMockService<'a> { - pub fn init_sequence( - &self, - store: &mut dyn Storage, - sequence_no: u64, - ) -> Result<(), ContractError> { - match self.sequence().save(store, &sequence_no) { - Ok(_) => Ok(()), - Err(error) => Err(ContractError::Std(error)), - } - } - - pub fn increment_sequence(&self, store: &mut dyn Storage) -> Result { - self.sequence().update(store, |seq| Ok(seq + 1)) - } - - pub fn get_sequence(&self, store: &dyn Storage) -> Result { - match self.sequence().load(store) { - Ok(sequence) => Ok(sequence), - Err(error) => Err(ContractError::Std(error)), - } - } -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/lib.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/lib.rs deleted file mode 100644 index 2258b5d7..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/lib.rs +++ /dev/null @@ -1,89 +0,0 @@ -pub mod contract; -pub mod errors; -pub mod helper; -pub mod msg; -pub mod state; -pub mod types; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - entry_point, to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, - Response, StdError, StdResult, Storage, WasmMsg, -}; - -use cw2::set_contract_version; -use cw_storage_plus::{Item, Map}; -pub use errors::*; -use msg::{ExecuteMsg, QueryMsg}; -use state::{Connection, CwMockService}; -use thiserror::Error; -pub use types::*; - -#[entry_point] -pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - let call_service = CwMockService::default(); - - call_service.instantiate(deps, env, info, msg) -} - -#[entry_point] -pub fn execute( - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let call_service = CwMockService::default(); - match msg { - ExecuteMsg::SendCallMessage { to, data, rollback } => { - let submsg = call_service.send_call_message(deps, info, to, data, rollback)?; - Ok(Response::new() - .add_submessage(submsg) - .add_attribute("Action", "SendMessage")) - } - ExecuteMsg::SendNewCallMessage { - to, - data, - message_type, - rollback, - } => call_service.send_new_call_message(deps, info, to, data, message_type, rollback), - ExecuteMsg::SendMessageAny { to, envelope } => { - call_service.send_call(deps, info, to, envelope) - } - ExecuteMsg::HandleCallMessage { - from, - data, - protocols, - } => call_service.handle_call_message(deps, info, from, data, protocols), - ExecuteMsg::AddConnection { - src_endpoint, - dest_endpoint, - network_id, - } => { - call_service.add_connection( - deps.storage, - network_id, - Connection { - src_endpoint, - dest_endpoint, - }, - )?; - Ok(Response::new().add_attribute("action", "add_connection")) - } - } -} - -#[entry_point] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - let call_service = CwMockService::default(); - match msg { - QueryMsg::GetSequence {} => { - to_json_binary(&call_service.get_sequence(deps.storage).unwrap()) - } - } -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/msg.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/msg.rs deleted file mode 100644 index 2a8d94f6..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/msg.rs +++ /dev/null @@ -1,41 +0,0 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; -use cw_xcall_lib::{message::envelope::Envelope, network_address::NetworkAddress}; - -#[cw_serde] -pub enum ExecuteMsg { - SendCallMessage { - to: NetworkAddress, - data: Vec, - rollback: Option>, - }, - SendMessageAny { - to: NetworkAddress, - envelope: Envelope, - }, - SendNewCallMessage { - to: NetworkAddress, - data: Vec, - message_type: u64, - rollback: Option>, - }, - HandleCallMessage { - from: NetworkAddress, - data: Vec, - protocols: Vec, - }, - AddConnection { - src_endpoint: String, - dest_endpoint: String, - network_id: String, - }, -} - -#[cw_serde] -#[derive(QueryResponses)] -/// This is a Rust enum representing different types of queries that can be made to the contract. Each -/// variant of the enum corresponds to a specific query and has a return type specified using the -/// `#[returns]` attribute. -pub enum QueryMsg { - #[returns(u64)] - GetSequence {}, -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/state.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/state.rs deleted file mode 100644 index d3c8a627..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/state.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::types::StorageKey; - -use super::*; - -#[cw_serde] -pub struct Connection { - pub src_endpoint: String, - pub dest_endpoint: String, -} - -pub struct CwMockService<'a> { - sequence: Item<'a, u64>, - xcall_address: Item<'a, String>, - connections: Map<'a, String, Vec>, -} - -impl<'a> Default for CwMockService<'a> { - fn default() -> Self { - Self::new() - } -} - -impl<'a> CwMockService<'a> { - pub fn new() -> Self { - Self { - sequence: Item::new(StorageKey::SequenceNo.as_str()), - xcall_address: Item::new(StorageKey::Address.as_str()), - connections: Map::new(StorageKey::Connections.as_str()), - } - } - - pub fn sequence(&self) -> &Item<'a, u64> { - &self.sequence - } - - pub fn xcall_address(&self) -> &Item<'a, String> { - &self.xcall_address - } - - pub fn connections(&self) -> &Map<'a, String, Vec> { - &self.connections - } - - pub fn add_connection( - &self, - store: &mut dyn Storage, - network_id: String, - conn: Connection, - ) -> Result<(), ContractError> { - let mut connections = self - .connections - .load(store, network_id.clone()) - .unwrap_or(Vec::::new()); - connections.push(conn); - self.connections - .save(store, network_id, &connections) - .map_err(ContractError::Std) - } - pub fn get_connections( - &self, - store: &dyn Storage, - network_id: String, - ) -> Result, ContractError> { - self.connections - .load(store, network_id.clone()) - .map_err(|_e| ContractError::ConnectionNotFound { network_id }) - } -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/types.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/types.rs deleted file mode 100644 index b20f0a46..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/src/types.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::*; - -#[cw_serde] -pub struct InstantiateMsg { - pub address: String, -} - -#[cw_serde] -pub enum StorageKey { - SequenceNo, - Address, - Request, - RollBack, - Connections, -} - -impl StorageKey { - pub fn as_str(&self) -> &'static str { - match self { - StorageKey::Address => "admin", - StorageKey::Request => "message_request", - StorageKey::SequenceNo => "sequenceno", - StorageKey::RollBack => "rollback", - StorageKey::Connections => "connections", - } - } -} - -#[cw_serde] -pub struct RollbackData { - pub id: u64, - pub rollback: Vec, -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/tests/mock_test.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/tests/mock_test.rs deleted file mode 100644 index 6933dde4..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/tests/mock_test.rs +++ /dev/null @@ -1,173 +0,0 @@ -pub mod setup; -use std::str::FromStr; - -use cosmwasm::serde::to_vec; -use cosmwasm_std::testing::mock_env; -use cw_mock_dapp_multi::{ - state::{Connection, CwMockService}, - types::InstantiateMsg, - RollbackData, -}; -use cw_xcall_lib::network_address::NetworkAddress; -use setup::*; - -#[test] -fn test_initialization() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("dapp", "umlg", 2000); - let env = mock_env(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - - let res = ctx.instantiate(deps.as_mut(), env, info, msg); - println!("{res:?}") -} - -#[test] -fn test_sequence() { - let mut deps = deps(); - let ctx = CwMockService::default(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - ctx.increment_sequence(&mut deps.storage).unwrap(); - let res = ctx.get_sequence(&deps.storage); - - assert!(res.is_ok()); - assert_eq!(res.unwrap(), 1) -} - -#[test] -fn test_send_message() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - ctx.add_connection( - deps.as_mut().storage, - "netid".to_string(), - Connection { - src_endpoint: "somesrc".into(), - dest_endpoint: "somedest".to_owned(), - }, - ) - .unwrap(); - let res = ctx.send_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/xcall").unwrap(), - vec![1, 2, 3, 4], - Some(vec![1, 2, 3, 4, 5]), - ); - - assert!(res.is_ok()); - assert_eq!(res.unwrap().id, 1) -} - -#[test] -#[should_panic(expected = "ModuleAddressNotFound")] -fn test_send_message_fail() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - ctx.send_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/xcall").unwrap(), - vec![1, 2, 3, 4], - Some(vec![1, 2, 3, 4, 5]), - ) - .unwrap(); -} - -#[test] -fn test_handle_message() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - let res = ctx.handle_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/xcall").unwrap(), - "helloError".as_bytes().to_vec(), - vec![], - ); - assert!(res.is_ok()) -} - -#[test] -#[should_panic(expected = "RevertFromDAPP")] -fn test_handle_message_fail_revert() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - ctx.handle_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/xcall").unwrap(), - "rollback".as_bytes().to_vec(), - vec![], - ) - .unwrap(); -} - -#[test] -fn test_handle_message_pass_true() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - - let rollback_data = RollbackData { - id: 1, - rollback: vec![1, 2, 3], - }; - let res = ctx.handle_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/hugobyte").unwrap(), - to_vec(&rollback_data).unwrap(), - vec![], - ); - assert!(res.is_ok()); - println!("{:?}", res); - assert_eq!(res.unwrap().attributes[0].value, "RollbackDataReceived") -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp-multi/tests/setup.rs b/contracts/cosmwasm-vm/cw-mock-dapp-multi/tests/setup.rs deleted file mode 100644 index 42b4cf97..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp-multi/tests/setup.rs +++ /dev/null @@ -1,14 +0,0 @@ -use cosmwasm_std::{ - coins, - testing::{mock_dependencies, mock_info, MockApi, MockQuerier, MockStorage}, - Empty, MessageInfo, OwnedDeps, -}; - -pub fn create_mock_info(creator: &str, denom: &str, amount: u128) -> MessageInfo { - let funds = coins(amount, denom); - mock_info(creator, &funds) -} - -pub fn deps() -> OwnedDeps { - mock_dependencies() -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/src/contract.rs b/contracts/cosmwasm-vm/cw-mock-dapp/src/contract.rs deleted file mode 100644 index 01aaa80a..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/src/contract.rs +++ /dev/null @@ -1,143 +0,0 @@ -use std::str::from_utf8; - -use super::*; -use cw_xcall_lib::message::call_message_persisted::CallMessagePersisted; -use cw_xcall_lib::message::AnyMessage; -use cw_xcall_lib::message::{ - call_message::CallMessage, call_message_rollback::CallMessageWithRollback, envelope::Envelope, -}; -use cw_xcall_lib::{network_address::NetworkAddress, xcall_msg::ExecuteMsg}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw-mock-dapp"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -impl<'a> CwMockService<'a> { - pub fn instantiate( - &self, - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, - ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let sequence = u64::default(); - self.sequence().save(deps.storage, &sequence)?; - self.xcall_address().save(deps.storage, &msg.address)?; - - Ok(Response::new()) - } - - pub fn send_call_message( - &self, - deps: DepsMut, - info: MessageInfo, - to: NetworkAddress, - data: Vec, - rollback: Option>, - ) -> Result { - let _sequence = self.increment_sequence(deps.storage)?; - let address = self - .xcall_address() - .load(deps.storage) - .map_err(|_e| ContractError::ModuleAddressNotFound)?; - - let msg = ExecuteMsg::SendCallMessage { - to, - data, - sources: None, - destinations: None, - rollback, - }; - let message: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: address, - msg: to_json_binary(&msg).unwrap(), - funds: info.funds, - }); - - println!("{:?}", message); - - Ok(Response::new() - .add_attribute("Action", "SendMessage") - .add_message(message)) - } - - pub fn send_new_call_message( - &self, - deps: DepsMut, - info: MessageInfo, - to: NetworkAddress, - data: Vec, - rollback: Option>, - is_persistent: bool, - ) -> Result { - let _sequence = self.increment_sequence(deps.storage)?; - let address = self - .xcall_address() - .load(deps.storage) - .map_err(|_e| ContractError::ModuleAddressNotFound)?; - - let msg = if is_persistent { - AnyMessage::CallMessagePersisted(CallMessagePersisted { data }) - } else if let Some(rollback) = rollback { - AnyMessage::CallMessageWithRollback(CallMessageWithRollback { data, rollback }) - } else { - AnyMessage::CallMessage(CallMessage { data }) - }; - let envelope = Envelope::new(msg, vec![], vec![]); - - let msg = ExecuteMsg::SendCall { envelope, to }; - let message: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: address, - msg: to_json_binary(&msg).unwrap(), - funds: info.funds, - }); - - println!("{:?}", message); - - Ok(Response::new() - .add_attribute("Action", "SendNewMessage") - .add_message(message)) - } - - pub fn handle_call_message( - &self, - deps: DepsMut, - info: MessageInfo, - from: NetworkAddress, - data: Vec, - ) -> Result { - if info.sender == from.account() { - let recieved_rollback = - serde_json_wasm::from_slice::(&data).map_err(|e| { - ContractError::DecodeError { - error: e.to_string(), - } - })?; - let seq = recieved_rollback.id; - let rollback_store = self - .roll_back() - .load(deps.storage, seq) - .map_err(|_e| ContractError::MisiingRollBack { sequence: seq })?; - if rollback_store != recieved_rollback.rollback { - return Err(ContractError::RollBackMismatch { sequence: seq }); - } - self.roll_back().remove(deps.storage, seq); - - Ok(Response::new() - .add_attribute("action", "RollbackDataReceived") - .add_attribute("from", from.to_string()) - .add_attribute("sequence", seq.to_string())) - } else { - let msg_data = from_utf8(&data).map_err(|e| ContractError::DecodeError { - error: e.to_string(), - })?; - if "rollback" == msg_data { - return Err(ContractError::RevertFromDAPP); - } - Ok(Response::new() - .add_attribute("from", from.to_string()) - .add_attribute("data", msg_data)) - } - } -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/src/errors.rs b/contracts/cosmwasm-vm/cw-mock-dapp/src/errors.rs deleted file mode 100644 index c6e4eb97..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/src/errors.rs +++ /dev/null @@ -1,23 +0,0 @@ -use super::*; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - #[error("Unauthorized")] - Unauthorized {}, - #[error("DecodeError {error}")] - DecodeError { error: String }, - #[error("RollBackMessageMismatch {sequence}")] - RollBackMismatch { sequence: u64 }, - #[error("RevertFromDAPP")] - RevertFromDAPP, - #[error("ModuleAddressNotFound")] - ModuleAddressNotFound, - #[error("MisiingRollBack {sequence}")] - MisiingRollBack { sequence: u64 }, - #[error("Connection Not Found {network_id}")] - ConnectionNotFound { network_id: String }, - #[error("Invalid Address {address}")] - InvalidAddress { address: String }, -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/src/helper.rs b/contracts/cosmwasm-vm/cw-mock-dapp/src/helper.rs deleted file mode 100644 index 9c6d3832..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/src/helper.rs +++ /dev/null @@ -1,25 +0,0 @@ -use super::*; - -impl<'a> CwMockService<'a> { - pub fn init_sequence( - &self, - store: &mut dyn Storage, - sequence_no: u64, - ) -> Result<(), ContractError> { - match self.sequence().save(store, &sequence_no) { - Ok(_) => Ok(()), - Err(error) => Err(ContractError::Std(error)), - } - } - - pub fn increment_sequence(&self, store: &mut dyn Storage) -> Result { - self.sequence().update(store, |seq| Ok(seq + 1)) - } - - pub fn get_sequence(&self, store: &dyn Storage) -> Result { - match self.sequence().load(store) { - Ok(sequence) => Ok(sequence), - Err(error) => Err(ContractError::Std(error)), - } - } -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/src/lib.rs b/contracts/cosmwasm-vm/cw-mock-dapp/src/lib.rs deleted file mode 100644 index 6990cd6a..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/src/lib.rs +++ /dev/null @@ -1,113 +0,0 @@ -pub mod contract; -pub mod errors; -pub mod helper; -pub mod msg; -pub mod state; -pub mod types; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - entry_point, to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, - Response, StdError, StdResult, Storage, SubMsg, WasmMsg, -}; - -use cw2::set_contract_version; -use cw_storage_plus::{Item, Map}; -pub use errors::*; -use msg::{ExecuteMsg, QueryMsg}; -use state::CwMockService; -use thiserror::Error; -pub use types::*; - -#[entry_point] -pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - let call_service = CwMockService::default(); - - call_service.instantiate(deps, env, info, msg) -} - -#[entry_point] -pub fn execute( - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let call_service = CwMockService::default(); - match msg { - ExecuteMsg::SendCallMessage { to, data, rollback } => { - call_service.send_call_message(deps, info, to, data, rollback) - } - ExecuteMsg::SendNewCallMessage { - to, - data, - rollback, - is_persistent, - } => call_service.send_new_call_message(deps, info, to, data, rollback, is_persistent), - ExecuteMsg::HandleCallMessage { from, data } => { - call_service.handle_call_message(deps, info, from, data) - } - ExecuteMsg::XCallMessage { data } => Ok(Response::new() - .add_attribute("action", "success execute call") - .set_data(data)), - ExecuteMsg::SuccessCall {} => { - let resukt = call_service.increment_sequence(deps.storage)?; - Ok(Response::new().add_attribute("sequence", resukt.to_string())) - } - ExecuteMsg::FailureCall {} => Err(ContractError::ModuleAddressNotFound), - ExecuteMsg::TestCall { - success_addr, - fail_addr, - } => { - let success = ExecuteMsg::SuccessCall {}; - let fail = ExecuteMsg::FailureCall {}; - let success_wasm = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: success_addr, - msg: to_json_binary(&success).map_err(ContractError::Std)?, - funds: info.funds.clone(), - }); - let fail_wasm = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: fail_addr, - msg: to_json_binary(&fail).map_err(ContractError::Std)?, - funds: info.funds, - }); - let submessages = vec![ - SubMsg { - msg: success_wasm.clone(), - gas_limit: None, - id: 2, - reply_on: cosmwasm_std::ReplyOn::Never, - }, - SubMsg { - msg: fail_wasm, - gas_limit: None, - id: 6, - reply_on: cosmwasm_std::ReplyOn::Never, - }, - SubMsg { - msg: success_wasm, - gas_limit: None, - id: 2, - reply_on: cosmwasm_std::ReplyOn::Never, - }, - ]; - - Ok(Response::new().add_submessages(submessages)) - } - } -} - -#[entry_point] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - let call_service = CwMockService::default(); - match msg { - QueryMsg::GetSequence {} => { - to_json_binary(&call_service.get_sequence(deps.storage).unwrap()) - } - } -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/src/msg.rs b/contracts/cosmwasm-vm/cw-mock-dapp/src/msg.rs deleted file mode 100644 index 8662db3f..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/src/msg.rs +++ /dev/null @@ -1,40 +0,0 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; -use cw_xcall_lib::network_address::NetworkAddress; - -#[cw_serde] -pub enum ExecuteMsg { - SendCallMessage { - to: NetworkAddress, - data: Vec, - rollback: Option>, - }, - SendNewCallMessage { - to: NetworkAddress, - data: Vec, - rollback: Option>, - is_persistent: bool, - }, - HandleCallMessage { - from: NetworkAddress, - data: Vec, - }, - XCallMessage { - data: Vec, - }, - SuccessCall {}, - FailureCall {}, - TestCall { - success_addr: String, - fail_addr: String, - }, -} - -#[cw_serde] -#[derive(QueryResponses)] -/// This is a Rust enum representing different types of queries that can be made to the contract. Each -/// variant of the enum corresponds to a specific query and has a return type specified using the -/// `#[returns]` attribute. -pub enum QueryMsg { - #[returns(u64)] - GetSequence {}, -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/src/state.rs b/contracts/cosmwasm-vm/cw-mock-dapp/src/state.rs deleted file mode 100644 index dc68fa9e..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/src/state.rs +++ /dev/null @@ -1,37 +0,0 @@ -use crate::types::StorageKey; - -use super::*; - -pub struct CwMockService<'a> { - sequence: Item<'a, u64>, - xcall_address: Item<'a, String>, - rollback: Map<'a, u64, Vec>, -} - -impl<'a> Default for CwMockService<'a> { - fn default() -> Self { - Self::new() - } -} - -impl<'a> CwMockService<'a> { - pub fn new() -> Self { - Self { - sequence: Item::new(StorageKey::SequenceNo.as_str()), - xcall_address: Item::new(StorageKey::Address.as_str()), - rollback: Map::new(StorageKey::RollBack.as_str()), - } - } - - pub fn sequence(&self) -> &Item<'a, u64> { - &self.sequence - } - - pub fn xcall_address(&self) -> &Item<'a, String> { - &self.xcall_address - } - - pub fn roll_back(&self) -> &Map<'a, u64, Vec> { - &self.rollback - } -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/src/types.rs b/contracts/cosmwasm-vm/cw-mock-dapp/src/types.rs deleted file mode 100644 index ad1e740b..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/src/types.rs +++ /dev/null @@ -1,31 +0,0 @@ -use super::*; - -#[cw_serde] -pub struct InstantiateMsg { - pub address: String, -} - -#[cw_serde] -pub enum StorageKey { - SequenceNo, - Address, - Request, - RollBack, -} - -impl StorageKey { - pub fn as_str(&self) -> &'static str { - match self { - StorageKey::Address => "admin", - StorageKey::Request => "message_request", - StorageKey::SequenceNo => "sequenceno", - StorageKey::RollBack => "rollback", - } - } -} - -#[cw_serde] -pub struct RollbackData { - pub id: u64, - pub rollback: Vec, -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/tests/mock_test.rs b/contracts/cosmwasm-vm/cw-mock-dapp/tests/mock_test.rs deleted file mode 100644 index 1c4b9681..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/tests/mock_test.rs +++ /dev/null @@ -1,191 +0,0 @@ -pub mod setup; -use std::str::FromStr; - -use cosmwasm::serde::to_vec; -use cosmwasm_std::testing::mock_env; -use cw_mock_dapp::{state::CwMockService, types::InstantiateMsg, RollbackData}; -use cw_xcall_lib::network_address::NetworkAddress; -use setup::*; - -#[test] -fn test_initialization() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("dapp", "umlg", 2000); - let env = mock_env(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - - let res = ctx.instantiate(deps.as_mut(), env, info, msg); - println!("{res:?}") -} - -#[test] -fn test_sequence() { - let mut deps = deps(); - let ctx = CwMockService::default(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - ctx.increment_sequence(&mut deps.storage).unwrap(); - let res = ctx.get_sequence(&deps.storage); - - assert!(res.is_ok()); - assert_eq!(res.unwrap(), 1) -} - -#[test] -fn test_send_message() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - - let res = ctx.send_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/xcall").unwrap(), - vec![1, 2, 3, 4], - Some(vec![1, 2, 3, 4, 5]), - ); - - assert!(res.is_ok()); - assert_eq!(res.unwrap().messages[0].id, 0) -} - -#[test] -#[should_panic(expected = "ModuleAddressNotFound")] -fn test_send_message_fail() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - ctx.send_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/xcall").unwrap(), - vec![1, 2, 3, 4], - Some(vec![1, 2, 3, 4, 5]), - ) - .unwrap(); -} - -#[test] -fn test_handle_message() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - let res = ctx.handle_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/xcall").unwrap(), - "helloError".as_bytes().to_vec(), - ); - assert!(res.is_ok()) -} - -#[test] -#[should_panic(expected = "RevertFromDAPP")] -fn test_handle_message_fail_revert() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - ctx.handle_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/xcall").unwrap(), - "rollback".as_bytes().to_vec(), - ) - .unwrap(); -} - -#[test] -fn test_handle_message_pass_true() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - - ctx.roll_back() - .save(&mut deps.storage, 1, &vec![1, 2, 3]) - .unwrap(); - - let rollback_data = RollbackData { - id: 1, - rollback: vec![1, 2, 3], - }; - let res = ctx.handle_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/hugobyte").unwrap(), - to_vec(&rollback_data).unwrap(), - ); - assert!(res.is_ok()); - println!("{:?}", res); - assert_eq!(res.unwrap().attributes[0].value, "RollbackDataReceived") -} - -#[test] -#[should_panic(expected = "MisiingRollBack")] -fn test_handle_message_fail_true() { - let mut deps = deps(); - let ctx = CwMockService::default(); - let info = create_mock_info("hugobyte", "umlg", 2000); - let env = mock_env(); - - ctx.init_sequence(&mut deps.storage, u64::default()) - .unwrap(); - let msg = InstantiateMsg { - address: "xcall-address".to_string(), - }; - ctx.instantiate(deps.as_mut(), env, info.clone(), msg) - .unwrap(); - - let rollback_data = RollbackData { - id: 1, - rollback: vec![1, 2, 3], - }; - ctx.handle_call_message( - deps.as_mut(), - info, - NetworkAddress::from_str("netid/hugobyte").unwrap(), - to_vec(&rollback_data).unwrap(), - ) - .unwrap(); -} diff --git a/contracts/cosmwasm-vm/cw-mock-dapp/tests/setup.rs b/contracts/cosmwasm-vm/cw-mock-dapp/tests/setup.rs deleted file mode 100644 index 42b4cf97..00000000 --- a/contracts/cosmwasm-vm/cw-mock-dapp/tests/setup.rs +++ /dev/null @@ -1,14 +0,0 @@ -use cosmwasm_std::{ - coins, - testing::{mock_dependencies, mock_info, MockApi, MockQuerier, MockStorage}, - Empty, MessageInfo, OwnedDeps, -}; - -pub fn create_mock_info(creator: &str, denom: &str, amount: u128) -> MessageInfo { - let funds = coins(amount, denom); - mock_info(creator, &funds) -} - -pub fn deps() -> OwnedDeps { - mock_dependencies() -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/.cargo/config b/contracts/cosmwasm-vm/cw-xcall-lib/.cargo/config deleted file mode 100644 index af5698e5..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --lib --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --bin schema" diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/Cargo.toml b/contracts/cosmwasm-vm/cw-xcall-lib/Cargo.toml deleted file mode 100644 index 63829f72..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/Cargo.toml +++ /dev/null @@ -1,47 +0,0 @@ -[package] -name = "cw-xcall-lib" -version = "0.1.0" -edition = "2021" - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -library = [] - -[package.metadata.scripts] -optimize = """docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ - --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.10 -""" - -[dependencies] -cosmwasm-schema = {workspace=true} -cosmwasm-std = {workspace=true} -cosmwasm-storage = {workspace=true} -cw-storage-plus = {workspace=true} -cw2 = {workspace=true} -schemars = {workspace=true} -serde = { workspace=true} -thiserror = { workspace=true} -debug_print={workspace=true} -common = { workspace=true } - - -[dev-dependencies] -cosmwasm = "0.7.2" -getrandom = {version = "0.2", default-features = false, features = ["custom"]} -hex = "0.4.3" -anyhow="*" -test-utils={ git = "https://github.com/icon-project/IBC-Integration.git",branch="main" } \ No newline at end of file diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/dapp_msg.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/dapp_msg.rs deleted file mode 100644 index 869b8f2b..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/dapp_msg.rs +++ /dev/null @@ -1,8 +0,0 @@ -use cosmwasm_schema::cw_serde; - -use crate::network_address::NetworkAddress; - -#[cw_serde] -pub enum ExecuteMsg { - HandleCallMessage { from: NetworkAddress, data: Vec }, -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/dapp_multi_msg.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/dapp_multi_msg.rs deleted file mode 100644 index 38927f0f..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/dapp_multi_msg.rs +++ /dev/null @@ -1,12 +0,0 @@ -use cosmwasm_schema::cw_serde; - -use crate::network_address::NetworkAddress; - -#[cw_serde] -pub enum ExecuteMsg { - HandleCallMessage { - from: NetworkAddress, - data: Vec, - protocols: Vec, - }, -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/lib.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/lib.rs deleted file mode 100644 index d32be794..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod dapp_msg; -pub mod dapp_multi_msg; -pub mod message; -pub mod network_address; -pub mod xcall_connection_msg; -pub mod xcall_msg; diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message.rs deleted file mode 100644 index dd84f6a0..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message.rs +++ /dev/null @@ -1,59 +0,0 @@ -use common::rlp::{self, Decodable, DecoderError, Encodable, RlpStream}; -use cosmwasm_schema::cw_serde; - -use super::msg_trait::IMessage; - -#[cw_serde] -pub struct CallMessage { - pub data: Vec, -} - -impl Encodable for CallMessage { - fn rlp_append(&self, stream: &mut RlpStream) { - stream.begin_list(1).append(&self.data); - } -} - -impl Decodable for CallMessage { - fn decode(rlp: &rlp::Rlp) -> Result { - Ok(Self { - data: rlp.val_at(0)?, - }) - } -} - -impl IMessage for CallMessage { - fn rollback(&self) -> Option> { - None - } - - fn data(&self) -> Vec { - self.data.clone() - } - - fn to_bytes(&self) -> Result, DecoderError> { - Ok(rlp::encode(self).to_vec()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use rlp::Rlp; - - #[test] - fn test_call_message() { - let msg = CallMessage { - data: vec![1, 2, 3], - }; - - let encoded = msg.rlp_bytes().to_vec(); - let decoded = CallMessage::decode(&Rlp::new(&encoded)).unwrap(); - - assert_eq!(msg, decoded); - assert_eq!(msg.rollback(), None); - assert_eq!(msg.data(), msg.data); - assert_eq!(msg.to_bytes().unwrap(), encoded) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message_persisted.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message_persisted.rs deleted file mode 100644 index ebec2203..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message_persisted.rs +++ /dev/null @@ -1,58 +0,0 @@ -use super::msg_trait::IMessage; -use common::rlp::{self, Decodable, DecoderError, Encodable, RlpStream}; -use cosmwasm_schema::cw_serde; - -#[cw_serde] -pub struct CallMessagePersisted { - pub data: Vec, -} - -impl Encodable for CallMessagePersisted { - fn rlp_append(&self, stream: &mut RlpStream) { - stream.begin_list(1).append(&self.data); - } -} - -impl Decodable for CallMessagePersisted { - fn decode(rlp: &rlp::Rlp) -> Result { - Ok(Self { - data: rlp.val_at(0)?, - }) - } -} - -impl IMessage for CallMessagePersisted { - fn rollback(&self) -> Option> { - None - } - - fn data(&self) -> Vec { - self.data.clone() - } - - fn to_bytes(&self) -> Result, DecoderError> { - Ok(rlp::encode(self).to_vec()) - } -} - -#[cfg(test)] -mod tests { - use common::rlp::Rlp; - - use super::*; - - #[test] - fn test_call_message_persisted() { - let msg = CallMessagePersisted { - data: vec![1, 2, 3], - }; - - let encoded = msg.rlp_bytes().to_vec(); - let decoded = CallMessagePersisted::decode(&Rlp::new(&encoded)).unwrap(); - - assert_eq!(msg, decoded); - assert_eq!(msg.rollback(), None); - assert_eq!(msg.data(), msg.data); - assert_eq!(msg.to_bytes().unwrap(), encoded) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message_rollback.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message_rollback.rs deleted file mode 100644 index 22df970b..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/call_message_rollback.rs +++ /dev/null @@ -1,65 +0,0 @@ -use common::rlp::{self, Decodable, DecoderError, Encodable, RlpStream}; -use cosmwasm_schema::cw_serde; - -use super::msg_trait::IMessage; - -#[cw_serde] -pub struct CallMessageWithRollback { - pub data: Vec, - pub rollback: Vec, -} - -impl Encodable for CallMessageWithRollback { - fn rlp_append(&self, stream: &mut RlpStream) { - stream - .begin_list(2) - .append(&self.data) - .append(&self.rollback); - } -} - -impl Decodable for CallMessageWithRollback { - fn decode(rlp: &rlp::Rlp) -> Result { - Ok(Self { - data: rlp.val_at(0)?, - rollback: rlp.val_at(1)?, - }) - } -} - -impl IMessage for CallMessageWithRollback { - fn rollback(&self) -> Option> { - Some(self.rollback.clone()) - } - - fn data(&self) -> Vec { - self.data.clone() - } - - fn to_bytes(&self) -> Result, DecoderError> { - Ok(rlp::encode(self).to_vec()) - } -} - -#[cfg(test)] -mod tests { - use common::rlp::Rlp; - - use super::*; - - #[test] - fn test_call_message_with_rollback() { - let msg = CallMessageWithRollback { - data: vec![1, 2, 3], - rollback: vec![1, 2, 3], - }; - - let encoded = msg.rlp_bytes().to_vec(); - let decoded = CallMessageWithRollback::decode(&Rlp::new(&encoded)).unwrap(); - - assert_eq!(msg, decoded); - assert_eq!(msg.rollback().unwrap(), msg.rollback); - assert_eq!(msg.data(), msg.data); - assert_eq!(msg.to_bytes().unwrap(), encoded) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/envelope.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/message/envelope.rs deleted file mode 100644 index 4960fa40..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/envelope.rs +++ /dev/null @@ -1,144 +0,0 @@ -use common::rlp::{self, Decodable, DecoderError, Encodable}; -use cosmwasm_schema::cw_serde; - -use super::{ - call_message::CallMessage, call_message_persisted::CallMessagePersisted, - call_message_rollback::CallMessageWithRollback, msg_trait::IMessage, msg_type::MessageType, - AnyMessage, -}; -#[cw_serde] -pub struct Envelope { - pub message: AnyMessage, - pub sources: Vec, - pub destinations: Vec, -} - -impl Envelope { - pub fn new(msg: AnyMessage, sources: Vec, destinations: Vec) -> Self { - Self { - message: msg, - sources, - destinations, - } - } -} - -impl Encodable for Envelope { - fn rlp_append(&self, stream: &mut common::rlp::RlpStream) { - stream.begin_list(4); - stream.append(&Into::::into(self.message.msg_type().clone())); - stream.append(&self.message.to_bytes().unwrap()); - stream.begin_list(self.sources.len()); - for source in self.sources.iter() { - stream.append(source); - } - stream.begin_list(self.destinations.len()); - for dest in self.destinations.iter() { - stream.append(dest); - } - } -} - -impl Decodable for Envelope { - fn decode(rlp: &rlp::Rlp) -> Result { - let msg_int: u8 = rlp.val_at(0)?; - let msg_type = MessageType::from(msg_int); - let message_bytes: Vec = rlp.val_at(1)?; - let message = decode_message(msg_type, message_bytes)?; - - let sources = rlp.at(2)?; - let sources: Vec = sources.as_list()?; - let destinations = rlp.at(3)?; - let destinations: Vec = destinations.as_list()?; - - Ok(Envelope { - message, - sources, - destinations, - }) - } -} - -pub fn decode_message(msg_type: MessageType, bytes: Vec) -> Result { - match msg_type { - MessageType::CallMessage => { - let msg: CallMessage = rlp::decode(&bytes)?; - Ok(AnyMessage::CallMessage(msg)) - } - MessageType::CallMessageWithRollback => { - let msg: CallMessageWithRollback = rlp::decode(&bytes)?; - Ok(AnyMessage::CallMessageWithRollback(msg)) - } - MessageType::CallMessagePersisted => { - let msg: CallMessagePersisted = rlp::decode(&bytes)?; - Ok(AnyMessage::CallMessagePersisted(msg)) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_envelope_call_message() { - let msg = AnyMessage::CallMessage(CallMessage { - data: vec![1, 2, 3], - }); - let sources = vec!["src".to_string()]; - let destinations = vec!["dst".to_string()]; - let envelope = Envelope::new(msg.clone(), sources, destinations); - - let encoded = envelope.rlp_bytes().to_vec(); - let decoded = Envelope::decode(&rlp::Rlp::new(&encoded)).unwrap(); - assert_eq!(envelope, decoded); - - let encoded = msg.to_bytes().unwrap(); - let decoded = decode_message(MessageType::CallMessage, encoded.clone()).unwrap(); - assert_eq!(decoded.rollback(), None); - assert_eq!(decoded.data(), vec![1, 2, 3]); - assert_eq!(decoded.to_bytes().unwrap(), encoded) - } - - #[test] - fn test_envelope_call_message_persisted() { - let msg = AnyMessage::CallMessagePersisted(CallMessagePersisted { - data: vec![1, 2, 3], - }); - let sources = vec!["src".to_string()]; - let destinations = vec!["dst".to_string()]; - let envelope = Envelope::new(msg.clone(), sources, destinations); - - let encoded = envelope.rlp_bytes().to_vec(); - let decoded = Envelope::decode(&rlp::Rlp::new(&encoded)).unwrap(); - assert_eq!(envelope, decoded); - - let encoded = msg.to_bytes().unwrap(); - let decoded = decode_message(MessageType::CallMessagePersisted, encoded.clone()).unwrap(); - assert_eq!(decoded.rollback(), None); - assert_eq!(decoded.data(), vec![1, 2, 3]); - assert_eq!(decoded.to_bytes().unwrap(), encoded) - } - - #[test] - fn test_envelope_call_message_with_rollback() { - let msg = AnyMessage::CallMessageWithRollback(CallMessageWithRollback { - data: vec![1, 2, 3], - rollback: vec![1, 2, 3], - }); - let sources = vec!["src".to_string()]; - let destinations = vec!["dst".to_string()]; - let envelope = Envelope::new(msg.clone(), sources, destinations); - - let encoded = envelope.rlp_bytes().to_vec(); - let decoded = Envelope::decode(&rlp::Rlp::new(&encoded)).unwrap(); - assert_eq!(envelope, decoded); - - let encoded = msg.to_bytes().unwrap(); - let decoded = - decode_message(MessageType::CallMessageWithRollback, encoded.clone()).unwrap(); - assert_eq!(decoded.rollback(), Some(vec![1, 2, 3])); - assert_eq!(decoded.data(), vec![1, 2, 3]); - assert_eq!(decoded.to_bytes().unwrap(), encoded) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/mod.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/message/mod.rs deleted file mode 100644 index e74bbfe0..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/mod.rs +++ /dev/null @@ -1,56 +0,0 @@ -use common::rlp::DecoderError; -use cosmwasm_schema::cw_serde; - -use self::{ - call_message::CallMessage, call_message_persisted::CallMessagePersisted, - call_message_rollback::CallMessageWithRollback, msg_trait::IMessage, msg_type::MessageType, -}; - -pub mod call_message; -pub mod call_message_persisted; -pub mod call_message_rollback; -pub mod envelope; -pub mod msg_trait; -pub mod msg_type; -#[cw_serde] -pub enum AnyMessage { - CallMessage(CallMessage), - CallMessageWithRollback(CallMessageWithRollback), - CallMessagePersisted(CallMessagePersisted), -} - -impl IMessage for AnyMessage { - fn rollback(&self) -> Option> { - match self { - AnyMessage::CallMessage(m) => m.rollback(), - AnyMessage::CallMessageWithRollback(m) => m.rollback(), - AnyMessage::CallMessagePersisted(m) => m.rollback(), - } - } - - fn data(&self) -> Vec { - match self { - AnyMessage::CallMessage(m) => m.data(), - AnyMessage::CallMessageWithRollback(m) => m.data(), - AnyMessage::CallMessagePersisted(m) => m.data(), - } - } - - fn to_bytes(&self) -> Result, DecoderError> { - match self { - AnyMessage::CallMessage(m) => m.to_bytes(), - AnyMessage::CallMessageWithRollback(m) => m.to_bytes(), - AnyMessage::CallMessagePersisted(m) => m.to_bytes(), - } - } -} - -impl AnyMessage { - pub fn msg_type(&self) -> &MessageType { - match self { - AnyMessage::CallMessage(_m) => &MessageType::CallMessage, - AnyMessage::CallMessageWithRollback(_m) => &MessageType::CallMessageWithRollback, - AnyMessage::CallMessagePersisted(_m) => &MessageType::CallMessagePersisted, - } - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/msg_trait.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/message/msg_trait.rs deleted file mode 100644 index 5f89edc0..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/msg_trait.rs +++ /dev/null @@ -1,8 +0,0 @@ -use common::rlp::DecoderError; - -pub trait IMessage: Clone { - fn rollback(&self) -> Option>; - fn data(&self) -> Vec; - - fn to_bytes(&self) -> Result, DecoderError>; -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/msg_type.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/message/msg_type.rs deleted file mode 100644 index e1e4c597..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/message/msg_type.rs +++ /dev/null @@ -1,66 +0,0 @@ -use serde::Serialize; - -#[derive(Clone, Debug, Serialize, serde::Deserialize, PartialEq, Eq)] -pub enum MessageType { - CallMessage = 0, - CallMessageWithRollback = 1, - CallMessagePersisted = 2, -} - -impl From for u8 { - fn from(val: MessageType) -> Self { - match val { - MessageType::CallMessage => 0, - MessageType::CallMessageWithRollback => 1, - MessageType::CallMessagePersisted => 2, - } - } -} - -impl From for MessageType { - fn from(value: u8) -> Self { - match value { - 0 => MessageType::CallMessage, - 1 => MessageType::CallMessageWithRollback, - 2 => MessageType::CallMessagePersisted, - _ => panic!("unsupported message type"), - } - } -} - -impl MessageType { - pub fn as_int(&self) -> u8 { - self.clone().into() - } - pub fn from_int(val: u8) -> Self { - MessageType::from(val) - } -} - -#[cfg(test)] -mod tests { - use crate::message::msg_type::MessageType; - - #[test] - fn test_message_type_for_u8() { - assert_eq!(MessageType::CallMessage, 0.into()); - assert_eq!(MessageType::CallMessagePersisted, 2.into()); - assert_eq!(MessageType::CallMessageWithRollback, 1.into()) - } - - #[test] - fn test_message_type_from_int() { - assert_eq!(MessageType::from_int(0), MessageType::CallMessage); - assert_eq!( - MessageType::from_int(1), - MessageType::CallMessageWithRollback - ); - assert_eq!(MessageType::from_int(2), MessageType::CallMessagePersisted) - } - - #[test] - #[should_panic(expected = "unsupported message type")] - fn test_message_type_from_int_fail() { - MessageType::from_int(4); - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/message_types.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/message_types.rs deleted file mode 100644 index d91a78d8..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/message_types.rs +++ /dev/null @@ -1,17 +0,0 @@ -use common::rlp::Encodable; -use common::rlp::Decodable; - - -pub struct Message { - msg_type:MessageType, - data:Vec, -} - - -pub struct MessageWithRollback{ - msg_type:MessageType, - data:Vec, - rollback:Vec, -} - - diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/network_address.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/network_address.rs deleted file mode 100644 index e0959b2c..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/network_address.rs +++ /dev/null @@ -1,107 +0,0 @@ -use std::str::FromStr; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, StdError}; -use cw_storage_plus::{Key, KeyDeserialize, PrimaryKey}; - -#[cw_serde] -#[derive(Eq)] -pub struct NetId(String); - -impl From for NetId { - fn from(value: String) -> Self { - Self(value) - } -} - -impl ToString for NetId { - fn to_string(&self) -> String { - self.0.to_string() - } -} - -impl NetId { - pub fn as_str(&self) -> &str { - &self.0 - } -} - -impl FromStr for NetId { - type Err = StdError; - - fn from_str(s: &str) -> Result { - Ok(Self(s.to_owned())) - } -} - -impl<'a> PrimaryKey<'a> for NetId { - type Prefix = (); - - type SubPrefix = (); - - type Suffix = Self; - - type SuperSuffix = Self; - - fn key(&self) -> Vec { - vec![Key::Ref(self.0.as_bytes())] - } -} - -impl KeyDeserialize for NetId { - type Output = NetId; - - fn from_vec(value: Vec) -> cosmwasm_std::StdResult { - let result = String::from_utf8(value) - .map_err(StdError::invalid_utf8) - .unwrap(); - let net_id = NetId::from_str(&result).unwrap(); - Ok(net_id) - } -} - -#[cw_serde] -#[derive(Eq)] -pub struct NetworkAddress(String); - -impl NetworkAddress { - pub fn new(nid: &str, address: &str) -> Self { - Self(format!("{}/{}", nid, address)) - } - pub fn nid(&self) -> NetId { - NetId(self.get_parts()[0].to_string()) - } - - pub fn account(&self) -> Addr { - Addr::unchecked(self.get_parts()[1]) - } - - pub fn get_parts(&self) -> Vec<&str> { - let parts = self.0.split('/').collect::>(); - if parts.len() != 2 { - panic!("Invalid Network Address"); - } - parts - } -} - -impl ToString for NetworkAddress { - fn to_string(&self) -> String { - self.0.to_string() - } -} - -impl FromStr for NetworkAddress { - type Err = StdError; - - fn from_str(s: &str) -> Result { - let parts = s.split('/').collect::>(); - if parts.len() != 2 { - return Err(StdError::GenericErr { - msg: "Invalid Network Address".to_owned(), - }); - } - let na = format!("{}/{}", parts[0], parts[1]); - Ok(Self(na)) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/xcall_connection_msg.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/xcall_connection_msg.rs deleted file mode 100644 index 09b450c0..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/xcall_connection_msg.rs +++ /dev/null @@ -1,18 +0,0 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; - -use crate::network_address::NetId; - -#[cw_serde] -pub enum ExecuteMsg { - SendMessage { to: NetId, sn: i64, msg: Vec }, -} - -#[cw_serde] -#[derive(QueryResponses)] -/// This is a Rust enum representing different types of queries that can be made to the contract. Each -/// variant of the enum corresponds to a specific query and has a return type specified using the -/// `#[returns]` attribute. -pub enum QueryMsg { - #[returns(u64)] - GetFee { nid: NetId, response: bool }, -} diff --git a/contracts/cosmwasm-vm/cw-xcall-lib/src/xcall_msg.rs b/contracts/cosmwasm-vm/cw-xcall-lib/src/xcall_msg.rs deleted file mode 100644 index b8a80665..00000000 --- a/contracts/cosmwasm-vm/cw-xcall-lib/src/xcall_msg.rs +++ /dev/null @@ -1,52 +0,0 @@ -use cosmwasm_schema::cw_serde; -use cosmwasm_std::Addr; - -use crate::{ - message::envelope::Envelope, - network_address::{NetId, NetworkAddress}, -}; - -#[cw_serde] -pub enum ExecuteMsg { - SetAdmin { - address: String, - }, - SetProtocolFee { - value: u128, - }, - SetProtocolFeeHandler { - address: String, - }, - - SendCallMessage { - to: NetworkAddress, - data: Vec, - rollback: Option>, - sources: Option>, - destinations: Option>, - }, - SendCall { - envelope: Envelope, - to: NetworkAddress, - }, - HandleMessage { - from_nid: NetId, - msg: Vec, - }, - - HandleError { - sn: u128, - }, - ExecuteCall { - request_id: u128, - data: Vec, - }, - - ExecuteRollback { - sequence_no: u128, - }, - SetDefaultConnection { - nid: NetId, - address: Addr, - }, -} diff --git a/contracts/cosmwasm-vm/cw-xcall/.cargo/config b/contracts/cosmwasm-vm/cw-xcall/.cargo/config deleted file mode 100644 index af5698e5..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --lib --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --bin schema" diff --git a/contracts/cosmwasm-vm/cw-xcall/Cargo.toml b/contracts/cosmwasm-vm/cw-xcall/Cargo.toml deleted file mode 100644 index 4c234ac9..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/Cargo.toml +++ /dev/null @@ -1,51 +0,0 @@ -[package] -name = "cw-xcall" -version.workspace = true -authors.workspace = true -edition = "2021" - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -library = [] - -[package.metadata.scripts] -optimize = """docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ - --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.10 -""" - -[dependencies] -cosmwasm-schema = {workspace=true} -cosmwasm-std = {workspace=true} -cosmwasm-storage = {workspace=true} -cw-storage-plus = {workspace=true} -cw2 = {workspace=true} -schemars = {workspace=true} -serde = { workspace=true} -thiserror = { workspace=true} -common = { git = "https://github.com/icon-project/IBC-Integration.git",branch="main" } - -cw-xcall-lib = { workspace=true } -debug_print={workspace=true} - - - -[dev-dependencies] -cosmwasm = "0.7.2" -getrandom = {version = "0.2", default-features = false, features = ["custom"]} -hex = "0.4.3" -anyhow="*" -test-utils={ git = "https://github.com/icon-project/IBC-Integration.git",branch="main" } \ No newline at end of file diff --git a/contracts/cosmwasm-vm/cw-xcall/src/admin.rs b/contracts/cosmwasm-vm/cw-xcall/src/admin.rs deleted file mode 100644 index eefde8e1..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/admin.rs +++ /dev/null @@ -1,63 +0,0 @@ -use super::*; - -impl<'a> CwCallService<'a> { - /// This function queries the admin of a smart contract from the storage. - /// - /// Arguments: - /// - /// * `store`: `store` is a reference to a trait object of type `dyn Storage`. This is used to - /// interact with the contract's storage, which is where data is stored permanently on the - /// blockchain. The `query_admin` function uses the `store` parameter to load the current admin - /// address from storage and return - /// - /// Returns: - /// - /// The function `query_admin` returns a `Result` containing either a `String` representing the admin - /// address if it exists in the storage or a `ContractError` if it does not exist. - pub fn query_admin(&self, store: &dyn Storage) -> Result { - let admin = self - .admin() - .load(store) - .map_err(|_| ContractError::AdminNotExist)?; - - Ok(admin.to_string()) - } - - /// This function adds an admin to the contract if the sender is the owner and the admin does not - /// already exist. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. It is used to - /// interact with the contract's storage and persist data on the blockchain. - /// * `info`: `info` is a parameter of type `MessageInfo` which contains information about the message - /// being executed, such as the sender's address, the amount of coins being sent, and the gas limit. - /// This parameter is used to check if the sender is authorized to add an admin. - /// * `admin`: A string representing the address of the new admin to be added to the contract. - /// - /// Returns: - /// - /// a `Result` - pub fn set_admin( - &self, - store: &mut dyn Storage, - admin: Addr, - ) -> Result { - self.admin().save(store, &admin)?; - Ok(Response::new() - .add_attribute("method", "set_admin") - .add_attribute("admin", admin.to_string())) - } - - pub fn validate_address(api: &dyn Api, address: &str) -> Result { - if !address.chars().all(|x| x.is_alphanumeric()) { - return Err(ContractError::InvalidAddress { - address: address.to_string(), - }); - } - - let validated_address = api.addr_validate(address).map_err(ContractError::Std)?; - - Ok(validated_address) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/assertion.rs b/contracts/cosmwasm-vm/cw-xcall/src/assertion.rs deleted file mode 100644 index 9cf7e704..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/assertion.rs +++ /dev/null @@ -1,207 +0,0 @@ -use cosmwasm_std::to_json_binary; - -use super::*; - -use crate::{ - error::ContractError, - state::{CwCallService, MAX_DATA_SIZE, MAX_ROLLBACK_SIZE}, - types::{request::CSMessageRequest, rollback::Rollback}, -}; - -impl<'a> CwCallService<'a> { - /// This function checks if the caller is a contract and if the rollback option is null, and returns - /// an error if the rollback is not possible. - /// - /// Arguments: - /// - /// * `deps`: `deps` is an object that contains dependencies required by the contract to interact - /// with the blockchain. It is of type `Deps`, which is a struct that contains various modules such - /// as `storage`, `querier`, `api`, etc. - /// * `address`: The address of the caller that needs to be checked if it is a contract or not. - /// * `rollback`: `rollback` is an optional `Vec` parameter that represents the rollback data. If - /// it is `Some`, it means that a rollback is possible and the caller must be a contract. If it is - /// `None`, it means that a rollback is not possible and the caller can be any type - /// - /// Returns: - /// - /// a `Result` type with the `Ok` variant containing an empty tuple `()` and the `Err` variant - /// containing a `ContractError` if the condition in the `ensure!` macro is not met. - pub fn ensure_caller_is_contract_and_rollback_is_null( - &self, - deps: Deps, - address: &Addr, - rollback: &Option>, - ) -> Result<(), ContractError> { - if rollback.is_some() { - ensure!( - is_contract(deps.querier, address), - ContractError::RollbackNotPossible - ); - } - - Ok(()) - } - - /// This function ensures that the length of the data is not greater than the maximum allowed size and - /// returns an error if it is. - /// - /// Arguments: - /// - /// * `data_len`: `data_len` is a variable of type `usize` that represents the length of some data. It - /// is used as a parameter in the `ensure_data_length` function to check if the length of the data is - /// within the maximum allowed size. If the length of the data exceeds the maximum size, - /// - /// Returns: - /// - /// The `ensure_data_length` function returns a `Result` type with the success case containing an empty - /// tuple `()` and the error case containing a `ContractError`. - pub fn ensure_data_length(&self, data_len: usize) -> Result<(), ContractError> { - ensure!( - data_len <= MAX_DATA_SIZE as usize, - ContractError::MaxDataSizeExceeded - ); - - Ok(()) - } - /// This function ensures that the length of a given byte array (rollback) is not greater than a - /// specified maximum size. - /// - /// Arguments: - /// - /// * `rollback`: `rollback` is a slice of bytes (`&[u8]`) that represents the data to be rolled back in - /// a smart contract. The function `ensure_rollback_length` checks if the length of the `rollback` slice - /// is within the maximum allowed size (`MAX_ROLLBACK_SIZE`) and is not empty. - /// - /// Returns: - /// - /// a `Result` type with the `Ok` variant containing an empty tuple `()` and the `Err` variant - /// containing a `ContractError` if the condition in the `ensure!` macro is not met. - - pub fn ensure_rollback_length(&self, rollback: &[u8]) -> Result<(), ContractError> { - ensure!( - rollback.is_empty() || rollback.len() <= MAX_ROLLBACK_SIZE as usize, - ContractError::MaxRollbackSizeExceeded - ); - - Ok(()) - } - - /// The function ensures that the request message is not null and returns an error if it is. - /// - /// Arguments: - /// - /// * `req_id`: A unique identifier for the request being made. - /// * `message`: `message` is a reference to a `CallServiceMessageRequest` struct. This struct likely - /// contains information about a request to call a service, such as the name of the service, the input - /// parameters, and any other relevant data. The function is checking to make sure that this message is - /// not null - /// - /// Returns: - /// - /// a `Result` with either an `Ok(())` if the `data` is not empty, or a - /// `ContractError::InvalidRequestId` with the given `req_id` if the `data` is empty. - pub fn ensure_request_not_null( - &self, - req_id: u128, - message: &CSMessageRequest, - ) -> Result<(), ContractError> { - let data = to_json_binary(message).unwrap(); - ensure!( - !(data.is_empty()), - ContractError::InvalidRequestId { id: req_id } - ); - - Ok(()) - } - - /// This function ensures that a call request message is not null and returns an error if it is. - /// - /// Arguments: - /// - /// * `sequence_no`: an unsigned 128-bit integer representing the sequence number of a call request. - /// * `message`: The `message` parameter is a reference to a `CallRequest` struct. It is used to ensure - /// that the `data` field of the `CallRequest` is not empty. If it is empty, it will return an error - /// indicating an invalid sequence ID. - /// - /// Returns: - /// - /// a `Result` enum with either an `Ok(())` value indicating that the call request is not null, or an - /// `Err(ContractError)` value indicating that the call request is null and providing an error message. - pub fn ensure_call_request_not_null( - &self, - sequence_no: u128, - message: &Rollback, - ) -> Result<(), ContractError> { - let data = to_json_binary(message).unwrap(); - ensure!( - !(data.is_empty()), - ContractError::InvalidSequenceId { id: sequence_no } - ); - - Ok(()) - } - /// This function checks if rollback is enabled and returns an error if it is not. - /// - /// Arguments: - /// - /// * `enabled`: A boolean value indicating whether rollback is enabled or not. If it is not enabled, - /// the function will return a `ContractError` with the message "RollbackNotEnabled". - /// - /// Returns: - /// - /// The function `ensure_rollback_enabled` is returning a `Result` type with the `Ok` variant containing - /// an empty tuple `()` if the `enabled` parameter is `true`, and a `ContractError` with the - /// `RollbackNotEnabled` variant if the `enabled` parameter is `false`. - - pub fn ensure_rollback_enabled(&self, enabled: bool) -> Result<(), ContractError> { - ensure!(enabled, ContractError::RollbackNotEnabled); - - Ok(()) - } - - /// The function ensures that the given address is the admin of the contract. - /// - /// Arguments: - /// - /// * `store`: `store` is a reference to a trait object of type `dyn Storage`. This is used to interact - /// with the contract's storage and retrieve data from it. The `ensure_admin` function uses `store` to - /// query the current admin address stored in the contract's storage. - /// * `address`: `address` is a variable of type `Addr` that represents the address of a user or - /// contract. It is used as an argument in the `ensure_admin` function to check if the address matches - /// the admin address stored in the contract's storage. If the addresses do not match, the function - /// returns - /// - /// Returns: - /// - /// a `Result` with either an `Ok(())` value indicating that the `address` parameter matches the stored - /// `admin` value, or a `ContractError` value with the message "OnlyAdmin" if the `address` parameter - /// does not match the stored `admin` value. - pub fn ensure_admin(&self, store: &dyn Storage, address: Addr) -> Result<(), ContractError> { - let admin = self.query_admin(store)?; - ensure_eq!(admin, address, ContractError::OnlyAdmin); - - Ok(()) - } -} - -/// The function checks if a given address is a valid smart contract by querying its information using a -/// QuerierWrapper. -/// -/// Arguments: -/// -/// * `querier`: The `querier` parameter is an instance of the `QuerierWrapper` struct, which is used to -/// query information from the blockchain. It provides methods to query account balances, contract -/// state, and other information related to the blockchain. -/// * `address`: The `address` parameter is a variable of type `Addr` which represents the address of a -/// smart contract on the blockchain. -/// -/// Returns: -/// -/// The function `is_contract` returns a boolean value indicating whether the given address is a valid -/// smart contract on the blockchain or not. It does this by querying the blockchain through the -/// `querier` object to get information about the contract at the given `address`. If the query is -/// successful, it returns `true`, indicating that the address is a valid contract. If the query fails, -/// it returns false ` -pub fn is_contract(querier: QuerierWrapper, address: &Addr) -> bool { - querier.query_wasm_contract_info(address).is_ok() -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/connection.rs b/contracts/cosmwasm-vm/cw-xcall/src/connection.rs deleted file mode 100644 index b2c1fca6..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/connection.rs +++ /dev/null @@ -1,79 +0,0 @@ -use crate::types::{message::CSMessage, LOG_PREFIX}; -use common::rlp; -use cosmwasm_std::{ - to_json_binary, Addr, Coin, CosmosMsg, Deps, DepsMut, QueryRequest, SubMsg, WasmMsg, -}; -use cosmwasm_std::{MessageInfo, Response}; -use cw_xcall_lib::network_address::NetId; -use cw_xcall_lib::xcall_connection_msg; - -use crate::{ - error::ContractError, - state::{CwCallService, SEND_CALL_MESSAGE_REPLY_ID}, -}; - -impl<'a> CwCallService<'a> { - pub fn call_connection_send_message( - &self, - address: &Addr, - fee: Vec, - to: NetId, - sn: i64, - msg: &CSMessage, - ) -> Result { - let msg = rlp::encode(msg).to_vec(); - self.ensure_data_length(msg.len())?; - let message = xcall_connection_msg::ExecuteMsg::SendMessage { to, sn, msg }; - - let cosm_msg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: address.to_string(), - msg: to_json_binary(&message).map_err(ContractError::Std)?, - funds: fee, - }); - let submessage = SubMsg { - id: SEND_CALL_MESSAGE_REPLY_ID, - msg: cosm_msg, - gas_limit: None, - reply_on: cosmwasm_std::ReplyOn::Never, - }; - println!("{LOG_PREFIX} sent message to connection :{address}"); - Ok(submessage) - } - - pub fn query_connection_fee( - &self, - deps: Deps, - nid: NetId, - need_response: bool, - address: &str, - ) -> Result { - let query_message = xcall_connection_msg::QueryMsg::GetFee { - nid, - response: need_response, - }; - - let query_request = QueryRequest::Wasm(cosmwasm_std::WasmQuery::Smart { - contract_addr: address.to_string(), - msg: to_json_binary(&query_message).map_err(ContractError::Std)?, - }); - let fee: u128 = deps - .querier - .query(&query_request) - .map_err(ContractError::Std)?; - Ok(fee) - } - - pub fn set_default_connection( - &self, - deps: DepsMut, - info: MessageInfo, - nid: NetId, - address: Addr, - ) -> Result { - self.ensure_admin(deps.storage, info.sender)?; - deps.api.addr_validate(address.as_str())?; - self.store_default_connection(deps.storage, nid, address)?; - - Ok(Response::new().add_attribute("method", "set_default_connection")) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/contract.rs b/contracts/cosmwasm-vm/cw-xcall/src/contract.rs deleted file mode 100644 index 3f08d520..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/contract.rs +++ /dev/null @@ -1,248 +0,0 @@ -use cw_xcall_lib::network_address::NetworkAddress; - -use crate::types::{config::Config, LOG_PREFIX}; - -use super::*; -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw-xcall"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -impl<'a> CwCallService<'a> { - /// This function instantiates a contract and initializes it with the provided message and - /// information. - /// - /// Arguments: - /// - /// * `deps`: `deps` is a `DepsMut` object, which is short for "dependencies mutable". It is a struct - /// that provides access to the contract's dependencies, such as the storage, API, and querier. - /// * `_env`: The `_env` parameter in the `instantiate` function is of type `Env`, which represents - /// the environment in which the contract is being executed. It contains information such as the - /// current block height, the current time, and the address of the contract being executed. However, - /// in the given code snippet - /// * `info`: `info` is a struct that contains information about the message sender, such as their - /// address, the amount of tokens they sent with the message, and the maximum amount of gas they are - /// willing to pay for the transaction. This information can be used to determine whether the sender - /// is authorized to perform certain actions. - /// * `msg`: The `msg` parameter in the `instantiate` function is of type `InstantiateMsg` and - /// contains the message sent by the user when instantiating the contract. It can contain any custom - /// data that the user wants to pass to the contract during instantiation. - /// Returns: - /// - /// The `instantiate` function returns a `Result` where `Response` is a - /// struct representing the response to a message and `ContractError` is an enum representing the - /// possible errors that can occur during contract execution. The function returns the result of - /// calling the `init` function with the provided arguments. - pub fn instantiate( - &self, - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: InstantiateMsg, - ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - self.init(deps.storage, info, msg) - } - - /// This function executes various messages based on their type and returns a response or an error. - /// - /// Arguments: - /// - /// * `deps`: `deps` is a `DepsMut` struct which provides access to the contract's dependencies such - /// as storage, API, and querier. It is mutable, meaning the contract can modify its dependencies. - /// * `env`: `env` is a struct that contains information about the current blockchain environment, - /// such as the block height, time, and chain ID. It is passed as a parameter to the `execute` - /// function in order to provide context for the execution of the contract. - /// * `info`: `info` is a struct that contains information about the message sender, including their - /// address, public key, and the amount of tokens they sent with the message. It is of type - /// `MessageInfo`. - /// * `msg`: The `msg` parameter is of type `ExecuteMsg` and represents the message that is being - /// executed by the contract. It is matched against different variants to determine the action to be - /// taken. - /// - /// Returns: - /// - /// a `Result` where `Response` is a struct representing the response to a - /// message and `ContractError` is an enum representing an error that occurred during contract - /// execution. - pub fn execute( - &mut self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, - ) -> Result { - match msg { - ExecuteMsg::SetAdmin { address } => { - let validated_address = - CwCallService::validate_address(deps.api, address.as_str())?; - self.ensure_admin(deps.storage, info.sender)?; - self.set_admin(deps.storage, validated_address) - } - ExecuteMsg::SetProtocolFee { value } => self.set_protocol_fee(deps, info, value), - ExecuteMsg::SetProtocolFeeHandler { address } => { - self.set_protocol_feehandler(deps, &info, address) - } - ExecuteMsg::SendCallMessage { - to, - sources, - destinations, - data, - rollback, - } => { - println!("{LOG_PREFIX} Received Send Call Message"); - let sources = sources.unwrap_or(vec![]); - let dests = destinations.unwrap_or(vec![]); - self.send_call_message(deps, info, env, to, data, rollback, sources, dests) - } - ExecuteMsg::SendCall { envelope, to } => self.send_call(deps, info, to, envelope), - ExecuteMsg::HandleMessage { msg, from_nid } => { - self.handle_message(deps, info, from_nid, msg) - } - ExecuteMsg::HandleError { sn } => self.handle_error(deps, info, sn), - ExecuteMsg::ExecuteCall { request_id, data } => { - self.execute_call(deps, info, request_id, data) - } - ExecuteMsg::ExecuteRollback { sequence_no } => { - self.execute_rollback(deps, env, info, sequence_no) - } - ExecuteMsg::SetDefaultConnection { nid, address } => { - self.set_default_connection(deps, info, nid, address) - } - } - } - - /// The `query` function takes in dependencies, environment, and a message, and returns a binary - /// result based on the type of message received. - /// - /// Arguments: - /// - /// * `deps`: `deps` is an object of type `Deps` which contains various dependencies required for - /// executing the contract. These dependencies include the storage, API, and querier. The `deps` - /// object is passed as an argument to the `query` function to access these dependencies. - /// * `_env`: The `_env` parameter is an instance of the `Env` struct, which provides information - /// about the current blockchain environment, such as the block height and time. However, it is not - /// used in this particular `query` function. - /// * `msg`: `msg` is a parameter of type `QueryMsg` which is an enum that represents different types - /// of queries that can be made to the smart contract. The function matches on the variant of - /// `QueryMsg` that is passed in and executes the corresponding logic. - /// - /// Returns: - /// - /// The `query` function returns a `StdResult` which can contain either the binary - /// representation of the result of the query or an error if the query fails. The specific result - /// being returned depends on the type of `QueryMsg` being passed in and the logic of the - /// corresponding match arm. - pub fn query(&self, deps: Deps, env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::GetAdmin {} => match self.query_admin(deps.storage) { - Ok(admin) => Ok(to_json_binary(&admin)?), - Err(error) => Err(StdError::NotFound { - kind: error.to_string(), - }), - }, - - QueryMsg::GetProtocolFee {} => to_json_binary(&self.get_protocol_fee(deps.storage)), - QueryMsg::GetProtocolFeeHandler {} => { - to_json_binary(&self.get_protocol_feehandler(deps)) - } - QueryMsg::GetNetworkAddress {} => { - to_json_binary(&self.get_own_network_address(deps.storage, &env).unwrap()) - } - QueryMsg::VerifySuccess { sn } => { - to_json_binary(&self.get_successful_response(deps.storage, sn)) - } - QueryMsg::GetDefaultConnection { nid } => { - to_json_binary(&self.get_default_connection(deps.storage, nid).unwrap()) - } - QueryMsg::GetFee { - nid, - rollback, - sources, - } => to_json_binary( - &self - .get_fee(deps, nid, rollback, sources.unwrap_or(vec![])) - .unwrap(), - ), - } - } - /// This function handles different types of reply messages and calls corresponding functions based on - /// the message ID. - /// - /// Arguments: - /// - /// * `deps`: A mutable reference to the dependencies of the contract, which includes access to the - /// storage, API, and other modules. - /// * `env`: `env` is an environment variable that provides information about the current execution - /// environment of the smart contract. It includes information such as the current block height, the - /// sender address, the contract address, and the current time. This information can be used by the - /// smart contract to make decisions or perform actions based on - /// * `msg`: `msg` is a `Reply` struct that contains the message ID and any associated data that was - /// sent as a reply to a previous message. The `reply` function uses the message ID to determine which - /// specific reply message was received and then calls the appropriate function to handle that message. - /// - /// Returns: - /// - /// a `Result` where `Response` is the response to the message and - /// `ContractError` is an error type that can be returned if there is an error in processing the - /// message. - - pub fn reply(&self, deps: DepsMut, env: Env, msg: Reply) -> Result { - match msg.id { - EXECUTE_CALL_ID => self.execute_call_reply(deps, env, msg), - _ => Err(ContractError::ReplyError { - code: msg.id, - msg: "Unknown".to_string(), - }), - } - } - - pub fn migrate( - &self, - deps: DepsMut, - _env: Env, - _msg: MigrateMsg, - ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION) - .map_err(ContractError::Std)?; - Ok(Response::default().add_attribute("migrate", "successful")) - } -} - -impl<'a> CwCallService<'a> { - fn init( - &self, - store: &mut dyn Storage, - info: MessageInfo, - msg: InstantiateMsg, - ) -> Result { - let last_sequence_no = u128::default(); - let last_request_id = u128::default(); - self.set_admin(store, info.sender.clone())?; - self.init_last_sequence_no(store, last_sequence_no)?; - self.init_last_request_id(store, last_request_id)?; - let caller = info.sender; - self.store_config( - store, - &Config { - network_id: msg.network_id, - denom: msg.denom, - }, - )?; - self.store_protocol_fee_handler(store, caller.to_string())?; - - Ok(Response::new() - .add_attribute("action", "instantiate") - .add_attribute("method", "init")) - } - - pub fn get_own_network_address( - &self, - store: &dyn Storage, - env: &Env, - ) -> Result { - let config = self.get_config(store)?; - let address = env.contract.address.to_string(); - let na = NetworkAddress::new(&config.network_id, &address); - Ok(na) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/dapp.rs b/contracts/cosmwasm-vm/cw-xcall/src/dapp.rs deleted file mode 100644 index c09df03c..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/dapp.rs +++ /dev/null @@ -1,54 +0,0 @@ -use cosmwasm_std::{ - to_json_binary, Addr, Binary, CosmosMsg, MessageInfo, StdError, SubMsg, WasmMsg, -}; -use cw_xcall_lib::{dapp_msg, dapp_multi_msg, network_address::NetworkAddress}; - -use crate::{error::ContractError, state::CwCallService}; - -impl<'a> CwCallService<'a> { - pub fn call_dapp_handle_message( - &self, - info: MessageInfo, - to: Addr, - from: NetworkAddress, - data: Vec, - protocols: Vec, - reply_id: u64, - ) -> Result { - let cosm_msg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: to.to_string(), - msg: self - .get_handle_message(from, data, protocols) - .map_err(ContractError::Std)?, - funds: info.funds, - }); - let submessage = SubMsg { - id: reply_id, - msg: cosm_msg, - gas_limit: None, - reply_on: cosmwasm_std::ReplyOn::Always, - }; - - Ok(submessage) - } - - pub fn get_handle_message( - &self, - from: NetworkAddress, - data: Vec, - protocols: Vec, - ) -> Result { - if protocols.is_empty() { - let message = dapp_msg::ExecuteMsg::HandleCallMessage { from, data }; - let msg = to_json_binary(&message); - return msg; - } - let message = dapp_multi_msg::ExecuteMsg::HandleCallMessage { - from, - data, - protocols, - }; - - to_json_binary(&message) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/error.rs b/contracts/cosmwasm-vm/cw-xcall/src/error.rs deleted file mode 100644 index ec96689a..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/error.rs +++ /dev/null @@ -1,51 +0,0 @@ -use super::*; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - #[error("Unauthorized")] - Unauthorized {}, - #[error("ERR_REPLY_ERROR|{code:?}|{msg:?}")] - ReplyError { code: u64, msg: String }, - #[error("Admin Already Exist")] - AdminAlreadyExist, - #[error("OwnerAlreadyExist")] - AdminNotExist, - #[error("RollbackNotPossible")] - RollbackNotPossible, - #[error("MaxDataSizeExceeded")] - MaxDataSizeExceeded, - #[error("MaxRollbackSizeExceeded")] - MaxRollbackSizeExceeded, - #[error("NotExistRequestId {id}")] - NotExistRequestId { id: u128 }, - #[error("InvalidRequestId {id}")] - InvalidRequestId { id: u128 }, - #[error("RollbackNotEnabled")] - RollbackNotEnabled, - #[error("InvalidSequenceId {id}")] - InvalidSequenceId { id: u128 }, - #[error("DecodeFailed {error}")] - DecodeFailed { error: String }, - #[error("OnlyAdmin")] - OnlyAdmin, - #[error("AdminAddressCannotBeNull")] - AdminAddressCannotBeNull {}, - #[error("InvalidAddress {address}")] - InvalidAddress { address: String }, - #[error("InsufficientFunds")] - InsufficientFunds, - #[error("ProtocolsMismatch")] - ProtocolsMismatch, - #[error("DataMismatch")] - DataMismatch, - #[error("CallAlreadyInProgress")] - CallAlreadyInProgress, - #[error("MessageTypeNotAllowed")] - MessageTypeNotAllowed, - #[error("InvalidReplyReceived")] - InvalidReplyReceived, - #[error("CallRequest Not Found For {sn}")] - CallRequestNotFound { sn: u128 }, -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/events.rs b/contracts/cosmwasm-vm/cw-xcall/src/events.rs deleted file mode 100644 index 86bf7dac..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/events.rs +++ /dev/null @@ -1,131 +0,0 @@ -use super::*; - -/// The function creates a new event with attributes for a call execution and returns it. -/// -/// Arguments: -/// -/// * `request_id`: The `request_id` parameter is an unsigned 128-bit integer that represents the unique -/// identifier of a call execution event. -/// * `code`: The `code` parameter is an integer value representing the status code of the executed -/// call. It can be used to indicate whether the call was successful or encountered an error. -/// * `msg`: The `msg` parameter is a string that represents a message associated with the event. It can -/// be used to provide additional information or context about the event being triggered. -/// -/// Returns: -/// -/// This code returns an instance of the `Event` struct with attributes `request_id`, `code`, and `msg` -/// added to it. The event represents the execution of a call. -pub fn event_call_executed(request_id: u128, code: u8, msg: &str) -> Event { - Event::new("CallExecuted") - .add_attribute("reqId", request_id.to_string()) - .add_attribute("code", code.to_string()) - .add_attribute("msg", msg.to_string()) -} - -/// This Rust function creates an event for a message sent through a cross-chain communication protocol. -/// -/// Arguments: -/// -/// * `sequence_no`: The sequence number of the message being sent. This is used to ensure that messages -/// are processed in the correct order. -/// * `from`: The sender of the cross-chain message. It is of type String. -/// * `req_id`: req_id is a unique identifier for the request being sent. It is of type u128, which -/// means it can hold a very large number. This identifier is used to track the request and match it -/// with the corresponding response. -/// * `data`: The `data` parameter is of type `&CallServiceMessage`, which is a reference to a struct -/// that contains information about a cross-chain message being sent. It likely includes details such as -/// the recipient chain, the message payload, and any required signatures or authentication. -/// -/// Returns: -/// -/// an instance of the `Event` struct. -pub fn event_xcall_message_sent(from: String, destination: String, sn: u128) -> Event { - let event = Event::new("CallMessageSent"); - - event - .add_attribute("from", from) - .add_attribute("to", destination) - .add_attribute("sn", sn.to_string()) -} - -/// The function creates an event object for a rollback execution with sequence number -/// -/// Arguments: -/// -/// * `sequence_no`: The sequence number of the rollback request that was executed. -/// -/// Returns: -/// -/// A new `Event` object with attributes "sequence_no" added to it. -pub fn event_rollback_executed(sequence_no: u128) -> Event { - Event::new("RollbackExecuted").add_attribute("sn", sequence_no.to_string()) -} - -/// The function creates a new event with attributes for a call message in Rust. -/// -/// Arguments: -/// -/// * `from`: The `from` parameter is a `String` representing the sender of a message in an event. -/// * `to`: The "to" parameter in the function `event_call_message` represents the recipient of a call -/// message. It is a string type parameter that takes the value of the recipient's address or -/// identifier. -/// * `sequence_no`: The `sequence_no` parameter is an unsigned 128-bit integer that represents the -/// sequence number of a message being sent from one entity to another. It is used to ensure that -/// messages are processed in the correct order and to prevent duplicate messages. -/// * `request_id`: The `request_id` parameter is a unique identifier for a specific request being made -/// in the `call_message` event. It is of type `u128`, which means it can hold a very large integer -/// value. This identifier can be used to track the progress of the request and match it with the -/// -/// Returns: -/// -/// A function is being returned that creates an instance of the `Event` struct with the attributes -/// "call_message", "from", "to", "sequence_no", and "request_id". -pub fn event_call_message( - from: String, - to: String, - sequence_no: u128, - request_id: u128, - data: Vec, -) -> Event { - Event::new("CallMessage") - .add_attribute("from", from) - .add_attribute("to", to) - .add_attribute("sn", sequence_no.to_string()) - .add_attribute("reqId", request_id.to_string()) - .add_attribute("data", format!("{:?}", data)) -} - -/// The function creates an event with a "rollback_message" type and a sequence number attribute. -/// -/// Arguments: -/// -/// * `sequence_no`: The `sequence_no` parameter is an unsigned 128-bit integer that represents the -/// sequence number of a rollback message event. It is used to uniquely identify the event and keep -/// track of the order in which events occur. -/// -/// Returns: -/// -/// A new `Event` object with the name "rollback_message" and an attribute "sequence_no" with the value -/// of `sequence_no` converted to a string. -pub fn event_rollback_message(sequence_no: u128) -> Event { - Event::new("RollbackMessage ").add_attribute("sn", sequence_no.to_string()) -} - -/// This Rust function creates an event with attributes for a response message. -/// -/// Arguments: -/// -/// * `sequence_no`: The sequence number is a unique identifier for a particular event or message. It is -/// used to keep track of the order in which events or messages are sent and received. -/// * `response_code`: The `response_code` parameter is an integer value representing the response code -/// of an event. It is of type `i8`, which means it can hold values from -128 to 127. The response code -/// is typically used to indicate the status or outcome of an operation or request. -/// -/// Returns: -/// -/// A new `Event` object with the attributes `sequence_no` and `response_code` added to it. -pub fn event_response_message(sequence_no: u128, response_code: u8) -> Event { - Event::new("ResponseMessage") - .add_attribute("sn", sequence_no.to_string()) - .add_attribute("code", response_code.to_string()) -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/execute_call.rs b/contracts/cosmwasm-vm/cw-xcall/src/execute_call.rs deleted file mode 100644 index ddb7e712..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/execute_call.rs +++ /dev/null @@ -1,141 +0,0 @@ -use common::{rlp, utils::keccak256}; -use cosmwasm_std::{DepsMut, Env, MessageInfo, Reply, Response, SubMsg}; - -use crate::{ - error::ContractError, - events::event_call_executed, - state::{CwCallService, EXECUTE_CALL_ID}, - types::{ - message::CSMessage, - result::{CSMessageResult, CallServiceResponseType}, - }, -}; - -impl<'a> CwCallService<'a> { - /// This function executes a call message to a smart contract and returns a response with a - /// submessage. - /// - /// Arguments: - /// - /// * `deps`: `deps` is a `DepsMut` object, which provides access to the contract's dependencies - /// such as storage, API, and querier. It is used to interact with the blockchain and other - /// contracts. - /// * `info`: `info` is a struct of type `MessageInfo` which contains information about the message - /// being executed, such as the sender address, the amount of funds sent with the message, and the - /// gas limit. - /// * `request_id`: `request_id` is a unique identifier for a specific request made by a user. It is - /// used to retrieve the details of the request from the contract's storage and execute the - /// corresponding action. - /// - /// Returns: - /// - /// a `Result` where `Response` is a struct representing the response to a - /// message and `ContractError` is an enum representing the possible errors that can occur during - /// contract execution. - pub fn execute_call( - &self, - deps: DepsMut, - info: MessageInfo, - request_id: u128, - data: Vec, - ) -> Result { - let proxy_requests = self.get_proxy_request(deps.storage, request_id).unwrap(); - - self.ensure_request_not_null(request_id, &proxy_requests) - .unwrap(); - - let data_hash = keccak256(&data).to_vec(); - if data_hash != proxy_requests.data().unwrap().to_vec() { - return Err(ContractError::DataMismatch); - } - - let sub_msg = self.call_dapp_handle_message( - info, - proxy_requests.to().clone(), - proxy_requests.from().clone(), - data, - proxy_requests.protocols().clone(), - EXECUTE_CALL_ID, - )?; - - self.store_execute_request_id(deps.storage, request_id)?; - - Ok(Response::new() - .add_attribute("action", "call_message") - .add_attribute("method", "execute_call") - .add_submessage(sub_msg)) - } - - pub fn execute_call_reply( - &self, - deps: DepsMut, - _env: Env, - msg: Reply, - ) -> Result { - let req_id = self.get_execute_request_id(deps.storage)?; - self.remove_execute_request_id(deps.storage); - - let request = self.get_proxy_request(deps.storage, req_id)?; - self.remove_proxy_request(deps.storage, req_id); - let reply = self - .pop_call_reply(deps.storage) - .map(|msg| rlp::encode(&msg).to_vec()); - - let (response, event) = match msg.result { - cosmwasm_std::SubMsgResult::Ok(_res) => { - let code = CallServiceResponseType::CallServiceResponseSuccess.into(); - let message_response = CSMessageResult::new( - request.sequence_no(), - CallServiceResponseType::CallServiceResponseSuccess, - reply, - ); - - let event = event_call_executed(req_id, code, "success"); - (message_response, event) - } - cosmwasm_std::SubMsgResult::Err(err) => { - let code = CallServiceResponseType::CallServiceResponseFailure; - let error_message = format!("CallService Reverted : {err}"); - let message_response = - CSMessageResult::new(request.sequence_no(), code.clone(), None); - let event = event_call_executed(req_id, code.into(), &error_message); - if request.allow_retry() { - return Err(ContractError::ReplyError { - code: msg.id, - msg: err, - }); - } - (message_response, event) - } - }; - let mut submsgs: Vec = vec![]; - let sn: i64 = -(request.sequence_no() as i64); - if request.need_response() { - let message: CSMessage = response.into(); - let mut reply_address = request.protocols().clone(); - let from = request.from().clone(); - if request.protocols().is_empty() { - let default_connection = self.get_default_connection(deps.storage, from.nid())?; - reply_address = vec![default_connection.to_string()]; - } - submsgs = reply_address - .iter() - .map(|to| { - self.call_connection_send_message( - &deps.api.addr_validate(to)?, - vec![], - from.nid(), - sn, - &message, - ) - }) - .collect::, ContractError>>()?; - } - - Ok(Response::new() - .add_submessages(submsgs) - .add_attribute("action", "call_message") - .add_attribute("method", "execute_callback") - .add_event(event)) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/execute_rollback.rs b/contracts/cosmwasm-vm/cw-xcall/src/execute_rollback.rs deleted file mode 100644 index 1c58461e..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/execute_rollback.rs +++ /dev/null @@ -1,64 +0,0 @@ -use cosmwasm_std::DepsMut; -use cosmwasm_std::MessageInfo; -use cosmwasm_std::ReplyOn; - -use cosmwasm_std::{Env, Response}; - -use crate::error::ContractError; -use crate::events::event_rollback_executed; -use crate::state::{CwCallService, EXECUTE_ROLLBACK_ID}; - -impl<'a> CwCallService<'a> { - /// This function executes a rollback operation for a previously made call request. - /// - /// Arguments: - /// - /// * `deps`: A mutable reference to the dependencies of the contract, which includes access to the - /// storage and other modules. - /// * `info`: `info` is a struct that contains information about the message sender, such as their - /// address and the amount of funds they are sending with the message. It is of type `MessageInfo`. - /// * `sequence_no`: The sequence number is a unique identifier assigned to each XCall request made - /// by the user. It is used to track the status of the request and to ensure that the correct request - /// is being executed or rolled back. - /// - /// Returns: - /// - /// a `Result` where `Response` is a struct representing the response to a - /// contract execution and `ContractError` is an enum representing possible errors that can occur - /// during contract execution. - pub fn execute_rollback( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - sequence_no: u128, - ) -> Result { - let call_request = self.get_call_request(deps.storage, sequence_no)?; - self.cleanup_request(deps.storage, sequence_no); - - self.ensure_call_request_not_null(sequence_no, &call_request) - .unwrap(); - self.ensure_rollback_enabled(call_request.enabled()) - .unwrap(); - let from = self.get_own_network_address(deps.as_ref().storage, &env)?; - - let mut sub_msg = self.call_dapp_handle_message( - info, - // the original caller is stored as from in call request - call_request.from().clone(), - from, - call_request.rollback().to_vec(), - call_request.protocols().clone(), - EXECUTE_ROLLBACK_ID, - )?; - sub_msg.reply_on = ReplyOn::Never; - - let event = event_rollback_executed(sequence_no); - - Ok(Response::new() - .add_attribute("action", "call_message") - .add_attribute("method", "execute_rollback") - .add_event(event) - .add_submessage(sub_msg)) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/fee_handler.rs b/contracts/cosmwasm-vm/cw-xcall/src/fee_handler.rs deleted file mode 100644 index ead419ff..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/fee_handler.rs +++ /dev/null @@ -1,100 +0,0 @@ -use super::*; - -impl<'a> CwCallService<'a> { - /// This function sets a fee handler address and sends any accrued fees to the new fee handler - /// address. - /// - /// Arguments: - /// - /// * `deps`: A mutable reference to the dependencies of the contract, which includes the storage - /// and the querier. - /// * `env`: The `env` parameter is of type `Env` and contains information about the current - /// blockchain environment, such as the block height and time. It is used in this function to get - /// the contract address and pass it to the `get_balance` function. - /// * `info`: `info` is a `MessageInfo` struct that contains information about the message being - /// executed, such as the sender's address, the amount of tokens sent with the message, and the gas - /// limit. - /// * `address`: The address of the fee handler that will receive protocol fees. - /// - /// Returns: - /// - /// a `Result` where `Response` is a struct representing the response to a - /// message and `ContractError` is an enum representing the possible errors that can occur during - /// contract execution. - pub fn set_protocol_feehandler( - &self, - deps: DepsMut, - info: &MessageInfo, - address: String, - ) -> Result { - self.ensure_admin(deps.storage, info.sender.clone())?; - deps.api.addr_validate(&address)?; - self.add_feehandler(deps.storage, &address)?; - Ok(Response::new().add_attribute("method", "set_protocol_feehandler")) - } - - /// This function retrieves the protocol fee handler address from storage. - /// - /// Arguments: - /// - /// * `deps`: `deps` is an object of type `Deps` which is a struct that contains various dependencies - /// required by the contract to interact with the blockchain. It includes the storage, API, and - /// querier objects. In this function, `deps` is used to access the storage object to query the fee - /// - /// Returns: - /// - /// A string representing the protocol fee handler. - pub fn get_protocol_feehandler(&self, deps: Deps) -> String { - self.query_feehandler(deps.storage).unwrap() - } -} - -impl<'a> CwCallService<'a> { - /// This function adds a fee handler address to the contract's storage. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. It is used to - /// interact with the contract's storage and persist data between contract executions. The `dyn` - /// keyword indicates that `Storage` is a dynamic trait object, meaning that it can be used to - /// interact with any - /// * `address`: The `address` parameter is a reference to a `String` that represents the Ethereum - /// address of the fee handler contract that needs to be added to the current contract. - /// - /// Returns: - /// - /// This function returns a `Result` object with either an `Ok(())` value indicating that the fee - /// handler was successfully added, or an `Err` value containing a `ContractError::Std` object if - /// there was an error while saving the fee handler to the storage. - fn add_feehandler( - &self, - store: &mut dyn Storage, - address: &String, - ) -> Result<(), ContractError> { - match self.fee_handler().save(store, address) { - Ok(_) => Ok(()), - Err(error) => Err(ContractError::Std(error)), - } - } - - /// This function queries the fee handler address from the storage and returns it as a string or an - /// error. - /// - /// Arguments: - /// - /// * `store`: `store` is a reference to a trait object of type `dyn Storage`. It is used to - /// interact with the contract's storage, which is a key-value store that persists data on the - /// blockchain. The `query_feehandler` function takes a reference to this object as an argument so - /// that it can - /// - /// Returns: - /// - /// A `Result` containing either the `String` address of the fee handler or a `ContractError` if - /// there was an error loading the address from the storage. - fn query_feehandler(&self, store: &dyn Storage) -> Result { - match self.fee_handler().load(store) { - Ok(address) => Ok(address), - Err(error) => Err(ContractError::Std(error)), - } - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/fees.rs b/contracts/cosmwasm-vm/cw-xcall/src/fees.rs deleted file mode 100644 index bdad658e..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/fees.rs +++ /dev/null @@ -1,77 +0,0 @@ -use cosmwasm_std::Coin; -use cw_xcall_lib::network_address::NetId; - -use super::*; -/// This is an implementation of two methods for the `CwCallService` struct. - -impl<'a> CwCallService<'a> { - /// The `set_protocol_fee` function sets the protocol fee and the `get_protocol_fee` function - /// retrieves the current protocol fee. - /// - /// Arguments: - /// - /// * `deps`: `deps` is a `DepsMut` or `Deps` object that provides access to the contract's - /// dependencies such as storage, API, and other modules. `DepsMut` is used when the function needs - /// to modify the state of the contract, while `Deps` is used - /// * `info`: MessageInfo is a struct that contains information about the message being executed, - /// such as the sender's address, the amount of coins being sent, and the gas limit. It is provided - /// by the Cosmos SDK to the contract's entry points. - /// * `value`: The `value` parameter in both functions represents the amount of protocol fee to be - /// set or retrieved. It is of type `u128`, which means it can hold a large unsigned integer value. - /// The protocol fee is a fee charged by the contract for executing certain operations or - /// transactions on the blockchain. - /// - /// Returns: - /// - /// The `set_protocol_fee` function returns a `Result` which contains a - /// `Response` object with an added attribute "method" set to "set_protocolfee". The - /// `get_protocol_fee` function returns a `u128` value which represents the current protocol fee. - pub fn set_protocol_fee( - &self, - deps: DepsMut, - info: MessageInfo, - value: u128, - ) -> Result { - self.ensure_admin(deps.storage, info.sender)?; - self.store_protocol_fee(deps.storage, value)?; - - Ok(Response::new().add_attribute("method", "set_protocolfee")) - } - - pub fn get_fee( - &self, - deps: Deps, - nid: NetId, - rollback: bool, - sources: Vec, - ) -> Result { - if !rollback && self.is_reply(deps, nid.clone(), &sources) { - return Ok(0_u128); - } - - let protocol_fee = self.get_protocol_fee(deps.storage); - let mut sources = sources; - if sources.is_empty() { - let conn = self.get_default_connection(deps.storage, nid.clone())?; - sources = vec![conn.to_string()]; - } - let conn_fees = sources - .into_iter() - .map(|s| self.query_connection_fee(deps, nid.clone(), rollback, &s)) - .collect::, ContractError>>()?; - let conn_total: u128 = conn_fees.iter().sum(); - - Ok(protocol_fee + conn_total) - } - - pub fn get_total_paid(&self, deps: Deps, coins: &Vec) -> Result { - let config = self.get_config(deps.storage)?; - let mut total = 0_u128; - for c in coins.iter() { - if c.denom == config.denom { - total += c.amount.u128(); - } - } - Ok(total) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/handle_call_message.rs b/contracts/cosmwasm-vm/cw-xcall/src/handle_call_message.rs deleted file mode 100644 index 0d8de537..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/handle_call_message.rs +++ /dev/null @@ -1,247 +0,0 @@ -use common::{rlp, utils::keccak256}; -use cw_xcall_lib::network_address::NetId; - -use super::*; - -impl<'a> CwCallService<'a> { - pub fn handle_message( - &self, - deps: DepsMut, - info: MessageInfo, - from_nid: NetId, - message: Vec, - ) -> Result { - let cfg = self.get_config(deps.storage).unwrap(); - if cfg.network_id == from_nid.to_string() { - return Err(ContractError::ProtocolsMismatch); - } - - let call_service_message: CSMessage = CSMessage::try_from(message)?; - match call_service_message.message_type() { - CSMessageType::CSMessageRequest => { - self.handle_request(deps, info, from_nid, call_service_message.payload()) - } - CSMessageType::CSMessageResult => { - self.handle_result(deps, info, call_service_message.payload()) - } - } - } - - pub fn handle_reply( - &self, - deps: DepsMut, - rollback: Rollback, - request: CSMessageRequest, - ) -> Result { - // reply can be targeted to source nid but any contract - if !(rollback.to().nid() == request.from().nid()) { - return Err(ContractError::InvalidReplyReceived); - } - let request_id = self.increment_last_request_id(deps.storage)?; - - let req = CSMessageRequest::new( - request.from().clone(), - request.to().clone(), - request.sequence_no(), - request.msg_type(), - keccak256(request.data().unwrap()).to_vec(), - rollback.protocols().clone(), - ); - self.store_proxy_request(deps.storage, request_id, &req)?; - - let event = event_call_message( - request.from().to_string(), - request.to().to_string(), - request.sequence_no(), - request_id, - request.data().unwrap().to_vec(), - ); - Ok(event) - } - - pub fn handle_request( - &self, - deps: DepsMut, - info: MessageInfo, - src_net: NetId, - data: &[u8], - ) -> Result { - let request: CSMessageRequest = rlp::decode(data).unwrap(); - - let from = request.from().clone(); - if from.nid() != src_net { - return Err(ContractError::ProtocolsMismatch); - } - let source = info.sender.to_string(); - let source_valid = - self.is_valid_source(deps.as_ref().storage, src_net, &source, request.protocols())?; - if !source_valid { - return Err(ContractError::ProtocolsMismatch); - } - - let to = deps.api.addr_validate(request.to().as_str())?; - - if request.protocols().len() > 1 { - let key = keccak256(data).to_vec(); - let caller = info.sender; - self.save_pending_requests(deps.storage, key.clone(), caller.to_string())?; - let registered = - self.get_pending_requests_by_hash(deps.as_ref().storage, key.clone())?; - - if registered.len() != request.protocols().len() { - return Ok(Response::new()); - } - - self.remove_pending_request_by_hash(deps.storage, key)?; - } - let request_id = self.increment_last_request_id(deps.storage)?; - - let req = CSMessageRequest::new( - request.from().clone(), - request.to().clone(), - request.sequence_no(), - request.msg_type(), - keccak256(request.data().unwrap()).to_vec(), - request.protocols().clone(), - ); - self.store_proxy_request(deps.storage, request_id, &req)?; - - let event = event_call_message( - from.to_string(), - to.to_string(), - request.sequence_no(), - request_id, - request.data().unwrap().to_vec(), - ); - - Ok(Response::new() - .add_attribute("action", "call_service") - .add_attribute("method", "handle_response") - .add_event(event)) - } - - pub fn handle_result( - &self, - deps: DepsMut, - info: MessageInfo, - data: &[u8], - ) -> Result { - let result: CSMessageResult = rlp::decode(data).unwrap(); - - let response_sequence_no = result.sequence_no(); - - let mut call_request = self - .get_call_request(deps.storage, response_sequence_no) - .map_err(|_e| ContractError::CallRequestNotFound { - sn: response_sequence_no, - })?; - - let source = info.sender.to_string(); - let source_valid = self.is_valid_source( - deps.as_ref().storage, - call_request.to().nid(), - &source, - call_request.protocols(), - )?; - if !source_valid { - return Err(ContractError::ProtocolsMismatch); - } - - if call_request.protocols().len() > 1 { - let key = keccak256(data).to_vec(); - let caller = info.sender; - self.save_pending_responses(deps.storage, key.clone(), caller.to_string())?; - let registered = - self.get_pending_responses_by_hash(deps.as_ref().storage, key.clone())?; - - if registered.len() != call_request.protocols().len() { - return Ok(Response::new()); - } - - self.remove_pending_responses_by_hash(deps.storage, key)?; - } - let response_event = event_response_message( - response_sequence_no, - (result.response_code().clone()).into(), - ); - - match result.response_code() { - CallServiceResponseType::CallServiceResponseSuccess => { - self.cleanup_request(deps.storage, response_sequence_no); - self.set_successful_response(deps.storage, response_sequence_no)?; - let mut res = Response::new() - .add_attribute("action", "call_service") - .add_attribute("method", "handle_response") - .add_event(response_event); - if result.get_message().is_some() { - let reply = result.get_message().unwrap(); - let event = self.handle_reply(deps, call_request, reply)?; - res = res.add_event(event); - } - - Ok(res) - } - _ => { - self.ensure_rollback_length(call_request.rollback()) - .unwrap(); - call_request.set_enabled(); - self.store_call_request(deps.storage, response_sequence_no, &call_request)?; - - let rollback_event = event_rollback_message(response_sequence_no); - - Ok(Response::new() - .add_attribute("action", "call_service") - .add_attribute("method", "handle_response") - .add_event(response_event) - .add_event(rollback_event)) - } - } - } - - /// The function removes a call request from storage based on a given sequence number. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. This means - /// that the function can accept any object that implements the `Storage` trait. The `Storage` trait - /// defines methods for storing and retrieving data in a persistent storage, such as a database or a - /// file system. - /// * `sequence_no`: `sequence_no` is an unsigned 128-bit integer that represents the sequence - /// number of a call request that needs to be cleaned up. It is used as an identifier to locate and - /// remove the corresponding call request from the storage. - pub fn cleanup_request(&self, store: &mut dyn Storage, sequence_no: u128) { - self.remove_call_request(store, sequence_no); - } - - pub fn is_valid_source( - &self, - store: &dyn Storage, - src_net: NetId, - source: &String, - protocols: &Vec, - ) -> Result { - if protocols.contains(source) { - return Ok(true); - } - if protocols.is_empty() { - let default_conn = self.get_default_connection(store, src_net)?; - Ok(source.clone() == default_conn) - } else { - Ok(false) - } - } - - pub fn handle_error( - &self, - deps: DepsMut, - info: MessageInfo, - sn: u128, - ) -> Result { - let msg = CSMessageResult::new( - sn, - CallServiceResponseType::CallServiceResponseFailure, - None, - ); - self.handle_result(deps, info, &rlp::encode(&msg)) - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/lib.rs b/contracts/cosmwasm-vm/cw-xcall/src/lib.rs deleted file mode 100644 index 6501fe6a..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/lib.rs +++ /dev/null @@ -1,173 +0,0 @@ -pub mod admin; -pub mod assertion; -pub mod connection; -pub mod contract; -pub mod dapp; -pub mod error; -pub mod events; -pub mod execute_call; -pub mod execute_rollback; -pub mod fee_handler; -pub mod fees; -pub mod handle_call_message; -pub mod msg; -pub mod requests; -pub mod send_call_message; -pub mod state; -pub mod types; - -use crate::{ - error::ContractError, - events::{ - event_call_message, event_response_message, event_rollback_message, - event_xcall_message_sent, - }, - msg::{InstantiateMsg, QueryMsg}, - state::{CwCallService, EXECUTE_CALL_ID}, - types::{ - message::{CSMessage, CSMessageType}, - request::CSMessageRequest, - result::{CSMessageResult, CallServiceResponseType}, - rollback::Rollback, - storage_keys::StorageKey, - }, -}; - -use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{ - ensure, ensure_eq, entry_point, to_json_binary, Addr, Api, Binary, Deps, DepsMut, Env, Event, - MessageInfo, QuerierWrapper, Reply, Response, StdError, StdResult, Storage, SubMsg, -}; - -use cw2::set_contract_version; -use cw_storage_plus::{Item, Map}; -use cw_xcall_lib::xcall_msg::ExecuteMsg; - -use serde::Serialize; -use thiserror::Error; - -/// This function instantiates a contract using the CwCallService. -/// -/// Arguments: -/// -/// * `deps`: `deps` is a `DepsMut` object, which is a mutable reference to the dependencies of the -/// contract. Dependencies include the storage, API, and other modules that the contract may need to -/// interact with. The `DepsMut` object allows the contract to modify the state of the dependencies -/// * `env`: `env` is a struct that contains information about the current blockchain environment, such -/// as the block height, time, and chain ID. It is passed as a parameter to the `instantiate` function -/// in order to provide the contract with access to this information. The `env` parameter is of type -/// * `info`: `info` is a struct that contains information about the message sender, such as their -/// address, the amount of tokens they sent with the message, and any other metadata included in the -/// message. This information can be used to determine whether the sender is authorized to perform -/// certain actions and to handle the tokens sent -/// * `msg`: `msg` is a parameter of type `InstantiateMsg` which contains the data sent by the user -/// during contract instantiation. It is used to initialize the state of the contract. The fields of -/// `InstantiateMsg` are defined by the developer and can vary depending on the requirements of the -/// contract. -/// -/// Returns: -/// -/// The `instantiate` function returns a `Result` which represents either a -/// successful response or an error. -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - let call_service = CwCallService::default(); - - call_service.instantiate(deps, env, info, msg) -} - -/// This is a Rust function that executes a message and returns a response, using a call service. -/// -/// Arguments: -/// -/// * `deps`: `deps` is a `DepsMut` object that provides access to the dependencies of the contract, -/// such as the storage, API, and querier. -/// * `env`: `env` is an object that contains information about the current blockchain environment, such -/// as the block height, time, and chain ID. It also includes information about the current transaction, -/// such as the sender and recipient addresses, the amount of tokens being transferred, and the gas -/// limit and price. This information -/// * `info`: `info` is a struct that contains information about the sender of the message, such as -/// their address, the amount of tokens they sent with the message, and any other metadata that was -/// included. This information can be used to determine whether the sender is authorized to perform -/// certain actions, and to track the -/// * `msg`: `msg` is a parameter of type `ExecuteMsg` which represents the message sent to the contract -/// for execution. It contains the necessary information and data required to execute the desired action -/// on the contract. The specific fields and data contained within `ExecuteMsg` will depend on the -/// specific implementation of the contract -/// -/// Returns: -/// -/// The `execute` function returns a `Result`. -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let mut call_service = CwCallService::default(); - - call_service.execute(deps, env, info, msg) -} - -/// This function calls a service to query data using the given dependencies, environment, and message. -/// -/// Arguments: -/// -/// * `deps`: `deps` is an instance of the `Deps` struct, which provides access to the dependencies of -/// the contract, such as the storage, API, and other modules. -/// * `env`: `env` is an object that contains information about the current blockchain environment, such -/// as the block height, time, and chain ID. -/// * `msg`: The `msg` parameter in the `query` function is of type `QueryMsg`, which is an enum that -/// defines all the possible query messages that can be sent to the smart contract. The `msg` parameter -/// represents the specific query message that is being sent to the smart contract. The `query -/// -/// Returns: -/// -/// a `StdResult` which is a type alias for `Result`. The `Binary` type -/// represents a binary data and `StdError` is a standard error type used in CosmWasm. -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { - let call_service = CwCallService::default(); - - call_service.query(deps, env, msg) -} - -/// This function handles a reply message in a Rust smart contract. -/// -/// Arguments: -/// -/// * `deps`: `deps` is a mutable reference to the dependencies of the contract. It allows the contract -/// to access the necessary modules and traits to interact with the blockchain and its state. -/// * `env`: `env` is an object that contains information about the current blockchain environment, such -/// as the block height, time, and chain ID. It is provided by the Cosmos SDK and is used to interact -/// with the blockchain. -/// * `msg`: The `msg` parameter in the `reply` function is of type `Reply`. It represents the reply -/// message sent by an external contract in response to a previous message sent by the current contract. -/// The `Reply` struct contains the following fields: -/// -/// Returns: -/// -/// a `Result` where `Response` and `ContractError` are types defined in the -/// contract's codebase. The `Result` type indicates that the function can either return a successful -/// `Response` or an error of type `ContractError`. -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result { - let call_service = CwCallService::default(); - - call_service.reply(deps, env, msg) -} - -#[cw_serde] -pub struct MigrateMsg {} -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> Result { - let call_service = CwCallService::default(); - - call_service.migrate(deps, env, msg) -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/msg.rs b/contracts/cosmwasm-vm/cw-xcall/src/msg.rs deleted file mode 100644 index 2ceee556..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/msg.rs +++ /dev/null @@ -1,36 +0,0 @@ -use cw_xcall_lib::network_address::NetId; - -use super::*; -#[cw_serde] -pub struct InstantiateMsg { - pub network_id: String, - pub denom: String, -} - -/// The `#[cw_serde]` attribute is used to automatically generate serialization and deserialization code -/// for the struct or enum it is applied to. -#[cw_serde] -#[derive(QueryResponses)] -/// This is a Rust enum representing different types of queries that can be made to the contract. Each -/// variant of the enum corresponds to a specific query and has a return type specified using the -/// `#[returns]` attribute. -pub enum QueryMsg { - #[returns(String)] - GetAdmin {}, - #[returns(u128)] - GetProtocolFee {}, - #[returns(String)] - GetProtocolFeeHandler {}, - #[returns(String)] - GetNetworkAddress {}, - #[returns(bool)] - VerifySuccess { sn: u128 }, - #[returns(String)] - GetDefaultConnection { nid: NetId }, - #[returns(u128)] - GetFee { - nid: NetId, - rollback: bool, - sources: Option>, - }, -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/requests.rs b/contracts/cosmwasm-vm/cw-xcall/src/requests.rs deleted file mode 100644 index 7bf1578f..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/requests.rs +++ /dev/null @@ -1,203 +0,0 @@ -use super::*; - -impl<'a> CwCallService<'a> { - /// This function queries and returns the last sequence number stored in a given storage. - /// - /// Arguments: - /// - /// * `store`: `store` is a reference to a trait object of type `dyn Storage`. This is an abstract - /// type that represents a key-value store where data can be persisted. In the context of smart - /// contract development on the CosmWasm platform, `store` is typically provided by the runtime - /// environment. - /// - /// Returns: - /// - /// a `Result` containing a `u128` value or a `ContractError` if an error occurs. The `u128` value - /// represents the last sequence number stored in the contract's storage. - pub fn query_last_sequence_no(&self, store: &dyn Storage) -> Result { - let last_sequence = self.get_current_sn(store)?; - - Ok(last_sequence) - } - - /// The function increments the last sequence number stored in a contract's storage and returns the - /// updated value. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. This is used - /// to interact with the contract's storage and persist data between contract executions. The - /// `increment_last_sequence_no` function updates the value of the last sequence number stored in - /// the contract's storage by incrementing it - /// - /// Returns: - /// - /// a `Result` containing an unsigned 128-bit integer (`u128`) or a `ContractError` if an error - /// occurs. - pub fn increment_last_sequence_no( - &self, - store: &mut dyn Storage, - ) -> Result { - self.get_next_sn(store) - } - - /// This function sets the last sequence number in a storage and returns the updated value. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. This is used - /// to interact with the contract's storage and persist data between contract executions. The `dyn` - /// keyword indicates that the type of the object implementing the `Storage` trait is not known at - /// compile time and will - /// * `sequence`: The `sequence` parameter is an unsigned 128-bit integer representing the last - /// sequence number to be set. This function updates the last sequence number stored in the - /// contract's storage with the provided value. - /// - /// Returns: - /// - /// a `Result` containing a `u128` value or a `ContractError` if an error occurs. - pub fn set_last_sequence_no( - &self, - store: &mut dyn Storage, - sequence: u128, - ) -> Result { - let req_id = self - .sn() - .update(store, |mut seq| -> Result<_, ContractError> { - seq.clone_from(&sequence); - Ok(seq) - })?; - - Ok(req_id) - } - - /// This function queries the last request ID from a storage and returns it as a result. - /// - /// Arguments: - /// - /// * `store`: `store` is a reference to a trait object of type `dyn Storage`. It is used to interact - /// with the contract's storage and retrieve the value of the `last_request_id` variable. The `load` - /// method is called on `last_request_id()` to retrieve the value from storage. - /// - /// Returns: - /// - /// a `Result` containing either a `u128` value representing the last request ID or a `ContractError` if - /// there was an error while loading the last request ID from the storage. - pub fn query_last_request_id(&self, store: &dyn Storage) -> Result { - let last_req_id = self.last_request_id().load(store)?; - - Ok(last_req_id) - } - - /// The function increments the last request ID stored in a storage object and returns the updated - /// ID. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. It is used to - /// interact with the contract's storage and persist data between contract invocations. The - /// `increment_last_request_id` function updates the value of the last request ID stored in the - /// contract's storage by incrementing - /// - /// Returns: - /// - /// a `Result` containing an unsigned 128-bit integer (`u128`) or a `ContractError` if an error - /// occurs during the execution of the function. - pub fn increment_last_request_id( - &self, - store: &mut dyn Storage, - ) -> Result { - let req_id = - self.last_request_id() - .update(store, |mut req_id| -> Result<_, ContractError> { - req_id += 1; - - Ok(req_id) - })?; - - Ok(req_id) - } - - /// This function sets the last request ID and returns the updated ID. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. This is used - /// to interact with the contract's storage and persist data between contract executions. The - /// `Storage` trait defines methods for reading and writing data to the contract's storage. - /// * `request_id`: The `request_id` parameter is a 128-bit unsigned integer that represents the ID - /// of the last request made to the contract. This function sets the value of the last request ID to - /// the provided `request_id` value. - /// - /// Returns: - /// - /// a `Result` containing a `u128` value or a `ContractError` if an error occurs. - pub fn set_last_request_id( - &self, - store: &mut dyn Storage, - request_id: u128, - ) -> Result { - let req_id = - self.last_request_id() - .update(store, |mut req_id| -> Result<_, ContractError> { - req_id.clone_from(&request_id); - Ok(req_id) - })?; - - Ok(req_id) - } - - /// This function initializes the last sequence number in a storage and returns an error if it - /// fails. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. It is used to - /// interact with the contract's storage and persist data between contract executions. - /// * `sequence_no`: `sequence_no` is an unsigned 128-bit integer representing the last sequence - /// number used in a transaction. This function initializes the last sequence number to the provided - /// value in the storage of the smart contract. - /// - /// Returns: - /// - /// This function returns a `Result` type with either an `Ok(())` value indicating that the - /// `sequence_no` was successfully saved to the storage, or an `Err` value with a - /// `ContractError::Std` variant indicating that an error occurred while saving the `sequence_no`. - pub fn init_last_sequence_no( - &self, - store: &mut dyn Storage, - sequence_no: u128, - ) -> Result<(), ContractError> { - match self.sn().save(store, &sequence_no) { - Ok(_) => Ok(()), - Err(error) => Err(ContractError::Std(error)), - } - } - - /// This function initializes the last request ID in a storage and returns an error if it fails. - /// - /// Arguments: - /// - /// * `store`: `store` is a mutable reference to a trait object of type `dyn Storage`. It is used to - /// interact with the storage of the smart contract. The `Storage` trait defines methods for reading - /// and writing data to the contract's storage. - /// * `request_id`: `request_id` is a 128-bit unsigned integer that represents the unique identifier - /// of a request. This function takes this `request_id` as an input parameter and saves it to the - /// contract's storage using the `save` method of the `last_request_id` field. The `store` parameter - /// - /// Returns: - /// - /// This function returns a `Result` object with either `Ok(())` if the `request_id` was - /// successfully saved in the storage, or `Err(ContractError::Std(error))` if there was an error - /// while saving the `request_id`. - pub fn init_last_request_id( - &self, - store: &mut dyn Storage, - request_id: u128, - ) -> Result<(), ContractError> { - match self.last_request_id().save(store, &request_id) { - Ok(_) => Ok(()), - Err(error) => Err(ContractError::Std(error)), - } - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/send_call_message.rs b/contracts/cosmwasm-vm/cw-xcall/src/send_call_message.rs deleted file mode 100644 index cbcb6ad7..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/send_call_message.rs +++ /dev/null @@ -1,192 +0,0 @@ -use cosmwasm_std::{coins, BankMsg}; -use cw_xcall_lib::message::call_message::CallMessage; -use cw_xcall_lib::message::msg_trait::IMessage; - -use cw_xcall_lib::message::AnyMessage; -use cw_xcall_lib::message::{call_message_rollback::CallMessageWithRollback, envelope::Envelope}; -use cw_xcall_lib::network_address::{NetId, NetworkAddress}; - -use crate::{assertion::is_contract, types::LOG_PREFIX}; - -use super::*; - -impl<'a> CwCallService<'a> { - pub fn send_call_message( - &self, - deps: DepsMut, - info: MessageInfo, - _env: Env, - to: NetworkAddress, - data: Vec, - rollback: Option>, - sources: Vec, - destinations: Vec, - ) -> Result { - let msg = if rollback.is_some() { - AnyMessage::CallMessageWithRollback(CallMessageWithRollback { - data, - rollback: rollback.unwrap(), - }) - } else { - AnyMessage::CallMessage(CallMessage { data }) - }; - let envelope = Envelope::new(msg, sources, destinations); - self.send_call(deps, info, to, envelope) - } - - pub fn validate_payload( - &self, - deps: Deps, - caller: &Addr, - envelope: &Envelope, - ) -> Result<(), ContractError> { - match &envelope.message { - AnyMessage::CallMessage(_m) => Ok(()), - AnyMessage::CallMessageWithRollback(m) => { - if !is_contract(deps.querier, caller) { - return Err(ContractError::RollbackNotPossible); - } - self.ensure_rollback_length(&m.rollback().unwrap())?; - Ok(()) - } - AnyMessage::CallMessagePersisted(_) => Ok(()), - } - } - - pub fn send_call( - &self, - deps: DepsMut, - info: MessageInfo, - to: NetworkAddress, - envelope: Envelope, - ) -> Result { - let caller = info.sender.clone(); - let config = self.get_config(deps.as_ref().storage)?; - let nid = config.network_id; - self.validate_payload(deps.as_ref(), &caller, &envelope)?; - - let sequence_no = self.get_next_sn(deps.storage)?; - - let from = NetworkAddress::new(&nid, caller.as_ref()); - - if envelope.message.rollback().is_some() { - let rollback_data = envelope.message.rollback().unwrap(); - let request = Rollback::new( - caller.clone(), - to.clone(), - envelope.sources.clone(), - rollback_data, - false, - ); - - self.store_call_request(deps.storage, sequence_no, &request)?; - } - let call_request = CSMessageRequest::new( - from, - to.account(), - sequence_no, - envelope.message.msg_type().clone(), - envelope.message.data(), - envelope.destinations, - ); - let need_response = call_request.need_response(); - - let event = event_xcall_message_sent(caller.to_string(), to.to_string(), sequence_no); - // if contract is in reply state - if envelope.message.rollback().is_none() - && self.is_reply(deps.as_ref(), to.nid(), &envelope.sources) - { - self.save_call_reply(deps.storage, &call_request)?; - let res = self.send_call_response(event, sequence_no); - return Ok(res); - } - - let mut confirmed_sources = envelope.sources; - if confirmed_sources.is_empty() { - let default = self.get_default_connection(deps.as_ref().storage, to.nid())?; - confirmed_sources = vec![default.to_string()] - } - let message: CSMessage = call_request.into(); - let sn: i64 = if need_response { sequence_no as i64 } else { 0 }; - let mut total_spent = 0_u128; - - let submessages = confirmed_sources - .iter() - .map(|r| { - return self - .query_connection_fee(deps.as_ref(), to.nid(), need_response, r) - .and_then(|fee| { - let fund = if fee > 0 { - total_spent = total_spent.checked_add(fee).unwrap(); - coins(fee, config.denom.clone()) - } else { - vec![] - }; - let address = deps.api.addr_validate(r)?; - - self.call_connection_send_message(&address, fund, to.nid(), sn, &message) - }); - }) - .collect::, ContractError>>()?; - - let total_paid = self.get_total_paid(deps.as_ref(), &info.funds)?; - let fee_handler = self.fee_handler().load(deps.storage)?; - let protocol_fee = self.get_protocol_fee(deps.as_ref().storage); - let total_fee_required = protocol_fee + total_spent; - - if total_paid < total_fee_required { - return Err(ContractError::InsufficientFunds); - } - let remaining = total_paid - total_spent; - - println!("{LOG_PREFIX} Sent Bank Message"); - let mut res = self - .send_call_response(event, sequence_no) - .add_submessages(submessages); - - if remaining > 0 { - let msg = BankMsg::Send { - to_address: fee_handler, - amount: coins(remaining, config.denom), - }; - res = res.add_message(msg); - } - - Ok(res) - } - - fn send_call_response(&self, event: Event, sequence_no: u128) -> Response { - Response::new() - .add_attribute("action", "xcall-service") - .add_attribute("method", "send_packet") - .add_attribute("sequence_no", sequence_no.to_string()) - .add_event(event) - } - - pub fn is_reply(&self, deps: Deps, to: NetId, sources: &Vec) -> bool { - if self.get_call_reply(deps.storage).is_some() { - return false; - } - - if let Ok(reqid) = self.get_execute_request_id(deps.storage) { - let request = self.get_proxy_request(deps.storage, reqid).unwrap(); - if request.from().nid() != to { - return false; - } - return self.are_equal(request.protocols(), sources); - } - false - } - - fn are_equal(&self, protocols: &Vec, sources: &Vec) -> bool { - if protocols.len() != sources.len() { - return false; - } - for protocol in protocols.iter() { - if !sources.contains(protocol) { - return false; - } - } - true - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/state.rs b/contracts/cosmwasm-vm/cw-xcall/src/state.rs deleted file mode 100644 index 757b7ce0..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/state.rs +++ /dev/null @@ -1,394 +0,0 @@ -use cosmwasm_std::{from_json, to_json_vec, Order}; -use cw_storage_plus::{KeyDeserialize, PrimaryKey}; -use cw_xcall_lib::network_address::NetId; -use serde::de::DeserializeOwned; - -use crate::types::config::Config; - -use super::*; - -/// These are constants defined in the `CwCallService` struct that are used throughout the codebase. -pub const MAX_DATA_SIZE: u64 = 2048; -pub const MAX_ROLLBACK_SIZE: u64 = 1024; -pub const EXECUTE_CALL_ID: u64 = 0; -pub const EXECUTE_ROLLBACK_ID: u64 = 1; -pub const SEND_CALL_MESSAGE_REPLY_ID: u64 = 2; - -pub struct CwCallService<'a> { - sn: Item<'a, u128>, - config: Item<'a, Config>, - last_request_id: Item<'a, u128>, - admin: Item<'a, Addr>, - proxy_request: Map<'a, u128, CSMessageRequest>, - call_requests: Map<'a, u128, Rollback>, - fee_handler: Item<'a, String>, - protocol_fee: Item<'a, u128>, - default_connections: Map<'a, NetId, Addr>, - pending_requests: Map<'a, (Vec, String), bool>, - pending_responses: Map<'a, (Vec, String), bool>, - successful_responses: Map<'a, u128, bool>, - callback_data: Map<'a, u64, Vec>, - call_reply: Item<'a, CSMessageRequest>, -} - -impl<'a> Default for CwCallService<'a> { - fn default() -> Self { - Self::new() - } -} - -impl<'a> CwCallService<'a> { - pub fn new() -> Self { - Self { - sn: Item::new(StorageKey::Sn.as_str()), - last_request_id: Item::new(StorageKey::RequestNo.as_str()), - admin: Item::new(StorageKey::Admin.as_str()), - proxy_request: Map::new(StorageKey::MessageRequest.as_str()), - call_requests: Map::new(StorageKey::Requests.as_str()), - fee_handler: Item::new(StorageKey::FeeHandler.as_str()), - protocol_fee: Item::new(StorageKey::ProtocolFee.as_str()), - default_connections: Map::new(StorageKey::DefaultConnections.as_str()), - pending_requests: Map::new(StorageKey::PendingRequests.as_str()), - pending_responses: Map::new(StorageKey::PendingResponses.as_str()), - successful_responses: Map::new(StorageKey::SuccessfulResponses.as_str()), - config: Item::new(StorageKey::Config.as_str()), - callback_data: Map::new(StorageKey::Callbackdata.as_str()), - call_reply: Item::new(StorageKey::CallReply.as_str()), - } - } - - pub fn get_next_sn(&self, store: &mut dyn Storage) -> Result { - let mut sn = self.sn.load(store).unwrap_or(0); - sn += 1; - self.sn.save(store, &sn)?; - Ok(sn) - } - - pub fn get_current_sn(&self, store: &dyn Storage) -> Result { - self.sn.load(store).map_err(ContractError::Std) - } - - pub fn sn(&self) -> &Item<'a, u128> { - &self.sn - } - - pub fn get_config(&self, store: &dyn Storage) -> Result { - self.config.load(store).map_err(ContractError::Std) - } - - pub fn store_config( - &self, - store: &mut dyn Storage, - config: &Config, - ) -> Result<(), ContractError> { - self.config.save(store, config).map_err(ContractError::Std) - } - - pub fn last_request_id(&self) -> &Item<'a, u128> { - &self.last_request_id - } - - pub fn store_execute_request_id( - &self, - store: &mut dyn Storage, - req_id: u128, - ) -> Result<(), ContractError> { - self.store_callback_data(store, EXECUTE_CALL_ID, &req_id) - } - pub fn remove_execute_request_id(&self, store: &mut dyn Storage) { - self.clear_callback_data(store, EXECUTE_CALL_ID) - } - - pub fn get_execute_request_id(&self, store: &dyn Storage) -> Result { - self.get_callback_data(store, EXECUTE_CALL_ID) - } - - pub fn admin(&self) -> &Item<'a, Addr> { - &self.admin - } - - pub fn get_proxy_request( - &self, - store: &dyn Storage, - id: u128, - ) -> Result { - self.proxy_request - .load(store, id) - .map_err(ContractError::Std) - } - - pub fn store_proxy_request( - &self, - store: &mut dyn Storage, - id: u128, - request: &CSMessageRequest, - ) -> Result<(), ContractError> { - self.proxy_request - .save(store, id, request) - .map_err(ContractError::Std) - } - - pub fn remove_proxy_request(&self, store: &mut dyn Storage, id: u128) { - self.proxy_request.remove(store, id) - } - - pub fn contains_proxy_request( - &self, - store: &dyn Storage, - request_id: u128, - ) -> Result<(), ContractError> { - match self.proxy_request.has(store, request_id) { - true => Ok(()), - false => Err(ContractError::InvalidRequestId { id: request_id }), - } - } - - pub fn get_call_request( - &self, - store: &dyn Storage, - id: u128, - ) -> Result { - self.call_requests - .load(store, id) - .map_err(ContractError::Std) - } - - pub fn remove_call_request(&self, store: &mut dyn Storage, id: u128) { - self.call_requests.remove(store, id) - } - - pub fn store_call_request( - &self, - store: &mut dyn Storage, - id: u128, - request: &Rollback, - ) -> Result<(), ContractError> { - self.call_requests - .save(store, id, request) - .map_err(ContractError::Std) - } - - pub fn fee_handler(&self) -> &Item<'a, String> { - &self.fee_handler - } - - pub fn store_default_connection( - &self, - store: &mut dyn Storage, - nid: NetId, - address: Addr, - ) -> Result<(), ContractError> { - self.default_connections - .save(store, nid, &address) - .map_err(ContractError::Std) - } - pub fn get_default_connection( - &self, - store: &dyn Storage, - nid: NetId, - ) -> Result { - self.default_connections - .load(store, nid) - .map_err(ContractError::Std) - } - - pub fn get_pending_requests_by_hash( - &self, - store: &dyn Storage, - hash: Vec, - ) -> Result, ContractError> { - self.get_by_prefix(store, &self.pending_requests, hash) - } - - pub fn remove_pending_request_by_hash( - &self, - store: &mut dyn Storage, - hash: Vec, - ) -> Result<(), ContractError> { - self.remove_by_prefix(store, &self.pending_requests, hash) - } - - pub fn save_pending_requests( - &self, - store: &mut dyn Storage, - hash: Vec, - caller: String, - ) -> Result<(), ContractError> { - self.pending_requests - .save(store, (hash, caller), &true) - .map_err(ContractError::Std) - } - - pub fn get_pending_responses_by_hash( - &self, - store: &dyn Storage, - hash: Vec, - ) -> Result, ContractError> { - self.get_by_prefix(store, &self.pending_responses, hash) - } - - pub fn remove_pending_responses_by_hash( - &self, - store: &mut dyn Storage, - hash: Vec, - ) -> Result<(), ContractError> { - self.remove_by_prefix(store, &self.pending_responses, hash) - } - - pub fn save_pending_responses( - &self, - store: &mut dyn Storage, - hash: Vec, - caller: String, - ) -> Result<(), ContractError> { - self.pending_responses - .save(store, (hash, caller), &true) - .map_err(ContractError::Std) - } - - pub fn get_all_connections(&self, store: &dyn Storage) -> Result, ContractError> { - let res = self.get_all_values::(store, &self.default_connections)?; - let addresses: Vec = res.into_iter().map(|a| a.to_string()).collect(); - Ok(addresses) - } - - fn get_by_prefix( - &self, - store: &dyn Storage, - map: &Map<(Vec, String), bool>, - hash: Vec, - ) -> Result, ContractError> { - let requests: StdResult> = map - .prefix(hash) - .range(store, None, None, cosmwasm_std::Order::Ascending) - .collect(); - requests.map_err(ContractError::Std) - } - - fn remove_by_prefix( - &self, - store: &mut dyn Storage, - map: &Map<(Vec, String), bool>, - hash: Vec, - ) -> Result<(), ContractError> { - let keys: StdResult> = map - .prefix(hash.clone()) - .keys(store, None, None, cosmwasm_std::Order::Ascending) - .collect(); - let keys = keys.map_err(ContractError::Std)?; - for key in keys { - self.pending_requests.remove(store, (hash.clone(), key)) - } - Ok(()) - } - - fn get_all_values + Clone + KeyDeserialize, V: DeserializeOwned + Serialize>( - &self, - store: &dyn Storage, - map: &Map<'a, K, V>, - ) -> Result, ContractError> - where - K::Output: 'static, - { - let values = map - .range(store, None, None, Order::Ascending) - .map(|r| r.map(|v| v.1)) - .collect::, StdError>>(); - values.map_err(ContractError::Std) - } - - pub fn get_protocol_fee(&self, store: &dyn Storage) -> u128 { - self.protocol_fee.load(store).unwrap_or(0) - } - pub fn store_protocol_fee( - &self, - store: &mut dyn Storage, - fee: u128, - ) -> Result<(), ContractError> { - self.protocol_fee - .save(store, &fee) - .map_err(ContractError::Std) - } - - pub fn store_protocol_fee_handler( - &self, - store: &mut dyn Storage, - handler: String, - ) -> Result<(), ContractError> { - self.fee_handler - .save(store, &handler) - .map_err(ContractError::Std) - } - - pub fn get_successful_response(&self, store: &dyn Storage, sn: u128) -> bool { - self.successful_responses.load(store, sn).unwrap_or(false) - } - - pub fn set_successful_response( - &self, - store: &mut dyn Storage, - sn: u128, - ) -> Result<(), ContractError> { - self.successful_responses - .save(store, sn, &true) - .map_err(ContractError::Std) - } - - pub fn store_callback_data( - &self, - store: &mut dyn Storage, - id: u64, - data: &T, - ) -> Result<(), ContractError> - where - T: DeserializeOwned + Serialize + ?Sized, - { - if self.has_callback_data(store, id) { - return Err(ContractError::CallAlreadyInProgress); - } - - let bytes = to_json_vec(data).map_err(ContractError::Std)?; - self.callback_data - .save(store, id, &bytes) - .map_err(ContractError::Std) - } - - pub fn has_callback_data(&self, store: &dyn Storage, id: u64) -> bool { - self.callback_data.load(store, id).is_ok() - } - - pub fn clear_callback_data(&self, store: &mut dyn Storage, id: u64) { - self.callback_data.remove(store, id) - } - - pub fn get_callback_data( - &self, - store: &dyn Storage, - id: u64, - ) -> Result { - let bytes = self - .callback_data - .load(store, id) - .map_err(ContractError::Std)?; - let data = from_json::(&bytes).map_err(ContractError::Std)?; - Ok(data) - } - - pub fn get_call_reply(&self, store: &dyn Storage) -> Option { - self.call_reply.load(store).ok() - } - - pub fn save_call_reply( - &self, - store: &mut dyn Storage, - msg: &CSMessageRequest, - ) -> Result<(), ContractError> { - self.call_reply.save(store, msg).map_err(ContractError::Std) - } - - pub fn pop_call_reply(&self, store: &mut dyn Storage) -> Option { - let reply = self.get_call_reply(store); - self.call_reply.remove(store); - reply - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/types/config.rs b/contracts/cosmwasm-vm/cw-xcall/src/types/config.rs deleted file mode 100644 index 74d3d6a0..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/types/config.rs +++ /dev/null @@ -1,7 +0,0 @@ -use cosmwasm_schema::cw_serde; - -#[cw_serde] -pub struct Config { - pub network_id: String, - pub denom: String, -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/types/message.rs b/contracts/cosmwasm-vm/cw-xcall/src/types/message.rs deleted file mode 100644 index 112e6137..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/types/message.rs +++ /dev/null @@ -1,135 +0,0 @@ -use super::*; - -#[cw_serde] -pub enum CSMessageType { - CSMessageRequest = 1, - CSMessageResult, -} - -#[cw_serde] -pub struct CSMessage { - pub message_type: CSMessageType, - pub payload: Vec, -} - -impl CSMessage { - pub fn new(message_type: CSMessageType, payload: Vec) -> Self { - Self { - message_type, - payload: payload.to_vec(), - } - } - - pub fn message_type(&self) -> &CSMessageType { - &self.message_type - } - pub fn payload(&self) -> &[u8] { - &self.payload - } - - pub fn as_bytes(&self) -> Vec { - rlp::encode(&self.clone()).to_vec() - } -} - -impl Encodable for CSMessage { - fn rlp_append(&self, stream: &mut rlp::RlpStream) { - let msg_type: u8 = match self.message_type { - CSMessageType::CSMessageRequest => 1, - CSMessageType::CSMessageResult => 2, - }; - stream.begin_list(2).append(&msg_type).append(&self.payload); - } -} - -impl Decodable for CSMessage { - fn decode(rlp: &rlp::Rlp) -> Result { - let msg_type: u8 = rlp.val_at(0)?; - - Ok(Self { - message_type: match msg_type { - 1 => Ok(CSMessageType::CSMessageRequest), - 2 => Ok(CSMessageType::CSMessageResult), - _ => Err(rlp::DecoderError::Custom("Invalid type")), - }?, - payload: rlp.val_at(1)?, - }) - } -} - -impl From for CSMessage { - fn from(value: CSMessageRequest) -> Self { - Self { - message_type: CSMessageType::CSMessageRequest, - payload: rlp::encode(&value).to_vec(), - } - } -} - -impl From for CSMessage { - fn from(value: CSMessageResult) -> Self { - Self { - message_type: CSMessageType::CSMessageResult, - payload: rlp::encode(&value).to_vec(), - } - } -} - -impl TryFrom for CSMessage { - type Error = ContractError; - - fn try_from(value: Binary) -> Result { - let rlp = rlp::Rlp::new(&value); - Self::decode(&rlp).map_err(|error| ContractError::DecodeFailed { - error: error.to_string(), - }) - } -} - -impl TryFrom> for CSMessage { - type Error = ContractError; - - fn try_from(value: Vec) -> Result { - let rlp = rlp::Rlp::new(&value); - Self::decode(&rlp).map_err(|error| ContractError::DecodeFailed { - error: error.to_string(), - }) - } -} - -impl From for Binary { - fn from(value: CSMessage) -> Self { - Binary(rlp::encode(&value).to_vec()) - } -} - -#[cfg(test)] -mod tests { - use common::rlp; - - use super::CSMessage; - /** - * CSMessage - type: CSMessage.REQUEST - data: 7465737431 - RLP: C701857465737431 - - CSMessage - type: CSMessage.RESPONSE - data: 7465737431 - RLP: C702857465737431 - */ - - #[test] - fn test_csmessage_encoding() { - let data = hex::decode("7465737431").unwrap(); - let message = CSMessage::new(super::CSMessageType::CSMessageRequest, data.clone()); - let encoded = rlp::encode(&message); - - assert_eq!("c701857465737431", hex::encode(encoded)); - - let message = CSMessage::new(crate::types::message::CSMessageType::CSMessageResult, data); - let encoded = rlp::encode(&message); - assert_eq!("c702857465737431", hex::encode(encoded)); - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/types/mod.rs b/contracts/cosmwasm-vm/cw-xcall/src/types/mod.rs deleted file mode 100644 index 0e5197e3..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/types/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -pub mod config; -pub mod message; -pub mod request; -pub mod result; -pub mod rollback; -pub mod storage_keys; - -pub const LOG_PREFIX: &str = "[xcall_app]:"; - -use crate::error::ContractError; -pub use common::rlp; -use common::rlp::{Decodable, Encodable}; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_json_binary, Binary}; -use request::CSMessageRequest; -use result::CSMessageResult; diff --git a/contracts/cosmwasm-vm/cw-xcall/src/types/request.rs b/contracts/cosmwasm-vm/cw-xcall/src/types/request.rs deleted file mode 100644 index 69997059..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/types/request.rs +++ /dev/null @@ -1,269 +0,0 @@ -use super::*; -use common::rlp::Nullable; -use cosmwasm_std::Addr; -use cw_xcall_lib::{message::msg_type::MessageType, network_address::NetworkAddress}; -use serde::{Deserialize, Serialize}; -use std::str::FromStr; - -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] -pub struct CSMessageRequest { - from: NetworkAddress, - to: Addr, - sequence_no: u128, - protocols: Vec, - msg_type: MessageType, - data: Nullable>, -} - -impl CSMessageRequest { - pub fn new( - from: NetworkAddress, - to: Addr, - sequence_no: u128, - msg_type: MessageType, - data: Vec, - protocols: Vec, - ) -> Self { - let data_bytes = match data.is_empty() { - true => None, - false => Some(data), - }; - Self { - from, - to, - sequence_no, - msg_type, - data: Nullable::new(data_bytes), - protocols, - } - } - - pub fn from(&self) -> &NetworkAddress { - &self.from - } - - pub fn to(&self) -> &Addr { - &self.to - } - - pub fn sequence_no(&self) -> u128 { - self.sequence_no - } - - pub fn msg_type(&self) -> MessageType { - self.msg_type.clone() - } - - pub fn need_response(&self) -> bool { - self.msg_type == MessageType::CallMessageWithRollback - } - - pub fn allow_retry(&self) -> bool { - self.msg_type == MessageType::CallMessagePersisted - } - - pub fn data(&self) -> Result<&[u8], ContractError> { - Ok(self - .data - .get() - .map_err(|error| ContractError::DecodeFailed { - error: error.to_string(), - })?) - } - - pub fn protocols(&self) -> &Vec { - &self.protocols - } - - pub fn as_bytes(&self) -> Vec { - rlp::encode(self).to_vec() - } -} - -impl Encodable for CSMessageRequest { - fn rlp_append(&self, stream: &mut rlp::RlpStream) { - stream.begin_list(6); - stream.append(&self.from.to_string()); - stream.append(&self.to.to_string()); - stream.append(&self.sequence_no); - stream.append(&self.msg_type.as_int()); - stream.append(&self.data); - stream.begin_list(self.protocols.len()); - for protocol in self.protocols.iter() { - stream.append(protocol); - } - } -} - -impl Decodable for CSMessageRequest { - fn decode(rlp: &rlp::Rlp) -> Result { - let rlp_protocols = rlp.at(5)?; - let list: Vec = rlp_protocols.as_list()?; - let str_from: String = rlp.val_at(0)?; - let to_str: String = rlp.val_at(1)?; - let msg_type_int: u8 = rlp.val_at(3)?; - Ok(Self { - from: NetworkAddress::from_str(&str_from) - .map_err(|_e| rlp::DecoderError::RlpInvalidLength)?, - to: Addr::unchecked(to_str), - sequence_no: rlp.val_at(2)?, - msg_type: MessageType::from_int(msg_type_int), - data: rlp.val_at(4)?, - protocols: list, - }) - } -} - -impl TryFrom<&Vec> for CSMessageRequest { - type Error = ContractError; - fn try_from(value: &Vec) -> Result { - let rlp = rlp::Rlp::new(value as &[u8]); - Self::decode(&rlp).map_err(|error| ContractError::DecodeFailed { - error: error.to_string(), - }) - } -} - -impl TryFrom<&[u8]> for CSMessageRequest { - type Error = ContractError; - fn try_from(value: &[u8]) -> Result { - let rlp = rlp::Rlp::new(value); - Self::decode(&rlp).map_err(|error| ContractError::DecodeFailed { - error: error.to_string(), - }) - } -} - -#[cfg(test)] -mod tests { - - /* - CSMessageRequest - from: 0x1.ETH/0xa - to: cx0000000000000000000000000000000000000102 - sn: 21 - messageType: 1 - data: 74657374 - protocol: [] - RLP: f83f8b3078312e4554482f307861aa63783030303030303030303030303030303030303030303030303030303030303030303030303031303215018474657374c0 - - CSMessageRequest - from: 0x1.ETH/0xa - to: cx0000000000000000000000000000000000000102 - sn: 21 - messageType: 1 - data: 74657374 - protocol: [abc, cde, efg] - RLP: f84b8b3078312e4554482f307861aa63783030303030303030303030303030303030303030303030303030303030303030303030303031303215018474657374cc836162638363646583656667 - - CSMessageRequest - from: 0x1.ETH/0xa - to: cx0000000000000000000000000000000000000102 - sn: 21 - messageType: 2 - data: 74657374 - protocol: [abc, cde, efg] - RLP: f84b8b3078312e4554482f307861aa63783030303030303030303030303030303030303030303030303030303030303030303030303031303215028474657374cc836162638363646583656667 - - - */ - - use std::{io::Read, str::FromStr}; - - use common::rlp::{self, RlpStream}; - use cosmwasm_std::Addr; - use cw_xcall_lib::network_address::NetworkAddress; - - use super::CSMessageRequest; - use cw_xcall_lib::message::msg_type::MessageType; - - #[test] - fn test_csmessage_request_encoding() { - let data = hex::decode("74657374").unwrap(); - let msg = CSMessageRequest::new( - NetworkAddress::from_str("0x1.ETH/0xa").unwrap(), - Addr::unchecked("cx0000000000000000000000000000000000000102"), - 21, - MessageType::CallMessage, - data.clone(), - vec![], - ); - - let encoded = rlp::encode(&msg); - - assert_eq!("f83f8b3078312e4554482f307861aa63783030303030303030303030303030303030303030303030303030303030303030303030303031303215008474657374c0",hex::encode(encoded)); - - let msg = CSMessageRequest::new( - NetworkAddress::from_str("0x1.ETH/0xa").unwrap(), - Addr::unchecked("cx0000000000000000000000000000000000000102"), - 21, - MessageType::CallMessage, - data.clone(), - vec!["abc".to_string(), "cde".to_string(), "efg".to_string()], - ); - - let encoded = rlp::encode(&msg); - - assert_eq!("f84b8b3078312e4554482f307861aa63783030303030303030303030303030303030303030303030303030303030303030303030303031303215008474657374cc836162638363646583656667",hex::encode(encoded)); - - let msg = CSMessageRequest::new( - NetworkAddress::from_str("0x1.ETH/0xa").unwrap(), - Addr::unchecked("cx0000000000000000000000000000000000000102"), - 21, - MessageType::CallMessageWithRollback, - data, - vec!["abc".to_string(), "cde".to_string(), "efg".to_string()], - ); - - let encoded = rlp::encode(&msg); - - assert_eq!("f84b8b3078312e4554482f307861aa63783030303030303030303030303030303030303030303030303030303030303030303030303031303215018474657374cc836162638363646583656667",hex::encode(encoded)); - } - - #[test] - fn test_network_address() { - let addr = NetworkAddress::from_str("0x1.ETH/0xa").unwrap(); - let mut rlp_stream = RlpStream::new(); - rlp_stream.append(&addr.to_string()); - let bytes = hex::encode(&rlp_stream.out()); - println!("{:?}", bytes); - assert_eq!("8b3078312e4554482f307861", &bytes); - } - - #[test] - fn test_sn_encode() { - let addr = NetworkAddress::from_str("0x1.ETH/0xa").unwrap(); - let mut rlp_stream = RlpStream::new(); - rlp_stream.append(&21); - let bytes = hex::encode(&rlp_stream.out()); - println!("{:?}", bytes); - assert_eq!("15", &bytes); - } - - #[test] - fn test_addr() { - let mut rlp_stream = RlpStream::new(); - rlp_stream.append(&"cx0000000000000000000000000000000000000102".to_string()); - let bytes = hex::encode(&rlp_stream.out()); - println!("{:?}", bytes); - assert_eq!("aa637830303030303030303030303030303030303030303030303030303030303030303030303030313032",&bytes); - } - - #[test] - fn test_bytes() { - let mut rlp_stream = RlpStream::new(); - rlp_stream.append(&hex::decode("74657374").unwrap()); - let bytes = hex::encode(&rlp_stream.out()); - println!("{:?}", bytes); - assert_eq!("8474657374", &bytes); - } - - #[test] - fn test_list() { - let mut rlp_stream = RlpStream::new(); - rlp_stream.append(&vec![]); - let bytes = hex::encode(&rlp_stream.out()); - println!("{:?}", bytes); - assert_eq!("80", &bytes); - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/types/result.rs b/contracts/cosmwasm-vm/cw-xcall/src/types/result.rs deleted file mode 100644 index 40c9ebd0..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/types/result.rs +++ /dev/null @@ -1,150 +0,0 @@ -use super::*; - -#[cw_serde] -pub enum CallServiceResponseType { - CallServiceResponseFailure, - CallServiceResponseSuccess, -} - -impl From for u8 { - fn from(val: CallServiceResponseType) -> Self { - val as u8 - } -} - -impl TryFrom for CallServiceResponseType { - type Error = rlp::DecoderError; - - fn try_from(value: u8) -> Result { - match value { - 0 => Ok(CallServiceResponseType::CallServiceResponseFailure), - 1 => Ok(CallServiceResponseType::CallServiceResponseSuccess), - _ => Err(rlp::DecoderError::Custom("Invalid type")), - } - } -} - -#[cw_serde] -pub struct CSMessageResult { - sequence_no: u128, - response_code: CallServiceResponseType, - message: Vec, -} - -impl CSMessageResult { - pub fn new( - sequence_no: u128, - response_code: CallServiceResponseType, - reply: Option>, - ) -> Self { - Self { - sequence_no, - response_code, - message: reply.unwrap_or_default(), - } - } - - pub fn sequence_no(&self) -> u128 { - self.sequence_no - } - - pub fn response_code(&self) -> &CallServiceResponseType { - &self.response_code - } - - pub fn set_fields(&mut self, sequence_no: u128, response_code: CallServiceResponseType) { - self.sequence_no.clone_from(&sequence_no); - self.response_code = response_code; - } - - pub fn get_message(&self) -> Option { - if self.message.is_empty() { - return None; - } - rlp::decode(&self.message).ok() - } - - pub fn as_bytes(&self) -> Vec { - rlp::encode(&self.clone()).to_vec() - } -} - -impl Encodable for CSMessageResult { - fn rlp_append(&self, stream: &mut rlp::RlpStream) { - let code: u8 = self.response_code.clone().into(); - - stream - .begin_list(3) - .append(&self.sequence_no()) - .append(&code) - .append(&self.message); - } -} - -impl Decodable for CSMessageResult { - fn decode(rlp: &rlp::Rlp) -> Result { - let code: u8 = rlp.val_at(1)?; - - Ok(Self { - sequence_no: rlp.val_at(0)?, - response_code: CallServiceResponseType::try_from(code)?, - message: rlp.val_at(2).unwrap_or_default(), - }) - } -} - -impl TryFrom<&Vec> for CSMessageResult { - type Error = ContractError; - fn try_from(value: &Vec) -> Result { - let rlp = rlp::Rlp::new(value as &[u8]); - Self::decode(&rlp).map_err(|error| ContractError::DecodeFailed { - error: error.to_string(), - }) - } -} - -impl TryFrom<&[u8]> for CSMessageResult { - type Error = ContractError; - fn try_from(value: &[u8]) -> Result { - let rlp = rlp::Rlp::new(value); - Self::decode(&rlp).map_err(|error| ContractError::DecodeFailed { - error: error.to_string(), - }) - } -} - -#[cfg(test)] -mod tests { - /* - CSMessageResponse - sn: 1 - code: CSMessageResponse.SUCCESS - errorMessage: errorMessage - RLP: C20101 - - CSMessageResponse - sn: 2 - code: CSMessageResponse.FAILURE - errorMessage: errorMessage - RLP: C20200 - */ - - use common::rlp; - - use super::{CSMessageResult, CallServiceResponseType}; - - #[test] - fn test_cs_message_response_encoding() { - let cs_response = - CSMessageResult::new(1, CallServiceResponseType::CallServiceResponseSuccess, None); - let encoded = rlp::encode(&cs_response); - - assert_eq!("c3010180", hex::encode(encoded)); - - let cs_response = - CSMessageResult::new(2, CallServiceResponseType::CallServiceResponseFailure, None); - let encoded = rlp::encode(&cs_response); - - assert_eq!("c3020080", hex::encode(encoded)); - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/types/rollback.rs b/contracts/cosmwasm-vm/cw-xcall/src/types/rollback.rs deleted file mode 100644 index ecd994f4..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/types/rollback.rs +++ /dev/null @@ -1,60 +0,0 @@ -use cosmwasm_std::Addr; -use cw_xcall_lib::network_address::NetworkAddress; - -use super::*; - -#[cw_serde] - -pub struct Rollback { - from: Addr, - to: NetworkAddress, - protocols: Vec, - rollback: Vec, - enabled: bool, -} - -impl Rollback { - pub fn new( - from: Addr, - to: NetworkAddress, - protocols: Vec, - rollback: Vec, - enabled: bool, - ) -> Self { - Self { - from, - to, - rollback, - protocols, - enabled, - } - } - - pub fn from(&self) -> &Addr { - &self.from - } - - pub fn to(&self) -> &NetworkAddress { - &self.to - } - - pub fn rollback(&self) -> &[u8] { - &self.rollback - } - - pub fn enabled(&self) -> bool { - self.enabled - } - - pub fn protocols(&self) -> &Vec { - &self.protocols - } - - pub fn is_null(&self) -> bool { - let r = to_json_binary(self).unwrap(); - r.is_empty() - } - pub fn set_enabled(&mut self) { - self.enabled = true; - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/src/types/storage_keys.rs b/contracts/cosmwasm-vm/cw-xcall/src/types/storage_keys.rs deleted file mode 100644 index ce4fe994..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/src/types/storage_keys.rs +++ /dev/null @@ -1,44 +0,0 @@ -use super::*; - -#[cw_serde] -pub enum StorageKey { - Sn, - RequestNo, - Admin, - MessageRequest, - Requests, - FeeHandler, - Balance, - ProtocolFee, - DefaultConnections, - Connections, - PendingRequests, - PendingResponses, - SuccessfulResponses, - Config, - Callbackdata, - CallReply, -} - -impl StorageKey { - pub fn as_str(&self) -> &'static str { - match self { - StorageKey::Admin => "admin", - StorageKey::MessageRequest => "message_request", - StorageKey::Sn => "sn", - StorageKey::RequestNo => "requestno", - StorageKey::Requests => "requests", - StorageKey::FeeHandler => "feehandler", - StorageKey::Balance => "balance", - StorageKey::ProtocolFee => "protocol_fee", - StorageKey::DefaultConnections => "default_connections", - StorageKey::Connections => "connections", - StorageKey::PendingRequests => "pending_requests", - StorageKey::PendingResponses => "pending_responses", - StorageKey::SuccessfulResponses => "successful_responses", - StorageKey::Config => "config", - StorageKey::Callbackdata => "callback_data", - StorageKey::CallReply => "call_reply", - } - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/tests/account.rs b/contracts/cosmwasm-vm/cw-xcall/tests/account.rs deleted file mode 100644 index e2b7f139..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/tests/account.rs +++ /dev/null @@ -1,71 +0,0 @@ -use std::fmt::Display; - -use common::rlp::{self, Decodable, Encodable}; -use cosmwasm_schema::cw_serde; -use cw_storage_plus::KeyDeserialize; -#[cw_serde] -pub struct Address(String); - -impl Display for Address { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -impl From<&str> for Address { - fn from(value: &str) -> Self { - Address(value.to_string()) - } -} - -impl From<&String> for Address { - fn from(value: &String) -> Self { - Address(value.to_string()) - } -} - -impl From<&[u8]> for Address { - fn from(value: &[u8]) -> Self { - let address = String::from_vec(value.to_vec()).unwrap(); - Address(address) - } -} -impl Encodable for Address { - fn rlp_append(&self, stream: &mut rlp::RlpStream) { - stream.begin_list(1).append(&self.0); - } -} - -impl Decodable for Address { - fn decode(rlp: &rlp::Rlp) -> Result { - Ok(Self(rlp.val_at(0)?)) - } -} - -impl Address { - pub fn len(&self) -> usize { - self.0.len() - } - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - pub fn as_str(&self) -> &str { - &self.0 - } -} - -pub fn alice() -> Address { - Address::from("alice") -} - -pub fn bob() -> Address { - Address::from("bob") -} - -pub fn admin_one() -> Address { - Address::from("adminone") -} - -pub fn admin_two() -> Address { - Address::from("admintwo") -} diff --git a/contracts/cosmwasm-vm/cw-xcall/tests/setup.rs b/contracts/cosmwasm-vm/cw-xcall/tests/setup.rs deleted file mode 100644 index 3d19443e..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/tests/setup.rs +++ /dev/null @@ -1,300 +0,0 @@ -use std::{collections::HashMap, str::FromStr}; - -use common::{rlp, utils::keccak256}; -use cosmwasm::encoding::Binary; -use cosmwasm_std::{ - coins, - testing::{ - mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, - MOCK_CONTRACT_ADDR, - }, - to_json_binary, Addr, BlockInfo, ContractInfo, ContractResult, Empty, Env, MessageInfo, - OwnedDeps, Storage, SystemResult, Timestamp, TransactionInfo, WasmQuery, -}; -use cw_xcall::{ - state::CwCallService, - types::{ - config::Config, - message::CSMessage, - request::CSMessageRequest, - result::{CSMessageResult, CallServiceResponseType}, - rollback::Rollback, - }, -}; -use cw_xcall_lib::{ - message::{ - call_message::CallMessage, call_message_rollback::CallMessageWithRollback, - envelope::Envelope, msg_trait::IMessage, msg_type::MessageType, AnyMessage, - }, - network_address::{NetId, NetworkAddress}, -}; - -pub fn get_dummy_network_address(nid: &str) -> NetworkAddress { - NetworkAddress::new(nid, "xcall") -} - -pub fn get_dummy_call_msg_envelop() -> Envelope { - let msg = AnyMessage::CallMessage(CallMessage { - data: vec![1, 2, 3], - }); - Envelope::new(msg, vec![], vec![]) -} - -pub fn get_dummy_req_msg() -> CSMessageRequest { - CSMessageRequest::new( - get_dummy_network_address("archway"), - Addr::unchecked("dapp"), - 1, - MessageType::CallMessage, - keccak256(&[1, 2, 3]).to_vec(), - vec![], - ) -} - -pub fn get_dummy_rollback_data() -> Rollback { - let msg = AnyMessage::CallMessageWithRollback(CallMessageWithRollback { - data: vec![1, 2, 3], - rollback: vec![1, 2, 3], - }); - let envelope = Envelope::new(msg, vec![], vec![]); - - Rollback::new( - Addr::unchecked("xcall"), - get_dummy_network_address("archway"), - envelope.sources, - envelope.message.rollback().unwrap(), - true, - ) -} - -pub fn get_dummy_request_message() -> CSMessage { - let payload = get_dummy_req_msg(); - CSMessage::new( - cw_xcall::types::message::CSMessageType::CSMessageRequest, - rlp::encode(&payload).to_vec(), - ) -} - -pub fn get_dummy_result_message() -> CSMessageResult { - let payload = get_dummy_req_msg(); - CSMessageResult::new( - 1, - CallServiceResponseType::CallServiceResponseSuccess, - Some(payload.as_bytes()), - ) -} - -pub fn get_dummy_result_message_failure() -> CSMessageResult { - let payload = get_dummy_req_msg(); - CSMessageResult::new( - 1, - CallServiceResponseType::CallServiceResponseFailure, - Some(payload.as_bytes()), - ) -} - -pub fn mock_connection_fee_query(deps: &mut OwnedDeps) { - deps.querier.update_wasm(|r| match r { - WasmQuery::Smart { - contract_addr: _, - msg: _, - } => SystemResult::Ok(ContractResult::Ok(to_json_binary(&10_u128).unwrap())), - _ => todo!(), - }); -} - -pub struct MockEnvBuilder { - env: Env, -} - -impl Default for MockEnvBuilder { - fn default() -> Self { - Self::new() - } -} - -impl MockEnvBuilder { - pub fn new() -> MockEnvBuilder { - MockEnvBuilder { - env: Env { - block: BlockInfo { - height: 0, - time: Timestamp::from_nanos(0), - chain_id: "".to_string(), - }, - transaction: None, - contract: ContractInfo { - address: Addr::unchecked("input"), - }, - }, - } - } - pub fn add_block(mut self, block: BlockInfo) -> MockEnvBuilder { - self.env.block = block; - self - } - - pub fn add_txn_info(mut self, txn_info: Option) -> MockEnvBuilder { - self.env.transaction = txn_info; - self - } - - pub fn add_contract_info(mut self, contract_info: ContractInfo) -> MockEnvBuilder { - self.env.contract = contract_info; - self - } - - pub fn build(self) -> Env { - Env { - block: self.env.block, - transaction: self.env.transaction, - contract: self.env.contract, - } - } -} - -#[cfg(test)] -pub mod test { - use super::*; - pub fn create_mock_info(creator: &str, denom: &str, amount: u128) -> MessageInfo { - let funds = coins(amount, denom); - mock_info(creator, &funds) - } - - pub fn deps() -> OwnedDeps { - mock_dependencies() - } -} - -#[test] -fn test() { - let mock = mock_env(); - - let block_info = BlockInfo { - height: 12_345, - time: Timestamp::from_nanos(1_571_797_419_879_305_533), - chain_id: "cosmos-testnet-14002".to_string(), - }; - - let transaction = None; - let contract = ContractInfo { - address: Addr::unchecked(MOCK_CONTRACT_ADDR), - }; - - let mock_env_builder: Env = MockEnvBuilder::new() - .add_block(block_info) - .add_txn_info(transaction) - .add_contract_info(contract) - .build(); - - assert_ne!(mock, mock_env_builder) -} - -pub struct TestContext { - pub nid: NetId, - pub network_address: NetworkAddress, - pub env: Env, - pub info: MessageInfo, - pub request_id: u128, - pub request_message: Option, - pub envelope: Option, - pub mock_queries: HashMap, -} - -impl TestContext { - pub fn default() -> Self { - Self { - nid: NetId::from_str("icon").unwrap(), - network_address: get_dummy_network_address("icon"), - env: MockEnvBuilder::new().env, - info: mock_info("admin", &coins(100, "icx")), - request_id: u128::default(), - request_message: Some(get_dummy_req_msg()), - envelope: None, - mock_queries: HashMap::::new(), - } - } - - pub fn init_context(&self, storage: &mut dyn Storage, contract: &CwCallService) { - self.store_config(storage, contract); - self.set_admin(storage, contract); - self.init_last_request_id(storage, contract); - self.init_last_sequence_no(storage, contract); - self.store_default_connection(storage, contract); - self.store_protocol_fee_handler(storage, contract) - } - - pub fn init_execute_call(&self, storage: &mut dyn Storage, contract: &CwCallService) { - self.init_context(storage, contract); - self.store_proxy_request(storage, contract); - } - - pub fn init_reply_state(&self, storage: &mut dyn Storage, contract: &CwCallService) { - self.init_context(storage, contract); - self.store_proxy_request(storage, contract); - self.store_execute_request_id(storage, contract); - } - - pub fn set_admin(&self, storage: &mut dyn Storage, contract: &CwCallService) { - contract - .set_admin(storage, self.info.sender.clone()) - .unwrap(); - } - - pub fn store_config(&self, storage: &mut dyn Storage, contract: &CwCallService) { - let config = Config { - network_id: "icon".to_string(), - denom: "icx".to_string(), - }; - contract.store_config(storage, &config).unwrap(); - } - - pub fn store_protocol_fee_handler(&self, storage: &mut dyn Storage, contract: &CwCallService) { - contract - .store_protocol_fee_handler(storage, self.info.sender.to_string()) - .unwrap(); - } - - pub fn store_default_connection(&self, storage: &mut dyn Storage, contract: &CwCallService) { - let network = get_dummy_network_address("archway"); - let address = Addr::unchecked("centralized"); - contract - .store_default_connection(storage, network.nid(), address) - .unwrap(); - } - - pub fn store_proxy_request(&self, storage: &mut dyn Storage, contract: &CwCallService) { - if let Some(proxy_request) = &self.request_message { - contract - .store_proxy_request(storage, self.request_id, proxy_request) - .unwrap(); - } - } - - pub fn store_execute_request_id(&self, storage: &mut dyn Storage, contract: &CwCallService) { - contract - .store_execute_request_id(storage, self.request_id) - .unwrap(); - } - - pub fn init_last_request_id(&self, storage: &mut dyn Storage, contract: &CwCallService) { - contract - .init_last_request_id(storage, self.request_id) - .unwrap(); - } - - pub fn init_last_sequence_no(&self, storage: &mut dyn Storage, contract: &CwCallService) { - contract - .init_last_sequence_no(storage, u128::default()) - .unwrap(); - } - - pub fn set_successful_response( - &self, - storage: &mut dyn Storage, - contract: &CwCallService, - sn: u128, - ) { - contract.set_successful_response(storage, sn).unwrap(); - } -} diff --git a/contracts/cosmwasm-vm/cw-xcall/tests/test_admin.rs b/contracts/cosmwasm-vm/cw-xcall/tests/test_admin.rs deleted file mode 100644 index 270439d7..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/tests/test_admin.rs +++ /dev/null @@ -1,244 +0,0 @@ -mod account; -mod setup; -use account::*; -use cosmwasm_std::{testing::mock_env, Addr}; - -use cw_xcall::state::CwCallService; -use cw_xcall_lib::xcall_msg::ExecuteMsg; -use setup::test::*; - -#[test] -#[should_panic(expected = "OnlyAdmin")] -fn set_admin_unauthorized() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); - let mock_env = mock_env(); - - let mut contract = CwCallService::default(); - - contract - .set_admin( - mock_deps.as_mut().storage, - Addr::unchecked(bob().to_string()), - ) - .unwrap(); - - contract - .execute( - mock_deps.as_mut(), - mock_env, - mock_info, - ExecuteMsg::SetAdmin { - address: bob().to_string(), - }, - ) - .unwrap(); -} - -#[test] -fn set_admin() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - let response = contract - .set_admin( - mock_deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - - assert_eq!(response.attributes[0].value, "set_admin"); - - assert_eq!(response.attributes[1].value, admin_one().to_string()); - - let result = contract.query_admin(mock_deps.as_ref().storage).unwrap(); - - assert_eq!(result, admin_one().to_string()) -} - -#[test] -fn update_existing_admin() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - contract - .set_admin( - mock_deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - - let result = contract.query_admin(mock_deps.as_ref().storage).unwrap(); - - assert_eq!(result, admin_one().to_string()); - - contract - .set_admin( - mock_deps.as_mut().storage, - Addr::unchecked(admin_two().to_string()), - ) - .unwrap(); - - let result = contract.query_admin(mock_deps.as_ref().storage).unwrap(); - - assert_eq!(result, admin_two().to_string()); -} - -#[test] -fn remove_existing_admin_and_set_admin() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - let response = contract - .set_admin( - mock_deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - - assert_eq!(response.attributes[0].value, "set_admin"); - - assert_eq!(response.attributes[1].value, admin_one().to_string()); - - let result = contract.query_admin(mock_deps.as_ref().storage).unwrap(); - - assert_eq!(result, admin_one().to_string()); - - contract - .set_admin( - mock_deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - - let result = contract.query_admin(mock_deps.as_ref().storage).unwrap(); - - assert_eq!(result, admin_one().to_string()); -} - -#[test] -#[should_panic(expected = "Invalid input:")] -fn set_admin_with_empty_address() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); - let mock_env = mock_env(); - - let mut contract = CwCallService::default(); - - contract - .execute( - mock_deps.as_mut(), - mock_env, - mock_info, - ExecuteMsg::SetAdmin { - address: "".to_string(), - }, - ) - .unwrap(); - - contract - .set_admin(mock_deps.as_mut().storage, Addr::unchecked("")) - .unwrap(); -} - -#[test] -fn query_admin() { - let mock_deps = deps(); - - let mock_env = mock_env(); - - let contract = CwCallService::default(); - - let result = contract.query( - mock_deps.as_ref(), - mock_env, - cw_xcall::msg::QueryMsg::GetAdmin {}, - ); - - assert!(result.is_err()) -} - -#[test] -#[should_panic(expected = "InvalidAddress { address: \"*************\"")] -fn add_invalid_char_as_admin() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); - let mock_env = mock_env(); - - let mut contract = CwCallService::default(); - contract - .set_admin( - mock_deps.as_mut().storage, - Addr::unchecked(alice().to_string()), - ) - .unwrap(); - - contract - .execute( - mock_deps.as_mut(), - mock_env, - mock_info, - ExecuteMsg::SetAdmin { - address: "*************".to_string(), - }, - ) - .unwrap(); -} - -#[test] -#[should_panic( - expected = "Std(GenericErr { msg: \"Invalid input: human address too short for this mock implementation (must be >= 3).\" })" -)] -fn validate_address_set_admin_size_lessthan_3() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); - let mock_env = mock_env(); - - let mut contract = CwCallService::default(); - - contract - .execute( - mock_deps.as_mut(), - mock_env, - mock_info, - ExecuteMsg::SetAdmin { - address: "sm".to_string(), - }, - ) - .unwrap(); -} - -#[test] -#[should_panic( - expected = "Std(GenericErr { msg: \"Invalid input: human address too long for this mock implementation (must be <= 90).\" })" -)] -fn validate_address_set_admin_size_more_than_45() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); - let mock_env = mock_env(); - - let mut contract = CwCallService::default(); - - contract - .set_admin(mock_deps.as_mut().storage, mock_info.sender.clone()) - .unwrap(); - - contract - .execute( - mock_deps.as_mut(), - mock_env, - mock_info, - ExecuteMsg::SetAdmin { - address: "eddiuo6lbp05golmz3rb5n7hbi4c5hhyh0rb1w6cslyjt5mhwd0chn3x254lyorpx4dzvrvsc9h2em44be2rj193dwe".to_string(), - }, - ) - .unwrap(); -} diff --git a/contracts/cosmwasm-vm/cw-xcall/tests/test_call_message.rs b/contracts/cosmwasm-vm/cw-xcall/tests/test_call_message.rs deleted file mode 100644 index df080a19..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/tests/test_call_message.rs +++ /dev/null @@ -1,447 +0,0 @@ -mod account; -mod setup; - -use crate::account::*; -use setup::{get_dummy_network_address, test::*, TestContext}; -use std::{collections::HashMap, str::FromStr, vec}; - -use cosmwasm_std::{ - testing::{mock_env, MOCK_CONTRACT_ADDR}, - to_json_binary, Addr, Binary, ContractInfoResponse, ContractResult, SystemError, SystemResult, - WasmQuery, -}; -use cw_xcall::{ - state::CwCallService, - types::{config::Config, request::CSMessageRequest}, -}; -use cw_xcall_lib::{ - message::{ - call_message_persisted::CallMessagePersisted, envelope::Envelope, msg_type::MessageType, - AnyMessage, - }, - network_address::{NetId, NetworkAddress}, -}; - -const MOCK_CONTRACT_TO_ADDR: &str = "cosmoscontract"; - -#[test] -#[should_panic(expected = "RollbackNotPossible")] -fn send_packet_by_non_contract_and_rollback_data_is_not_null() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "arch", 2000); - - let contract = CwCallService::default(); - - contract.sn().save(mock_deps.as_mut().storage, &0).unwrap(); - - contract - .store_config( - mock_deps.as_mut().storage, - &Config { - network_id: "nid".to_string(), - denom: "arch".to_string(), - }, - ) - .unwrap(); - contract - .set_admin( - mock_deps.as_mut().storage, - Addr::unchecked(alice().to_string()), - ) - .unwrap(); - contract - .set_default_connection( - mock_deps.as_mut(), - mock_info.clone(), - NetId::from_str("nid").unwrap(), - Addr::unchecked("defaultconn".to_string()), - ) - .unwrap(); - - contract - .send_call_message( - mock_deps.as_mut(), - mock_info, - mock_env(), - NetworkAddress::new("nid", MOCK_CONTRACT_ADDR), - vec![1, 2, 3], - Some(vec![1, 2, 3]), - vec![], - vec![], - ) - .unwrap(); -} - -#[test] -#[should_panic(expected = "MaxDataSizeExceeded")] -fn send_packet_failure_due_data_len() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(MOCK_CONTRACT_ADDR, "umlg", 2000); - - let _env = mock_env(); - - let contract = CwCallService::default(); - - contract.sn().save(mock_deps.as_mut().storage, &0).unwrap(); - - mock_deps.querier.update_wasm(|r| { - let constract1 = Addr::unchecked(MOCK_CONTRACT_ADDR); - let mut storage1 = HashMap::::default(); - storage1.insert(b"the key".into(), b"the value".into()); - match r { - WasmQuery::ContractInfo { contract_addr } => { - if *contract_addr == constract1 { - let response = ContractInfoResponse::new(0, "test"); - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Err(SystemError::NoSuchContract { - addr: contract_addr.clone(), - }) - } - } - // protocol fee query - WasmQuery::Smart { - contract_addr: _, - msg: _, - } => SystemResult::Ok(ContractResult::Ok(to_json_binary(&0_u128).unwrap())), - _ => todo!(), - } - }); - contract - .store_config( - mock_deps.as_mut().storage, - &Config { - network_id: "nid".to_string(), - denom: "arch".to_string(), - }, - ) - .unwrap(); - contract - .store_default_connection( - mock_deps.as_mut().storage, - NetId::from("nid".to_owned()), - Addr::unchecked("hostaddress"), - ) - .unwrap(); - - contract - .send_call_message( - mock_deps.as_mut(), - mock_info, - mock_env(), - NetworkAddress::new("nid", MOCK_CONTRACT_ADDR), - "HuykcBsssssTXfpMmbwWx9COZWbuMkecnMTGI54oXFBsSFOypVHuiBT2egh0drcRAS4wQyGxOCGhL8mBWTttEOG88kuvDcF5R5OmhBa1beo46i9IwD56OqhpzCOVxJqF87fhctAymhmMSBWA95gCnNP45If5FfFtRIsiU9fkwqYPRKCpjtwsFcYJSB3fmABDfsiQBT3rCjvWybzrdN3NoS4VHT3sKuzVeOTNSHDGZaztEpRqBBX1NgNMdky63xfCcslBujryZIbT3xFOXQTzhmCqypqCBsfE2IKbRpZ4zjJjRHhK9e2H2EThk0huP7QVKkHJ2UECyj8QahqvqwtK3QOV8PN1lQmaLV8gtKuBEQalQScHopXOCbeSZgrGRE0r447i7ppCLi6PbX3qja1R3UxMQ2mTIqZRwAsqFHazl7hjchqKkLKrbc0YRz3egQdZi55c7BBpvwGLvEeHUFH4qrSbZ6oRHOJfyWaBtTsoZzjAApSL94EFcFjZV7b5ImDt1uvCy8lGULMig8D8XWcdYQWdlMYwvStzzDpqBU2tw1dX9omD7IJNcBnYNQEXtiEGDdhnCDF9z6lxH0JHG9ZepbiMKi1bduhZrUR51gkqNPT3JxziAlN2xuaM9f3TVIqNLI9IjJYAFNIqe4IZ7qfJCSIoDj2Tq0wJrEkXgW8kAheMzvmOVglr1SlSo3uweVaOgfGbwANak39MtplyksgH8GGgSv0k3ghLHeT06HbKt6MCVCi5fcFLXuCa0HZt7Dslg601YqJn36Hw031ObkJf1HFoNf8mdLHjCfDCXaUwWY9owqmYDL39Jh46P80sXa4u1IqKUfrFMmmCpF7MaVvtdMsJelz2zZHZUPSiC38xfUkOdcgRVcLVBv8GSKcqrMGo9QZs2fu9Zi25WuSZ0SzRo61TjBpRXm1MypIDnxTTEMMBA7l9L7TeojRak80SXhKGx1Pj4AKKNGiKYeIhyx3eSL1JzXmW9qABN6ex1MK4v8pdViMszPgWjeAL95hIWZHuQRMQkTW6A8zBIltmBrM7HAVXbgvMEN48MiacvF7uyC4ogptOw2M01RPX5vgrYS0uXiNUe3AkkPM52z73t6zcNtB1ey1p99HlvVi7ESkPfwQ6MWI2M0bJjru9qYll61idDW3H05v7fFtGg8Ic0MyMbzSX115GIMn6wadHubyaOLNCTJzsApcwuVDUb7uYxRkb53ZP4vVKbPqGugcQojjq22rYNTJt0frigyQYpXm8F1B06VcHnUj460kXEXrpep7UkPaRX5qloF5csnqStuutf9lDPSX8Yrfy6ptdS6FLys0gJpJvR1cDc2h1AfKYyRkflHWUShpJlyrxF4bsOR42vu5ZzX1OQZJaTMaiq1K8IlgzEIFzj9NVji7t26iIgtiZnq17twaw97L3U0I2RlVV6xF9oE27uF08ttTQ0D33VnrzeYBfyrHfrjouf44igELGwolxamYgmaT6NqWhLW45juzqmklNt33DoFRYfMImRrnAbh5zR20XLWAgspPDXgdd52b1sclR6DbAa43wQgdHpoPhSnYCGszGrN2vR1kyMRb32wf37BA725rcOBvfhQSFzNtTk1IqYDyPGUPsZTSknUq4oBRTFJhfzDMh6xy6950EyNAsfUd471kIFvg2dpprhbStY92ftm5TAiAorUXRCljzzU5hfJ6NQinsCmDSRcadtlgn1uThvdqi62xcmDlWDvCf5nKrmad1e3SEmyo99TjjoZXMMPtiGbq9YLEp96JP1TTlcPLHuDewAJNDjQN3ZYg0zQM6b1F3cAD5AgP8ZZc8pK1lJph05YzzV4Lindpx99zewUinVS60ipj4hKbQWNCJhlQCWXPURXI7J8RoLC9leZCqOyPMYEF0tosVmtA4yn1Vup7LJP8DhZ5Br5M0oFGPzmlBSztMj9Gpp0bHnqby5q4elF3KTncyAFDv5xtlN4pxFgclB22aCaT2j7BvNTgaLPQEfH1NQY3fdDzpQbAbGzdLjo77RbClagKYH2iCnq0lg885jMiavPL1NMtqOKPFc".to_string().as_bytes().to_vec(), - Some(vec![]), - vec![], - vec![], - ) - .unwrap(); -} - -#[test] -#[should_panic(expected = "MaxRollbackSizeExceeded")] -fn send_packet_failure_due_rollback_len() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(MOCK_CONTRACT_ADDR, "umlg", 2000); - - let _env = mock_env(); - - let contract = CwCallService::default(); - - contract.sn().save(mock_deps.as_mut().storage, &0).unwrap(); - - mock_deps.querier.update_wasm(|r| { - let constract1 = Addr::unchecked(MOCK_CONTRACT_ADDR); - let mut storage1 = HashMap::::default(); - storage1.insert(b"the key".into(), b"the value".into()); - match r { - WasmQuery::ContractInfo { contract_addr } => { - if *contract_addr == constract1 { - let response = ContractInfoResponse::new(0, "test"); - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Err(SystemError::NoSuchContract { - addr: contract_addr.clone(), - }) - } - } - WasmQuery::Smart { - contract_addr: _, - msg: _, - } => SystemResult::Ok(ContractResult::Ok(to_json_binary(&0_u128).unwrap())), - _ => todo!(), - } - }); - contract - .store_config( - mock_deps.as_mut().storage, - &Config { - network_id: "nid".to_string(), - denom: "arch".to_string(), - }, - ) - .unwrap(); - contract - .store_default_connection( - mock_deps.as_mut().storage, - NetId::from("nid".to_owned()), - Addr::unchecked("hostaddress"), - ) - .unwrap(); - - contract - .send_call_message( - mock_deps.as_mut(), - mock_info, - mock_env(), - NetworkAddress::new("nid", MOCK_CONTRACT_ADDR), - vec![], - Some("HuykcBsssssTXfpMmbwWx9COZWbuMkecnMTGI54oXFBsSFOypVHuiBT2egh0drcRAS4wQyGxOCGhL8mBWTttEOG88kuvDcF5R5OmhBa1beo46i9IwD56OqhpzCOVxJqF87fhctAymhmMSBWA95gCnNP45If5FfFtRIsiU9fkwqYPRKCpjtwsFcYJSB3fmABDfsiQBT3rCjvWybzrdN3NoS4VHT3sKuzVeOTNSHDGZaztEpRqBBX1NgNMdky63xfCcslBujryZIbT3xFOXQTzhmCqypqCBsfE2IKbRpZ4zjJjRHhK9e2H2EThk0huP7QVKkHJ2UECyj8QahqvqwtK3QOV8PN1lQmaLV8gtKuBEQalQScHopXOCbeSZgrGRE0r447i7ppCLi6PbX3qja1R3UxMQ2mTIqZRwAsqFHazl7hjchqKkLKrbc0YRz3egQdZi55c7BBpvwGLvEeHUFH4qrSbZ6oRHOJfyWaBtTsoZzjAApSL94EFcFjZV7b5ImDt1uvCy8lGULMig8D8XWcdYQWdlMYwvStzzDpqBU2tw1dX9omD7IJNcBnYNQEXtiEGDdhnCDF9z6lxH0JHG9ZepbiMKi1bduhZrUR51gkqNPT3JxziAlN2xuaM9f3TVIqNLI9IjJYAFNIqe4IZ7qfJCSIoDj2Tq0wJrEkXgW8kAheMzvmOVglr1SlSo3uweVaOgfGbwANak39MtplyksgH8GGgSv0k3ghLHeT06HbKt6MCVCi5fcFLXuCa0HZt7Dslg601YqJn36Hw031ObkJf1HFoNf8mdLHjCfDCXaUwWY9owqmYDL39Jh46P80sXa4u1IqKUfrFMmmCpF7MaVvtdMsJelz2zZHZUPSiC38xfUkOdcgRVcLVBv8GSKcqrMGo9QZs2fu9Zi25WuSZ0SzRo61TjBpRXm1MypIDnxTTEMMBA7l9L7TeojRak80SXhKGx1Pj4AKKNGiKYeIhyx3eSL1JzXmW9qABN6ex1MK4v8pdViMszPgWjeAL95hIWZHuQRMQkTW6A8zBIltmBrM7HAVXbgvMEN48MiacvF7uyC4ogptOw2M01RPX5vgrYS0uXiNUe3AkkPM52z73t6zcNtB1ey1p99HlvVi7ESkPfwQ6MWI2M0bJjru9qYll61idDW3H05v7fFtGg8Ic0MyMbzSX115GIMn6wadHubyaOLNCTJzsApcwuVDUb7uYxRkb53ZP4vVKbPqGugcQojjq22rYNTJt0frigyQYpXm8F1B06VcHnUj460kXEXrpep7UkPaRX5qloF5csnqStuutf9lDPSX8Yrfy6ptdS6FLys0gJpJvR1cDc2h1AfKYyRkflHWUShpJlyrxF4bsOR42vu5ZzX1OQZJaTMaiq1K8IlgzEIFzj9NVji7t26iIgtiZnq17twaw97L3U0I2RlVV6xF9oE27uF08ttTQ0D33VnrzeYBfyrHfrjouf44igELGwolxamYgmaT6NqWhLW45juzqmklNt33DoFRYfMImRrnAbh5zR20XLWAgspPDXgdd52b1sclR6DbAa43wQgdHpoPhSnYCGszGrN2vR1kyMRb32wf37BA725rcOBvfhQSFzNtTk1IqYDyPGUPsZTSknUq4oBRTFJhfzDMh6xy6950EyNAsfUd471kIFvg2dpprhbStY92ftm5TAiAorUXRCljzzU5hfJ6NQinsCmDSRcadtlgn1uThvdqi62xcmDlWDvCf5nKrmad1e3SEmyo99TjjoZXMMPtiGbq9YLEp96JP1TTlcPLHuDewAJNDjQN3ZYg0zQM6b1F3cAD5AgP8ZZc8pK1lJph05YzzV4Lindpx99zewUinVS60ipj4hKbQWNCJhlQCWXPURXI7J8RoLC9leZCqOyPMYEF0tosVmtA4yn1Vup7LJP8DhZ5Br5M0oFGPzmlBSztMj9Gpp0bHnqby5q4elF3KTncyAFDv5xtlN4pxFgclB22aCaT2j7BvNTgaLPQEfH1NQY3fdDzpQbAbGzdLjo77RbClagKYH2iCnq0lg885jMiavPL1NMtqOKPFc".to_string().as_bytes().to_vec()), - vec![], - vec![], - ) - .unwrap(); -} - -#[test] -fn send_packet_success_needresponse() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(MOCK_CONTRACT_ADDR, "arch", 2000); - - let _env = mock_env(); - - let contract = CwCallService::default(); - contract - .instantiate( - mock_deps.as_mut(), - _env, - mock_info.clone(), - cw_xcall::msg::InstantiateMsg { - network_id: "nid".to_string(), - denom: "arch".to_string(), - }, - ) - .unwrap(); - - contract.sn().save(mock_deps.as_mut().storage, &0).unwrap(); - - mock_deps.querier.update_wasm(|r| { - let constract1 = Addr::unchecked(MOCK_CONTRACT_ADDR); - let mut storage1 = HashMap::::default(); - storage1.insert(b"the key".into(), b"the value".into()); - match r { - WasmQuery::ContractInfo { contract_addr } => { - if *contract_addr == constract1 { - let response = ContractInfoResponse::default(); - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Err(SystemError::NoSuchContract { - addr: contract_addr.clone(), - }) - } - } - WasmQuery::Smart { - contract_addr: _, - msg: _, - } => SystemResult::Ok(ContractResult::Ok(to_json_binary(&10_u128).unwrap())), - _ => todo!(), - } - }); - - contract - .store_default_connection( - mock_deps.as_mut().storage, - NetId::from("btp".to_owned()), - Addr::unchecked("hostaddress"), - ) - .unwrap(); - - contract - .send_call_message( - mock_deps.as_mut(), - mock_info, - mock_env(), - NetworkAddress::new("btp", MOCK_CONTRACT_TO_ADDR), - vec![1, 2, 3], - Some(vec![1, 2, 3]), - vec![], - vec![], - ) - .unwrap(); - - let result = contract - .get_call_request(mock_deps.as_ref().storage, 1) - .unwrap(); - - assert!(!result.enabled()) -} - -#[test] -#[should_panic(expected = "InsufficientFunds")] -fn send_packet_fail_insufficient_funds() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(MOCK_CONTRACT_ADDR, "arch", 0); - - let _env = mock_env(); - - let contract = CwCallService::default(); - contract - .instantiate( - mock_deps.as_mut(), - _env, - mock_info.clone(), - cw_xcall::msg::InstantiateMsg { - network_id: "nid".to_string(), - denom: "arch".to_string(), - }, - ) - .unwrap(); - - contract.sn().save(mock_deps.as_mut().storage, &0).unwrap(); - - mock_deps.querier.update_wasm(|r| { - let constract1 = Addr::unchecked(MOCK_CONTRACT_ADDR); - let mut storage1 = HashMap::::default(); - storage1.insert(b"the key".into(), b"the value".into()); - match r { - WasmQuery::ContractInfo { contract_addr } => { - if *contract_addr == constract1 { - let response = ContractInfoResponse::new(0, "test"); - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Err(SystemError::NoSuchContract { - addr: contract_addr.clone(), - }) - } - } - WasmQuery::Smart { - contract_addr: _, - msg: _, - } => SystemResult::Ok(ContractResult::Ok(to_json_binary(&10_u128).unwrap())), - _ => todo!(), - } - }); - - contract - .store_default_connection( - mock_deps.as_mut().storage, - NetId::from("btp".to_owned()), - Addr::unchecked("hostaddress"), - ) - .unwrap(); - - contract - .send_call_message( - mock_deps.as_mut(), - mock_info, - mock_env(), - NetworkAddress::new("btp", MOCK_CONTRACT_TO_ADDR), - vec![1, 2, 3], - Some(vec![1, 2, 3]), - vec![], - vec![], - ) - .unwrap(); - - let result = contract - .get_call_request(mock_deps.as_ref().storage, 1) - .unwrap(); - - assert!(!result.enabled()) -} - -#[test] -fn test_send_message_on_reply_state() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_reply_state(deps.as_mut().storage, &contract); - - let from = ctx.request_message.unwrap().from().clone(); - let envelope = Envelope::new( - AnyMessage::CallMessagePersisted(CallMessagePersisted { - data: vec![1, 2, 3], - }), - vec![], - vec![], - ); - - let res = contract - .send_call(deps.as_mut(), ctx.info, from, envelope) - .unwrap(); - assert_eq!(res.attributes[0].value, "xcall-service"); - assert_eq!(res.attributes[1].value, "send_packet"); -} - -#[test] -fn test_is_reply_returns_false_on_mismatch_network_id() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_reply_state(deps.as_mut().storage, &contract); - - let res = contract.is_reply(deps.as_ref(), ctx.nid, &vec![]); - assert!(!res) -} - -#[test] -fn test_is_reply_returns_false_on_proxy_request_not_found() { - let deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - - let res = contract.is_reply(deps.as_ref(), ctx.nid, &vec![]); - assert!(!res) -} - -#[test] -fn test_is_reply_returns_false_on_mismatch_array_len() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_reply_state(deps.as_mut().storage, &contract); - - let res = contract.is_reply( - deps.as_ref(), - NetId::from_str("archway").unwrap(), - &vec!["src_1".to_string()], - ); - assert!(!res) -} - -#[test] -fn test_is_reply_returns_false_on_mismatch_protocols() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_reply_state(deps.as_mut().storage, &contract); - - let request = CSMessageRequest::new( - get_dummy_network_address("archway"), - Addr::unchecked("dapp"), - 1, - MessageType::CallMessagePersisted, - vec![], - vec!["src_2".to_string()], - ); - contract - .store_proxy_request(deps.as_mut().storage, ctx.request_id, &request) - .unwrap(); - - let res = contract.is_reply( - deps.as_ref(), - NetId::from_str("archway").unwrap(), - &vec!["src_1".to_string()], - ); - assert!(!res) -} diff --git a/contracts/cosmwasm-vm/cw-xcall/tests/test_call_service.rs b/contracts/cosmwasm-vm/cw-xcall/tests/test_call_service.rs deleted file mode 100644 index 9ce51d5c..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/tests/test_call_service.rs +++ /dev/null @@ -1,389 +0,0 @@ -mod account; -mod setup; - -use common::utils::keccak256; -use cw2::{get_contract_version, ContractVersion}; -use cw_xcall::MigrateMsg; -use setup::{test::*, *}; -use std::str::FromStr; - -use cosmwasm_std::{ - testing::{mock_env, MOCK_CONTRACT_ADDR}, - to_json_binary, Addr, Event, Reply, SubMsgResponse, SubMsgResult, -}; -use cw_xcall::{ - execute, instantiate, migrate, - msg::{InstantiateMsg, QueryMsg}, - query, reply, - state::CwCallService, - types::{request::CSMessageRequest, rollback::Rollback}, -}; -use cw_xcall_lib::{ - message::msg_type::MessageType, - network_address::{NetId, NetworkAddress}, - xcall_msg::ExecuteMsg, -}; - -#[test] -fn proper_instantiate() { - let mut mock_deps = deps(); - let mock_info = create_mock_info(MOCK_CONTRACT_ADDR, "umlg", 2000); - let env = mock_env(); - let store = CwCallService::default(); - - let res = instantiate( - mock_deps.as_mut(), - env, - mock_info, - InstantiateMsg { - network_id: "nid".to_string(), - denom: "arch".to_string(), - }, - ) - .unwrap(); - - assert_eq!(res.messages.len(), 0); - - let last_request_id = store - .query_last_request_id(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(0, last_request_id); - - let admin = store.query_admin(mock_deps.as_ref().storage).unwrap(); - - assert_eq!(MOCK_CONTRACT_ADDR, admin) -} - -#[test] -#[should_panic(expected = "NotFound")] -fn improper_instantiate() { - let mock_deps = deps(); - - let store = CwCallService::default(); - - let last_request_id = store - .query_last_request_id(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(0, last_request_id); -} - -#[test] -fn test_migrate() { - let ctx = TestContext::default(); - let mut deps = deps(); - - const CONTRACT_NAME: &str = "crates.io:cw-xcall"; - const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - - migrate(deps.as_mut(), ctx.env, MigrateMsg {}).unwrap(); - let expected = ContractVersion { - contract: CONTRACT_NAME.to_string(), - version: CONTRACT_VERSION.to_string(), - }; - let version = get_contract_version(deps.as_ref().storage).unwrap(); - assert_eq!(expected, version); -} - -#[test] -#[should_panic(expected = "ReplyError { code: 5, msg: \"Unknown\" }")] -fn test_reply_fail_for_unknown_reply_id() { - let mut deps = deps(); - let ctx = TestContext::default(); - - let msg = Reply { - id: 5, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![Event::new("empty")], - data: Some(to_json_binary(&vec![1]).unwrap()), - }), - }; - reply(deps.as_mut(), ctx.env, msg).unwrap(); -} - -#[test] -fn test_execute_set_admin() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let msg = ExecuteMsg::SetAdmin { - address: "new".to_string(), - }; - let res = execute(deps.as_mut(), ctx.env, ctx.info, msg); - assert!(res.is_ok()) -} - -#[test] -fn test_execute_set_protocol_fee_handler() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let msg = ExecuteMsg::SetProtocolFeeHandler { - address: "fee_handler".to_string(), - }; - let res = execute(deps.as_mut(), ctx.env, ctx.info, msg).unwrap(); - - assert_eq!(res.attributes[0].value, "set_protocol_feehandler"); -} - -#[test] -fn test_execute_set_default_connection() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let msg = ExecuteMsg::SetDefaultConnection { - nid: ctx.nid, - address: Addr::unchecked("icon_contract"), - }; - let res = execute(deps.as_mut(), ctx.env, ctx.info, msg); - assert!(res.is_ok()) -} - -#[test] -fn test_execute_send_call_message() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let msg = ExecuteMsg::SendCallMessage { - to: get_dummy_network_address("archway"), - data: vec![1, 2, 3], - rollback: None, - sources: Some(vec![]), - destinations: Some(vec![]), - }; - - mock_connection_fee_query(&mut deps); - - let res = execute(deps.as_mut(), ctx.env, ctx.info, msg).unwrap(); - assert_eq!(res.attributes[0].value, "xcall-service"); - assert_eq!(res.attributes[1].value, "send_packet"); - assert_eq!(res.attributes[2].value, "1"); -} - -#[test] -fn test_execute_send_call() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - mock_connection_fee_query(&mut deps); - - let envelope = get_dummy_call_msg_envelop(); - let msg = ExecuteMsg::SendCall { - envelope, - to: get_dummy_network_address("archway"), - }; - let res = execute(deps.as_mut(), ctx.env, ctx.info, msg).unwrap(); - assert_eq!(res.attributes[0].value, "xcall-service"); - assert_eq!(res.attributes[1].value, "send_packet"); - assert_eq!(res.attributes[2].value, "1"); -} - -#[test] -fn test_execute_handle_request_message_with_default_connection() { - let mut deps = deps(); - let contract = CwCallService::new(); - let info = create_mock_info("centralized", "icx", 100); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let from_nid = NetId::from_str("archway").unwrap(); - let msg = ExecuteMsg::HandleMessage { - from_nid, - msg: get_dummy_request_message().as_bytes(), - }; - let res = execute(deps.as_mut(), ctx.env, info, msg).unwrap(); - assert_eq!(res.attributes[0].value, "call_service"); - assert_eq!(res.attributes[1].value, "handle_response") -} - -#[test] -fn test_execute_call() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_execute_call(deps.as_mut().storage, &contract); - - let msg = ExecuteMsg::ExecuteCall { - request_id: ctx.request_id, - data: vec![1, 2, 3], - }; - let res = execute(deps.as_mut(), ctx.env, ctx.info, msg).unwrap(); - assert_eq!(res.attributes[1].value, "execute_call") -} - -#[test] -fn test_execute_handle_error() { - let mut deps = deps(); - let contract = CwCallService::new(); - let info = create_mock_info("centralized", "arch", 100); - - let ctx = TestContext::default(); - ctx.init_execute_call(deps.as_mut().storage, &contract); - - let rollback = get_dummy_rollback_data(); - contract - .store_call_request(deps.as_mut().storage, ctx.request_id, &rollback) - .unwrap(); - - let msg = ExecuteMsg::HandleError { sn: 0 }; - let res = execute(deps.as_mut(), ctx.env, info, msg).unwrap(); - assert_eq!(res.attributes[1].value, "handle_response") -} - -#[test] -fn test_execute_rollback() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_execute_call(deps.as_mut().storage, &contract); - - let rollback = Rollback::new( - Addr::unchecked("dapp"), - get_dummy_network_address("archway"), - vec!["src".to_string()], - vec![1, 2, 3], - true, - ); - contract - .store_call_request(deps.as_mut().storage, ctx.request_id, &rollback) - .unwrap(); - - let msg = ExecuteMsg::ExecuteRollback { - sequence_no: ctx.request_id, - }; - let res = execute(deps.as_mut(), ctx.env, ctx.info, msg).unwrap(); - assert_eq!(res.attributes[1].value, "execute_rollback"); -} - -#[test] -fn test_query_get_admin() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let msg = QueryMsg::GetAdmin {}; - let res = query(deps.as_ref(), ctx.env, msg).unwrap(); - assert_eq!(res, to_json_binary("admin").unwrap()) -} - -#[test] -fn test_query_get_network_address() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let msg = QueryMsg::GetNetworkAddress {}; - let res = query(deps.as_ref(), ctx.env.clone(), msg).unwrap(); - - let expected_network_address = - NetworkAddress::new("icon", ctx.env.contract.address.clone().as_str()); - assert_eq!(res, to_json_binary(&expected_network_address).unwrap()) -} - -#[test] -fn test_query_verify_success() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - ctx.set_successful_response(deps.as_mut().storage, &contract, 1); - - let msg = QueryMsg::VerifySuccess { sn: 1 }; - let res = query(deps.as_ref(), ctx.env, msg); - assert!(res.is_ok()) -} - -#[test] -fn test_query_get_default_connection() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let msg = QueryMsg::GetDefaultConnection { - nid: NetId::from_str("archway").unwrap(), - }; - let res = query(deps.as_ref(), ctx.env, msg).unwrap(); - assert_eq!( - res, - to_json_binary(&Addr::unchecked("centralized")).unwrap() - ); -} - -#[test] -fn test_get_all_connection() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let res = contract.get_all_connections(deps.as_ref().storage).unwrap(); - assert_eq!(res, vec!["centralized".to_string()]); -} - -#[test] -fn test_execute_call_reply() { - let mut deps = deps(); - let contract = CwCallService::new(); - - let ctx = TestContext::default(); - ctx.init_context(deps.as_mut().storage, &contract); - - let request: CSMessageRequest = CSMessageRequest::new( - get_dummy_network_address("archway"), - Addr::unchecked("xcall"), - u128::default(), - MessageType::CallMessageWithRollback, - keccak256(&[1, 2, 3]).to_vec(), - vec![], - ); - contract - .store_proxy_request(deps.as_mut().storage, ctx.request_id, &request) - .unwrap(); - contract - .save_call_reply(deps.as_mut().storage, &ctx.request_message.unwrap()) - .unwrap(); - contract - .store_execute_request_id(deps.as_mut().storage, ctx.request_id) - .unwrap(); - - let msg = Reply { - id: 1, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![Event::new("empty")], - data: Some(to_json_binary(&vec![1]).unwrap()), - }), - }; - - let res = contract - .execute_call_reply(deps.as_mut(), ctx.env, msg) - .unwrap(); - assert_eq!(res.attributes[1].value, "execute_callback") -} diff --git a/contracts/cosmwasm-vm/cw-xcall/tests/test_fee_handler.rs b/contracts/cosmwasm-vm/cw-xcall/tests/test_fee_handler.rs deleted file mode 100644 index 21a2bfe8..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/tests/test_fee_handler.rs +++ /dev/null @@ -1,207 +0,0 @@ -use std::str::FromStr; - -use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Coin, ContractResult, SystemResult, WasmQuery, -}; -use cw_xcall::{msg::QueryMsg, state::CwCallService}; -pub mod account; -use account::*; -use cw_xcall_lib::network_address::NetId; - -#[test] -fn set_protocol_fee_handler() { - let mut deps = mock_dependencies(); - let address = "xyz".to_string(); - - let contract = CwCallService::new(); - - contract - .set_admin( - deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - - contract - .fee_handler() - .save(&mut deps.storage, &address) - .unwrap(); - - let info = mock_info(&admin_one().to_string(), &[Coin::new(1000, "uconst")]); - - contract - .set_protocol_feehandler(deps.as_mut(), &info, address.clone()) - .unwrap(); - - let result = contract.get_protocol_feehandler(deps.as_ref()); - assert_eq!(address, result); -} - -#[test] -#[should_panic(expected = "OnlyAdmin")] -fn test_invalid_input() { - let mut deps = mock_dependencies(); - let info = mock_info("user", &[Coin::new(1000, "ucosm")]); - let address = "xyz".to_string(); - let cw_callservice = CwCallService::new(); - - cw_callservice - .set_admin( - deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - - let result = cw_callservice.query_admin(deps.as_ref().storage).unwrap(); - - assert_eq!(result, admin_one().to_string()); - - cw_callservice - .set_protocol_feehandler(deps.as_mut(), &info, address) - .unwrap(); -} - -#[test] -fn get_protocol_fee_handler() { - let mut deps = mock_dependencies(); - let address = "xyz".to_string(); - - let contract = CwCallService::new(); - - contract - .set_admin( - deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - contract - .fee_handler() - .save(&mut deps.storage, &address) - .unwrap(); - let info = mock_info(&admin_one().to_string(), &[Coin::new(1000, "ucosm")]); - contract - .set_protocol_feehandler(deps.as_mut(), &info, address) - .unwrap(); - let result = contract.get_protocol_feehandler(deps.as_ref()); - let env = mock_env(); - - assert_eq!("xyz", result); - let result = contract - .query(deps.as_ref(), env, QueryMsg::GetProtocolFeeHandler {}) - .unwrap(); - let result: String = from_json(result).unwrap(); - assert_eq!("xyz".to_string(), result); -} - -#[test] -fn set_protocol_fee() { - let mut deps = mock_dependencies(); - let value = 123; - let mut contract = CwCallService::new(); - - contract - .set_admin( - deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - - let info = mock_info(&admin_one().to_string(), &[Coin::new(1000, "uconst")]); - let result = contract.set_protocol_fee(deps.as_mut(), info.clone(), value); - assert_eq!(result.unwrap().attributes.len(), 1); - let env = mock_env(); - let result = contract - .execute( - deps.as_mut(), - env, - info, - cw_xcall_lib::xcall_msg::ExecuteMsg::SetProtocolFee { value }, - ) - .unwrap(); - println!("{result:?}"); - assert_eq!(result.attributes.len(), 1); -} - -#[test] -fn get_protocol_fee() { - let mut deps = mock_dependencies(); - let value = 123; - let contract = CwCallService::new(); - - contract - .set_admin( - deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - let info = mock_info(&admin_one().to_string(), &[Coin::new(1000, "ucosm")]); - contract - .set_protocol_fee(deps.as_mut(), info, value) - .unwrap(); - let result = contract.get_protocol_fee(deps.as_ref().storage); - assert_eq!("123", result.to_string()); - let env = mock_env(); - let result = contract - .query(deps.as_ref(), env, QueryMsg::GetProtocolFee {}) - .unwrap(); - let result: u128 = from_json(result).unwrap(); - assert_eq!("123", result.to_string()); -} - -#[test] -fn get_fee() { - let mut deps = mock_dependencies(); - let value = 123; - let contract = CwCallService::new(); - - contract - .set_admin( - deps.as_mut().storage, - Addr::unchecked(admin_one().to_string()), - ) - .unwrap(); - let env = mock_env(); - let info = mock_info(&admin_one().to_string(), &[Coin::new(1000, "ucosm")]); - contract - .set_protocol_fee(deps.as_mut(), info.clone(), value) - .unwrap(); - contract - .set_default_connection( - deps.as_mut(), - info, - NetId::from_str("icon").unwrap(), - Addr::unchecked("connectionaddress"), - ) - .unwrap(); - deps.querier.update_wasm(|r| match r { - WasmQuery::Smart { - contract_addr: _, - msg: _, - } => SystemResult::Ok(ContractResult::Ok(to_json_binary(&100_u128).unwrap())), - _ => todo!(), - }); - let result = contract - .get_fee( - deps.as_ref(), - NetId::from_str("icon").unwrap(), - true, - vec![], - ) - .unwrap(); - assert_eq!("223", result.to_string()); - let result = contract - .query( - deps.as_ref(), - env, - QueryMsg::GetFee { - nid: NetId::from_str("icon").unwrap(), - rollback: true, - sources: None, - }, - ) - .unwrap(); - let result: u128 = from_json(result).unwrap(); - assert_eq!("223", result.to_string()); -} diff --git a/contracts/cosmwasm-vm/cw-xcall/tests/test_handle_call_message.rs b/contracts/cosmwasm-vm/cw-xcall/tests/test_handle_call_message.rs deleted file mode 100644 index e30abc42..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/tests/test_handle_call_message.rs +++ /dev/null @@ -1,555 +0,0 @@ -mod account; -mod setup; -use crate::account::alice; - -use common::utils::keccak256; -use schemars::_serde_json::to_string; -use setup::test::*; -use setup::*; -use std::str::FromStr; - -use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Coin, CosmosMsg, Reply, SubMsgResponse, SubMsgResult, WasmMsg, -}; -use cw_xcall::{ - state::{CwCallService, EXECUTE_CALL_ID}, - types::{ - message::{CSMessage, CSMessageType}, - request::CSMessageRequest, - rollback::Rollback, - }, -}; -use cw_xcall_lib::{ - message::msg_type::MessageType, - network_address::{NetId, NetworkAddress}, -}; - -#[test] -#[should_panic(expected = "InvalidRequestId")] -fn test_execute_call_invalid_request_id() { - let cw_callservice = CwCallService::new(); - - let deps = mock_dependencies(); - - cw_callservice - .contains_proxy_request(&deps.storage, 123456) - .unwrap(); -} - -#[test] -#[should_panic(expected = "DataMismatch")] -fn test_execute_call_with_wrong_data() { - let mut deps = mock_dependencies(); - - let info = mock_info("user1", &[Coin::new(1000, "ucosm")]); - let cw_callservice = CwCallService::default(); - let data = vec![104, 101, 108, 108, 111]; - let request_id = 123456; - let proxy_requests = CSMessageRequest::new( - NetworkAddress::new("nid", "mockaddress"), - Addr::unchecked("88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f123t7"), - 123, - MessageType::CallMessage, - keccak256(&[104, 106, 108, 108, 111]).to_vec(), - vec![], - ); - cw_callservice - .store_proxy_request(deps.as_mut().storage, request_id, &proxy_requests) - .unwrap(); - - cw_callservice - .execute_call(deps.as_mut(), info, request_id, data) - .unwrap(); -} - -#[test] -fn test_execute_call_having_request_id_without_rollback() { - let mut deps = mock_dependencies(); - - let info = mock_info("user1", &[Coin::new(1000, "ucosm")]); - let cw_callservice = CwCallService::default(); - let data = vec![104, 101, 108, 108, 111]; - let request_id = 123456; - let proxy_requests = CSMessageRequest::new( - NetworkAddress::new("nid", "mockaddress"), - Addr::unchecked("88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f123t7"), - 123, - MessageType::CallMessage, - keccak256(&data).to_vec(), - vec![], - ); - cw_callservice - .store_proxy_request(deps.as_mut().storage, request_id, &proxy_requests) - .unwrap(); - - let res = cw_callservice - .execute_call(deps.as_mut(), info, request_id, data) - .unwrap(); - match &res.messages[0].msg { - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds: _, - }) => { - assert_eq!( - contract_addr, - "88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f123t7" - ); - - assert_eq!( - "\"eyJoYW5kbGVfY2FsbF9tZXNzYWdlIjp7ImZyb20iOiJuaWQvbW9ja2FkZHJlc3MiLCJkYXRhIjpbMTA0LDEwMSwxMDgsMTA4LDExMV19fQ==\"", - to_string(msg).unwrap() - ) - } - _ => {} - } -} - -#[test] -fn test_successful_reply_message() { - let mut mock_deps = deps(); - - let env = mock_env(); - - let msg = Reply { - id: EXECUTE_CALL_ID, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: None, - }), - }; - - let contract = CwCallService::default(); - - let request_id = 123456; - let proxy_requests = CSMessageRequest::new( - NetworkAddress::new("nid", "mockaddress"), - Addr::unchecked("88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f123t7"), - 123, - MessageType::CallMessage, - vec![], - vec![], - ); - contract - .store_proxy_request(mock_deps.as_mut().storage, request_id, &proxy_requests) - .unwrap(); - - contract - .store_execute_request_id(mock_deps.as_mut().storage, request_id) - .unwrap(); - - let response = contract.reply(mock_deps.as_mut(), env, msg).unwrap(); - - assert_eq!(response.events[0].attributes[1].value, 1.to_string()); -} - -#[test] -fn test_failed_reply_message() { - let mut mock_deps = deps(); - - let env = mock_env(); - - let msg = Reply { - id: EXECUTE_CALL_ID, - result: SubMsgResult::Err("error message".into()), - }; - - let contract = CwCallService::default(); - - let request_id = 123456; - let proxy_requests = CSMessageRequest::new( - NetworkAddress::new("nid", "mockaddress"), - Addr::unchecked("88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f123t7"), - 123, - MessageType::CallMessage, - vec![], - vec![], - ); - contract - .store_proxy_request(mock_deps.as_mut().storage, request_id, &proxy_requests) - .unwrap(); - - contract - .store_execute_request_id(mock_deps.as_mut().storage, request_id) - .unwrap(); - - let response = contract.reply(mock_deps.as_mut(), env, msg).unwrap(); - - assert_eq!(response.events[0].attributes[1].value, "0".to_string()); -} - -#[test] -#[should_panic(expected = "td(NotFound { kind: \"cw_xcall::types::request::CSMessageRequest\" })")] -fn test_invalid_sequence_no() { - let deps = mock_dependencies(); - let contract = CwCallService::new(); - contract - .get_proxy_request(deps.as_ref().storage, 123456) - .unwrap(); -} - -#[test] -fn execute_rollback_success() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); - - let env = mock_env(); - - let contract = CwCallService::default(); - contract - .instantiate( - mock_deps.as_mut(), - env, - mock_info.clone(), - cw_xcall::msg::InstantiateMsg { - network_id: "nid".to_string(), - denom: "arch".to_string(), - }, - ) - .unwrap(); - - let seq_id = 123456; - - let request = Rollback::new( - Addr::unchecked("88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f126e4"), - NetworkAddress::new("nid", "mockaddress"), - vec![], - vec![1, 2, 3], - true, - ); - - contract - .store_call_request(mock_deps.as_mut().storage, seq_id, &request) - .unwrap(); - - let response = contract - .execute_rollback(mock_deps.as_mut(), mock_env(), mock_info, seq_id) - .unwrap(); - - match response.messages[0].msg.clone() { - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: _, - msg, - funds: _, - }) => { - let data = String::from_utf8(msg.0).unwrap(); - assert_eq!( - "{\"handle_call_message\":{\"from\":\"nid/cosmos2contract\",\"data\":[1,2,3]}}", - data - ) - } - _ => todo!(), - } - assert_eq!(seq_id.to_string(), response.events[0].attributes[0].value) -} - -#[test] -#[should_panic(expected = "RollbackNotEnabled")] -fn execute_rollback_failure() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); - - let contract = CwCallService::default(); - - let seq_id = 123456; - - let request = Rollback::new( - Addr::unchecked("88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f126e4"), - NetworkAddress::new("nid", "mockaddress"), - vec![], - vec![], - false, - ); - - contract - .store_call_request(mock_deps.as_mut().storage, seq_id, &request) - .unwrap(); - - let response = contract - .execute_rollback(mock_deps.as_mut(), mock_env(), mock_info, seq_id) - .unwrap(); - - match response.messages[0].msg.clone() { - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: _, - msg, - funds: _, - }) => { - let r: Vec = from_json(msg).unwrap(); - - assert_eq!(vec![1, 2, 3], r) - } - _ => todo!(), - } -} - -#[test] -fn test_persisted_message_not_removed_on_error() { - let mut mock_deps = deps(); - - let env = mock_env(); - - let msg = Reply { - id: EXECUTE_CALL_ID, - result: SubMsgResult::Err("error message".into()), - }; - - let contract = CwCallService::default(); - - let request_id = 123456; - let proxy_requests = CSMessageRequest::new( - NetworkAddress::new("nid", "mockaddress"), - Addr::unchecked("88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f123t7"), - 123, - MessageType::CallMessagePersisted, - vec![], - vec![], - ); - contract - .store_proxy_request(mock_deps.as_mut().storage, request_id, &proxy_requests) - .unwrap(); - - contract - .store_execute_request_id(mock_deps.as_mut().storage, request_id) - .unwrap(); - - let _response = contract.reply(mock_deps.as_mut(), env, msg); - - assert!(_response.is_err()); -} - -#[test] -fn test_persisted_message_removed_on_success() { - let mut mock_deps = deps(); - - let env = mock_env(); - - let msg = Reply { - id: EXECUTE_CALL_ID, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: to_json_binary(&1).ok(), - }), - }; - - let contract = CwCallService::default(); - - let request_id = 123456; - let proxy_requests = CSMessageRequest::new( - NetworkAddress::new("nid", "mockaddress"), - Addr::unchecked("88bd05442686be0a5df7da33b6f1089ebfea3769b19dbb2477fe0cd6e0f123t7"), - 123, - MessageType::CallMessagePersisted, - vec![], - vec![], - ); - contract - .store_proxy_request(mock_deps.as_mut().storage, request_id, &proxy_requests) - .unwrap(); - - contract - .store_execute_request_id(mock_deps.as_mut().storage, request_id) - .unwrap(); - - let _response = contract.reply(mock_deps.as_mut(), env, msg).unwrap(); - - let req = contract - .get_proxy_request(mock_deps.as_ref().storage, request_id) - .ok(); - assert_eq!(req, None); -} - -#[test] -fn test_handle_reply() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - - ctx.init_context(deps.as_mut().storage, &contract); - - let request = get_dummy_req_msg(); - let rollback = get_dummy_rollback_data(); - - let res = contract.handle_reply(deps.as_mut(), rollback, request); - assert!(res.is_ok()) -} - -#[test] -#[should_panic(expected = "InvalidReplyReceived")] -fn test_handle_reply_fail() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - - ctx.init_context(deps.as_mut().storage, &contract); - - let request = CSMessageRequest::new( - get_dummy_network_address("icon"), - Addr::unchecked("dapp"), - 1, - MessageType::CallMessage, - keccak256(&[1, 2, 3]).to_vec(), - vec![], - ); - let rollback = get_dummy_rollback_data(); - - contract - .handle_reply(deps.as_mut(), rollback, request) - .unwrap(); -} - -#[test] -#[should_panic(expected = "ProtocolsMismatch")] -fn test_handle_request_fail_on_mismatch_protocols_request() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - - ctx.init_context(deps.as_mut().storage, &contract); - - let data = ctx.request_message.unwrap().as_bytes(); - let src_net = NetId::from_str("evm").unwrap(); - contract - .handle_request(deps.as_mut(), ctx.info, src_net, &data) - .unwrap(); -} - -#[test] -#[should_panic(expected = "ProtocolsMismatch")] -fn test_handle_request_fail_on_invalid_source() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - - ctx.init_context(deps.as_mut().storage, &contract); - - let nid = NetId::from_str("archway").unwrap(); - let data = ctx.request_message.unwrap().as_bytes(); - contract - .handle_request(deps.as_mut(), ctx.info, nid, &data) - .unwrap(); -} - -#[test] -fn test_handle_request_from_multiple_protocols() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - - ctx.init_context(deps.as_mut().storage, &contract); - - let request = CSMessageRequest::new( - get_dummy_network_address("archway"), - Addr::unchecked("dapp"), - 1, - MessageType::CallMessage, - keccak256(&[1, 2, 3]).to_vec(), - vec!["centralized".to_string(), "ibc".to_string()], - ); - - let nid = NetId::from_str("archway").unwrap(); - for protocol in request.protocols() { - let info = create_mock_info(protocol, "icx", 100); - let res = contract - .handle_request(deps.as_mut(), info, nid.clone(), &request.as_bytes()) - .unwrap(); - if protocol == "ibc" { - assert_eq!(res.attributes[0].value, "call_service"); - } else { - assert_eq!(res.attributes.len(), 0) - } - } -} - -#[test] -#[should_panic(expected = "CallRequestNotFound { sn: 1 }")] -fn test_handle_call_message_fail_on_invalid_request() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - - ctx.init_context(deps.as_mut().storage, &contract); - - let message_result = get_dummy_result_message(); - let msg = CSMessage::new(CSMessageType::CSMessageResult, message_result.as_bytes()); - - let nid = NetId::from_str("archway").unwrap(); - contract - .handle_message(deps.as_mut(), ctx.info, nid, msg.as_bytes()) - .unwrap(); -} - -#[test] -#[should_panic(expected = "ProtocolsMismatch")] -fn test_handle_result_fail_on_invalid_source() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - - ctx.init_context(deps.as_mut().storage, &contract); - - let rollback = get_dummy_rollback_data(); - contract - .store_call_request(deps.as_mut().storage, 1, &rollback) - .unwrap(); - - let msg = get_dummy_result_message().as_bytes(); - contract - .handle_result(deps.as_mut(), ctx.info, &msg) - .unwrap(); -} - -#[test] -fn test_handle_result_from_multiple_protocols() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - - ctx.init_context(deps.as_mut().storage, &contract); - - let rollback = Rollback::new( - Addr::unchecked("xcall"), - get_dummy_network_address("archway"), - vec!["centralized".to_string(), "ibc".to_string()], - vec![1, 2, 3], - false, - ); - contract - .store_call_request(deps.as_mut().storage, 1, &rollback) - .unwrap(); - - let msg = get_dummy_result_message().as_bytes(); - - for protocol in rollback.protocols() { - let info = create_mock_info(protocol, "arch", 100); - let res = contract.handle_result(deps.as_mut(), info, &msg).unwrap(); - if protocol == "centralized" { - assert_eq!(res.attributes.len(), 0); - } else { - assert_eq!(res.attributes[1].value, "handle_response") - } - } -} - -#[test] -fn test_handle_result_on_error_response() { - let ctx = TestContext::default(); - let mut deps = deps(); - let contract = CwCallService::new(); - let info = create_mock_info("centralized", "arch", 100); - - ctx.init_reply_state(deps.as_mut().storage, &contract); - - let rollback = get_dummy_rollback_data(); - contract - .store_call_request(deps.as_mut().storage, 1, &rollback) - .unwrap(); - - let msg = get_dummy_result_message_failure().as_bytes(); - let res = contract.handle_result(deps.as_mut(), info, &msg).unwrap(); - assert_eq!(res.attributes[1].value, "handle_response") -} diff --git a/contracts/cosmwasm-vm/cw-xcall/tests/test_request.rs b/contracts/cosmwasm-vm/cw-xcall/tests/test_request.rs deleted file mode 100644 index e135697f..00000000 --- a/contracts/cosmwasm-vm/cw-xcall/tests/test_request.rs +++ /dev/null @@ -1,196 +0,0 @@ -mod account; -mod setup; - -use std::str::FromStr; - -use cosmwasm_std::testing::mock_env; -use cw_xcall::{error::ContractError, state::CwCallService}; -use cw_xcall_lib::network_address::NetId; -use setup::test::*; - -#[test] -fn update_sequence() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - contract.sn().save(mock_deps.as_mut().storage, &0).unwrap(); - - let result = contract - .query_last_sequence_no(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(result, 0); - - let updated = contract - .increment_last_sequence_no(mock_deps.as_mut().storage) - .unwrap(); - - let result = contract - .query_last_sequence_no(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(result, updated); -} - -#[test] -#[should_panic(expected = "Std(NotFound { kind: \"u128\" })")] - -fn update_sequence_without_proper_initialisation() { - let mock_deps = deps(); - - let contract = CwCallService::default(); - - let result = contract - .query_last_sequence_no(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(result, 1); -} - -#[test] -fn update_request_id() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - contract - .last_request_id() - .save(mock_deps.as_mut().storage, &0) - .unwrap(); - - let result = contract - .query_last_request_id(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(result, 0); - - contract - .increment_last_request_id(mock_deps.as_mut().storage) - .unwrap(); - - let result = contract - .query_last_request_id(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(result, 1); -} - -#[test] -#[should_panic(expected = "Std(NotFound { kind: \"u128\" })")] -fn update_request_id_without_proper_initialisation() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - contract - .increment_last_request_id(mock_deps.as_mut().storage) - .unwrap(); - - let result = contract - .query_last_request_id(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(result, 1); -} - -#[test] -fn set_sequence() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - contract.sn().save(mock_deps.as_mut().storage, &0).unwrap(); - - let updated = contract - .set_last_sequence_no(mock_deps.as_mut().storage, 20) - .unwrap(); - - let result = contract - .query_last_sequence_no(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(result, updated); -} - -#[test] -fn set_request_id() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - contract - .last_request_id() - .save(mock_deps.as_mut().storage, &0) - .unwrap(); - - let updated = contract - .set_last_request_id(mock_deps.as_mut().storage, 20) - .unwrap(); - - let result = contract - .query_last_request_id(mock_deps.as_ref().storage) - .unwrap(); - - assert_eq!(result, updated); -} - -#[test] -#[should_panic(expected = "Std(NotFound { kind: \"u128\" })")] -fn set_sequence_without_proper_initialisation() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - contract - .set_last_sequence_no(mock_deps.as_mut().storage, 20) - .unwrap(); -} - -#[test] -#[should_panic(expected = "Std(NotFound { kind: \"u128\" })")] -fn set_request_id_without_proper_initialisation() { - let mut mock_deps = deps(); - - let contract = CwCallService::default(); - - contract - .set_last_request_id(mock_deps.as_mut().storage, 20) - .unwrap(); -} - -#[test] -fn invalid_network_id() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info("test", "umlg", 2000); - - let env = mock_env(); - - let contract = CwCallService::default(); - contract - .instantiate( - mock_deps.as_mut(), - env, - mock_info.clone(), - cw_xcall::msg::InstantiateMsg { - network_id: "nid".to_string(), - denom: "arch".to_string(), - }, - ) - .unwrap(); - - let response = contract.handle_message( - mock_deps.as_mut(), - mock_info, - NetId::from_str("nid").unwrap(), - vec![], - ); - - assert!(response.is_err()); - let error = response.err().unwrap(); - assert_eq!( - error.to_string(), - ContractError::ProtocolsMismatch.to_string() - ); -} diff --git a/scripts/optimize-cosmwasm.sh b/scripts/optimize-cosmwasm.sh index 769704fa..29b8be24 100755 --- a/scripts/optimize-cosmwasm.sh +++ b/scripts/optimize-cosmwasm.sh @@ -9,7 +9,7 @@ RUSTC_VERS="1.78.0" MAX_WASM_SIZE=800 # 800 KB -PROJECTS=("cw-xcall" "cw-xcall-lib") +PROJECTS=("cw-intents-v1") # Install wasm-opt binary if ! which wasm-opt; then @@ -47,9 +47,7 @@ done # check all generated wasm files -cosmwasm-check artifacts/archway/cw_mock_dapp.wasm -cosmwasm-check artifacts/archway/cw_mock_dapp_multi.wasm -cosmwasm-check artifacts/archway/cw_xcall.wasm +cosmwasm-check artifacts/archway/cw_intents_v1.wasm # Update version