diff --git a/Cargo.lock b/Cargo.lock index b671a68..dfd0f51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.16.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -23,17 +23,17 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.7", ] [[package]] name = "age" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf320f937ccd0eb7f63450be0f071586cd918cd86785303ec1d052a3e243b550" +checksum = "23100453ca2a1bbda9bfc6deac1bebb828d7e66ba481ebccfedfddf29321b6b9" dependencies = [ "age-core", - "base64 0.13.0", + "base64 0.13.1", "bech32 0.8.1", "chacha20poly1305", "cookie-factory", @@ -42,13 +42,13 @@ dependencies = [ "i18n-embed", "i18n-embed-fl", "lazy_static", - "nom 7.1.0", + "nom 7.1.3", "pin-project", "rand 0.7.3", "rand 0.8.5", "rust-embed", "scrypt", - "sha2 0.9.8", + "sha2 0.9.9", "subtle", "x25519-dalek 1.1.1", "zeroize", @@ -56,29 +56,53 @@ dependencies = [ [[package]] name = "age-core" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a485102f6c7a23e0666b169ba77c9ff6c6d249c05395c379be3cbab48a948e84" +checksum = "70afa630ef12a4fc666277713efbe6da2bc87bb3f3af0f1149415b701362c615" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "chacha20poly1305", "cookie-factory", "hkdf", - "nom 7.1.0", + "nom 7.1.3", "rand 0.8.5", "secrecy 0.8.0", - "sha2 0.9.8", + "sha2 0.9.9", ] [[package]] name = "aho-corasick" -version = "0.7.18" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] +[[package]] +name = "aligned" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80a21b9440a626c7fc8573a9e3d3a06b75c7c97754c2949bc7857b90353ca655" +dependencies = [ + "as-slice", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -94,6 +118,12 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8" +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + [[package]] name = "arrayvec" version = "0.3.25" @@ -113,34 +143,219 @@ dependencies = [ "nodrop", ] +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +dependencies = [ + "concurrent-queue", + "event-listener 4.0.0", + "event-listener-strategy", + "futures-core", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.2.0", + "async-task", + "concurrent-queue", + "fastrand 2.0.1", + "futures-lite 2.1.0", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.1.1", + "async-executor", + "async-io 2.2.2", + "async-lock 3.2.0", + "blocking", + "futures-lite 2.1.0", + "once_cell", + "tokio 0.2.25", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg 1.1.0", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +dependencies = [ + "async-lock 3.2.0", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-io", + "futures-lite 2.1.0", + "parking", + "polling 3.3.1", + "rustix 0.38.25", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +dependencies = [ + "event-listener 4.0.0", + "event-listener-strategy", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "async-socks5" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "575663f6d00adcfc4289d3f0825f49856380e062c030e799a2f9f4a275d842d6" +dependencies = [ + "async-trait", + "thiserror", + "tokio 0.2.25", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io 1.13.0", + "async-lock 2.8.0", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite 1.13.0", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite 0.2.13", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d90cd0b264dfdd8eb5bad0a2c217c1f88fa96a8573f40e7b12de23fb468f46" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi 0.3.9", ] [[package]] name = "autocfg" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.1.0", +] [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.62" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091bcdf2da9950f96aa522681ce805e6857f6ca8df73833d35736ab2dc78e152" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -175,15 +390,21 @@ checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.3.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a30f9c631ae8b97868a2e841015b72f2c99b05e3f03a14d543b843816a0a5b4d" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bech32" @@ -212,8 +433,8 @@ dependencies = [ "lazycell", "log", "peeking_take_while", - "proc-macro2 1.0.34", - "quote 1.0.10", + "proc-macro2 1.0.70", + "quote 1.0.33", "regex", "rustc-hash", "shlex", @@ -238,6 +459,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "blake2-rfc" version = "0.2.18" @@ -266,16 +493,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.7", ] [[package]] name = "block-buffer" -version = "0.10.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.7", ] [[package]] @@ -287,6 +514,22 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "blocking" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +dependencies = [ + "async-channel 2.1.1", + "async-lock 3.2.0", + "async-task", + "fastrand 2.0.1", + "futures-io", + "futures-lite 2.1.0", + "piper", + "tracing", +] + [[package]] name = "bs58" version = "0.3.1" @@ -295,18 +538,19 @@ checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" [[package]] name = "bstr" -version = "0.2.17" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" dependencies = [ "memchr", + "serde", ] [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byte-tools" @@ -316,9 +560,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -338,15 +582,18 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.71" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cexpr" @@ -354,7 +601,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" dependencies = [ - "nom 5.1.2", + "nom 5.1.3", ] [[package]] @@ -371,41 +618,53 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chacha20" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" +checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" dependencies = [ "cfg-if 1.0.0", - "cipher", + "cipher 0.3.0", "cpufeatures", "zeroize", ] [[package]] -name = "chacha20poly1305" -version = "0.9.0" +name = "chacha20" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if 1.0.0", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" dependencies = [ "aead", - "chacha20", - "cipher", + "chacha20 0.8.2", + "cipher 0.3.0", "poly1305", "zeroize", ] [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ - "libc", - "num-integer", - "num-traits 0.2.14", + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits 0.2.17", "serde", - "time", - "winapi 0.3.9", + "wasm-bindgen", + "windows-targets 0.48.5", ] [[package]] @@ -414,14 +673,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.7", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", ] [[package]] name = "clang-sys" -version = "1.3.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa66045b9cb23c2e9c1520732030608b02ee07e5cfaa5a521ec15ded7fa24c90" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ "glob", "libc", @@ -453,6 +722,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -477,11 +755,11 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "core-foundation-sys 0.8.3", + "core-foundation-sys 0.8.6", "libc", ] @@ -493,24 +771,24 @@ checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if 1.0.0", ] @@ -537,21 +815,11 @@ dependencies = [ "libc", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", @@ -560,34 +828,34 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ + "autocfg 1.1.0", "cfg-if 1.0.0", "crossbeam-utils", - "lazy_static", "memoffset", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if 1.0.0", - "lazy_static", ] [[package]] name = "crypto-common" -version = "0.1.1" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.7", + "typenum", ] [[package]] @@ -596,10 +864,31 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.7", "subtle", ] +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa 1.0.9", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "ct-logs" version = "0.6.0" @@ -609,6 +898,16 @@ dependencies = [ "sct", ] +[[package]] +name = "ctrlc" +version = "3.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" +dependencies = [ + "nix 0.27.1", + "windows-sys 0.48.0", +] + [[package]] name = "curve25519-dalek" version = "2.1.3" @@ -636,20 +935,32 @@ dependencies = [ ] [[package]] -name = "dashmap" -version = "4.0.2" +name = "cvt" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" +checksum = "d2ae9bf77fbf2d39ef573205d554d87e86c12f1994e9ea335b0651b9b278bcf1" dependencies = [ "cfg-if 1.0.0", - "num_cpus", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown 0.14.3", + "lock_api 0.4.11", + "once_cell", + "parking_lot_core 0.9.9", ] [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "digest" @@ -666,18 +977,17 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.7", ] [[package]] name = "digest" -version = "0.10.1" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.0", + "block-buffer 0.10.4", "crypto-common", - "generic-array 0.14.4", "subtle", ] @@ -692,10 +1002,20 @@ dependencies = [ ] [[package]] -name = "dirs-sys" -version = "0.3.6" +name = "dirs-next" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", @@ -703,16 +1023,26 @@ dependencies = [ ] [[package]] -name = "doc-comment" -version = "0.3.3" +name = "dirs-sys-next" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.9", +] [[package]] -name = "dtoa" -version = "0.4.8" +name = "displaydoc" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", +] [[package]] name = "easy-jsonrpc-mw" @@ -741,9 +1071,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.3.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e1069e39f1454367eb2de793ed062fac4c35c2934b76a81d90dd9abcd28816" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "signature", ] @@ -758,21 +1088,27 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2 0.9.8", + "sha2 0.9.9", "zeroize", ] [[package]] name = "either" -version = "1.6.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if 1.0.0", ] @@ -800,25 +1136,46 @@ dependencies = [ ] [[package]] -name = "failure" -version = "0.1.8" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "backtrace", - "failure_derive", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "failure_derive" -version = "0.1.8" +name = "event-listener" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", - "synstructure", + "concurrent-queue", + "parking", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.0", + "pin-project-lite 0.2.13", ] [[package]] @@ -827,24 +1184,37 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "find-crate" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ - "cfg-if 1.0.0", "crc32fast", - "libc", "miniz_oxide", ] @@ -869,7 +1239,7 @@ dependencies = [ "intl-memoizer", "intl_pluralrules", "rustc-hash", - "self_cell", + "self_cell 0.10.3", "smallvec", "unic-langid", ] @@ -915,11 +1285,10 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "matches", "percent-encoding", ] @@ -933,6 +1302,20 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "fs_at" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982f82cc75107eef84f417ad6c53ae89bf65b561937ca4a3b3b0fd04d0aa2425" +dependencies = [ + "aligned", + "cfg-if 1.0.0", + "cvt", + "libc", + "nix 0.26.4", + "windows-sys 0.48.0", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -978,9 +1361,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -993,9 +1376,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -1003,15 +1386,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -1020,42 +1403,67 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite 0.2.13", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +dependencies = [ + "fastrand 2.0.1", + "futures-core", + "futures-io", + "parking", + "pin-project-lite 0.2.13", +] [[package]] name = "futures-macro" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ - "autocfg 1.0.1", - "proc-macro-hack", - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", ] [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ - "autocfg 1.0.1", "futures-channel", "futures-core", "futures-io", @@ -1063,10 +1471,8 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.7", + "pin-project-lite 0.2.13", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -1087,9 +1493,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1108,89 +1514,66 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] name = "gimli" -version = "0.25.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.8" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", ] [[package]] name = "grin_api" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin?branch=master#78c9794d30c21d40a24f255c411e04f3eab5d512" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "bytes 0.5.6", "easy-jsonrpc-mw", - "failure", - "failure_derive", - "futures 0.3.17", - "grin_chain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_p2p 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_pool 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "http", - "hyper 0.13.10", - "hyper-rustls 0.20.0", - "hyper-timeout", - "lazy_static", - "log", - "regex", - "ring", - "rustls 0.17.0", - "serde", - "serde_derive", - "serde_json", - "tokio 0.2.25", - "tokio-rustls 0.13.1", - "url", -] - -[[package]] -name = "grin_api" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" -dependencies = [ - "bytes 0.5.6", - "easy-jsonrpc-mw", - "failure", - "failure_derive", - "futures 0.3.17", - "grin_chain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_p2p 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_pool 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "futures 0.3.29", + "grin_chain", + "grin_core", + "grin_p2p", + "grin_pool", + "grin_store", + "grin_util", "http", "hyper 0.13.10", "hyper-rustls 0.20.0", @@ -1203,6 +1586,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "thiserror", "tokio 0.2.25", "tokio-rustls 0.13.1", "url", @@ -1210,8 +1594,8 @@ dependencies = [ [[package]] name = "grin_chain" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin?branch=master#78c9794d30c21d40a24f255c411e04f3eab5d512" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "bit-vec", "bitflags 1.3.2", @@ -1219,47 +1603,22 @@ dependencies = [ "chrono", "croaring", "enum_primitive", - "failure", - "failure_derive", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "lazy_static", - "log", - "lru-cache", - "serde", - "serde_derive", -] - -[[package]] -name = "grin_chain" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" -dependencies = [ - "bit-vec", - "bitflags 1.3.2", - "byteorder", - "chrono", - "croaring", - "enum_primitive", - "failure", - "failure_derive", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "grin_core", + "grin_keychain", + "grin_store", + "grin_util", "lazy_static", "log", "lru-cache", "serde", "serde_derive", + "thiserror", ] [[package]] name = "grin_core" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin?branch=master#78c9794d30c21d40a24f255c411e04f3eab5d512" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "blake2-rfc", "byteorder", @@ -1267,37 +1626,8 @@ dependencies = [ "chrono", "croaring", "enum_primitive", - "failure", - "failure_derive", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "lazy_static", - "log", - "lru-cache", - "num", - "num-bigint", - "rand 0.6.5", - "serde", - "serde_derive", - "siphasher", - "zeroize", -] - -[[package]] -name = "grin_core" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" -dependencies = [ - "blake2-rfc", - "byteorder", - "bytes 0.5.6", - "chrono", - "croaring", - "enum_primitive", - "failure", - "failure_derive", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "grin_keychain", + "grin_util", "lazy_static", "log", "lru-cache", @@ -1307,18 +1637,19 @@ dependencies = [ "serde", "serde_derive", "siphasher", + "thiserror", "zeroize", ] [[package]] name = "grin_keychain" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin?branch=master#78c9794d30c21d40a24f255c411e04f3eab5d512" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "blake2-rfc", "byteorder", "digest 0.9.0", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", + "grin_util", "hmac 0.11.0", "lazy_static", "log", @@ -1328,29 +1659,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha2 0.9.8", - "zeroize", -] - -[[package]] -name = "grin_keychain" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" -dependencies = [ - "blake2-rfc", - "byteorder", - "digest 0.9.0", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "hmac 0.11.0", - "lazy_static", - "log", - "pbkdf2 0.8.0", - "rand 0.6.5", - "ripemd160", - "serde", - "serde_derive", - "serde_json", - "sha2 0.9.8", + "sha2 0.9.9", "zeroize", ] @@ -1361,70 +1670,48 @@ dependencies = [ "blake2-rfc", "byteorder", "bytes 0.5.6", - "chacha20", + "chacha20 0.8.2", "curve25519-dalek 2.1.3", "ed25519-dalek", - "grin_api 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_chain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "grin_api", + "grin_chain", + "grin_core", + "grin_keychain", "grin_secp256k1zkp", "grin_servers", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.1.1", + "grin_store", + "grin_util", "grin_wallet_api", "grin_wallet_impls", "grin_wallet_libwallet", "grin_wallet_util", - "hmac 0.12.0", - "itertools", + "hmac 0.12.1", + "itertools 0.10.5", "lazy_static", "rand 0.7.3", "rpassword", "serde", "serde_derive", "serde_json", - "sha2 0.10.0", + "sha2 0.10.8", "thiserror", - "toml", + "toml 0.5.11", "x25519-dalek 0.6.0", ] [[package]] name = "grin_p2p" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin?branch=master#78c9794d30c21d40a24f255c411e04f3eab5d512" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "bitflags 1.3.2", "bytes 0.5.6", "chrono", "enum_primitive", - "grin_chain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "log", - "lru-cache", - "num", - "rand 0.6.5", - "serde", - "serde_derive", - "tempfile", -] - -[[package]] -name = "grin_p2p" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" -dependencies = [ - "bitflags 1.3.2", - "bytes 0.5.6", - "chrono", - "enum_primitive", - "grin_chain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "grin_chain", + "grin_core", + "grin_store", + "grin_util", "log", "lru-cache", "num", @@ -1436,45 +1723,26 @@ dependencies = [ [[package]] name = "grin_pool" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin?branch=master#78c9794d30c21d40a24f255c411e04f3eab5d512" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "blake2-rfc", "chrono", - "failure", - "failure_derive", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "log", - "rand 0.6.5", - "serde", - "serde_derive", -] - -[[package]] -name = "grin_pool" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" -dependencies = [ - "blake2-rfc", - "chrono", - "failure", - "failure_derive", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "grin_core", + "grin_keychain", + "grin_util", "log", "rand 0.6.5", "serde", "serde_derive", + "thiserror", ] [[package]] name = "grin_secp256k1zkp" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af3c4c4829b3e2e7ee1d9a542833e4244912fbb887fabe44682558159b068a7" +checksum = "b04798e32404c0af082b6a209ad4df1ab1d9ec3a5a5056f284cfa32f74e59ce6" dependencies = [ "arrayvec 0.3.25", "cc", @@ -1488,20 +1756,20 @@ dependencies = [ [[package]] name = "grin_servers" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "chrono", "fs2", - "futures 0.3.17", - "grin_api 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_chain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_p2p 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_pool 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "futures 0.3.29", + "grin_api", + "grin_chain", + "grin_core", + "grin_keychain", + "grin_p2p", + "grin_pool", + "grin_store", + "grin_util", "http", "hyper 0.13.10", "hyper-rustls 0.20.0", @@ -1518,35 +1786,13 @@ dependencies = [ [[package]] name = "grin_store" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin?branch=master#78c9794d30c21d40a24f255c411e04f3eab5d512" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "byteorder", "croaring", - "failure", - "failure_derive", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "libc", - "lmdb-zero", - "log", - "memmap", - "serde", - "serde_derive", - "tempfile", -] - -[[package]] -name = "grin_store" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" -dependencies = [ - "byteorder", - "croaring", - "failure", - "failure_derive", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "grin_core", + "grin_util", "libc", "lmdb-zero", "log", @@ -1554,55 +1800,13 @@ dependencies = [ "serde", "serde_derive", "tempfile", + "thiserror", ] [[package]] name = "grin_util" -version = "5.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdbab6869a23e2c2b4307f4015aa1f04242aace9ca62fbe34b5ad192f6b9d9e6" -dependencies = [ - "backtrace", - "base64 0.12.3", - "byteorder", - "grin_secp256k1zkp", - "lazy_static", - "log", - "log4rs", - "parking_lot 0.10.2", - "rand 0.6.5", - "serde", - "serde_derive", - "walkdir", - "zeroize", - "zip", -] - -[[package]] -name = "grin_util" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin?branch=master#78c9794d30c21d40a24f255c411e04f3eab5d512" -dependencies = [ - "backtrace", - "base64 0.12.3", - "byteorder", - "grin_secp256k1zkp", - "lazy_static", - "log", - "log4rs", - "parking_lot 0.10.2", - "rand 0.6.5", - "serde", - "serde_derive", - "walkdir", - "zeroize", - "zip", -] - -[[package]] -name = "grin_util" -version = "5.2.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#382e914c50c46ddd167b47f9f0c2c3d33f273ef4" +version = "5.2.0-beta.3" +source = "git+https://github.com/mimblewimble/grin?tag=v5.2.0-beta.3#94277bba9db2e31e713f2a4cfdc37b11e46a1630" dependencies = [ "backtrace", "base64 0.12.3", @@ -1622,15 +1826,16 @@ dependencies = [ [[package]] name = "grin_wallet_api" -version = "5.1.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213" +version = "5.2.0-beta.1" +source = "git+https://github.com/mimblewimble/grin-wallet#12a25f82f1a799caa738f3d7cf42e8ee2b13f005" dependencies = [ "base64 0.12.3", "chrono", "easy-jsonrpc-mw", "ed25519-dalek", - "failure", - "failure_derive", + "grin_core", + "grin_keychain", + "grin_util", "grin_wallet_config", "grin_wallet_impls", "grin_wallet_libwallet", @@ -1646,21 +1851,57 @@ dependencies = [ [[package]] name = "grin_wallet_config" -version = "5.1.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213" +version = "5.2.0-beta.1" +source = "git+https://github.com/mimblewimble/grin-wallet#12a25f82f1a799caa738f3d7cf42e8ee2b13f005" dependencies = [ "dirs", + "grin_core", + "grin_util", "grin_wallet_util", "rand 0.6.5", "serde", "serde_derive", - "toml", + "toml 0.5.11", +] + +[[package]] +name = "grin_wallet_controller" +version = "5.2.0-beta.1" +source = "git+https://github.com/mimblewimble/grin-wallet#12a25f82f1a799caa738f3d7cf42e8ee2b13f005" +dependencies = [ + "chrono", + "easy-jsonrpc-mw", + "futures 0.3.29", + "grin_api", + "grin_core", + "grin_keychain", + "grin_util", + "grin_wallet_api", + "grin_wallet_config", + "grin_wallet_impls", + "grin_wallet_libwallet", + "grin_wallet_util", + "hyper 0.13.10", + "lazy_static", + "log", + "prettytable-rs", + "qr_code", + "rand 0.7.3", + "ring", + "serde", + "serde_derive", + "serde_json", + "term 0.6.1", + "thiserror", + "tokio 0.2.25", + "url", + "uuid", ] [[package]] name = "grin_wallet_impls" -version = "5.1.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213" +version = "5.2.0-beta.1" +source = "git+https://github.com/mimblewimble/grin-wallet#12a25f82f1a799caa738f3d7cf42e8ee2b13f005" dependencies = [ "base64 0.12.3", "blake2-rfc", @@ -1668,9 +1909,13 @@ dependencies = [ "chrono", "data-encoding", "ed25519-dalek", - "failure", - "failure_derive", - "futures 0.3.17", + "futures 0.3.29", + "grin_api", + "grin_chain", + "grin_core", + "grin_keychain", + "grin_store", + "grin_util", "grin_wallet_config", "grin_wallet_libwallet", "grin_wallet_util", @@ -1684,6 +1929,7 @@ dependencies = [ "serde_derive", "serde_json", "sysinfo", + "thiserror", "timer", "tokio 0.2.25", "url", @@ -1693,8 +1939,8 @@ dependencies = [ [[package]] name = "grin_wallet_libwallet" -version = "5.1.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213" +version = "5.2.0-beta.1" +source = "git+https://github.com/mimblewimble/grin-wallet#12a25f82f1a799caa738f3d7cf42e8ee2b13f005" dependencies = [ "age", "base64 0.9.3", @@ -1705,12 +1951,15 @@ dependencies = [ "chrono", "curve25519-dalek 2.1.3", "ed25519-dalek", - "failure", - "failure_derive", + "grin_core", + "grin_keychain", + "grin_store", + "grin_util", "grin_wallet_config", "grin_wallet_util", "lazy_static", "log", + "num-bigint", "rand 0.6.5", "regex", "secrecy 0.6.0", @@ -1720,27 +1969,24 @@ dependencies = [ "sha2 0.8.2", "strum", "strum_macros", + "thiserror", "uuid", "x25519-dalek 0.6.0", ] [[package]] name = "grin_wallet_util" -version = "5.1.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213" +version = "5.2.0-beta.1" +source = "git+https://github.com/mimblewimble/grin-wallet#12a25f82f1a799caa738f3d7cf42e8ee2b13f005" dependencies = [ "data-encoding", "ed25519-dalek", - "grin_api 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_chain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", - "grin_util 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin?branch=master)", + "grin_util", "rand 0.6.5", "serde", "serde_derive", "sha3", + "thiserror", ] [[package]] @@ -1755,7 +2001,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio 0.2.25", "tokio-util 0.3.1", @@ -1764,42 +2010,28 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.7" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" -dependencies = [ - "bytes 1.1.0", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio 1.12.0", - "tokio-util 0.6.8", - "tracing", -] +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.0", - "bitflags 1.3.2", - "bytes 1.1.0", + "base64 0.21.5", + "bytes 1.5.0", "headers-core", "http", - "httpdate 1.0.1", + "httpdate 1.0.3", "mime", "sha1", ] @@ -1831,6 +2063,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + [[package]] name = "hkdf" version = "0.11.0" @@ -1853,22 +2091,22 @@ dependencies = [ [[package]] name = "hmac" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddca131f3e7f2ce2df364b57949a9d47915cfbd35e46cfee355ccebbf794d6a2" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.1", + "digest 0.10.7", ] [[package]] name = "http" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ - "bytes 1.1.0", + "bytes 1.5.0", "fnv", - "itoa", + "itoa 1.0.9", ] [[package]] @@ -1883,20 +2121,20 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.1.0", + "bytes 1.5.0", "http", - "pin-project-lite 0.2.7", + "pin-project-lite 0.2.13", ] [[package]] name = "httparse" -version = "1.5.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -1906,9 +2144,9 @@ checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" [[package]] name = "httpdate" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -1935,12 +2173,12 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.2.7", + "h2", "http", "http-body 0.3.1", "httparse", "httpdate 0.3.2", - "itoa", + "itoa 0.4.8", "pin-project", "socket2 0.3.19", "tokio 0.2.25", @@ -1951,23 +2189,22 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.14" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b91bb1f221b6ea1f1e4371216b70f40748774c2fb5971b450c07773fb92d26b" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "bytes 1.1.0", + "bytes 1.5.0", "futures-channel", "futures-core", "futures-util", - "h2 0.3.7", "http", - "http-body 0.4.4", + "http-body 0.4.5", "httparse", - "httpdate 1.0.1", - "itoa", - "pin-project-lite 0.2.7", - "socket2 0.4.2", - "tokio 1.12.0", + "httpdate 1.0.3", + "itoa 1.0.9", + "pin-project-lite 0.2.13", + "socket2 0.4.10", + "tokio 1.34.0", "tower-service", "tracing", "want", @@ -1979,14 +2216,14 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" dependencies = [ - "bytes 1.1.0", - "futures 0.3.17", + "bytes 1.5.0", + "futures 0.3.29", "headers", "http", - "hyper 0.14.14", + "hyper 0.14.27", "hyper-tls 0.5.0", "native-tls", - "tokio 1.12.0", + "tokio 1.34.0", "tokio-native-tls", "tower-service", ] @@ -2025,6 +2262,21 @@ dependencies = [ "webpki", ] +[[package]] +name = "hyper-socks2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "100482b5da07f568a53fabd8ca1639ae21d8d94b25f36331613d77b2fb951e52" +dependencies = [ + "async-socks5", + "futures 0.3.29", + "http", + "hyper 0.13.10", + "hyper-tls 0.4.3", + "thiserror", + "tokio 0.2.25", +] + [[package]] name = "hyper-timeout" version = "0.3.1" @@ -2056,33 +2308,34 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.1.0", - "hyper 0.14.14", + "bytes 1.5.0", + "hyper 0.14.27", "native-tls", - "tokio 1.12.0", + "tokio 1.34.0", "tokio-native-tls", ] [[package]] name = "i18n-config" -version = "0.4.2" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62affcd43abfb51f3cbd8736f9407908dc5b44fc558a9be07460bbfd104d983" +checksum = "0c9ce3c48cbc21fd5b22b9331f32b5b51f6ad85d969b99e793427332e76e7640" dependencies = [ "log", "serde", "serde_derive", "thiserror", - "toml", + "toml 0.8.8", "unic-langid", ] [[package]] name = "i18n-embed" -version = "0.13.1" +version = "0.13.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a0b4598fcd199eb5da38f70ece82903b178ad638839661c00612719bcfc0ad" +checksum = "92a86226a7a16632de6723449ee5fe70bac5af718bc642ee9ca2f0f6e14fa1fa" dependencies = [ + "arc-swap 1.6.0", "fluent", "fluent-langneg", "fluent-syntax", @@ -2090,7 +2343,7 @@ dependencies = [ "intl-memoizer", "lazy_static", "log", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rust-embed", "thiserror", "unic-langid", @@ -2099,9 +2352,9 @@ dependencies = [ [[package]] name = "i18n-embed-fl" -version = "0.6.1" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c1d347d2f7f9f2f977385b43b204d59ebeb1b2f93ce73cd23622df2d2da1033" +checksum = "d26a3d3569737dfaac7fc1c4078e6af07471c3060b8e570bcd83cdd5f4685395" dependencies = [ "dashmap", "find-crate", @@ -2111,45 +2364,86 @@ dependencies = [ "i18n-embed", "lazy_static", "proc-macro-error", - "proc-macro2 1.0.34", - "quote 1.0.10", + "proc-macro2 1.0.70", + "quote 1.0.33", "strsim 0.10.0", - "syn 1.0.84", + "syn 2.0.39", "unic-langid", ] [[package]] name = "i18n-embed-impl" -version = "0.8.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db2330e035808eb064afb67e6743ddce353763af3e0f2bdfc2476e00ce76136" +checksum = "81093c4701672f59416582fe3145676126fd23ba5db910acad0793c1108aaa58" dependencies = [ "find-crate", "i18n-config", - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys 0.8.6", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", ] [[package]] name = "idna" -version = "0.2.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] [[package]] name = "indexmap" -version = "1.7.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg 1.0.1", - "hashbrown", + "autocfg 1.1.0", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", ] [[package]] @@ -2173,14 +2467,24 @@ dependencies = [ [[package]] name = "intl_pluralrules" -version = "7.0.1" +version = "7.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18f988384267d7066cc2be425e6faf352900652c046b6971d2e228d3b1c5ecf" +checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972" dependencies = [ - "tinystr", "unic-langid", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.3", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "iovec" version = "0.1.4" @@ -2192,15 +2496,35 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.3.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +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.25", + "windows-sys 0.48.0", +] [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" dependencies = [ "either", ] @@ -2212,10 +2536,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] -name = "js-sys" -version = "0.3.55" +name = "itoa" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -2235,11 +2565,11 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "18.0.0" +version = "17.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +checksum = "d4467ab6dfa369b69e52bd0692e480c4d117410538526a57a304a0f2250fd95e" dependencies = [ - "futures 0.3.17", + "futures 0.3.29", "futures-executor", "futures-util", "log", @@ -2250,25 +2580,25 @@ dependencies = [ [[package]] name = "jsonrpc-derive" -version = "18.0.0" +version = "17.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2" +checksum = "34f6326966ebac440db89eba788f5a0e5ac2614b4b4bfbdc049a971e71040f32" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", ] [[package]] name = "jsonrpc-http-server" -version = "18.0.0" +version = "17.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1dea6e07251d9ce6a552abfb5d7ad6bc290a4596c8dcc3d795fae2bbdc1f3ff" +checksum = "522a047cac0958097ee71d047dd71cb84979fd2fa21c7a68fbe12736bef870a2" dependencies = [ - "futures 0.3.17", - "hyper 0.14.14", - "jsonrpc-core 18.0.0", + "futures 0.3.29", + "hyper 0.13.10", + "jsonrpc-core 17.1.0", "jsonrpc-server-utils", "log", "net2", @@ -2278,27 +2608,29 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" -version = "18.0.0" +version = "17.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4" +checksum = "bce68fa279a2822b3619369cd024f8a4f8e5ce485468834f8679a3c7919aae2d" dependencies = [ - "bytes 1.1.0", - "futures 0.3.17", + "bytes 0.5.6", + "futures 0.3.29", "globset", - "jsonrpc-core 18.0.0", + "jsonrpc-core 17.1.0", "lazy_static", "log", - "tokio 1.12.0", - "tokio-stream", - "tokio-util 0.6.8", + "tokio 0.2.25", + "tokio-util 0.3.1", "unicase", ] [[package]] name = "keccak" -version = "0.1.0" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] [[package]] name = "kernel32-sys" @@ -2310,6 +2642,15 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2324,9 +2665,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.105" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "liblmdb-sys" @@ -2340,19 +2681,42 @@ dependencies = [ [[package]] name = "libloading" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if 1.0.0", "winapi 0.3.9", ] [[package]] -name = "linked-hash-map" -version = "0.5.4" +name = "libredox" +version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lmdb-zero" @@ -2377,21 +2741,22 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ + "autocfg 1.1.0", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" dependencies = [ - "cfg-if 1.0.0", "serde", + "value-bag", ] [[package]] @@ -2406,7 +2771,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4d8e6e1d5f89acca713132acc6034f30bad09b961d1338161bdb71c08f6e4fa" dependencies = [ - "arc-swap", + "arc-swap 0.4.8", "chrono", "flate2", "fnv", @@ -2434,17 +2799,11 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" -version = "2.4.1" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap" @@ -2458,24 +2817,24 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.3" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" dependencies = [ "mime", "unicase", @@ -2489,12 +2848,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", - "autocfg 1.0.1", ] [[package]] @@ -2518,15 +2876,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.14" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", - "log", - "miow 0.3.7", - "ntapi", - "winapi 0.3.9", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", ] [[package]] @@ -2577,56 +2933,67 @@ dependencies = [ name = "mwixnet" version = "0.1.0" dependencies = [ + "async-std", + "async-trait", "blake2-rfc", "byteorder", - "bytes 0.5.6", - "chacha20", + "bytes 1.5.0", + "chacha20 0.9.1", + "chrono", "clap", + "ctrlc", "curve25519-dalek 2.1.3", "dirs", "ed25519-dalek", "function_name", - "futures 0.3.17", - "grin_api 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_chain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_core 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_keychain 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", + "futures 0.3.29", + "grin_api", + "grin_chain", + "grin_core", + "grin_keychain", "grin_onion", + "grin_p2p", "grin_secp256k1zkp", "grin_servers", - "grin_store 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)", - "grin_util 5.1.1", + "grin_store", + "grin_util", "grin_wallet_api", + "grin_wallet_config", + "grin_wallet_controller", "grin_wallet_impls", "grin_wallet_libwallet", "grin_wallet_util", - "hmac 0.12.0", - "hyper 0.14.14", + "hmac 0.12.1", + "hyper 0.13.10", "hyper-proxy", - "itertools", - "jsonrpc-core 18.0.0", + "hyper-socks2", + "hyper-timeout", + "itertools 0.12.0", + "jsonrpc-core 17.1.0", "jsonrpc-derive", "jsonrpc-http-server", "lazy_static", + "log", "pbkdf2 0.8.0", "rand 0.7.3", + "remove_dir_all", "ring", "rpassword", "serde", "serde_derive", "serde_json", - "sha2 0.10.0", + "sha2 0.10.8", "thiserror", - "tokio 1.12.0", - "toml", + "tokio 0.2.25", + "toml 0.8.8", "x25519-dalek 0.6.0", ] [[package]] name = "native-tls" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", @@ -2635,22 +3002,44 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework 2.4.2", - "security-framework-sys 2.4.2", + "security-framework 2.9.2", + "security-framework-sys 2.9.1", "tempfile", ] [[package]] name = "net2" -version = "0.2.37" +version = "0.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" dependencies = [ "cfg-if 0.1.10", "libc", "winapi 0.3.9", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if 1.0.0", + "libc", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.1", + "cfg-if 1.0.0", + "libc", +] + [[package]] name = "nodrop" version = "0.1.14" @@ -2659,9 +3048,9 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "nom" -version = "5.1.2" +version = "5.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" dependencies = [ "memchr", "version_check", @@ -2669,20 +3058,28 @@ dependencies = [ [[package]] name = "nom" -version = "7.1.0" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", - "version_check", +] + +[[package]] +name = "normpath" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +dependencies = [ + "windows-sys 0.48.0", ] [[package]] name = "ntapi" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" dependencies = [ "winapi 0.3.9", ] @@ -2698,7 +3095,7 @@ dependencies = [ "num-integer", "num-iter", "num-rational", - "num-traits 0.2.14", + "num-traits 0.2.17", ] [[package]] @@ -2707,9 +3104,9 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-integer", - "num-traits 0.2.14", + "num-traits 0.2.17", ] [[package]] @@ -2718,29 +3115,29 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" dependencies = [ - "autocfg 1.0.1", - "num-traits 0.2.14", + "autocfg 1.1.0", + "num-traits 0.2.17", ] [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg 1.0.1", - "num-traits 0.2.14", + "autocfg 1.1.0", + "num-traits 0.2.17", ] [[package]] name = "num-iter" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-integer", - "num-traits 0.2.14", + "num-traits 0.2.17", ] [[package]] @@ -2749,10 +3146,10 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-bigint", "num-integer", - "num-traits 0.2.14", + "num-traits 0.2.17", ] [[package]] @@ -2761,33 +3158,33 @@ version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" dependencies = [ - "num-traits 0.2.14", + "num-traits 0.2.17", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.3", "libc", ] [[package]] name = "object" -version = "0.27.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -2800,9 +3197,9 @@ checksum = "4eae0151b9dacf24fcc170d9995e511669a082856a91f958a2fe380bfab3fb22" [[package]] name = "once_cell" -version = "1.8.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -2818,31 +3215,42 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.38" +version = "0.10.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "cfg-if 1.0.0", "foreign-types", "libc", "once_cell", + "openssl-macros", "openssl-sys", ] [[package]] -name = "openssl-probe" -version = "0.1.4" +name = "openssl-macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.72" +version = "0.9.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" dependencies = [ - "autocfg 1.0.1", "cc", "libc", "pkg-config", @@ -2855,9 +3263,15 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3305af35278dd29f46fcdd139e0b1fbfae2153f0e5928b39b035542dd31e37b7" dependencies = [ - "num-traits 0.2.14", + "num-traits 0.2.17", ] +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" version = "0.10.2" @@ -2865,7 +3279,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ "lock_api 0.3.4", - "parking_lot_core 0.7.2", + "parking_lot_core 0.7.3", ] [[package]] @@ -2875,15 +3289,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", - "lock_api 0.4.5", - "parking_lot_core 0.8.5", + "lock_api 0.4.11", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api 0.4.11", + "parking_lot_core 0.9.9", ] [[package]] name = "parking_lot_core" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +checksum = "b93f386bb233083c799e6e642a9d73db98c24a5deeb95ffc85bf281255dffc98" dependencies = [ "cfg-if 0.1.10", "cloudabi", @@ -2895,18 +3319,31 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.10", + "redox_syscall 0.2.16", "smallvec", "winapi 0.3.9", ] +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + [[package]] name = "password-hash" version = "0.2.3" @@ -2914,7 +3351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77e0b28ace46c5a396546bcf443bf422b57049617433d8854227352a4a9b24e7" dependencies = [ "base64ct", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -2928,16 +3365,16 @@ dependencies = [ "crypto-mac", "hmac 0.11.0", "password-hash", - "sha2 0.9.8", + "sha2 0.9.9", ] [[package]] name = "pbkdf2" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4628cc3cf953b82edcd3c1388c5715401420ce5524fedbab426bd5aba017434" +checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" dependencies = [ - "digest 0.10.1", + "digest 0.10.7", ] [[package]] @@ -2948,28 +3385,28 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.0.9" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1622113ce508488160cff04e6abc60960e676d330e1ca0f77c0b8df17c81438f" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.9" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95af56fee93df76d721d356ac1ca41fccf168bc448eb14049234df764ba3e76" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", ] [[package]] @@ -2980,9 +3417,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2991,10 +3428,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "pkg-config" -version = "0.3.24" +name = "piper" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg 1.1.0", + "bitflags 1.3.2", + "cfg-if 1.0.0", + "concurrent-queue", + "libc", + "log", + "pin-project-lite 0.2.13", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +dependencies = [ + "cfg-if 1.0.0", + "concurrent-queue", + "pin-project-lite 0.2.13", + "rustix 0.38.25", + "tracing", + "windows-sys 0.52.0", +] [[package]] name = "poly1305" @@ -3009,9 +3487,23 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettytable-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" +dependencies = [ + "csv", + "encode_unicode", + "is-terminal", + "lazy_static", + "term 0.7.0", + "unicode-width", +] [[package]] name = "proc-macro-crate" @@ -3019,7 +3511,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] @@ -3029,9 +3521,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", "version_check", ] @@ -3041,41 +3533,35 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", + "proc-macro2 1.0.70", + "quote 1.0.33", "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" dependencies = [ - "unicode-xid 0.1.0", + "unicode-xid", ] [[package]] name = "proc-macro2" -version = "1.0.34" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ - "unicode-xid 0.2.2", + "unicode-ident", ] +[[package]] +name = "qr_code" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5520fbcd7da152a449261c5a533a1c7fad044e9e8aa9528cfec3f464786c7926" + [[package]] name = "quick-error" version = "1.2.3" @@ -3093,11 +3579,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.10" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ - "proc-macro2 1.0.34", + "proc-macro2 1.0.70", ] [[package]] @@ -3119,7 +3605,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" dependencies = [ - "autocfg 0.1.7", + "autocfg 0.1.8", "libc", "rand_chacha 0.1.1", "rand_core 0.4.2", @@ -3153,7 +3639,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -3162,7 +3648,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" dependencies = [ - "autocfg 0.1.7", + "autocfg 0.1.8", "rand_core 0.3.1", ] @@ -3183,7 +3669,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -3212,11 +3698,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.11", ] [[package]] @@ -3277,7 +3763,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" dependencies = [ - "autocfg 0.1.7", + "autocfg 0.1.8", "rand_core 0.4.2", ] @@ -3292,27 +3778,22 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ - "autocfg 1.0.1", - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", - "num_cpus", ] [[package]] @@ -3332,28 +3813,50 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ - "getrandom 0.2.3", - "redox_syscall 0.2.10", + "getrandom 0.2.11", + "libredox", + "thiserror", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -3362,17 +3865,24 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "remove_dir_all" -version = "0.5.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "23895cfadc1917fed9c6ed76a8c2903615fa3704f7493ff82b364c6540acc02b" dependencies = [ - "winapi 0.3.9", + "aligned", + "cfg-if 1.0.0", + "cvt", + "fs_at", + "lazy_static", + "libc", + "normpath", + "windows-sys 0.45.0", ] [[package]] @@ -3381,7 +3891,7 @@ version = "0.10.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0718f81a8e14c4dbb3b34cf23dc6aaf9ab8a0dfec160c534b3dbca1aaa21f47c" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "bytes 0.5.6", "encoding_rs", "futures-core", @@ -3399,7 +3909,7 @@ dependencies = [ "mime_guess", "native-tls", "percent-encoding", - "pin-project-lite 0.2.7", + "pin-project-lite 0.2.13", "rustls 0.18.1", "serde", "serde_urlencoded", @@ -3453,9 +3963,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "6.3.0" +version = "6.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40377bff8cceee81e28ddb73ac97f5c2856ce5522f0b260b763f434cdfae602" +checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -3464,32 +3974,32 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "6.2.0" +version = "6.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e763e24ba2bf0c72bc6be883f967f794a019fafd1b86ba1daff9c91a7edd30" +checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", + "proc-macro2 1.0.70", + "quote 1.0.33", "rust-embed-utils", - "syn 1.0.84", + "syn 2.0.39", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "7.1.0" +version = "7.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad22c7226e4829104deab21df575e995bfbc4adfad13a595e387477f238c1aec" +checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" dependencies = [ - "sha2 0.9.8", + "sha2 0.10.8", "walkdir", ] [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -3503,6 +4013,33 @@ version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys 0.4.12", + "windows-sys 0.48.0", +] + [[package]] name = "rustls" version = "0.17.0" @@ -3542,10 +4079,16 @@ dependencies = [ ] [[package]] -name = "ryu" -version = "1.0.5" +name = "rustversion" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "safemem" @@ -3559,7 +4102,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686" dependencies = [ - "cipher", + "cipher 0.3.0", ] [[package]] @@ -3573,19 +4116,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "lazy_static", - "winapi 0.3.9", + "windows-sys 0.48.0", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scrypt" @@ -3593,10 +4135,10 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e73d6d7c6311ebdbd9184ad6c4447b2f36337e327bda107d3ba9e3c374f9d325" dependencies = [ - "hmac 0.12.0", - "pbkdf2 0.10.0", + "hmac 0.12.1", + "pbkdf2 0.10.1", "salsa20", - "sha2 0.10.0", + "sha2 0.10.8", ] [[package]] @@ -3642,15 +4184,15 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.4.2" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.2", - "core-foundation-sys 0.8.3", + "core-foundation 0.9.4", + "core-foundation-sys 0.8.6", "libc", - "security-framework-sys 2.4.2", + "security-framework-sys 2.9.1", ] [[package]] @@ -3665,25 +4207,34 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.4.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ - "core-foundation-sys 0.8.3", + "core-foundation-sys 0.8.6", "libc", ] [[package]] name = "self_cell" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" +checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d" +dependencies = [ + "self_cell 1.0.2", +] + +[[package]] +name = "self_cell" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e388332cd64eb80cd595a00941baf513caffae8dce9cfd0467fc9c66397dade6" [[package]] name = "serde" -version = "1.0.130" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] @@ -3700,59 +4251,68 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", ] [[package]] name = "serde_json" -version = "1.0.68" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ - "itoa", + "itoa 1.0.9", "ryu", "serde", ] [[package]] -name = "serde_urlencoded" -version = "0.7.0" +name = "serde_spanned" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa", + "itoa 1.0.9", "ryu", "serde", ] [[package]] name = "serde_yaml" -version = "0.8.21" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ - "dtoa", - "indexmap", + "indexmap 1.9.3", + "ryu", "serde", "yaml-rust 0.4.5", ] [[package]] name = "sha1" -version = "0.10.0" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cc229fb94bcb689ffc39bd4ded842f6ff76885efede7c6d1ffb62582878bea" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.1", + "digest 0.10.7", ] [[package]] @@ -3769,9 +4329,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -3782,13 +4342,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.0" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900d964dd36bb15bcf2f2b35694c072feab74969a54f2bbeec7a2d725d2bdcb6" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.1", + "digest 0.10.7", ] [[package]] @@ -3812,36 +4372,39 @@ checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "siphasher" -version = "0.3.7" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" -version = "0.4.5" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg 1.1.0", +] [[package]] name = "smallvec" -version = "1.7.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "socket2" @@ -3856,20 +4419,36 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.2" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" version = "0.8.0" @@ -3895,9 +4474,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" dependencies = [ "heck", - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", ] [[package]] @@ -3920,40 +4499,39 @@ checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" dependencies = [ "proc-macro2 0.4.30", "quote 0.6.13", - "unicode-xid 0.1.0", + "unicode-xid", ] [[package]] name = "syn" -version = "1.0.84" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "unicode-xid 0.2.2", + "proc-macro2 1.0.70", + "quote 1.0.33", + "unicode-ident", ] [[package]] -name = "synstructure" -version = "0.12.6" +name = "syn" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", - "unicode-xid 0.2.2", + "proc-macro2 1.0.70", + "quote 1.0.33", + "unicode-ident", ] [[package]] name = "sysinfo" -version = "0.14.15" +version = "0.29.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2983daff11a197c7c406b130579bc362177aa54cf2cc1f34d6ac88fccaa6a5e1" +checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" dependencies = [ - "cfg-if 0.1.10", - "doc-comment", + "cfg-if 1.0.0", + "core-foundation-sys 0.8.6", "libc", "ntapi", "once_cell", @@ -3963,23 +4541,43 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.2.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if 1.0.0", - "libc", - "rand 0.8.5", - "redox_syscall 0.2.10", - "remove_dir_all", + "fastrand 2.0.1", + "redox_syscall 0.4.1", + "rustix 0.38.25", + "windows-sys 0.48.0", +] + +[[package]] +name = "term" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" +dependencies = [ + "dirs", + "winapi 0.3.9", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", "winapi 0.3.9", ] [[package]] name = "termcolor" -version = "1.1.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -3995,22 +4593,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", ] [[package]] @@ -4024,16 +4622,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi 0.3.9", -] - [[package]] name = "timer" version = "0.2.0" @@ -4045,24 +4633,27 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.3.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29738eedb4388d9ea620eeab9384884fc3f06f586a2eddb56bedc5885126c7c1" +checksum = "83c02bf3c538ab32ba913408224323915f4ef9a6d61c0e85d493f355921c0ece" +dependencies = [ + "displaydoc", +] [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" @@ -4084,28 +4675,23 @@ dependencies = [ "pin-project-lite 0.1.12", "signal-hook-registry", "slab", - "tokio-macros 0.2.6", + "tokio-macros", "winapi 0.3.9", ] [[package]] name = "tokio" -version = "1.12.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ - "autocfg 1.0.1", - "bytes 1.1.0", + "backtrace", + "bytes 1.5.0", "libc", - "memchr", - "mio 0.7.14", - "num_cpus", - "once_cell", - "parking_lot 0.11.2", - "pin-project-lite 0.2.7", - "signal-hook-registry", - "tokio-macros 1.5.0", - "winapi 0.3.9", + "mio 0.8.9", + "pin-project-lite 0.2.13", + "socket2 0.5.5", + "windows-sys 0.48.0", ] [[package]] @@ -4124,30 +4710,19 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", -] - -[[package]] -name = "tokio-macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2dd85aeaba7b68df939bd357c6afb36c87951be9e80bf9c859f2fc3e9fca0fd" -dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", ] [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.12.0", + "tokio 1.34.0", ] [[package]] @@ -4182,22 +4757,11 @@ checksum = "d611fd5d241872372d52a0a3d309c52d0b95a6a67671a6c8f7ab2c4a37fb2539" dependencies = [ "bytes 0.4.12", "either", - "futures 0.3.17", + "futures 0.3.29", "thiserror", "tokio 0.2.25", ] -[[package]] -name = "tokio-stream" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" -dependencies = [ - "futures-core", - "pin-project-lite 0.2.7", - "tokio 1.12.0", -] - [[package]] name = "tokio-tls" version = "0.3.1" @@ -4236,54 +4800,73 @@ dependencies = [ "tokio 0.2.25", ] -[[package]] -name = "tokio-util" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd" -dependencies = [ - "bytes 1.1.0", - "futures-core", - "futures-sink", - "log", - "pin-project-lite 0.2.7", - "tokio 1.12.0", -] - [[package]] name = "toml" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] [[package]] -name = "tower-service" -version = "0.3.1" +name = "toml" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.29" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.7", + "pin-project-lite 0.2.13", "tracing-core", ] [[package]] name = "tracing-core" -version = "0.1.21" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] @@ -4304,9 +4887,9 @@ checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "type-map" @@ -4328,24 +4911,24 @@ dependencies = [ [[package]] name = "typenum" -version = "1.14.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unic-langid" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73328fcd730a030bdb19ddf23e192187a6b01cd98be6d3140622a89129459ce5" +checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f" dependencies = [ "unic-langid-impl", ] [[package]] name = "unic-langid-impl" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4a8eeaf0494862c1404c95ec2f4c33a2acff5076f64314b465e3ddae1b934d" +checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff" dependencies = [ "serde", "tinystr", @@ -4353,39 +4936,45 @@ dependencies = [ [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" @@ -4393,19 +4982,13 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "universal-hash" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.7", "subtle", ] @@ -4426,13 +5009,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -4442,10 +5024,16 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.11", "serde", ] +[[package]] +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" + [[package]] name = "vcpkg" version = "0.2.15" @@ -4460,28 +5048,32 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "walkdir" -version = "2.3.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", - "winapi 0.3.9", "winapi-util", ] [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -4493,15 +5085,15 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.78" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if 1.0.0", "serde", @@ -4511,24 +5103,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.78" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", - "lazy_static", "log", - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "once_cell", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.28" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -4538,38 +5130,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.78" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ - "quote 1.0.10", + "quote 1.0.33", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.78" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.78" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "web-sys" -version = "0.3.55" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -4633,9 +5225,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi 0.3.9", ] @@ -4646,6 +5238,222 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.7.0" @@ -4704,23 +5512,22 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.4.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.2.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.34", - "quote 1.0.10", - "syn 1.0.84", - "synstructure", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.39", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fbd4750..008dd4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,46 +9,57 @@ edition = "2021" members = ["onion"] [dependencies] +async-std = { version = "1", features = ["tokio02"] } +async-trait = "0.1.74" blake2 = { package = "blake2-rfc", version = "0.2"} byteorder = "1" -bytes = "0.5.6" -chacha20 = "0.8.1" +bytes = "1.5.0" +chacha20 = "0.9.1" +chrono = "0.4.31" clap = { version = "2.33", features = ["yaml"] } +ctrlc = { version = "3.1", features = ["termination"] } curve25519-dalek = "2.1" dirs = "2.0" ed25519-dalek = "1.0.1" function_name = "0.3.0" futures = "0.3" hmac = { version = "0.12.0", features = ["std"]} -hyper = { version = "0.14", features = ["full"] } +hyper = "0.13" hyper-proxy = "0.9.1" -itertools = { version = "0.10.3"} -jsonrpc-core = "18.0" -jsonrpc-derive = "18.0" -jsonrpc-http-server = "18.0" +hyper-socks2 = "0.5.0" +hyper-timeout = { version = "0.3", features = [] } +itertools = { version = "0.12.0" } +jsonrpc-core = "17.1" +jsonrpc-derive = "17.1" +jsonrpc-http-server = "17.1" lazy_static = "1" pbkdf2 = "0.8.0" rand = "0.7.3" +remove_dir_all = "0.8.2" ring = "0.16" rpassword = "4.0" serde = { version = "1", features= ["derive"]} serde_derive = "1" serde_json = "1" sha2 = "0.10.0" -thiserror = "1.0.31" -tokio = { version = "1", features = ["full"] } -toml = "0.5" +thiserror = "1.0.30" +tokio = { version = "0.2", features = ["full"] } +toml = "0.8.8" x25519-dalek = "0.6.0" grin_onion = { path = "./onion" } -grin_secp256k1zkp = { version = "0.7.11", features = ["bullet-proof-sizing"]} -grin_util = "5" -grin_api = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_core = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_chain = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_keychain = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_servers = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_store = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_wallet_api = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" } -grin_wallet_impls = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" } -grin_wallet_libwallet = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" } -grin_wallet_util = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" } \ No newline at end of file +grin_secp256k1zkp = { version = "0.7.12", features = ["bullet-proof-sizing"]} +grin_api = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_core = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_chain = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_keychain = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_p2p = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_servers = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_store = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_util = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_wallet_api = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +grin_wallet_config = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +grin_wallet_controller = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +grin_wallet_impls = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +grin_wallet_libwallet = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +grin_wallet_util = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +log = "0.4.20" \ No newline at end of file diff --git a/onion/Cargo.toml b/onion/Cargo.toml index 43a9e4b..1c5a143 100644 --- a/onion/Cargo.toml +++ b/onion/Cargo.toml @@ -21,18 +21,18 @@ serde = { version = "1", features= ["derive"]} serde_derive = "1" serde_json = "1" sha2 = "0.10.0" -thiserror = "1.0.31" +thiserror = "1" toml = "0.5" x25519-dalek = "0.6.0" -grin_secp256k1zkp = { version = "0.7.11", features = ["bullet-proof-sizing"]} -grin_util = "5" -grin_api = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_core = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_chain = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_keychain = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_servers = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_store = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" } -grin_wallet_api = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" } -grin_wallet_impls = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" } -grin_wallet_libwallet = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" } -grin_wallet_util = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" } \ No newline at end of file +grin_secp256k1zkp = { version = "0.7.12", features = ["bullet-proof-sizing"]} +grin_api = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_core = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_chain = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_keychain = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_servers = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_store = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_util = { git = "https://github.com/mimblewimble/grin", tag = "v5.2.0-beta.3" } +grin_wallet_api = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +grin_wallet_impls = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +grin_wallet_libwallet = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } +grin_wallet_util = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.2.0-beta.1" } \ No newline at end of file diff --git a/onion/src/crypto/dalek.rs b/onion/src/crypto/dalek.rs index 70c7654..ab107bc 100644 --- a/onion/src/crypto/dalek.rs +++ b/onion/src/crypto/dalek.rs @@ -162,7 +162,7 @@ pub fn sign(sk: &SecretKey, message: &[u8]) -> Result for OnionError { pub mod tests { use super::*; use crate::crypto::secp::random_secret; - use crate::{new_hop, Hop}; + use crate::{create_onion, new_hop, Hop}; use grin_core::core::FeeFields; @@ -376,7 +376,7 @@ pub mod tests { hops.push(hop); } - let mut onion_packet = test_util::create_onion(&commitment, &hops).unwrap(); + let mut onion_packet = create_onion(&commitment, &hops).unwrap(); let mut payload = Payload { next_ephemeral_pk: onion_packet.ephemeral_pubkey.clone(), diff --git a/onion/src/util.rs b/onion/src/util.rs index 99ae709..2b2f134 100644 --- a/onion/src/util.rs +++ b/onion/src/util.rs @@ -19,10 +19,10 @@ use grin_core::ser::{self, Readable, Reader, Writeable, Writer}; /// # Example /// /// ``` -/// let mut writer = vec![]; +/// let mut buf = vec![]; /// let optional_value: Option = Some(10); -/// write_optional(&mut writer, &optional_value); -/// assert_eq!(buf, &[1, 0, 0, 0, 10]); +/// grin_onion::util::write_optional(&mut grin_core::ser::BinWriter::default(&mut buf), &optional_value).unwrap(); +/// assert_eq!(&buf, &[1, 0, 0, 0, 10]); /// ``` pub fn write_optional( writer: &mut W, @@ -58,8 +58,8 @@ pub fn write_optional( /// /// ``` /// let mut buf: &[u8] = &[1, 0, 0, 0, 10]; -/// let mut reader = BinReader::new(&mut buf, ProtocolVersion::local(), DeserializationMode::default()); -/// let optional_value: Option = read_optional(&mut reader).unwrap(); +/// let mut reader = grin_core::ser::BinReader::new(&mut buf, grin_core::ser::ProtocolVersion::local(), grin_core::ser::DeserializationMode::default()); +/// let optional_value: Option = grin_onion::util::read_optional(&mut reader).unwrap(); /// assert_eq!(optional_value, Some(10)); /// ``` pub fn read_optional(reader: &mut R) -> Result, ser::Error> { @@ -87,7 +87,7 @@ pub fn read_optional(reader: &mut R) -> Result /// /// ``` /// let v = vec![0, 1, 2, 3, 4, 5]; -/// let a = vec_to_array::<4>(&v).unwrap(); +/// let a = grin_onion::util::vec_to_array::<4>(&v).unwrap(); /// assert_eq!(a, [0, 1, 2, 3]); /// ``` pub fn vec_to_array(vec: &Vec) -> Result<[u8; S], ser::Error> { diff --git a/src/main.rs b/src/bin/mwixnet.rs similarity index 81% rename from src/main.rs rename to src/bin/mwixnet.rs index fdf84bb..a02aa1c 100644 --- a/src/main.rs +++ b/src/bin/mwixnet.rs @@ -1,34 +1,28 @@ -use config::ServerConfig; -use node::HttpGrinNode; -use store::SwapStore; -use wallet::HttpWallet; +use mwixnet::config::{self, ServerConfig}; +use mwixnet::node::HttpGrinNode; +use mwixnet::servers; +use mwixnet::store::SwapStore; +use mwixnet::tor; +use mwixnet::wallet::HttpWallet; -use crate::client::{MixClient, MixClientImpl}; -use crate::node::GrinNode; -use crate::store::StoreError; use clap::App; use grin_core::global; use grin_core::global::ChainTypes; use grin_onion::crypto; use grin_onion::crypto::dalek::DalekPublicKey; use grin_util::{StopState, ZeroingString}; +use mwixnet::client::{MixClient, MixClientImpl}; +use mwixnet::node::GrinNode; +use mwixnet::store::StoreError; use rpassword; use std::path::PathBuf; use std::sync::Arc; -use tokio::runtime::Runtime; +use std::thread::{sleep, spawn}; +use std::time::Duration; #[macro_use] extern crate clap; -mod client; -mod config; -mod node; -mod servers; -mod store; -mod tor; -mod tx; -mod wallet; - const DEFAULT_INTERVAL: u32 = 12 * 60 * 60; fn main() -> Result<(), Box> { @@ -37,7 +31,7 @@ fn main() -> Result<(), Box> { } fn real_main() -> Result<(), Box> { - let yml = load_yaml!("../mwixnet.yml"); + let yml = load_yaml!("mwixnet.yml"); let args = App::from_yaml(yml).get_matches(); let chain_type = if args.is_present("testnet") { ChainTypes::Testnet @@ -168,18 +162,22 @@ fn real_main() -> Result<(), Box> { ); // Node API health check - if let Err(e) = node.get_chain_height() { + let mut rt = tokio::runtime::Builder::new() + .threaded_scheduler() + .enable_all() + .build()?; + if let Err(e) = rt.block_on(node.async_get_chain_height()) { eprintln!("Node communication failure. Is node listening?"); return Err(e.into()); }; // Open wallet let wallet_pass = prompt_wallet_password(&args.value_of("wallet_pass")); - let wallet = HttpWallet::open_wallet( + let wallet = rt.block_on(HttpWallet::async_open_wallet( &server_config.wallet_owner_url, &server_config.wallet_owner_api_secret(), &wallet_pass, - ); + )); let wallet = match wallet { Ok(w) => w, Err(e) => { @@ -188,12 +186,14 @@ fn real_main() -> Result<(), Box> { } }; - let mut tor_process = tor::init_tor_listener(&server_config)?; + let mut tor_process = tor::init_tor_listener( + &config::get_grin_path(&chain_type).to_str().unwrap(), + &server_config, + )?; let stop_state = Arc::new(StopState::new()); let stop_state_clone = stop_state.clone(); - let rt = Runtime::new()?; rt.spawn(async move { futures::executor::block_on(build_signals_fut()); let _ = tor_process.kill(); @@ -213,13 +213,26 @@ fn real_main() -> Result<(), Box> { server_config.server_pubkey().to_hex() ); - servers::mix_rpc::listen( + let (_, http_server) = servers::mix_rpc::listen( + rt.handle(), server_config, next_mixer, Arc::new(wallet), Arc::new(node), - stop_state, - ) + )?; + + let close_handle = http_server.close_handle(); + let round_handle = spawn(move || loop { + if stop_state.is_stopped() { + close_handle.close(); + break; + } + + sleep(Duration::from_millis(100)); + }); + + http_server.wait(); + round_handle.join().unwrap(); } else { println!( "Starting SWAP server with public key {:?}", @@ -237,15 +250,40 @@ fn real_main() -> Result<(), Box> { )?; // Start the mwixnet JSON-RPC HTTP 'swap' server - servers::swap_rpc::listen( - server_config, + let (swap_server, http_server) = servers::swap_rpc::listen( + rt.handle(), + &server_config, next_mixer, Arc::new(wallet), Arc::new(node), store, - stop_state, - ) + )?; + + let close_handle = http_server.close_handle(); + let round_handle = spawn(move || { + let mut secs = 0; + loop { + if stop_state.is_stopped() { + close_handle.close(); + break; + } + + sleep(Duration::from_secs(1)); + secs = (secs + 1) % server_config.interval_s; + + if secs == 0 { + let server = swap_server.clone(); + rt.spawn(async move { server.lock().await.execute_round().await }); + //let _ = swap_server.lock().unwrap().execute_round(); + } + } + }); + + http_server.wait(); + round_handle.join().unwrap(); } + + Ok(()) } #[cfg(unix)] diff --git a/mwixnet.yml b/src/bin/mwixnet.yml similarity index 100% rename from mwixnet.yml rename to src/bin/mwixnet.yml diff --git a/src/client.rs b/src/client.rs index 1785e26..42060dc 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,17 +1,17 @@ use crate::config::ServerConfig; -use crate::crypto::dalek; -use crate::servers::mix_rpc::MixReq; -use crate::tx::TxComponents; -use crate::{tor, DalekPublicKey}; +use crate::servers::mix_rpc::{MixReq, MixResp}; +use crate::tor; +use grin_onion::crypto::dalek::{self, DalekPublicKey}; use grin_onion::onion::Onion; -use grin_api::client; -use grin_api::json_rpc::build_request; +use async_trait::async_trait; +use grin_api::json_rpc::{build_request, Response}; use grin_core::ser; use grin_core::ser::ProtocolVersion; use grin_wallet_util::OnionV3Address; use hyper::client::HttpConnector; -use hyper_proxy::{Intercept, Proxy, ProxyConnector}; +use hyper::header::{ACCEPT, CONTENT_TYPE, USER_AGENT}; +use hyper_socks2::SocksConnector; use serde_json; use thiserror::Error; @@ -24,16 +24,19 @@ pub enum ClientError { API(grin_api::Error), #[error("Dalek Error: {0:?}")] Dalek(dalek::DalekError), - #[error("Error parsing response: {0:?}")] - ResponseParse(serde_json::Error), + #[error("Error decoding JSON response: {0:?}")] + DecodeResponseError(serde_json::Error), + #[error("Error in JSON-RPC response: {0:?}")] + ResponseError(grin_api::json_rpc::RpcError), #[error("Custom client error: {0:?}")] Custom(String), } /// A client for consuming a mix API +#[async_trait] pub trait MixClient: Send + Sync { /// Swaps the outputs provided and returns the final swapped outputs and kernels. - fn mix_outputs(&self, onions: &Vec) -> Result<(Vec, TxComponents), ClientError>; + async fn mix_outputs(&self, onions: &Vec) -> Result; } pub struct MixClientImpl { @@ -47,63 +50,104 @@ impl MixClientImpl { MixClientImpl { config, addr } } - fn send_json_request( + async fn async_send_json_request( &self, addr: &OnionV3Address, method: &str, params: &serde_json::Value, ) -> Result { - let _tor = tor::init_tor_sender(&self.config).map_err(ClientError::Tor)?; - let proxy = { - let proxy_uri = format!("http://{:?}", self.config.socks_proxy_addr) - .parse() - .unwrap(); - let proxy = Proxy::new(Intercept::All, proxy_uri); - //proxy.set_authorization(Authorization::basic("John Doe", "Agent1234")); - let connector = HttpConnector::new(); - let proxy_connector = ProxyConnector::from_proxy(connector, proxy).unwrap(); + let proxy_uri = format!( + "socks5://{}:{}", + self.config.socks_proxy_addr.ip(), + self.config.socks_proxy_addr.port() + ) + .parse() + .unwrap(); + let mut connector = HttpConnector::new(); + connector.enforce_http(false); + let proxy_connector = SocksConnector { + proxy_addr: proxy_uri, + auth: None, + connector, + }; proxy_connector }; let url = format!("{}/v1", addr.to_http_str()); - let mut req = client::create_post_request(&url, None, &build_request(method, params)) - .map_err(ClientError::API)?; - let uri = url.parse().unwrap(); - if let Some(headers) = proxy.http_headers(&uri) { - req.headers_mut().extend(headers.clone().into_iter()); + let body = + hyper::body::Body::from(serde_json::to_string(&build_request(method, params)).unwrap()); + + let req = hyper::Request::builder() + .method(hyper::Method::POST) + .uri(url) + .header(USER_AGENT, "grin-client") + .header(ACCEPT, "application/json") + .header(CONTENT_TYPE, "application/json") + .body(body) + .map_err(|e| { + ClientError::API(grin_api::Error::RequestError(format!( + "Cannot make request: {}", + e + ))) + })?; + + let client = hyper::Client::builder().build::<_, hyper::Body>(proxy); + let res = client.request(req).await.unwrap(); + + let body_bytes = hyper::body::to_bytes(res.into_body()).await.unwrap(); + let res = String::from_utf8(body_bytes.to_vec()).unwrap(); + + let response: Response = + serde_json::from_str(&res).map_err(ClientError::DecodeResponseError)?; + + if let Some(ref e) = response.error { + return Err(ClientError::ResponseError(e.clone())); } - let res = client::send_request(req).map_err(ClientError::API)?; + let result = match response.result.clone() { + Some(r) => serde_json::from_value(r).map_err(ClientError::DecodeResponseError), + None => serde_json::from_value(serde_json::Value::Null) + .map_err(ClientError::DecodeResponseError), + }?; - serde_json::from_str(&res).map_err(ClientError::ResponseParse) + Ok(result) } } +#[async_trait] impl MixClient for MixClientImpl { - fn mix_outputs(&self, onions: &Vec) -> Result<(Vec, TxComponents), ClientError> { + async fn mix_outputs(&self, onions: &Vec) -> Result { let serialized = ser::ser_vec(&onions, ProtocolVersion::local()).unwrap(); let sig = dalek::sign(&self.config.key, serialized.as_slice()).map_err(ClientError::Dalek)?; + // println!( + // "Created sig ({:?}) with public key ({}) for server ({})", + // &sig, + // DalekPublicKey::from_secret(&self.config.key).to_hex(), + // self.config.next_server.as_ref().unwrap().to_hex() + // ); let mix = MixReq::new(onions.clone(), sig); - let params = serde_json::json!(mix); + let params = serde_json::json!([mix]); - self.send_json_request::<(Vec, TxComponents)>(&self.addr, "mix", ¶ms) + self.async_send_json_request::(&self.addr, "mix", ¶ms) + .await } } #[cfg(test)] pub mod mock { use super::{ClientError, MixClient}; - use crate::tx::TxComponents; use grin_onion::onion::Onion; + use crate::servers::mix_rpc::MixResp; + use async_trait::async_trait; use std::collections::HashMap; pub struct MockMixClient { - results: HashMap, (Vec, TxComponents)>, + results: HashMap, MixResp>, } impl MockMixClient { @@ -113,16 +157,14 @@ pub mod mock { } } - pub fn set_response(&mut self, onions: &Vec, r: (Vec, TxComponents)) { + pub fn set_response(&mut self, onions: &Vec, r: MixResp) { self.results.insert(onions.clone(), r); } } + #[async_trait] impl MixClient for MockMixClient { - fn mix_outputs( - &self, - onions: &Vec, - ) -> Result<(Vec, TxComponents), ClientError> { + async fn mix_outputs(&self, onions: &Vec) -> Result { self.results .get(onions) .map(|r| Ok(r.clone())) @@ -134,13 +176,13 @@ pub mod mock { #[cfg(test)] pub mod test_util { use super::{ClientError, MixClient}; - use crate::crypto::dalek; - use crate::crypto::secp::SecretKey; use crate::servers::mix::MixServer; - use crate::tx::TxComponents; - use crate::DalekPublicKey; + use crate::servers::mix_rpc::MixResp; + use async_trait::async_trait; use grin_core::ser; use grin_core::ser::ProtocolVersion; + use grin_onion::crypto::dalek::{self, DalekPublicKey}; + use grin_onion::crypto::secp::SecretKey; use grin_onion::onion::Onion; use std::sync::Arc; @@ -152,11 +194,9 @@ pub mod test_util { pub mix_server: Arc, } + #[async_trait] impl MixClient for DirectMixClient { - fn mix_outputs( - &self, - onions: &Vec, - ) -> Result<(Vec, TxComponents), ClientError> { + async fn mix_outputs(&self, onions: &Vec) -> Result { let serialized = ser::ser_vec(&onions, ProtocolVersion::local()).unwrap(); let sig = dalek::sign(&self.key, serialized.as_slice()).map_err(ClientError::Dalek)?; @@ -165,7 +205,7 @@ pub mod test_util { serialized.as_slice(), ) .unwrap(); - Ok(self.mix_server.mix_outputs(&onions, &sig).unwrap()) + Ok(self.mix_server.mix_outputs(&onions, &sig).await.unwrap()) } } } diff --git a/src/config.rs b/src/config.rs index 1fab7dc..9c84383 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ -use crate::crypto::dalek::DalekPublicKey; -use crate::crypto::secp::SecretKey; +use grin_onion::crypto::dalek::DalekPublicKey; +use grin_onion::crypto::secp::SecretKey; use core::num::NonZeroU32; use grin_core::global::ChainTypes; @@ -39,10 +39,10 @@ pub struct ServerConfig { /// path to file containing secret for the grin wallet's owner api pub wallet_owner_secret_path: Option, /// public key of the previous mix/swap server (e.g. N_1 if this is N_2) - #[serde(with = "crate::crypto::dalek::option_dalek_pubkey_serde", default)] + #[serde(with = "grin_onion::crypto::dalek::option_dalek_pubkey_serde", default)] pub prev_server: Option, /// public key of the next mix server - #[serde(with = "crate::crypto::dalek::option_dalek_pubkey_serde", default)] + #[serde(with = "grin_onion::crypto::dalek::option_dalek_pubkey_serde", default)] pub next_server: Option, } @@ -186,9 +186,9 @@ struct RawConfig { grin_node_secret_path: Option, wallet_owner_url: SocketAddr, wallet_owner_secret_path: Option, - #[serde(with = "crate::crypto::dalek::option_dalek_pubkey_serde", default)] + #[serde(with = "grin_onion::crypto::dalek::option_dalek_pubkey_serde", default)] prev_server: Option, - #[serde(with = "crate::crypto::dalek::option_dalek_pubkey_serde", default)] + #[serde(with = "grin_onion::crypto::dalek::option_dalek_pubkey_serde", default)] next_server: Option, } @@ -289,7 +289,8 @@ pub fn wallet_owner_url(_chain_type: &ChainTypes) -> SocketAddr { #[cfg(test)] pub mod test_util { - use crate::{DalekPublicKey, ServerConfig}; + use crate::config::ServerConfig; + use grin_onion::crypto::dalek::DalekPublicKey; use secp256k1zkp::SecretKey; use std::net::TcpListener; @@ -317,7 +318,7 @@ pub mod test_util { #[cfg(test)] mod tests { use super::*; - use crate::crypto::secp; + use grin_onion::crypto::secp; #[test] fn server_key_encrypt() { diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..66d80f0 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,21 @@ +#[macro_use] +extern crate log; + +pub mod client; +pub mod config; +pub mod node; +pub mod servers; +pub mod store; +pub mod tor; +pub mod tx; +pub mod wallet; + +pub use client::MixClient; +pub use config::ServerConfig; +pub use node::{GrinNode, HttpGrinNode, NodeError}; +pub use servers::mix::{MixError, MixServer}; +pub use servers::mix_rpc::listen as mix_listen; +pub use servers::swap::{SwapError, SwapServer}; +pub use servers::swap_rpc::listen as swap_listen; +pub use store::{StoreError, SwapStore}; +pub use wallet::{HttpWallet, Wallet, WalletError}; diff --git a/src/node.rs b/src/node.rs index b8dc236..0220bc9 100644 --- a/src/node.rs +++ b/src/node.rs @@ -1,26 +1,42 @@ -use crate::crypto::secp::Commitment; +use grin_onion::crypto::secp::Commitment; -use grin_api::client; use grin_api::json_rpc::{build_request, Request, Response}; +use grin_api::{client, LocatedTxKernel}; use grin_api::{OutputPrintable, OutputType, Tip}; use grin_core::consensus::COINBASE_MATURITY; use grin_core::core::{Input, OutputFeatures, Transaction}; use grin_util::ToHex; +use async_trait::async_trait; use serde_json::json; use std::net::SocketAddr; use std::sync::Arc; use thiserror::Error; +#[async_trait] pub trait GrinNode: Send + Sync { /// Retrieves the unspent output with a matching commitment - fn get_utxo(&self, output_commit: &Commitment) -> Result, NodeError>; + async fn async_get_utxo( + &self, + output_commit: &Commitment, + ) -> Result, NodeError>; /// Gets the height of the chain tip - fn get_chain_height(&self) -> Result; + async fn async_get_chain_height(&self) -> Result; /// Posts a transaction to the grin node - fn post_tx(&self, tx: &Transaction) -> Result<(), NodeError>; + async fn async_post_tx(&self, tx: &Transaction) -> Result<(), NodeError>; + + /// Returns a LocatedTxKernel based on the kernel excess. + /// The min_height and max_height parameters are both optional. + /// If not supplied, min_height will be set to 0 and max_height will be set to the head of the chain. + /// The method will start at the block height max_height and traverse the kernel MMR backwards, until either the kernel is found or min_height is reached. + async fn async_get_kernel( + &self, + excess: &Commitment, + min_height: Option, + max_height: Option, + ) -> Result, NodeError>; } /// Error types for interacting with nodes @@ -35,18 +51,21 @@ pub enum NodeError { } /// Checks if a commitment is in the UTXO set -pub fn is_unspent(node: &Arc, commit: &Commitment) -> Result { - let utxo = node.get_utxo(&commit)?; +pub async fn async_is_unspent( + node: &Arc, + commit: &Commitment, +) -> Result { + let utxo = node.async_get_utxo(&commit).await?; Ok(utxo.is_some()) } /// Checks whether a commitment is spendable at the block height provided -pub fn is_spendable( +pub async fn async_is_spendable( node: &Arc, commit: &Commitment, next_block_height: u64, ) -> Result { - let output = node.get_utxo(&commit)?; + let output = node.async_get_utxo(&commit).await?; if let Some(out) = output { let is_coinbase = match out.output_type { OutputType::Coinbase => true, @@ -70,11 +89,11 @@ pub fn is_spendable( } /// Builds an input for an unspent output commitment -pub fn build_input( +pub async fn async_build_input( node: &Arc, output_commit: &Commitment, ) -> Result, NodeError> { - let output = node.get_utxo(&output_commit)?; + let output = node.async_get_utxo(&output_commit).await?; if let Some(out) = output { let features = match out.output_type { @@ -106,16 +125,20 @@ impl HttpGrinNode { } } - fn send_json_request( + async fn async_send_request( &self, method: &str, params: &serde_json::Value, ) -> Result { let url = format!("http://{}{}", self.node_url, ENDPOINT); let req = build_request(method, params); - let res = - client::post::(url.as_str(), self.node_api_secret.clone(), &req) - .map_err(NodeError::ApiCommError)?; + let res = client::post_async::( + url.as_str(), + &req, + self.node_api_secret.clone(), + ) + .await + .map_err(NodeError::ApiCommError)?; let parsed = res .clone() .into_result() @@ -124,8 +147,12 @@ impl HttpGrinNode { } } +#[async_trait] impl GrinNode for HttpGrinNode { - fn get_utxo(&self, output_commit: &Commitment) -> Result, NodeError> { + async fn async_get_utxo( + &self, + output_commit: &Commitment, + ) -> Result, NodeError> { let commits: Vec = vec![output_commit.to_hex()]; let start_height: Option = None; let end_height: Option = None; @@ -139,7 +166,9 @@ impl GrinNode for HttpGrinNode { include_proof, include_merkle_proof ]); - let outputs = self.send_json_request::>("get_outputs", ¶ms)?; + let outputs = self + .async_send_request::>("get_outputs", ¶ms) + .await?; if outputs.is_empty() { return Ok(None); } @@ -147,29 +176,54 @@ impl GrinNode for HttpGrinNode { Ok(Some(outputs[0].clone())) } - fn get_chain_height(&self) -> Result { + async fn async_get_chain_height(&self) -> Result { let params = json!([]); - let tip_json = self.send_json_request::("get_tip", ¶ms)?; + let tip_json = self + .async_send_request::("get_tip", ¶ms) + .await?; let tip = serde_json::from_value::(tip_json).map_err(NodeError::DecodeResponseError)?; Ok(tip.height) } - fn post_tx(&self, tx: &Transaction) -> Result<(), NodeError> { + async fn async_post_tx(&self, tx: &Transaction) -> Result<(), NodeError> { let params = json!([tx, true]); - self.send_json_request::("push_transaction", ¶ms)?; + self.async_send_request::("push_transaction", ¶ms) + .await?; Ok(()) } + + async fn async_get_kernel( + &self, + excess: &Commitment, + min_height: Option, + max_height: Option, + ) -> Result, NodeError> { + let params = json!([excess.0.as_ref().to_hex(), min_height, max_height]); + let value = self + .async_send_request::("get_kernel", ¶ms) + .await?; + + let contents = format!("{:?}", value); + if contents.contains("NotFound") { + return Ok(None); + } + + let located_kernel = serde_json::from_value::(value) + .map_err(NodeError::DecodeResponseError)?; + Ok(Some(located_kernel)) + } } #[cfg(test)] pub mod mock { use super::{GrinNode, NodeError}; - use crate::crypto::secp::Commitment; - use grin_api::{OutputPrintable, OutputType}; + use async_trait::async_trait; + use grin_api::{LocatedTxKernel, OutputPrintable, OutputType}; use grin_core::core::Transaction; + use grin_onion::crypto::secp::Commitment; use std::collections::HashMap; use std::sync::RwLock; @@ -178,6 +232,7 @@ pub mod mock { pub struct MockGrinNode { utxos: HashMap, txns_posted: RwLock>, + kernels: HashMap, } impl MockGrinNode { @@ -185,6 +240,7 @@ pub mod mock { MockGrinNode { utxos: HashMap::new(), txns_posted: RwLock::new(Vec::new()), + kernels: HashMap::new(), } } @@ -192,6 +248,7 @@ pub mod mock { let mut node = MockGrinNode { utxos: HashMap::new(), txns_posted: RwLock::new(Vec::new()), + kernels: HashMap::new(), }; for utxo in utxos { node.add_default_utxo(utxo); @@ -222,10 +279,16 @@ pub mod mock { let read = self.txns_posted.read().unwrap(); read.clone() } + + pub fn add_kernel(&mut self, kernel: &LocatedTxKernel) { + self.kernels + .insert(kernel.tx_kernel.excess.clone(), kernel.clone()); + } } + #[async_trait] impl GrinNode for MockGrinNode { - fn get_utxo( + async fn async_get_utxo( &self, output_commit: &Commitment, ) -> Result, NodeError> { @@ -236,14 +299,27 @@ pub mod mock { Ok(None) } - fn get_chain_height(&self) -> Result { + async fn async_get_chain_height(&self) -> Result { Ok(100) } - fn post_tx(&self, tx: &Transaction) -> Result<(), NodeError> { + async fn async_post_tx(&self, tx: &Transaction) -> Result<(), NodeError> { let mut write = self.txns_posted.write().unwrap(); write.push(tx.clone()); Ok(()) } + + async fn async_get_kernel( + &self, + excess: &Commitment, + _min_height: Option, + _max_height: Option, + ) -> Result, NodeError> { + if let Some(kernel) = self.kernels.get(&excess) { + return Ok(Some(kernel.clone())); + } + + Ok(None) + } } } diff --git a/src/servers/mix.rs b/src/servers/mix.rs index 4510521..31a3151 100644 --- a/src/servers/mix.rs +++ b/src/servers/mix.rs @@ -1,9 +1,12 @@ use crate::client::MixClient; use crate::config::ServerConfig; -use crate::tx::TxComponents; +use crate::node::{self, GrinNode}; +use crate::tx::{self, TxComponents}; use crate::wallet::Wallet; -use crate::{node, tx, GrinNode}; +use crate::servers::mix_rpc::MixResp; +use async_trait::async_trait; +use futures::stream::{self, StreamExt}; use grin_core::core::{Output, OutputFeatures, TransactionBody}; use grin_core::global::DEFAULT_ACCEPT_FEE_BASE; use grin_core::ser; @@ -47,13 +50,14 @@ pub enum MixError { } /// An internal MWixnet server - a "Mixer" +#[async_trait] pub trait MixServer: Send + Sync { /// Swaps the outputs provided and returns the final swapped outputs and kernels. - fn mix_outputs( + async fn mix_outputs( &self, onions: &Vec, sig: &DalekSignature, - ) -> Result<(Vec, TxComponents), MixError>; + ) -> Result; } /// The standard MWixnet "Mixer" implementation @@ -130,15 +134,19 @@ impl MixServerImpl { Ok(peeled) } - fn build_final_outputs( + async fn async_build_final_outputs( &self, peeled: &Vec<(usize, PeeledOnion)>, - ) -> Result<(Vec, TxComponents), MixError> { + ) -> Result { // Filter out commitments that already exist in the UTXO set - let filtered: Vec<&(usize, PeeledOnion)> = peeled - .iter() - .filter(|(_, p)| !node::is_unspent(&self.node, &p.onion.commit).unwrap_or(true)) - .collect(); + let filtered: Vec<&(usize, PeeledOnion)> = stream::iter(peeled.iter()) + .filter(|(_, p)| async { + !node::async_is_unspent(&self.node, &p.onion.commit) + .await + .unwrap_or(true) + }) + .collect() + .await; // Build plain outputs for each mix entry let outputs: Vec = filtered @@ -158,7 +166,7 @@ impl MixServerImpl { .map(|(_, p)| p.payload.excess.clone()) .collect(); - let components = tx::assemble_components( + let components = tx::async_assemble_components( &self.wallet, &TxComponents { offset: ZERO_KEY, @@ -169,17 +177,21 @@ impl MixServerImpl { self.get_fee_base(), fees_paid, ) + .await .map_err(MixError::TxError)?; let indices = filtered.iter().map(|(i, _)| *i).collect(); - Ok((indices, components)) + Ok(MixResp { + indices, + components, + }) } - fn call_next_mixer( + async fn call_next_mixer( &self, peeled: &Vec<(usize, PeeledOnion)>, - ) -> Result<(Vec, TxComponents), MixError> { + ) -> Result { // Sort by commitment let mut onions_with_index = peeled.clone(); onions_with_index @@ -191,15 +203,16 @@ impl MixServerImpl { // Call next server let onions = peeled.iter().map(|(_, p)| p.onion.clone()).collect(); - let (mixed_indices, mixed_components) = self + let mixed = self .mix_client .as_ref() .unwrap() .mix_outputs(&onions) + .await .map_err(MixError::Client)?; // Remove filtered entries - let kept_next_indices = HashSet::<_>::from_iter(mixed_indices.clone()); + let kept_next_indices = HashSet::<_>::from_iter(mixed.indices.clone()); let filtered_onions: Vec<&(usize, PeeledOnion)> = onions_with_index .iter() .filter(|(i, _)| { @@ -221,25 +234,30 @@ impl MixServerImpl { let indices = kept_next_indices.into_iter().sorted().collect(); - let components = tx::assemble_components( + let components = tx::async_assemble_components( &self.wallet, - &mixed_components, + &mixed.components, &excesses, self.get_fee_base(), fees_paid, ) + .await .map_err(MixError::TxError)?; - Ok((indices, components)) + Ok(MixResp { + indices, + components, + }) } } +#[async_trait] impl MixServer for MixServerImpl { - fn mix_outputs( + async fn mix_outputs( &self, onions: &Vec, sig: &DalekSignature, - ) -> Result<(Vec, TxComponents), MixError> { + ) -> Result { // Verify Signature let serialized = ser::ser_vec(&onions, ProtocolVersion::local()).unwrap(); sig.verify( @@ -252,10 +270,10 @@ impl MixServer for MixServerImpl { let mut peeled: Vec<(usize, PeeledOnion)> = onions .iter() .enumerate() - .filter_map(|(i, o)| { - if let Some(p) = self.peel_onion(&o).ok() { - Some((i, p)) - } else { + .filter_map(|(i, o)| match self.peel_onion(&o) { + Ok(p) => Some((i, p)), + Err(e) => { + println!("Error peeling onion: {:?}", e); None } }) @@ -271,9 +289,9 @@ impl MixServer for MixServerImpl { } if self.server_config.next_server.is_some() { - self.call_next_mixer(&peeled) + self.call_next_mixer(&peeled).await } else { - self.build_final_outputs(&peeled) + self.async_build_final_outputs(&peeled).await } } } @@ -281,11 +299,13 @@ impl MixServer for MixServerImpl { #[cfg(test)] mod test_util { use crate::client::test_util::DirectMixClient; + use crate::client::MixClient; + use crate::config; use crate::node::mock::MockGrinNode; - use crate::wallet::mock::MockWallet; - use crate::{config, DalekPublicKey, MixClient}; - use crate::servers::mix::MixServerImpl; + use crate::wallet::mock::MockWallet; + + use grin_onion::crypto::dalek::DalekPublicKey; use secp256k1zkp::SecretKey; use std::sync::Arc; @@ -320,10 +340,11 @@ mod test_util { #[cfg(test)] mod tests { + use crate::client::MixClient; use crate::node::mock::MockGrinNode; - use crate::{DalekPublicKey, MixClient}; use ::function_name::named; + use grin_onion::crypto::dalek::DalekPublicKey; use grin_onion::crypto::secp::{self, Commitment}; use grin_onion::test_util as onion_test_util; use grin_onion::{create_onion, new_hop, Hop}; @@ -373,9 +394,9 @@ mod tests { /// * Swap Server - Simulated by test /// * Mixer 1 - Internal MixServerImpl directly called by test /// * Mixer 2 - Final MixServerImpl called by Mixer 1 - #[test] + #[tokio::test] #[named] - fn mix_lifecycle() -> Result<(), Box> { + async fn mix_lifecycle() -> Result<(), Box> { init_test!(); // Setup Input(s) @@ -426,13 +447,15 @@ mod tests { // Simulate the swap server peeling the onion and then calling mix1 let mix1_onion = onion.peel_layer(&swap_vars.sk)?; - let (mixed_indices, mixed_components) = - mixer1_client.mix_outputs(&vec![mix1_onion.onion.clone()])?; + let mixed = mixer1_client + .mix_outputs(&vec![mix1_onion.onion.clone()]) + .await?; // Verify 3 outputs are returned: mixed output, mixer1's output, and mixer2's output - assert_eq!(mixed_indices, vec![0 as usize]); - assert_eq!(mixed_components.outputs.len(), 3); - let output_commits: HashSet = mixed_components + assert_eq!(mixed.indices, vec![0 as usize]); + assert_eq!(mixed.components.outputs.len(), 3); + let output_commits: HashSet = mixed + .components .outputs .iter() .map(|o| o.identifier.commit.clone()) diff --git a/src/servers/mix_rpc.rs b/src/servers/mix_rpc.rs index 7cb5181..fed8f14 100644 --- a/src/servers/mix_rpc.rs +++ b/src/servers/mix_rpc.rs @@ -1,19 +1,19 @@ use crate::client::MixClient; use crate::config::ServerConfig; -use crate::crypto::dalek::{self, DalekSignature}; use crate::node::GrinNode; use crate::servers::mix::{MixError, MixServer, MixServerImpl}; use crate::wallet::Wallet; +use crate::tx::TxComponents; +use futures::FutureExt; +use grin_onion::crypto::dalek::{self, DalekSignature}; use grin_onion::onion::Onion; -use grin_util::StopState; +use jsonrpc_core::BoxFuture; use jsonrpc_derive::rpc; use jsonrpc_http_server::jsonrpc_core::{self as jsonrpc, IoHandler}; use jsonrpc_http_server::{DomainsValidation, ServerBuilder}; use serde::{Deserialize, Serialize}; -use std::sync::{Arc, Mutex}; -use std::thread::{sleep, spawn}; -use std::time::Duration; +use std::sync::Arc; #[derive(Serialize, Deserialize)] pub struct MixReq { @@ -22,6 +22,12 @@ pub struct MixReq { sig: DalekSignature, } +#[derive(Clone, Serialize, Deserialize)] +pub struct MixResp { + pub indices: Vec, + pub components: TxComponents, +} + impl MixReq { pub fn new(onions: Vec, sig: DalekSignature) -> Self { MixReq { onions, sig } @@ -31,22 +37,23 @@ impl MixReq { #[rpc(server)] pub trait MixAPI { #[rpc(name = "mix")] - fn mix(&self, mix: MixReq) -> jsonrpc::Result; + fn mix(&self, mix: MixReq) -> BoxFuture>; } #[derive(Clone)] struct RPCMixServer { server_config: ServerConfig, - server: Arc>, + server: Arc>, } impl RPCMixServer { /// Spin up an instance of the JSON-RPC HTTP server. - fn start_http(&self) -> jsonrpc_http_server::Server { + fn start_http(&self, runtime_handle: tokio::runtime::Handle) -> jsonrpc_http_server::Server { let mut io = IoHandler::new(); io.extend_with(RPCMixServer::to_delegate(self.clone())); ServerBuilder::new(io) + .event_loop_executor(runtime_handle) .cors(DomainsValidation::Disabled) .request_middleware(|request: hyper::Request| { if request.uri() == "/v1" { @@ -67,50 +74,48 @@ impl From for jsonrpc::Error { } impl MixAPI for RPCMixServer { - fn mix(&self, mix: MixReq) -> jsonrpc::Result { - self.server - .lock() - .unwrap() - .mix_outputs(&mix.onions, &mix.sig)?; - Ok(jsonrpc::Value::String("success".into())) + fn mix(&self, mix: MixReq) -> BoxFuture> { + let server = self.server.clone(); + async move { + let response = server + .lock() + .await + .mix_outputs(&mix.onions, &mix.sig) + .await?; + Ok(response) + } + .boxed() } } /// Spin up the JSON-RPC web server pub fn listen( + rt_handle: &tokio::runtime::Handle, server_config: ServerConfig, next_server: Option>, wallet: Arc, node: Arc, - stop_state: Arc, -) -> Result<(), Box> { +) -> Result< + ( + Arc>, + jsonrpc_http_server::Server, + ), + Box, +> { let server = MixServerImpl::new( server_config.clone(), next_server, wallet.clone(), node.clone(), ); - let server = Arc::new(Mutex::new(server)); + let server = Arc::new(tokio::sync::Mutex::new(server)); let rpc_server = RPCMixServer { server_config: server_config.clone(), server: server.clone(), }; - let http_server = rpc_server.start_http(); + let http_server = rpc_server.start_http(rt_handle.clone()); - let close_handle = http_server.close_handle(); - let round_handle = spawn(move || loop { - if stop_state.is_stopped() { - close_handle.close(); - break; - } - - sleep(Duration::from_millis(100)); - }); - - http_server.wait(); - round_handle.join().unwrap(); - - Ok(()) + Ok((server, http_server)) } diff --git a/src/servers/swap.rs b/src/servers/swap.rs index a02095c..b811bea 100644 --- a/src/servers/swap.rs +++ b/src/servers/swap.rs @@ -1,21 +1,21 @@ use crate::client::MixClient; use crate::config::ServerConfig; -use crate::crypto::comsig::ComSignature; -use crate::crypto::secp::{Commitment, Secp256k1, SecretKey}; use crate::node::{self, GrinNode}; use crate::store::{StoreError, SwapData, SwapStatus, SwapStore}; use crate::tx; use crate::wallet::Wallet; -use grin_core::core::hash::Hashed; +use async_trait::async_trait; use grin_core::core::{Input, Output, OutputFeatures, Transaction, TransactionBody}; use grin_core::global::DEFAULT_ACCEPT_FEE_BASE; +use grin_onion::crypto::comsig::ComSignature; +use grin_onion::crypto::secp::{Commitment, Secp256k1, SecretKey}; use grin_onion::onion::{Onion, OnionError}; use itertools::Itertools; use secp256k1zkp::key::ZERO_KEY; use std::collections::HashSet; use std::result::Result; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use thiserror::Error; /// Swap error types @@ -39,20 +39,43 @@ pub enum SwapError { FeeTooLow { minimum_fee: u64, actual_fee: u64 }, #[error("Error saving swap to data store: {0}")] StoreError(StoreError), + #[error("Error building transaction: {0}")] + TxError(String), + #[error("Node communication error: {0}")] + NodeError(String), #[error("Client communication error: {0:?}")] ClientError(String), #[error("{0}")] UnknownError(String), } +impl From for SwapError { + fn from(e: StoreError) -> SwapError { + SwapError::StoreError(e) + } +} + +impl From for SwapError { + fn from(e: tx::TxError) -> SwapError { + SwapError::TxError(e.to_string()) + } +} + +impl From for SwapError { + fn from(e: node::NodeError) -> SwapError { + SwapError::NodeError(e.to_string()) + } +} + /// A public MWixnet server - the "Swap Server" +#[async_trait] pub trait SwapServer: Send + Sync { /// Submit a new output to be swapped. - fn swap(&self, onion: &Onion, comsig: &ComSignature) -> Result<(), SwapError>; + async fn swap(&self, onion: &Onion, comsig: &ComSignature) -> Result<(), SwapError>; /// Iterate through all saved submissions, filter out any inputs that are no longer spendable, /// and assemble the coinswap transaction, posting the transaction to the configured node. - fn execute_round(&self) -> Result, Box>; + async fn execute_round(&self) -> Result>, SwapError>; } /// The standard MWixnet server implementation @@ -62,7 +85,7 @@ pub struct SwapServerImpl { next_server: Option>, wallet: Arc, node: Arc, - store: Arc>, + store: Arc>, } impl SwapServerImpl { @@ -79,7 +102,7 @@ impl SwapServerImpl { next_server, wallet, node, - store: Arc::new(Mutex::new(store)), + store: Arc::new(tokio::sync::Mutex::new(store)), } } @@ -93,10 +116,29 @@ impl SwapServerImpl { fn get_minimum_swap_fee(&self) -> u64 { TransactionBody::weight_by_iok(1, 1, 1) * self.get_fee_base() } + + async fn async_is_spendable(&self, next_block_height: u64, swap: &SwapData) -> bool { + if let SwapStatus::Unprocessed = swap.status { + if node::async_is_spendable(&self.node, &swap.input.commit, next_block_height) + .await + .unwrap_or(false) + { + if !node::async_is_unspent(&self.node, &swap.output_commit) + .await + .unwrap_or(true) + { + return true; + } + } + } + + false + } } +#[async_trait] impl SwapServer for SwapServerImpl { - fn swap(&self, onion: &Onion, comsig: &ComSignature) -> Result<(), SwapError> { + async fn swap(&self, onion: &Onion, comsig: &ComSignature) -> Result<(), SwapError> { // Verify that more than 1 payload exists when there's a next server, // or that exactly 1 payload exists when this is the final server if self.server_config.next_server.is_some() && onion.enc_payloads.len() <= 1 @@ -114,7 +156,8 @@ impl SwapServer for SwapServerImpl { .map_err(|_| SwapError::InvalidComSignature)?; // Verify that commitment is unspent - let input = node::build_input(&self.node, &onion.commit) + let input = node::async_build_input(&self.node, &onion.commit) + .await .map_err(|e| SwapError::UnknownError(e.to_string()))?; let input = input.ok_or(SwapError::CoinNotFound { commit: onion.commit.clone(), @@ -144,7 +187,7 @@ impl SwapServer for SwapServerImpl { return Err(SwapError::MissingRangeproof); } - let locked = self.store.lock().unwrap(); + let locked = self.store.lock().await; locked .save_swap( @@ -168,23 +211,22 @@ impl SwapServer for SwapServerImpl { Ok(()) } - fn execute_round(&self) -> Result, Box> { - let locked_store = self.store.lock().unwrap(); - let next_block_height = self.node.get_chain_height()? + 1; + async fn execute_round(&self) -> Result>, SwapError> { + let next_block_height = self.node.async_get_chain_height().await? + 1; - let spendable: Vec = locked_store + let locked_store = self.store.lock().await; + let swaps: Vec = locked_store .swaps_iter()? .unique_by(|s| s.output_commit) - .filter(|s| match s.status { - SwapStatus::Unprocessed => true, - _ => false, - }) - .filter(|s| { - node::is_spendable(&self.node, &s.input.commit, next_block_height).unwrap_or(false) - }) - .filter(|s| !node::is_unspent(&self.node, &s.output_commit).unwrap_or(true)) - .sorted_by(|a, b| a.output_commit.partial_cmp(&b.output_commit).unwrap()) .collect(); + let mut spendable: Vec = vec![]; + for swap in &swaps { + if self.async_is_spendable(next_block_height, &swap).await { + spendable.push(swap.clone()); + } + } + + spendable.sort_by(|a, b| a.output_commit.partial_cmp(&b.output_commit).unwrap()); if spendable.len() == 0 { return Ok(None); @@ -193,12 +235,13 @@ impl SwapServer for SwapServerImpl { let (filtered, failed, offset, outputs, kernels) = if let Some(client) = &self.next_server { // Call next mix server let onions = spendable.iter().map(|s| s.onion.clone()).collect(); - let (indices, mixed) = client + let mixed = client .mix_outputs(&onions) + .await .map_err(|e| SwapError::ClientError(e.to_string()))?; // Filter out failed entries - let kept_indices = HashSet::<_>::from_iter(indices.clone()); + let kept_indices = HashSet::<_>::from_iter(mixed.indices.clone()); let filtered = spendable .iter() .enumerate() @@ -213,7 +256,13 @@ impl SwapServer for SwapServerImpl { .map(|(_, j)| j.clone()) .collect(); - (filtered, failed, mixed.offset, mixed.outputs, mixed.kernels) + ( + filtered, + failed, + mixed.components.offset, + mixed.components.outputs, + mixed.components.kernels, + ) } else { // Build plain outputs for each swap entry let outputs: Vec = spendable @@ -234,7 +283,7 @@ impl SwapServer for SwapServerImpl { let inputs: Vec = filtered.iter().map(|s| s.input).collect(); let output_excesses: Vec = filtered.iter().map(|s| s.excess.clone()).collect(); - let tx = tx::assemble_tx( + let tx = tx::async_assemble_tx( &self.wallet, &inputs, &outputs, @@ -243,14 +292,15 @@ impl SwapServer for SwapServerImpl { fees_paid, &offset, &output_excesses, - )?; + ) + .await?; - self.node.post_tx(&tx)?; + self.node.async_post_tx(&tx).await?; // Update status to in process - let kernel_hash = tx.kernels().first().unwrap().hash(); + let kernel_commit = tx.kernels().first().unwrap().excess; for mut swap in filtered { - swap.status = SwapStatus::InProcess { kernel_hash }; + swap.status = SwapStatus::InProcess { kernel_commit }; locked_store.save_swap(&swap, true)?; } @@ -260,16 +310,17 @@ impl SwapServer for SwapServerImpl { locked_store.save_swap(&swap, true)?; } - Ok(Some(tx)) + Ok(Some(Arc::new(tx))) } } #[cfg(test)] pub mod mock { use super::{SwapError, SwapServer}; - use crate::crypto::comsig::ComSignature; + use async_trait::async_trait; use grin_core::core::Transaction; + use grin_onion::crypto::comsig::ComSignature; use grin_onion::onion::Onion; use std::collections::HashMap; @@ -289,8 +340,9 @@ pub mod mock { } } + #[async_trait] impl SwapServer for MockSwapServer { - fn swap(&self, onion: &Onion, _comsig: &ComSignature) -> Result<(), SwapError> { + async fn swap(&self, onion: &Onion, _comsig: &ComSignature) -> Result<(), SwapError> { if let Some(e) = self.errors.get(&onion) { return Err(e.clone()); } @@ -298,7 +350,7 @@ pub mod mock { Ok(()) } - fn execute_round(&self) -> Result, Box> { + async fn execute_round(&self) -> Result>, SwapError> { Ok(None) } } @@ -306,11 +358,15 @@ pub mod mock { #[cfg(test)] pub mod test_util { - use crate::crypto::dalek::DalekPublicKey; - use crate::crypto::secp::SecretKey; + use crate::client::MixClient; + use crate::config; + use crate::node::GrinNode; use crate::servers::swap::SwapServerImpl; + use crate::store::SwapStore; use crate::wallet::mock::MockWallet; - use crate::{config, GrinNode, MixClient, SwapStore}; + + use grin_onion::crypto::dalek::DalekPublicKey; + use grin_onion::crypto::secp::SecretKey; use std::sync::Arc; pub fn new_swapper( @@ -339,14 +395,15 @@ pub mod test_util { #[cfg(test)] mod tests { + use crate::client::{self, MixClient}; use crate::node::mock::MockGrinNode; + use crate::servers::mix_rpc::MixResp; use crate::servers::swap::{SwapError, SwapServer}; use crate::store::{SwapData, SwapStatus}; + use crate::tx; use crate::tx::TxComponents; - use crate::{client, tx, MixClient}; use ::function_name::named; - use grin_core::core::hash::Hashed; use grin_core::core::{Committed, Input, Output, OutputFeatures, Transaction, Weighting}; use grin_onion::crypto::comsig::ComSignature; use grin_onion::crypto::secp; @@ -380,9 +437,9 @@ mod tests { } /// Standalone swap server to demonstrate request validation and onion unwrapping. - #[test] + #[tokio::test] #[named] - fn swap_standalone() -> Result<(), Box> { + async fn swap_standalone() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -400,7 +457,7 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new_with_utxos(&vec![&input_commit])); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - server.swap(&onion, &comsig)?; + server.swap(&onion, &comsig).await?; // Make sure entry is added to server. let expected = SwapData { @@ -418,21 +475,21 @@ mod tests { }; { - let store = server.store.lock().unwrap(); + let store = server.store.lock().await; assert_eq!(1, store.swaps_iter().unwrap().count()); assert!(store.swap_exists(&input_commit).unwrap()); assert_eq!(expected, store.get_swap(&input_commit).unwrap()); } - let tx = server.execute_round()?; + let tx = server.execute_round().await?; assert!(tx.is_some()); { // check that status was updated - let store = server.store.lock().unwrap(); + let store = server.store.lock().await; assert!(match store.get_swap(&input_commit)?.status { - SwapStatus::InProcess { kernel_hash } => - kernel_hash == tx.unwrap().kernels().first().unwrap().hash(), + SwapStatus::InProcess { kernel_commit } => + kernel_commit == tx.unwrap().kernels().first().unwrap().excess, _ => false, }); } @@ -451,9 +508,9 @@ mod tests { } /// Multi-server test to verify proper MixClient communication. - #[test] + #[tokio::test] #[named] - fn swap_multiserver() -> Result<(), Box> { + async fn swap_multiserver() -> Result<(), Box> { let test_dir = init_test!(); // Setup input @@ -498,7 +555,10 @@ mod tests { }; mock_mixer.set_response( &vec![mixer_onion.clone()], - (vec![0 as usize], mixer_response), + MixResp { + indices: vec![0 as usize], + components: mixer_response, + }, ); let mixer: Arc = Arc::new(mock_mixer); @@ -508,9 +568,9 @@ mod tests { Some((&mixer_pk, &mixer)), node.clone(), ); - swapper.swap(&onion, &comsig)?; + swapper.swap(&onion, &comsig).await?; - let tx = swapper.execute_round()?; + let tx = swapper.execute_round().await?; assert!(tx.is_some()); // check that the transaction was posted @@ -527,9 +587,9 @@ mod tests { } /// Returns InvalidPayloadLength when too many payloads are provided. - #[test] + #[tokio::test] #[named] - fn swap_too_many_payloads() -> Result<(), Box> { + async fn swap_too_many_payloads() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -549,22 +609,19 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new_with_utxos(&vec![&input_commit])); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - let result = server.swap(&onion, &comsig); + let result = server.swap(&onion, &comsig).await; assert_eq!(Err(SwapError::InvalidPayloadLength), result); // Make sure no entry is added to the store - assert_eq!( - 0, - server.store.lock().unwrap().swaps_iter().unwrap().count() - ); + assert_eq!(0, server.store.lock().await.swaps_iter().unwrap().count()); Ok(()) } /// Returns InvalidComSignature when ComSignature fails to verify. - #[test] + #[tokio::test] #[named] - fn swap_invalid_com_signature() -> Result<(), Box> { + async fn swap_invalid_com_signature() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -585,22 +642,19 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new_with_utxos(&vec![&input_commit])); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - let result = server.swap(&onion, &comsig); + let result = server.swap(&onion, &comsig).await; assert_eq!(Err(SwapError::InvalidComSignature), result); // Make sure no entry is added to the store - assert_eq!( - 0, - server.store.lock().unwrap().swaps_iter().unwrap().count() - ); + assert_eq!(0, server.store.lock().await.swaps_iter().unwrap().count()); Ok(()) } /// Returns InvalidRangeProof when the rangeproof fails to verify for the commitment. - #[test] + #[tokio::test] #[named] - fn swap_invalid_rangeproof() -> Result<(), Box> { + async fn swap_invalid_rangeproof() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -620,22 +674,19 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new_with_utxos(&vec![&input_commit])); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - let result = server.swap(&onion, &comsig); + let result = server.swap(&onion, &comsig).await; assert_eq!(Err(SwapError::InvalidRangeproof), result); // Make sure no entry is added to the store - assert_eq!( - 0, - server.store.lock().unwrap().swaps_iter().unwrap().count() - ); + assert_eq!(0, server.store.lock().await.swaps_iter().unwrap().count()); Ok(()) } /// Returns MissingRangeproof when no rangeproof is provided. - #[test] + #[tokio::test] #[named] - fn swap_missing_rangeproof() -> Result<(), Box> { + async fn swap_missing_rangeproof() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -652,22 +703,19 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new_with_utxos(&vec![&input_commit])); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - let result = server.swap(&onion, &comsig); + let result = server.swap(&onion, &comsig).await; assert_eq!(Err(SwapError::MissingRangeproof), result); // Make sure no entry is added to the store - assert_eq!( - 0, - server.store.lock().unwrap().swaps_iter().unwrap().count() - ); + assert_eq!(0, server.store.lock().await.swaps_iter().unwrap().count()); Ok(()) } /// Returns CoinNotFound when there's no matching output in the UTXO set. - #[test] + #[tokio::test] #[named] - fn swap_utxo_missing() -> Result<(), Box> { + async fn swap_utxo_missing() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -686,7 +734,7 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new()); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - let result = server.swap(&onion, &comsig); + let result = server.swap(&onion, &comsig).await; assert_eq!( Err(SwapError::CoinNotFound { commit: input_commit.clone() @@ -695,18 +743,15 @@ mod tests { ); // Make sure no entry is added to the store - assert_eq!( - 0, - server.store.lock().unwrap().swaps_iter().unwrap().count() - ); + assert_eq!(0, server.store.lock().await.swaps_iter().unwrap().count()); Ok(()) } /// Returns AlreadySwapped when trying to swap the same commitment multiple times. - #[test] + #[tokio::test] #[named] - fn swap_already_swapped() -> Result<(), Box> { + async fn swap_already_swapped() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -725,10 +770,10 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new_with_utxos(&vec![&input_commit])); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - server.swap(&onion, &comsig)?; + server.swap(&onion, &comsig).await?; // Call swap a second time - let result = server.swap(&onion, &comsig); + let result = server.swap(&onion, &comsig).await; assert_eq!( Err(SwapError::AlreadySwapped { commit: input_commit.clone() @@ -740,9 +785,9 @@ mod tests { } /// Returns PeelOnionFailure when a failure occurs trying to decrypt the onion payload. - #[test] + #[tokio::test] #[named] - fn swap_peel_onion_failure() -> Result<(), Box> { + async fn swap_peel_onion_failure() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -763,7 +808,7 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new_with_utxos(&vec![&input_commit])); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - let result = server.swap(&onion, &comsig); + let result = server.swap(&onion, &comsig).await; assert!(result.is_err()); assert_error_type!(result, SwapError::PeelOnionFailure(_)); @@ -772,9 +817,9 @@ mod tests { } /// Returns FeeTooLow when the minimum fee is not met. - #[test] + #[tokio::test] #[named] - fn swap_fee_too_low() -> Result<(), Box> { + async fn swap_fee_too_low() -> Result<(), Box> { let test_dir = init_test!(); let value: u64 = 200_000_000; @@ -793,7 +838,7 @@ mod tests { let node: Arc = Arc::new(MockGrinNode::new_with_utxos(&vec![&input_commit])); let (server, _) = super::test_util::new_swapper(&test_dir, &server_key, None, node.clone()); - let result = server.swap(&onion, &comsig); + let result = server.swap(&onion, &comsig).await; assert_eq!( Err(SwapError::FeeTooLow { minimum_fee: 12_500_000, diff --git a/src/servers/swap_rpc.rs b/src/servers/swap_rpc.rs index 788e4c1..77f91f3 100644 --- a/src/servers/swap_rpc.rs +++ b/src/servers/swap_rpc.rs @@ -5,17 +5,15 @@ use crate::servers::swap::{SwapError, SwapServer, SwapServerImpl}; use crate::store::SwapStore; use crate::wallet::Wallet; +use futures::FutureExt; use grin_onion::crypto::comsig::{self, ComSignature}; use grin_onion::onion::Onion; -use grin_util::StopState; use jsonrpc_core::Value; use jsonrpc_derive::rpc; use jsonrpc_http_server::jsonrpc_core::*; -use jsonrpc_http_server::*; +use jsonrpc_http_server::{DomainsValidation, ServerBuilder}; use serde::{Deserialize, Serialize}; -use std::sync::{Arc, Mutex}; -use std::thread::{sleep, spawn}; -use std::time::Duration; +use std::sync::Arc; #[derive(Serialize, Deserialize)] pub struct SwapReq { @@ -27,22 +25,23 @@ pub struct SwapReq { #[rpc(server)] pub trait SwapAPI { #[rpc(name = "swap")] - fn swap(&self, swap: SwapReq) -> jsonrpc_core::Result; + fn swap(&self, swap: SwapReq) -> BoxFuture>; } #[derive(Clone)] struct RPCSwapServer { server_config: ServerConfig, - server: Arc>, + server: Arc>, } impl RPCSwapServer { /// Spin up an instance of the JSON-RPC HTTP server. - fn start_http(&self) -> jsonrpc_http_server::Server { + fn start_http(&self, runtime_handle: tokio::runtime::Handle) -> jsonrpc_http_server::Server { let mut io = IoHandler::new(); io.extend_with(RPCSwapServer::to_delegate(self.clone())); ServerBuilder::new(io) + .event_loop_executor(runtime_handle) .cors(DomainsValidation::Disabled) .request_middleware(|request: hyper::Request| { if request.uri() == "/v1" { @@ -70,24 +69,31 @@ impl From for Error { } impl SwapAPI for RPCSwapServer { - fn swap(&self, swap: SwapReq) -> jsonrpc_core::Result { - self.server - .lock() - .unwrap() - .swap(&swap.onion, &swap.comsig)?; - Ok(Value::String("success".into())) + fn swap(&self, swap: SwapReq) -> BoxFuture> { + let server = self.server.clone(); + async move { + server.lock().await.swap(&swap.onion, &swap.comsig).await?; + Ok(Value::String("success".into())) + } + .boxed() } } /// Spin up the JSON-RPC web server pub fn listen( - server_config: ServerConfig, + rt_handle: &tokio::runtime::Handle, + server_config: &ServerConfig, next_server: Option>, wallet: Arc, node: Arc, store: SwapStore, - stop_state: Arc, -) -> std::result::Result<(), Box> { +) -> std::result::Result< + ( + Arc>, + jsonrpc_http_server::Server, + ), + Box, +> { let server = SwapServerImpl::new( server_config.clone(), next_server, @@ -95,54 +101,33 @@ pub fn listen( node.clone(), store, ); - let server = Arc::new(Mutex::new(server)); + let server = Arc::new(tokio::sync::Mutex::new(server)); let rpc_server = RPCSwapServer { server_config: server_config.clone(), server: server.clone(), }; - let http_server = rpc_server.start_http(); + let http_server = rpc_server.start_http(rt_handle.clone()); - let close_handle = http_server.close_handle(); - let round_handle = spawn(move || { - let mut secs = 0; - loop { - if stop_state.is_stopped() { - close_handle.close(); - break; - } - - sleep(Duration::from_secs(1)); - secs = (secs + 1) % server_config.interval_s; - - if secs == 0 { - let _ = server.lock().unwrap().execute_round(); - } - } - }); - - http_server.wait(); - round_handle.join().unwrap(); - - Ok(()) + Ok((server, http_server)) } #[cfg(test)] mod tests { use crate::config::ServerConfig; - use crate::crypto::comsig::ComSignature; - use crate::crypto::secp; use crate::servers::swap::mock::MockSwapServer; use crate::servers::swap::{SwapError, SwapServer}; use crate::servers::swap_rpc::{RPCSwapServer, SwapReq}; use grin_onion::create_onion; + use grin_onion::crypto::comsig::ComSignature; + use grin_onion::crypto::secp; use std::net::TcpListener; - use std::sync::{Arc, Mutex}; + use std::sync::Arc; use hyper::{Body, Client, Request, Response}; - use tokio::runtime::Runtime; + use tokio::sync::Mutex; async fn body_to_string(req: Response) -> String { let body_bytes = hyper::body::to_bytes(req.into_body()).await.unwrap(); @@ -150,10 +135,11 @@ mod tests { } /// Spin up a temporary web service, query the API, then cleanup and return response - fn make_request( - server: Arc>, + async fn async_make_request( + server: Arc>, req: String, - ) -> Result> { + runtime_handle: &tokio::runtime::Handle, + ) -> Result> { let server_config = ServerConfig { key: secp::random_secret(), interval_s: 1, @@ -173,28 +159,21 @@ mod tests { }; // Start the JSON-RPC server - let http_server = rpc_server.start_http(); + let http_server = rpc_server.start_http(runtime_handle.clone()); let uri = format!("http://{}/v1", server_config.addr); - let threaded_rt = Runtime::new()?; - let do_request = async move { - let request = Request::post(uri) - .header("Content-Type", "application/json") - .body(Body::from(req)) - .unwrap(); + let request = Request::post(uri) + .header("Content-Type", "application/json") + .body(Body::from(req)) + .unwrap(); - Client::new().request(request).await - }; + let response = Client::new().request(request).await?; - let response = threaded_rt.block_on(do_request)?; - let response_str: String = threaded_rt.block_on(body_to_string(response)); - - // Wait for shutdown - threaded_rt.shutdown_background(); + let response_str: String = body_to_string(response).await; // Execute one round - server.lock().unwrap().execute_round()?; + server.lock().await.execute_round().await?; // Stop the server http_server.close(); @@ -206,7 +185,11 @@ mod tests { /// Demonstrates a successful swap response #[test] - fn swap_success() -> Result<(), Box> { + fn swap_success() -> Result<(), Box> { + let mut rt = tokio::runtime::Builder::new() + .threaded_scheduler() + .enable_all() + .build()?; let commitment = secp::commit(1234, &secp::random_secret())?; let onion = create_onion(&commitment, &vec![])?; let comsig = ComSignature::sign(1234, &secp::random_secret(), &onion.serialize()?)?; @@ -221,7 +204,8 @@ mod tests { "{{\"jsonrpc\": \"2.0\", \"method\": \"swap\", \"params\": [{}], \"id\": \"1\"}}", serde_json::json!(swap) ); - let response = make_request(server, req)?; + let rt_handle = rt.handle().clone(); + let response = rt.block_on(async_make_request(server, req, &rt_handle))?; let expected = "{\"jsonrpc\":\"2.0\",\"result\":\"success\",\"id\":\"1\"}\n"; assert_eq!(response, expected); @@ -229,7 +213,11 @@ mod tests { } #[test] - fn swap_bad_request() -> Result<(), Box> { + fn swap_bad_request() -> Result<(), Box> { + let mut rt = tokio::runtime::Builder::new() + .threaded_scheduler() + .enable_all() + .build()?; let server: Arc> = Arc::new(Mutex::new(MockSwapServer::new())); let params = "{ \"param\": \"Not a valid Swap request\" }"; @@ -237,7 +225,8 @@ mod tests { "{{\"jsonrpc\": \"2.0\", \"method\": \"swap\", \"params\": [{}], \"id\": \"1\"}}", params ); - let response = make_request(server, req)?; + let rt_handle = rt.handle().clone(); + let response = rt.block_on(async_make_request(server, req, &rt_handle))?; let expected = "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32602,\"message\":\"Invalid params: missing field `onion`.\"},\"id\":\"1\"}\n"; assert_eq!(response, expected); Ok(()) @@ -245,7 +234,12 @@ mod tests { /// Returns "Commitment not found" when there's no matching output in the UTXO set. #[test] - fn swap_utxo_missing() -> Result<(), Box> { + fn swap_utxo_missing() -> Result<(), Box> { + let mut rt = tokio::runtime::Builder::new() + .threaded_scheduler() + .enable_all() + .build()?; + let commitment = secp::commit(1234, &secp::random_secret())?; let onion = create_onion(&commitment, &vec![])?; let comsig = ComSignature::sign(1234, &secp::random_secret(), &onion.serialize()?)?; @@ -267,7 +261,8 @@ mod tests { "{{\"jsonrpc\": \"2.0\", \"method\": \"swap\", \"params\": [{}], \"id\": \"1\"}}", serde_json::json!(swap) ); - let response = make_request(server, req)?; + let rt_handle = rt.handle().clone(); + let response = rt.block_on(async_make_request(server, req, &rt_handle))?; let expected = format!( "{{\"jsonrpc\":\"2.0\",\"error\":{{\"code\":-32602,\"message\":\"Output {:?} does not exist, or is already spent.\"}},\"id\":\"1\"}}\n", commitment diff --git a/src/store.rs b/src/store.rs index 2122cfc..39cbfba 100644 --- a/src/store.rs +++ b/src/store.rs @@ -21,8 +21,13 @@ const SWAP_PREFIX: u8 = b'S'; #[derive(Clone, Debug, PartialEq)] pub enum SwapStatus { Unprocessed, - InProcess { kernel_hash: Hash }, - Completed { kernel_hash: Hash, block_hash: Hash }, + InProcess { + kernel_commit: Commitment, + }, + Completed { + kernel_commit: Commitment, + block_hash: Hash, + }, Failed, } @@ -32,16 +37,16 @@ impl Writeable for SwapStatus { SwapStatus::Unprocessed => { writer.write_u8(0)?; } - SwapStatus::InProcess { kernel_hash } => { + SwapStatus::InProcess { kernel_commit } => { writer.write_u8(1)?; - kernel_hash.write(writer)?; + kernel_commit.write(writer)?; } SwapStatus::Completed { - kernel_hash, + kernel_commit, block_hash, } => { writer.write_u8(2)?; - kernel_hash.write(writer)?; + kernel_commit.write(writer)?; block_hash.write(writer)?; } SwapStatus::Failed => { @@ -58,14 +63,14 @@ impl Readable for SwapStatus { let status = match reader.read_u8()? { 0 => SwapStatus::Unprocessed, 1 => { - let kernel_hash = Hash::read(reader)?; - SwapStatus::InProcess { kernel_hash } + let kernel_commit = Commitment::read(reader)?; + SwapStatus::InProcess { kernel_commit } } 2 => { - let kernel_hash = Hash::read(reader)?; + let kernel_commit = Commitment::read(reader)?; let block_hash = Hash::read(reader)?; SwapStatus::Completed { - kernel_hash, + kernel_commit, block_hash, } } @@ -244,8 +249,7 @@ impl SwapStore { #[cfg(test)] mod tests { - use crate::store::{SwapData, SwapStatus, SwapStore}; - use crate::StoreError; + use crate::store::{StoreError, SwapData, SwapStatus, SwapStore}; use grin_core::core::{Input, OutputFeatures}; use grin_core::global::{self, ChainTypes}; use grin_onion::crypto::secp; @@ -278,11 +282,11 @@ mod tests { SwapStatus::Unprocessed } else if s == 1 { SwapStatus::InProcess { - kernel_hash: onion_test_util::rand_hash(), + kernel_commit: onion_test_util::rand_commit(), } } else { SwapStatus::Completed { - kernel_hash: onion_test_util::rand_hash(), + kernel_commit: onion_test_util::rand_commit(), block_hash: onion_test_util::rand_hash(), } }; @@ -330,7 +334,7 @@ mod tests { assert!(store.swap_exists(&swap.input.commit)?); swap.status = SwapStatus::InProcess { - kernel_hash: onion_test_util::rand_hash(), + kernel_commit: onion_test_util::rand_commit(), }; let result = store.save_swap(&swap, false); assert_eq!( diff --git a/src/tor.rs b/src/tor.rs index dfbcb72..37ac860 100644 --- a/src/tor.rs +++ b/src/tor.rs @@ -1,6 +1,5 @@ -use crate::config::{self, ServerConfig}; +use crate::config::ServerConfig; -use grin_core::global; use grin_wallet_impls::tor::config as tor_config; use grin_wallet_impls::tor::process::TorProcess; use std::collections::HashMap; @@ -10,72 +9,96 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum TorError { #[error("Error generating config: {0:?}")] - ConfigError(String), + ConfigError(grin_wallet_impls::Error), #[error("Error starting process: {0:?}")] ProcessError(grin_wallet_impls::tor::process::Error), } -pub fn init_tor_listener(server_config: &ServerConfig) -> Result { - println!("Initializing tor listener"); +pub fn init_tor_listener( + data_dir: &str, + server_config: &ServerConfig, +) -> Result { + warn!("Initializing tor listener"); - let mut tor_dir = config::get_grin_path(&global::get_chain_type()); - tor_dir.push("tor/listener"); + let tor_dir = format!("{}/tor/listener", &data_dir); + trace!( + "Dir: {}, Proxy: {}", + &tor_dir, + server_config.socks_proxy_addr.to_string() + ); - let mut torrc_dir = tor_dir.clone(); - torrc_dir.push("torrc"); + // create data directory if it doesn't exist + std::fs::create_dir_all(&format!("{}/data", tor_dir)).unwrap(); - tor_config::output_tor_listener_config( - tor_dir.to_str().unwrap(), + let service_dir = tor_config::output_onion_service_config(tor_dir.as_str(), &server_config.key) + .map_err(|e| TorError::ConfigError(e))?; + let service_dirs = vec![service_dir.to_string()]; + + tor_config::output_torrc( + tor_dir.as_str(), server_config.addr.to_string().as_str(), - &vec![server_config.key.clone()], + &server_config.socks_proxy_addr.to_string(), + &service_dirs, HashMap::new(), HashMap::new(), ) - .map_err(|e| TorError::ConfigError(e.to_string()))?; + .map_err(|e| TorError::ConfigError(e))?; // Start TOR process let mut process = TorProcess::new(); process - .torrc_path(torrc_dir.to_str().unwrap()) - .working_dir(tor_dir.to_str().unwrap()) - .timeout(20) - .completion_percent(100) - .launch() - .map_err(TorError::ProcessError)?; + .torrc_path("./torrc") + .working_dir(tor_dir.as_str()) + .timeout(30) + .completion_percent(100); - println!( + let mut attempts = 0; + let max_attempts = 3; + let mut result; + + loop { + attempts += 1; + info!("Launching TorProcess... Attempt {}", attempts); + result = process.launch(); + + if result.is_ok() || attempts >= max_attempts { + break; + } + } + + result.map_err(TorError::ProcessError)?; + + warn!( "Server listening at http://{}.onion", server_config.onion_address().to_ov3_str() ); Ok(process) } -pub fn init_tor_sender(server_config: &ServerConfig) -> Result { - println!( +pub fn init_tor_sender( + data_dir: &str, + server_config: &ServerConfig, +) -> Result { + warn!( "Starting TOR Process for send at {:?}", server_config.socks_proxy_addr ); - let mut tor_dir = config::get_grin_path(&global::get_chain_type()); - tor_dir.push("tor/sender"); - - let mut torrc_dir = tor_dir.clone(); - torrc_dir.push("torrc"); - + let tor_dir = format!("{}/tor/sender", data_dir); tor_config::output_tor_sender_config( - tor_dir.to_str().unwrap(), + tor_dir.as_str(), &server_config.socks_proxy_addr.to_string(), HashMap::new(), HashMap::new(), ) - .map_err(|e| TorError::ConfigError(e.to_string()))?; + .map_err(|e| TorError::ConfigError(e))?; // Start TOR process let mut tor_process = TorProcess::new(); tor_process - .torrc_path(torrc_dir.to_str().unwrap()) - .working_dir(tor_dir.to_str().unwrap()) - .timeout(20) + .torrc_path("./torrc") + .working_dir(tor_dir.as_str()) + .timeout(40) .completion_percent(100) .launch() .map_err(TorError::ProcessError)?; diff --git a/src/tx.rs b/src/tx.rs index 73ca7fd..4e11a5f 100644 --- a/src/tx.rs +++ b/src/tx.rs @@ -1,10 +1,10 @@ -use crate::crypto::secp; use crate::wallet::Wallet; use grin_core::core::{ FeeFields, Input, Inputs, KernelFeatures, Output, Transaction, TransactionBody, TxKernel, }; use grin_keychain::BlindingFactor; +use grin_onion::crypto::secp; use secp256k1zkp::{ContextFlag, Secp256k1, SecretKey}; use serde::{Deserialize, Serialize}; use std::sync::Arc; @@ -43,7 +43,7 @@ pub struct TxComponents { } /// Builds and verifies the finalized swap 'Transaction' using the provided components. -pub fn assemble_tx( +pub async fn async_assemble_tx( wallet: &Arc, inputs: &Vec, outputs: &Vec, @@ -57,7 +57,7 @@ pub fn assemble_tx( let min_kernel_fee = TransactionBody::weight_by_iok(inputs.len() as u64, outputs.len() as u64, 1) * fee_base; - let components = add_kernel_and_collect_fees( + let components = async_add_kernel_and_collect_fees( &wallet, &outputs, &kernels, @@ -66,7 +66,8 @@ pub fn assemble_tx( fees_paid, &prev_offset, &output_excesses, - )?; + ) + .await?; // assemble the transaction let tx = Transaction::new( @@ -79,7 +80,7 @@ pub fn assemble_tx( } /// Adds a kernel and output to a collection of transaction components to consume fees and offset excesses. -pub fn assemble_components( +pub async fn async_assemble_components( wallet: &Arc, components: &TxComponents, output_excesses: &Vec, @@ -89,7 +90,7 @@ pub fn assemble_components( // calculate minimum fee required for the kernel let min_kernel_fee = TransactionBody::weight_by_iok(0, 0, 1) * fee_base; - add_kernel_and_collect_fees( + async_add_kernel_and_collect_fees( &wallet, &components.outputs, &components.kernels, @@ -99,9 +100,10 @@ pub fn assemble_components( &components.offset, &output_excesses, ) + .await } -fn add_kernel_and_collect_fees( +async fn async_add_kernel_and_collect_fees( wallet: &Arc, outputs: &Vec, kernels: &Vec, @@ -128,7 +130,10 @@ fn add_kernel_and_collect_fees( let amount = fees_paid - (min_kernel_fee + fee_to_collect); kernel_fee -= amount; - let wallet_output = wallet.build_output(amount).map_err(TxError::WalletError)?; + let wallet_output = wallet + .async_build_output(amount) + .await + .map_err(TxError::WalletError)?; txn_outputs.push(wallet_output.1); let output_excess = SecretKey::from_slice(&secp, &wallet_output.0.as_ref()) @@ -202,11 +207,12 @@ fn add_kernel_and_collect_fees( /// /// ```rust /// use secp256k1zkp::key::SecretKey; -/// use crate::crypto::secp; +/// use secp256k1zkp::rand::thread_rng; +/// use grin_onion::crypto::secp; /// -/// let secret_key = SecretKey::new(&mut secp::rand::thread_rng()); +/// let secret_key = secp::random_secret(); /// let fee = 10; // 10 nanogrin -/// let kernel = build_kernel(&secret_key, fee); +/// let kernel = mwixnet::tx::build_kernel(&secret_key, fee); /// ``` pub fn build_kernel(excess: &SecretKey, fee: u64) -> Result { let mut kernel = TxKernel::with_features(KernelFeatures::Plain { diff --git a/src/wallet.rs b/src/wallet.rs index 74395c1..52c29f0 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -1,10 +1,10 @@ -use crate::crypto::secp; - +use async_trait::async_trait; use grin_api::client; -use grin_api::json_rpc::{build_request, Request, Response}; +use grin_api::json_rpc::{build_request, Request, Response, RpcError}; use grin_core::core::Output; use grin_core::libtx::secp_ser; use grin_keychain::BlindingFactor; +use grin_onion::crypto::secp; use grin_util::{ToHex, ZeroingString}; use grin_wallet_api::{EncryptedRequest, EncryptedResponse, JsonId, Token}; use secp256k1zkp::{PublicKey, Secp256k1, SecretKey}; @@ -13,9 +13,13 @@ use serde_json::json; use std::net::SocketAddr; use thiserror::Error; +#[async_trait] pub trait Wallet: Send + Sync { /// Builds an output for the wallet with the provided amount. - fn build_output(&self, amount: u64) -> Result<(BlindingFactor, Output), WalletError>; + async fn async_build_output( + &self, + amount: u64, + ) -> Result<(BlindingFactor, Output), WalletError>; } /// Error types for interacting with wallets @@ -31,6 +35,8 @@ pub enum WalletError { ApiCommError(grin_api::Error), #[error("Error decoding JSON-RPC response: {0:?}")] ResponseParseError(grin_api::json_rpc::Error), + #[error("Unsucessful response returned: {0:?}")] + ResponseRpcError(Option), } /// HTTP (JSONRPC) implementation of the 'Wallet' trait. @@ -55,26 +61,27 @@ pub struct ECDHPubkey { impl HttpWallet { /// Calls the 'open_wallet' using the RPC API. - pub fn open_wallet( + pub async fn async_open_wallet( wallet_owner_url: &SocketAddr, wallet_owner_secret: &Option, wallet_pass: &ZeroingString, ) -> Result { - println!("Opening wallet at {}", wallet_owner_url); - let shared_key = HttpWallet::init_secure_api(&wallet_owner_url, &wallet_owner_secret)?; - + info!("Opening wallet at {}", wallet_owner_url); + let shared_key = + HttpWallet::async_init_secure_api(&wallet_owner_url, &wallet_owner_secret).await?; let open_wallet_params = json!({ "name": null, "password": wallet_pass.to_string() }); - let token: Token = HttpWallet::send_enc_request( + let token: Token = HttpWallet::async_send_enc_request( &wallet_owner_url, &wallet_owner_secret, "open_wallet", &open_wallet_params, &shared_key, - )?; - println!("Connected to wallet"); + ) + .await?; + info!("Connected to wallet"); Ok(HttpWallet { wallet_owner_url: wallet_owner_url.clone(), @@ -84,7 +91,7 @@ impl HttpWallet { }) } - fn init_secure_api( + async fn async_init_secure_api( wallet_owner_url: &SocketAddr, wallet_owner_secret: &Option, ) -> Result { @@ -95,12 +102,13 @@ impl HttpWallet { "ecdh_pubkey": ephemeral_pk.serialize_vec(&secp, true).to_hex() }); - let response_pk: ECDHPubkey = HttpWallet::send_json_request( + let response_pk: ECDHPubkey = HttpWallet::async_send_json_request( &wallet_owner_url, &wallet_owner_secret, "init_secure_api", &init_params, - )?; + ) + .await?; let shared_key = { let mut shared_pubkey = response_pk.ecdh_pubkey.clone(); @@ -113,7 +121,22 @@ impl HttpWallet { Ok(shared_key) } - fn send_enc_request( + pub async fn async_perform_request( + &self, + method: &str, + params: &serde_json::Value, + ) -> Result { + HttpWallet::async_send_enc_request( + &self.wallet_owner_url, + &self.wallet_owner_secret, + method, + params, + &self.shared_key, + ) + .await + } + + async fn async_send_enc_request( wallet_owner_url: &SocketAddr, wallet_owner_secret: &Option, method: &str, @@ -129,23 +152,30 @@ impl HttpWallet { }); let enc_req = EncryptedRequest::from_json(&JsonId::IntId(1), &req, &shared_key) .map_err(WalletError::EncryptRequestError)?; - let res = client::post::( + let res = client::post_async::( url.as_str(), - wallet_owner_secret.clone(), &enc_req, + wallet_owner_secret.clone(), ) + .await .map_err(WalletError::ApiCommError)?; let decrypted = res .decrypt(&shared_key) .map_err(WalletError::DecryptResponseError)?; let response: Response = serde_json::from_value(decrypted).map_err(WalletError::DecodeResponseError)?; - let ok = response.result.unwrap().get("Ok").unwrap().clone(); - let parsed = serde_json::from_value(ok).map_err(WalletError::DecodeResponseError)?; + let result = response + .result + .ok_or(WalletError::ResponseRpcError(response.error.clone()))?; + let ok = result + .get("Ok") + .ok_or(WalletError::ResponseRpcError(response.error.clone()))?; + let parsed = + serde_json::from_value(ok.clone()).map_err(WalletError::DecodeResponseError)?; Ok(parsed) } - fn send_json_request( + async fn async_send_json_request( wallet_owner_url: &SocketAddr, wallet_owner_secret: &Option, method: &str, @@ -153,15 +183,23 @@ impl HttpWallet { ) -> Result { let url = format!("http://{}{}", wallet_owner_url, ENDPOINT); let req = build_request(method, params); - let res = - client::post::(url.as_str(), wallet_owner_secret.clone(), &req) - .map_err(WalletError::ApiCommError)?; + let res = client::post_async::( + url.as_str(), + &req, + wallet_owner_secret.clone(), + ) + .await + .map_err(WalletError::ApiCommError)?; let parsed = res .clone() .into_result() .map_err(WalletError::ResponseParseError)?; Ok(parsed) } + + pub fn get_token(&self) -> Token { + self.token.clone() + } } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -174,21 +212,26 @@ pub struct OutputWithBlind { output: Output, } +#[async_trait] impl Wallet for HttpWallet { /// Builds an 'Output' for the wallet using the 'build_output' RPC API. - fn build_output(&self, amount: u64) -> Result<(BlindingFactor, Output), WalletError> { + async fn async_build_output( + &self, + amount: u64, + ) -> Result<(BlindingFactor, Output), WalletError> { let req_json = json!({ - "token": self.token.keychain_mask.clone().unwrap().0, + "token": self.token, "features": "Plain", "amount": amount }); - let output: OutputWithBlind = HttpWallet::send_enc_request( + let output: OutputWithBlind = HttpWallet::async_send_enc_request( &self.wallet_owner_url, &self.wallet_owner_secret, "build_output", &req_json, &self.shared_key, - )?; + ) + .await?; Ok((output.blind, output.output)) } } @@ -196,11 +239,12 @@ impl Wallet for HttpWallet { #[cfg(test)] pub mod mock { use super::{Wallet, WalletError}; - use crate::crypto::secp; use std::borrow::BorrowMut; + use async_trait::async_trait; use grin_core::core::{Output, OutputFeatures}; use grin_keychain::BlindingFactor; + use grin_onion::crypto::secp; use secp256k1zkp::pedersen::Commitment; use secp256k1zkp::Secp256k1; use std::sync::{Arc, Mutex}; @@ -225,9 +269,13 @@ pub mod mock { } } + #[async_trait] impl Wallet for MockWallet { /// Builds an 'Output' for the wallet using the 'build_output' RPC API. - fn build_output(&self, amount: u64) -> Result<(BlindingFactor, Output), WalletError> { + async fn async_build_output( + &self, + amount: u64, + ) -> Result<(BlindingFactor, Output), WalletError> { let secp = Secp256k1::new(); let blind = secp::random_secret(); let commit = secp::commit(amount, &blind).unwrap(); diff --git a/tests/common/miner.rs b/tests/common/miner.rs new file mode 100644 index 0000000..11985c0 --- /dev/null +++ b/tests/common/miner.rs @@ -0,0 +1,255 @@ +// Copyright 2021 The Grin Developers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Mining service, gets a block to mine, and based on mining configuration +//! chooses a version of the cuckoo miner to mine the block and produce a valid +//! header with its proof-of-work. Any valid mined blocks are submitted to the +//! network. + +use crate::common::types::BlockFees; +use crate::common::wallet::IntegrationGrinWallet; +use chrono::prelude::Utc; +use chrono::{DateTime, NaiveDateTime}; +use grin_chain::Chain; +use grin_core::core::hash::{Hash, Hashed}; +use grin_core::core::{Block, BlockHeader, Transaction}; +use grin_core::{consensus, global}; +use grin_keychain::Identifier; +use grin_util::Mutex; +use rand::{thread_rng, Rng}; +use std::sync::Arc; +use std::time::Duration; + +pub struct Miner { + chain: Arc, +} + +impl Miner { + // Creates a new Miner. Needs references to the chain state and its + /// storage. + pub fn new(chain: Arc) -> Miner { + Miner { chain } + } + + pub async fn async_mine_empty_blocks( + &self, + wallet: &Arc>, + num_blocks: usize, + ) { + for _ in 0..num_blocks { + self.async_mine_next_block(wallet, &vec![]).await; + } + } + + /// Builds a new block on top of the existing chain. + pub async fn async_mine_next_block( + &self, + wallet: &Arc>, + txs: &Vec, + ) { + info!("Starting test miner loop."); + + // iteration, we keep the returned derivation to provide it back when + // nothing has changed. We only want to create a new key_id for each new block. + let mut key_id = None; + + loop { + // get the latest chain state and build a block on top of it + let head = self.chain.head_header().unwrap(); + let mut latest_hash = self.chain.head().unwrap().last_block_h; + + let (mut b, block_fees) = self.async_get_block(wallet, txs, key_id.clone()).await; + let sol = self.inner_mining_loop(&mut b, &head, &mut latest_hash); + + // we found a solution, push our block through the chain processing pipeline + if sol { + info!( + "Found valid proof of work, adding block {} (prev_root {}).", + b.hash(), + b.header.prev_root, + ); + let res = self.chain.process_block(b, grin_chain::Options::MINE); + if let Err(e) = res { + error!("Error validating mined block: {:?}", e); + } else { + return; + } + key_id = None; + } else { + key_id = block_fees.key_id(); + } + } + } + + /// The inner part of mining loop for the internal miner + /// kept around mostly for automated testing purposes + fn inner_mining_loop(&self, b: &mut Block, head: &BlockHeader, latest_hash: &mut Hash) -> bool { + while head.hash() == *latest_hash { + let mut ctx = global::create_pow_context::( + head.height, + global::min_edge_bits(), + global::proofsize(), + 10, + ) + .unwrap(); + ctx.set_header_nonce(b.header.pre_pow(), None, true) + .unwrap(); + if let Ok(proofs) = ctx.find_cycles() { + b.header.pow.proof = proofs[0].clone(); + let proof_diff = b.header.pow.to_difficulty(b.header.height); + if proof_diff >= (b.header.total_difficulty() - head.total_difficulty()) { + return true; + } + } + + b.header.pow.nonce += 1; + *latest_hash = self.chain.head().unwrap().last_block_h; + } + + false + } + + // Ensure a block suitable for mining is built and returned + // If a wallet listener URL is not provided the reward will be "burnt" + // Warning: This call does not return until/unless a new block can be built + async fn async_get_block( + &self, + wallet: &Arc>, + txs: &Vec, + key_id: Option, + ) -> (Block, BlockFees) { + let wallet_retry_interval = 5; + // get the latest chain state and build a block on top of it + let mut result = self.async_build_block(wallet, txs, key_id.clone()).await; + while let Err(e) = result { + println!("Error: {:?}", &e); + let mut new_key_id = key_id.to_owned(); + match e { + grin_servers::common::types::Error::Chain(c) => match c { + grin_chain::Error::DuplicateCommitment(_) => { + debug!( + "Duplicate commit for potential coinbase detected. Trying next derivation." + ); + // use the next available key to generate a different coinbase commitment + new_key_id = None; + } + _ => { + error!("Chain Error: {}", c); + } + }, + grin_servers::common::types::Error::WalletComm(_) => { + error!( + "Error building new block: Can't connect to wallet listener; will retry" + ); + async_std::task::sleep(Duration::from_secs(wallet_retry_interval)).await; + } + ae => { + warn!("Error building new block: {:?}. Retrying.", ae); + } + } + + // only wait if we are still using the same key: a different coinbase commitment is unlikely + // to have duplication + if new_key_id.is_some() { + async_std::task::sleep(Duration::from_millis(100)).await; + } + + result = self.async_build_block(wallet, txs, new_key_id).await; + } + return result.unwrap(); + } + + /// Builds a new block with the chain head as previous and eligible + /// transactions from the pool. + async fn async_build_block( + &self, + wallet: &Arc>, + txs: &Vec, + key_id: Option, + ) -> Result<(Block, BlockFees), grin_servers::common::types::Error> { + let head = self.chain.head_header()?; + + // prepare the block header timestamp + let mut now_sec = Utc::now().timestamp(); + let head_sec = head.timestamp.timestamp(); + if now_sec <= head_sec { + now_sec = head_sec + 1; + } + + // Determine the difficulty our block should be at. + // Note: do not keep the difficulty_iter in scope (it has an active batch). + let difficulty = consensus::next_difficulty(head.height + 1, self.chain.difficulty_iter()?); + + // build the coinbase and the block itself + let fees = txs.iter().map(|tx| tx.fee()).sum(); + let height = head.height + 1; + let block_fees = BlockFees { + fees, + key_id, + height, + }; + + let res = wallet.lock().async_create_coinbase(&block_fees).await?; + let output = res.output; + let kernel = res.kernel; + let block_fees = BlockFees { + key_id: res.key_id, + ..block_fees + }; + let mut b = Block::from_reward(&head, &txs, output, kernel, difficulty.difficulty)?; + + // making sure we're not spending time mining a useless block + b.validate(&head.total_kernel_offset)?; + + b.header.pow.nonce = thread_rng().gen(); + b.header.pow.secondary_scaling = difficulty.secondary_scaling; + b.header.timestamp = DateTime::::from_naive_utc_and_offset( + NaiveDateTime::from_timestamp_opt(now_sec, 0).unwrap(), + Utc, + ); + + debug!( + "Built new block with {} inputs and {} outputs, block difficulty: {}, cumulative difficulty {}", + b.inputs().len(), + b.outputs().len(), + difficulty.difficulty, + b.header.total_difficulty().to_num(), + ); + + // Now set txhashset roots and sizes on the header of the block being built. + match self.chain.set_txhashset_roots(&mut b) { + Ok(_) => Ok((b, block_fees)), + Err(e) => { + match e { + // If this is a duplicate commitment then likely trying to use + // a key that hass already been derived but not in the wallet + // for some reason, allow caller to retry. + grin_chain::Error::DuplicateCommitment(e) => { + Err(grin_servers::common::types::Error::Chain( + grin_chain::Error::DuplicateCommitment(e), + )) + } + + // Some other issue, possibly duplicate kernel + _ => { + error!("Error setting txhashset root to build a block: {:?}", e); + Err(grin_servers::common::types::Error::Chain( + grin_chain::Error::Other(format!("{:?}", e)), + )) + } + } + } + } + } +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs new file mode 100644 index 0000000..dc3e692 --- /dev/null +++ b/tests/common/mod.rs @@ -0,0 +1,5 @@ +pub mod miner; +pub mod node; +pub mod server; +pub mod types; +pub mod wallet; diff --git a/tests/common/node.rs b/tests/common/node.rs new file mode 100644 index 0000000..a554920 --- /dev/null +++ b/tests/common/node.rs @@ -0,0 +1,122 @@ +extern crate grin_wallet_api as apiwallet; +extern crate grin_wallet_config as wallet_config; +extern crate grin_wallet_controller as wallet_controller; +extern crate grin_wallet_impls as wallet; +extern crate grin_wallet_libwallet as libwallet; + +use futures::channel::oneshot; + +use grin_core as core; + +use grin_p2p as p2p; +use grin_servers as servers; + +use grin_util::logger::LogEntry; +use grin_util::{Mutex, StopState}; +use std::default::Default; +use std::net::SocketAddr; + +use mwixnet::{GrinNode, HttpGrinNode}; +use std::sync::{mpsc, Arc}; +use std::thread; + +#[allow(dead_code)] +pub struct IntegrationGrinNode { + server_config: servers::ServerConfig, + stop_state: Arc, + server: Option>, +} + +impl IntegrationGrinNode { + pub fn start(&mut self) -> Arc { + let stop_state_thread = self.stop_state.clone(); + let server_config_thread = self.server_config.clone(); + + // Create a channel to communicate between threads + let (tx, rx) = mpsc::channel(); + + // Start the node in a new thread + thread::spawn(move || { + let api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>) = + Box::leak(Box::new(oneshot::channel::<()>())); + + servers::Server::start( + server_config_thread.clone(), + None, + move |serv: servers::Server, _: Option>| { + // Signal that the callback has been called + tx.send(serv).unwrap(); + // Do other necessary stuff here + }, + Some(stop_state_thread.clone()), + api_chan, + ) + .unwrap(); + }); + + // Wait for the signal from the node-running thread + let server = Arc::new(rx.recv().unwrap()); + self.server = Some(server.clone()); + + server + } + + pub fn stop(&self) { + self.stop_state.stop(); + } + + pub fn api_address(&self) -> SocketAddr { + self.server_config.api_http_addr.parse().unwrap() + } + + pub fn to_client(&self) -> Arc { + Arc::new(HttpGrinNode::new(&self.api_address(), &None)) + } +} + +#[allow(dead_code)] +pub struct GrinNodeManager { + // base directory for the server instance + working_dir: String, + + nodes: Vec>>, +} + +impl GrinNodeManager { + pub fn new(test_dir: &str) -> GrinNodeManager { + GrinNodeManager { + working_dir: String::from(test_dir), + nodes: vec![], + } + } + + pub fn new_node(&mut self) -> Arc> { + let server_config = servers::ServerConfig { + api_http_addr: format!("127.0.0.1:{}", 20000 + self.nodes.len()), + api_secret_path: None, + db_root: format!("{}/nodes/{}", self.working_dir, self.nodes.len()), + p2p_config: p2p::P2PConfig { + port: 13414, + seeding_type: p2p::Seeding::None, + ..p2p::P2PConfig::default() + }, + chain_type: core::global::ChainTypes::AutomatedTesting, + skip_sync_wait: Some(true), + stratum_mining_config: None, + ..Default::default() + }; + let node = Arc::new(Mutex::new(IntegrationGrinNode { + server_config, + stop_state: Arc::new(StopState::new()), + server: None, + })); + self.nodes.push(node.clone()); + node + } + + pub fn stop_all(&self) { + for node in &self.nodes { + node.lock().stop(); + } + } +} diff --git a/tests/common/server.rs b/tests/common/server.rs new file mode 100644 index 0000000..0d5a075 --- /dev/null +++ b/tests/common/server.rs @@ -0,0 +1,244 @@ +use crate::common::node::IntegrationGrinNode; +use crate::common::wallet::{GrinWalletManager, IntegrationGrinWallet}; +use grin_core::core::Transaction; +use grin_onion::crypto::comsig::ComSignature; +use grin_onion::crypto::dalek::DalekPublicKey; +use grin_onion::onion::Onion; +use grin_wallet_impls::tor::process::TorProcess; +use mwixnet::client::MixClientImpl; +use mwixnet::{tor, SwapError, SwapServer, SwapStore}; +use secp256k1zkp::SecretKey; +use std::iter; +use std::net::TcpListener; +use std::sync::Arc; +use x25519_dalek::{PublicKey as xPublicKey, StaticSecret}; + +pub struct IntegrationSwapServer { + server_key: SecretKey, + tor_process: TorProcess, + swap_server: Arc>, + rpc_server: jsonrpc_http_server::Server, + _wallet: Arc>, +} + +impl IntegrationSwapServer { + pub async fn async_swap(&self, onion: &Onion, comsig: &ComSignature) -> Result<(), SwapError> { + self.swap_server.lock().await.swap(&onion, &comsig).await + } + + pub async fn async_execute_round(&self) -> Result>, SwapError> { + self.swap_server.lock().await.execute_round().await + } +} + +pub struct IntegrationMixServer { + server_key: SecretKey, + tor_process: TorProcess, + rpc_server: jsonrpc_http_server::Server, + _wallet: Arc>, +} + +async fn async_new_swap_server( + data_dir: &str, + rt_handle: &tokio::runtime::Handle, + wallets: &mut GrinWalletManager, + server_key: &SecretKey, + node: &Arc>, + next_server: Option<&IntegrationMixServer>, +) -> IntegrationSwapServer { + let wallet = wallets.async_new_wallet(&node.lock().api_address()).await; + + let server_config = mwixnet::ServerConfig { + key: server_key.clone(), + interval_s: 15, + addr: TcpListener::bind("127.0.0.1:0") + .unwrap() + .local_addr() + .unwrap(), + socks_proxy_addr: TcpListener::bind("127.0.0.1:0") + .unwrap() + .local_addr() + .unwrap(), + grin_node_url: node.lock().api_address(), + grin_node_secret_path: None, + wallet_owner_url: wallet.lock().owner_address(), + wallet_owner_secret_path: None, + prev_server: None, + next_server: match next_server { + Some(s) => Some(DalekPublicKey::from_secret(&s.server_key)), + None => None, + }, + }; + + // Open SwapStore + let store = SwapStore::new(format!("{}/db", data_dir).as_str()).unwrap(); + let tor_process = tor::init_tor_listener(&data_dir, &server_config).unwrap(); + + let (swap_server, rpc_server) = mwixnet::swap_listen( + rt_handle, + &server_config, + match next_server { + Some(s) => Some(Arc::new(MixClientImpl::new( + server_config.clone(), + DalekPublicKey::from_secret(&s.server_key), + ))), + None => None, + }, + wallet.lock().get_client(), + node.lock().to_client(), + store, + ) + .unwrap(); + + IntegrationSwapServer { + server_key: server_key.clone(), + tor_process, + swap_server, + rpc_server, + _wallet: wallet, + } +} + +async fn async_new_mix_server( + data_dir: &str, + rt_handle: &tokio::runtime::Handle, + wallets: &mut GrinWalletManager, + server_key: &SecretKey, + node: &Arc>, + prev_server: DalekPublicKey, + next_server: Option<&IntegrationMixServer>, +) -> IntegrationMixServer { + let wallet = wallets.async_new_wallet(&node.lock().api_address()).await; + let server_config = mwixnet::ServerConfig { + key: server_key.clone(), + interval_s: 15, + addr: TcpListener::bind("127.0.0.1:0") + .unwrap() + .local_addr() + .unwrap(), + socks_proxy_addr: TcpListener::bind("127.0.0.1:0") + .unwrap() + .local_addr() + .unwrap(), + grin_node_url: node.lock().api_address(), + grin_node_secret_path: None, + wallet_owner_url: wallet.lock().owner_address(), + wallet_owner_secret_path: None, + prev_server: Some(prev_server), + next_server: match next_server { + Some(s) => Some(DalekPublicKey::from_secret(&s.server_key)), + None => None, + }, + }; + + let tor_process = tor::init_tor_listener(&data_dir, &server_config).unwrap(); + + let (_, rpc_server) = mwixnet::mix_listen( + rt_handle, + server_config.clone(), + match next_server { + Some(s) => Some(Arc::new(MixClientImpl::new( + server_config.clone(), + DalekPublicKey::from_secret(&s.server_key), + ))), + None => None, + }, + wallet.lock().get_client(), + node.lock().to_client(), + ) + .unwrap(); + + IntegrationMixServer { + server_key: server_key.clone(), + tor_process, + rpc_server, + _wallet: wallet, + } +} + +pub struct Servers { + pub swapper: IntegrationSwapServer, + + pub mixers: Vec, +} + +impl Servers { + pub async fn async_setup( + test_dir: &str, + rt_handle: &tokio::runtime::Handle, + wallets: &mut GrinWalletManager, + node: &Arc>, + num_mixers: usize, + ) -> Servers { + // Pre-generate all server keys + let server_keys: Vec = + iter::repeat_with(|| grin_onion::crypto::secp::random_secret()) + .take(num_mixers + 1) + .collect(); + + // Build mixers in reverse order + let mut mixers = Vec::new(); + for i in (0..num_mixers).rev() { + let mix_server = async_new_mix_server( + format!("{}/mixers/{}", test_dir, i).as_str(), + rt_handle, + wallets, + &server_keys[i + 1], + &node, + DalekPublicKey::from_secret(&server_keys[i]), + mixers.last(), + ) + .await; + println!( + "Mixer {}: server_key={}, prev_server={}, next_server={}", + i, + DalekPublicKey::from_secret(&server_keys[i + 1]).to_hex(), + DalekPublicKey::from_secret(&server_keys[i]).to_hex(), + match mixers.last() { + Some(s) => DalekPublicKey::from_secret(&s.server_key).to_hex(), + None => "NONE".to_string(), + }, + ); + mixers.push(mix_server); + } + mixers.reverse(); + + let swapper = async_new_swap_server( + format!("{}/swapper", test_dir).as_str(), + rt_handle, + wallets, + &server_keys[0], + &node, + mixers.first(), + ) + .await; + println!( + "Swapper: server_key={}", + DalekPublicKey::from_secret(&server_keys[0]).to_hex() + ); + + Servers { swapper, mixers } + } + + pub fn get_pub_keys(&self) -> Vec { + let mut pub_keys = vec![xPublicKey::from(&StaticSecret::from( + self.swapper.server_key.0.clone(), + ))]; + for mixer in &self.mixers { + pub_keys.push(xPublicKey::from(&StaticSecret::from( + mixer.server_key.0.clone(), + ))) + } + pub_keys + } + + pub fn stop_all(&mut self) { + self.swapper.rpc_server.close_handle().close(); + self.swapper.tor_process.kill().unwrap(); + + self.mixers.iter_mut().for_each(|mixer| { + mixer.rpc_server.close_handle().close(); + mixer.tor_process.kill().unwrap(); + }); + } +} diff --git a/tests/common/types.rs b/tests/common/types.rs new file mode 100644 index 0000000..dba05dc --- /dev/null +++ b/tests/common/types.rs @@ -0,0 +1,24 @@ +use grin_core::libtx::secp_ser; +use grin_keychain::Identifier; +use serde_derive::{Deserialize, Serialize}; + +/// Fees in block to use for coinbase amount calculation +/// (Duplicated from Grin wallet project) +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct BlockFees { + /// fees + #[serde(with = "secp_ser::string_or_u64")] + pub fees: u64, + /// height + #[serde(with = "secp_ser::string_or_u64")] + pub height: u64, + /// key id + pub key_id: Option, +} + +impl BlockFees { + /// return key id + pub fn key_id(&self) -> Option { + self.key_id.clone() + } +} diff --git a/tests/common/wallet.rs b/tests/common/wallet.rs new file mode 100644 index 0000000..21ef399 --- /dev/null +++ b/tests/common/wallet.rs @@ -0,0 +1,431 @@ +use crate::common::types::BlockFees; +use grin_api::client; +use grin_api::json_rpc::Response; +use grin_core::core::{FeeFields, Output, OutputFeatures, Transaction, TxKernel}; +use grin_core::global::ChainTypes; +use grin_core::libtx::tx_fee; +use grin_keychain::{BlindingFactor, ExtKeychain, Identifier, Keychain, SwitchCommitmentType}; +use grin_onion::crypto::comsig::ComSignature; +use grin_onion::onion::Onion; +use grin_onion::Hop; +use grin_util::{Mutex, ToHex, ZeroingString}; +use grin_wallet_api::Owner; +use grin_wallet_config::WalletConfig; +use grin_wallet_controller::controller; +use grin_wallet_impls::{DefaultLCProvider, DefaultWalletImpl, HTTPNodeClient}; +use grin_wallet_libwallet::{InitTxArgs, Slate, VersionedSlate, WalletInfo, WalletInst}; +use log::error; +use mwixnet::wallet::HttpWallet; +use secp256k1zkp::pedersen::Commitment; +use secp256k1zkp::{Secp256k1, SecretKey}; +use serde_derive::{Deserialize, Serialize}; +use serde_json::json; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::sync::Arc; +use std::thread; +use x25519_dalek::PublicKey as xPublicKey; + +/// Response to build a coinbase output. +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct CbData { + /// Output + pub output: Output, + /// Kernel + pub kernel: TxKernel, + /// Key Id + pub key_id: Option, +} + +pub struct IntegrationGrinWallet { + wallet: Arc< + Mutex< + Box< + dyn WalletInst< + 'static, + DefaultLCProvider<'static, HTTPNodeClient, ExtKeychain>, + HTTPNodeClient, + ExtKeychain, + >, + >, + >, + >, + api_listen_port: u16, + owner_api: Arc< + Owner, HTTPNodeClient, ExtKeychain>, + >, + http_client: Arc, +} + +impl IntegrationGrinWallet { + pub async fn async_new_wallet( + wallet_dir: String, + api_listen_port: u16, + node_api: String, + ) -> IntegrationGrinWallet { + let node_client = HTTPNodeClient::new(&node_api, None).unwrap(); + let mut wallet = Box::new( + DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap(), + ) + as Box< + dyn WalletInst< + 'static, + DefaultLCProvider, + HTTPNodeClient, + ExtKeychain, + >, + >; + + // Wallet LifeCycle Provider provides all functions init wallet and work with seeds, etc... + let lc = wallet.lc_provider().unwrap(); + + let mut wallet_config = WalletConfig::default(); + wallet_config.check_node_api_http_addr = node_api.clone(); + wallet_config.owner_api_listen_port = Some(api_listen_port); + wallet_config.api_secret_path = None; + wallet_config.data_file_dir = wallet_dir.clone(); + + // The top level wallet directory should be set manually (in the reference implementation, + // this is provided in the WalletConfig) + let _ = lc.set_top_level_directory(&wallet_config.data_file_dir); + + lc.create_config( + &ChainTypes::AutomatedTesting, + "grin-wallet.toml", + Some(wallet_config.clone()), + None, + None, + ) + .unwrap(); + + lc.create_wallet(None, None, 12, ZeroingString::from("pass"), false) + .unwrap(); + + // Start owner API + let km = Arc::new(Mutex::new(None)); + let wallet = Arc::new(Mutex::new(wallet)); + let owner_api = Arc::new(Owner::new(wallet.clone(), None)); + + let address_str = format!("127.0.0.1:{}", api_listen_port); + let owner_addr: SocketAddr = address_str.parse().unwrap(); + let thr_wallet = wallet.clone(); + let _thread_handle = thread::spawn(move || { + controller::owner_listener( + thr_wallet, + km, + address_str.as_str(), + None, + None, + Some(true), + None, + false, + ) + .unwrap() + }); + + let http_client = Arc::new( + HttpWallet::async_open_wallet(&owner_addr, &None, &ZeroingString::from("pass")) + .await + .unwrap(), + ); + + IntegrationGrinWallet { + wallet, + api_listen_port, + owner_api, + http_client, + } + } + + pub async fn async_retrieve_summary_info(&self) -> Result { + let params = json!({ + "token": self.http_client.clone().get_token(), + "refresh_from_node": true, + "minimum_confirmations": 1 + }); + let (_, wallet_info): (bool, WalletInfo) = self + .http_client + .clone() + .async_perform_request("retrieve_summary_info", ¶ms) + .await?; + Ok(wallet_info) + } + + pub async fn async_send( + &self, + receiving_wallet: &IntegrationGrinWallet, + amount: u64, + ) -> Result { + let slate = self.async_init_send_tx(amount).await.unwrap(); + let slate = receiving_wallet.async_receive_tx(&slate).await.unwrap(); + let slate = self.async_finalize_tx(&slate).await.unwrap(); + let tx = Slate::from(slate).tx_or_err().unwrap().clone(); + Ok(tx) + } + + async fn async_init_send_tx( + &self, + amount: u64, + ) -> Result { + let args = InitTxArgs { + src_acct_name: None, + amount, + minimum_confirmations: 0, + max_outputs: 10, + num_change_outputs: 1, + selection_strategy_is_use_all: false, + ..Default::default() + }; + let params = json!({ + "token": self.http_client.clone().get_token(), + "args": args + }); + + let slate: VersionedSlate = self + .http_client + .clone() + .async_perform_request("init_send_tx", ¶ms) + .await?; + + let params = json!({ + "token": self.http_client.clone().get_token(), + "slate": &slate + }); + self.http_client + .clone() + .async_perform_request("tx_lock_outputs", ¶ms) + .await?; + + Ok(slate) + } + + pub async fn async_receive_tx( + &self, + slate: &VersionedSlate, + ) -> Result { + let req_body = json!({ + "jsonrpc": "2.0", + "method": "receive_tx", + "id": 1, + "params": [slate, null, null] + }); + + let res: Response = client::post_async(self.foreign_api().as_str(), &req_body, None) + .await + .map_err(|e| { + let report = format!("Failed to receive tx. Is the wallet listening? {}", e); + error!("{}", report); + grin_servers::common::types::Error::WalletComm(report) + })?; + + let parsed: VersionedSlate = res.clone().into_result().map_err(|e| { + let report = format!("Error parsing result: {}", e); + error!("{}", report); + grin_servers::common::types::Error::WalletComm(report) + })?; + + Ok(parsed) + } + + async fn async_finalize_tx( + &self, + slate: &VersionedSlate, + ) -> Result { + let params = json!({ + "token": self.http_client.clone().get_token(), + "slate": slate + }); + + self.http_client + .clone() + .async_perform_request("finalize_tx", ¶ms) + .await + } + + async fn async_post_tx( + &self, + finalized_slate: &VersionedSlate, + fluff: bool, + ) -> Result { + let params = json!({ + "token": self.http_client.clone().get_token(), + "slate": finalized_slate, + "fluff": fluff + }); + + self.http_client + .clone() + .async_perform_request("post_tx", ¶ms) + .await + } + + /// Call the wallet API to create a coinbase output for the given block_fees. + /// Will retry based on default "retry forever with backoff" behavior. + pub async fn async_create_coinbase( + &self, + block_fees: &BlockFees, + ) -> Result { + let req_body = json!({ + "jsonrpc": "2.0", + "method": "build_coinbase", + "id": 1, + "params": { + "block_fees": block_fees + } + }); + + let res: Response = client::post_async(self.foreign_api().as_str(), &req_body, None) + .await + .map_err(|e| { + let report = format!("Failed to get coinbase. Is the wallet listening? {}", e); + error!("{}", report); + grin_servers::common::types::Error::WalletComm(report) + })?; + let parsed: CbData = res.clone().into_result().map_err(|e| { + let report = format!("Error parsing result: {}", e); + error!("{}", report); + grin_servers::common::types::Error::WalletComm(report) + })?; + + Ok(parsed) + } + + pub fn build_onion( + &self, + commitment: &Commitment, + server_pubkeys: &Vec, + ) -> Result<(Onion, ComSignature), grin_wallet_libwallet::Error> { + let keychain = self + .wallet + .lock() + .lc_provider()? + .wallet_inst()? + .keychain(self.keychain_mask().as_ref())?; + let (_, outputs) = + self.owner_api + .retrieve_outputs(self.keychain_mask().as_ref(), false, false, None)?; + + let mut output = None; + for o in &outputs { + if o.commit == *commitment { + output = Some(o.output.clone()); + break; + } + } + + if output.is_none() { + return Err(grin_wallet_libwallet::Error::GenericError(String::from( + "output not found", + ))); + } + + let amount = output.clone().unwrap().value; + let input_blind = keychain.derive_key( + amount, + &output.clone().unwrap().key_id, + SwitchCommitmentType::Regular, + )?; + + let fee = tx_fee(1, 1, 1); + let new_amount = amount - (fee * server_pubkeys.len() as u64); + let new_output = self.owner_api.build_output( + self.keychain_mask().as_ref(), + OutputFeatures::Plain, + new_amount, + )?; + + let secp = Secp256k1::new(); + let mut blind_sum = new_output + .blind + .split(&BlindingFactor::from_secret_key(input_blind.clone()), &secp)?; + + let hops = server_pubkeys + .iter() + .enumerate() + .map(|(i, &p)| { + if (i + 1) == server_pubkeys.len() { + Hop { + server_pubkey: p.clone(), + excess: blind_sum.secret_key(&secp).unwrap(), + fee: FeeFields::from(fee as u32), + rangeproof: Some(new_output.output.proof.clone()), + } + } else { + let hop_excess = BlindingFactor::rand(&secp); + blind_sum = blind_sum.split(&hop_excess, &secp).unwrap(); + Hop { + server_pubkey: p.clone(), + excess: hop_excess.secret_key(&secp).unwrap(), + fee: FeeFields::from(fee as u32), + rangeproof: None, + } + } + }) + .collect(); + + let onion = grin_onion::create_onion(&commitment, &hops).unwrap(); + let comsig = ComSignature::sign(amount, &input_blind, &onion.serialize().unwrap()).unwrap(); + + Ok((onion, comsig)) + } + + pub fn owner_api( + &self, + ) -> Arc< + Owner, HTTPNodeClient, ExtKeychain>, + > { + self.owner_api.clone() + } + + pub fn foreign_api(&self) -> String { + format!("http://127.0.0.1:{}/v2/foreign", self.api_listen_port) + } + + pub fn owner_address(&self) -> SocketAddr { + SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), + self.api_listen_port, + ) + } + + pub fn keychain_mask(&self) -> Option { + self.http_client.as_ref().get_token().keychain_mask.clone() + } + + pub fn get_client(&self) -> Arc { + self.http_client.clone() + } +} + +#[allow(dead_code)] +pub struct GrinWalletManager { + // base directory for the server instance + working_dir: String, + + wallets: Vec>>, +} + +impl GrinWalletManager { + pub fn new(test_dir: &str) -> GrinWalletManager { + GrinWalletManager { + working_dir: String::from(test_dir), + wallets: vec![], + } + } + + pub async fn async_new_wallet( + &mut self, + node_api_addr: &SocketAddr, + ) -> Arc> { + let wallet_dir = format!("{}/wallets/{}", self.working_dir, self.wallets.len()); + let wallet = Arc::new(Mutex::new( + IntegrationGrinWallet::async_new_wallet( + wallet_dir, + 21000 + self.wallets.len() as u16, + format!("http://{}", node_api_addr), + ) + .await, + )); + self.wallets.push(wallet.clone()); + wallet + } +} diff --git a/tests/e2e.rs b/tests/e2e.rs new file mode 100644 index 0000000..6a15bd4 --- /dev/null +++ b/tests/e2e.rs @@ -0,0 +1,135 @@ +use crate::common::miner::Miner; +use crate::common::node::GrinNodeManager; +use crate::common::server::Servers; +use crate::common::wallet::GrinWalletManager; +use function_name::named; +use grin_core::global; +use grin_util::logger::LoggingConfig; +use log::Level; +use std::ops::Deref; + +mod common; + +#[macro_use] +extern crate log; + +/// Just removes all results from previous runs +fn clean_all_output(test_dir: &str) { + if let Err(e) = remove_dir_all::remove_dir_all(test_dir) { + println!("can't remove output from previous test :{}, may be ok", e); + } +} + +fn setup_test(test_name: &str) -> (GrinNodeManager, GrinWalletManager, String) { + let test_dir = format!("./target/tmp/.{}", test_name); + clean_all_output(test_dir.as_str()); + + let mut logger = LoggingConfig::default(); + logger.log_to_file = false; + logger.stdout_log_level = Level::Error; + grin_util::init_logger(Some(logger), None); + global::set_local_chain_type(global::ChainTypes::AutomatedTesting); + global::set_local_accept_fee_base(50_000_000); + global::init_global_chain_type(global::ChainTypes::AutomatedTesting); + + let nodes = GrinNodeManager::new(test_dir.as_str()); + let wallets = GrinWalletManager::new(test_dir.as_str()); + + (nodes, wallets, test_dir) +} + +#[test] +#[named] +fn integration_test() -> Result<(), Box> { + let (mut nodes, mut wallets, test_dir) = setup_test(function_name!()); + let mut rt = tokio::runtime::Builder::new() + .threaded_scheduler() + .enable_all() + .build()?; + + // Create node + let node1 = nodes.new_node(); + let node1_url = node1.lock().api_address(); + let node1_server = node1.lock().start(); + + // Setup swap & mix servers and their wallets + let rt_handle = rt.handle().clone(); + let mut servers = rt.block_on(Servers::async_setup( + test_dir.as_str(), + &rt_handle, + &mut wallets, + &node1, + 2usize, + )); + + rt.block_on(async { + // Setup wallet to use with miner + let mining_wallet = wallets.async_new_wallet(&node1_url).await; + + // Mine enough blocks to have spendable coins + let miner = Miner::new(node1_server.chain.clone()); + miner + .async_mine_empty_blocks(&mining_wallet, 5 + global::coinbase_maturity() as usize) + .await; + + // Setup wallets for swap users + let user1_wallet = wallets.async_new_wallet(&node1_url).await; + let user2_wallet = wallets.async_new_wallet(&node1_url).await; + + // Send from mining_wallet to user1_wallet + let tx1 = mining_wallet + .lock() + .async_send(user1_wallet.lock().deref(), 10_000_000_000) + .await + .unwrap(); + let tx2 = mining_wallet + .lock() + .async_send(user2_wallet.lock().deref(), 20_000_000_000) + .await + .unwrap(); + miner + .async_mine_next_block(&mining_wallet, &vec![tx1, tx2]) + .await; + + let user1_km = user1_wallet.lock().keychain_mask(); + let (_, outputs) = user1_wallet + .lock() + .owner_api() + .retrieve_outputs(user1_km.as_ref(), false, false, None) + .unwrap(); + assert_eq!(outputs.len(), 1); + for output in &outputs { + let (onion, comsig) = user1_wallet + .lock() + .build_onion(&output.commit, &servers.get_pub_keys()) + .unwrap(); + servers.swapper.async_swap(&onion, &comsig).await.unwrap(); + } + + let mining_wallet_info = mining_wallet + .lock() + .async_retrieve_summary_info() + .await + .unwrap(); + println!("Mining wallet: {:?}", mining_wallet_info); + let user1_wallet_info = user1_wallet + .lock() + .async_retrieve_summary_info() + .await + .unwrap(); + println!("User1 wallet: {:?}", user1_wallet_info); + let user2_wallet_info = user2_wallet + .lock() + .async_retrieve_summary_info() + .await + .unwrap(); + println!("User2 wallet: {:?}", user2_wallet_info); + + let _tx = servers.swapper.async_execute_round().await.unwrap(); + }); + + servers.stop_all(); + nodes.stop_all(); + + Ok(()) +}