diff --git a/Cargo.lock b/Cargo.lock index 6ab88042b..e280dc8d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,7 +330,7 @@ checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ "event-listener", "event-listener-strategy", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -341,7 +341,7 @@ checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -372,11 +372,11 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-sink", "futures-util", "memchr", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -385,11 +385,11 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-sink", "futures-util", "memchr", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -435,19 +435,19 @@ dependencies = [ "async-trait", "axum-core", "base64 0.22.1", - "bytes", + "bytes 1.9.0", "futures-util", "http 1.1.0", "http-body 1.0.1", "http-body-util", "hyper 1.5.1", "hyper-util", - "itoa", + "itoa 1.0.14", "matchit", "memchr", "mime", "percent-encoding", - "pin-project-lite", + "pin-project-lite 0.2.15", "rustversion", "serde", "serde_json", @@ -455,7 +455,7 @@ dependencies = [ "serde_urlencoded", "sha1", "sync_wrapper 1.0.2", - "tokio", + "tokio 1.41.1", "tokio-tungstenite", "tower 0.5.1", "tower-layer", @@ -470,13 +470,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", - "bytes", + "bytes 1.9.0", "futures-util", "http 1.1.0", "http-body 1.0.1", "http-body-util", "mime", - "pin-project-lite", + "pin-project-lite 0.2.15", "rustversion", "sync_wrapper 1.0.2", "tower-layer", @@ -491,17 +491,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1ad46c3ec4e12f4a4b6835e173ba21c25e484c9d02b49770bf006ce5367c036" dependencies = [ "arc-swap", - "bytes", + "bytes 1.9.0", "futures-util", "http 1.1.0", "http-body 1.0.1", "http-body-util", "hyper 1.5.1", "hyper-util", - "pin-project-lite", + "pin-project-lite 0.2.15", "rustls 0.21.12", "rustls-pemfile 2.2.0", - "tokio", + "tokio 1.41.1", "tokio-rustls 0.24.1", "tower 0.4.13", "tower-service", @@ -514,13 +514,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ea4cd08ae2a5f075d28fa31190163c8106a1d2d3189442494bae22b39040a0d" dependencies = [ "axum-server", - "bytes", + "bytes 1.9.0", "http 1.1.0", "http-body-util", "pin-project", - "tokio", + "tokio 1.41.1", "tokio-rustls 0.24.1", - "tokio-util", + "tokio-util 0.7.12", "tower-layer", "tower-service", ] @@ -795,6 +795,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + [[package]] name = "bytes" version = "1.9.0" @@ -857,8 +863,8 @@ dependencies = [ "serde", "sha2 0.10.8", "thiserror 1.0.69", - "tokio", - "tokio-util", + "tokio 1.41.1", + "tokio-util 0.7.12", ] [[package]] @@ -893,8 +899,8 @@ dependencies = [ "rand 0.8.5", "reqwest 0.12.9", "serde", - "tokio", - "tokio-util", + "tokio 1.41.1", + "tokio-util 0.7.12", "tracing", ] @@ -954,7 +960,7 @@ dependencies = [ "near-workspaces", "rand 0.8.5", "serde_json", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -965,12 +971,14 @@ dependencies = [ "calimero-context-config", "candid", "ed25519-dalek", + "flate2", "hex", "ic-cdk 0.16.0", "ic-cdk-macros 0.16.0", "ic-ledger-types", "pocket-ic", "rand 0.8.5", + "reqwest 0.10.10", "serde", "thiserror 1.0.69", ] @@ -989,7 +997,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -1007,28 +1015,18 @@ dependencies = [ [[package]] name = "calimero-mock-external-icp" version = "0.1.0" -dependencies = [ - "candid", - "ic-cdk 0.16.0", - "ic-cdk-macros 0.16.0", -] - -[[package]] -name = "calimero-mock-ledger-icp" -version = "0.1.0" dependencies = [ "candid", "ic-cdk 0.16.0", "ic-cdk-macros 0.16.0", "ic-ledger-types", - "serde", ] [[package]] name = "calimero-network" version = "0.1.0" dependencies = [ - "bytes", + "bytes 1.9.0", "calimero-primitives", "eyre", "futures-util", @@ -1038,9 +1036,9 @@ dependencies = [ "owo-colors", "serde", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", "tokio-test", - "tokio-util", + "tokio-util 0.7.12", "tracing", ] @@ -1067,7 +1065,7 @@ dependencies = [ "owo-colors", "rand 0.8.5", "serde_json", - "tokio", + "tokio 1.41.1", "tracing", "url", ] @@ -1080,7 +1078,7 @@ dependencies = [ "calimero-runtime", "serde", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -1108,7 +1106,7 @@ dependencies = [ "near-workspaces", "semver", "serde_json", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -1206,7 +1204,7 @@ dependencies = [ "starknet", "starknet-crypto 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", "tower 0.4.13", "tower-http", "tower-sessions", @@ -1286,7 +1284,7 @@ dependencies = [ "eyre", "near-sdk", "near-workspaces", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -2067,7 +2065,7 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2106,7 +2104,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -2376,7 +2374,7 @@ checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -2386,7 +2384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ "event-listener", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -2537,7 +2535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2555,6 +2553,22 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags 1.3.2", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + [[package]] name = "funty" version = "2.0.0" @@ -2627,7 +2641,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" dependencies = [ "futures-core", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -2704,7 +2718,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite", + "pin-project-lite 0.2.15", "pin-utils", "slab", ] @@ -2804,13 +2818,33 @@ dependencies = [ "subtle", ] +[[package]] +name = "h2" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +dependencies = [ + "bytes 0.5.6", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 1.9.3", + "slab", + "tokio 0.2.25", + "tokio-util 0.3.1", + "tracing", + "tracing-futures", +] + [[package]] name = "h2" version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bytes", + "bytes 1.9.0", "fnv", "futures-core", "futures-sink", @@ -2818,8 +2852,8 @@ dependencies = [ "http 0.2.12", "indexmap 2.6.0", "slab", - "tokio", - "tokio-util", + "tokio 1.41.1", + "tokio-util 0.7.12", "tracing", ] @@ -2830,15 +2864,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", - "bytes", + "bytes 1.9.0", "fnv", "futures-core", "futures-sink", "http 1.1.0", "indexmap 2.6.0", "slab", - "tokio", - "tokio-util", + "tokio 1.41.1", + "tokio-util 0.7.12", "tracing", ] @@ -2885,10 +2919,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ "base64 0.21.7", - "bytes", + "bytes 1.9.0", "headers-core", "http 0.2.12", - "httpdate", + "httpdate 1.0.3", "mime", "sha1", ] @@ -2958,10 +2992,10 @@ dependencies = [ "ipnet", "once_cell", "rand 0.8.5", - "socket2", + "socket2 0.5.8", "thiserror 1.0.69", "tinyvec", - "tokio", + "tokio 1.41.1", "tracing", "url", ] @@ -2983,7 +3017,7 @@ dependencies = [ "resolv-conf", "smallvec", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", "tracing", ] @@ -3022,7 +3056,7 @@ checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ "libc", "match_cfg", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -3031,9 +3065,9 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes", + "bytes 1.9.0", "fnv", - "itoa", + "itoa 1.0.14", ] [[package]] @@ -3042,9 +3076,19 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "bytes", + "bytes 1.9.0", "fnv", - "itoa", + "itoa 1.0.14", +] + +[[package]] +name = "http-body" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" +dependencies = [ + "bytes 0.5.6", + "http 0.2.12", ] [[package]] @@ -3053,9 +3097,9 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "bytes", + "bytes 1.9.0", "http 0.2.12", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -3064,7 +3108,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes", + "bytes 1.9.0", "http 1.1.0", ] @@ -3074,11 +3118,11 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-util", "http 1.1.0", "http-body 1.0.1", - "pin-project-lite", + "pin-project-lite 0.2.15", ] [[package]] @@ -3093,19 +3137,49 @@ version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +[[package]] +name = "httpdate" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" + [[package]] name = "httpdate" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hyper" +version = "0.13.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a6f157065790a3ed2f88679250419b5cdd96e714a0d65f7797fd337186e96bb" +dependencies = [ + "bytes 0.5.6", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.2.7", + "http 0.2.12", + "http-body 0.3.1", + "httparse", + "httpdate 0.3.2", + "itoa 0.4.8", + "pin-project", + "socket2 0.3.19", + "tokio 0.2.25", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-channel", "futures-core", "futures-util", @@ -3113,11 +3187,11 @@ dependencies = [ "http 0.2.12", "http-body 0.4.6", "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", + "httpdate 1.0.3", + "itoa 1.0.14", + "pin-project-lite 0.2.15", + "socket2 0.5.8", + "tokio 1.41.1", "tower-service", "tracing", "want", @@ -3129,18 +3203,18 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-channel", "futures-util", "h2 0.4.7", "http 1.1.0", "http-body 1.0.1", "httparse", - "httpdate", - "itoa", - "pin-project-lite", + "httpdate 1.0.3", + "itoa 1.0.14", + "pin-project-lite 0.2.15", "smallvec", - "tokio", + "tokio 1.41.1", "want", ] @@ -3154,7 +3228,7 @@ dependencies = [ "http 0.2.12", "hyper 0.14.31", "rustls 0.21.12", - "tokio", + "tokio 1.41.1", "tokio-rustls 0.24.1", ] @@ -3171,22 +3245,35 @@ dependencies = [ "rustls 0.23.19", "rustls-native-certs", "rustls-pki-types", - "tokio", + "tokio 1.41.1", "tokio-rustls 0.26.0", "tower-service", "webpki-roots 0.26.7", ] +[[package]] +name = "hyper-tls" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" +dependencies = [ + "bytes 0.5.6", + "hyper 0.13.10", + "native-tls", + "tokio 0.2.25", + "tokio-tls", +] + [[package]] name = "hyper-tls" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes", + "bytes 1.9.0", "hyper 0.14.31", "native-tls", - "tokio", + "tokio 1.41.1", "tokio-native-tls", ] @@ -3196,12 +3283,12 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes", + "bytes 1.9.0", "http-body-util", "hyper 1.5.1", "hyper-util", "native-tls", - "tokio", + "tokio 1.41.1", "tokio-native-tls", "tower-service", ] @@ -3212,15 +3299,15 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.1", "hyper 1.5.1", - "pin-project-lite", - "socket2", - "tokio", + "pin-project-lite 0.2.15", + "socket2 0.5.8", + "tokio 1.41.1", "tower-service", "tracing", ] @@ -3287,7 +3374,7 @@ dependencies = [ "simple_asn1", "thiserror 1.0.69", "time", - "tokio", + "tokio 1.41.1", "tower-service", "url", ] @@ -3724,7 +3811,7 @@ dependencies = [ "netlink-sys", "rtnetlink", "system-configuration 0.6.1", - "tokio", + "tokio 1.41.1", "windows", ] @@ -3736,13 +3823,13 @@ checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" dependencies = [ "async-trait", "attohttpc", - "bytes", + "bytes 1.9.0", "futures", "http 0.2.12", "hyper 0.14.31", "log", "rand 0.8.5", - "tokio", + "tokio 1.41.1", "url", "xmltree", ] @@ -3851,16 +3938,25 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + [[package]] name = "ipconfig" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2", + "socket2 0.5.8", "widestring", "windows-sys 0.48.0", - "winreg", + "winreg 0.50.0", ] [[package]] @@ -3875,7 +3971,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d553b8abc8187beb7d663e34c065ac4570b273bc9511a50e940e99409c577" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -3902,6 +3998,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + [[package]] name = "itoa" version = "1.0.14" @@ -4008,6 +4110,16 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -4102,7 +4214,7 @@ version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681fb3f183edfbedd7a57d32ebe5dcdc0b9f94061185acf3c30249349cc6fc99" dependencies = [ - "bytes", + "bytes 1.9.0", "either", "futures", "futures-timer", @@ -4235,7 +4347,7 @@ dependencies = [ "asynchronous-codec 0.7.0", "base64 0.21.7", "byteorder", - "bytes", + "bytes 1.9.0", "either", "fnv", "futures", @@ -4307,7 +4419,7 @@ checksum = "5cc5767727d062c4eac74dd812c998f0e488008e82cce9c33b463d38423f9ad2" dependencies = [ "arrayvec 0.7.6", "asynchronous-codec 0.7.0", - "bytes", + "bytes 1.9.0", "either", "fnv", "futures", @@ -4343,8 +4455,8 @@ dependencies = [ "libp2p-swarm", "rand 0.8.5", "smallvec", - "socket2", - "tokio", + "socket2 0.5.8", + "tokio 1.41.1", "tracing", "void", ] @@ -4377,7 +4489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecd0545ce077f6ea5434bcb76e8d0fe942693b4380aaad0d34a358c2bd05793" dependencies = [ "asynchronous-codec 0.7.0", - "bytes", + "bytes 1.9.0", "curve25519-dalek", "futures", "libp2p-core", @@ -4420,7 +4532,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c67296ad4e092e23f92aea3d2bdb6f24eab79c0929ed816dfb460ea2f4567d2b" dependencies = [ - "bytes", + "bytes 1.9.0", "futures", "futures-timer", "if-watch", @@ -4432,9 +4544,9 @@ dependencies = [ "rand 0.8.5", "ring 0.17.8", "rustls 0.23.19", - "socket2", + "socket2 0.5.8", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", "tracing", ] @@ -4445,7 +4557,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d1c667cfabf3dd675c8e3cea63b7b98434ecf51721b7894cbb01d29983a6a9b" dependencies = [ "asynchronous-codec 0.7.0", - "bytes", + "bytes 1.9.0", "either", "futures", "futures-bounded", @@ -4541,7 +4653,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "smallvec", - "tokio", + "tokio 1.41.1", "tracing", "void", ] @@ -4570,8 +4682,8 @@ dependencies = [ "libc", "libp2p-core", "libp2p-identity", - "socket2", - "tokio", + "socket2 0.5.8", + "tokio 1.41.1", "tracing", ] @@ -4624,7 +4736,7 @@ dependencies = [ "igd-next", "libp2p-core", "libp2p-swarm", - "tokio", + "tokio 1.41.1", "tracing", "void", ] @@ -4849,7 +4961,7 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", "tokio-tungstenite", "url", ] @@ -4882,7 +4994,7 @@ dependencies = [ "near-crypto", "rand 0.8.5", "starknet", - "tokio", + "tokio 1.41.1", "toml_edit", "tracing", "tracing-subscriber", @@ -4929,6 +5041,25 @@ dependencies = [ "adler2", ] +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + [[package]] name = "mio" version = "0.8.11" @@ -4953,6 +5084,18 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + [[package]] name = "more-asserts" version = "0.2.2" @@ -5005,7 +5148,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19" dependencies = [ - "bytes", + "bytes 1.9.0", "futures", "log", "pin-project", @@ -5239,7 +5382,7 @@ dependencies = [ "base64 0.21.7", "bitvec", "borsh", - "bytes", + "bytes 1.9.0", "bytesize", "cfg-if 1.0.0", "chrono", @@ -5302,7 +5445,7 @@ dependencies = [ "binary-install", "fs2", "home", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -5462,7 +5605,7 @@ dependencies = [ "sha2 0.10.8", "tempfile", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", "tokio-retry", "tracing", "url", @@ -5520,6 +5663,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "net2" +version = "0.2.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + [[package]] name = "netlink-packet-core" version = "0.7.0" @@ -5563,13 +5717,13 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b33524dc0968bfad349684447bfce6db937a9ac3332a1fe60c0c5a5ce63f21" dependencies = [ - "bytes", + "bytes 1.9.0", "futures", "log", "netlink-packet-core", "netlink-sys", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -5578,11 +5732,11 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" dependencies = [ - "bytes", + "bytes 1.9.0", "futures", "libc", "log", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -5650,7 +5804,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ "overload", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -6019,6 +6173,12 @@ dependencies = [ "syn 2.0.89", ] +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + [[package]] name = "pin-project-lite" version = "0.2.15" @@ -6069,7 +6229,7 @@ dependencies = [ "strum 0.26.3", "strum_macros 0.26.4", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", "tracing", "tracing-appender", "tracing-subscriber", @@ -6085,7 +6245,7 @@ dependencies = [ "cfg-if 1.0.0", "concurrent-queue", "hermit-abi 0.4.0", - "pin-project-lite", + "pin-project-lite 0.2.15", "rustix", "tracing", "windows-sys 0.59.0", @@ -6254,7 +6414,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", - "itoa", + "itoa 1.0.14", "parking_lot", "prometheus-client-derive-encode", ] @@ -6321,7 +6481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ededb1cd78531627244d51dd0c7139fbe736c7d57af0092a76f0ffb2f56e98" dependencies = [ "asynchronous-codec 0.6.2", - "bytes", + "bytes 1.9.0", "quick-protobuf", "thiserror 1.0.69", "unsigned-varint 0.7.2", @@ -6334,7 +6494,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15a0580ab32b169745d7a39db2ba969226ca16738931be152a3209b409de2474" dependencies = [ "asynchronous-codec 0.7.0", - "bytes", + "bytes 1.9.0", "quick-protobuf", "thiserror 1.0.69", "unsigned-varint 0.8.0", @@ -6346,16 +6506,16 @@ version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-io", - "pin-project-lite", + "pin-project-lite 0.2.15", "quinn-proto", "quinn-udp", "rustc-hash 2.0.0", "rustls 0.23.19", - "socket2", + "socket2 0.5.8", "thiserror 2.0.3", - "tokio", + "tokio 1.41.1", "tracing", ] @@ -6365,7 +6525,7 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ - "bytes", + "bytes 1.9.0", "getrandom", "rand 0.8.5", "ring 0.17.8", @@ -6388,7 +6548,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2", + "socket2 0.5.8", "tracing", "windows-sys 0.59.0", ] @@ -6418,7 +6578,7 @@ dependencies = [ "libc", "rand_core 0.3.1", "rdrand", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -6622,7 +6782,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -6634,6 +6794,41 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "reqwest" +version = "0.10.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0718f81a8e14c4dbb3b34cf23dc6aaf9ab8a0dfec160c534b3dbca1aaa21f47c" +dependencies = [ + "base64 0.13.1", + "bytes 0.5.6", + "encoding_rs", + "futures-core", + "futures-util", + "http 0.2.12", + "http-body 0.3.1", + "hyper 0.13.10", + "hyper-tls 0.4.3", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "mime_guess", + "native-tls", + "percent-encoding", + "pin-project-lite 0.2.15", + "serde", + "serde_urlencoded", + "tokio 0.2.25", + "tokio-tls", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.7.0", +] + [[package]] name = "reqwest" version = "0.11.27" @@ -6641,7 +6836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", - "bytes", + "bytes 1.9.0", "encoding_rs", "futures-core", "futures-util", @@ -6658,7 +6853,7 @@ dependencies = [ "native-tls", "once_cell", "percent-encoding", - "pin-project-lite", + "pin-project-lite 0.2.15", "rustls 0.21.12", "rustls-pemfile 1.0.4", "serde", @@ -6666,7 +6861,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 0.1.2", "system-configuration 0.5.1", - "tokio", + "tokio 1.41.1", "tokio-native-tls", "tokio-rustls 0.24.1", "tower-service", @@ -6675,7 +6870,7 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots 0.25.4", - "winreg", + "winreg 0.50.0", ] [[package]] @@ -6685,7 +6880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", - "bytes", + "bytes 1.9.0", "encoding_rs", "futures-channel", "futures-core", @@ -6706,7 +6901,7 @@ dependencies = [ "native-tls", "once_cell", "percent-encoding", - "pin-project-lite", + "pin-project-lite 0.2.15", "quinn", "rustls 0.23.19", "rustls-native-certs", @@ -6717,11 +6912,11 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 1.0.2", "system-configuration 0.6.1", - "tokio", + "tokio 1.41.1", "tokio-native-tls", "tokio-rustls 0.26.0", "tokio-socks", - "tokio-util", + "tokio-util 0.7.12", "tower-service", "url", "wasm-bindgen", @@ -6764,7 +6959,7 @@ dependencies = [ "spin 0.5.2", "untrusted 0.7.1", "web-sys", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -6799,7 +6994,7 @@ checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", - "bytes", + "bytes 1.9.0", "hashbrown 0.12.3", "indexmap 1.9.3", "ptr_meta", @@ -6827,7 +7022,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" dependencies = [ - "bytes", + "bytes 1.9.0", "rustc-hex", ] @@ -6856,7 +7051,7 @@ dependencies = [ "netlink-sys", "nix 0.26.4", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -7292,7 +7487,7 @@ version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ - "itoa", + "itoa 1.0.14", "memchr", "ryu", "serde", @@ -7304,7 +7499,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62212da9872ca2a0cad0093191ee33753eddff9266cbbc1b4a602d13a3a768db" dependencies = [ - "itoa", + "itoa 1.0.14", "ryu", "serde", ] @@ -7315,7 +7510,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ - "itoa", + "itoa 1.0.14", "serde", ] @@ -7358,7 +7553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa", + "itoa 1.0.14", "ryu", "serde", ] @@ -7400,7 +7595,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap 2.6.0", - "itoa", + "itoa 1.0.14", "ryu", "serde", "unsafe-libyaml", @@ -7479,7 +7674,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" dependencies = [ - "bytes", + "bytes 1.9.0", "memmap2", ] @@ -7590,6 +7785,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "socket2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "winapi 0.3.9", +] + [[package]] name = "socket2" version = "0.5.8" @@ -7607,7 +7813,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ "base64 0.13.1", - "bytes", + "bytes 1.9.0", "futures", "httparse", "log", @@ -8145,7 +8351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", - "itoa", + "itoa 1.0.14", "num-conv", "powerfmt", "serde", @@ -8203,6 +8409,24 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" +dependencies = [ + "bytes 0.5.6", + "fnv", + "futures-core", + "iovec", + "lazy_static", + "memchr", + "mio 0.6.23", + "num_cpus", + "pin-project-lite 0.1.12", + "slab", +] + [[package]] name = "tokio" version = "1.41.1" @@ -8210,13 +8434,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", - "bytes", + "bytes 1.9.0", "libc", "mio 1.0.2", "parking_lot", - "pin-project-lite", + "pin-project-lite 0.2.15", "signal-hook-registry", - "socket2", + "socket2 0.5.8", "tokio-macros", "windows-sys 0.52.0", ] @@ -8239,7 +8463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -8250,7 +8474,7 @@ checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" dependencies = [ "pin-project", "rand 0.8.5", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -8260,7 +8484,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls 0.21.12", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -8271,7 +8495,7 @@ checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ "rustls 0.23.19", "rustls-pki-types", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -8283,7 +8507,7 @@ dependencies = [ "either", "futures-util", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", ] [[package]] @@ -8293,8 +8517,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", - "pin-project-lite", - "tokio", + "pin-project-lite 0.2.15", + "tokio 1.41.1", ] [[package]] @@ -8304,12 +8528,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7" dependencies = [ "async-stream", - "bytes", + "bytes 1.9.0", "futures-core", - "tokio", + "tokio 1.41.1", "tokio-stream", ] +[[package]] +name = "tokio-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343" +dependencies = [ + "native-tls", + "tokio 0.2.25", +] + [[package]] name = "tokio-tungstenite" version = "0.24.0" @@ -8318,22 +8552,36 @@ checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" dependencies = [ "futures-util", "log", - "tokio", + "tokio 1.41.1", "tungstenite", ] +[[package]] +name = "tokio-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +dependencies = [ + "bytes 0.5.6", + "futures-core", + "futures-sink", + "log", + "pin-project-lite 0.1.12", + "tokio 0.2.25", +] + [[package]] name = "tokio-util" version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-core", "futures-io", "futures-sink", - "pin-project-lite", - "tokio", + "pin-project-lite 0.2.15", + "tokio 1.41.1", ] [[package]] @@ -8379,7 +8627,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project", - "pin-project-lite", + "pin-project-lite 0.2.15", "tower-layer", "tower-service", "tracing", @@ -8393,9 +8641,9 @@ checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" dependencies = [ "futures-core", "futures-util", - "pin-project-lite", + "pin-project-lite 0.2.15", "sync_wrapper 0.1.2", - "tokio", + "tokio 1.41.1", "tower-layer", "tower-service", "tracing", @@ -8413,7 +8661,7 @@ dependencies = [ "futures-util", "http 1.1.0", "parking_lot", - "pin-project-lite", + "pin-project-lite 0.2.15", "tower-layer", "tower-service", ] @@ -8425,19 +8673,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "bitflags 2.6.0", - "bytes", + "bytes 1.9.0", "futures-util", "http 1.1.0", "http-body 1.0.1", "http-body-util", "http-range-header", - "httpdate", + "httpdate 1.0.3", "mime", "mime_guess", "percent-encoding", - "pin-project-lite", - "tokio", - "tokio-util", + "pin-project-lite 0.2.15", + "tokio 1.41.1", + "tokio-util 0.7.12", "tower-layer", "tower-service", "tracing", @@ -8464,7 +8712,7 @@ dependencies = [ "async-trait", "http 1.1.0", "time", - "tokio", + "tokio 1.41.1", "tower-cookies", "tower-layer", "tower-service", @@ -8490,7 +8738,7 @@ dependencies = [ "serde_json", "thiserror 1.0.69", "time", - "tokio", + "tokio 1.41.1", "tracing", ] @@ -8502,7 +8750,7 @@ checksum = "cec5f88eeef0f036e6900217034efbce733cbdf0528a85204eaaed90bc34c354" dependencies = [ "async-trait", "time", - "tokio", + "tokio 1.41.1", "tower-sessions-core", ] @@ -8513,7 +8761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", - "pin-project-lite", + "pin-project-lite 0.2.15", "tracing-attributes", "tracing-core", ] @@ -8561,6 +8809,16 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "tracing-log" version = "0.2.0" @@ -8631,7 +8889,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" dependencies = [ "byteorder", - "bytes", + "bytes 1.9.0", "data-encoding", "http 1.1.0", "httparse", @@ -8728,7 +8986,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" dependencies = [ "asynchronous-codec 0.6.2", - "bytes", + "bytes 1.9.0", ] [[package]] @@ -8922,6 +9180,8 @@ checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if 1.0.0", "once_cell", + "serde", + "serde_json", "wasm-bindgen-macro", ] @@ -9009,7 +9269,7 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d920d06243e9f456c336c428a34560357dedf59d9febaae14f1995ac120cff6" dependencies = [ - "bytes", + "bytes 1.9.0", "cfg-if 1.0.0", "derivative", "indexmap 1.9.3", @@ -9039,7 +9299,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e01832173aa52345e480965f18c638a8a5a9e5e4d85a48675bdf1964147dc7f" dependencies = [ "backtrace", - "bytes", + "bytes 1.9.0", "cfg-if 1.0.0", "enum-iterator", "enumset", @@ -9200,7 +9460,7 @@ checksum = "5388522c899d1e1c96a4c307e3797e0f697ba7c77dd8e0e625ecba9dd0342937" dependencies = [ "arrayvec 0.7.6", "base64 0.21.7", - "bytes", + "bytes 1.9.0", "derive_more", "ethabi", "ethereum-types", @@ -9221,9 +9481,9 @@ dependencies = [ "serde_json", "soketto", "tiny-keccak", - "tokio", + "tokio 1.41.1", "tokio-stream", - "tokio-util", + "tokio-util 0.7.12", "url", "web3-async-native-tls", ] @@ -9236,7 +9496,7 @@ checksum = "1f6d8d1636b2627fe63518d5a9b38a569405d9c9bc665c43c9c341de57227ebb" dependencies = [ "native-tls", "thiserror 1.0.69", - "tokio", + "tokio 1.41.1", "url", ] @@ -9264,7 +9524,7 @@ dependencies = [ "cfg-if 0.1.10", "libc", "memory_units", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -9273,6 +9533,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -9283,6 +9549,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -9572,6 +9844,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "winreg" version = "0.50.0" @@ -9594,6 +9875,16 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "wslpath" version = "0.0.2" diff --git a/Cargo.toml b/Cargo.toml index 4013dd509..111625350 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,6 @@ members = [ "./contracts/icp/context-config", "./contracts/icp/context-proxy", - "./contracts/icp/context-proxy/mock/ledger", "./contracts/icp/context-proxy/mock/external", "./e2e-tests", diff --git a/contracts/icp/.gitignore b/contracts/icp/.gitignore index 1eb29a7ed..96e52d091 100644 --- a/contracts/icp/.gitignore +++ b/contracts/icp/.gitignore @@ -28,3 +28,4 @@ dist/ pocket-ic !**/res/*.did +**/canister_ids.json diff --git a/contracts/icp/context-config/.env b/contracts/icp/context-config/.env index a649e815c..63dae3118 100644 --- a/contracts/icp/context-config/.env +++ b/contracts/icp/context-config/.env @@ -1,7 +1,8 @@ # DFX CANISTER ENVIRONMENT VARIABLES -DFX_VERSION='0.24.2' +DFX_VERSION='0.24.3' DFX_NETWORK='local' +CANISTER_ID_LEDGER='bd3sg-teaaa-aaaaa-qaaba-cai' CANISTER_ID_CONTEXT_CONTRACT='bkyz2-fmaaa-aaaaa-qaaaq-cai' CANISTER_ID='bkyz2-fmaaa-aaaaa-qaaaq-cai' CANISTER_CANDID_PATH='/Users/alen/www/calimero/core/contracts/icp/context-config/./res/calimero_context_config_icp.did' diff --git a/contracts/icp/context-config/deploy_devnet.sh b/contracts/icp/context-config/deploy_devnet.sh index 51b77ea92..825caf38b 100755 --- a/contracts/icp/context-config/deploy_devnet.sh +++ b/contracts/icp/context-config/deploy_devnet.sh @@ -1,13 +1,178 @@ #!/bin/bash +set -e -# Build the contract -./build.sh +# Function to generate a new identity and return its principal +generate_identity() { + local name=$1 + dfx identity new "$name" --storage-mode=plaintext || true + dfx identity use "$name" + dfx identity get-principal +} + +# Function to get account ID from principal +get_account_id() { + local principal=$1 + dfx ledger account-id --of-principal "$principal" +} + +echo "Checking dependencies..." +# Check for required commands +REQUIRED_COMMANDS="dfx cargo candid-extractor" + +for cmd in $REQUIRED_COMMANDS; do + if ! command -v $cmd >/dev/null 2>&1; then + case $cmd in + "dfx") + echo "dfx is required but not installed. Please install dfx: https://internetcomputer.org/docs/current/developer-docs/setup/install/" >&2 + ;; + "cargo") + echo "cargo is required but not installed. Please install Rust: https://rustup.rs/" >&2 + ;; + "candid-extractor") + echo "candid-extractor is required but not installed. Please install: cargo install candid-extractor" >&2 + ;; + esac + exit 1 + fi +done -# Stop the replica + +dfxvm default 0.24.3 + +# Stop dfx and clean up all state dfx stop +rm -rf .dfx +rm -rf ~/.config/dfx/replica-configuration/ +rm -rf ~/.config/dfx/identity/minting +rm -rf ~/.config/dfx/identity/initial +rm -rf ~/.config/dfx/identity/archive +rm -rf ~/.cache/dfinity/ +rm -rf ~/.config/dfx/ +dfxvm default 0.24.3 +# Remove canister_ids.json if it exists +if [ -f "canister_ids.json" ]; then + rm canister_ids.json +fi + +# Generate minting account +dfx identity new minting --storage-mode=plaintext || true +dfx identity use minting +MINTING_PRINCIPAL=$(dfx identity get-principal) +MINTING_ACCOUNT=$(get_account_id "$MINTING_PRINCIPAL") + +# Generate initial account +dfx identity new initial --storage-mode=plaintext || true +dfx identity use initial +INITIAL_PRINCIPAL=$(dfx identity get-principal) +INITIAL_ACCOUNT=$(get_account_id "$INITIAL_PRINCIPAL") + +# Generate archive controller account +dfx identity new archive --storage-mode=plaintext || true +dfx identity use archive +ARCHIVE_PRINCIPAL=$(dfx identity get-principal) + +# Generate test recipient account +dfx identity new recipient --storage-mode=plaintext || true +dfx identity use recipient +RECIPIENT_PRINCIPAL=$(dfx identity get-principal) + +# Switch back to default identity +dfx identity use default + +# Start dfx with clean state +dfx start --clean --background + +dfx identity use default + +# Create initial identity if needed +dfx identity new --storage-mode=plaintext minting || true +# dfx identity use minting + +echo "Creating and deploying canister..." +dfx canister create context_contract +dfx canister create ledger + +# Get the context ID +CONTEXT_ID=$(dfx canister id context_contract) +# Get the wallet ID and seed it +WALLET_ID=$(dfx identity get-wallet) + +# abricate cycles for the wallet +dfx ledger fabricate-cycles --canister $WALLET_ID --amount 200000 + +# Transfer cycles from wallet to context contract +dfx canister deposit-cycles 1000000000000000000 $CONTEXT_ID + +echo "Done! Cycles transferred to context contract: $CONTEXT_ID" + +# Get the IDs +CONTEXT_ID=$(dfx canister id context_contract) +LEDGER_ID=$(dfx canister id ledger) + +# Build contracts +echo "Building contracts..." +cd "$(dirname $0)" +./build.sh +cd ../context-proxy +./build.sh +cd ../context-config + +# Prepare ledger initialization argument +LEDGER_INIT_ARG="(variant { Init = record { + minting_account = \"${MINTING_ACCOUNT}\"; + initial_values = vec { + record { \"${INITIAL_ACCOUNT}\"; record { e8s = 100_000_000_000 } } + }; + send_whitelist = vec {}; + transfer_fee = opt record { e8s = 10_000 }; + token_symbol = opt \"LICP\"; + token_name = opt \"Local Internet Computer Protocol Token\"; + archive_options = opt record { + trigger_threshold = 2000; + num_blocks_to_archive = 1000; + controller_id = principal \"${ARCHIVE_PRINCIPAL}\" + }; +} })" + +# Build and install canisters +dfx build +dfx canister install context_contract --mode=install +dfx canister install ledger --mode=install --argument "$LEDGER_INIT_ARG" + +# Get the directory where the script is located +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +# Build path relative to the script location +WASM_FILE="${SCRIPT_DIR}/../context-proxy/res/calimero_context_proxy_icp.wasm" + +# Verify file exists +if [ ! -f "$WASM_FILE" ]; then + echo "Error: WASM file not found at: $WASM_FILE" + exit 1 +fi + +# Then modify the script to use a consistent reading method +WASM_CONTENTS=$(xxd -p "$WASM_FILE" | tr -d '\n' | sed 's/\(..\)/\\\1/g') + +TEMP_CMD=$(mktemp) +echo "( + blob \"${WASM_CONTENTS}\", + principal \"${LEDGER_ID}\" +)" > "$TEMP_CMD" + +# Execute the command using the temporary file +dfx canister call context_contract set_proxy_code --argument-file "$TEMP_CMD" -# Start the replica -dfx start --background +# Clean up +rm "$TEMP_CMD" -# Deploy the contract -dfx deploy +# Print all relevant information at the end +echo -e "\n=== Deployment Summary ===" +echo "Context Contract ID: ${CONTEXT_ID}" +echo "Ledger Contract ID: ${LEDGER_ID}" +echo -e "\nAccount Information:" +echo "Minting Account: ${MINTING_ACCOUNT}" +echo "Initial Account: ${INITIAL_ACCOUNT}" +echo "Archive Principal: ${ARCHIVE_PRINCIPAL}" +echo "Recipient Principal: ${RECIPIENT_PRINCIPAL}" +echo -e "\nDeployment completed successfully!" diff --git a/contracts/icp/context-config/dfx.json b/contracts/icp/context-config/dfx.json index c429488ba..5b70ce5d6 100644 --- a/contracts/icp/context-config/dfx.json +++ b/contracts/icp/context-config/dfx.json @@ -4,6 +4,11 @@ "package": "calimero-context-config-icp", "candid": "./res/calimero_context_config_icp.did", "type": "rust" + }, + "ledger": { + "type": "custom", + "wasm": "https://download.dfinity.systems/ic/aba60ffbc46acfc8990bf4d5685c1360bd7026b9/canisters/ledger-canister.wasm.gz", + "candid": "https://raw.githubusercontent.com/dfinity/ic/aba60ffbc46acfc8990bf4d5685c1360bd7026b9/rs/ledger_suite/icp/ledger.did" } }, "defaults": { @@ -12,6 +17,15 @@ "packtool": "" } }, - "output_env_file": ".env", + "networks": { + "local": { + "bind": "127.0.0.1:4943", + "type": "persistent" + } + }, + "routing_table": { + "start_canister_id": "aaaaa-aa", + "end_canister_id": "zzzzz-zz" + }, "version": 1 } diff --git a/contracts/icp/context-config/res/calimero_context_config_icp.did b/contracts/icp/context-config/res/calimero_context_config_icp.did index 51f18aa22..6d536a811 100644 --- a/contracts/icp/context-config/res/calimero_context_config_icp.did +++ b/contracts/icp/context-config/res/calimero_context_config_icp.did @@ -11,6 +11,7 @@ type Result = variant { Ok; Err : text }; service : () -> { application : (blob) -> (ICApplication) query; application_revision : (blob) -> (nat64) query; + fetch_nonce : (blob, blob) -> (opt nat64) query; has_member : (blob, blob) -> (bool) query; members : (blob, nat64, nat64) -> (vec blob) query; members_revision : (blob) -> (nat64) query; diff --git a/contracts/icp/context-config/src/lib.rs b/contracts/icp/context-config/src/lib.rs index 744b4c810..40cb300c1 100644 --- a/contracts/icp/context-config/src/lib.rs +++ b/contracts/icp/context-config/src/lib.rs @@ -23,6 +23,7 @@ pub struct Context { pub application: Guard, pub members: Guard>>, pub proxy: Guard, + pub member_nonces: BTreeMap, u64>, } #[derive(CandidType, Deserialize, Debug)] diff --git a/contracts/icp/context-config/src/mutate.rs b/contracts/icp/context-config/src/mutate.rs index 10f8357ca..5fb1899d8 100644 --- a/contracts/icp/context-config/src/mutate.rs +++ b/contracts/icp/context-config/src/mutate.rs @@ -21,31 +21,39 @@ pub async fn mutate(signed_request: ICSigned) -> Result<(), String> { .parse(|r| *r.signer_id) .map_err(|e| format!("Failed to verify signature: {}", e))?; - match request.kind { - ICRequestKind::Context(ICContextRequest { context_id, kind }) => match kind { - ICContextRequestKind::Add { - author_id, - application, - } => add_context(&request.signer_id, context_id, *author_id, application).await, - ICContextRequestKind::UpdateApplication { application } => { - update_application(&request.signer_id, &context_id, application) - } - ICContextRequestKind::AddMembers { members } => { - add_members(&request.signer_id, &context_id, members) - } - ICContextRequestKind::RemoveMembers { members } => { - remove_members(&request.signer_id, &context_id, members) - } - ICContextRequestKind::Grant { capabilities } => { - grant(&request.signer_id, &context_id, capabilities) - } - ICContextRequestKind::Revoke { capabilities } => { - revoke(&request.signer_id, &context_id, capabilities) - } - ICContextRequestKind::UpdateProxyContract => { - update_proxy_contract(&request.signer_id, context_id).await - } - }, + let (context_id, kind) = match request.kind { + ICRequestKind::Context(ICContextRequest { context_id, kind }) => (context_id, kind), + }; + + check_and_increment_nonce( + *context_id, + request.signer_id.rt().expect("infallible conversion"), + request.nonce, + )?; + + match kind { + ICContextRequestKind::Add { + author_id, + application, + } => add_context(&request.signer_id, context_id, *author_id, application).await, + ICContextRequestKind::UpdateApplication { application } => { + update_application(&request.signer_id, &context_id, application) + } + ICContextRequestKind::AddMembers { members } => { + add_members(&request.signer_id, &context_id, members) + } + ICContextRequestKind::RemoveMembers { members } => { + remove_members(&request.signer_id, &context_id, members) + } + ICContextRequestKind::Grant { capabilities } => { + grant(&request.signer_id, &context_id, capabilities) + } + ICContextRequestKind::Revoke { capabilities } => { + revoke(&request.signer_id, &context_id, capabilities) + } + ICContextRequestKind::UpdateProxyContract => { + update_proxy_contract(&request.signer_id, context_id).await + } } } @@ -59,6 +67,10 @@ async fn add_context( return Err("context addition must be signed by the context itself".into()); } + if with_state(|configs| configs.contexts.contains_key(&context_id)) { + return Err("context already exists".to_owned()); + } + let proxy_canister_id = deploy_proxy_contract(context_id) .await .unwrap_or_else(|e| panic!("Failed to deploy proxy contract: {}", e)); @@ -69,12 +81,17 @@ async fn add_context( application: Guard::new(author_id.rt().expect("infallible conversion"), application), members: Guard::new( author_id.rt().expect("infallible conversion"), - [author_id.rt().expect("infallible conversion")].into(), + [author_id.rt().expect("infallible conversion")] + .into_iter() + .collect(), ), proxy: Guard::new( author_id.rt().expect("infallible conversion"), proxy_canister_id, ), + member_nonces: [(author_id.rt().expect("infallible conversion"), 0)] + .into_iter() + .collect(), }; // Store context @@ -106,7 +123,7 @@ async fn deploy_proxy_contract(context_id: ICRepr) -> Result Result<(), String> { with_state_mut(|configs| { - // Get the context or return error if it doesn't exist let context = configs .contexts .get_mut(context_id) .ok_or_else(|| "context does not exist".to_string())?; - // Get mutable access to the application through the Guard + // Original implementation continues unchanged let guard_ref = context .application .get(signer_id) .map_err(|e| e.to_string())?; let mut app_ref = guard_ref.get_mut(); - - // Replace the application with the new one *app_ref = application; Ok(()) @@ -162,19 +176,19 @@ fn add_members( members: Vec>, ) -> Result<(), String> { with_state_mut(|configs| { - // Get the context or return error if it doesn't exist let context = configs .contexts .get_mut(context_id) .ok_or_else(|| "context does not exist".to_string())?; - // Get mutable access to the members through the Guard let guard_ref = context.members.get(signer_id).map_err(|e| e.to_string())?; let mut ctx_members = guard_ref.get_mut(); - // Add each member for member in members { - ctx_members.insert(member); + if ctx_members.insert(member) { + // returns true if the value was newly inserted + let _ignored = context.member_nonces.entry(member).or_default(); + } } Ok(()) @@ -187,30 +201,17 @@ fn remove_members( members: Vec>, ) -> Result<(), String> { with_state_mut(|configs| { - // Get the context or return error if it doesn't exist let context = configs .contexts .get_mut(context_id) .ok_or_else(|| "context does not exist".to_string())?; - // Get mutable access to the members through the Guard - let mut ctx_members = context - .members - .get(signer_id) - .map_err(|e| e.to_string())? - .get_mut(); + let guard_ref = context.members.get(signer_id).map_err(|e| e.to_string())?; + let mut ctx_members = guard_ref.get_mut(); for member in members { ctx_members.remove(&member); - - // Revoke privileges - ctx_members - .privileges() - .revoke(&member.rt().expect("infallible conversion")); - context - .application - .privileges() - .revoke(&member.rt().expect("infallible conversion")); + context.member_nonces.remove(&member); } Ok(()) @@ -346,3 +347,27 @@ async fn update_proxy_contract( Ok(()) } + +fn check_and_increment_nonce( + context_id: ContextId, + member_id: ContextIdentity, + nonce: u64, +) -> Result<(), String> { + with_state_mut(|configs| { + let Some(context) = configs.contexts.get_mut(&context_id) else { + return Ok(()); + }; + + let Some(current_nonce) = context.member_nonces.get_mut(&member_id) else { + return Ok(()); + }; + + if *current_nonce != nonce { + return Err("invalid nonce".into()); + } + + *current_nonce += 1; + + Ok(()) + }) +} diff --git a/contracts/icp/context-config/src/query.rs b/contracts/icp/context-config/src/query.rs index 0c5f534a9..fc2b84140 100644 --- a/contracts/icp/context-config/src/query.rs +++ b/contracts/icp/context-config/src/query.rs @@ -134,3 +134,14 @@ fn privileges( privileges }) } + +#[ic_cdk::query] +fn fetch_nonce(context_id: ICRepr, member_id: ICRepr) -> Option { + with_state(|configs| { + configs + .contexts + .get(&context_id) + .and_then(|context| context.member_nonces.get(&member_id)) + .copied() + }) +} diff --git a/contracts/icp/context-config/tests/integration.rs b/contracts/icp/context-config/tests/integration.rs index dbd7f5134..32b596910 100644 --- a/contracts/icp/context-config/tests/integration.rs +++ b/contracts/icp/context-config/tests/integration.rs @@ -294,7 +294,7 @@ fn test_member_management() { }, }), signer_id: (alice_pk.rt().expect("infallible conversion")), - nonce: 0, + nonce: 1, }; let signed_request = create_signed_request(&alice_sk, remove_member_request); @@ -403,7 +403,7 @@ fn test_capability_management() { }, }), signer_id: (alice_pk.to_bytes().rt().expect("infallible conversion")), - nonce: 0, + nonce: 1, }; let signed_request = create_signed_request(&alice_sk, grant_request); @@ -444,7 +444,7 @@ fn test_capability_management() { }, }), signer_id: (alice_pk.to_bytes().rt().expect("infallible conversion")), - nonce: 0, + nonce: 2, }; let signed_request = create_signed_request(&alice_sk, revoke_request); @@ -731,7 +731,7 @@ fn test_edge_cases() { }, }), signer_id: (alice_pk.to_bytes().rt().expect("infallible conversion")), - nonce: 0, + nonce: 1, }; let signed_request = create_signed_request(&alice_sk, add_duplicate_members); @@ -804,7 +804,7 @@ fn test_concurrent_operations() { // Create multiple member additions with same timestamp let mut requests = Vec::new(); - for _ in 0..3 { + for i in 0..3 { let new_member = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); let request = ICRequest { kind: ICRequestKind::Context(ICContextRequest { @@ -814,7 +814,7 @@ fn test_concurrent_operations() { }, }), signer_id: (alice_pk.to_bytes().rt().expect("infallible conversion")), - nonce: 0, + nonce: i as u64, }; requests.push(create_signed_request(&alice_sk, request)); } @@ -855,3 +855,110 @@ fn test_concurrent_operations() { ); } } + +#[test] +fn test_nonce_management() { + let (pic, canister) = setup(); + let mut rng = rand::thread_rng(); + + // Create test identities + let context_sk = SigningKey::from_bytes(&rng.gen()); + let context_pk = context_sk.verifying_key(); + let context_id = context_pk.rt().expect("infallible conversion"); + + let alice_sk = SigningKey::from_bytes(&rng.gen()); + let alice_pk = alice_sk.verifying_key(); + let alice_id = alice_pk.rt().expect("infallible conversion"); + + // Create initial context + let create_request = ICRequest { + kind: ICRequestKind::Context(ICContextRequest { + context_id, + kind: ICContextRequestKind::Add { + author_id: alice_id, + application: ICApplication { + id: rng.gen::<[_; 32]>().rt().expect("infallible conversion"), + blob: rng.gen::<[_; 32]>().rt().expect("infallible conversion"), + size: 0, + source: String::new(), + metadata: vec![], + }, + }, + }), + signer_id: context_id.rt().expect("infallible conversion"), + nonce: 0, + }; + + let signed_request = create_signed_request(&context_sk, create_request); + let response = pic.update_call( + canister, + Principal::anonymous(), + "mutate", + candid::encode_one(signed_request).unwrap(), + ); + handle_response(response, true, "Context creation"); + + // Test sequential nonce increment + for i in 0..3 { + let request = ICRequest { + kind: ICRequestKind::Context(ICContextRequest { + context_id, + kind: ICContextRequestKind::AddMembers { + members: vec![rng.gen::<[_; 32]>().rt().expect("infallible conversion")], + }, + }), + signer_id: alice_id.rt().expect("infallible conversion"), + nonce: i as u64, + }; + + let signed_request = create_signed_request(&alice_sk, request); + let response = pic.update_call( + canister, + Principal::anonymous(), + "mutate", + candid::encode_one(signed_request).unwrap(), + ); + handle_response(response, true, &format!("Member addition {}", i)); + + // Verify nonce was incremented + let query_response = pic.query_call( + canister, + Principal::anonymous(), + "fetch_nonce", + candid::encode_args((context_id, alice_id)).unwrap(), + ); + + let current_nonce = if let Ok(WasmResult::Reply(bytes)) = query_response { + candid::decode_one::>(&bytes).expect("Failed to decode nonce") + } else { + panic!("Failed to fetch nonce"); + }; + + assert_eq!( + current_nonce.unwrap(), + i + 1, + "Nonce should be incremented after operation" + ); + } + + // Test invalid nonce rejection + let invalid_nonce_request = ICRequest { + kind: ICRequestKind::Context(ICContextRequest { + context_id, + kind: ICContextRequestKind::AddMembers { + members: vec![rng.gen::<[_; 32]>().rt().expect("infallible conversion")], + }, + }), + signer_id: alice_id.rt().expect("infallible conversion"), + nonce: 0, // Using old nonce + }; + + let signed_request = create_signed_request(&alice_sk, invalid_nonce_request); + let response = pic.update_call( + canister, + Principal::anonymous(), + "mutate", + candid::encode_one(signed_request).unwrap(), + ); + handle_response(response, false, "Invalid nonce rejection"); +} diff --git a/contracts/icp/context-proxy/Cargo.toml b/contracts/icp/context-proxy/Cargo.toml index 6152e076d..cd81472b7 100644 --- a/contracts/icp/context-proxy/Cargo.toml +++ b/contracts/icp/context-proxy/Cargo.toml @@ -21,3 +21,5 @@ thiserror.workspace = true [dev-dependencies] pocket-ic = "6.0.0" rand = "0.8" +reqwest = { version = "0.10.10", features = ["blocking"] } +flate2 = "1.0.35" diff --git a/contracts/icp/context-proxy/build_contracts.sh b/contracts/icp/context-proxy/build_contracts.sh index a8d9cecd8..df10a76df 100755 --- a/contracts/icp/context-proxy/build_contracts.sh +++ b/contracts/icp/context-proxy/build_contracts.sh @@ -6,9 +6,6 @@ cd "$(dirname $0)" echo "Building proxy contract..." ./build.sh -echo "Building mock ledger contract..." -./mock/ledger/build.sh - echo "Building mock external contract..." ./mock/external/build.sh diff --git a/contracts/icp/context-proxy/dfx.json b/contracts/icp/context-proxy/dfx.json index bea695add..1a5ef2754 100644 --- a/contracts/icp/context-proxy/dfx.json +++ b/contracts/icp/context-proxy/dfx.json @@ -5,12 +5,6 @@ "candid": "./res/calimero_context_proxy_icp.did", "type": "rust" }, - "mock_ledger": { - "type": "rust", - "package": "calimero-mock-ledger-icp", - "candid": "./mock/ledger/res/calimero_mock_ledger_icp.did", - "path": "mock/ledger" - }, "mock_external": { "type": "rust", "package": "calimero-mock-external-icp", @@ -24,6 +18,12 @@ "packtool": "" } }, + "networks": { + "local": { + "bind": "127.0.0.1:4943", + "type": "persistent" + } + }, "output_env_file": ".env", "version": 1 } diff --git a/contracts/icp/context-proxy/mock/external/Cargo.toml b/contracts/icp/context-proxy/mock/external/Cargo.toml index 8a6b5993f..4dd47bcb8 100644 --- a/contracts/icp/context-proxy/mock/external/Cargo.toml +++ b/contracts/icp/context-proxy/mock/external/Cargo.toml @@ -10,3 +10,4 @@ crate-type = ["cdylib"] candid = "0.10" ic-cdk = "0.16" ic-cdk-macros = "0.16" +ic-ledger-types = "0.14.0" diff --git a/contracts/icp/context-proxy/mock/external/res/calimero_mock_external_icp.did b/contracts/icp/context-proxy/mock/external/res/calimero_mock_external_icp.did index 4057d383d..0aad69bcc 100644 --- a/contracts/icp/context-proxy/mock/external/res/calimero_mock_external_icp.did +++ b/contracts/icp/context-proxy/mock/external/res/calimero_mock_external_icp.did @@ -1 +1,6 @@ -service : { get_calls : () -> (vec blob) query; test_method : (blob) -> (blob) } +service : (principal) -> { + clear_state : () -> (); + get_calls : () -> (vec blob) query; + test_method : (blob) -> (blob); + test_method_no_transfer : (blob) -> (blob); +} diff --git a/contracts/icp/context-proxy/mock/external/src/lib.rs b/contracts/icp/context-proxy/mock/external/src/lib.rs index ca10b9152..f230e9c3d 100644 --- a/contracts/icp/context-proxy/mock/external/src/lib.rs +++ b/contracts/icp/context-proxy/mock/external/src/lib.rs @@ -1,15 +1,65 @@ use std::cell::RefCell; +use candid::Principal; +use ic_ledger_types::{AccountIdentifier, Memo, Subaccount, Tokens, TransferArgs, TransferError}; + thread_local! { static CALLS: RefCell>> = RefCell::new(Vec::new()); + static LEDGER_ID: RefCell> = RefCell::new(None); +} + +#[ic_cdk::init] +fn init(ledger_id: Principal) { + LEDGER_ID.with(|id| { + *id.borrow_mut() = Some(ledger_id); + }); } #[ic_cdk::update] -fn test_method(args: Vec) -> Vec { +async fn test_method(args: Vec) -> Vec { + let self_id = ic_cdk::id(); + let caller = ic_cdk::caller(); + + let ledger_id = LEDGER_ID.with(|id| id.borrow().expect("Ledger ID not initialized")); + + // Prepare transfer args to move the approved tokens + let transfer_args = TransferArgs { + memo: Memo(0), + amount: Tokens::from_e8s(100_000_000), // Example amount, in practice this would be parsed from args + fee: Tokens::from_e8s(10_000), + from_subaccount: Some(Subaccount::from(caller)), + to: AccountIdentifier::new(&self_id, &Subaccount([0; 32])), + created_at_time: None, + }; + + // Execute the transfer with proper type annotations + let transfer_result: Result<(Result,), _> = + ic_cdk::call(ledger_id, "transfer", (transfer_args,)).await; + + match transfer_result { + Ok((Ok(_block_height),)) => { + // Transfer successful, record the call + CALLS.with(|calls| { + calls.borrow_mut().push(args.clone()); + }); + args // Return the same args back + } + Ok((Err(transfer_error),)) => { + ic_cdk::trap(&format!("Transfer failed: {:?}", transfer_error)); + } + Err(e) => { + ic_cdk::trap(&format!("Call to ledger failed: {:?}", e)); + } + } +} + +#[ic_cdk::update] +async fn test_method_no_transfer(args: Vec) -> Vec { + // Simply record the call and return CALLS.with(|calls| { calls.borrow_mut().push(args.clone()); - args // Return the same args back - }) + }); + args } #[ic_cdk::query] @@ -17,4 +67,10 @@ fn get_calls() -> Vec> { CALLS.with(|calls| calls.borrow().clone()) } +// Clear state (useful for testing) +#[ic_cdk::update] +fn clear_state() { + CALLS.with(|calls| calls.borrow_mut().clear()); +} + ic_cdk::export_candid!(); diff --git a/contracts/icp/context-proxy/mock/ledger/Cargo.toml b/contracts/icp/context-proxy/mock/ledger/Cargo.toml deleted file mode 100644 index df65c8b1d..000000000 --- a/contracts/icp/context-proxy/mock/ledger/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "calimero-mock-ledger-icp" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -candid = "0.10" -serde = { version = "1.0", features = ["derive"] } -ic-cdk = "0.16" -ic-cdk-macros = "0.16" -ic-ledger-types = "0.14.0" diff --git a/contracts/icp/context-proxy/mock/ledger/build.sh b/contracts/icp/context-proxy/mock/ledger/build.sh deleted file mode 100755 index d9d74e1ef..000000000 --- a/contracts/icp/context-proxy/mock/ledger/build.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -set -e - -cd "$(dirname $0)" - -TARGET="${CARGO_TARGET_DIR:-../../../../../target}" - -rustup target add wasm32-unknown-unknown - -cargo build --target wasm32-unknown-unknown --profile app-release - -mkdir -p res - -cp $TARGET/wasm32-unknown-unknown/app-release/calimero_mock_ledger_icp.wasm ./res/ - -if command -v wasm-opt > /dev/null; then - wasm-opt -Oz ./res/calimero_mock_ledger_icp.wasm -o ./res/calimero_mock_ledger_icp.wasm -fi - -if command -v candid-extractor > /dev/null; then - candid-extractor ./res/calimero_mock_ledger_icp.wasm > ./res/calimero_mock_ledger_icp.did -fi diff --git a/contracts/icp/context-proxy/mock/ledger/res/calimero_mock_ledger_icp.did b/contracts/icp/context-proxy/mock/ledger/res/calimero_mock_ledger_icp.did deleted file mode 100644 index 3b3ac2fd5..000000000 --- a/contracts/icp/context-proxy/mock/ledger/res/calimero_mock_ledger_icp.did +++ /dev/null @@ -1,23 +0,0 @@ -type AccountBalanceArgs = record { account : blob }; -type Result = variant { Ok : nat64; Err : TransferError }; -type Timestamp = record { timestamp_nanos : nat64 }; -type Tokens = record { e8s : nat64 }; -type TransferArgs = record { - to : blob; - fee : Tokens; - memo : nat64; - from_subaccount : opt blob; - created_at_time : opt Timestamp; - amount : Tokens; -}; -type TransferError = variant { - TxTooOld : record { allowed_window_nanos : nat64 }; - BadFee : record { expected_fee : Tokens }; - TxDuplicate : record { duplicate_of : nat64 }; - TxCreatedInFuture; - InsufficientFunds : record { balance : Tokens }; -}; -service : { - account_balance : (AccountBalanceArgs) -> (Tokens) query; - transfer : (TransferArgs) -> (Result); -} diff --git a/contracts/icp/context-proxy/mock/ledger/src/lib.rs b/contracts/icp/context-proxy/mock/ledger/src/lib.rs deleted file mode 100644 index 11de831d9..000000000 --- a/contracts/icp/context-proxy/mock/ledger/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::cell::RefCell; - -use candid::{CandidType, Deserialize}; -use ic_ledger_types::{AccountIdentifier, BlockIndex, Tokens, TransferArgs, TransferError}; - -thread_local! { - static BALANCE: RefCell = RefCell::new(1_000_000_000); -} - -type TransferResult = Result; - -#[ic_cdk::update] -fn transfer(args: TransferArgs) -> TransferResult { - ic_cdk::println!( - "Mock ledger received transfer: to={:?}, amount={}", - args.to, - args.amount - ); - - // Verify fee - if args.fee.e8s() != 10_000 { - return Err(TransferError::BadFee { - expected_fee: Tokens::from_e8s(10_000), - }); - } - - let amount_e8s = args.amount.e8s(); - - BALANCE.with(|balance| { - let mut bal = balance.borrow_mut(); - - // Check if we have enough balance - if amount_e8s > *bal { - return Err(TransferError::InsufficientFunds { - balance: Tokens::from_e8s(*bal), - }); - } - - // Subtract amount and fee - *bal = bal.saturating_sub(amount_e8s); - *bal = bal.saturating_sub(args.fee.e8s()); - - ic_cdk::println!("New balance: {}", *bal); - - // Return mock block index - Ok(1) - }) -} - -#[ic_cdk::query] -fn account_balance(_args: AccountBalanceArgs) -> Tokens { - BALANCE.with(|balance| Tokens::from_e8s(*balance.borrow())) -} - -#[derive(CandidType, Deserialize)] -struct AccountBalanceArgs { - account: AccountIdentifier, -} - -ic_cdk::export_candid!(); diff --git a/contracts/icp/context-proxy/res/calimero_context_proxy_icp.did b/contracts/icp/context-proxy/res/calimero_context_proxy_icp.did index 7dd442d89..566c10fff 100644 --- a/contracts/icp/context-proxy/res/calimero_context_proxy_icp.did +++ b/contracts/icp/context-proxy/res/calimero_context_proxy_icp.did @@ -17,7 +17,6 @@ type ICProposalAction = variant { }; }; type ICProposalApprovalWithSigner = record { - added_timestamp : nat64; signer_id : blob; proposal_id : blob; }; diff --git a/contracts/icp/context-proxy/src/mutate.rs b/contracts/icp/context-proxy/src/mutate.rs index b9ab239f2..a0042d387 100644 --- a/contracts/icp/context-proxy/src/mutate.rs +++ b/contracts/icp/context-proxy/src/mutate.rs @@ -7,9 +7,11 @@ use calimero_context_config::icp::{ ICProxyMutateRequest, }; use calimero_context_config::types::{ProposalId, SignerId}; -use candid::Principal; +use candid::{Nat, Principal}; use ic_cdk::api::call::CallResult; -use ic_ledger_types::{AccountIdentifier, Memo, Subaccount, Tokens, TransferArgs, TransferError}; +use ic_ledger_types::{ + AccountIdentifier, Memo, Subaccount, Timestamp, Tokens, TransferArgs, TransferError, +}; use crate::{with_state, with_state_mut, ICProxyContract}; @@ -89,36 +91,74 @@ async fn execute_proposal(proposal_id: &ProposalId) -> Result<(), String> { args, deposit, } => { - // If there's a deposit, transfer it first if deposit > 0 { let ledger_id = with_state(|contract| contract.ledger_id.clone()); - let transfer_args = TransferArgs { - memo: Memo(0), - amount: Tokens::from_e8s( - deposit - .try_into() - .map_err(|e| format!("Amount conversion error: {}", e))?, - ), - fee: Tokens::from_e8s(10_000), // Standard fee is 0.0001 ICP - from_subaccount: None, - to: AccountIdentifier::new(&receiver_id, &Subaccount([0; 32])), - created_at_time: None, - }; - - let _: (Result,) = - ic_cdk::call(Principal::from(ledger_id), "transfer", (transfer_args,)) + // 1. First approve 0 + let approve_args = ( + None::, // from_subaccount + AccountIdentifier::new(&receiver_id, &Subaccount([0; 32])), // spender + 0_u128, // amount (0) + None::, // expected_allowance + None::, // expires_at + None::, // memo + None::, // created_at_time + ); + + let (approve_result,): (Result,) = + ic_cdk::call(Principal::from(ledger_id), "icrc2_approve", approve_args) + .await + .map_err(|e| format!("Initial approve(0) failed: {:?}", e))?; + + approve_result.map_err(|e| format!("Initial approve(0) rejected: {}", e))?; + + // 2. Approve the deposit amount + let approve_args = ( + None::, // from_subaccount + AccountIdentifier::new(&receiver_id, &Subaccount([0; 32])), // spender + deposit as u128, // amount + None::, // expected_allowance + None::, // expires_at + None::, // memo + None::, // created_at_time + ); + + let (approve_result,): (Result,) = + ic_cdk::call(Principal::from(ledger_id), "icrc2_approve", approve_args) .await - .map_err(|e| format!("Transfer failed: {:?}", e))?; + .map_err(|e| format!("Approve deposit failed: {:?}", e))?; + + approve_result.map_err(|e| format!("Approve deposit rejected: {}", e))?; } - // Then make the actual cross-contract call + // 3. Make the cross-contract call let args_bytes = candid::encode_one(args) .map_err(|e| format!("Failed to encode args: {}", e))?; let _: () = ic_cdk::call(receiver_id, method_name.as_str(), (args_bytes,)) .await .map_err(|e| format!("Inter-canister call failed: {:?}", e))?; + + // 4. Final approve(0) only if we did initial approvals + if deposit > 0 { + let ledger_id = with_state(|contract| contract.ledger_id.clone()); + let approve_args = ( + None::, // from_subaccount + AccountIdentifier::new(&receiver_id, &Subaccount([0; 32])), // spender + 0_u128, // amount (0) + None::, // expected_allowance + None::, // expires_at + None::, // memo + None::, // created_at_time + ); + + let (approve_result,): (Result,) = + ic_cdk::call(Principal::from(ledger_id), "icrc2_approve", approve_args) + .await + .map_err(|e| format!("Approve deposit failed: {:?}", e))?; + + approve_result.map_err(|e| format!("Approve deposit rejected: {}", e))?; + } } ICProposalAction::Transfer { receiver_id, diff --git a/contracts/icp/context-proxy/tests/integration.rs b/contracts/icp/context-proxy/tests/integration.rs index 0f553b3a3..e1683e6d3 100644 --- a/contracts/icp/context-proxy/tests/integration.rs +++ b/contracts/icp/context-proxy/tests/integration.rs @@ -1,4 +1,5 @@ use std::cell::RefCell; +use std::io::Read; use calimero_context_config::icp::repr::ICRepr; use calimero_context_config::icp::types::{ @@ -10,11 +11,15 @@ use calimero_context_config::icp::{ }; use calimero_context_config::repr::ReprTransmute; use calimero_context_config::types::{ContextId, ContextIdentity}; -use candid::Principal; +use candid::{CandidType, Principal}; use ed25519_dalek::{Signer, SigningKey}; -use ic_ledger_types::{AccountBalanceArgs, AccountIdentifier, Subaccount, Tokens}; +use flate2::read::GzDecoder; +use ic_ledger_types::{ + AccountBalanceArgs, AccountIdentifier, Memo, Subaccount, Tokens, TransferArgs, TransferError, +}; use pocket_ic::{PocketIc, WasmResult}; use rand::Rng; +use reqwest; // Mock canister states thread_local! { @@ -78,12 +83,81 @@ struct ProxyTestContext { mock_external: Principal, author_sk: SigningKey, context_id: ICRepr, + test_user: Principal, +} + +#[derive(CandidType)] +enum LedgerCanisterInit { + Init(LedgerCanisterInitPayload), +} + +#[derive(CandidType)] +struct LedgerCanisterInitPayload { + minting_account: String, + initial_values: Vec<(String, Tokens)>, + send_whitelist: Vec, + transfer_fee: Option, + token_symbol: Option, + token_name: Option, + archive_options: Option, +} + +#[derive(CandidType)] +struct ArchiveOptions { + trigger_threshold: u64, + num_blocks_to_archive: u64, + controller_id: Principal, } fn setup() -> ProxyTestContext { let pic = PocketIc::new(); let mut rng = rand::thread_rng(); + // Create test user principal first + let test_user = Principal::from_text("rrkah-fqaaa-aaaaa-aaaaq-cai").unwrap(); + + // Setup ledger canister + let mock_ledger = pic.create_canister(); + pic.add_cycles(mock_ledger, 100_000_000_000_000_000); + + // Download the compressed ledger wasm + let compressed_wasm = reqwest::blocking::get( + "https://download.dfinity.systems/ic/aba60ffbc46acfc8990bf4d5685c1360bd7026b9/canisters/ledger-canister.wasm.gz" + ).expect("Failed to download ledger wasm") + .bytes().expect("Failed to read ledger wasm bytes"); + + // Decompress the wasm file + let mut decoder = GzDecoder::new(&compressed_wasm[..]); + let mut ledger_wasm = Vec::new(); + decoder + .read_to_end(&mut ledger_wasm) + .expect("Failed to decompress ledger wasm"); + + // Initialize ledger with the same args as in dfx.json + let init_args = LedgerCanisterInit::Init(LedgerCanisterInitPayload { + minting_account: "e8478037d13e48f9d43d28136328d0642e4ed680c8be9f08f0da98791740203c" + .to_string(), + initial_values: vec![( + AccountIdentifier::new(&test_user, &Subaccount([0; 32])).to_string(), + Tokens::from_e8s(100_000_000_000), + )], + send_whitelist: vec![test_user], // Add test_user to whitelist + transfer_fee: Some(Tokens::from_e8s(10_000)), + token_symbol: Some("LICP".to_string()), + token_name: Some("Local Internet Computer Protocol Token".to_string()), + archive_options: Some(ArchiveOptions { + trigger_threshold: 2000, + num_blocks_to_archive: 1000, + controller_id: Principal::from_text( + "bwmrp-pfufw-yvlwr-nwbuh-4ko7l-2fz7x-kt6gq-4d3mc-hzqsi-pfwmp-kqe", + ) + .unwrap(), + }), + }); + + let init_args = candid::encode_one(init_args).expect("Failed to encode ledger init args"); + pic.install_canister(mock_ledger, ledger_wasm, init_args, None); + // Setup context contract first let context_canister = pic.create_canister(); pic.add_cycles(context_canister, 100_000_000_000_000_000); @@ -91,22 +165,18 @@ fn setup() -> ProxyTestContext { .expect("failed to read context wasm"); pic.install_canister(context_canister, context_wasm, vec![], None); - // Setup mock ledger - let mock_ledger = pic.create_canister(); - pic.add_cycles(mock_ledger, 100_000_000_000_000); - let mock_ledger_wasm = std::fs::read("mock/ledger/res/calimero_mock_ledger_icp.wasm") - .expect("failed to read mock ledger wasm"); - pic.install_canister(mock_ledger, mock_ledger_wasm, vec![], None); - // Set proxy code in context contract set_proxy_code(&pic, context_canister, mock_ledger).expect("Failed to set proxy code"); - // Setup mock external + // Setup mock external with ledger ID let mock_external = pic.create_canister(); pic.add_cycles(mock_external, 100_000_000_000_000); let mock_external_wasm = std::fs::read("mock/external/res/calimero_mock_external_icp.wasm") .expect("failed to read mock external wasm"); - pic.install_canister(mock_external, mock_external_wasm, vec![], None); + + // Pass ledger ID during initialization + let init_args = candid::encode_one(mock_ledger).expect("Failed to encode ledger ID"); + pic.install_canister(mock_external, mock_external_wasm, init_args, None); // Create initial author key let author_sk = SigningKey::from_bytes(&rng.gen()); @@ -124,6 +194,7 @@ fn setup() -> ProxyTestContext { mock_external, author_sk, context_id, + test_user, } } @@ -163,6 +234,9 @@ fn create_context_with_proxy( ) -> Result<(Principal, ICRepr), String> { let mut rng = rand::thread_rng(); + // Get initial cycle balance + let initial_cycle_balance = pic.cycle_balance(context_canister); + // Generate context ID let context_sk = SigningKey::from_bytes(&rng.gen()); let context_pk = context_sk.verifying_key(); @@ -218,7 +292,7 @@ fn create_context_with_proxy( candid::encode_one(context_id).unwrap(), ); - match query_response { + let result = match query_response { Ok(WasmResult::Reply(bytes)) => { let proxy_canister: Principal = candid::decode_one(&bytes) .map_err(|e| format!("Failed to decode proxy canister ID: {}", e))?; @@ -226,7 +300,14 @@ fn create_context_with_proxy( } Ok(WasmResult::Reject(msg)) => Err(format!("Query rejected: {}", msg)), Err(e) => Err(format!("Query failed: {}", e)), - } + }; + + // Get final cycle balance and calculate usage + let final_cycle_balance = pic.cycle_balance(context_canister); + let cycles_used = initial_cycle_balance - final_cycle_balance; + println!("Cycles used in create_context_with_proxy: {}", cycles_used); + + result } // Helper function to add members to context @@ -392,6 +473,9 @@ fn test_create_proposal_transfer() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -407,6 +491,11 @@ fn test_create_proposal_transfer() { create_and_verify_proposal(&pic, proxy_canister, &author_sk, proposal) .expect("Transfer proposal creation should succeed"); + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -420,6 +509,9 @@ fn test_create_proposal_external_call() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -429,7 +521,7 @@ fn test_create_proposal_external_call() { author_id, actions: vec![ICProposalAction::ExternalFunctionCall { receiver_id: Principal::anonymous(), - method_name: "test_method".to_string(), + method_name: "test_method_no_transfer".to_string(), args: "deadbeef".to_string(), deposit: 0, }], @@ -437,6 +529,11 @@ fn test_create_proposal_external_call() { create_and_verify_proposal(&pic, proxy_canister, &author_sk, proposal) .expect("External call proposal creation should succeed"); + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -450,6 +547,9 @@ fn test_create_proposal_set_context() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -465,6 +565,11 @@ fn test_create_proposal_set_context() { create_and_verify_proposal(&pic, proxy_canister, &author_sk, proposal) .expect("Setting context value should succeed"); + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -478,6 +583,9 @@ fn test_create_proposal_multiple_actions() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -495,6 +603,11 @@ fn test_create_proposal_multiple_actions() { create_and_verify_proposal(&pic, proxy_canister, &author_sk, proposal) .expect("Multiple actions proposal creation should succeed"); + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -508,6 +621,9 @@ fn test_create_proposal_invalid_transfer_amount() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -547,6 +663,11 @@ fn test_create_proposal_invalid_transfer_amount() { panic!("Failed to call canister: {}", err); } } + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -560,6 +681,9 @@ fn test_create_proposal_invalid_method_name() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -598,6 +722,11 @@ fn test_create_proposal_invalid_method_name() { panic!("Failed to call canister: {}", err); } } + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -611,6 +740,9 @@ fn test_approve_own_proposal() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -651,6 +783,11 @@ fn test_approve_own_proposal() { } _ => panic!("Unexpected response type"), } + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -664,6 +801,9 @@ fn test_approve_non_existent_proposal() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let signer_pk = signer_sk.verifying_key(); let signer_id = signer_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -694,6 +834,11 @@ fn test_approve_non_existent_proposal() { } _ => panic!("Unexpected response type"), } + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -707,6 +852,9 @@ fn test_create_proposal_empty_actions() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); @@ -739,6 +887,11 @@ fn test_create_proposal_empty_actions() { } _ => panic!("Unexpected response type"), } + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -752,6 +905,9 @@ fn test_create_proposal_exceeds_limit() { .. } = setup(); + // Get initial cycle balance + let initial_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); @@ -798,6 +954,11 @@ fn test_create_proposal_exceeds_limit() { } _ => panic!("Unexpected response type"), } + + // Get new cycle balance and calculate usage + let new_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_balance - new_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -812,10 +973,47 @@ fn test_proposal_execution_transfer() { author_sk, context_canister, context_id, + test_user, .. } = setup(); - let initial_balance = MOCK_LEDGER_BALANCE.with(|b| *b.borrow()); + // First, seed the proxy with tokens + let seed_amount = 1_000_000; + let transfer_args = TransferArgs { + memo: Memo(0), + amount: Tokens::from_e8s(seed_amount), + fee: Tokens::from_e8s(10_000), + from_subaccount: None, + to: AccountIdentifier::new(&proxy_canister, &Subaccount([0; 32])), + created_at_time: None, + }; + + // Use test_user for the transfer since it has the tokens + let response = pic + .update_call( + mock_ledger, + test_user, + "transfer", + candid::encode_one(transfer_args).unwrap(), + ) + .expect("Failed to call transfer"); + + match response { + WasmResult::Reply(bytes) => { + let result: Result = + candid::decode_one(&bytes).expect("Failed to decode transfer result"); + match result { + Ok(block_height) => { + println!("Transfer successful at block height: {}", block_height) + } + Err(e) => panic!("Transfer failed: {:?}", e), + } + } + WasmResult::Reject(msg) => panic!("Transfer rejected: {}", msg), + } + + // Get initial cycle balance + let initial_cycle_balance = pic.cycle_balance(proxy_canister); // Setup signers let author_pk = author_sk.verifying_key(); @@ -833,7 +1031,6 @@ fn test_proposal_execution_transfer() { let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); - // let receiver_id = Principal::from_text("bnz7o-iuaaa-aaaaa-qaaaa-cai").unwrap(); // Create transfer proposal let proposal = ICProposal { id: proposal_id, @@ -919,7 +1116,7 @@ fn test_proposal_execution_transfer() { } let args = AccountBalanceArgs { - account: AccountIdentifier::new(&Principal::anonymous(), &Subaccount([0; 32])), + account: AccountIdentifier::new(&mock_external, &Subaccount([0; 32])), }; let response = pic @@ -935,17 +1132,20 @@ fn test_proposal_execution_transfer() { WasmResult::Reply(bytes) => { let balance: Tokens = candid::decode_one(&bytes).expect("Failed to decode balance"); let final_balance = balance.e8s(); - // Verify the transfer was executed + // Verify the transfer was executed - mock_external should have received exactly transfer_amount assert_eq!( final_balance, - initial_balance - .saturating_sub(transfer_amount as u64) - .saturating_sub(10_000), // Subtract both transfer amount and fee - "Transfer amount should be deducted from ledger balance" + u64::try_from(transfer_amount).unwrap(), // mock_external should have exactly the amount we transferred + "Receiver should have received the transfer amount" ); } _ => panic!("Unexpected response type"), } + + // Get final cycle balance and calculate usage + let final_cycle_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_cycle_balance - final_cycle_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -962,6 +1162,9 @@ fn test_proposal_execution_external_call() { .. } = setup(); + // Get initial cycle balance + let initial_cycle_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); @@ -982,7 +1185,7 @@ fn test_proposal_execution_external_call() { author_id, actions: vec![ICProposalAction::ExternalFunctionCall { receiver_id: mock_external, - method_name: "test_method".to_string(), + method_name: "test_method_no_transfer".to_string(), args: test_args.clone(), deposit: 0, }], @@ -1084,6 +1287,11 @@ fn test_proposal_execution_external_call() { } _ => panic!("Unexpected response type"), } + + // Get final cycle balance and calculate usage + let final_cycle_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_cycle_balance - final_cycle_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -1101,6 +1309,9 @@ fn test_proposal_execution_external_call_with_deposit() { .. } = setup(); + let initial_cycle_balance = pic.cycle_balance(proxy_canister); + let initial_ledger_balance = MOCK_LEDGER_BALANCE.with(|b| *b.borrow()); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); @@ -1114,9 +1325,9 @@ fn test_proposal_execution_external_call_with_deposit() { let proposal_id = rng.gen::<[_; 32]>().rt().expect("infallible conversion"); - // Create external call proposal + // Create external call proposal with deposit let deposit_amount = 1_000_000; - let test_args = "01020304".to_string(); // Test arguments as string + let test_args = "01020304".to_string(); let proposal = ICProposal { id: proposal_id, author_id, @@ -1154,22 +1365,20 @@ fn test_proposal_execution_external_call_with_deposit() { let request = ICProxyMutateRequest::Approve { approval }; let signed_request = create_signed_request(&signer_sk, request); - let response = pic - .update_call( - proxy_canister, - Principal::anonymous(), - "mutate", - candid::encode_one(signed_request).unwrap(), - ) - .expect("Failed to approve proposal"); + let response = pic.update_call( + proxy_canister, + Principal::anonymous(), + "mutate", + candid::encode_one(signed_request).unwrap(), + ); match response { - WasmResult::Reply(bytes) => { + Ok(WasmResult::Reply(bytes)) => { let result: Result, String> = candid::decode_one(&bytes).expect("Failed to decode response"); if let Ok(None) = result { - // Proposal was executed, verify it's gone + // Verify proposal was executed and removed let query_response = pic .query_call( proxy_canister, @@ -1190,61 +1399,67 @@ fn test_proposal_execution_external_call_with_deposit() { } WasmResult::Reject(msg) => panic!("Query rejected: {}", msg), } - } - } - WasmResult::Reject(msg) => panic!("Approval rejected: {}", msg), - } - } - // Verify the transfer was executed by checking mock ledger balance - let args = AccountBalanceArgs { - account: AccountIdentifier::new(&mock_external, &Subaccount([0; 32])), - }; + // Verify the external call was executed + let calls_response = pic + .query_call( + mock_external, + Principal::anonymous(), + "get_calls", + candid::encode_args(()).unwrap(), + ) + .expect("Query failed"); - let response = pic - .query_call( - mock_ledger, - Principal::anonymous(), - "account_balance", - candid::encode_one(args).unwrap(), - ) - .expect("Failed to query balance"); + match calls_response { + WasmResult::Reply(bytes) => { + let calls: Vec> = + candid::decode_one(&bytes).expect("Failed to decode calls"); + assert_eq!(calls.len(), 1, "Should have exactly one call"); - match response { - WasmResult::Reply(bytes) => { - let balance: Tokens = candid::decode_one(&bytes).expect("Failed to decode balance"); - let gas_fee = 10_000; - assert_eq!( - balance.e8s(), - MOCK_LEDGER_BALANCE.with(|b| *b.borrow()) - deposit_amount as u64 - gas_fee as u64, - "External contract should have received the deposit" - ); - } - WasmResult::Reject(msg) => panic!("Balance query rejected: {}", msg), - } + let received_args: String = candid::decode_one(&calls[0]) + .expect("Failed to decode call arguments"); + assert_eq!(received_args, test_args, "Call arguments should match"); + } + _ => panic!("Unexpected response type"), + } - // Verify the external call was executed - let response = pic - .query_call( - mock_external, - Principal::anonymous(), - "get_calls", - candid::encode_args(()).unwrap(), - ) - .expect("Query failed"); + // Verify the ledger balance changes + // The mock external contract should have received the deposit + let balance_args = AccountBalanceArgs { + account: AccountIdentifier::new(&mock_external, &Subaccount([0; 32])), + }; - match response { - WasmResult::Reply(bytes) => { - let calls: Vec> = candid::decode_one(&bytes).expect("Failed to decode calls"); - assert_eq!(calls.len(), 1, "Should have exactly one call"); + let balance_response = pic + .query_call( + mock_ledger, + Principal::anonymous(), + "account_balance", + candid::encode_one(balance_args).unwrap(), + ) + .expect("Failed to query balance"); - // Decode the Candid-encoded argument - let received_args: String = - candid::decode_one(&calls[0]).expect("Failed to decode call arguments"); - assert_eq!(received_args, test_args, "Call arguments should match"); + match balance_response { + WasmResult::Reply(bytes) => { + let balance: Tokens = + candid::decode_one(&bytes).expect("Failed to decode balance"); + let expected_balance = initial_ledger_balance + deposit_amount as u64; + assert_eq!( + balance.e8s(), + expected_balance, + "External contract should have received the deposit" + ); + } + _ => panic!("Unexpected response type"), + } + } + } + _ => panic!("Unexpected response type"), } - _ => panic!("Unexpected response type"), } + + let final_cycle_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_cycle_balance - final_cycle_balance; + println!("Cycles used: {}", cycles_used); } #[test] @@ -1258,6 +1473,9 @@ fn test_delete_proposal() { .. } = setup(); + // Get initial cycle balance + let initial_cycle_balance = pic.cycle_balance(proxy_canister); + let author_pk = author_sk.verifying_key(); let author_id = author_pk.rt().expect("infallible conversion"); @@ -1318,4 +1536,9 @@ fn test_delete_proposal() { } WasmResult::Reject(msg) => panic!("Query rejected: {}", msg), } + + // Get final cycle balance and calculate usage + let final_cycle_balance = pic.cycle_balance(proxy_canister); + let cycles_used = initial_cycle_balance - final_cycle_balance; + println!("Cycles used: {}", cycles_used); } diff --git a/contracts/near/context-config/tests/sandbox.rs b/contracts/near/context-config/tests/sandbox.rs index 73f9112ee..a524d1590 100644 --- a/contracts/near/context-config/tests/sandbox.rs +++ b/contracts/near/context-config/tests/sandbox.rs @@ -1371,7 +1371,7 @@ async fn test_storage_usage_matches_code_size() -> eyre::Result<()> { context_id, ContextRequestKind::UpdateProxyContract, )); - Request::new(alice_cx_id.rt()?, kind, 0) + Request::new(alice_cx_id.rt()?, kind, 1) }, |p| alice_cx_sk.sign(p), )?) diff --git a/crates/context/config/src/client/env/config/query/fetch_nonce.rs b/crates/context/config/src/client/env/config/query/fetch_nonce.rs index 6b1acbb63..83dc11b82 100644 --- a/crates/context/config/src/client/env/config/query/fetch_nonce.rs +++ b/crates/context/config/src/client/env/config/query/fetch_nonce.rs @@ -87,9 +87,8 @@ impl Method for FetchNonceRequest { let context_id = ICRepr::new(*self.context_id); let member_id = ICRepr::new(*self.member_id); - let payload = (context_id, member_id); - - Encode!(&payload).map_err(Into::into) + // Encode arguments separately + Encode!(&context_id, &member_id).map_err(Into::into) } fn decode(response: Vec) -> eyre::Result { diff --git a/crates/context/src/lib.rs b/crates/context/src/lib.rs index c322c4487..61c77ef37 100644 --- a/crates/context/src/lib.rs +++ b/crates/context/src/lib.rs @@ -1421,4 +1421,15 @@ impl ContextManager { .map_err(|err| eyre::eyre!("Failed to fetch context storage entries: {}", err))?; Ok(response) } + + pub async fn get_proxy_id(&self, context_id: ContextId) -> EyreResult { + let handle = self.store.handle(); + let Some(context_config) = handle.get(&ContextConfigKey::new(context_id))? else { + bail!("Context not found"); + }; + + let proxy_contract = context_config.proxy_contract.as_ref().into(); + + Ok(proxy_contract) + } } diff --git a/crates/merod/src/cli/init.rs b/crates/merod/src/cli/init.rs index 4d66d5c3b..9dbb00800 100644 --- a/crates/merod/src/cli/init.rs +++ b/crates/merod/src/cli/init.rs @@ -299,7 +299,7 @@ impl InitCommand { "0x1b991ee006e2d1e372ab96d0a957401fa200358f317b681df2948f30e17c29c" .parse()? } - ConfigProtocol::Icp => "br5f7-7uaaa-aaaaa-qaaca-cai".parse()?, + ConfigProtocol::Icp => "bkyz2-fmaaa-aaaaa-qaaaq-cai".parse()?, }, }, }, diff --git a/crates/server/src/admin/handlers/proposals.rs b/crates/server/src/admin/handlers/proposals.rs index a8e8e4e7f..2edec97b6 100644 --- a/crates/server/src/admin/handlers/proposals.rs +++ b/crates/server/src/admin/handlers/proposals.rs @@ -110,6 +110,12 @@ pub struct GetProposalResponse { pub data: ProposalConfig, } +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct GetProxyContractResponse { + pub data: String, +} + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct GetProposalsRequest { @@ -181,6 +187,21 @@ pub async fn get_proposal_handler( } } +pub async fn get_proxy_contract_handler( + Path(context_id): Path, + Extension(state): Extension>, +) -> impl IntoResponse { + match state.ctx_manager.get_proxy_id(context_id).await { + Ok(proxy_contract) => ApiResponse { + payload: GetProxyContractResponse { + data: proxy_contract, + }, + } + .into_response(), + Err(err) => parse_api_error(err).into_response(), + } +} + pub async fn get_context_value_handler( Path(context_id): Path, Extension(state): Extension>, diff --git a/crates/server/src/admin/service.rs b/crates/server/src/admin/service.rs index f31e31d1a..215a612f6 100644 --- a/crates/server/src/admin/service.rs +++ b/crates/server/src/admin/service.rs @@ -23,6 +23,7 @@ use super::handlers::proposals::{ get_context_storage_entries_handler, get_context_value_handler, get_number_of_active_proposals_handler, get_number_of_proposal_approvals_handler, get_proposal_approvers_handler, get_proposal_handler, get_proposals_handler, + get_proxy_contract_handler, }; use super::storage::ssl::get_ssl; use crate::admin::handlers::add_client_key::{ @@ -173,6 +174,10 @@ pub(crate) fn setup( .route( "/contexts/:context_id/proposals/context-storage-entries", post(get_context_storage_entries_handler), + ) + .route( + "/contexts/:context_id/proxy-contract", + get(get_proxy_contract_handler), ); let dev_router = Router::new()