From bc48a7382519642a8b4c96ca05505211599af0f2 Mon Sep 17 00:00:00 2001 From: Phuong Nguyen Date: Thu, 19 Oct 2023 15:37:47 -0700 Subject: [PATCH 1/2] fix: nonce issues (#310) * Internalize RwLock into ShiningState * made &TestContext<'a> => TestContext * Added near_fetch library for cached nonces * Added KeyRotatingSigner * tmp * Working stress test * Cleaning up * Use Open Source Relayer for integration tests * Fmt * cleanup * Fix wrong container image * Working local testing * Moved running local related testing functions over to local.rs * Reduced LeaderNode::api to not require arguments * Moved all containers init into env/ * Moved containers.rs and local.rs into env/ * Change feature flag to docker-test * Fix docker test * Consistent way to create CLI args * Removed need for integration-tests/main.rs * Update docs and cleanup * Cleanup * setup-env cmd * Update GA pipeline * More cleanup * Use env::run for setup-env * More cleanup * Better setup-env logging * prefer 127.0.0.1 over localhost to enforce IPv4 * Separate out docker image dep * Rename local_url to pk_local_url * tmp * Minor fixes for local build * Terraform * Fix parsing * Actually fix parsing * Address comments --------- Co-authored-by: Daniyar Itegulov --- Cargo.lock | 625 ++++++++++++------------ infra/modules/leader/main.tf | 2 +- infra/terraform-dev.tfvars | 2 +- integration-tests/Cargo.toml | 1 + integration-tests/src/env/containers.rs | 47 +- integration-tests/src/env/local.rs | 9 +- integration-tests/src/lib.rs | 10 +- integration-tests/src/sandbox.rs | 38 +- integration-tests/src/util.rs | 18 +- integration-tests/tests/mpc/positive.rs | 87 ++-- mpc-recovery/Cargo.toml | 1 + mpc-recovery/src/leader_node/mod.rs | 47 +- mpc-recovery/src/lib.rs | 61 ++- mpc-recovery/src/nar.rs | 117 ----- mpc-recovery/src/oauth.rs | 5 +- mpc-recovery/src/relayer/mod.rs | 54 +- mpc-recovery/src/transaction.rs | 38 +- 17 files changed, 569 insertions(+), 593 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5fb9c5292..055342012 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,7 +30,7 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", - "tokio-util 0.7.9", + "tokio-util 0.7.8", ] [[package]] @@ -40,7 +40,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -56,13 +56,13 @@ dependencies = [ [[package]] name = "actix_derive" -version = "0.6.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3" +checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 1.0.109", ] [[package]] @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.10.3" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" dependencies = [ "aead", "aes", @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -163,9 +163,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", @@ -177,15 +177,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -252,7 +252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener 2.5.3", + "event-listener", "futures-core", ] @@ -283,7 +283,7 @@ dependencies = [ "log", "parking", "polling", - "rustix 0.37.25", + "rustix 0.37.23", "slab", "socket2", "waker-fn", @@ -295,41 +295,24 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ - "event-listener 2.5.3", + "event-listener", ] [[package]] name = "async-process" -version = "1.8.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" dependencies = [ "async-io", "async-lock", - "async-signal", + "autocfg 1.1.0", "blocking", "cfg-if 1.0.0", - "event-listener 3.0.0", + "event-listener", "futures-lite", - "rustix 0.38.18", - "windows-sys 0.48.0", -] - -[[package]] -name = "async-signal" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2a5415b7abcdc9cd7d63d6badba5288b2ca017e3fbd4173b8f405449f1a2399" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if 1.0.0", - "futures-core", - "futures-io", - "rustix 0.38.18", - "signal-hook-registry", - "slab", + "rustix 0.37.23", + "signal-hook", "windows-sys 0.48.0", ] @@ -352,14 +335,14 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] name = "async-task" -version = "4.4.1" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9441c6b2fe128a7c2bf680a44c34d0df31ce09e5b7e401fcca3faa483dbc921" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" [[package]] name = "async-trait" @@ -369,14 +352,14 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] name = "atomic-waker" -version = "1.1.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" [[package]] name = "atty" @@ -503,9 +486,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "base64ct" @@ -626,18 +609,17 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "blocking" -version = "1.4.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" dependencies = [ "async-channel", "async-lock", "async-task", - "fastrand 2.0.1", - "futures-io", + "atomic-waker", + "fastrand 1.9.0", "futures-lite", - "piper", - "tracing", + "log", ] [[package]] @@ -797,9 +779,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "byte-slice-cast" @@ -815,15 +797,15 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byteorder" -version = "1.5.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.5.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "bytesize" @@ -894,16 +876,16 @@ dependencies = [ "rustc_version", "schemars", "serde_json", - "sha2 0.10.8", + "sha2 0.10.7", "symbolic-debuginfo", "zstd", ] [[package]] name = "cargo-platform" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" dependencies = [ "serde", ] @@ -945,15 +927,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", + "time 0.1.45", "wasm-bindgen", "windows-targets 0.48.5", ] @@ -996,9 +979,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" dependencies = [ "clap_builder", "clap_derive 4.4.2", @@ -1006,9 +989,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" dependencies = [ "anstream", "anstyle", @@ -1038,7 +1021,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -1084,9 +1067,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" dependencies = [ "crossbeam-utils", ] @@ -1122,7 +1105,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding 2.3.0", - "time", + "time 0.3.28", "version_check", ] @@ -1139,7 +1122,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time", + "time 0.3.28", "url 2.4.1", ] @@ -1362,7 +1345,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -1384,7 +1367,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -1439,7 +1422,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -1520,9 +1503,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" [[package]] name = "easy-ext" @@ -1610,22 +1593,22 @@ dependencies = [ [[package]] name = "enum-map" -version = "2.6.3" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c188012f8542dee7b3996e44dd89461d64aa471b0a7c71a1ae2f595d259e96e5" +checksum = "9705d8de4776df900a4a0b2384f8b0ab42f775e93b083b42f8ce71bdc32a47e3" dependencies = [ "enum-map-derive", ] [[package]] name = "enum-map-derive" -version = "0.14.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d0b288e3bb1d861c4403c1774a6f7a798781dfc519b3647df2a3dd4ae95f25" +checksum = "ccb14d927583dd5c2eac0f2cf264fc4762aefe1ae14c47a8a20fc1939d3a5fc0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -1662,30 +1645,30 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ + "errno-dragonfly", "libc", "windows-sys 0.48.0", ] [[package]] -name = "event-listener" -version = "2.5.3" +name = "errno-dragonfly" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] [[package]] name = "event-listener" -version = "3.0.0" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fake-simd" @@ -1710,9 +1693,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "ff" @@ -1931,7 +1914,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -2197,7 +2180,7 @@ dependencies = [ "indexmap 1.9.3", "slab", "tokio", - "tokio-util 0.7.9", + "tokio-util 0.7.8", "tracing", ] @@ -2230,9 +2213,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "heck" @@ -2260,9 +2243,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -2556,12 +2539,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.0", "serde", ] @@ -2589,7 +2572,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.2", "libc", "windows-sys 0.48.0", ] @@ -2606,8 +2589,8 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.3", - "rustix 0.38.18", + "hermit-abi 0.3.2", + "rustix 0.38.11", "windows-sys 0.48.0", ] @@ -2646,9 +2629,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] @@ -2670,9 +2653,9 @@ dependencies = [ [[package]] name = "json-patch" -version = "1.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6" +checksum = "1f54898088ccb91df1b492cc80029a6fdf1c48ca0db7c6822a8babad69c94658" dependencies = [ "serde", "serde_json", @@ -2692,9 +2675,9 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.4", + "base64 0.21.3", "pem", - "ring 0.16.20", + "ring", "serde", "serde_json", "simple_asn1", @@ -2726,9 +2709,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libloading" @@ -2742,9 +2725,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "linux-raw-sys" @@ -2760,9 +2743,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "load-tests" @@ -2807,15 +2790,15 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matchit" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" [[package]] name = "memchr" -version = "2.6.4" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memmap2" @@ -2884,10 +2867,10 @@ dependencies = [ "atty", "axum", "axum-extra", - "base64 0.21.4", + "base64 0.21.3", "borsh 0.10.3", "chrono", - "clap 4.4.6", + "clap 4.4.2", "curv-kzen", "ed25519-dalek", "futures", @@ -2900,6 +2883,7 @@ dependencies = [ "lazy_static", "multi-party-eddsa", "near-crypto 0.17.0", + "near-fetch", "near-jsonrpc-client", "near-jsonrpc-primitives", "near-primitives 0.17.0", @@ -2934,7 +2918,7 @@ dependencies = [ "anyhow", "async-process", "bollard", - "clap 4.4.6", + "clap 4.4.2", "curv-kzen", "ed25519-dalek", "env_logger 0.10.0", @@ -2957,8 +2941,8 @@ dependencies = [ "test-log", "testcontainers", "tokio", - "tokio-util 0.7.9", - "toml 0.8.2", + "tokio-util 0.7.8", + "toml 0.8.1", "tracing", "tracing-log", "tracing-subscriber", @@ -3060,7 +3044,7 @@ dependencies = [ "once_cell", "serde", "serde_json", - "sha2 0.10.8", + "sha2 0.10.7", "smart-default", "tracing", ] @@ -3130,6 +3114,24 @@ dependencies = [ "thiserror", ] +[[package]] +name = "near-fetch" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d227650df31a89e5bd256f7a9b5ae85f6f9b855f7114b2a4e935d15372d77cab" +dependencies = [ + "near-account-id 0.17.0", + "near-crypto 0.17.0", + "near-jsonrpc-client", + "near-jsonrpc-primitives", + "near-primitives 0.17.0", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-retry", +] + [[package]] name = "near-fmt" version = "0.17.0" @@ -3193,7 +3195,7 @@ checksum = "af7d35397b02b131c188c72f3885e97daeccab134ec2fc8cc0073a94cf1cfe19" dependencies = [ "actix", "atty", - "clap 4.4.6", + "clap 4.4.2", "near-crypto 0.17.0", "near-primitives-core 0.17.0", "once_cell", @@ -3273,7 +3275,7 @@ dependencies = [ "smart-default", "strum 0.24.1", "thiserror", - "time", + "time 0.3.28", "tracing", ] @@ -3290,7 +3292,7 @@ dependencies = [ "near-account-id 0.14.0", "num-rational", "serde", - "sha2 0.10.8", + "sha2 0.10.7", "strum 0.24.1", ] @@ -3301,7 +3303,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775fec19ef51a341abdbf792a9dda5b4cb89f488f681b2fd689b9321d24db47b" dependencies = [ "arbitrary", - "base64 0.21.4", + "base64 0.21.3", "borsh 0.10.3", "bs58 0.4.0", "derive_more", @@ -3311,7 +3313,7 @@ dependencies = [ "serde", "serde_repr", "serde_with 3.3.0", - "sha2 0.10.8", + "sha2 0.10.7", "strum 0.24.1", "thiserror", ] @@ -3335,7 +3337,7 @@ checksum = "84c1eda300e2e78f4f945ae58117d49e806899f4a51ee2faa09eda5ebc2e6571" dependencies = [ "quote", "serde", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -3358,7 +3360,7 @@ dependencies = [ "fs2", "near-rpc-error-core 0.17.0", "serde", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -3497,7 +3499,7 @@ dependencies = [ "near-vm-errors 0.14.0", "ripemd", "serde", - "sha2 0.10.8", + "sha2 0.10.7", "sha3 0.10.8", "zeropool-bn", ] @@ -3509,7 +3511,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1f43c3cac1cf61d0f20fbc49f2c3182caa6422c0d2acd92c926a3e3190b26a9" dependencies = [ "async-trait", - "base64 0.21.4", + "base64 0.21.3", "borsh 0.10.3", "bs58 0.5.0", "cargo-near", @@ -3529,7 +3531,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "sha2 0.10.8", + "sha2 0.10.7", "tempfile", "thiserror", "tokio", @@ -3684,9 +3686,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg 1.1.0", "libm", @@ -3698,7 +3700,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.2", "libc", ] @@ -3761,7 +3763,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -3772,9 +3774,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" dependencies = [ "cc", "libc", @@ -4006,9 +4008,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.1.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" [[package]] name = "parking_lot" @@ -4053,7 +4055,7 @@ dependencies = [ "digest 0.10.7", "hmac 0.12.1", "password-hash", - "sha2 0.10.8", + "sha2 0.10.7", ] [[package]] @@ -4104,7 +4106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.2", + "indexmap 2.0.0", ] [[package]] @@ -4133,7 +4135,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -4148,17 +4150,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" -dependencies = [ - "atomic-waker", - "fastrand 2.0.1", - "futures-io", -] - [[package]] name = "pkcs1" version = "0.4.1" @@ -4270,7 +4261,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit 0.19.15", + "toml_edit 0.19.14", ] [[package]] @@ -4299,9 +4290,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -4703,14 +4694,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.1", - "regex-syntax 0.8.0", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", ] [[package]] @@ -4724,13 +4715,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.1" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.0", + "regex-syntax 0.7.5", ] [[package]] @@ -4741,18 +4732,18 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.0" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ "async-compression", - "base64 0.21.4", + "base64 0.21.3", "bytes", "cookie", "cookie_store", @@ -4763,6 +4754,7 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-rustls 0.24.1", "hyper-tls", "ipnet", "js-sys", @@ -4772,18 +4764,21 @@ dependencies = [ "once_cell", "percent-encoding 2.3.0", "pin-project-lite", + "rustls 0.21.7", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", - "system-configuration", "tokio", "tokio-native-tls", - "tokio-util 0.7.9", + "tokio-rustls 0.24.1", + "tokio-util 0.7.8", "tower-service", "url 2.4.1", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg", ] @@ -4797,25 +4792,11 @@ dependencies = [ "libc", "once_cell", "spin 0.5.2", - "untrusted 0.7.1", + "untrusted", "web-sys", "winapi", ] -[[package]] -name = "ring" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" -dependencies = [ - "cc", - "getrandom 0.2.10", - "libc", - "spin 0.9.8", - "untrusted 0.9.0", - "windows-sys 0.48.0", -] - [[package]] name = "ripemd" version = "0.1.3" @@ -4893,9 +4874,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.25" +version = "0.37.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ "bitflags 1.3.2", "errno", @@ -4907,14 +4888,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.18" +version = "0.38.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" +checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.10", + "linux-raw-sys 0.4.5", "windows-sys 0.48.0", ] @@ -4925,7 +4906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", - "ring 0.16.20", + "ring", "sct", "webpki", ] @@ -4937,7 +4918,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", - "ring 0.16.20", + "ring", "rustls-webpki", "sct", ] @@ -4960,17 +4941,17 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.4", + "base64 0.21.3", ] [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring", + "untrusted", ] [[package]] @@ -4996,9 +4977,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "763f8cd0d4c71ed8389c90cb8100cba87e763bd01a8e614d4f0af97bcd50a161" dependencies = [ "dyn-clone", "schemars_derive", @@ -5008,9 +4989,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "ec0f696e21e10fa546b7ffb1c9672c6de8fbc7a81acf59524386d8639bf12737" dependencies = [ "proc-macro2", "quote", @@ -5047,7 +5028,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -5056,8 +5037,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring", + "untrusted", ] [[package]] @@ -5130,9 +5111,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" dependencies = [ "serde", ] @@ -5163,7 +5144,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -5179,9 +5160,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -5206,7 +5187,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -5253,7 +5234,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros 2.3.3", - "time", + "time 0.3.28", ] [[package]] @@ -5262,15 +5243,15 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" dependencies = [ - "base64 0.21.4", + "base64 0.21.3", "chrono", "hex 0.4.3", "indexmap 1.9.3", - "indexmap 2.0.2", + "indexmap 2.0.0", "serde", "serde_json", "serde_with_macros 3.3.0", - "time", + "time 0.3.28", ] [[package]] @@ -5294,7 +5275,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -5306,7 +5287,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -5315,7 +5296,7 @@ version = "0.9.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.0.0", "itoa", "ryu", "serde", @@ -5360,9 +5341,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -5393,13 +5374,23 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.7" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ "lazy_static", ] +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -5438,7 +5429,7 @@ dependencies = [ "num-bigint 0.4.4", "num-traits", "thiserror", - "time", + "time 0.3.28", ] [[package]] @@ -5449,7 +5440,7 @@ checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369" dependencies = [ "log", "termcolor", - "time", + "time 0.3.28", ] [[package]] @@ -5469,9 +5460,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "smart-default" @@ -5598,7 +5589,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -5662,9 +5653,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" dependencies = [ "proc-macro2", "quote", @@ -5677,27 +5668,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tap" version = "1.0.1" @@ -5722,9 +5692,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if 1.0.0", - "fastrand 2.0.1", + "fastrand 2.0.0", "redox_syscall 0.3.5", - "rustix 0.38.18", + "rustix 0.38.11", "windows-sys 0.48.0", ] @@ -5774,7 +5744,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "sha2 0.10.8", + "sha2 0.10.7", "tokio", ] @@ -5786,22 +5756,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -5816,9 +5786,20 @@ dependencies = [ [[package]] name = "time" -version = "0.3.29" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", @@ -5831,15 +5812,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] @@ -5896,7 +5877,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -5980,9 +5961,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -6007,14 +5988,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "1bc1433177506450fe920e46a4f9812d0c211f5dd556da10e731a0a3dfa151f0" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.20.1", ] [[package]] @@ -6028,22 +6009,22 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.0.0", "toml_datetime", "winnow", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "ca676d9ba1a322c1b64eb8045a5ec5c0cfb0c9d08e15e9ff622589ad5221c8fe" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", @@ -6089,7 +6070,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.4", + "base64 0.21.3", "bytes", "futures-core", "futures-util", @@ -6135,7 +6116,7 @@ dependencies = [ "rand 0.8.5", "slab", "tokio", - "tokio-util 0.7.9", + "tokio-util 0.7.8", "tower-layer", "tower-service", "tracing", @@ -6191,7 +6172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" dependencies = [ "crossbeam-channel", - "time", + "time 0.3.28", "tracing-subscriber", ] @@ -6203,7 +6184,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -6321,9 +6302,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "uint" @@ -6345,9 +6326,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -6386,19 +6367,13 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "ureq" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ - "base64 0.21.4", + "base64 0.21.3", "flate2", "log", "once_cell", @@ -6475,9 +6450,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "want" @@ -6494,6 +6469,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -6521,7 +6502,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", "wasm-bindgen-shared", ] @@ -6555,7 +6536,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6584,12 +6565,12 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.4" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" dependencies = [ - "ring 0.17.3", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -6619,7 +6600,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.18", + "rustix 0.38.11", ] [[package]] @@ -6640,9 +6621,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] @@ -6796,9 +6777,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.16" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] @@ -6839,9 +6820,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.19" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +checksum = "1eee6bf5926be7cf998d7381a9a23d833fd493f6a8034658a9505a4dc4b20444" [[package]] name = "yup-oauth2" @@ -6864,7 +6845,7 @@ dependencies = [ "seahash", "serde", "serde_json", - "time", + "time 0.3.28", "tokio", "tower-service", "url 2.4.1", @@ -6887,7 +6868,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.31", ] [[package]] @@ -6932,7 +6913,7 @@ dependencies = [ "hmac 0.12.1", "pbkdf2", "sha1", - "time", + "time 0.3.28", "zstd", ] diff --git a/infra/modules/leader/main.tf b/infra/modules/leader/main.tf index 2ad2bffc1..0254bfc5b 100644 --- a/infra/modules/leader/main.tf +++ b/infra/modules/leader/main.tf @@ -48,7 +48,7 @@ resource "google_cloud_run_v2_service" "leader" { value_source { secret_key_ref { secret = var.account_creator_sk_secret_id - version = "latest" + version = "1" } } } diff --git a/infra/terraform-dev.tfvars b/infra/terraform-dev.tfvars index aea09d410..f0899093b 100644 --- a/infra/terraform-dev.tfvars +++ b/infra/terraform-dev.tfvars @@ -3,7 +3,7 @@ project = "pagoda-discovery-platform-dev" docker_image = "us-east1-docker.pkg.dev/pagoda-discovery-platform-dev/mpc-recovery/mpc-recovery" account_creator_id = "mpc-recovery-dev-creator.testnet" -account_creator_sk_secret_id = "mpc-account-creator-sk-dev" +account_creator_sk_secret_id = "mpc-recovery-account-creator-sk-dev" oidc_providers_secret_id = "mpc-allowed-oidc-providers-dev" fast_auth_partners_secret_id = "mpc-fast-auth-partners-dev" signer_configs = [ diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 5e81bc4c6..041fcdd14 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -23,6 +23,7 @@ near-jsonrpc-client = "0.6" near-primitives = "0.17" near-units = "0.2.0" once_cell = "1" +rand = "0.7" serde = "1" serde_json = "1" testcontainers = { version = "0.14", features = ["experimental"] } diff --git a/integration-tests/src/env/containers.rs b/integration-tests/src/env/containers.rs index e7d870340..19beed1fe 100644 --- a/integration-tests/src/env/containers.rs +++ b/integration-tests/src/env/containers.rs @@ -8,6 +8,7 @@ use ed25519_dalek::{PublicKey as PublicKeyEd25519, Verifier}; use futures::{lock::Mutex, StreamExt}; use hyper::StatusCode; use mpc_recovery::firewall::allowed::DelegateActionRelayer; +use mpc_recovery::logging; use mpc_recovery::sign_node::oidc::OidcToken; use mpc_recovery::{ msg::{ @@ -43,8 +44,9 @@ use tracing; use std::fs; use crate::env::{Context, LeaderNodeApi, SignerNodeApi}; -use crate::util::{self, create_key_file, create_relayer_cofig_file}; -use mpc_recovery::logging; +use crate::util::{ + self, create_key_file, create_key_file_with_filepath, create_relayer_cofig_file, +}; static NETWORK_MUTEX: Lazy> = Lazy::new(|| Mutex::new(0)); @@ -297,7 +299,7 @@ impl<'a> Relayer<'a> { near_rpc: &str, redis_full_address: &str, relayer_account_id: &AccountId, - relayer_account_sk: &near_workspaces::types::SecretKey, + relayer_account_sks: &[near_workspaces::types::SecretKey], creator_account_id: &AccountId, social_db_id: &AccountId, social_account_id: &AccountId, @@ -312,14 +314,20 @@ impl<'a> Relayer<'a> { .unwrap_or_else(|_| panic!("Failed to create {relayer_configs_path} directory")); // Create dir for keys - let keys_path = format!("{relayer_configs_path}/account_keys"); - std::fs::create_dir_all(&keys_path).expect("Failed to create account_keys directory"); + let key_dir = format!("{relayer_configs_path}/account_keys"); + std::fs::create_dir_all(&key_dir).expect("Failed to create account_keys directory"); let keys_absolute_path = - fs::canonicalize(&keys_path).expect("Failed to get absolute path for keys"); + fs::canonicalize(&key_dir).expect("Failed to get absolute path for keys"); // Create JSON key files - create_key_file(relayer_account_id, relayer_account_sk, &keys_path)?; - create_key_file(social_account_id, social_account_sk, &keys_path)?; + create_key_file(social_account_id, social_account_sk, &key_dir)?; + let mut relayer_keyfiles = Vec::with_capacity(relayer_account_sks.len()); + for (i, relayer_sk) in relayer_account_sks.iter().enumerate() { + let filename = format!("{i}-{relayer_account_id}"); + let keypath = format!("{key_dir}/{filename}.json"); + create_key_file_with_filepath(relayer_account_id, relayer_sk, &keypath)?; + relayer_keyfiles.push(format!("./account_keys/{filename}.json")); + } // Create relayer config file let config_file_name = "config.toml"; @@ -328,7 +336,7 @@ impl<'a> Relayer<'a> { ip_address: [0, 0, 0, 0], port: Self::CONTAINER_PORT, relayer_account_id: relayer_account_id.clone(), - keys_filenames: vec![format!("./account_keys/{}.json", relayer_account_id)], + keys_filenames: relayer_keyfiles, shared_storage_account_id: social_account_id.clone(), shared_storage_keys_filename: format!("./account_keys/{}.json", social_account_id), whitelisted_contracts: vec![creator_account_id.clone()], @@ -643,7 +651,12 @@ impl<'a> LeaderNode<'a> { near_rpc: ctx.relayer_ctx.sandbox.address.clone(), near_root_account: ctx.relayer_ctx.worker.root_account()?.id().to_string(), account_creator_id: account_creator.id().clone(), - account_creator_sk: Some(account_creator.secret_key().to_string()), + account_creator_sk: ctx + .relayer_ctx + .creator_account_keys + .iter() + .map(|k| k.to_string().parse()) + .collect::, _>>()?, fast_auth_partners: Some( serde_json::json!([ { @@ -765,7 +778,7 @@ impl LeaderNodeApi { let frp_signature = match user_secret_key.sign(&user_credentials_request_digest) { near_crypto::Signature::ED25519(k) => k, - _ => return Err(anyhow::anyhow!("Wrong signature type")), + _ => anyhow::bail!("Wrong signature type"), }; let new_account_request = NewAccountRequest { @@ -773,7 +786,7 @@ impl LeaderNodeApi { create_account_options, oidc_token: oidc_token.clone(), user_credentials_frp_signature: frp_signature, - frp_public_key: user_pk.clone(), + frp_public_key: user_pk, }; self.new_account(new_account_request).await @@ -789,10 +802,7 @@ impl LeaderNodeApi { frp_pk: &PublicKey, ) -> anyhow::Result<(StatusCode, SignResponse)> { // Prepare SignRequest with add key delegate action - let (_, block_height, nonce) = self - .client - .access_key(account_id.clone(), recovery_pk.clone()) - .await?; + let (_, block_height, nonce) = self.client.access_key(account_id, recovery_pk).await?; let add_key_delegate_action = DelegateAction { sender_id: account_id.clone(), @@ -846,10 +856,7 @@ impl LeaderNodeApi { frp_pk: &PublicKey, ) -> anyhow::Result<(StatusCode, SignResponse)> { // Prepare SignRequest with add key delegate action - let (_, block_height, nonce) = self - .client - .access_key(account_id.clone(), recovery_pk.clone()) - .await?; + let (_, block_height, nonce) = self.client.access_key(account_id, recovery_pk).await?; let delete_key_delegate_action = DelegateAction { sender_id: account_id.clone(), diff --git a/integration-tests/src/env/local.rs b/integration-tests/src/env/local.rs index 66a74b6d7..57c5ac7c1 100644 --- a/integration-tests/src/env/local.rs +++ b/integration-tests/src/env/local.rs @@ -2,12 +2,12 @@ use aes_gcm::aead::consts::U32; use aes_gcm::aead::generic_array::GenericArray; use async_process::Child; use mpc_recovery::firewall::allowed::DelegateActionRelayer; +use mpc_recovery::logging; use mpc_recovery::relayer::NearRpcAndRelayerClient; use multi_party_eddsa::protocols::ExpandedKeyPair; use crate::env::{LeaderNodeApi, SignerNodeApi}; use crate::util; -use mpc_recovery::logging; pub struct SignerNode { pub address: String, @@ -108,7 +108,12 @@ impl LeaderNode { near_rpc: ctx.relayer_ctx.sandbox.local_address.clone(), near_root_account: ctx.relayer_ctx.worker.root_account()?.id().to_string(), account_creator_id: account_creator.id().clone(), - account_creator_sk: Some(account_creator.secret_key().to_string()), + account_creator_sk: ctx + .relayer_ctx + .creator_account_keys + .iter() + .map(|k| k.to_string().parse()) + .collect::, _>>()?, fast_auth_partners_filepath: None, fast_auth_partners: Some( serde_json::json!([ diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 0375684a0..d5e58cc1b 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -4,6 +4,7 @@ use near_crypto::KeyFile; use near_units::parse_near; use near_workspaces::{ network::{Sandbox, ValidatorKey}, + types::SecretKey, Account, Worker, }; @@ -59,6 +60,7 @@ pub struct RelayerCtx<'a> { pub relayer: containers::Relayer<'a>, pub worker: Worker, pub creator_account: Account, + pub creator_account_keys: Vec, } pub async fn initialize_relayer<'a>( @@ -90,7 +92,11 @@ pub async fn initialize_relayer<'a>( tracing::info!("Initializing relayer accounts..."); let relayer_account = sandbox::create_account(&worker, "relayer", parse_near!("1000 N")).await?; + let relayer_account_keys = sandbox::gen_rotating_keys(&relayer_account, 5).await?; + let creator_account = sandbox::create_account(&worker, "creator", parse_near!("200 N")).await?; + let creator_account_keys = sandbox::gen_rotating_keys(&creator_account, 5).await?; + let social_account = sandbox::create_account(&worker, "social", parse_near!("1000 N")).await?; tracing::info!( "Relayer accounts initialized. Relayer account: {}, Creator account: {}, Social account: {}", @@ -100,14 +106,13 @@ pub async fn initialize_relayer<'a>( ); let redis = containers::Redis::run(docker_client, network).await?; - let relayer = containers::Relayer::run( docker_client, network, &sandbox.address, &redis.full_address, relayer_account.id(), - relayer_account.secret_key(), + &relayer_account_keys, creator_account.id(), social_db.id(), social_account.id(), @@ -122,5 +127,6 @@ pub async fn initialize_relayer<'a>( relayer, worker, creator_account, + creator_account_keys, }) } diff --git a/integration-tests/src/sandbox.rs b/integration-tests/src/sandbox.rs index 7d519becf..b056a9dbf 100644 --- a/integration-tests/src/sandbox.rs +++ b/integration-tests/src/sandbox.rs @@ -1,4 +1,6 @@ -use near_workspaces::{network::Sandbox, Account, Contract, Worker}; +use near_workspaces::{network::Sandbox, types::SecretKey, AccessKey, Account, Contract, Worker}; + +const BATCH_COUNT_LIMIT: usize = 100; pub async fn initialize_social_db(worker: &Worker) -> anyhow::Result { tracing::info!("Initializing social DB contract..."); @@ -53,3 +55,37 @@ pub async fn create_account( tracing::info!("Account created: {}", new_account.id()); Ok(new_account) } + +pub async fn gen_rotating_keys(account: &Account, amount: usize) -> anyhow::Result> { + let mut keys = Vec::with_capacity(amount + 1); + keys.push(account.secret_key().clone()); + + // Each batch transaction has a limit of BATCH_COUNT_LIMIT actions. + let num_batches = amount / BATCH_COUNT_LIMIT + 1; + let rem_batches = amount % BATCH_COUNT_LIMIT; + let batch_counts = (0..num_batches).map(|i| { + if i == num_batches - 1 { + rem_batches + } else { + BATCH_COUNT_LIMIT + } + }); + + for batch_count in batch_counts { + let mut batch_tx = account.batch(account.id()); + for _ in 0..batch_count { + let sk = SecretKey::from_seed( + near_workspaces::types::KeyType::ED25519, + &rand::Rng::sample_iter(rand::thread_rng(), &rand::distributions::Alphanumeric) + .take(10) + .map(char::from) + .collect::(), + ); + batch_tx = batch_tx.add_key(sk.public_key(), AccessKey::full_access()); + keys.push(sk); + } + batch_tx.transact().await?.into_result()?; + } + + Ok(keys) +} diff --git a/integration-tests/src/util.rs b/integration-tests/src/util.rs index c96bafde1..950a4e7db 100644 --- a/integration-tests/src/util.rs +++ b/integration-tests/src/util.rs @@ -79,7 +79,19 @@ struct KeyFile { pub fn create_key_file( account_id: &AccountId, account_sk: &SecretKey, - key_path: &str, + key_dir: &str, +) -> anyhow::Result<(), anyhow::Error> { + create_key_file_with_filepath( + account_id, + account_sk, + &format!("{key_dir}/{account_id}.json"), + ) +} + +pub fn create_key_file_with_filepath( + account_id: &AccountId, + account_sk: &SecretKey, + filepath: &str, ) -> anyhow::Result<(), anyhow::Error> { let key_file = KeyFile { account_id: account_id.to_string(), @@ -87,9 +99,7 @@ pub fn create_key_file( private_key: account_sk.to_string(), }; let key_json_str = serde_json::to_string(&key_file).expect("Failed to serialize to JSON"); - let key_json_file_path = format!("{key_path}/{account_id}.json"); - let mut json_key_file = - File::create(key_json_file_path).expect("Failed to create JSON key file"); + let mut json_key_file = File::create(filepath).expect("Failed to create JSON key file"); json_key_file .write_all(key_json_str.as_bytes()) .expect("Failed to write to JSON key file"); diff --git a/integration-tests/tests/mpc/positive.rs b/integration-tests/tests/mpc/positive.rs index a77d83cc2..c5a2dcf59 100644 --- a/integration-tests/tests/mpc/positive.rs +++ b/integration-tests/tests/mpc/positive.rs @@ -1,8 +1,9 @@ use std::collections::HashMap; use crate::mpc::{add_pk_and_check_validity, fetch_recovery_pk, new_random_account}; -use crate::{account, key, with_nodes, MpcCheck}; +use crate::{account, key, with_nodes, MpcCheck, TestContext}; +use futures::stream::FuturesUnordered; use hyper::StatusCode; use near_workspaces::types::AccessKeyPermission; @@ -54,35 +55,7 @@ async fn test_basic_front_running_protection() -> anyhow::Result<()> { #[test(tokio::test)] async fn test_basic_action() -> anyhow::Result<()> { - with_nodes(3, |ctx| async move { - let (account_id, user_secret_key, oidc_token) = new_random_account(&ctx, None).await?; - - // Add key - let recovery_pk = fetch_recovery_pk(&ctx, &user_secret_key, &oidc_token).await?; - let new_user_public_key = add_pk_and_check_validity( - &ctx, - &account_id, - &user_secret_key, - &oidc_token, - &recovery_pk, - None, - ) - .await?; - - // Adding the same key should now fail - add_pk_and_check_validity( - &ctx, - &account_id, - &user_secret_key, - &oidc_token, - &recovery_pk, - Some(new_user_public_key), - ) - .await?; - - Ok(()) - }) - .await + with_nodes(3, |ctx| async move { basic_action(&ctx).await }).await } #[test(tokio::test)] @@ -281,3 +254,57 @@ async fn test_rotate_node_keys() -> anyhow::Result<()> { }) .await } + +#[test(tokio::test(flavor = "multi_thread", worker_threads = 8))] +async fn test_stress_network() -> anyhow::Result<()> { + with_nodes(3, |ctx| { + Box::pin(async move { + let ctx = std::sync::Arc::new(ctx); + let tasks = (0..30) + .map(|_| { + let ctx = ctx.clone(); + tokio::spawn(async move { basic_action(&ctx).await }) + }) + .collect::>(); + + let result = futures::future::join_all(tasks) + .await + .into_iter() + .collect::, _>>()? + .into_iter() + .collect::, _>>()?; + tracing::debug!("{:#?}", result); + Ok(()) + }) + }) + .await +} + +async fn basic_action(ctx: &TestContext) -> anyhow::Result<()> { + let (account_id, user_secret_key, oidc_token) = new_random_account(ctx, None).await?; + + // Add key + let recovery_pk = fetch_recovery_pk(ctx, &user_secret_key, &oidc_token).await?; + let new_user_public_key = add_pk_and_check_validity( + ctx, + &account_id, + &user_secret_key, + &oidc_token, + &recovery_pk, + None, + ) + .await?; + + // Adding the same key should now fail + add_pk_and_check_validity( + ctx, + &account_id, + &user_secret_key, + &oidc_token, + &recovery_pk, + Some(new_user_public_key), + ) + .await?; + + Ok(()) +} diff --git a/mpc-recovery/Cargo.toml b/mpc-recovery/Cargo.toml index a2a215f25..04496f83f 100644 --- a/mpc-recovery/Cargo.toml +++ b/mpc-recovery/Cargo.toml @@ -44,6 +44,7 @@ tracing = "0.1" tracing-appender = "0.2.2" tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-opentelemetry = "0.21.0" +near-fetch = "0.0.12" near-jsonrpc-client = "0.6" near-jsonrpc-primitives = "0.17" near-primitives = "0.17" diff --git a/mpc-recovery/src/leader_node/mod.rs b/mpc-recovery/src/leader_node/mod.rs index 6943cb868..87e0cb924 100644 --- a/mpc-recovery/src/leader_node/mod.rs +++ b/mpc-recovery/src/leader_node/mod.rs @@ -10,8 +10,8 @@ use crate::oauth::verify_oidc_token; use crate::relayer::msg::{CreateAccountAtomicRequest, RegisterAccountRequest}; use crate::relayer::NearRpcAndRelayerClient; use crate::transaction::{ - get_create_account_delegate_action, get_local_signed_delegated_action, get_mpc_signature, - sign_payload_with_mpc, to_dalek_combined_public_key, + get_mpc_signature, new_create_account_delegate_action, sign_payload_with_mpc, + to_dalek_combined_public_key, }; use crate::utils::{check_digest_signature, user_credentials_request_digest}; use crate::{metrics, nar}; @@ -28,12 +28,14 @@ use axum::{ use axum_extra::extract::WithRejection; use borsh::BorshDeserialize; use curv::elliptic::curves::{Ed25519, Point}; -use near_crypto::SecretKey; +use prometheus::{Encoder, TextEncoder}; +use rand::{distributions::Alphanumeric, Rng}; + +use near_fetch::signer::KeyRotatingSigner; use near_primitives::delegate_action::{DelegateAction, NonDelegateAction}; use near_primitives::transaction::{Action, DeleteKeyAction}; use near_primitives::types::AccountId; -use prometheus::{Encoder, TextEncoder}; -use rand::{distributions::Alphanumeric, Rng}; + use std::net::SocketAddr; use std::sync::Arc; use std::time::Instant; @@ -46,7 +48,7 @@ pub struct Config { pub near_root_account: String, pub account_creator_id: AccountId, // TODO: temporary solution - pub account_creator_sk: SecretKey, + pub account_creator_signer: KeyRotatingSigner, pub partners: PartnerList, pub jwt_signature_pk_url: String, } @@ -59,7 +61,7 @@ pub async fn run(config: Config) { near_rpc, near_root_account, account_creator_id, - account_creator_sk, + account_creator_signer, partners, jwt_signature_pk_url, } = config; @@ -96,8 +98,7 @@ pub async fn run(config: Config) { client, reqwest_client: reqwest::Client::new(), near_root_account: near_root_account.parse().unwrap(), - account_creator_id, - account_creator_sk, + account_creator_signer, partners, jwt_signature_pk_url, }); @@ -216,9 +217,8 @@ struct LeaderState { client: NearRpcAndRelayerClient, reqwest_client: reqwest::Client, near_root_account: AccountId, - account_creator_id: AccountId, // TODO: temporary solution - account_creator_sk: SecretKey, + account_creator_signer: KeyRotatingSigner, partners: PartnerList, jwt_signature_pk_url: String, } @@ -390,13 +390,12 @@ async fn process_new_account( .await?; nar::retry(|| async { + let account_creator = state.account_creator_signer.fetch_and_rotate_signer(); + // Get nonce and recent block hash let (_hash, block_height, nonce) = state .client - .access_key( - state.account_creator_id.clone(), - state.account_creator_sk.public_key(), - ) + .access_key(&account_creator.account_id, &account_creator.public_key) .await .map_err(LeaderNodeError::RelayerError)?; @@ -407,22 +406,16 @@ async fn process_new_account( None => new_account_options.full_access_keys = Some(vec![mpc_user_recovery_pk.clone()]), } - let delegate_action = get_create_account_delegate_action( - &state.account_creator_id, - &state.account_creator_sk.public_key(), + // We create accounts using the local key + let signed_delegate_action = new_create_account_delegate_action( + account_creator, &new_user_account_id, - new_account_options.clone(), + &new_account_options, &state.near_root_account, nonce, block_height + 100, ) .map_err(LeaderNodeError::Other)?; - // We create accounts using the local key - let signed_delegate_action = get_local_signed_delegated_action( - delegate_action, - state.account_creator_id.clone(), - state.account_creator_sk.clone(), - ); // Send delegate action to relayer let request = CreateAccountAtomicRequest { @@ -456,8 +449,8 @@ async fn process_new_account( .client .invalidate_cache_if_acc_creation_failed( &( - state.account_creator_id.clone(), - state.account_creator_sk.public_key(), + account_creator.account_id.clone(), + account_creator.public_key.clone(), ), &err_str, ) diff --git a/mpc-recovery/src/lib.rs b/mpc-recovery/src/lib.rs index fdc5a255c..7ed1815aa 100644 --- a/mpc-recovery/src/lib.rs +++ b/mpc-recovery/src/lib.rs @@ -14,6 +14,8 @@ use multi_party_eddsa::protocols::ExpandedKeyPair; use serde::de::DeserializeOwned; use tracing_subscriber::EnvFilter; +use near_crypto::{InMemorySigner, SecretKey}; +use near_fetch::signer::KeyRotatingSigner; use near_primitives::types::AccountId; use crate::firewall::allowed::{OidcProviderList, PartnerList}; @@ -91,9 +93,14 @@ pub enum Cli { /// Account creator ID #[arg(long, env("MPC_RECOVERY_ACCOUNT_CREATOR_ID"))] account_creator_id: AccountId, - /// TEMPORARY - Account creator ed25519 secret key - #[arg(long, env("MPC_RECOVERY_ACCOUNT_CREATOR_SK"))] - account_creator_sk: Option, + /// Account creator's secret key(s) + #[arg( + long, + value_parser = parse_json_str::>, + env("MPC_RECOVERY_ACCOUNT_CREATOR_SK"), + default_value("[]") + )] + account_creator_sk: ::std::vec::Vec, /// JSON list of related items to be used to verify OIDC tokens. #[arg(long, env("FAST_AUTH_PARTNERS"))] fast_auth_partners: Option, @@ -215,15 +222,14 @@ pub async fn run(cmd: Cli) -> anyhow::Result<()> { .global(); let gcp_service = GcpService::new(env.clone(), gcp_project_id, gcp_datastore_url).await?; - let account_creator_sk = - load_account_creator_sk(&gcp_service, &env, account_creator_sk).await?; + let account_creator_signer = + load_account_creator(&gcp_service, &env, &account_creator_id, account_creator_sk) + .await?; let partners = PartnerList { entries: load_entries(&gcp_service, &env, "leader", partners, partners_filepath) .await?, }; - let account_creator_sk = account_creator_sk.parse()?; - let config = LeaderConfig { env, port: web_port, @@ -232,7 +238,7 @@ pub async fn run(cmd: Cli) -> anyhow::Result<()> { near_root_account, // TODO: Create such an account for testnet and mainnet in a secure way account_creator_id, - account_creator_sk, + account_creator_signer, partners, jwt_signature_pk_url, }; @@ -380,18 +386,23 @@ async fn load_cipher_key( } } -async fn load_account_creator_sk( +async fn load_account_creator( gcp_service: &GcpService, env: &str, - account_creator_sk_arg: Option, -) -> anyhow::Result { - match account_creator_sk_arg { - Some(account_creator_sk) => Ok(account_creator_sk), - None => { - let name = format!("mpc-recovery-account-creator-sk-{env}/versions/latest"); - Ok(std::str::from_utf8(&gcp_service.load_secret(name).await?)?.to_string()) - } - } + account_creator_id: &AccountId, + account_creator_sk: Vec, +) -> anyhow::Result { + let sks = if account_creator_sk.is_empty() { + let name = format!("mpc-recovery-account-creator-sk-{env}/versions/latest"); + let data = gcp_service.load_secret(name).await?; + serde_json::from_str(std::str::from_utf8(&data)?)? + } else { + account_creator_sk + }; + + Ok(KeyRotatingSigner::from_signers(sks.into_iter().map(|sk| { + InMemorySigner::from_secret_key(account_creator_id.clone(), sk) + }))) } async fn load_entries( @@ -462,10 +473,6 @@ impl Cli { jwt_signature_pk_url, ]; - if let Some(key) = account_creator_sk { - buf.push("--account-creator-sk".to_string()); - buf.push(key); - } if let Some(partners) = fast_auth_partners { buf.push("--fast-auth-partners".to_string()); buf.push(partners); @@ -482,6 +489,9 @@ impl Cli { buf.push("--sign-nodes".to_string()); buf.push(sign_node); } + let account_creator_sk = serde_json::to_string(&account_creator_sk).unwrap(); + buf.push("--account-creator-sk".to_string()); + buf.push(account_creator_sk); buf.extend(logging_options.into_str_args()); buf @@ -578,3 +588,10 @@ impl Cli { } } } + +fn parse_json_str(val: &str) -> Result +where + for<'a> T: serde::Deserialize<'a>, +{ + serde_json::from_str(val).map_err(|e| e.to_string()) +} diff --git a/mpc-recovery/src/nar.rs b/mpc-recovery/src/nar.rs index 2bdf9b7c5..ceea20ba3 100644 --- a/mpc-recovery/src/nar.rs +++ b/mpc-recovery/src/nar.rs @@ -3,27 +3,11 @@ //! need to be moved eventually into their own separate crate. Not necessarily //! to be used from workspaces directly even though it is imported from there. -use std::collections::hash_map::Entry; -use std::collections::HashMap; -use std::sync::atomic::{AtomicU64, Ordering}; use std::time::Duration; -use near_crypto::PublicKey; -use near_jsonrpc_client::errors::{JsonRpcError, JsonRpcServerError}; -use near_jsonrpc_client::methods::query::RpcQueryError; -use near_jsonrpc_client::{methods, JsonRpcClient}; -use near_jsonrpc_primitives::types::query::QueryResponseKind; -use near_primitives::hash::CryptoHash; -use near_primitives::types::{AccountId, BlockHeight, Finality, Nonce}; -use near_primitives::views::{AccessKeyView, BlockView, QueryRequest}; -use tokio::sync::RwLock; use tokio_retry::strategy::{jitter, ExponentialBackoff}; use tokio_retry::Retry; -use crate::relayer::error::RelayerError; - -pub type CachedAccessKeyNonces = RwLock>; - pub(crate) async fn retry_every(interval: Duration, task: F) -> T::Output where F: FnMut() -> T, @@ -44,104 +28,3 @@ where let retry_strategy = ExponentialBackoff::from_millis(5).map(jitter).take(4); Retry::spawn(retry_strategy, task).await } - -pub(crate) async fn access_key( - rpc_client: &JsonRpcClient, - account_id: AccountId, - public_key: near_crypto::PublicKey, -) -> Result<(AccessKeyView, CryptoHash, BlockHeight), RelayerError> { - let query_resp = rpc_client - .call(&methods::query::RpcQueryRequest { - block_reference: Finality::None.into(), - request: QueryRequest::ViewAccessKey { - account_id, - public_key, - }, - }) - .await - .map_err(|e| match e { - JsonRpcError::ServerError(JsonRpcServerError::HandlerError( - RpcQueryError::UnknownAccount { - requested_account_id, - .. - }, - )) => RelayerError::UnknownAccount(requested_account_id), - JsonRpcError::ServerError(JsonRpcServerError::HandlerError( - RpcQueryError::UnknownAccessKey { public_key, .. }, - )) => RelayerError::UnknownAccessKey(public_key), - _ => anyhow::anyhow!(e).into(), - })?; - - match query_resp.kind { - QueryResponseKind::AccessKey(access_key) => { - Ok((access_key, query_resp.block_hash, query_resp.block_height)) - } - _ => Err(anyhow::anyhow!("query returned invalid data while querying access key").into()), - } -} - -async fn cached_nonce( - nonce: &AtomicU64, - rpc_client: &JsonRpcClient, -) -> Result<(CryptoHash, BlockHeight, Nonce), RelayerError> { - let nonce = nonce.fetch_add(1, Ordering::SeqCst); - - // Fetch latest block_hash since the previous one is now invalid for new transactions: - let block = latest_block(rpc_client).await?; - Ok((block.header.hash, block.header.height, nonce + 1)) -} - -/// Fetches the transaction nonce and block hash associated to the access key. Internally -/// caches the nonce as to not need to query for it every time, and ending up having to run -/// into contention with others. -pub async fn fetch_tx_nonce( - cached_nonces: &CachedAccessKeyNonces, - rpc_client: &JsonRpcClient, - cache_key: &(AccountId, near_crypto::PublicKey), -) -> Result<(CryptoHash, BlockHeight, Nonce), RelayerError> { - let nonces = cached_nonces.read().await; - if let Some(nonce) = nonces.get(cache_key) { - cached_nonce(nonce, rpc_client).await - } else { - drop(nonces); - let mut nonces = cached_nonces.write().await; - match nonces.entry(cache_key.clone()) { - // case where multiple writers end up at the same lock acquisition point and tries - // to overwrite the cached value that a previous writer already wrote. - Entry::Occupied(entry) => cached_nonce(entry.get(), rpc_client).await, - - // Write the cached value. This value will get invalidated when an InvalidNonce error is returned. - Entry::Vacant(entry) => { - let (account_id, public_key) = entry.key(); - let (access_key, block_hash, block_height) = - access_key(rpc_client, account_id.clone(), public_key.clone()).await?; - entry.insert(AtomicU64::new(access_key.nonce + 1)); - Ok((block_hash, block_height, access_key.nonce + 1)) - } - } - } -} - -pub(crate) async fn invalidate_nonce_if_tx_failed( - cached_nonces: &CachedAccessKeyNonces, - cache_key: &(AccountId, near_crypto::PublicKey), - err_str: &str, -) { - // InvalidNonce, cached nonce is potentially very far behind, so invalidate it. - if err_str.contains("InvalidNonce") - || err_str.contains("DelegateActionInvalidNonce") - || err_str.contains("must be larger than nonce of the used access key") - { - let mut nonces = cached_nonces.write().await; - nonces.remove(cache_key); - } -} - -pub async fn latest_block(rpc_client: &JsonRpcClient) -> Result { - rpc_client - .call(&methods::block::RpcBlockRequest { - block_reference: Finality::Final.into(), - }) - .await - .map_err(|err| anyhow::anyhow!(err).into()) -} diff --git a/mpc-recovery/src/oauth.rs b/mpc-recovery/src/oauth.rs index d1854c84f..e50ec2a9d 100644 --- a/mpc-recovery/src/oauth.rs +++ b/mpc-recovery/src/oauth.rs @@ -62,7 +62,6 @@ fn validate_jwt( } tracing::info!( - oidc_token = format!("{:.5}...", token), issuer = issuer, audience = audience, "validate_jwt call decoded" @@ -101,9 +100,7 @@ pub async fn get_pagoda_firebase_public_keys( ) -> anyhow::Result> { let response = client.get(jwt_signature_pk_url).send().await?; let json: HashMap = response.json().await?; - let keys: Vec = json.values().cloned().collect(); - tracing::info!("get_pagoda_firebase_public_keys keys: {:?}", keys); - Ok(keys) + Ok(json.into_values().collect()) } #[cfg(test)] diff --git a/mpc-recovery/src/relayer/mod.rs b/mpc-recovery/src/relayer/mod.rs index 2fe910877..430b10176 100644 --- a/mpc-recovery/src/relayer/mod.rs +++ b/mpc-recovery/src/relayer/mod.rs @@ -3,8 +3,10 @@ pub mod msg; use anyhow::Context; use hyper::{Body, Client, Method, Request}; + use near_crypto::PublicKey; -use near_jsonrpc_client::JsonRpcClient; +use near_jsonrpc_client::errors::{JsonRpcError, JsonRpcServerError}; +use near_jsonrpc_primitives::types::query::RpcQueryError; use near_primitives::hash::CryptoHash; use near_primitives::types::{AccountId, BlockHeight, Nonce}; use near_primitives::views::FinalExecutionStatus; @@ -15,32 +17,44 @@ use self::msg::{ }; use crate::firewall::allowed::DelegateActionRelayer; -use crate::nar::{self, CachedAccessKeyNonces}; pub struct NearRpcAndRelayerClient { - rpc_client: JsonRpcClient, - cached_nonces: CachedAccessKeyNonces, + rpc_client: near_fetch::Client, } impl NearRpcAndRelayerClient { pub fn connect(near_rpc: &str) -> Self { Self { - rpc_client: JsonRpcClient::connect(near_rpc), - cached_nonces: Default::default(), + rpc_client: near_fetch::Client::new(near_rpc), } } pub async fn access_key( &self, - account_id: AccountId, - public_key: PublicKey, + account_id: &AccountId, + public_key: &PublicKey, ) -> Result<(CryptoHash, BlockHeight, Nonce), RelayerError> { - nar::fetch_tx_nonce( - &self.cached_nonces, - &self.rpc_client, - &(account_id, public_key), - ) - .await + let (nonce, hash, height) = self + .rpc_client + .fetch_nonce(account_id, public_key) + .await + .map_err(|e| match e { + near_fetch::error::Error::RpcQueryError(JsonRpcError::ServerError( + JsonRpcServerError::HandlerError(RpcQueryError::UnknownAccount { + requested_account_id, + .. + }), + )) => RelayerError::UnknownAccount(requested_account_id), + near_fetch::error::Error::RpcQueryError(JsonRpcError::ServerError( + JsonRpcServerError::HandlerError(RpcQueryError::UnknownAccessKey { + public_key, + .. + }), + )) => RelayerError::UnknownAccessKey(public_key), + _ => anyhow::anyhow!(e).into(), + })?; + + Ok((hash, height, nonce)) } #[tracing::instrument(level = "debug", skip_all, fields(account_id = request.account_id.to_string()))] @@ -190,7 +204,13 @@ impl NearRpcAndRelayerClient { cache_key: &(AccountId, PublicKey), err_str: &str, ) { - nar::invalidate_nonce_if_tx_failed(&self.cached_nonces, cache_key, err_str).await; + // InvalidNonce, cached nonce is potentially very far behind, so invalidate it. + if err_str.contains("InvalidNonce") + || err_str.contains("DelegateActionInvalidNonce") + || err_str.contains("must be larger than nonce of the used access key") + { + self.rpc_client.invalidate_cache(cache_key).await; + } } } @@ -205,8 +225,8 @@ mod tests { let testnet = NearRpcAndRelayerClient::connect(TESTNET_URL); let (block_hash, block_height, nonce) = testnet .access_key( - "dev-1636354824855-78504059330123".parse()?, - "ed25519:8n5HXTibTDtXKAnEUPFUXXJoKqa5A1c2vWXt6LbRAcGn".parse()?, + &"dev-1636354824855-78504059330123".parse()?, + &"ed25519:8n5HXTibTDtXKAnEUPFUXXJoKqa5A1c2vWXt6LbRAcGn".parse()?, ) .await?; diff --git a/mpc-recovery/src/transaction.rs b/mpc-recovery/src/transaction.rs index 38203719c..d33d6e9d4 100644 --- a/mpc-recovery/src/transaction.rs +++ b/mpc-recovery/src/transaction.rs @@ -2,6 +2,7 @@ use crate::error::{AggregateSigningError, LeaderNodeError}; use crate::msg::{SignNodeRequest, SignShareNodeRequest}; use crate::sign_node::aggregate_signer::{Reveal, SignedCommitment}; use crate::sign_node::oidc::OidcToken; + use anyhow::Context; use curv::elliptic::curves::{Ed25519, Point}; use ed25519_dalek::Signature; @@ -9,14 +10,15 @@ use futures::{future, FutureExt}; use hyper::StatusCode; use multi_party_eddsa::protocols::aggsig::KeyAgg; use multi_party_eddsa::protocols::{self, aggsig}; -use near_crypto::{InMemorySigner, PublicKey, SecretKey}; +use serde::de::DeserializeOwned; +use serde::{Deserialize, Serialize}; +use serde_json::json; + +use near_crypto::{InMemorySigner, PublicKey}; use near_primitives::delegate_action::{DelegateAction, NonDelegateAction, SignedDelegateAction}; use near_primitives::signable_message::{SignableMessage, SignableMessageType}; use near_primitives::transaction::{Action, FunctionCallAction}; use near_primitives::types::{AccountId, Nonce}; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; -use serde_json::json; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct CreateAccountOptions { @@ -46,15 +48,14 @@ pub struct LimitedAccessKey { } #[allow(clippy::too_many_arguments)] -pub fn get_create_account_delegate_action( - signer_id: &AccountId, - signer_pk: &PublicKey, +pub fn new_create_account_delegate_action( + signer: &InMemorySigner, new_account_id: &AccountId, - new_account_options: CreateAccountOptions, + new_account_options: &CreateAccountOptions, near_root_account: &AccountId, nonce: Nonce, max_block_height: u64, -) -> anyhow::Result { +) -> anyhow::Result { let create_acc_action = Action::FunctionCall(FunctionCallAction { method_name: "create_account_advanced".to_string(), args: json!({ @@ -70,31 +71,22 @@ pub fn get_create_account_delegate_action( let delegate_create_acc_action = NonDelegateAction::try_from(create_acc_action)?; let delegate_action = DelegateAction { - sender_id: signer_id.clone(), + sender_id: signer.account_id.clone(), receiver_id: near_root_account.clone(), actions: vec![delegate_create_acc_action], nonce, max_block_height, - public_key: signer_pk.clone(), + public_key: signer.public_key.clone(), }; - Ok(delegate_action) -} - -pub fn get_local_signed_delegated_action( - delegate_action: DelegateAction, - signer_id: AccountId, - signer_sk: SecretKey, -) -> SignedDelegateAction { - let signer = InMemorySigner::from_secret_key(signer_id, signer_sk); let signable_message = SignableMessage::new(&delegate_action, SignableMessageType::DelegateAction); - let signature = signable_message.sign(&signer); + let signature = signable_message.sign(signer); - SignedDelegateAction { + Ok(SignedDelegateAction { delegate_action, signature, - } + }) } pub async fn get_mpc_signature( From 17c664941f3a1cd7328cd415c8378f34a0e8ce13 Mon Sep 17 00:00:00 2001 From: Serhii Volovyk Date: Mon, 23 Oct 2023 14:46:05 +0300 Subject: [PATCH 2/2] new_acc load tests (#325) * new_acc load tests * sign logic added to load tests * short load scenarion updated * recovery pk set in session * fore load scenarios * remove unwraps * use tracing --- .gitignore | 1 + Cargo.lock | 14 +- load-tests/Cargo.toml | 10 ++ load-tests/README.md | 2 +- load-tests/src/constants.rs | 3 + load-tests/src/main.rs | 309 +++++++++++++++++++++++++++++++- load-tests/src/primitives.rs | 20 +++ load-tests/src/utils.rs | 62 +++++++ load-tests/test_plans/short.txt | 2 +- 9 files changed, 410 insertions(+), 13 deletions(-) create mode 100644 load-tests/src/constants.rs create mode 100644 load-tests/src/primitives.rs create mode 100644 load-tests/src/utils.rs diff --git a/.gitignore b/.gitignore index b00bc8dd7..6709739cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target .direnv .DS_Store +tmp diff --git a/Cargo.lock b/Cargo.lock index 055342012..88811c78a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2709,9 +2709,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libloading" @@ -2751,10 +2751,20 @@ checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" name = "load-tests" version = "0.1.0" dependencies = [ + "chrono", "goose", "goose-eggs", + "jsonwebtoken", + "mpc-recovery", + "near-crypto 0.17.0", + "near-primitives 0.17.0", + "rand 0.8.5", "reqwest", + "serde", + "serde_json", "tokio", + "tracing", + "tracing-subscriber", ] [[package]] diff --git a/load-tests/Cargo.toml b/load-tests/Cargo.toml index cdf162b82..08a2fe376 100644 --- a/load-tests/Cargo.toml +++ b/load-tests/Cargo.toml @@ -8,3 +8,13 @@ goose = "^0.17" goose-eggs = "0.5.1" tokio = "^1.12" reqwest = "^0.11" +jsonwebtoken = "8.3.0" +near-primitives = "0.17.0" +serde = "1.0.130" +serde_json = "1.0.68" +chrono = "0.4.19" +near-crypto = "0.17.0" +mpc-recovery = { path = "../mpc-recovery" } +rand = "0.8.4" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/load-tests/README.md b/load-tests/README.md index cde6af722..fd4e1f687 100644 --- a/load-tests/README.md +++ b/load-tests/README.md @@ -5,7 +5,7 @@ This directory contains load tests for the MPC Recovery service. It is build usi To run the tests, you need to have Rust installed. You can install Rust using [rustup](https://rustup.rs/). To start the tests, run the following command: ```bash -cargo run --release -- --host --report-file=load_test_results.html --test-plan "$(cat ./test_plans/short.txt)" +RUST_LOG=info cargo run --release -- --host --report-file=load_test_results.html --test-plan "$(cat ./test_plans/short.txt)" --scenarios simpleMpcPublicKey ``` You can run Load Tests against your local development environment (check `/integration-tests` for more info) or against the staging environment by setting the `--host` parameter. diff --git a/load-tests/src/constants.rs b/load-tests/src/constants.rs new file mode 100644 index 000000000..55c495dd6 --- /dev/null +++ b/load-tests/src/constants.rs @@ -0,0 +1,3 @@ +pub const VALID_OIDC_PROVIDER_KEY: &str = "-----BEGIN RSA PRIVATE KEY-----MIIJKAIBAAKCAgEAg6UuFBM3QmtQID8cOHltjM8WF/XpFj2d5feVShG19jan76n6kEQPIhbqC4gweqWWdKdwbOmJKvDzV7qER5BC2tKB7ViKRFpsEc5pSp2vc4w81Wni9Dzicpz1R0Qr2p3lkqLuG6G/nJaD6s0KMfiyPiIBSBOgd1gaGIZcN2MtZm4bT2cVBxgBBW9L3bkpyONf0JHtia+6M7LPwzKwd29LYuirPFU31psCBejXwuWst/KBncEeHASEW/LK0UJS4tJVH05mNuicBjKkYJ8Q+UTVZPA+8bgkrWEzScAoedVn+QwbwUxZ+C0r1NunllwU+e29s9rpf9wifzX43vA4FGPYdDuEPiGmaNqFTsV/Z8oOMLDuAt/QqFVrp24S6DyHy/aWAZcJzcAbwckP0B5GsrvbAogcWzPpRzFLFkPmsQ1IMG/MK382AJ04rh+u0jomXxImLYiDFvzEXTelNsiDICHY6PQ1Fd/OfxuKVFl4cVVx5VeyWOIAjRePaeMaijHr0KrxKDZiz+Umx8UJTwbjAfPx9fM5mvBXlmsXYAm/hmnp74xDlr/s8c4fAyXmuqRocu8jq0GkMDjYJKj2QQSZSLQUMxmeF6gRIFpjK8mawsSvM88Kiu6o/pZD3i0e3QL5OBwYjcd0muxY23yvcmdVmLeTds+wB0xAtA8wkWEu8N8SGXcCAwEAAQKCAgBaJCHAF0RQU4DjA7PEK8lKkIY1U+oNk5Vp4TS1KhlphRVK8x4h6KhgFEagLNndMUMrj3dY7DRDVgeaO5nWEr7kbR4QMf9DPJMhQjAwqnZ37T++dim0SXhZOIZvDQvmPxXyaWQXQZMdmqargUiI3RzXlJtCCkZnUclUn7PHLT7qE1zZ6uCoIdSZLxNIuEAXUTHLdBCtpckfG0JOC4hvz6JUELMntcZtSWiCOWR8DJ5OulvsdE60qpcjCsW7sellbNZigGFXGcG0MLsDege6V1qzKho/k3Jx0cu3pT9R5UGzc4oRusEkQXHw55MCTv0CAbtSywP1y/tHFeLabKxJsfCE6BciR7PCIuB0DD+4cP82AD3xu2HbJuw1ata8PnDSk1SwgCHnnj1Qh5ExVyPLQa6vlEqRI7gA52xB6q56YNWpEiLeEPWvnky4rq/w3xTEFoG9N4XkjQGD3PRLngdm/u3YKQ4uVrp2GwiNTsjN6eOcZYfffH2YNH4qf4tKmDInBmig4dQE/brXLAU7mh7x6gUH8EMm5lUaeQhKYfpSnJPdAJEKFZ5UYnMEKuDYUDIhs9yn9Vlzr4acIlnRvu/nM00NUwjZfWJDTbmbktRQANKQdnC41WcqCh9p1+zSbBlzmTSSIGXu+dnfTtKzswU7fFoMgS8FWfV+u5v1wjPO6GXUIQKCAQEA9ZbiE3oghHK3qQHseHllyxWShUY0xVa4K1nd1fHUDOwWR9/qW8V/m+c7tu8yya95DngWvK5zFhzgygP49QRc30W+CTZPTQ5UHEvmyzD3CuL5XCAXPSi+C+hpt6vAdM4ZkHSwAT5Ce1KjzN49xQS33H0QZA9CR6/gcnUoJJx1tdMPghHjJAOTlQaNPJVK+OXJmQIxDvJL7MB0UK084ELYeP+o6Qlt0aC+zAfMwMVAxpc+O/4QBig6d2a1+mi6jJYvFtH1UAWbE8WbQtEX1Lql2rxkJCGe6TYCY2rm2muVuYda5yYbr4CkzUCM8vNecgpuU82aVIsp/p0n7zO2FZ29BwKCAQEAiTnIqEfNmdX3a5rRNfX78c8A3rAK5jiiBiHHcu40Fd5ETGT/Fm2BsY+xfX+Ldgv4oc7RDTZReJPXr1Y0l9ht+0LUvY4BX5ym3ADImxwQ/tCV+U/El0ffDL+cNtuIR8XOHMP9WnuajqSo2I33a79r09jGbAMZNAAmoUTIsFXtB51CVEcHM/mMZpGMddpu6yvtEW9XhorCxANIAzqdyqB9/e9jChkIG/bGqMLzv2vZYxUxNTfnhYYhK5xmqvTyGxPKOLHa61e561FBnbom3EslIq8IkorkGqUtRby7w+NiSGpr+ChkmQiyfzSOhBs5Pc7areUXqLvQ9+MyO9/aG4wUEQKCAQAXtZxX0weGoeiXOWdR7i5kn82IblGz535aOQ/QksstADHaeISQnY2HSJicPZWCoR0nx3Iyfwj/ToRpHF8RkH1C1OHW09ZuEv8NyEocvbpr46O9QB/eOKu4TJTANaWb4TXYm1tOk2spqr3DjoUaGy2A7NYDQvHcJ9+cTTE176Dxj9HEdeOe23WJApvqCGO3ib+ftPV1gvDPh3jzPPZOlEV/0PbGoLFodoNVAT/EMIbjZUCN3CZB4epbEqBo72lrHyimpFhxhEkHbKFjnvoVAHv4lQ1564EC9MLgRDbLSW2n/qhI/oXXuKywYBX7coFgsx8ZmhTXKqRAP33WewCOL69LAoIBAE2nM1N2/nPVTuPHgihFAMN/XoCloiVRWu6ZYuI4xaSyWHfalzc71K6EH+5ipKqyb4oxHL+bQ1M2ZlFEORLMWMBcu0Jg/4n5fbr1fo+3vC5WHugsKZVqCGCQdXfdlyr2VoKUrePsGjQqHZoeDCse8Ye6Hd61iieRBkswP1j55t3uMcC7SOoyhy7rok52w1m1S7wYA7GRCFIfgTrCitRFKcbvFl56d8pLRXPujjx+bU/SiDwTXKKEmnSxVq/bWL3V3xNiIf4XcJAnNThqRN9YbrVH01QJ4LbrTcku2hoprE5KWrrdMMAg2dF+Dj/Xn/bH/Zt2DoNfdQsxuBWFwUjhZeECggEBANTpwOCTpEIv9AwFs7q3vvYl/dqVcjAliQLk7fq7U0C1pL5f51jrLQWwWLhpJhkQvnmVhUFAOqWxKFvvpJ4NQbjHldQzIou9rBofsHPju42yo0NC1zwyQy4SGl644Fg5jL5KxE2AdOsTkk47uBxdPfEcZOaF5oqY6yVk3x4qNOqfxqt/MUwyDviEHgd/TfHIvNcpLl7l1CcaHv/eobSB3XPjNXcXy1MTyolH0pg662eW8Su3h7qAhP4m7ArizpgnFgHEdarXF/g3OrMDgj2IPAzalHnGSuuSjLYE7fdjGcqZ9R6+ZUpk4Vwaba6tjzB1f/SU2Myampd4H+tkHbLyJJE=-----END RSA PRIVATE KEY-----"; +pub const VALID_OIDC_AUD: &str = "test_audience"; +pub const VALID_OIDC_ISS: &str = "https://securetoken.google.com/test_audience"; diff --git a/load-tests/src/main.rs b/load-tests/src/main.rs index 2e12a8288..ad44303c1 100644 --- a/load-tests/src/main.rs +++ b/load-tests/src/main.rs @@ -1,14 +1,89 @@ -use std::time::Duration; +mod constants; +mod primitives; +pub mod utils; -use goose::prelude::*; -use goose_eggs::{validate_and_load_static_assets, Validate}; +use core::panic; use reqwest::{header::CONTENT_TYPE, Body}; +use std::{time::Duration, vec}; +use tracing_subscriber::{filter, prelude::*}; + +use constants::VALID_OIDC_PROVIDER_KEY; +use goose::prelude::*; +use mpc_recovery::{ + msg::{ + ClaimOidcRequest, MpcPkRequest, NewAccountRequest, SignRequest, UserCredentialsRequest, + UserCredentialsResponse, + }, + sign_node::oidc::OidcToken, + transaction::CreateAccountOptions, + utils::{ + claim_oidc_request_digest, sign_digest, sign_request_digest, + user_credentials_request_digest, + }, +}; +use near_crypto::SecretKey; +use near_primitives::{ + account::{AccessKey, AccessKeyPermission}, + borsh::BorshSerialize, + delegate_action::DelegateAction, + transaction::{Action, AddKeyAction}, + types::AccountId, +}; +use primitives::UserSession; +use rand::{distributions::Alphanumeric, Rng}; +use utils::build_send_and_check_request; #[tokio::main] async fn main() -> Result<(), GooseError> { + let stdout_log = tracing_subscriber::fmt::layer().pretty(); + + tracing_subscriber::registry() + .with(stdout_log.with_filter(filter::LevelFilter::INFO)) + .init(); + GooseAttack::initialize()? .register_scenario( - scenario!("simple_mpc_public_key").register_transaction(transaction!(mpc_public_key)), + scenario!("registration") + .register_transaction(transaction!(prepare_user_credentials).set_sequence(1)) + .register_transaction(transaction!(claim_oidc).set_sequence(2)) + .register_transaction(transaction!(new_account).set_sequence(3)), + ) + .register_scenario( + scenario!("registrationAndSign") + .register_transaction(transaction!(prepare_user_credentials).set_sequence(1)) + .register_transaction(transaction!(claim_oidc).set_sequence(2)) + .register_transaction(transaction!(new_account).set_sequence(3)) + .register_transaction(transaction!(user_credentials).set_sequence(4)) + .register_transaction( + transaction!(sign) + .set_sequence(5) + .set_weight(1000) // In this scenario we are mostly testing /sign functionality + .expect("Failed to set weight"), + ), + ) + .register_scenario( + scenario!("simpleClaimOidc") + .register_transaction(transaction!(prepare_user_credentials).set_sequence(1)) + .register_transaction( + transaction!(claim_oidc) + .set_sequence(2) + .set_weight(100) + .expect("Failed to set weight"), + ), + ) + .register_scenario( + scenario!("simpleUserCredentials") + .register_transaction(transaction!(prepare_user_credentials).set_sequence(1)) + .register_transaction(transaction!(claim_oidc).set_sequence(2)) + .register_transaction( + transaction!(user_credentials) + .set_sequence(3) + .set_weight(100) + .expect("Failed to set weight"), + ), + ) + .register_scenario( + scenario!("simpleMpcPublicKey").register_transaction(transaction!(mpc_public_key)), ) .execute() .await?; @@ -16,10 +91,75 @@ async fn main() -> Result<(), GooseError> { Ok(()) } -async fn mpc_public_key(user: &mut GooseUser) -> TransactionResult { +async fn prepare_user_credentials(user: &mut GooseUser) -> TransactionResult { + tracing::info!("prepare_user_credentials"); + // Generate 2 key pairs + let fa_sk = SecretKey::from_random(near_crypto::KeyType::ED25519); + let la_sk = SecretKey::from_random(near_crypto::KeyType::ED25519); + + // Create JWT with random sub (usually done by OIDC Provider) + let oidc_token = OidcToken::new(&utils::create_jwt_token( + VALID_OIDC_PROVIDER_KEY, + constants::VALID_OIDC_AUD, + constants::VALID_OIDC_ISS, + None, + )); + + // Generate random near account id + let account_id_rand: String = rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(10) + .map(char::from) + .collect(); + + let near_account_id: AccountId = format!("acc-{}.near", account_id_rand.to_lowercase()) + .try_into() + .expect("Failed to generate random account Id"); + + let session = UserSession { + jwt_token: oidc_token, + near_account_id, + fa_sk, + la_sk, + recovery_pk: None, + }; + + user.set_session_data(session); + + Ok(()) +} + +async fn user_credentials(user: &mut GooseUser) -> TransactionResult { + tracing::info!("user_credentials"); + let sesion = user + .get_session_data::() + .expect("Session Data must be set"); + + let oidc_token = sesion.jwt_token.clone(); + let fa_sk = sesion.fa_sk.clone(); + let fa_pk = fa_sk.public_key(); + let la_sk = sesion.la_sk.clone(); + let near_account_id = sesion.near_account_id.clone(); + + let user_credentials_request_digest = + user_credentials_request_digest(&oidc_token, &fa_pk).expect("Failed to create digest"); + + let user_credentials_frp_signature = + sign_digest(&user_credentials_request_digest, &fa_sk).expect("Failed to sign digest"); + + let user_credentials_request = UserCredentialsRequest { + oidc_token: oidc_token.clone(), + frp_public_key: fa_pk, + frp_signature: user_credentials_frp_signature, + }; + + let body_json = + serde_json::to_string(&user_credentials_request).expect("json serialization failed"); + + let body = Body::from(body_json.to_owned()); let request_builder = user - .get_request_builder(&GooseMethod::Post, "mpc_public_key")? - .body(Body::from("{}")) + .get_request_builder(&GooseMethod::Post, "user_credentials")? + .body(body) .header(CONTENT_TYPE, "application/json") .timeout(Duration::from_secs(10)); @@ -29,8 +169,159 @@ async fn mpc_public_key(user: &mut GooseUser) -> TransactionResult { let goose_responce = user.request(goose_request).await?; - let validate = &Validate::builder().status(200).build(); - validate_and_load_static_assets(user, goose_responce, validate).await?; + let response = goose_responce.response.expect("Expected response ... ."); + + let user_credentials_response = response + .json::() + .await + .expect("Failed to parse user credentials response"); + + if let UserCredentialsResponse::Ok { recovery_pk } = user_credentials_response { + tracing::info!("UserCredentialsResponce has Ok, setting session data"); + let session = UserSession { + jwt_token: oidc_token, + near_account_id, + fa_sk, + la_sk, + recovery_pk: Some(recovery_pk), + }; + user.set_session_data(session); + } else { + panic!( + "UserCredentialsResponce has Error: {:?}", + user_credentials_response + ); + } Ok(()) } + +async fn mpc_public_key(user: &mut GooseUser) -> TransactionResult { + tracing::info!("mpc_public_key"); + let body_json = serde_json::to_string(&MpcPkRequest {}).expect("json serialization failed"); + build_send_and_check_request(user, "mpc_public_key", &body_json).await +} + +async fn claim_oidc(user: &mut GooseUser) -> TransactionResult { + tracing::info!("claim_oidc"); + let sesion = user + .get_session_data::() + .expect("Session Data must be set"); + let oidc_token_hash = sesion.jwt_token.digest_hash(); + let frp_secret_key = sesion.fa_sk.clone(); + let frp_public_key = frp_secret_key.public_key(); + + let request_digest = claim_oidc_request_digest(&oidc_token_hash, &frp_public_key) + .expect("Failed to create digest"); + let frp_signature = + sign_digest(&request_digest, &frp_secret_key).expect("Failed to sign digest"); + + let claim_oidc_request = ClaimOidcRequest { + oidc_token_hash: oidc_token_hash.to_owned(), + frp_public_key, + frp_signature, + }; + + let body_json = serde_json::to_string(&claim_oidc_request).expect("json serialization failed"); + + build_send_and_check_request(user, "claim_oidc", &body_json).await +} + +async fn new_account(user: &mut GooseUser) -> TransactionResult { + let sesion = user + .get_session_data::() + .expect("Session Data must be set"); + let oidc_token = sesion.jwt_token.clone(); + let fa_secret_key = sesion.fa_sk.clone(); + let fa_public_key = fa_secret_key.public_key(); + let user_account_id = sesion.near_account_id.clone(); + + let create_account_options = CreateAccountOptions { + full_access_keys: Some(vec![fa_public_key.clone()]), + limited_access_keys: None, + contract_bytes: None, + }; + + let user_credentials_request_digest = + user_credentials_request_digest(&oidc_token, &fa_public_key) + .expect("Failed to create digest"); + + let user_credentials_frp_signature = + sign_digest(&user_credentials_request_digest, &fa_secret_key) + .expect("Failed to sign digest"); + + let new_account_request = NewAccountRequest { + near_account_id: user_account_id, + create_account_options, + oidc_token: sesion.jwt_token.clone(), + user_credentials_frp_signature, + frp_public_key: fa_public_key, + }; + + let body_json = serde_json::to_string(&new_account_request).expect("json serialization failed"); + build_send_and_check_request(user, "new_account", &body_json).await +} + +async fn sign(user: &mut GooseUser) -> TransactionResult { + tracing::info!("sign"); + let session = user + .get_session_data::() + .expect("Session Data must be set"); + let oidc_token = session.jwt_token.clone(); + let fa_secret_key = session.fa_sk.clone(); + let fa_public_key = fa_secret_key.public_key(); + let account_id = session.near_account_id.clone(); + let recovery_pk = session + .recovery_pk + .clone() + .expect("Recovery PK must be set before calling /sign"); + + let new_secret_key = SecretKey::from_random(near_crypto::KeyType::ED25519); + let new_public_key = new_secret_key.public_key(); + + let nonce = 0; // Set real nonce in case transaction is entend to be executed + let block_height = 0; // Set real block height in case transaction is entend to be executed + + let add_key_delegate_action = DelegateAction { + sender_id: account_id.clone(), + receiver_id: account_id.clone(), + actions: vec![Action::AddKey(AddKeyAction { + public_key: new_public_key.clone(), + access_key: AccessKey { + nonce: 0, + permission: AccessKeyPermission::FullAccess, + }, + }) + .try_into() + .unwrap()], + nonce, + max_block_height: block_height + 100, + public_key: recovery_pk, + }; + + let sign_request_digest = + sign_request_digest(&add_key_delegate_action, &oidc_token, &fa_public_key) + .expect("Failed to create digest"); + let sign_request_frp_signature = + sign_digest(&sign_request_digest, &fa_secret_key).expect("Failed to sign digest"); + + let user_credentials_request_digest = + user_credentials_request_digest(&oidc_token, &fa_public_key) + .expect("Failed to create digest"); + let user_credentials_frp_signature = + sign_digest(&user_credentials_request_digest, &fa_secret_key) + .expect("Failed to sign digest"); + + let sign_request = SignRequest { + delegate_action: add_key_delegate_action + .try_to_vec() + .expect("Failed to serialize delegate action"), + oidc_token, + frp_signature: sign_request_frp_signature, + user_credentials_frp_signature, + frp_public_key: fa_public_key, + }; + + let body_json = serde_json::to_string(&sign_request).expect("json serialization failed"); + build_send_and_check_request(user, "sign", &body_json).await +} diff --git a/load-tests/src/primitives.rs b/load-tests/src/primitives.rs new file mode 100644 index 000000000..638863a3b --- /dev/null +++ b/load-tests/src/primitives.rs @@ -0,0 +1,20 @@ +use mpc_recovery::sign_node::oidc::OidcToken; +use near_crypto::{PublicKey, SecretKey}; +use near_primitives::types::AccountId; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct IdTokenClaims { + pub iss: String, + pub sub: String, + pub aud: String, + pub exp: usize, +} + +pub struct UserSession { + pub jwt_token: OidcToken, + pub near_account_id: AccountId, + pub fa_sk: SecretKey, + pub la_sk: SecretKey, + pub recovery_pk: Option, +} diff --git a/load-tests/src/utils.rs b/load-tests/src/utils.rs new file mode 100644 index 000000000..917059913 --- /dev/null +++ b/load-tests/src/utils.rs @@ -0,0 +1,62 @@ +use chrono::Utc; +use goose::prelude::{GooseMethod, GooseRequest, GooseUser, TransactionResult}; +use goose_eggs::{validate_and_load_static_assets, Validate}; +use jsonwebtoken::{encode, Algorithm, EncodingKey, Header}; +use near_primitives::utils::generate_random_string; +use reqwest::{header::CONTENT_TYPE, Body}; +use std::time::Duration; + +use crate::primitives::IdTokenClaims; + +// TODO: try using existing function +pub fn create_jwt_token( + secret_rsa_pem_key: &str, + aud: &str, + iss: &str, + sub: Option<&str>, +) -> String { + let rnd_sub = generate_random_string(10); + let sub = sub.unwrap_or_else(|| &rnd_sub); + + let my_claims = IdTokenClaims { + iss: iss.to_owned(), + sub: sub.to_owned(), + aud: aud.to_owned(), + exp: (Utc::now() + chrono::Duration::hours(1)).timestamp() as usize, + }; + + let private_key_der = secret_rsa_pem_key.as_bytes().to_vec(); + + let token = encode( + &Header::new(Algorithm::RS256), + &my_claims, + &EncodingKey::from_rsa_pem(&private_key_der).unwrap(), + ) + .expect("Failed to encode jwt token"); + + token.to_string() +} + +pub async fn build_send_and_check_request( + user: &mut GooseUser, + path: &str, + body_json: &str, +) -> TransactionResult { + let body = Body::from(body_json.to_owned()); + let request_builder = user + .get_request_builder(&GooseMethod::Post, path)? + .body(body) + .header(CONTENT_TYPE, "application/json") + .timeout(Duration::from_secs(10)); + + let goose_request = GooseRequest::builder() + .set_request_builder(request_builder) + .build(); + + let goose_responce = user.request(goose_request).await?; + + let validate = &Validate::builder().status(200).build(); + validate_and_load_static_assets(user, goose_responce, validate).await?; + + Ok(()) +} diff --git a/load-tests/test_plans/short.txt b/load-tests/test_plans/short.txt index 3563b0f88..a2c87bb25 100644 --- a/load-tests/test_plans/short.txt +++ b/load-tests/test_plans/short.txt @@ -1 +1 @@ -10,2s;20,5s;0,0s \ No newline at end of file +0,0s;100,20s;0,0s \ No newline at end of file