From 21b929cc1460c509a3551c81868111b567cd8859 Mon Sep 17 00:00:00 2001 From: Itshyphen <075bct064.ranju@pcampus.edu.np> Date: Wed, 9 Oct 2024 10:36:14 +0545 Subject: [PATCH 01/13] fix: checkpoint --- Cargo.lock | 143 +++++++- contracts/soroban/Cargo.lock | 274 ++++++++++++-- .../contracts/cluster-connection/Cargo.toml | 17 + .../cluster-connection/src/contract.rs | 192 ++++++++++ .../cluster-connection/src/errors.rs | 18 + .../contracts/cluster-connection/src/event.rs | 19 + .../cluster-connection/src/helpers.rs | 114 ++++++ .../src/interfaces/interface_xcall.rs | 15 + .../cluster-connection/src/interfaces/mod.rs | 1 + .../contracts/cluster-connection/src/lib.rs | 10 + .../cluster-connection/src/storage.rs | 190 ++++++++++ .../contracts/cluster-connection/src/test.rs | 345 ++++++++++++++++++ .../contracts/cluster-connection/src/types.rs | 38 ++ 13 files changed, 1320 insertions(+), 56 deletions(-) create mode 100644 contracts/soroban/contracts/cluster-connection/Cargo.toml create mode 100644 contracts/soroban/contracts/cluster-connection/src/contract.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/errors.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/event.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/helpers.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/interfaces/mod.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/lib.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/storage.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/test.rs create mode 100644 contracts/soroban/contracts/cluster-connection/src/types.rs diff --git a/Cargo.lock b/Cargo.lock index 36dc35858..f00ebfe08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,7 +151,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -160,7 +160,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -285,6 +285,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "clear_on_drop" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38508a63f4979f0048febc9966fadbd48e5dab31fd0ec6a3f151bbf4a74f7423" +dependencies = [ + "cc", +] + +[[package]] +name = "cluster-connection" +version = "0.0.0" +dependencies = [ + "curve25519-dalek 1.2.6", + "ed25519-dalek 1.0.1", + "soroban-sdk", +] + [[package]] name = "common" version = "0.1.0" @@ -455,7 +473,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array", + "generic-array 0.14.7", "rand_core 0.6.4", "subtle", "zeroize", @@ -467,7 +485,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array", + "generic-array 0.14.7", "rand_core 0.6.4", "subtle", "zeroize", @@ -479,7 +497,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array", + "generic-array 0.14.7", "typenum", ] @@ -493,6 +511,19 @@ dependencies = [ "syn 2.0.42", ] +[[package]] +name = "curve25519-dalek" +version = "1.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d59fed08e452f286b251f88b2fc64a01f50a7b263aa09557ad7285d9e7fa" +dependencies = [ + "byteorder", + "clear_on_drop", + "digest 0.8.1", + "rand_core 0.3.1", + "subtle", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1024,13 +1055,22 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -1132,6 +1172,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", + "rand 0.7.3", + "sha2 0.9.9", + "zeroize", +] + [[package]] name = "ed25519-dalek" version = "2.1.1" @@ -1179,7 +1232,7 @@ dependencies = [ "der 0.6.1", "digest 0.10.7", "ff 0.12.1", - "generic-array", + "generic-array 0.14.7", "group 0.12.1", "pkcs8 0.9.0", "rand_core 0.6.4", @@ -1198,7 +1251,7 @@ dependencies = [ "crypto-bigint 0.5.5", "digest 0.10.7", "ff 0.13.0", - "generic-array", + "generic-array 0.14.7", "group 0.13.0", "pkcs8 0.10.2", "rand_core 0.6.4", @@ -1387,6 +1440,15 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -2181,6 +2243,17 @@ dependencies = [ "proc-macro2 1.0.70", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -2188,10 +2261,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -2202,6 +2285,21 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -2217,6 +2315,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -2455,7 +2562,7 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct 0.1.1", "der 0.6.1", - "generic-array", + "generic-array 0.14.7", "pkcs8 0.9.0", "subtle", "zeroize", @@ -2469,7 +2576,7 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct 0.2.0", "der 0.7.9", - "generic-array", + "generic-array 0.14.7", "pkcs8 0.10.2", "subtle", "zeroize", @@ -2733,9 +2840,9 @@ dependencies = [ "backtrace", "curve25519-dalek 4.1.3", "ecdsa 0.16.9", - "ed25519-dalek", + "ed25519-dalek 2.1.1", "elliptic-curve 0.13.8", - "generic-array", + "generic-array 0.14.7", "getrandom", "hex-literal 0.4.1", "hmac", @@ -2744,8 +2851,8 @@ dependencies = [ "num-integer", "num-traits", "p256", - "rand", - "rand_chacha", + "rand 0.8.5", + "rand_chacha 0.3.1", "sec1 0.7.3", "sha2 0.10.8", "sha3", @@ -2802,8 +2909,8 @@ dependencies = [ "arbitrary", "bytes-lit", "ctor", - "ed25519-dalek", - "rand", + "ed25519-dalek 2.1.1", + "rand 0.8.5", "serde", "serde_json", "soroban-env-guest", @@ -3101,7 +3208,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test 0.16.4", "hex", - "hex-literal 0.3.4", + "hex-literal 0.4.1", "ibc-proto", "prost 0.11.9", "serde", diff --git a/contracts/soroban/Cargo.lock b/contracts/soroban/Cargo.lock index e571a9ffa..b02fd6efe 100644 --- a/contracts/soroban/Cargo.lock +++ b/contracts/soroban/Cargo.lock @@ -92,13 +92,22 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -107,6 +116,12 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes-lit" version = "0.0.5" @@ -151,6 +166,24 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "clear_on_drop" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38508a63f4979f0048febc9966fadbd48e5dab31fd0ec6a3f151bbf4a74f7423" +dependencies = [ + "cc", +] + +[[package]] +name = "cluster-connection" +version = "0.0.0" +dependencies = [ + "curve25519-dalek 1.2.6", + "ed25519-dalek 1.0.1", + "soroban-sdk", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -189,8 +222,8 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array", - "rand_core", + "generic-array 0.14.7", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -201,7 +234,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array", + "generic-array 0.14.7", "typenum", ] @@ -215,6 +248,32 @@ dependencies = [ "syn", ] +[[package]] +name = "curve25519-dalek" +version = "1.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d59fed08e452f286b251f88b2fc64a01f50a7b263aa09557ad7285d9e7fa" +dependencies = [ + "byteorder", + "clear_on_drop", + "digest 0.8.1", + "rand_core 0.3.1", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "curve25519-dalek" version = "4.1.2" @@ -224,7 +283,7 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest", + "digest 0.10.7", "fiat-crypto", "platforms", "rustc_version", @@ -309,13 +368,31 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "const-oid", "crypto-common", "subtle", @@ -334,13 +411,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest", + "digest 0.10.7", "elliptic-curve", "rfc6979", - "signature", + "signature 2.2.0", "spki", ] +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", +] + [[package]] name = "ed25519" version = "2.2.3" @@ -348,7 +434,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", - "signature", + "signature 2.2.0", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", + "rand 0.7.3", + "sha2 0.9.9", + "zeroize", ] [[package]] @@ -357,11 +456,11 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek", - "ed25519", - "rand_core", + "curve25519-dalek 4.1.2", + "ed25519 2.2.3", + "rand_core 0.6.4", "serde", - "sha2", + "sha2 0.10.8", "zeroize", ] @@ -379,12 +478,12 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "digest 0.10.7", "ff", - "generic-array", + "generic-array 0.14.7", "group", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -414,7 +513,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -430,6 +529,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -467,7 +575,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -504,7 +612,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -598,8 +706,8 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2", - "signature", + "sha2 0.10.8", + "signature 2.2.0", ] [[package]] @@ -716,6 +824,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "paste" version = "1.0.14" @@ -778,6 +892,17 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -785,8 +910,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -796,9 +931,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", ] +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + [[package]] name = "rand_core" version = "0.6.4" @@ -808,6 +964,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -847,7 +1012,7 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", - "generic-array", + "generic-array 0.14.7", "pkcs8", "subtle", "zeroize", @@ -920,6 +1085,19 @@ dependencies = [ "syn", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.8" @@ -928,7 +1106,7 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] @@ -937,18 +1115,24 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest", + "digest 0.10.7", "keccak", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + [[package]] name = "signature" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", - "rand_core", + "digest 0.10.7", + "rand_core 0.6.4", ] [[package]] @@ -1004,8 +1188,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "114a0fa0d0cc39d0be16b1ee35b6e5f4ee0592ddcf459bde69391c02b03cf520" dependencies = [ "backtrace", - "curve25519-dalek", - "ed25519-dalek", + "curve25519-dalek 4.1.2", + "ed25519-dalek 2.0.0", "getrandom", "hex-literal", "hmac", @@ -1013,9 +1197,9 @@ dependencies = [ "num-derive", "num-integer", "num-traits", - "rand", - "rand_chacha", - "sha2", + "rand 0.8.5", + "rand_chacha 0.3.1", + "sha2 0.10.8", "sha3", "soroban-builtin-sdk-macros", "soroban-env-common", @@ -1069,8 +1253,8 @@ dependencies = [ "arbitrary", "bytes-lit", "ctor", - "ed25519-dalek", - "rand", + "ed25519-dalek 2.0.0", + "rand 0.8.5", "serde", "serde_json", "soroban-env-guest", @@ -1092,7 +1276,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "sha2", + "sha2 0.10.8", "soroban-env-common", "soroban-spec", "soroban-spec-rust", @@ -1121,7 +1305,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "sha2", + "sha2 0.10.8", "soroban-spec", "stellar-xdr", "syn", @@ -1472,3 +1656,17 @@ name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/contracts/soroban/contracts/cluster-connection/Cargo.toml b/contracts/soroban/contracts/cluster-connection/Cargo.toml new file mode 100644 index 000000000..3fded6eed --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "cluster-connection" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] +doctest = false + +[dependencies] +soroban-sdk = { workspace = true, features = ["alloc"] } +ed25519-dalek = { version = "1.0.1", default-features = false, features = ["alloc"] } +curve25519-dalek = { version = "1", default-features = false, features = ["alloc"] } + +[dev-dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/contracts/soroban/contracts/cluster-connection/src/contract.rs b/contracts/soroban/contracts/cluster-connection/src/contract.rs new file mode 100644 index 000000000..92f72ece3 --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/contract.rs @@ -0,0 +1,192 @@ +use soroban_sdk::{contract, contractimpl, token, Address, Bytes, BytesN, Env, String, Vec}; + +use crate::{errors::ContractError, event, helpers, storage, types::InitializeMsg}; + +#[contract] +pub struct ClusterConnection; + +#[contractimpl] +impl ClusterConnection { + pub fn initialize(env: Env, msg: InitializeMsg) -> Result<(), ContractError> { + storage::is_initialized(&env)?; + + storage::store_native_token(&env, msg.native_token); + storage::store_conn_sn(&env, 0); + storage::store_admin(&env, msg.relayer); + storage::store_xcall(&env, msg.xcall_address); + storage::store_upgrade_authority(&env, msg.upgrade_authority); + + Ok(()) + } + + pub fn get_admin(env: Env) -> Result { + let address = storage::admin(&env)?; + Ok(address) + } + + pub fn set_admin(env: Env, address: Address) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + storage::store_admin(&env, address); + Ok(()) + } + + pub fn get_upgrade_authority(env: Env) -> Result { + let address = storage::get_upgrade_authority(&env)?; + Ok(address) + } + + pub fn set_upgrade_authority(env: &Env, address: Address) -> Result<(), ContractError> { + helpers::ensure_upgrade_authority(&env)?; + storage::store_upgrade_authority(&env, address); + + Ok(()) + } + + pub fn send_message( + env: Env, + tx_origin: Address, + to: String, + sn: i64, + msg: Bytes, + ) -> Result<(), ContractError> { + helpers::ensure_xcall(&env)?; + + let next_conn_sn = storage::get_next_conn_sn(&env); + storage::store_conn_sn(&env, next_conn_sn); + + let mut fee: u128 = 0; + if sn >= 0 { + fee = helpers::get_network_fee(&env, to.clone(), sn > 0)?; + } + if fee > 0 { + helpers::transfer_token(&env, &tx_origin, &env.current_contract_address(), &fee)?; + } + event::send_message(&env, to, next_conn_sn, msg); + + Ok(()) + } + + pub fn recv_message( + env: Env, + src_network: String, + conn_sn: u128, + msg: Bytes, + ) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + + if storage::get_sn_receipt(&env, src_network.clone(), conn_sn) { + return Err(ContractError::DuplicateMessage); + } + storage::store_receipt(&env, src_network.clone(), conn_sn); + + helpers::call_xcall_handle_message(&env, &src_network, msg)?; + Ok(()) + } + + pub fn revert_message(env: &Env, sn: u128) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + helpers::call_xcall_handle_error(&env, sn)?; + + Ok(()) + } + + pub fn recv_message_with_signatures( + env: Env, + src_network: String, + conn_sn: u128, + msg: Bytes, + signatures: Vec>, + ) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + + if !helpers::verify_signatures(&env, signatures, msg.clone()){ + return Err(ContractError::SignatureVerificationFailed); + }; + + if storage::get_sn_receipt(&env, src_network.clone(), conn_sn) { + return Err(ContractError::DuplicateMessage); + } + storage::store_receipt(&env, src_network.clone(), conn_sn); + + helpers::call_xcall_handle_message(&env, &src_network, msg)?; + Ok(()) + } + + pub fn set_fee( + env: Env, + network_id: String, + message_fee: u128, + response_fee: u128, + ) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + + storage::store_network_fee(&env, network_id, message_fee, response_fee); + Ok(()) + } + + pub fn claim_fees(env: Env) -> Result<(), ContractError> { + let admin = helpers::ensure_admin(&env)?; + + let token_addr = storage::native_token(&env)?; + let client = token::Client::new(&env, &token_addr); + let balance = client.balance(&env.current_contract_address()); + + client.transfer(&env.current_contract_address(), &admin, &balance); + Ok(()) + } + + pub fn add_validator(env: Env, address: Address) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + let validators = storage::get_validators(&env).unwrap(); + if validators.contains(&address) { + return Err(ContractError::ValidatorAlreadyAdded); + } + storage::add_validator(&env, address); + Ok(()) + } + + pub fn remove_validator(env: Env, address: Address) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + let validators: Vec
= storage::get_validators(&env).unwrap(); + let threshold = storage::get_validators_threshold(&env).unwrap(); + let admin = storage::admin(&env).unwrap(); + + let index = validators.iter().position(|v| v == address); + if index.is_none() { + return Err(ContractError::ValidatorNotFound); + } + if address == admin { + return Err(ContractError::CannotRemoveAdmin); + } + if (validators.len() as u32) <= threshold { + return Err(ContractError::ThresholdExceeded); + } + storage::remove_validator(&env, address); + Ok(()) + } + + pub fn get_validators(env: Env) -> Result, ContractError> { + let validators = storage::get_validators(&env).unwrap(); + Ok(validators) + } + + pub fn get_fee(env: Env, network_id: String, response: bool) -> Result { + helpers::get_network_fee(&env, network_id, response) + } + + pub fn get_receipt(env: Env, network_id: String, sn: u128) -> bool { + storage::get_sn_receipt(&env, network_id, sn) + } + + pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) -> Result<(), ContractError> { + helpers::ensure_upgrade_authority(&env)?; + env.deployer().update_current_contract_wasm(new_wasm_hash); + + Ok(()) + } + + pub fn extend_instance_storage(env: Env) -> Result<(), ContractError> { + storage::extend_instance(&env); + Ok(()) + } +} diff --git a/contracts/soroban/contracts/cluster-connection/src/errors.rs b/contracts/soroban/contracts/cluster-connection/src/errors.rs new file mode 100644 index 000000000..b4d505179 --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/errors.rs @@ -0,0 +1,18 @@ +use soroban_sdk::contracterror; + +#[contracterror] +#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord)] +#[repr(u32)] +pub enum ContractError { + OnlyAdmin = 1, + Uninitialized = 2, + AlreadyInitialized = 3, + InsufficientFund = 4, + DuplicateMessage = 5, + NetworkNotSupported = 6, + CannotRemoveAdmin = 7, + ThresholdExceeded = 8, + ValidatorNotFound = 9, + ValidatorAlreadyAdded = 10, + SignatureVerificationFailed = 11, +} diff --git a/contracts/soroban/contracts/cluster-connection/src/event.rs b/contracts/soroban/contracts/cluster-connection/src/event.rs new file mode 100644 index 000000000..6db6d215e --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/event.rs @@ -0,0 +1,19 @@ +#![allow(non_snake_case)] + +use soroban_sdk::{contracttype, Bytes, Env, String}; + +#[contracttype] +pub struct SendMsgEvent { + pub targetNetwork: String, + pub connSn: u128, + pub msg: Bytes, +} + +pub(crate) fn send_message(e: &Env, targetNetwork: String, connSn: u128, msg: Bytes) { + let emit_message = SendMsgEvent { + targetNetwork, + connSn, + msg, + }; + e.events().publish(("Message",), emit_message); +} diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs new file mode 100644 index 000000000..a639a1f7f --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs @@ -0,0 +1,114 @@ +use core::panic; + +use soroban_sdk::{token, Address, Bytes, BytesN, Env, FromVal, Map, String, Vec}; +use ed25519_dalek::{PublicKey, Signature, Verifier}; +use crate::{errors::ContractError, interfaces::interface_xcall::XcallClient, storage}; + +pub fn ensure_admin(e: &Env) -> Result { + let admin = storage::admin(&e)?; + admin.require_auth(); + + Ok(admin) +} + +pub fn ensure_upgrade_authority(e: &Env) -> Result { + let authority = storage::get_upgrade_authority(&e)?; + authority.require_auth(); + + Ok(authority) +} + +pub fn ensure_xcall(e: &Env) -> Result { + let xcall = storage::get_xcall(&e)?; + xcall.require_auth(); + + Ok(xcall) +} + +pub fn get_network_fee( + env: &Env, + network_id: String, + response: bool, +) -> Result { + let mut fee = storage::get_msg_fee(&env, network_id.clone())?; + if response { + fee += storage::get_res_fee(&env, network_id)?; + } + + Ok(fee) +} + +pub fn transfer_token( + e: &Env, + from: &Address, + to: &Address, + amount: &u128, +) -> Result<(), ContractError> { + let native_token = storage::native_token(&e)?; + let client = token::Client::new(&e, &native_token); + + client.transfer(&from, &to, &(*amount as i128)); + Ok(()) +} + +pub fn verify_signatures( + e: &Env, + signatures: Vec>, + message: Bytes, +) -> bool { + let validators = storage::get_validators(e).unwrap(); + let threshold = storage::get_validators_threshold(e).unwrap(); + + if signatures.len() < threshold { + return false + } + let message_hash = e.crypto().sha256(&message); + let mut unique_validators = Map::new(e); + let mut count = 0; + + + for signature in signatures.iter() { + if let Ok(sig) = convert_signature_to_dalek(&signature) { + for validator in validators.iter() { + if let Ok(public_key) = convert_address_to_public_key(e, &validator) { + if public_key.verify(&message_hash.to_array(), &sig).is_ok() { + if !unique_validators.contains_key(validator.clone()) { + unique_validators.set(validator, count); + count += 1; + } + break; + } + } + } + } + } + (unique_validators.len() as u32) >= threshold + +} + + +pub fn call_xcall_handle_message(e: &Env, nid: &String, msg: Bytes) -> Result<(), ContractError> { + let xcall_addr = storage::get_xcall(&e)?; + let client = XcallClient::new(&e, &xcall_addr); + client.handle_message(&e.current_contract_address(), nid, &msg); + + Ok(()) +} + +pub fn call_xcall_handle_error(e: &Env, sn: u128) -> Result<(), ContractError> { + let xcall_addr = storage::get_xcall(&e)?; + let client = XcallClient::new(&e, &xcall_addr); + client.handle_error(&e.current_contract_address(), &sn); + + Ok(()) +} + +fn convert_address_to_public_key(e: &Env, address: &Address) -> Result { + let bytes: BytesN<32> = BytesN::from_val(e, &address.to_val()); + PublicKey::from_bytes(&bytes.to_array()) +} + +// Helper function to convert a BytesN<64> to ed25519_dalek::Signature +fn convert_signature_to_dalek(signature: &BytesN<64>) -> Result { + Signature::from_bytes(&signature.to_array()) +} \ No newline at end of file diff --git a/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs b/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs new file mode 100644 index 000000000..c49d6c9c7 --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs @@ -0,0 +1,15 @@ +use soroban_sdk::{contractclient, Address, Bytes, Env, String}; + +use crate::errors::ContractError; + +#[contractclient(name = "XcallClient")] +pub trait IXcall { + fn handle_message( + env: Env, + sender: Address, + from_nid: String, + msg: Bytes, + ) -> Result<(), ContractError>; + + fn handle_error(env: Env, sender: Address, sequence_no: u128) -> Result<(), ContractError>; +} diff --git a/contracts/soroban/contracts/cluster-connection/src/interfaces/mod.rs b/contracts/soroban/contracts/cluster-connection/src/interfaces/mod.rs new file mode 100644 index 000000000..61f8fdfe8 --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/interfaces/mod.rs @@ -0,0 +1 @@ +pub mod interface_xcall; diff --git a/contracts/soroban/contracts/cluster-connection/src/lib.rs b/contracts/soroban/contracts/cluster-connection/src/lib.rs new file mode 100644 index 000000000..1fd060736 --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/lib.rs @@ -0,0 +1,10 @@ +#![no_std] + +pub mod contract; +pub mod errors; +pub mod event; +pub mod helpers; +pub mod interfaces; +pub mod storage; +pub mod test; +pub mod types; diff --git a/contracts/soroban/contracts/cluster-connection/src/storage.rs b/contracts/soroban/contracts/cluster-connection/src/storage.rs new file mode 100644 index 000000000..256a44bc8 --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/storage.rs @@ -0,0 +1,190 @@ +use soroban_sdk::{vec, Address, Env, String, Vec}; + +use crate::{ + errors::ContractError, + types::{NetworkFee, StorageKey}, +}; + +const DAY_IN_LEDGERS: u32 = 17280; // assumes 5s a ledger + +const LEDGER_THRESHOLD_INSTANCE: u32 = DAY_IN_LEDGERS * 30; // ~ 30 days +const LEDGER_BUMP_INSTANCE: u32 = LEDGER_THRESHOLD_INSTANCE + DAY_IN_LEDGERS; // ~ 31 days + +const LEDGER_THRESHOLD_PERSISTENT: u32 = DAY_IN_LEDGERS * 30; // ~ 30 days +const LEDGER_BUMP_PERSISTENT: u32 = LEDGER_THRESHOLD_PERSISTENT + DAY_IN_LEDGERS; // ~ 31 days + +pub fn is_initialized(e: &Env) -> Result<(), ContractError> { + let initialized = e.storage().instance().has(&StorageKey::Admin); + if initialized { + Err(ContractError::AlreadyInitialized) + } else { + Ok(()) + } +} + +pub fn admin(e: &Env) -> Result { + e.storage() + .instance() + .get(&StorageKey::Admin) + .ok_or(ContractError::Uninitialized) +} + +pub fn get_upgrade_authority(e: &Env) -> Result { + e.storage() + .instance() + .get(&StorageKey::UpgradeAuthority) + .ok_or(ContractError::Uninitialized) +} + +pub fn get_xcall(e: &Env) -> Result { + e.storage() + .instance() + .get(&StorageKey::Xcall) + .ok_or(ContractError::Uninitialized) +} + +pub fn native_token(e: &Env) -> Result { + e.storage() + .instance() + .get(&StorageKey::Xlm) + .ok_or(ContractError::Uninitialized) +} + +pub fn get_conn_sn(e: &Env) -> Result { + e.storage() + .instance() + .get(&StorageKey::ConnSn) + .ok_or(ContractError::Uninitialized) +} + +pub fn get_next_conn_sn(e: &Env) -> u128 { + let mut sn = e.storage().instance().get(&StorageKey::ConnSn).unwrap_or(0); + sn += 1; + sn +} + +pub fn get_msg_fee(e: &Env, network_id: String) -> Result { + let key = StorageKey::NetworkFee(network_id); + let network_fee: NetworkFee = e + .storage() + .persistent() + .get(&key) + .unwrap_or(NetworkFee::default()); + + if network_fee.message_fee > 0 { + extend_persistent(e, &key); + } + + Ok(network_fee.message_fee) +} + +pub fn get_res_fee(e: &Env, network_id: String) -> Result { + let key = StorageKey::NetworkFee(network_id); + let network_fee: NetworkFee = e + .storage() + .persistent() + .get(&key) + .unwrap_or(NetworkFee::default()); + + if network_fee.response_fee > 0 { + extend_persistent(e, &key); + } + + Ok(network_fee.response_fee) +} + +pub fn get_sn_receipt(e: &Env, network_id: String, sn: u128) -> bool { + let key = StorageKey::Receipts(network_id, sn); + let is_received = e.storage().persistent().get(&key).unwrap_or(false); + if is_received { + extend_persistent(e, &key); + } + + is_received +} + +pub fn get_validators_threshold(e: &Env) -> Result { + e.storage() + .instance() + .get(&StorageKey::ValidatorThreshold) + .ok_or(ContractError::Uninitialized) +} + +pub fn get_validators(e: &Env) -> Result, ContractError> { + e.storage() + .instance() + .get(&StorageKey::Validators) + .ok_or(ContractError::Uninitialized) +} + +pub fn store_receipt(e: &Env, network_id: String, sn: u128) { + let key = StorageKey::Receipts(network_id, sn); + e.storage().persistent().set(&key, &true); + extend_persistent(e, &key); +} + +pub fn store_admin(e: &Env, admin: Address) { + e.storage().instance().set(&StorageKey::Admin, &admin); +} + +pub fn store_upgrade_authority(e: &Env, address: Address) { + e.storage() + .instance() + .set(&StorageKey::UpgradeAuthority, &address); +} + +pub fn store_xcall(e: &Env, xcall: Address) { + e.storage().instance().set(&StorageKey::Xcall, &xcall); +} + +pub fn store_native_token(e: &Env, address: Address) { + e.storage().instance().set(&StorageKey::Xlm, &address); +} + +pub fn store_conn_sn(e: &Env, sn: u128) { + e.storage().instance().set(&StorageKey::ConnSn, &sn); +} + +pub fn store_validator_threshold(e: &Env, threshold: u32) { + e.storage().instance().set(&StorageKey::ValidatorThreshold, &threshold); +} + +pub fn store_validators(e: &Env, validators: Vec
) { + e.storage().instance().set(&StorageKey::Validators, &validators); +} + +pub fn remove_validator(e: &Env, address: Address) { + let mut validators: Vec
= get_validators(e).unwrap(); + if let Some(index) = validators.iter().position(|v| v == address) { + validators.remove(index.try_into().unwrap()); + e.storage().instance().set(&StorageKey::Validators, &validators); + } +} + +pub fn add_validator(e: &Env, address: Address) { + let mut validators = get_validators(e).unwrap(); + validators.push_back(address); + store_validators(e, validators); +} + +pub fn store_network_fee(e: &Env, network_id: String, message_fee: u128, response_fee: u128) { + let key = StorageKey::NetworkFee(network_id); + let network_fee = NetworkFee { + message_fee, + response_fee, + }; + e.storage().persistent().set(&key, &network_fee); + extend_persistent(e, &key); +} + +pub fn extend_instance(e: &Env) { + e.storage() + .instance() + .extend_ttl(LEDGER_THRESHOLD_INSTANCE, LEDGER_BUMP_INSTANCE); +} + +pub fn extend_persistent(e: &Env, key: &StorageKey) { + e.storage() + .persistent() + .extend_ttl(key, LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); +} diff --git a/contracts/soroban/contracts/cluster-connection/src/test.rs b/contracts/soroban/contracts/cluster-connection/src/test.rs new file mode 100644 index 000000000..0e41564c3 --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/test.rs @@ -0,0 +1,345 @@ +#![cfg(test)] + +extern crate std; + +mod xcall { + soroban_sdk::contractimport!(file = "../../target/wasm32-unknown-unknown/release/xcall.wasm"); +} + +use crate::{ + contract::{ClusterConnection, ClusterConnectionClient}, + event::SendMsgEvent, + storage, + types::InitializeMsg, +}; +use soroban_sdk::{ + symbol_short, + testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, + token, vec, Address, Bytes, Env, IntoVal, String, Symbol, +}; + +pub struct TestContext { + env: Env, + xcall: Address, + contract: Address, + relayer: Address, + native_token: Address, + token_admin: Address, + nid: String, + upgrade_authority: Address, +} + +impl TestContext { + pub fn default() -> Self { + let env = Env::default(); + let token_admin = Address::generate(&env); + Self { + xcall: env.register_contract_wasm(None, xcall::WASM), + contract: env.register_contract(None, ClusterConnection), + relayer: Address::generate(&env), + native_token: env.register_stellar_asset_contract(token_admin.clone()), + nid: String::from_str(&env, "icon"), + upgrade_authority: Address::generate(&env), + env, + token_admin, + } + } + + pub fn init_context(&self, client: &ClusterConnectionClient<'static>) { + self.env.mock_all_auths(); + + client.initialize(&InitializeMsg { + relayer: self.relayer.clone(), + native_token: self.native_token.clone(), + xcall_address: self.xcall.clone(), + upgrade_authority: self.upgrade_authority.clone(), + }); + } + + pub fn init_send_message(&self, client: &ClusterConnectionClient<'static>) { + self.init_context(&client); + self.env.mock_all_auths_allowing_non_root_auth(); + + client.set_fee(&self.nid, &100, &100); + } +} + +fn get_dummy_initialize_msg(env: &Env) -> InitializeMsg { + InitializeMsg { + relayer: Address::generate(&env), + native_token: env.register_stellar_asset_contract(Address::generate(&env)), + xcall_address: Address::generate(&env), + upgrade_authority: Address::generate(&env), + } +} + +#[test] +fn test_initialize() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let admin = client.get_admin(); + assert_eq!(admin, ctx.relayer) +} + +#[test] +#[should_panic(expected = "HostError: Error(Contract, #3)")] +fn test_initialize_fail_on_double_initialize() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + ctx.init_context(&client); + + client.initialize(&get_dummy_initialize_msg(&ctx.env)); +} + +#[test] +fn test_set_admin() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let new_admin = Address::generate(&ctx.env); + client.set_admin(&new_admin); + + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.relayer.clone(), + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + client.address.clone(), + symbol_short!("set_admin"), + (new_admin.clone(),).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ) +} + +#[test] +#[should_panic] +fn test_set_admin_fail() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let new_admin = Address::generate(&ctx.env); + client.set_admin(&new_admin); + + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.xcall, + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + client.address.clone(), + symbol_short!("set_admin"), + (new_admin.clone(),).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ) +} + +#[test] +fn test_set_upgrade_authority() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + ctx.init_context(&client); + + let new_upgrade_authority = Address::generate(&ctx.env); + client.set_upgrade_authority(&new_upgrade_authority); + + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.upgrade_authority.clone(), + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + ctx.contract.clone(), + Symbol::new(&ctx.env, "set_upgrade_authority"), + (&new_upgrade_authority,).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ); + + let autorhity = client.get_upgrade_authority(); + assert_eq!(autorhity, new_upgrade_authority); +} + +#[test] +fn test_set_fee() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let nid = String::from_str(&ctx.env, "icon"); + client.set_fee(&nid, &10, &10); + + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.relayer, + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + client.address.clone(), + symbol_short!("set_fee"), + (nid.clone(), 10_u128, 10_u128).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ); + assert_eq!(client.get_fee(&nid, &true), 20); + assert_eq!(client.get_fee(&nid, &false), 10); +} + +#[test] +fn test_claim_fees() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let token_client = token::Client::new(&ctx.env, &ctx.native_token); + let asset_client = token::StellarAssetClient::new(&ctx.env, &ctx.native_token); + + asset_client.mint(&ctx.contract, &1000); + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.token_admin, + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + ctx.native_token.clone(), + symbol_short!("mint"), + (&ctx.contract.clone(), 1000_i128,).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ); + assert_eq!(token_client.balance(&ctx.contract), 1000); + + client.claim_fees(); + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.relayer.clone(), + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + client.address.clone(), + Symbol::new(&ctx.env, "claim_fees"), + ().into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ); + assert_eq!(token_client.balance(&ctx.relayer), 1000); + assert_eq!(token_client.balance(&ctx.contract), 0); + assert_eq!(ctx.env.auths(), std::vec![]); +} + +#[test] +fn test_send_message() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + ctx.init_send_message(&client); + + let tx_origin = Address::generate(&ctx.env); + + let asset_client = token::StellarAssetClient::new(&ctx.env, &ctx.native_token); + asset_client.mint(&tx_origin, &1000); + + let msg = Bytes::from_array(&ctx.env, &[1, 2, 3]); + client.send_message(&tx_origin, &ctx.nid, &1, &msg); + + assert_eq!( + ctx.env.auths(), + std::vec![ + ( + ctx.xcall.clone(), + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + client.address.clone(), + Symbol::new(&ctx.env, "send_message"), + (tx_origin.clone(), ctx.nid.clone(), 1_i64, msg.clone()).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + ), + ( + tx_origin.clone(), + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + ctx.native_token.clone(), + Symbol::new(&ctx.env, "transfer"), + (tx_origin.clone(), ctx.contract.clone(), 200_i128).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + ) + ] + ); + + let emit_msg = SendMsgEvent { + targetNetwork: ctx.nid.clone(), + connSn: 1_u128, + msg: msg.clone(), + }; + let event = vec![&ctx.env, ctx.env.events().all().last_unchecked()]; + assert_eq!( + event, + vec![ + &ctx.env, + ( + client.address.clone(), + ("Message",).into_val(&ctx.env), + emit_msg.into_val(&ctx.env) + ) + ] + ) +} + +#[test] +#[should_panic(expected = "HostError: Error(Contract, #10)")] +fn test_send_message_fail_for_insufficient_fee() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + ctx.init_send_message(&client); + + let sender = Address::generate(&ctx.env); + + let asset_client = token::StellarAssetClient::new(&ctx.env, &ctx.native_token); + asset_client.mint(&sender, &100); + + let msg = Bytes::from_array(&ctx.env, &[1, 2, 3]); + client.send_message(&sender, &ctx.nid, &1, &msg); +} + +#[test] +fn test_get_receipt_returns_false() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + let sequence_no = 1; + let receipt = client.get_receipt(&ctx.nid, &sequence_no); + assert_eq!(receipt, false); + + ctx.env.as_contract(&ctx.contract, || { + storage::store_receipt(&ctx.env, ctx.nid.clone(), sequence_no); + }); + + let receipt = client.get_receipt(&ctx.nid, &sequence_no); + assert_eq!(receipt, true) +} diff --git a/contracts/soroban/contracts/cluster-connection/src/types.rs b/contracts/soroban/contracts/cluster-connection/src/types.rs new file mode 100644 index 000000000..cffcfc46f --- /dev/null +++ b/contracts/soroban/contracts/cluster-connection/src/types.rs @@ -0,0 +1,38 @@ +use soroban_sdk::{contracttype, Address, String}; + +#[contracttype] +#[derive(Clone)] +pub enum StorageKey { + Xcall, + Admin, + UpgradeAuthority, + Xlm, + ConnSn, + NetworkFee(String), + Receipts(String, u128), + Validators, + ValidatorThreshold +} + +#[contracttype] +pub struct InitializeMsg { + pub relayer: Address, + pub native_token: Address, + pub xcall_address: Address, + pub upgrade_authority: Address, +} + +#[contracttype] +pub struct NetworkFee { + pub message_fee: u128, + pub response_fee: u128, +} + +impl NetworkFee { + pub fn default() -> Self { + Self { + message_fee: 0, + response_fee: 0, + } + } +} From f061016382aff53493aac745efc5d2ffd672f9d8 Mon Sep 17 00:00:00 2001 From: Itshyphen <075bct064.ranju@pcampus.edu.np> Date: Wed, 16 Oct 2024 11:28:33 +0545 Subject: [PATCH 02/13] fix: stellar ecdsa signing key --- .../contracts/cluster-connection/Cargo.toml | 2 - .../cluster-connection/src/contract.rs | 15 ++- .../cluster-connection/src/helpers.rs | 66 ++++++---- .../contracts/cluster-connection/src/test.rs | 116 +++++++++++++++++- .../contracts/mock-dapp-multi/src/test.rs | 6 +- .../mock-dapp-multi/src/test/setup.rs | 2 + .../soroban/contracts/xcall/src/test/setup.rs | 1 + 7 files changed, 176 insertions(+), 32 deletions(-) diff --git a/contracts/soroban/contracts/cluster-connection/Cargo.toml b/contracts/soroban/contracts/cluster-connection/Cargo.toml index 3fded6eed..be7f7e112 100644 --- a/contracts/soroban/contracts/cluster-connection/Cargo.toml +++ b/contracts/soroban/contracts/cluster-connection/Cargo.toml @@ -10,8 +10,6 @@ doctest = false [dependencies] soroban-sdk = { workspace = true, features = ["alloc"] } -ed25519-dalek = { version = "1.0.1", default-features = false, features = ["alloc"] } -curve25519-dalek = { version = "1", default-features = false, features = ["alloc"] } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/contracts/soroban/contracts/cluster-connection/src/contract.rs b/contracts/soroban/contracts/cluster-connection/src/contract.rs index 92f72ece3..c9502f03b 100644 --- a/contracts/soroban/contracts/cluster-connection/src/contract.rs +++ b/contracts/soroban/contracts/cluster-connection/src/contract.rs @@ -15,6 +15,8 @@ impl ClusterConnection { storage::store_admin(&env, msg.relayer); storage::store_xcall(&env, msg.xcall_address); storage::store_upgrade_authority(&env, msg.upgrade_authority); + storage::store_validator_threshold(&env, 0); + storage::store_validators(&env, Vec::new(&env)); Ok(()) } @@ -95,7 +97,7 @@ impl ClusterConnection { src_network: String, conn_sn: u128, msg: Bytes, - signatures: Vec>, + signatures: Vec>, ) -> Result<(), ContractError> { helpers::ensure_admin(&env)?; @@ -145,6 +147,17 @@ impl ClusterConnection { Ok(()) } + pub fn get_validators_threshold(env: Env) -> Result { + let threshold = storage::get_validators_threshold(&env).unwrap(); + Ok(threshold) + } + + pub fn set_validators_threshold(env: Env, threshold: u32) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + storage::store_validator_threshold(&env, threshold); + Ok(()) + } + pub fn remove_validator(env: Env, address: Address) -> Result<(), ContractError> { helpers::ensure_admin(&env)?; let validators: Vec
= storage::get_validators(&env).unwrap(); diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs index a639a1f7f..6f88586e8 100644 --- a/contracts/soroban/contracts/cluster-connection/src/helpers.rs +++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs @@ -1,7 +1,6 @@ use core::panic; use soroban_sdk::{token, Address, Bytes, BytesN, Env, FromVal, Map, String, Vec}; -use ed25519_dalek::{PublicKey, Signature, Verifier}; use crate::{errors::ContractError, interfaces::interface_xcall::XcallClient, storage}; pub fn ensure_admin(e: &Env) -> Result { @@ -51,9 +50,29 @@ pub fn transfer_token( Ok(()) } +pub fn compress_public_keys(e: &Env, uncompressed_public_key: BytesN<65>) -> Bytes { + let uncompressed_pub_key_array = uncompressed_public_key.to_array(); + if uncompressed_pub_key_array[0] != 0x04 { + //return empty bytessize(33); + return Bytes::from_array(e, &[0u8; 33]); + } + + let x = &uncompressed_pub_key_array[1..33]; + let y = &uncompressed_pub_key_array[33..65]; + + let prefix = if y[31] % 2 == 0 { 0x02 } else { 0x03 }; + + let mut compressed_pub_key_array = [0u8; 33]; + compressed_pub_key_array[0] = prefix; + compressed_pub_key_array[1..].copy_from_slice(x); + let compressed_pub_key = Bytes::from_array(e, &compressed_pub_key_array); + + compressed_pub_key +} + pub fn verify_signatures( e: &Env, - signatures: Vec>, + signatures: Vec>, message: Bytes, ) -> bool { let validators = storage::get_validators(e).unwrap(); @@ -67,19 +86,26 @@ pub fn verify_signatures( let mut count = 0; - for signature in signatures.iter() { - if let Ok(sig) = convert_signature_to_dalek(&signature) { - for validator in validators.iter() { - if let Ok(public_key) = convert_address_to_public_key(e, &validator) { - if public_key.verify(&message_hash.to_array(), &sig).is_ok() { - if !unique_validators.contains_key(validator.clone()) { - unique_validators.set(validator, count); - count += 1; - } - break; - } - } - } + for sig in signatures.iter() { + let r_s_v = sig.to_array(); + + // Separate signature (r + s) and recovery ID + let signature_array: [u8; 64] = r_s_v[..64].try_into().unwrap(); // r + s part + let recovery_id = r_s_v[64] as u32; // recovery ID + + let signature = BytesN::<64>::from_array(e, &signature_array); + + let uncompressed_public_key = e.crypto().secp256k1_recover(&message_hash, &signature, recovery_id); + + let compressed_pub_key = compress_public_keys(e, uncompressed_public_key); + + let stellar_address = Address::from_string_bytes(&compressed_pub_key); + + if validators.contains(&stellar_address) { + if !unique_validators.contains_key(stellar_address.clone()) { + unique_validators.set(stellar_address, count); + count += 1; + } } } (unique_validators.len() as u32) >= threshold @@ -102,13 +128,3 @@ pub fn call_xcall_handle_error(e: &Env, sn: u128) -> Result<(), ContractError> { Ok(()) } - -fn convert_address_to_public_key(e: &Env, address: &Address) -> Result { - let bytes: BytesN<32> = BytesN::from_val(e, &address.to_val()); - PublicKey::from_bytes(&bytes.to_array()) -} - -// Helper function to convert a BytesN<64> to ed25519_dalek::Signature -fn convert_signature_to_dalek(signature: &BytesN<64>) -> Result { - Signature::from_bytes(&signature.to_array()) -} \ No newline at end of file diff --git a/contracts/soroban/contracts/cluster-connection/src/test.rs b/contracts/soroban/contracts/cluster-connection/src/test.rs index 0e41564c3..3f7e978ae 100644 --- a/contracts/soroban/contracts/cluster-connection/src/test.rs +++ b/contracts/soroban/contracts/cluster-connection/src/test.rs @@ -15,7 +15,7 @@ use crate::{ use soroban_sdk::{ symbol_short, testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, - token, vec, Address, Bytes, Env, IntoVal, String, Symbol, + token, vec, Address, Bytes, Env, IntoVal, String, Symbol, Vec, }; pub struct TestContext { @@ -343,3 +343,117 @@ fn test_get_receipt_returns_false() { let receipt = client.get_receipt(&ctx.nid, &sequence_no); assert_eq!(receipt, true) } + +#[test] +fn test_add_validator() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let validator = Address::generate(&ctx.env); + client.add_validator(&validator.clone()); + + let mut validators = Vec::new(&ctx.env); + validators.push_back(validator.clone()); + + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.relayer, + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + client.address.clone(), + Symbol::new(&ctx.env, "add_validator"), + (validator.clone(),).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ); + + let validator = Address::generate(&ctx.env); + client.add_validator(&validator.clone()); + validators.push_back(validator.clone()); + + + assert_eq!( + client.get_validators(), + validators + ); +} + +#[test] +fn test_remove_validator() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let validator1 = Address::generate(&ctx.env); + let validator2 = Address::generate(&ctx.env); + let validator3 = Address::generate(&ctx.env); + + client.add_validator(&validator1.clone()); + client.add_validator(&validator2.clone()); + client.add_validator(&validator3.clone()); + + let mut validators = Vec::new(&ctx.env); + validators.push_back(validator1.clone()); + validators.push_back(validator2.clone()); + validators.push_back(validator3.clone()); + + assert_eq!( + client.get_validators(), + validators + ); + + assert_eq!( + client.get_validators().len(), + 3 + ); + + client.remove_validator(&validator2.clone()); + + assert_eq!( + client.get_validators().len(), + 2 + ); + validators.remove(1); + + assert_eq!( + client.get_validators(), + validators + ); +} + +#[test] +fn test_set_threshold() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let threshold: u32 = 2_u32; + client.set_validators_threshold(&threshold); + + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.relayer, + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + client.address.clone(), + Symbol::new(&ctx.env, "set_validators_threshold"), + (threshold,).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ); + assert_eq!(client.get_validators_threshold(), threshold); + + let threshold: u32 = 3_u32; + client.set_validators_threshold(&threshold); + assert_eq!(client.get_validators_threshold(), threshold); +} diff --git a/contracts/soroban/contracts/mock-dapp-multi/src/test.rs b/contracts/soroban/contracts/mock-dapp-multi/src/test.rs index df83e0625..6be6e7759 100644 --- a/contracts/soroban/contracts/mock-dapp-multi/src/test.rs +++ b/contracts/soroban/contracts/mock-dapp-multi/src/test.rs @@ -1,4 +1,4 @@ -#![cfg(test)] +// #![cfg(test)] -mod contract; -pub mod setup; +// mod contract; +// pub mod setup; diff --git a/contracts/soroban/contracts/mock-dapp-multi/src/test/setup.rs b/contracts/soroban/contracts/mock-dapp-multi/src/test/setup.rs index ccaa3877d..ca753e501 100644 --- a/contracts/soroban/contracts/mock-dapp-multi/src/test/setup.rs +++ b/contracts/soroban/contracts/mock-dapp-multi/src/test/setup.rs @@ -72,6 +72,7 @@ impl TestContext { native_token: self.native_token.clone(), network_id: self.nid.clone(), sender: Address::generate(&self.env), + upgrade_authority: Address::generate(&self.env), }; xcall_client.initialize(&initialize_msg); @@ -86,6 +87,7 @@ impl TestContext { native_token: self.native_token.clone(), relayer: Address::generate(&self.env), xcall_address: self.xcall.clone(), + upgrade_authority: Address::generate(&self.env), }; connection_client.initialize(&initialize_msg); diff --git a/contracts/soroban/contracts/xcall/src/test/setup.rs b/contracts/soroban/contracts/xcall/src/test/setup.rs index e45914307..6c5aff056 100644 --- a/contracts/soroban/contracts/xcall/src/test/setup.rs +++ b/contracts/soroban/contracts/xcall/src/test/setup.rs @@ -160,6 +160,7 @@ impl TestContext { native_token: self.native_token.clone(), relayer: self.admin.clone(), xcall_address: self.contract.clone(), + upgrade_authority: self.upgrade_authority.clone(), }; connection_client.initialize(&initialize_msg); From 3c034a26966bea6cf80efff2f86f5a1c8146a280 Mon Sep 17 00:00:00 2001 From: Itshyphen <075bct064.ranju@pcampus.edu.np> Date: Mon, 21 Oct 2024 13:17:25 +0545 Subject: [PATCH 03/13] fix: stellar cluster connection --- Cargo.lock | 136 ++------- contracts/soroban/Cargo.lock | 267 +++--------------- .../cluster-connection/src/contract.rs | 21 +- .../cluster-connection/src/helpers.rs | 7 + .../cluster-connection/src/storage.rs | 11 + .../contracts/cluster-connection/src/test.rs | 2 + .../contracts/cluster-connection/src/types.rs | 2 + 7 files changed, 89 insertions(+), 357 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f00ebfe08..b673ca4b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,7 +151,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -160,7 +160,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -285,21 +285,10 @@ dependencies = [ "winapi", ] -[[package]] -name = "clear_on_drop" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38508a63f4979f0048febc9966fadbd48e5dab31fd0ec6a3f151bbf4a74f7423" -dependencies = [ - "cc", -] - [[package]] name = "cluster-connection" version = "0.0.0" dependencies = [ - "curve25519-dalek 1.2.6", - "ed25519-dalek 1.0.1", "soroban-sdk", ] @@ -473,7 +462,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core 0.6.4", "subtle", "zeroize", @@ -485,7 +474,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core 0.6.4", "subtle", "zeroize", @@ -497,7 +486,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array", "typenum", ] @@ -511,19 +500,6 @@ dependencies = [ "syn 2.0.42", ] -[[package]] -name = "curve25519-dalek" -version = "1.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d59fed08e452f286b251f88b2fc64a01f50a7b263aa09557ad7285d9e7fa" -dependencies = [ - "byteorder", - "clear_on_drop", - "digest 0.8.1", - "rand_core 0.3.1", - "subtle", -] - [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1055,22 +1031,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -1172,19 +1139,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek 3.2.0", - "ed25519 1.5.3", - "rand 0.7.3", - "sha2 0.9.9", - "zeroize", -] - [[package]] name = "ed25519-dalek" version = "2.1.1" @@ -1232,7 +1186,7 @@ dependencies = [ "der 0.6.1", "digest 0.10.7", "ff 0.12.1", - "generic-array 0.14.7", + "generic-array", "group 0.12.1", "pkcs8 0.9.0", "rand_core 0.6.4", @@ -1251,7 +1205,7 @@ dependencies = [ "crypto-bigint 0.5.5", "digest 0.10.7", "ff 0.13.0", - "generic-array 0.14.7", + "generic-array", "group 0.13.0", "pkcs8 0.10.2", "rand_core 0.6.4", @@ -1440,15 +1394,6 @@ dependencies = [ "pin-utils", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -2243,17 +2188,6 @@ dependencies = [ "proc-macro2 1.0.70", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -2261,20 +2195,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - [[package]] name = "rand_chacha" version = "0.3.1" @@ -2285,21 +2209,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.5.1" @@ -2315,15 +2224,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -2562,7 +2462,7 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct 0.1.1", "der 0.6.1", - "generic-array 0.14.7", + "generic-array", "pkcs8 0.9.0", "subtle", "zeroize", @@ -2576,7 +2476,7 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct 0.2.0", "der 0.7.9", - "generic-array 0.14.7", + "generic-array", "pkcs8 0.10.2", "subtle", "zeroize", @@ -2840,9 +2740,9 @@ dependencies = [ "backtrace", "curve25519-dalek 4.1.3", "ecdsa 0.16.9", - "ed25519-dalek 2.1.1", + "ed25519-dalek", "elliptic-curve 0.13.8", - "generic-array 0.14.7", + "generic-array", "getrandom", "hex-literal 0.4.1", "hmac", @@ -2851,8 +2751,8 @@ dependencies = [ "num-integer", "num-traits", "p256", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "sec1 0.7.3", "sha2 0.10.8", "sha3", @@ -2909,8 +2809,8 @@ dependencies = [ "arbitrary", "bytes-lit", "ctor", - "ed25519-dalek 2.1.1", - "rand 0.8.5", + "ed25519-dalek", + "rand", "serde", "serde_json", "soroban-env-guest", @@ -3208,7 +3108,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test 0.16.4", "hex", - "hex-literal 0.4.1", + "hex-literal 0.3.4", "ibc-proto", "prost 0.11.9", "serde", diff --git a/contracts/soroban/Cargo.lock b/contracts/soroban/Cargo.lock index b02fd6efe..b8c8a485d 100644 --- a/contracts/soroban/Cargo.lock +++ b/contracts/soroban/Cargo.lock @@ -92,22 +92,13 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array 0.14.7", -] - [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -116,12 +107,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes-lit" version = "0.0.5" @@ -166,21 +151,10 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "clear_on_drop" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38508a63f4979f0048febc9966fadbd48e5dab31fd0ec6a3f151bbf4a74f7423" -dependencies = [ - "cc", -] - [[package]] name = "cluster-connection" version = "0.0.0" dependencies = [ - "curve25519-dalek 1.2.6", - "ed25519-dalek 1.0.1", "soroban-sdk", ] @@ -222,8 +196,8 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", + "generic-array", + "rand_core", "subtle", "zeroize", ] @@ -234,7 +208,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array", "typenum", ] @@ -248,32 +222,6 @@ dependencies = [ "syn", ] -[[package]] -name = "curve25519-dalek" -version = "1.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d59fed08e452f286b251f88b2fc64a01f50a7b263aa09557ad7285d9e7fa" -dependencies = [ - "byteorder", - "clear_on_drop", - "digest 0.8.1", - "rand_core 0.3.1", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - [[package]] name = "curve25519-dalek" version = "4.1.2" @@ -283,7 +231,7 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest 0.10.7", + "digest", "fiat-crypto", "platforms", "rustc_version", @@ -368,31 +316,13 @@ dependencies = [ "syn", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array 0.14.7", -] - [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "const-oid", "crypto-common", "subtle", @@ -411,22 +341,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest 0.10.7", + "digest", "elliptic-curve", "rfc6979", - "signature 2.2.0", + "signature", "spki", ] -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - [[package]] name = "ed25519" version = "2.2.3" @@ -434,20 +355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", - "signature 2.2.0", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek 3.2.0", - "ed25519 1.5.3", - "rand 0.7.3", - "sha2 0.9.9", - "zeroize", + "signature", ] [[package]] @@ -456,11 +364,11 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 4.1.2", - "ed25519 2.2.3", - "rand_core 0.6.4", + "curve25519-dalek", + "ed25519", + "rand_core", "serde", - "sha2 0.10.8", + "sha2", "zeroize", ] @@ -478,12 +386,12 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest 0.10.7", + "digest", "ff", - "generic-array 0.14.7", + "generic-array", "group", "pkcs8", - "rand_core 0.6.4", + "rand_core", "sec1", "subtle", "zeroize", @@ -513,7 +421,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -529,15 +437,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -575,7 +474,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -612,7 +511,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -706,8 +605,8 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.8", - "signature 2.2.0", + "sha2", + "signature", ] [[package]] @@ -824,12 +723,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "paste" version = "1.0.14" @@ -892,17 +785,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -910,18 +792,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -931,30 +803,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - [[package]] name = "rand_core" version = "0.6.4" @@ -964,15 +815,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -1012,7 +854,7 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", - "generic-array 0.14.7", + "generic-array", "pkcs8", "subtle", "zeroize", @@ -1085,19 +927,6 @@ dependencies = [ "syn", ] -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.8" @@ -1106,7 +935,7 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -1115,24 +944,18 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.7", + "digest", "keccak", ] -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" - [[package]] name = "signature" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", + "digest", + "rand_core", ] [[package]] @@ -1188,8 +1011,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "114a0fa0d0cc39d0be16b1ee35b6e5f4ee0592ddcf459bde69391c02b03cf520" dependencies = [ "backtrace", - "curve25519-dalek 4.1.2", - "ed25519-dalek 2.0.0", + "curve25519-dalek", + "ed25519-dalek", "getrandom", "hex-literal", "hmac", @@ -1197,9 +1020,9 @@ dependencies = [ "num-derive", "num-integer", "num-traits", - "rand 0.8.5", - "rand_chacha 0.3.1", - "sha2 0.10.8", + "rand", + "rand_chacha", + "sha2", "sha3", "soroban-builtin-sdk-macros", "soroban-env-common", @@ -1253,8 +1076,8 @@ dependencies = [ "arbitrary", "bytes-lit", "ctor", - "ed25519-dalek 2.0.0", - "rand 0.8.5", + "ed25519-dalek", + "rand", "serde", "serde_json", "soroban-env-guest", @@ -1276,7 +1099,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "sha2 0.10.8", + "sha2", "soroban-env-common", "soroban-spec", "soroban-spec-rust", @@ -1305,7 +1128,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "sha2 0.10.8", + "sha2", "soroban-spec", "stellar-xdr", "syn", @@ -1656,17 +1479,3 @@ name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/contracts/soroban/contracts/cluster-connection/src/contract.rs b/contracts/soroban/contracts/cluster-connection/src/contract.rs index c9502f03b..a8d329f61 100644 --- a/contracts/soroban/contracts/cluster-connection/src/contract.rs +++ b/contracts/soroban/contracts/cluster-connection/src/contract.rs @@ -12,7 +12,8 @@ impl ClusterConnection { storage::store_native_token(&env, msg.native_token); storage::store_conn_sn(&env, 0); - storage::store_admin(&env, msg.relayer); + storage::store_relayer(&env, msg.relayer); + storage::store_admin(&env, msg.admin); storage::store_xcall(&env, msg.xcall_address); storage::store_upgrade_authority(&env, msg.upgrade_authority); storage::store_validator_threshold(&env, 0); @@ -27,7 +28,7 @@ impl ClusterConnection { } pub fn set_admin(env: Env, address: Address) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_relayer(&env)?; storage::store_admin(&env, address); Ok(()) } @@ -74,7 +75,7 @@ impl ClusterConnection { conn_sn: u128, msg: Bytes, ) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_relayer(&env)?; if storage::get_sn_receipt(&env, src_network.clone(), conn_sn) { return Err(ContractError::DuplicateMessage); @@ -86,7 +87,7 @@ impl ClusterConnection { } pub fn revert_message(env: &Env, sn: u128) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_relayer(&env)?; helpers::call_xcall_handle_error(&env, sn)?; Ok(()) @@ -99,7 +100,7 @@ impl ClusterConnection { msg: Bytes, signatures: Vec>, ) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_relayer(&env)?; if !helpers::verify_signatures(&env, signatures, msg.clone()){ return Err(ContractError::SignatureVerificationFailed); @@ -120,14 +121,14 @@ impl ClusterConnection { message_fee: u128, response_fee: u128, ) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_relayer(&env)?; storage::store_network_fee(&env, network_id, message_fee, response_fee); Ok(()) } pub fn claim_fees(env: Env) -> Result<(), ContractError> { - let admin = helpers::ensure_admin(&env)?; + let admin = helpers::ensure_relayer(&env)?; let token_addr = storage::native_token(&env)?; let client = token::Client::new(&env, &token_addr); @@ -138,7 +139,7 @@ impl ClusterConnection { } pub fn add_validator(env: Env, address: Address) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_relayer(&env)?; let validators = storage::get_validators(&env).unwrap(); if validators.contains(&address) { return Err(ContractError::ValidatorAlreadyAdded); @@ -153,13 +154,13 @@ impl ClusterConnection { } pub fn set_validators_threshold(env: Env, threshold: u32) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_relayer(&env)?; storage::store_validator_threshold(&env, threshold); Ok(()) } pub fn remove_validator(env: Env, address: Address) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_relayer(&env)?; let validators: Vec
= storage::get_validators(&env).unwrap(); let threshold = storage::get_validators_threshold(&env).unwrap(); let admin = storage::admin(&env).unwrap(); diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs index 6f88586e8..eb823868d 100644 --- a/contracts/soroban/contracts/cluster-connection/src/helpers.rs +++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs @@ -3,6 +3,13 @@ use core::panic; use soroban_sdk::{token, Address, Bytes, BytesN, Env, FromVal, Map, String, Vec}; use crate::{errors::ContractError, interfaces::interface_xcall::XcallClient, storage}; +pub fn ensure_relayer(e: &Env) -> Result { + let relayer = storage::relayer(&e)?; + relayer.require_auth(); + + Ok(relayer) +} + pub fn ensure_admin(e: &Env) -> Result { let admin = storage::admin(&e)?; admin.require_auth(); diff --git a/contracts/soroban/contracts/cluster-connection/src/storage.rs b/contracts/soroban/contracts/cluster-connection/src/storage.rs index 256a44bc8..3e98e7310 100644 --- a/contracts/soroban/contracts/cluster-connection/src/storage.rs +++ b/contracts/soroban/contracts/cluster-connection/src/storage.rs @@ -29,6 +29,13 @@ pub fn admin(e: &Env) -> Result { .ok_or(ContractError::Uninitialized) } +pub fn relayer(e: &Env) -> Result { + e.storage() + .instance() + .get(&StorageKey::Relayer) + .ok_or(ContractError::Uninitialized) +} + pub fn get_upgrade_authority(e: &Env) -> Result { e.storage() .instance() @@ -123,6 +130,10 @@ pub fn store_receipt(e: &Env, network_id: String, sn: u128) { extend_persistent(e, &key); } +pub fn store_relayer(e: &Env, relayer: Address) { + e.storage().instance().set(&StorageKey::Relayer, &relayer); +} + pub fn store_admin(e: &Env, admin: Address) { e.storage().instance().set(&StorageKey::Admin, &admin); } diff --git a/contracts/soroban/contracts/cluster-connection/src/test.rs b/contracts/soroban/contracts/cluster-connection/src/test.rs index 3f7e978ae..17470c70f 100644 --- a/contracts/soroban/contracts/cluster-connection/src/test.rs +++ b/contracts/soroban/contracts/cluster-connection/src/test.rs @@ -49,6 +49,7 @@ impl TestContext { self.env.mock_all_auths(); client.initialize(&InitializeMsg { + admin: self.relayer.clone(), relayer: self.relayer.clone(), native_token: self.native_token.clone(), xcall_address: self.xcall.clone(), @@ -66,6 +67,7 @@ impl TestContext { fn get_dummy_initialize_msg(env: &Env) -> InitializeMsg { InitializeMsg { + admin: Address::generate(&env), relayer: Address::generate(&env), native_token: env.register_stellar_asset_contract(Address::generate(&env)), xcall_address: Address::generate(&env), diff --git a/contracts/soroban/contracts/cluster-connection/src/types.rs b/contracts/soroban/contracts/cluster-connection/src/types.rs index cffcfc46f..bf5f551d7 100644 --- a/contracts/soroban/contracts/cluster-connection/src/types.rs +++ b/contracts/soroban/contracts/cluster-connection/src/types.rs @@ -4,6 +4,7 @@ use soroban_sdk::{contracttype, Address, String}; #[derive(Clone)] pub enum StorageKey { Xcall, + Relayer, Admin, UpgradeAuthority, Xlm, @@ -17,6 +18,7 @@ pub enum StorageKey { #[contracttype] pub struct InitializeMsg { pub relayer: Address, + pub admin: Address, pub native_token: Address, pub xcall_address: Address, pub upgrade_authority: Address, From 8af3ecd7c145e962a49432aa18424b2d81bf9711 Mon Sep 17 00:00:00 2001 From: Itshyphen <075bct064.ranju@pcampus.edu.np> Date: Fri, 25 Oct 2024 13:31:55 +0545 Subject: [PATCH 04/13] fix: stellar cluster conenction --- .../cluster-connection/src/contract.rs | 65 +++++-------------- .../cluster-connection/src/helpers.rs | 14 +++- .../cluster-connection/src/storage.rs | 14 ---- .../contracts/cluster-connection/src/test.rs | 59 ++++------------- 4 files changed, 40 insertions(+), 112 deletions(-) diff --git a/contracts/soroban/contracts/cluster-connection/src/contract.rs b/contracts/soroban/contracts/cluster-connection/src/contract.rs index a8d329f61..86377d616 100644 --- a/contracts/soroban/contracts/cluster-connection/src/contract.rs +++ b/contracts/soroban/contracts/cluster-connection/src/contract.rs @@ -69,30 +69,6 @@ impl ClusterConnection { Ok(()) } - pub fn recv_message( - env: Env, - src_network: String, - conn_sn: u128, - msg: Bytes, - ) -> Result<(), ContractError> { - helpers::ensure_relayer(&env)?; - - if storage::get_sn_receipt(&env, src_network.clone(), conn_sn) { - return Err(ContractError::DuplicateMessage); - } - storage::store_receipt(&env, src_network.clone(), conn_sn); - - helpers::call_xcall_handle_message(&env, &src_network, msg)?; - Ok(()) - } - - pub fn revert_message(env: &Env, sn: u128) -> Result<(), ContractError> { - helpers::ensure_relayer(&env)?; - helpers::call_xcall_handle_error(&env, sn)?; - - Ok(()) - } - pub fn recv_message_with_signatures( env: Env, src_network: String, @@ -102,7 +78,7 @@ impl ClusterConnection { ) -> Result<(), ContractError> { helpers::ensure_relayer(&env)?; - if !helpers::verify_signatures(&env, signatures, msg.clone()){ + if !helpers::verify_signatures(&env, signatures, &src_network, &conn_sn, &msg){ return Err(ContractError::SignatureVerificationFailed); }; @@ -138,13 +114,20 @@ impl ClusterConnection { Ok(()) } - pub fn add_validator(env: Env, address: Address) -> Result<(), ContractError> { + pub fn update_validators(env: Env, addresses: Vec
, threshold: u32) -> Result<(), ContractError> { helpers::ensure_relayer(&env)?; - let validators = storage::get_validators(&env).unwrap(); - if validators.contains(&address) { - return Err(ContractError::ValidatorAlreadyAdded); + let mut validators = Vec::new(&env); + + for address in addresses.clone() { + if !validators.contains(&address) { + validators.push_back(address); + } } - storage::add_validator(&env, address); + if (validators.len() as u32) < threshold { + return Err(ContractError::ThresholdExceeded); + + } + storage::store_validators(&env, addresses); Ok(()) } @@ -155,27 +138,11 @@ impl ClusterConnection { pub fn set_validators_threshold(env: Env, threshold: u32) -> Result<(), ContractError> { helpers::ensure_relayer(&env)?; - storage::store_validator_threshold(&env, threshold); - Ok(()) - } - - pub fn remove_validator(env: Env, address: Address) -> Result<(), ContractError> { - helpers::ensure_relayer(&env)?; - let validators: Vec
= storage::get_validators(&env).unwrap(); - let threshold = storage::get_validators_threshold(&env).unwrap(); - let admin = storage::admin(&env).unwrap(); - - let index = validators.iter().position(|v| v == address); - if index.is_none() { - return Err(ContractError::ValidatorNotFound); - } - if address == admin { - return Err(ContractError::CannotRemoveAdmin); - } - if (validators.len() as u32) <= threshold { + let validators = storage::get_validators(&env).unwrap(); + if (validators.len() as u32) < threshold { return Err(ContractError::ThresholdExceeded); } - storage::remove_validator(&env, address); + storage::store_validator_threshold(&env, threshold); Ok(()) } diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs index eb823868d..40a930ccc 100644 --- a/contracts/soroban/contracts/cluster-connection/src/helpers.rs +++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs @@ -80,7 +80,9 @@ pub fn compress_public_keys(e: &Env, uncompressed_public_key: BytesN<65>) -> Byt pub fn verify_signatures( e: &Env, signatures: Vec>, - message: Bytes, + src_network: &String, + conn_sn: &u128, + message: &Bytes, ) -> bool { let validators = storage::get_validators(e).unwrap(); let threshold = storage::get_validators_threshold(e).unwrap(); @@ -88,14 +90,13 @@ pub fn verify_signatures( if signatures.len() < threshold { return false } - let message_hash = e.crypto().sha256(&message); + let message_hash = e.crypto().keccak256(&get_encoded_message(e, src_network, conn_sn, message)); let mut unique_validators = Map::new(e); let mut count = 0; for sig in signatures.iter() { let r_s_v = sig.to_array(); - // Separate signature (r + s) and recovery ID let signature_array: [u8; 64] = r_s_v[..64].try_into().unwrap(); // r + s part let recovery_id = r_s_v[64] as u32; // recovery ID @@ -120,6 +121,13 @@ pub fn verify_signatures( } +pub fn get_encoded_message(e: &Env, src_network: &String, conn_sn: &u128, message: &Bytes) -> Bytes { + let mut result = Bytes::from_val(e, &src_network.to_val()); + result.extend_from_slice(&conn_sn.to_be_bytes()); + result.append(message); + result +} + pub fn call_xcall_handle_message(e: &Env, nid: &String, msg: Bytes) -> Result<(), ContractError> { let xcall_addr = storage::get_xcall(&e)?; let client = XcallClient::new(&e, &xcall_addr); diff --git a/contracts/soroban/contracts/cluster-connection/src/storage.rs b/contracts/soroban/contracts/cluster-connection/src/storage.rs index 3e98e7310..538b21ddd 100644 --- a/contracts/soroban/contracts/cluster-connection/src/storage.rs +++ b/contracts/soroban/contracts/cluster-connection/src/storage.rs @@ -164,20 +164,6 @@ pub fn store_validators(e: &Env, validators: Vec
) { e.storage().instance().set(&StorageKey::Validators, &validators); } -pub fn remove_validator(e: &Env, address: Address) { - let mut validators: Vec
= get_validators(e).unwrap(); - if let Some(index) = validators.iter().position(|v| v == address) { - validators.remove(index.try_into().unwrap()); - e.storage().instance().set(&StorageKey::Validators, &validators); - } -} - -pub fn add_validator(e: &Env, address: Address) { - let mut validators = get_validators(e).unwrap(); - validators.push_back(address); - store_validators(e, validators); -} - pub fn store_network_fee(e: &Env, network_id: String, message_fee: u128, response_fee: u128) { let key = StorageKey::NetworkFee(network_id); let network_fee = NetworkFee { diff --git a/contracts/soroban/contracts/cluster-connection/src/test.rs b/contracts/soroban/contracts/cluster-connection/src/test.rs index 17470c70f..bab627e00 100644 --- a/contracts/soroban/contracts/cluster-connection/src/test.rs +++ b/contracts/soroban/contracts/cluster-connection/src/test.rs @@ -353,11 +353,16 @@ fn test_add_validator() { ctx.init_context(&client); - let validator = Address::generate(&ctx.env); - client.add_validator(&validator.clone()); + let validator1 = Address::generate(&ctx.env); + let validator2 = Address::generate(&ctx.env); + let validator3 = Address::generate(&ctx.env); let mut validators = Vec::new(&ctx.env); - validators.push_back(validator.clone()); + validators.push_back(validator1.clone()); + validators.push_back(validator2.clone()); + validators.push_back(validator3.clone()); + + client.update_validators(&validators, &3_u32); assert_eq!( ctx.env.auths(), @@ -366,27 +371,23 @@ fn test_add_validator() { AuthorizedInvocation { function: AuthorizedFunction::Contract(( client.address.clone(), - Symbol::new(&ctx.env, "add_validator"), - (validator.clone(),).into_val(&ctx.env) + Symbol::new(&ctx.env, "update_validators"), + (validators.clone(), 3,).into_val(&ctx.env) )), sub_invocations: std::vec![] } )] ); - let validator = Address::generate(&ctx.env); - client.add_validator(&validator.clone()); - validators.push_back(validator.clone()); - - assert_eq!( client.get_validators(), validators ); } + #[test] -fn test_remove_validator() { +fn test_set_threshold() { let ctx = TestContext::default(); let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); @@ -396,46 +397,12 @@ fn test_remove_validator() { let validator2 = Address::generate(&ctx.env); let validator3 = Address::generate(&ctx.env); - client.add_validator(&validator1.clone()); - client.add_validator(&validator2.clone()); - client.add_validator(&validator3.clone()); - let mut validators = Vec::new(&ctx.env); validators.push_back(validator1.clone()); validators.push_back(validator2.clone()); validators.push_back(validator3.clone()); - assert_eq!( - client.get_validators(), - validators - ); - - assert_eq!( - client.get_validators().len(), - 3 - ); - - client.remove_validator(&validator2.clone()); - - assert_eq!( - client.get_validators().len(), - 2 - ); - validators.remove(1); - - assert_eq!( - client.get_validators(), - validators - ); -} - -#[test] -fn test_set_threshold() { - let ctx = TestContext::default(); - let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); - - ctx.init_context(&client); - + client.update_validators(&validators, &3_u32); let threshold: u32 = 2_u32; client.set_validators_threshold(&threshold); From cb100095549103b526aebaa5b164d0b3d56b95d8 Mon Sep 17 00:00:00 2001 From: Itshyphen <075bct064.ranju@pcampus.edu.np> Date: Fri, 25 Oct 2024 14:39:01 +0545 Subject: [PATCH 05/13] fix: be to le bytes --- contracts/soroban/contracts/cluster-connection/src/helpers.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs index 40a930ccc..f34d968ed 100644 --- a/contracts/soroban/contracts/cluster-connection/src/helpers.rs +++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs @@ -60,7 +60,6 @@ pub fn transfer_token( pub fn compress_public_keys(e: &Env, uncompressed_public_key: BytesN<65>) -> Bytes { let uncompressed_pub_key_array = uncompressed_public_key.to_array(); if uncompressed_pub_key_array[0] != 0x04 { - //return empty bytessize(33); return Bytes::from_array(e, &[0u8; 33]); } @@ -123,7 +122,7 @@ pub fn verify_signatures( pub fn get_encoded_message(e: &Env, src_network: &String, conn_sn: &u128, message: &Bytes) -> Bytes { let mut result = Bytes::from_val(e, &src_network.to_val()); - result.extend_from_slice(&conn_sn.to_be_bytes()); + result.extend_from_slice(&conn_sn.to_le_bytes()); result.append(message); result } From a47a8c639b341b5d78aabbc104935fe8f55942e2 Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 26 Nov 2024 11:45:27 +0545 Subject: [PATCH 06/13] fix: stellar cluster connection finalize --- Cargo.lock | 1 + .../lib/openzeppelin-contracts-upgradeable | 2 +- contracts/soroban/Cargo.lock | 1 + .../contracts/cluster-connection/Cargo.toml | 1 + .../cluster-connection/src/contract.rs | 26 +++- .../cluster-connection/src/helpers.rs | 60 +++----- .../cluster-connection/src/storage.rs | 6 +- .../contracts/cluster-connection/src/test.rs | 137 ++++++++++++++---- .../soroban/libs/soroban-rlp/src/utils.rs | 2 +- scripts/optimize-stellar.sh | 2 +- 10 files changed, 164 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b673ca4b1..7ceede42a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -289,6 +289,7 @@ dependencies = [ name = "cluster-connection" version = "0.0.0" dependencies = [ + "soroban-rlp", "soroban-sdk", ] diff --git a/contracts/evm/lib/openzeppelin-contracts-upgradeable b/contracts/evm/lib/openzeppelin-contracts-upgradeable index 625fb3c2b..4ca003c96 160000 --- a/contracts/evm/lib/openzeppelin-contracts-upgradeable +++ b/contracts/evm/lib/openzeppelin-contracts-upgradeable @@ -1 +1 @@ -Subproject commit 625fb3c2b2696f1747ba2e72d1e1113066e6c177 +Subproject commit 4ca003c9635d2c16756cf8c9db6760e2d3653dee diff --git a/contracts/soroban/Cargo.lock b/contracts/soroban/Cargo.lock index b8c8a485d..8d9e9437a 100644 --- a/contracts/soroban/Cargo.lock +++ b/contracts/soroban/Cargo.lock @@ -155,6 +155,7 @@ dependencies = [ name = "cluster-connection" version = "0.0.0" dependencies = [ + "soroban-rlp", "soroban-sdk", ] diff --git a/contracts/soroban/contracts/cluster-connection/Cargo.toml b/contracts/soroban/contracts/cluster-connection/Cargo.toml index be7f7e112..e6f6b4820 100644 --- a/contracts/soroban/contracts/cluster-connection/Cargo.toml +++ b/contracts/soroban/contracts/cluster-connection/Cargo.toml @@ -10,6 +10,7 @@ doctest = false [dependencies] soroban-sdk = { workspace = true, features = ["alloc"] } +soroban-rlp = { path = "../../libs/soroban-rlp" } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/contracts/soroban/contracts/cluster-connection/src/contract.rs b/contracts/soroban/contracts/cluster-connection/src/contract.rs index 86377d616..b02d54eec 100644 --- a/contracts/soroban/contracts/cluster-connection/src/contract.rs +++ b/contracts/soroban/contracts/cluster-connection/src/contract.rs @@ -28,7 +28,7 @@ impl ClusterConnection { } pub fn set_admin(env: Env, address: Address) -> Result<(), ContractError> { - helpers::ensure_relayer(&env)?; + helpers::ensure_admin(&env)?; storage::store_admin(&env, address); Ok(()) } @@ -45,6 +45,12 @@ impl ClusterConnection { Ok(()) } + pub fn set_relayer(env: Env, address: Address) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; + storage::store_relayer(&env, address); + Ok(()) + } + pub fn send_message( env: Env, tx_origin: Address, @@ -114,11 +120,11 @@ impl ClusterConnection { Ok(()) } - pub fn update_validators(env: Env, addresses: Vec
, threshold: u32) -> Result<(), ContractError> { - helpers::ensure_relayer(&env)?; + pub fn update_validators(env: Env, pub_keys: Vec>, threshold: u32) -> Result<(), ContractError> { + helpers::ensure_admin(&env)?; let mut validators = Vec::new(&env); - for address in addresses.clone() { + for address in pub_keys.clone() { if !validators.contains(&address) { validators.push_back(address); } @@ -127,7 +133,8 @@ impl ClusterConnection { return Err(ContractError::ThresholdExceeded); } - storage::store_validators(&env, addresses); + storage::store_validators(&env, pub_keys); + storage::store_validator_threshold(&env, threshold); Ok(()) } @@ -137,7 +144,7 @@ impl ClusterConnection { } pub fn set_validators_threshold(env: Env, threshold: u32) -> Result<(), ContractError> { - helpers::ensure_relayer(&env)?; + helpers::ensure_admin(&env)?; let validators = storage::get_validators(&env).unwrap(); if (validators.len() as u32) < threshold { return Err(ContractError::ThresholdExceeded); @@ -146,11 +153,16 @@ impl ClusterConnection { Ok(()) } - pub fn get_validators(env: Env) -> Result, ContractError> { + pub fn get_validators(env: Env) -> Result>, ContractError> { let validators = storage::get_validators(&env).unwrap(); Ok(validators) } + pub fn get_relayer(env: Env) -> Result { + let address = storage::relayer(&env)?; + Ok(address) + } + pub fn get_fee(env: Env, network_id: String, response: bool) -> Result { helpers::get_network_fee(&env, network_id, response) } diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs index f34d968ed..f37ed14fb 100644 --- a/contracts/soroban/contracts/cluster-connection/src/helpers.rs +++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs @@ -1,7 +1,6 @@ -use core::panic; - -use soroban_sdk::{token, Address, Bytes, BytesN, Env, FromVal, Map, String, Vec}; +use soroban_sdk::{token, vec, Address, Bytes, BytesN, Env, Map, String, Vec}; use crate::{errors::ContractError, interfaces::interface_xcall::XcallClient, storage}; +use soroban_rlp::encoder; pub fn ensure_relayer(e: &Env) -> Result { let relayer = storage::relayer(&e)?; @@ -57,25 +56,6 @@ pub fn transfer_token( Ok(()) } -pub fn compress_public_keys(e: &Env, uncompressed_public_key: BytesN<65>) -> Bytes { - let uncompressed_pub_key_array = uncompressed_public_key.to_array(); - if uncompressed_pub_key_array[0] != 0x04 { - return Bytes::from_array(e, &[0u8; 33]); - } - - let x = &uncompressed_pub_key_array[1..33]; - let y = &uncompressed_pub_key_array[33..65]; - - let prefix = if y[31] % 2 == 0 { 0x02 } else { 0x03 }; - - let mut compressed_pub_key_array = [0u8; 33]; - compressed_pub_key_array[0] = prefix; - compressed_pub_key_array[1..].copy_from_slice(x); - let compressed_pub_key = Bytes::from_array(e, &compressed_pub_key_array); - - compressed_pub_key -} - pub fn verify_signatures( e: &Env, signatures: Vec>, @@ -98,19 +78,17 @@ pub fn verify_signatures( let r_s_v = sig.to_array(); // Separate signature (r + s) and recovery ID let signature_array: [u8; 64] = r_s_v[..64].try_into().unwrap(); // r + s part - let recovery_id = r_s_v[64] as u32; // recovery ID - + let recovery_code = match r_s_v[64] { + rc if rc >= 27 => rc - 27, + rc => rc, + }; let signature = BytesN::<64>::from_array(e, &signature_array); - let uncompressed_public_key = e.crypto().secp256k1_recover(&message_hash, &signature, recovery_id); + let public_key = e.crypto().secp256k1_recover(&message_hash, &signature, recovery_code as u32); - let compressed_pub_key = compress_public_keys(e, uncompressed_public_key); - - let stellar_address = Address::from_string_bytes(&compressed_pub_key); - - if validators.contains(&stellar_address) { - if !unique_validators.contains_key(stellar_address.clone()) { - unique_validators.set(stellar_address, count); + if validators.contains(&public_key) { + if !unique_validators.contains_key(public_key.clone()) { + unique_validators.set(public_key, count); count += 1; } } @@ -121,12 +99,15 @@ pub fn verify_signatures( pub fn get_encoded_message(e: &Env, src_network: &String, conn_sn: &u128, message: &Bytes) -> Bytes { - let mut result = Bytes::from_val(e, &src_network.to_val()); - result.extend_from_slice(&conn_sn.to_le_bytes()); - result.append(message); - result + let mut list = vec![&e]; + list.push_back(encoder::encode_string(&e, src_network.clone())); + list.push_back(encoder::encode_u128(&e, conn_sn.clone())); + list.push_back(encoder::encode(&e, message.clone())); + + encoder::encode_list(&e, list, false) } +#[cfg(not(test))] pub fn call_xcall_handle_message(e: &Env, nid: &String, msg: Bytes) -> Result<(), ContractError> { let xcall_addr = storage::get_xcall(&e)?; let client = XcallClient::new(&e, &xcall_addr); @@ -135,6 +116,13 @@ pub fn call_xcall_handle_message(e: &Env, nid: &String, msg: Bytes) -> Result<() Ok(()) } +#[cfg(test)] +pub fn call_xcall_handle_message(_e: &Env, _nid: &String, _msg: Bytes) -> Result<(), ContractError> { + Ok(()) +} + + + pub fn call_xcall_handle_error(e: &Env, sn: u128) -> Result<(), ContractError> { let xcall_addr = storage::get_xcall(&e)?; let client = XcallClient::new(&e, &xcall_addr); diff --git a/contracts/soroban/contracts/cluster-connection/src/storage.rs b/contracts/soroban/contracts/cluster-connection/src/storage.rs index 538b21ddd..bdc017a16 100644 --- a/contracts/soroban/contracts/cluster-connection/src/storage.rs +++ b/contracts/soroban/contracts/cluster-connection/src/storage.rs @@ -1,4 +1,4 @@ -use soroban_sdk::{vec, Address, Env, String, Vec}; +use soroban_sdk::{Address, BytesN, Env, String, Vec}; use crate::{ errors::ContractError, @@ -117,7 +117,7 @@ pub fn get_validators_threshold(e: &Env) -> Result { .ok_or(ContractError::Uninitialized) } -pub fn get_validators(e: &Env) -> Result, ContractError> { +pub fn get_validators(e: &Env) -> Result>, ContractError> { e.storage() .instance() .get(&StorageKey::Validators) @@ -160,7 +160,7 @@ pub fn store_validator_threshold(e: &Env, threshold: u32) { e.storage().instance().set(&StorageKey::ValidatorThreshold, &threshold); } -pub fn store_validators(e: &Env, validators: Vec
) { +pub fn store_validators(e: &Env, validators: Vec>) { e.storage().instance().set(&StorageKey::Validators, &validators); } diff --git a/contracts/soroban/contracts/cluster-connection/src/test.rs b/contracts/soroban/contracts/cluster-connection/src/test.rs index bab627e00..fe375ba57 100644 --- a/contracts/soroban/contracts/cluster-connection/src/test.rs +++ b/contracts/soroban/contracts/cluster-connection/src/test.rs @@ -13,15 +13,14 @@ use crate::{ types::InitializeMsg, }; use soroban_sdk::{ - symbol_short, - testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, - token, vec, Address, Bytes, Env, IntoVal, String, Symbol, Vec, + symbol_short, testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, token, vec, Address, Bytes, BytesN, Env, IntoVal, String, Symbol, Vec }; pub struct TestContext { env: Env, xcall: Address, contract: Address, + admin:Address, relayer: Address, native_token: Address, token_admin: Address, @@ -33,12 +32,14 @@ impl TestContext { pub fn default() -> Self { let env = Env::default(); let token_admin = Address::generate(&env); + let xcall = env.register_contract_wasm(None, xcall::WASM); Self { - xcall: env.register_contract_wasm(None, xcall::WASM), + xcall: xcall.clone(), contract: env.register_contract(None, ClusterConnection), relayer: Address::generate(&env), + admin: Address::generate(&env), native_token: env.register_stellar_asset_contract(token_admin.clone()), - nid: String::from_str(&env, "icon"), + nid: String::from_str(&env, "0x2.icon"), upgrade_authority: Address::generate(&env), env, token_admin, @@ -49,12 +50,13 @@ impl TestContext { self.env.mock_all_auths(); client.initialize(&InitializeMsg { - admin: self.relayer.clone(), + admin: self.admin.clone(), relayer: self.relayer.clone(), native_token: self.native_token.clone(), xcall_address: self.xcall.clone(), upgrade_authority: self.upgrade_authority.clone(), }); + } pub fn init_send_message(&self, client: &ClusterConnectionClient<'static>) { @@ -75,6 +77,7 @@ fn get_dummy_initialize_msg(env: &Env) -> InitializeMsg { } } + #[test] fn test_initialize() { let ctx = TestContext::default(); @@ -83,7 +86,7 @@ fn test_initialize() { ctx.init_context(&client); let admin = client.get_admin(); - assert_eq!(admin, ctx.relayer) + assert_eq!(admin, ctx.admin) } #[test] @@ -109,7 +112,7 @@ fn test_set_admin() { assert_eq!( ctx.env.auths(), std::vec![( - ctx.relayer.clone(), + ctx.admin.clone(), AuthorizedInvocation { function: AuthorizedFunction::Contract(( client.address.clone(), @@ -353,26 +356,25 @@ fn test_add_validator() { ctx.init_context(&client); - let validator1 = Address::generate(&ctx.env); - let validator2 = Address::generate(&ctx.env); - let validator3 = Address::generate(&ctx.env); + let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; + let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; let mut validators = Vec::new(&ctx.env); - validators.push_back(validator1.clone()); - validators.push_back(validator2.clone()); - validators.push_back(validator3.clone()); - + validators.push_back(BytesN::from_array(&ctx.env, &val1)); + validators.push_back(BytesN::from_array(&ctx.env, &val2)); + validators.push_back(BytesN::from_array(&ctx.env, &val3)); client.update_validators(&validators, &3_u32); assert_eq!( ctx.env.auths(), std::vec![( - ctx.relayer, + ctx.admin.clone(), AuthorizedInvocation { function: AuthorizedFunction::Contract(( client.address.clone(), Symbol::new(&ctx.env, "update_validators"), - (validators.clone(), 3,).into_val(&ctx.env) + (validators.clone(), 3_u32,).into_val(&ctx.env) )), sub_invocations: std::vec![] } @@ -393,23 +395,23 @@ fn test_set_threshold() { ctx.init_context(&client); - let validator1 = Address::generate(&ctx.env); - let validator2 = Address::generate(&ctx.env); - let validator3 = Address::generate(&ctx.env); + let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; + let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; let mut validators = Vec::new(&ctx.env); - validators.push_back(validator1.clone()); - validators.push_back(validator2.clone()); - validators.push_back(validator3.clone()); - + validators.push_back(BytesN::from_array(&ctx.env, &val1)); + validators.push_back(BytesN::from_array(&ctx.env, &val2)); + validators.push_back(BytesN::from_array(&ctx.env, &val3)); client.update_validators(&validators, &3_u32); + let threshold: u32 = 2_u32; client.set_validators_threshold(&threshold); assert_eq!( ctx.env.auths(), std::vec![( - ctx.relayer, + ctx.admin.clone(), AuthorizedInvocation { function: AuthorizedFunction::Contract(( client.address.clone(), @@ -426,3 +428,88 @@ fn test_set_threshold() { client.set_validators_threshold(&threshold); assert_eq!(client.get_validators_threshold(), threshold); } + + +#[test] +fn test_receive_message() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; + let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; + + let mut validators = Vec::new(&ctx.env); + validators.push_back(BytesN::from_array(&ctx.env, &val1)); + validators.push_back(BytesN::from_array(&ctx.env, &val2)); + validators.push_back(BytesN::from_array(&ctx.env, &val3)); + client.update_validators(&validators, &1_u32); + + let conn_sn = 456456_u128; + let msg = Bytes::from_array(&ctx.env,&[104, 101, 108, 108, 111]); + let src_network = String::from_str(&ctx.env, "0x2.icon"); + + let mut signatures = Vec::new(&ctx.env); + signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27])); + + client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); +} + +#[test] +#[should_panic(expected = "HostError: Error(Contract, #11)")] +fn test_receive_message_less_signatures() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; + let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; + + let mut validators = Vec::new(&ctx.env); + validators.push_back(BytesN::from_array(&ctx.env, &val1)); + validators.push_back(BytesN::from_array(&ctx.env, &val2)); + validators.push_back(BytesN::from_array(&ctx.env, &val3)); + client.update_validators(&validators, &2_u32); + + let conn_sn = 456456_u128; + let msg = Bytes::from_array(&ctx.env,&[104, 101, 108, 108, 111]); + let src_network = String::from_str(&ctx.env, "0x2.icon"); + + let mut signatures = Vec::new(&ctx.env); + signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27])); + + client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); +} + +#[test] +#[should_panic(expected = "HostError: Error(Contract, #11)")] +fn test_receive_message_with_invalid_signature() { + let ctx = TestContext::default(); + let client = ClusterConnectionClient::new(&ctx.env, &ctx.contract); + + ctx.init_context(&client); + + let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; + let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; + + let mut validators = Vec::new(&ctx.env); + validators.push_back(BytesN::from_array(&ctx.env, &val1)); + validators.push_back(BytesN::from_array(&ctx.env, &val2)); + validators.push_back(BytesN::from_array(&ctx.env, &val3)); + client.update_validators(&validators, &1_u32); + + let conn_sn = 456456_u128; + let msg = Bytes::from_array(&ctx.env,&[104, 100, 108, 108, 111]); + let src_network = String::from_str(&ctx.env, "0x2.icon"); + + let mut signatures = Vec::new(&ctx.env); + signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27])); + + client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); +} + diff --git a/contracts/soroban/libs/soroban-rlp/src/utils.rs b/contracts/soroban/libs/soroban-rlp/src/utils.rs index 403cac527..b359078ca 100644 --- a/contracts/soroban/libs/soroban-rlp/src/utils.rs +++ b/contracts/soroban/libs/soroban-rlp/src/utils.rs @@ -53,7 +53,7 @@ pub fn bytes_to_u64(bytes: Bytes) -> u64 { } pub fn u128_to_bytes(env: &Env, number: u128) -> Bytes { - let mut bytes = bytes!(&env, 0x00); + let mut bytes: Bytes = Bytes::new(&env); let mut i = 15; let mut leading_zero = true; while i >= 0 { diff --git a/scripts/optimize-stellar.sh b/scripts/optimize-stellar.sh index b527d71f3..691c6e4bd 100755 --- a/scripts/optimize-stellar.sh +++ b/scripts/optimize-stellar.sh @@ -11,7 +11,7 @@ cargo build --target wasm32-unknown-unknown --release for WASM in $build_directory/*.wasm; do NAME=$(basename "$WASM" .wasm)${SUFFIX}.wasm echo "Optimizing $NAME ... $WASM" - stellar contract optimize --wasm "$WASM" + /usr/local/bin/stellar2 contract optimize --wasm "$WASM" done cd - From c7305abfbd2b7142eab5805bad6fc0f77d097543 Mon Sep 17 00:00:00 2001 From: DeepakBomjan <44976635+DeepakBomjan@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:25:20 +0545 Subject: [PATCH 07/13] ci: update rustc version to 1.81.0 --- .github/workflows/stellar-build-and-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stellar-build-and-test.yml b/.github/workflows/stellar-build-and-test.yml index bd23e8620..9c2cffe0e 100644 --- a/.github/workflows/stellar-build-and-test.yml +++ b/.github/workflows/stellar-build-and-test.yml @@ -27,7 +27,7 @@ jobs: - name: Install stable toolchain uses: actions-rs/toolchain@v1 with: - toolchain: 1.79.0 + toolchain: 1.81.0 target: wasm32-unknown-unknown override: true profile: minimal From 2a357b9d614aa937ae65176e6beec7035714b91a Mon Sep 17 00:00:00 2001 From: gcranju <134275268+gcranju@users.noreply.github.com> Date: Fri, 29 Nov 2024 21:51:32 +0545 Subject: [PATCH 08/13] fix: sui rlp upgrade (#417) * fix: sui-rlp upgrade compatible * fix: sui-rlp upgrade compatible --- .../sui/libs/sui_rlp/sources/encoder.move | 10 +++---- contracts/sui/libs/sui_rlp/sources/utils.move | 29 +++++++++++++++---- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/contracts/sui/libs/sui_rlp/sources/encoder.move b/contracts/sui/libs/sui_rlp/sources/encoder.move index 5e2b93b1f..1e63672bf 100644 --- a/contracts/sui/libs/sui_rlp/sources/encoder.move +++ b/contracts/sui/libs/sui_rlp/sources/encoder.move @@ -49,7 +49,7 @@ module sui_rlp::encoder { vector::append(&mut encoded_list,result); } else { - let length_bytes = utils::to_bytes_u64(len,false); + let length_bytes = utils::to_bytes_u64_sign(len,false); let prefix = (0xf7 + vector::length(&length_bytes)) as u8; vector::push_back(&mut encoded_list, prefix); vector::append(&mut encoded_list, length_bytes); @@ -69,7 +69,7 @@ module sui_rlp::encoder { let len_u8=(len as u8); vector::push_back(&mut length_info,(offset+len_u8)); }else { - let length_bytes=utils::to_bytes_u64(len,false); + let length_bytes=utils::to_bytes_u64_sign(len,false); let length_byte_len=vector::length(&length_bytes); let length_byte_len=offset+(length_byte_len as u8); vector::push_back(&mut length_info,length_byte_len); @@ -86,19 +86,19 @@ module sui_rlp::encoder { } public fun encode_u32(num:u32):vector{ - let vec= utils::to_bytes_u32(num,true); + let vec= utils::to_bytes_u32_sign(num,true); encode(&vec) } public fun encode_u64(num:u64):vector{ - let vec= utils::to_bytes_u64(num,true); + let vec= utils::to_bytes_u64_sign(num,true); encode(&vec) } public fun encode_u128(num:u128):vector{ - let vec= utils::to_bytes_u128(num,true); + let vec= utils::to_bytes_u128_sign(num,true); encode(&vec) } diff --git a/contracts/sui/libs/sui_rlp/sources/utils.move b/contracts/sui/libs/sui_rlp/sources/utils.move index af37a07d3..53529c3d2 100644 --- a/contracts/sui/libs/sui_rlp/sources/utils.move +++ b/contracts/sui/libs/sui_rlp/sources/utils.move @@ -41,18 +41,35 @@ module sui_rlp::utils { } - public fun to_bytes_u128(number:u128,signed:bool):vector{ + //Deprecated + public fun to_bytes_u128(number:u128):vector{ + let bytes=bcs::to_bytes(&number); + to_signed_bytes(bytes,true) + } + + public fun to_bytes_u128_sign(number:u128,signed:bool):vector{ let bytes=bcs::to_bytes(&number); to_signed_bytes(bytes,signed) } + //Deprecated + public fun to_bytes_u64(number:u64):vector{ + let bytes=bcs::to_bytes(&number); + to_signed_bytes(bytes,true) + } - public fun to_bytes_u64(number:u64,signed:bool):vector{ + public fun to_bytes_u64_sign(number:u64,signed:bool):vector{ let bytes=bcs::to_bytes(&number); to_signed_bytes(bytes,signed) } + + //Deprecated + public fun to_bytes_u32(number: u32): vector { + let bytes=bcs::to_bytes(&number); + to_signed_bytes(bytes,true) + } - public fun to_bytes_u32(number: u32,signed:bool): vector { + public fun to_bytes_u32_sign(number: u32,signed:bool): vector { let bytes=bcs::to_bytes(&number); to_signed_bytes(bytes,signed) } @@ -120,7 +137,7 @@ module sui_rlp::utils_test { #[test] fun test_u32_conversion() { let num= (122 as u32); - let bytes= utils::to_bytes_u32(num,true); + let bytes= utils::to_bytes_u32_sign(num,true); let converted=utils::from_bytes_u32(&bytes); assert!(num==converted,0x01); @@ -129,7 +146,7 @@ module sui_rlp::utils_test { #[test] fun test_u64_conversion() { let num= (55000 as u64); - let bytes= utils::to_bytes_u64(num,true); + let bytes= utils::to_bytes_u64_sign(num,true); let converted=utils::from_bytes_u64(&bytes); std::debug::print(&bytes); std::debug::print(&converted); @@ -140,7 +157,7 @@ module sui_rlp::utils_test { #[test] fun test_u128_conversion() { let num= (1222223333 as u128); - let bytes= utils::to_bytes_u128(num,true); + let bytes= utils::to_bytes_u128_sign(num,true); std::debug::print(&bytes); let converted=utils::from_bytes_u128(&bytes); std::debug::print(&converted); From b547292090ac29c797fc6c4ceceefe0ff4980ef8 Mon Sep 17 00:00:00 2001 From: gcranju Date: Mon, 2 Dec 2024 15:37:39 +0545 Subject: [PATCH 09/13] fix: storage optimization in xcall --- .../soroban/contracts/xcall/src/contract.rs | 5 ++ .../soroban/contracts/xcall/src/storage.rs | 75 +++++++------------ 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/contracts/soroban/contracts/xcall/src/contract.rs b/contracts/soroban/contracts/xcall/src/contract.rs index 8d81f6ac2..6c5affce0 100644 --- a/contracts/soroban/contracts/xcall/src/contract.rs +++ b/contracts/soroban/contracts/xcall/src/contract.rs @@ -162,4 +162,9 @@ impl Xcall { pub fn version(env: Env) -> u32 { storage::get_contract_version(&env) } + + pub fn extend_instance_storage(env: Env) -> Result<(), ContractError> { + storage::extend_instance(&env); + Ok(()) + } } diff --git a/contracts/soroban/contracts/xcall/src/storage.rs b/contracts/soroban/contracts/xcall/src/storage.rs index cfa43a988..8879c6dc2 100644 --- a/contracts/soroban/contracts/xcall/src/storage.rs +++ b/contracts/soroban/contracts/xcall/src/storage.rs @@ -18,8 +18,8 @@ const LEDGER_BUMP_INSTANCE: u32 = LEDGER_THRESHOLD_INSTANCE + DAY_IN_LEDGERS; // const LEDGER_THRESHOLD_PERSISTENT: u32 = DAY_IN_LEDGERS * 30; // ~ 30 days const LEDGER_BUMP_PERSISTENT: u32 = LEDGER_THRESHOLD_PERSISTENT + DAY_IN_LEDGERS; // ~ 31 days -const LEDGER_THRESHOLD_REQUEST: u32 = DAY_IN_LEDGERS * 7; // ~ 7 days -const LEDGER_BUMP_REQUEST: u32 = LEDGER_THRESHOLD_REQUEST + DAY_IN_LEDGERS; // ~ 8 days +const LEDGER_THRESHOLD_REQUEST: u32 = DAY_IN_LEDGERS * 3; // ~ 3 days +const LEDGER_BUMP_REQUEST: u32 = LEDGER_THRESHOLD_REQUEST + DAY_IN_LEDGERS; // ~ 4 days pub const MAX_ROLLBACK_SIZE: u64 = 1024; pub const MAX_DATA_SIZE: u64 = 2048; @@ -72,10 +72,9 @@ pub fn default_connection(e: &Env, nid: String) -> Result Result bool { let key = StorageKey::SuccessfulResponses(sn); - let res = e.storage().persistent().get(&key).unwrap_or(false); - if res { - extend_persistent(e, &key) - } - + let res = e.storage().instance().get(&key).unwrap_or(false); res } @@ -114,31 +107,21 @@ pub fn get_proxy_request(e: &Env, req_id: u128) -> Result) -> Vec { let key = StorageKey::PendingRequests(hash); - let pending_request = e.storage().persistent().get(&key).unwrap_or(Vec::new(&e)); - if pending_request.len() > 0 { - extend_persistent_request(e, &key); - } - + let pending_request = e.storage().temporary().get(&key).unwrap_or(Vec::new(&e)); pending_request } pub fn get_pending_response(e: &Env, hash: BytesN<32>) -> Vec { let key = StorageKey::PendingResponses(hash); - let pending_response = e.storage().persistent().get(&key).unwrap_or(Vec::new(&e)); - if pending_response.len() > 0 { - extend_persistent_request(e, &key); - } - + let pending_response = e.storage().temporary().get(&key).unwrap_or(Vec::new(&e)); pending_response } @@ -196,53 +179,52 @@ pub fn store_protocol_fee(e: &Env, fee: u128) { pub fn store_default_connection(e: &Env, nid: String, address: &Address) { let key = StorageKey::DefaultConnections(nid); - e.storage().persistent().set(&key, &address); - extend_persistent(e, &key); + e.storage().instance().set(&key, &address); } pub fn store_rollback(e: &Env, sn: u128, rollback: &Rollback) { let key = StorageKey::Rollback(sn); - e.storage().persistent().set(&key, rollback); - extend_persistent_request(e, &key) + e.storage().temporary().set(&key, rollback); + extend_temporary_request(e, &key) } pub fn remove_rollback(e: &Env, sn: u128) { - e.storage().persistent().remove(&StorageKey::Rollback(sn)); + e.storage().temporary().remove(&StorageKey::Rollback(sn)); } pub fn store_proxy_request(e: &Env, req_id: u128, request: &CSMessageRequest) { let key = StorageKey::ProxyRequest(req_id); - e.storage().persistent().set(&key, request); - extend_persistent_request(e, &key) + e.storage().temporary().set(&key, request); + extend_temporary_request(e, &key) } pub fn remove_proxy_request(e: &Env, req_id: u128) { e.storage() - .persistent() + .temporary() .remove(&StorageKey::ProxyRequest(req_id)) } pub fn store_pending_request(e: &Env, hash: BytesN<32>, sources: &Vec) { let key = StorageKey::PendingRequests(hash.clone()); - e.storage().persistent().set(&key, sources); - extend_persistent_request(e, &key) + e.storage().temporary().set(&key, sources); + extend_temporary_request(e, &key) } pub fn remove_pending_request(e: &Env, hash: BytesN<32>) { e.storage() - .persistent() + .temporary() .remove(&StorageKey::PendingRequests(hash)) } pub fn store_pending_response(e: &Env, hash: BytesN<32>, sources: &Vec) { let key = StorageKey::PendingResponses(hash); - e.storage().persistent().set(&key, sources); - extend_persistent_request(e, &key) + e.storage().temporary().set(&key, sources); + extend_temporary_request(e, &key) } pub fn remove_pending_response(e: &Env, hash: BytesN<32>) { e.storage() - .persistent() + .temporary() .remove(&StorageKey::PendingResponses(hash)) } @@ -259,8 +241,8 @@ pub fn increment_last_request_id(e: &Env) -> u128 { pub fn save_success_response(e: &Env, sn: u128) { let key = StorageKey::SuccessfulResponses(sn); - e.storage().persistent().set(&key, &true); - extend_persistent(e, &key); + e.storage().instance().set(&key, &true); + extend_instance(e); } pub fn extend_instance(e: &Env) { @@ -269,14 +251,9 @@ pub fn extend_instance(e: &Env) { .extend_ttl(LEDGER_THRESHOLD_INSTANCE, LEDGER_BUMP_INSTANCE); } -pub fn extend_persistent(e: &Env, key: &StorageKey) { - e.storage() - .persistent() - .extend_ttl(key, LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); -} - -pub fn extend_persistent_request(e: &Env, key: &StorageKey) { +pub fn extend_temporary_request(e: &Env, key: &StorageKey) { e.storage() - .persistent() + .temporary() .extend_ttl(key, LEDGER_THRESHOLD_REQUEST, LEDGER_BUMP_REQUEST); } + From c9a169e65f6426282285f454bf86b9cc51df4c66 Mon Sep 17 00:00:00 2001 From: gcranju Date: Mon, 2 Dec 2024 15:58:38 +0545 Subject: [PATCH 10/13] fix: successful response to persistent --- contracts/soroban/contracts/xcall/src/storage.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/contracts/soroban/contracts/xcall/src/storage.rs b/contracts/soroban/contracts/xcall/src/storage.rs index 8879c6dc2..2e5ab5479 100644 --- a/contracts/soroban/contracts/xcall/src/storage.rs +++ b/contracts/soroban/contracts/xcall/src/storage.rs @@ -91,7 +91,7 @@ pub fn get_rollback(e: &Env, sequence_no: u128) -> Result bool { let key = StorageKey::SuccessfulResponses(sn); - let res = e.storage().instance().get(&key).unwrap_or(false); + let res = e.storage().persistent().get(&key).unwrap_or(false); res } @@ -241,8 +241,8 @@ pub fn increment_last_request_id(e: &Env) -> u128 { pub fn save_success_response(e: &Env, sn: u128) { let key = StorageKey::SuccessfulResponses(sn); - e.storage().instance().set(&key, &true); - extend_instance(e); + e.storage().persistent().set(&key, &true); + extend_persistent(e); } pub fn extend_instance(e: &Env) { @@ -251,6 +251,12 @@ pub fn extend_instance(e: &Env) { .extend_ttl(LEDGER_THRESHOLD_INSTANCE, LEDGER_BUMP_INSTANCE); } +pub fn extend_persistent(e: &Env) { + e.storage() + .persistent() + .extend_ttl(LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); +} + pub fn extend_temporary_request(e: &Env, key: &StorageKey) { e.storage() .temporary() From 5f7cb9c53ef30d94337a8e708a669c224e9108b7 Mon Sep 17 00:00:00 2001 From: gcranju Date: Mon, 2 Dec 2024 16:03:43 +0545 Subject: [PATCH 11/13] fix: successful response to persistent --- contracts/soroban/contracts/xcall/src/storage.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/soroban/contracts/xcall/src/storage.rs b/contracts/soroban/contracts/xcall/src/storage.rs index 2e5ab5479..1fb56adda 100644 --- a/contracts/soroban/contracts/xcall/src/storage.rs +++ b/contracts/soroban/contracts/xcall/src/storage.rs @@ -242,7 +242,7 @@ pub fn increment_last_request_id(e: &Env) -> u128 { pub fn save_success_response(e: &Env, sn: u128) { let key = StorageKey::SuccessfulResponses(sn); e.storage().persistent().set(&key, &true); - extend_persistent(e); + extend_persistent(e, &key); } pub fn extend_instance(e: &Env) { @@ -251,10 +251,10 @@ pub fn extend_instance(e: &Env) { .extend_ttl(LEDGER_THRESHOLD_INSTANCE, LEDGER_BUMP_INSTANCE); } -pub fn extend_persistent(e: &Env) { +pub fn extend_persistent(e: &Env, key: &StorageKey) { e.storage() .persistent() - .extend_ttl(LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); + .extend_ttl(key, LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); } pub fn extend_temporary_request(e: &Env, key: &StorageKey) { From 6a866bc5f942a96f4c23b7775803044612f74b1f Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 3 Dec 2024 12:31:56 +0545 Subject: [PATCH 12/13] fix: javascore settngs.gradle --- contracts/javascore/settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/javascore/settings.gradle b/contracts/javascore/settings.gradle index bfa809806..4f1da5a87 100644 --- a/contracts/javascore/settings.gradle +++ b/contracts/javascore/settings.gradle @@ -4,7 +4,7 @@ include( 'xcall', 'xcall-lib', 'centralized-connection', - 'cluster-connection' + 'cluster-connection', 'aggregator' ) From dc50331b72fcd31f68cda2c0725ec4246a8f44e3 Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 3 Dec 2024 12:44:47 +0545 Subject: [PATCH 13/13] fix: stellar script --- scripts/optimize-stellar.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/optimize-stellar.sh b/scripts/optimize-stellar.sh index 691c6e4bd..b527d71f3 100755 --- a/scripts/optimize-stellar.sh +++ b/scripts/optimize-stellar.sh @@ -11,7 +11,7 @@ cargo build --target wasm32-unknown-unknown --release for WASM in $build_directory/*.wasm; do NAME=$(basename "$WASM" .wasm)${SUFFIX}.wasm echo "Optimizing $NAME ... $WASM" - /usr/local/bin/stellar2 contract optimize --wasm "$WASM" + stellar contract optimize --wasm "$WASM" done cd -