From bf09b5cc7e19deb60a9f421bbf28cac8f83e50ab Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 4 Jan 2023 03:17:36 -0500 Subject: [PATCH 01/74] cargo update --- Cargo.lock | 743 ++++++++---------- substrate/node/Cargo.toml | 5 +- substrate/node/src/command_helper.rs | 8 +- substrate/runtime/src/lib.rs | 9 +- .../tendermint/client/src/authority/mod.rs | 2 +- substrate/tendermint/client/src/tendermint.rs | 2 +- substrate/tendermint/machine/Cargo.toml | 2 +- 7 files changed, 344 insertions(+), 427 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba3aa9b2..3d2949d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -249,66 +249,6 @@ dependencies = [ "futures-lite", ] -[[package]] -name = "async-process" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6381ead98388605d0d9ff86371043b5aa922a3905824244de40dc263a14fcba4" -dependencies = [ - "async-io", - "async-lock", - "autocfg", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "libc", - "signal-hook", - "windows-sys 0.42.0", -] - -[[package]] -name = "async-std" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" -dependencies = [ - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite 0.2.9", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-std-resolver" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba50e24d9ee0a8950d3d03fc6d0dd10aa14b5de3b101949b4e160f7fee7c723" -dependencies = [ - "async-std", - "async-trait", - "futures-io", - "futures-util", - "pin-utils", - "socket2", - "trust-dns-resolver", -] - [[package]] name = "async-task" version = "4.3.0" @@ -408,7 +348,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object 0.30.1", "rustc-demangle", ] @@ -954,9 +894,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.30" +version = "4.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "656ad1e55e23d287773f7d8192c300dc715c3eeded93b3da651d11c42cfd74d2" +checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39" dependencies = [ "bitflags", "clap_derive 4.0.21", @@ -1080,9 +1020,9 @@ dependencies = [ [[package]] name = "comfy-table" -version = "6.1.3" +version = "6.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e621e7e86c46fd8a14c32c6ae3cb95656621b4743a27d0cffedb831d46e7ad21" +checksum = "6e7b787b0dc42e8111badfdbe4c3059158ccb2db8780352fa1b01e8ccf45cc4d" dependencies = [ "strum", "strum_macros", @@ -1115,15 +1055,14 @@ dependencies = [ [[package]] name = "console" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" +checksum = "c9b6515d269224923b26b5febea2ed42b2d5f2ce37284a4dd670fedd6cb8347a" dependencies = [ "encode_unicode", "lazy_static", "libc", - "terminal_size", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -1394,16 +1333,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ctor" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "ctr" version = "0.8.0" @@ -2458,7 +2387,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", ] @@ -2481,7 +2410,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-support", "frame-system", @@ -2504,12 +2433,12 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "Inflector", "array-bytes", "chrono", - "clap 4.0.30", + "clap 4.0.32", "comfy-table", "frame-benchmarking", "frame-support", @@ -2556,7 +2485,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-support", "frame-system", @@ -2584,7 +2513,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "bitflags", "frame-metadata", @@ -2616,7 +2545,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "Inflector", "cfg-expr", @@ -2630,7 +2559,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -2642,7 +2571,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "proc-macro2", "quote", @@ -2652,7 +2581,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-support", "log", @@ -2670,7 +2599,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", "sp-api", @@ -2940,18 +2869,6 @@ dependencies = [ "regex", ] -[[package]] -name = "gloo-timers" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c4a8d6391675c6b2ee1a6c8d06e8e2d03605c44cec1270675985a4c2a5500b" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "group" version = "0.12.1" @@ -3156,6 +3073,12 @@ dependencies = [ "pin-project-lite 0.2.9", ] +[[package]] +name = "http-range-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" + [[package]] name = "httparse" version = "1.8.0" @@ -3363,13 +3286,19 @@ dependencies = [ "serde", ] +[[package]] +name = "indexmap-nostd" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" + [[package]] name = "indicatif" version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" dependencies = [ - "console 0.15.2", + "console 0.15.4", "lazy_static", "number_prefix", "regex", @@ -3631,7 +3560,7 @@ checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" dependencies = [ "hermit-abi 0.2.6", "io-lifetimes 1.0.3", - "rustix 0.36.5", + "rustix 0.36.6", "windows-sys 0.42.0", ] @@ -3670,23 +3599,22 @@ dependencies = [ [[package]] name = "jsonrpsee" -version = "0.15.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd0d559d5e679b1ab2f869b486a11182923863b1b3ee8b421763cdd707b783a" +checksum = "7d291e3a5818a2384645fd9756362e6d89cf0541b0b916fa7702ea4a9833608e" dependencies = [ "jsonrpsee-core", - "jsonrpsee-http-server", "jsonrpsee-proc-macros", + "jsonrpsee-server", "jsonrpsee-types", - "jsonrpsee-ws-server", "tracing", ] [[package]] name = "jsonrpsee-core" -version = "0.15.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3dc3e9cf2ba50b7b1d7d76a667619f82846caa39e8e8daa8a4962d74acaddca" +checksum = "a4e70b4439a751a5de7dd5ed55eacff78ebf4ffe0fc009cb1ebb11417f5b536b" dependencies = [ "anyhow", "arrayvec 0.7.2", @@ -3695,10 +3623,8 @@ dependencies = [ "futures-channel", "futures-util", "globset", - "http", "hyper", "jsonrpsee-types", - "lazy_static", "parking_lot 0.12.1", "rand 0.8.5", "rustc-hash", @@ -3708,33 +3634,15 @@ dependencies = [ "thiserror", "tokio", "tracing", - "unicase", -] - -[[package]] -name = "jsonrpsee-http-server" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03802f0373a38c2420c70b5144742d800b509e2937edc4afb116434f07120117" -dependencies = [ - "futures-channel", - "futures-util", - "hyper", - "jsonrpsee-core", - "jsonrpsee-types", - "serde", - "serde_json", - "tokio", - "tracing", - "tracing-futures", ] [[package]] name = "jsonrpsee-proc-macros" -version = "0.15.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd67957d4280217247588ac86614ead007b301ca2fa9f19c19f880a536f029e3" +checksum = "baa6da1e4199c10d7b1d0a6e5e8bd8e55f351163b6f4b3cbb044672a69bd4c1c" dependencies = [ + "heck", "proc-macro-crate", "proc-macro2", "quote", @@ -3742,10 +3650,32 @@ dependencies = [ ] [[package]] -name = "jsonrpsee-types" -version = "0.15.1" +name = "jsonrpsee-server" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e290bba767401b646812f608c099b922d8142603c9e73a50fb192d3ac86f4a0d" +checksum = "1fb69dad85df79527c019659a992498d03f8495390496da2f07e6c24c2b356fc" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "hyper", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "soketto", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd522fe1ce3702fd94812965d7bb7a3364b1c9aba743944c5a00529aae80f8c" dependencies = [ "anyhow", "beef", @@ -3755,26 +3685,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "jsonrpsee-ws-server" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d488ba74fb369e5ab68926feb75a483458b88e768d44319f37e4ecad283c7325" -dependencies = [ - "futures-channel", - "futures-util", - "http", - "jsonrpsee-core", - "jsonrpsee-types", - "serde_json", - "soketto", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", - "tracing-futures", -] - [[package]] name = "k256" version = "0.11.6" @@ -3797,46 +3707,33 @@ dependencies = [ "cpufeatures", ] -[[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 = "kvdb" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585089ceadba0197ffe9af6740ab350b325e3c1f5fccfbc3522e0250c750409b" +checksum = "e7d770dcb02bf6835887c3a979b5107a04ff4bbde97a5f0928d27404a155add9" dependencies = [ - "parity-util-mem", "smallvec", ] [[package]] name = "kvdb-memorydb" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40d109c87bfb7759edd2a49b2649c1afe25af785d930ad6a38479b4dc70dd873" +checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2" dependencies = [ "kvdb", - "parity-util-mem", "parking_lot 0.12.1", ] [[package]] name = "kvdb-rocksdb" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c076cc2cdbac89b9910c853a36c957d3862a779f31c2661174222cefb49ee597" +checksum = "2182b8219fee6bd83aacaab7344e840179ae079d5216aa4e249b4d704646a844" dependencies = [ "kvdb", - "log", "num_cpus", - "parity-util-mem", "parking_lot 0.12.1", "regex", "rocksdb", @@ -3889,9 +3786,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libloading" @@ -3988,7 +3885,6 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2322c9fb40d99101def6a01612ee30500c89abbbecb6297b3cd252903a4c1720" dependencies = [ - "async-std-resolver", "futures", "libp2p-core", "log", @@ -4052,7 +3948,6 @@ version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "761704e727f7d68d58d7bc2231eafae5fc1b9814de24290f126df09d4bd37a15" dependencies = [ - "async-io", "data-encoding", "dns-parser", "futures", @@ -4063,6 +3958,7 @@ dependencies = [ "rand 0.8.5", "smallvec", "socket2", + "tokio", "void", ] @@ -4191,7 +4087,6 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9839d96761491c6d3e238e70554b856956fca0ab60feb9de2cd08eed4473fa92" dependencies = [ - "async-io", "futures", "futures-timer", "if-watch", @@ -4199,6 +4094,7 @@ dependencies = [ "libp2p-core", "log", "socket2", + "tokio", ] [[package]] @@ -4385,7 +4281,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", - "value-bag", ] [[package]] @@ -4497,7 +4392,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb" dependencies = [ - "rustix 0.36.5", + "rustix 0.36.6", ] [[package]] @@ -4529,13 +4424,12 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac11bb793c28fa095b7554466f53b3a60a2cd002afdac01bcf135cbd73a269" +checksum = "5e0c7cba9ce19ac7ffd2053ac9f49843bbd3f4318feedfd74e85c19d5fb0ba66" dependencies = [ "hash-db", "hashbrown", - "parity-util-mem", ] [[package]] @@ -4965,9 +4859,9 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nom" -version = "7.1.1" +version = "7.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c" dependencies = [ "memchr", "minimal-lexical", @@ -5071,18 +4965,18 @@ dependencies = [ [[package]] name = "object" -version = "0.30.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "8d864c91689fdc196779b98dba0aceac6118594c2df6ee5d943eb6a8df4d107a" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "opaque-debug" @@ -5196,7 +5090,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-benchmarking", "frame-support", @@ -5211,7 +5105,7 @@ dependencies = [ [[package]] name = "pallet-contracts" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "bitflags", "frame-benchmarking", @@ -5230,16 +5124,16 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-sandbox", "sp-std", - "wasm-instrument", - "wasmi-validation", + "wasm-instrument 0.4.0", + "wasmi 0.20.0", + "wasmparser-nostd", ] [[package]] name = "pallet-contracts-primitives" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "bitflags", "parity-scale-codec", @@ -5251,7 +5145,7 @@ dependencies = [ [[package]] name = "pallet-contracts-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "proc-macro2", "quote", @@ -5261,7 +5155,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-support", "frame-system", @@ -5275,7 +5169,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-support", "frame-system", @@ -5309,7 +5203,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-benchmarking", "frame-support", @@ -5327,7 +5221,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-support", "frame-system", @@ -5343,7 +5237,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -5359,7 +5253,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -5420,33 +5314,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" -[[package]] -name = "parity-util-mem" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d32c34f4f5ca7f9196001c0aba5a1f9a5a12382c8944b8b0f90233282d1e8f8" -dependencies = [ - "cfg-if", - "hashbrown", - "impl-trait-for-tuples", - "parity-util-mem-derive", - "parking_lot 0.12.1", - "primitive-types", - "smallvec", - "winapi", -] - -[[package]] -name = "parity-util-mem-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" -dependencies = [ - "proc-macro2", - "syn", - "synstructure", -] - [[package]] name = "parity-wasm" version = "0.45.0" @@ -5574,9 +5441,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" +checksum = "0f6e86fb9e7026527a0d46bc308b841d73170ef8f443e1807f6ef88526a816d4" dependencies = [ "thiserror", "ucd-trie", @@ -5584,9 +5451,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdc078600d06ff90d4ed238f0119d84ab5d43dbaad278b0e33a8820293b32344" +checksum = "96504449aa860c8dcde14f9fba5c58dc6658688ca1fe363589d6327b8662c603" dependencies = [ "pest", "pest_generator", @@ -5594,9 +5461,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a1af60b1c4148bb269006a750cff8e2ea36aff34d2d96cf7be0b14d1bed23c" +checksum = "798e0220d1111ae63d66cb66a5dcb3fc2d986d520b98e49e1852bfdb11d7c5e7" dependencies = [ "pest", "pest_meta", @@ -5607,9 +5474,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec8605d59fc2ae0c6c1aefc0c7c7a9769732017c0ce07f7a9cfffa7b4404f20" +checksum = "984298b75898e30a843e278a9f2452c31e349a073a0ce6fd950a12a74464e065" dependencies = [ "once_cell", "pest", @@ -5803,9 +5670,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "predicates" -version = "2.1.4" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54fc5dc63ed3bbf19494623db4f3af16842c0d975818e469022d09e53f0aa05" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", @@ -6344,7 +6211,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", + "spin 0.5.2", "untrusted", "web-sys", "winapi", @@ -6484,9 +6351,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.5" +version = "0.36.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" dependencies = [ "bitflags", "errno", @@ -6582,7 +6449,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "log", "sp-core", @@ -6593,7 +6460,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", "futures-timer", @@ -6616,7 +6483,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -6632,7 +6499,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "impl-trait-for-tuples", "memmap2", @@ -6649,7 +6516,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6660,11 +6527,11 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "array-bytes", "chrono", - "clap 4.0.30", + "clap 4.0.32", "fdlimit", "futures", "libp2p", @@ -6700,7 +6567,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "fnv", "futures", @@ -6728,7 +6595,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "hash-db", "kvdb", @@ -6753,13 +6620,14 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "futures", "futures-timer", "libp2p", "log", + "mockall", "parking_lot 0.12.1", "sc-client-api", "sc-utils", @@ -6777,9 +6645,8 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ - "lazy_static", "lru", "parity-scale-codec", "parking_lot 0.12.1", @@ -6788,7 +6655,6 @@ dependencies = [ "sc-executor-wasmtime", "sp-api", "sp-core", - "sp-core-hashing-proc-macro", "sp-externalities", "sp-io", "sp-panic-handler", @@ -6797,56 +6663,48 @@ dependencies = [ "sp-version", "sp-wasm-interface", "tracing", - "wasmi", + "wasmi 0.13.2", ] [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ - "environmental", - "parity-scale-codec", "sc-allocator", "sp-maybe-compressed-blob", - "sp-sandbox", "sp-wasm-interface", "thiserror", - "wasm-instrument", - "wasmi", + "wasm-instrument 0.3.0", + "wasmi 0.13.2", ] [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "log", - "parity-scale-codec", "sc-allocator", "sc-executor-common", "sp-runtime-interface", - "sp-sandbox", "sp-wasm-interface", - "wasmi", + "wasmi 0.13.2", ] [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "cfg-if", "libc", "log", "once_cell", - "parity-scale-codec", - "parity-wasm", "rustix 0.35.13", "sc-allocator", "sc-executor-common", "sp-runtime-interface", - "sp-sandbox", "sp-wasm-interface", "wasmtime", ] @@ -6854,13 +6712,12 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "ansi_term", "futures", "futures-timer", "log", - "parity-util-mem", "sc-client-api", "sc-network-common", "sc-transaction-pool-api", @@ -6871,7 +6728,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "array-bytes", "async-trait", @@ -6886,7 +6743,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "array-bytes", "async-trait", @@ -6933,7 +6790,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "cid", "futures", @@ -6953,7 +6810,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "bitflags", @@ -6979,7 +6836,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "ahash", "futures", @@ -6997,7 +6854,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "array-bytes", "futures", @@ -7018,9 +6875,10 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "array-bytes", + "async-trait", "fork-tree", "futures", "libp2p", @@ -7042,13 +6900,14 @@ dependencies = [ "sp-core", "sp-finality-grandpa", "sp-runtime", + "substrate-prometheus-endpoint", "thiserror", ] [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "array-bytes", "futures", @@ -7067,7 +6926,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "array-bytes", "bytes", @@ -7097,7 +6956,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", "libp2p", @@ -7110,7 +6969,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -7119,7 +6978,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", "hash-db", @@ -7149,7 +7008,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", "jsonrpsee", @@ -7172,20 +7031,23 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", + "http", "jsonrpsee", "log", "serde_json", "substrate-prometheus-endpoint", "tokio", + "tower", + "tower-http", ] [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", "hex", @@ -7204,7 +7066,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "directories", @@ -7215,7 +7077,6 @@ dependencies = [ "jsonrpsee", "log", "parity-scale-codec", - "parity-util-mem", "parking_lot 0.12.1", "pin-project", "rand 0.7.3", @@ -7275,12 +7136,10 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "log", "parity-scale-codec", - "parity-util-mem", - "parity-util-mem-derive", "parking_lot 0.12.1", "sc-client-api", "sp-core", @@ -7289,7 +7148,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", "libc", @@ -7308,7 +7167,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "chrono", "futures", @@ -7358,7 +7217,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "ansi_term", "atty", @@ -7389,7 +7248,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7400,7 +7259,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "futures", @@ -7408,7 +7267,6 @@ dependencies = [ "linked-hash-map", "log", "parity-scale-codec", - "parity-util-mem", "parking_lot 0.12.1", "sc-client-api", "sc-transaction-pool-api", @@ -7427,7 +7285,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "futures", @@ -7441,7 +7299,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", "futures-timer", @@ -7685,10 +7543,11 @@ name = "serai-node" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.0.30", + "clap 4.0.32", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", + "futures", "jsonrpsee", "log", "pallet-tendermint", @@ -7785,9 +7644,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.151" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] @@ -7804,9 +7663,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.151" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -7930,16 +7789,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" -[[package]] -name = "signal-hook" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -8041,6 +7890,7 @@ dependencies = [ "bytes", "flate2", "futures", + "http", "httparse", "log", "rand 0.8.5", @@ -8063,7 +7913,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "hash-db", "log", @@ -8081,7 +7931,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "blake2", "proc-macro-crate", @@ -8092,8 +7942,8 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", "scale-info", @@ -8105,8 +7955,8 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "6.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "integer-sqrt", "num-traits", @@ -8121,7 +7971,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", "sp-api", @@ -8133,7 +7983,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures", "log", @@ -8151,7 +8001,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "futures", @@ -8169,8 +8019,8 @@ dependencies = [ [[package]] name = "sp-core" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "array-bytes", "base58 0.2.0", @@ -8208,14 +8058,14 @@ dependencies = [ "substrate-bip39", "thiserror", "tiny-bip39", - "wasmi", + "wasmi 0.13.2", "zeroize", ] [[package]] name = "sp-core-hashing" -version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "5.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "blake2", "byteorder", @@ -8229,7 +8079,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "proc-macro2", "quote", @@ -8240,7 +8090,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -8248,8 +8098,8 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "5.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "proc-macro2", "quote", @@ -8258,8 +8108,8 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.12.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "0.13.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "environmental", "parity-scale-codec", @@ -8270,7 +8120,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "finality-grandpa", "log", @@ -8288,7 +8138,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -8301,10 +8151,11 @@ dependencies = [ [[package]] name = "sp-io" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "bytes", + "ed25519-dalek", "futures", "hash-db", "libsecp256k1", @@ -8327,8 +8178,8 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "lazy_static", "sp-core", @@ -8338,8 +8189,8 @@ dependencies = [ [[package]] name = "sp-keystore" -version = "0.12.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "0.13.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "futures", @@ -8356,7 +8207,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "thiserror", "zstd", @@ -8365,7 +8216,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "sp-api", "sp-core", @@ -8374,8 +8225,8 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "5.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "backtrace", "lazy_static", @@ -8385,7 +8236,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "rustc-hash", "serde", @@ -8394,15 +8245,14 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "either", "hash256-std-hasher", "impl-trait-for-tuples", "log", "parity-scale-codec", - "parity-util-mem", "paste", "rand 0.7.3", "scale-info", @@ -8417,8 +8267,8 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -8435,8 +8285,8 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "6.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "Inflector", "proc-macro-crate", @@ -8445,24 +8295,10 @@ dependencies = [ "syn", ] -[[package]] -name = "sp-sandbox" -version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" -dependencies = [ - "log", - "parity-scale-codec", - "sp-core", - "sp-io", - "sp-std", - "sp-wasm-interface", - "wasmi", -] - [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", "scale-info", @@ -8476,18 +8312,19 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", "scale-info", + "sp-core", "sp-runtime", "sp-std", ] [[package]] name = "sp-state-machine" -version = "0.12.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "0.13.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "hash-db", "log", @@ -8508,13 +8345,13 @@ dependencies = [ [[package]] name = "sp-std" -version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "5.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" [[package]] name = "sp-storage" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "impl-serde 0.4.0", "parity-scale-codec", @@ -8536,7 +8373,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "futures-timer", @@ -8551,8 +8388,8 @@ dependencies = [ [[package]] name = "sp-tracing" -version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "6.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", "sp-std", @@ -8564,7 +8401,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "sp-api", "sp-runtime", @@ -8573,7 +8410,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "async-trait", "log", @@ -8588,8 +8425,8 @@ dependencies = [ [[package]] name = "sp-trie" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "ahash", "hash-db", @@ -8612,7 +8449,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "impl-serde 0.4.0", "parity-scale-codec", @@ -8629,7 +8466,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -8639,21 +8476,21 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +version = "7.0.0" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "impl-trait-for-tuples", "log", "parity-scale-codec", "sp-std", - "wasmi", + "wasmi 0.13.2", "wasmtime", ] [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -8672,6 +8509,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" + [[package]] name = "spki" version = "0.6.0" @@ -8807,7 +8650,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "platforms 2.0.0", ] @@ -8815,7 +8658,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -8836,7 +8679,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "futures-util", "hyper", @@ -8849,7 +8692,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#881cfbc59c8b65bcccc9fa6187e5096ac3594e3a" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ "ansi_term", "build-helper", @@ -9248,6 +9091,41 @@ dependencies = [ "serde", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite 0.2.9", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -9261,6 +9139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", + "log", "pin-project-lite 0.2.9", "tracing-attributes", "tracing-core", @@ -9383,6 +9262,7 @@ dependencies = [ "smallvec", "thiserror", "tinyvec", + "tokio", "tracing", "url", ] @@ -9402,6 +9282,7 @@ dependencies = [ "resolv-conf", "smallvec", "thiserror", + "tokio", "tracing", "trust-dns-proto", ] @@ -9454,15 +9335,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.8" @@ -9557,16 +9429,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "value-bag" -version = "1.0.0-alpha.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" -dependencies = [ - "ctor", - "version_check", -] - [[package]] name = "vcpkg" version = "0.2.15" @@ -9705,6 +9567,15 @@ dependencies = [ "parity-wasm", ] +[[package]] +name = "wasm-instrument" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a47ecb37b9734d1085eaa5ae1a81e60801fd8c28d4cabdd8aedb982021918bc" +dependencies = [ + "parity-wasm", +] + [[package]] name = "wasm-opt" version = "0.110.2" @@ -9769,7 +9640,19 @@ checksum = "06c326c93fbf86419608361a2c925a31754cf109da1b8b55737070b4d6669422" dependencies = [ "parity-wasm", "wasmi-validation", - "wasmi_core", + "wasmi_core 0.2.1", +] + +[[package]] +name = "wasmi" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01bf50edb2ea9d922aa75a7bf3c15e26a6c9e2d18c56e862b49737a582901729" +dependencies = [ + "spin 0.9.4", + "wasmi_arena", + "wasmi_core 0.5.0", + "wasmparser-nostd", ] [[package]] @@ -9781,6 +9664,12 @@ dependencies = [ "parity-wasm", ] +[[package]] +name = "wasmi_arena" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ea379cbb0b41f3a9f0bf7b47036d036aae7f43383d8cc487d4deccf40dee0a" + [[package]] name = "wasmi_core" version = "0.2.1" @@ -9794,6 +9683,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "wasmi_core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5bf998ab792be85e20e771fe14182b4295571ad1d4f89d3da521c1bef5f597a" +dependencies = [ + "downcast-rs", + "libm 0.2.6", + "num-traits", +] + [[package]] name = "wasmparser" version = "0.89.1" @@ -9803,6 +9703,15 @@ dependencies = [ "indexmap", ] +[[package]] +name = "wasmparser-nostd" +version = "0.91.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c37f310b5a62bfd5ae7c0f1d8e6f98af16a5d6d84ba764e9c36439ec14e318b" +dependencies = [ + "indexmap-nostd", +] + [[package]] name = "wasmtime" version = "1.0.2" diff --git a/substrate/node/Cargo.toml b/substrate/node/Cargo.toml index 22dcbbcf..6f12d087 100644 --- a/substrate/node/Cargo.toml +++ b/substrate/node/Cargo.toml @@ -16,8 +16,11 @@ async-trait = "0.1" log = "0.4" +futures = { version = "0.3" } + clap = { version = "4", features = ["derive"] } -jsonrpsee = { version = "0.15", features = ["server"] } + +jsonrpsee = { version = "0.16", features = ["server"] } sp-core = { git = "https://github.com/serai-dex/substrate" } sp-application-crypto = { git = "https://github.com/serai-dex/substrate" } diff --git a/substrate/node/src/command_helper.rs b/substrate/node/src/command_helper.rs index d0de95b9..664a894c 100644 --- a/substrate/node/src/command_helper.rs +++ b/substrate/node/src/command_helper.rs @@ -88,8 +88,10 @@ pub fn create_benchmark_extrinsic( pub fn inherent_benchmark_data() -> Result { let mut inherent_data = InherentData::new(); - sp_timestamp::InherentDataProvider::new(Duration::from_millis(0).into()) - .provide_inherent_data(&mut inherent_data) - .map_err(|e| format!("creating inherent data: {e:?}"))?; + futures::executor::block_on( + sp_timestamp::InherentDataProvider::new(Duration::from_millis(0).into()) + .provide_inherent_data(&mut inherent_data), + ) + .map_err(|e| format!("creating inherent data: {e:?}"))?; Ok(inherent_data) } diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 9747950b..2b397ab0 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -18,9 +18,9 @@ use sp_version::NativeVersion; use sp_version::RuntimeVersion; use frame_support::{ - traits::{ConstU8, ConstU32, ConstU64}, + traits::{ConstBool, ConstU8, ConstU32, ConstU64}, weights::{ - constants::{RocksDbWeight, WEIGHT_PER_SECOND}, + constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND}, IdentityFee, Weight, }, dispatch::DispatchClass, @@ -117,7 +117,7 @@ parameter_types! { frame_system::limits::BlockLength::max_with_normal_ratio(BLOCK_SIZE, NORMAL_DISPATCH_RATIO); pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights::with_sensible_defaults( - (2u64 * WEIGHT_PER_SECOND).set_proof_size(u64::MAX), + Weight::from_ref_time(2u64 * WEIGHT_REF_TIME_PER_SECOND).set_proof_size(u64::MAX), NORMAL_DISPATCH_RATIO, ); @@ -214,6 +214,9 @@ impl pallet_contracts::Config for Runtime { type MaxCodeLen = ConstU32<{ 128 * 1024 }>; type MaxStorageKeyLen = ConstU32<128>; + + type UnsafeUnstableInterface = ConstBool; + type MaxDebugBufferLen = ConstU32<255>; } impl pallet_tendermint::Config for Runtime {} diff --git a/substrate/tendermint/client/src/authority/mod.rs b/substrate/tendermint/client/src/authority/mod.rs index 778f50d4..09242fce 100644 --- a/substrate/tendermint/client/src/authority/mod.rs +++ b/substrate/tendermint/client/src/authority/mod.rs @@ -405,7 +405,7 @@ impl Network for TendermintAuthority { let mut queue_write = self.import.queue.write().await; *self.import.importing_block.write().unwrap() = Some(hash); - queue_write.as_mut().unwrap().import_blocks( + queue_write.as_mut().unwrap().service_ref().import_blocks( BlockOrigin::ConsensusBroadcast, // TODO: Use BlockOrigin::Own when it's our block vec![IncomingBlock { hash, diff --git a/substrate/tendermint/client/src/tendermint.rs b/substrate/tendermint/client/src/tendermint.rs index 6e1b6f9e..58d0e292 100644 --- a/substrate/tendermint/client/src/tendermint.rs +++ b/substrate/tendermint/client/src/tendermint.rs @@ -97,7 +97,7 @@ impl TendermintImport { .create_inherent_data_providers(parent, ()) .await { - Ok(providers) => match providers.create_inherent_data() { + Ok(providers) => match providers.create_inherent_data().await { Ok(data) => Some(data), Err(err) => { warn!(target: "tendermint", "Failed to create inherent data: {}", err); diff --git a/substrate/tendermint/machine/Cargo.toml b/substrate/tendermint/machine/Cargo.toml index 4d269a7d..7184e057 100644 --- a/substrate/tendermint/machine/Cargo.toml +++ b/substrate/tendermint/machine/Cargo.toml @@ -18,7 +18,7 @@ parity-scale-codec = { version = "3.2", features = ["derive"] } futures = "0.3" tokio = { version = "1", features = ["macros", "sync", "time", "rt"] } -sp-runtime = { git = "https://github.com/serai-dex/substrate", version = "6.0.0", optional = true } +sp-runtime = { git = "https://github.com/serai-dex/substrate", version = "7.0.0", optional = true } [features] substrate = ["sp-runtime"] From 056dd1afcb16afad0d5919ceb3defdebdf9e5741 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 4 Jan 2023 06:07:58 -0500 Subject: [PATCH 02/74] Update README --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e2713106..363b0f20 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Serai Serai is a new DEX, built from the ground up, initially planning on listing -Bitcoin, Ethereum, Monero, DAI, offering a liquidity pool trading experience. -Funds are stored in an economically secured threshold multisig wallet. +Bitcoin, Ethereum, Monero, and DAI, offering a liquidity-pool-based trading +experience. Funds are stored in an economically secured threshold-multisig +wallet. [Getting Started](docs/Getting%20Started.md) @@ -10,6 +11,9 @@ Funds are stored in an economically secured threshold multisig wallet. - `docs`: Documentation on the Serai protocol. +- `common`: Crates containing utilities common to a variety of areas under + Serai, none neatly fitting under another category. + - `crypto`: A series of composable cryptographic libraries built around the `ff`/`group` APIs achieving a variety of tasks. These range from generic infrastructure, to our IETF-compliant FROST implementation, to a DLEq proof as @@ -22,13 +26,14 @@ Funds are stored in an economically secured threshold multisig wallet. - `processor`: A generic chain processor to process data for Serai and process events from Serai, executing transactions as expected and needed. -- `contracts`: Smart Contracts implementing Serai's functionality. - - `substrate`: Substrate crates used to instantiate the Serai network. +- `deploy`: Scripts to deploy a Serai node/test environment. + ### Links - [Twitter](https://twitter.com/SeraiDEX): https://twitter.com/SeraiDEX +- [Mastodon](https://cryptodon.lol/@serai): https://cryptodon.lol/@serai - [Discord](https://discord.gg/mpEUtJR3vz): https://discord.gg/mpEUtJR3vz - [Matrix](https://matrix.to/#/#serai:matrix.org): https://matrix.to/#/#serai:matrix.org From 52913a6e8d6c8241939aa049689f525a527a5b67 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 4 Jan 2023 06:17:00 -0500 Subject: [PATCH 03/74] Reorder coins in README by market cap --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 363b0f20..5b90cb10 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Serai Serai is a new DEX, built from the ground up, initially planning on listing -Bitcoin, Ethereum, Monero, and DAI, offering a liquidity-pool-based trading +Bitcoin, Ethereum, DAI, and Monero, offering a liquidity-pool-based trading experience. Funds are stored in an economically secured threshold-multisig wallet. From e979883f2d02dc38c6ee012aed5865fa0fa8eb79 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 4 Jan 2023 22:52:41 -0500 Subject: [PATCH 04/74] Initial validator sets pallet (#187) * Initial work on a Validator Sets pallet * Update Validator Set docs per current discussions * Update validator-sets primitives and storage handling * Add validator set pallets to deny.toml * Remove Curve from primitives Since we aren't reusing keys across coins, there's no reason for it to be on-chain (as previously planned). * Update documentation on Validator Sets * Use Twox64Concat instead of Identity Ensures an even distribution of keys. While xxhash is breakable, these keys aren't manipulatable by users. * Add math ops on Amount and define a coin as 1e8 * Add validator-sets to the runtime and remove contracts Also removes the randomness pallet which was only required by the contracts runtime. Does not remove the contracts folder yet so they can still be referred to while validator-sets is under development. Does remove them from Cargo.toml. * Add vote function to validator-sets * Remove contracts folder * Create an event for the Validator Sets pallet * Remove old contracts crates from deny.toml * Remove line from staking branch * Remove staking from runtime * Correct VS Config in runtime * cargo update * Resolve a few PR comments on terminology * Create a serai-primitives crate Move types such as Amount/Coin out of validator-sets. Will be expanded in the future. * Fixes for last commit * Don't reserve set 0 * Further fixes * Add files meant for last commit * Remove Staking transfer --- Cargo.lock | 452 +++--------------- Cargo.toml | 13 +- contracts/extension/Cargo.toml | 24 - contracts/extension/src/lib.rs | 122 ----- contracts/multisig/Cargo.toml | 48 -- contracts/multisig/lib.rs | 356 -------------- deny.toml | 6 +- docs/Serai.md | 21 +- docs/protocol/Constants.md | 54 +-- docs/protocol/Multisig.md | 35 -- docs/protocol/Staking.md | 19 + docs/protocol/Validator Sets.md | 89 +++- docs/protocol/Validators.md | 44 -- substrate/node/Cargo.toml | 6 +- substrate/node/src/chain_spec.rs | 11 +- substrate/runtime/Cargo.toml | 10 +- substrate/runtime/src/lib.rs | 43 +- substrate/serai/primitives/Cargo.toml | 25 + .../serai/primitives}/LICENSE | 0 substrate/serai/primitives/src/lib.rs | 36 ++ substrate/validator-sets/pallet/Cargo.toml | 41 ++ .../validator-sets/pallet}/LICENSE | 0 substrate/validator-sets/pallet/src/lib.rs | 207 ++++++++ .../validator-sets/primitives/Cargo.toml | 25 + substrate/validator-sets/primitives/LICENSE | 15 + .../validator-sets/primitives/src/lib.rs | 21 + 26 files changed, 572 insertions(+), 1151 deletions(-) delete mode 100644 contracts/extension/Cargo.toml delete mode 100644 contracts/extension/src/lib.rs delete mode 100644 contracts/multisig/Cargo.toml delete mode 100644 contracts/multisig/lib.rs delete mode 100644 docs/protocol/Multisig.md create mode 100644 docs/protocol/Staking.md delete mode 100644 docs/protocol/Validators.md create mode 100644 substrate/serai/primitives/Cargo.toml rename {contracts/extension => substrate/serai/primitives}/LICENSE (100%) create mode 100644 substrate/serai/primitives/src/lib.rs create mode 100644 substrate/validator-sets/pallet/Cargo.toml rename {contracts/multisig => substrate/validator-sets/pallet}/LICENSE (100%) create mode 100644 substrate/validator-sets/pallet/src/lib.rs create mode 100644 substrate/validator-sets/primitives/Cargo.toml create mode 100644 substrate/validator-sets/primitives/LICENSE create mode 100644 substrate/validator-sets/primitives/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3d2949d7..eb4880b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,14 +137,9 @@ dependencies = [ [[package]] name = "array-bytes" -version = "4.1.0" -source = "git+https://github.com/hack-ink/array-bytes?rev=994cd29b66bd2ab5c8c15f0b15a1618d4bb2d94c#994cd29b66bd2ab5c8c15f0b15a1618d4bb2d94c" - -[[package]] -name = "array-init" -version = "2.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" +checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" [[package]] name = "arrayref" @@ -274,7 +269,7 @@ checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ "futures", "pharos", - "rustc_version 0.4.0", + "rustc_version", ] [[package]] @@ -1911,7 +1906,7 @@ dependencies = [ "fixed-hash", "impl-codec", "impl-rlp", - "impl-serde 0.4.0", + "impl-serde", "scale-info", "tiny-keccak", ] @@ -1945,7 +1940,7 @@ dependencies = [ "fixed-hash", "impl-codec", "impl-rlp", - "impl-serde 0.4.0", + "impl-serde", "primitive-types", "scale-info", "uint", @@ -3240,15 +3235,6 @@ dependencies = [ "rlp", ] -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - [[package]] name = "impl-serde" version = "0.4.0" @@ -3286,12 +3272,6 @@ dependencies = [ "serde", ] -[[package]] -name = "indexmap-nostd" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" - [[package]] name = "indicatif" version = "0.16.2" @@ -3304,184 +3284,6 @@ dependencies = [ "regex", ] -[[package]] -name = "ink_allocator" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9588a59a0e8997c0b2153cd11b5aaa77c06a0537a6b18f3811d1f1aa098b12" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ink_engine" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487c3b390b7feb0620496b0cd38683433c7d7e6946b1caabda51e1f23eb24b30" -dependencies = [ - "blake2", - "derive_more", - "parity-scale-codec", - "rand 0.8.5", - "secp256k1", - "sha2 0.10.6", - "sha3", -] - -[[package]] -name = "ink_env" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a891d34301a3dbb1c7b7424c49ae184282b163491c54f9acd17fcbe14a80447b" -dependencies = [ - "arrayref", - "blake2", - "cfg-if", - "derive_more", - "ink_allocator", - "ink_engine", - "ink_metadata", - "ink_prelude", - "ink_primitives", - "num-traits", - "parity-scale-codec", - "paste", - "rand 0.8.5", - "rlibc", - "scale-info", - "secp256k1", - "sha2 0.10.6", - "sha3", - "static_assertions", -] - -[[package]] -name = "ink_lang" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cca26e374e0f89c82cf5dabb4309ef3c76a01659ad95186f4e84455c5f4621a0" -dependencies = [ - "derive_more", - "ink_env", - "ink_lang_macro", - "ink_prelude", - "ink_primitives", - "ink_storage", - "parity-scale-codec", -] - -[[package]] -name = "ink_lang_codegen" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fe57826726d89c84fe0b1fafe0dee328f58c8e927be40f0290f04602aacc45c" -dependencies = [ - "blake2", - "derive_more", - "either", - "heck", - "impl-serde 0.3.2", - "ink_lang_ir", - "itertools", - "parity-scale-codec", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ink_lang_ir" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47d16b2a5340df90f11b2ec2242b37907f5c8396dbbc72c52ec9f2b1a8c90c8" -dependencies = [ - "blake2", - "either", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ink_lang_macro" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b858be42ac6cde2c15ce6d7fa75cef59b64a3baf37f7105f39208f2b84dadb" -dependencies = [ - "ink_lang_codegen", - "ink_lang_ir", - "ink_primitives", - "parity-scale-codec", - "proc-macro2", - "syn", -] - -[[package]] -name = "ink_metadata" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74913aaed5751f5615af4631b7559328b8ed56c9cb821b89e14af0706176e849" -dependencies = [ - "derive_more", - "impl-serde 0.3.2", - "ink_prelude", - "ink_primitives", - "scale-info", - "serde", -] - -[[package]] -name = "ink_prelude" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f031e6b8495594a7288b089bf4122e76c26b994959d1b2b693bdfe846b14c0e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ink_primitives" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12cf42dce81d060401c7cec95a392ad6d3c2f18661fa3083f619ce135133c33" -dependencies = [ - "cfg-if", - "ink_prelude", - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "ink_storage" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c0a98b6acbd79eedf44720412437d713e7195d1407822604de5885b0ee6c7e1" -dependencies = [ - "array-init", - "cfg-if", - "derive_more", - "ink_env", - "ink_metadata", - "ink_prelude", - "ink_primitives", - "ink_storage_derive", - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "ink_storage_derive" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "babf1d8903dc9219ad8e8aa181eddb919d9794aad1da23ccdce770925b7de2ba" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "inout" version = "0.1.3" @@ -5102,70 +4904,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-contracts" -version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" -dependencies = [ - "bitflags", - "frame-benchmarking", - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "log", - "pallet-contracts-primitives", - "pallet-contracts-proc-macro", - "parity-scale-codec", - "rand 0.8.5", - "scale-info", - "serde", - "smallvec", - "sp-api", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "wasm-instrument 0.4.0", - "wasmi 0.20.0", - "wasmparser-nostd", -] - -[[package]] -name = "pallet-contracts-primitives" -version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" -dependencies = [ - "bitflags", - "parity-scale-codec", - "sp-runtime", - "sp-std", - "sp-weights", -] - -[[package]] -name = "pallet-contracts-proc-macro" -version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pallet-randomness-collective-flip" -version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "safe-mix", - "scale-info", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-session" version = "4.0.0-dev" @@ -5500,7 +5238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" dependencies = [ "futures", - "rustc_version 0.4.0", + "rustc_version", ] [[package]] @@ -5717,7 +5455,7 @@ dependencies = [ "fixed-hash", "impl-codec", "impl-rlp", - "impl-serde 0.4.0", + "impl-serde", "scale-info", "uint", ] @@ -6211,7 +5949,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin 0.5.2", + "spin", "untrusted", "web-sys", "winapi", @@ -6226,12 +5964,6 @@ dependencies = [ "digest 0.10.6", ] -[[package]] -name = "rlibc" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" - [[package]] name = "rlp" version = "0.5.2" @@ -6317,15 +6049,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.0" @@ -6419,15 +6142,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" -[[package]] -name = "safe-mix" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d3d055a2582e6b00ed7a31c1524040aa391092bf636328350813f3a0605215c" -dependencies = [ - "rustc_version 0.2.3", -] - [[package]] name = "salsa20" version = "0.10.2" @@ -6663,7 +6377,7 @@ dependencies = [ "sp-version", "sp-wasm-interface", "tracing", - "wasmi 0.13.2", + "wasmi", ] [[package]] @@ -6675,8 +6389,8 @@ dependencies = [ "sp-maybe-compressed-blob", "sp-wasm-interface", "thiserror", - "wasm-instrument 0.3.0", - "wasmi 0.13.2", + "wasm-instrument", + "wasmi", ] [[package]] @@ -6689,7 +6403,7 @@ dependencies = [ "sc-executor-common", "sp-runtime-interface", "sp-wasm-interface", - "wasmi 0.13.2", + "wasmi", ] [[package]] @@ -7484,15 +7198,6 @@ dependencies = [ "semver-parser", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.16" @@ -7514,30 +7219,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7" -[[package]] -name = "serai-extension" -version = "0.1.0" -dependencies = [ - "ink_env", - "ink_lang", - "parity-scale-codec", -] - -[[package]] -name = "serai-multisig" -version = "0.1.0" -dependencies = [ - "ink_env", - "ink_lang", - "ink_metadata", - "ink_primitives", - "ink_storage", - "lazy_static", - "parity-scale-codec", - "scale-info", - "serai-extension", -] - [[package]] name = "serai-node" version = "0.1.0" @@ -7568,6 +7249,7 @@ dependencies = [ "sc-tendermint", "sc-transaction-pool", "sc-transaction-pool-api", + "serai-primitives", "serai-runtime", "sp-api", "sp-application-crypto", @@ -7583,6 +7265,18 @@ dependencies = [ "sp-timestamp", "substrate-build-script-utils", "substrate-frame-rpc-system", + "validator-sets-pallet", +] + +[[package]] +name = "serai-primitives" +version = "0.1.0" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-std", ] [[package]] @@ -7617,9 +7311,6 @@ dependencies = [ "frame-system-rpc-runtime-api", "hex-literal", "pallet-balances", - "pallet-contracts", - "pallet-contracts-primitives", - "pallet-randomness-collective-flip", "pallet-session", "pallet-tendermint", "pallet-timestamp", @@ -7640,6 +7331,7 @@ dependencies = [ "sp-transaction-pool", "sp-version", "substrate-wasm-builder", + "validator-sets-pallet", ] [[package]] @@ -7865,7 +7557,7 @@ dependencies = [ "curve25519-dalek 4.0.0-pre.5", "rand_core 0.6.4", "ring", - "rustc_version 0.4.0", + "rustc_version", "sha2 0.10.6", "subtle", ] @@ -8032,7 +7724,7 @@ dependencies = [ "futures", "hash-db", "hash256-std-hasher", - "impl-serde 0.4.0", + "impl-serde", "lazy_static", "libsecp256k1", "log", @@ -8058,7 +7750,7 @@ dependencies = [ "substrate-bip39", "thiserror", "tiny-bip39", - "wasmi 0.13.2", + "wasmi", "zeroize", ] @@ -8353,7 +8045,7 @@ name = "sp-storage" version = "7.0.0" source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ - "impl-serde 0.4.0", + "impl-serde", "parity-scale-codec", "ref-cast", "serde", @@ -8451,7 +8143,7 @@ name = "sp-version" version = "5.0.0" source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" dependencies = [ - "impl-serde 0.4.0", + "impl-serde", "parity-scale-codec", "parity-wasm", "scale-info", @@ -8483,7 +8175,7 @@ dependencies = [ "log", "parity-scale-codec", "sp-std", - "wasmi 0.13.2", + "wasmi", "wasmtime", ] @@ -8509,12 +8201,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spin" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" - [[package]] name = "spki" version = "0.6.0" @@ -9423,6 +9109,29 @@ dependencies = [ "serde", ] +[[package]] +name = "validator-sets-pallet" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serai-primitives", + "validator-sets-primitives", +] + +[[package]] +name = "validator-sets-primitives" +version = "0.1.0" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-std", +] + [[package]] name = "valuable" version = "0.1.0" @@ -9567,15 +9276,6 @@ dependencies = [ "parity-wasm", ] -[[package]] -name = "wasm-instrument" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a47ecb37b9734d1085eaa5ae1a81e60801fd8c28d4cabdd8aedb982021918bc" -dependencies = [ - "parity-wasm", -] - [[package]] name = "wasm-opt" version = "0.110.2" @@ -9640,19 +9340,7 @@ checksum = "06c326c93fbf86419608361a2c925a31754cf109da1b8b55737070b4d6669422" dependencies = [ "parity-wasm", "wasmi-validation", - "wasmi_core 0.2.1", -] - -[[package]] -name = "wasmi" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01bf50edb2ea9d922aa75a7bf3c15e26a6c9e2d18c56e862b49737a582901729" -dependencies = [ - "spin 0.9.4", - "wasmi_arena", - "wasmi_core 0.5.0", - "wasmparser-nostd", + "wasmi_core", ] [[package]] @@ -9664,12 +9352,6 @@ dependencies = [ "parity-wasm", ] -[[package]] -name = "wasmi_arena" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ea379cbb0b41f3a9f0bf7b47036d036aae7f43383d8cc487d4deccf40dee0a" - [[package]] name = "wasmi_core" version = "0.2.1" @@ -9683,17 +9365,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "wasmi_core" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5bf998ab792be85e20e771fe14182b4295571ad1d4f89d3da521c1bef5f597a" -dependencies = [ - "downcast-rs", - "libm 0.2.6", - "num-traits", -] - [[package]] name = "wasmparser" version = "0.89.1" @@ -9703,15 +9374,6 @@ dependencies = [ "indexmap", ] -[[package]] -name = "wasmparser-nostd" -version = "0.91.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c37f310b5a62bfd5ae7c0f1d8e6f98af16a5d6d84ba764e9c36439ec14e318b" -dependencies = [ - "indexmap-nostd", -] - [[package]] name = "wasmtime" version = "1.0.2" @@ -10130,7 +9792,7 @@ dependencies = [ "futures", "js-sys", "pharos", - "rustc_version 0.4.0", + "rustc_version", "send_wrapper", "thiserror", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index df9adc65..7cdec0c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,11 @@ members = [ "processor", + "substrate/serai/primitives", + + "substrate/validator-sets/primitives", + "substrate/validator-sets/pallet", + "substrate/tendermint/machine", "substrate/tendermint/primitives", "substrate/tendermint/client", @@ -29,9 +34,6 @@ members = [ "substrate/runtime", "substrate/node", - - "contracts/extension", - "contracts/multisig", ] # Always compile Monero (and a variety of dependencies) with optimizations due @@ -53,8 +55,3 @@ monero-serai = { opt-level = 3 } [profile.release] panic = "unwind" - -[patch.crates-io] -# array-bytes 4.1.0 is GPL-3.0. -# array-bytes git, which has no code changes, includes a dual-license under Apache-2.0. -array-bytes = { git = "https://github.com/hack-ink/array-bytes", rev = "994cd29b66bd2ab5c8c15f0b15a1618d4bb2d94c" } diff --git a/contracts/extension/Cargo.toml b/contracts/extension/Cargo.toml deleted file mode 100644 index 9272659e..00000000 --- a/contracts/extension/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "serai-extension" -version = "0.1.0" -description = "An ink! extension for exposing Serai to ink" -license = "AGPL-3.0-only" -repository = "https://github.com/serai-dex/serai/tree/develop/contracts/extension" -authors = ["Luke Parker "] -edition = "2021" -publish = false - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[dependencies] -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } - -ink_env = { version = "3", default-features = false } -ink_lang = { version = "3", default-features = false } - -[features] -default = ["std"] -std = ["ink_env/std"] -ink-as-dependency = [] diff --git a/contracts/extension/src/lib.rs b/contracts/extension/src/lib.rs deleted file mode 100644 index 1c5a34bc..00000000 --- a/contracts/extension/src/lib.rs +++ /dev/null @@ -1,122 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -use ink_lang as ink; -use ink_env::{Environment, DefaultEnvironment, AccountId}; - -pub type Curve = u16; -pub type Coin = u32; -pub type GlobalValidatorSetId = u32; -pub type ValidatorSetIndex = u8; -pub type Key = Vec; - -#[ink::chain_extension] -pub trait SeraiExtension { - type ErrorCode = (); - - /// Returns the ID for the current global validator set. - #[ink(extension = 0, handle_status = false, returns_result = false)] - fn global_validator_set_id() -> GlobalValidatorSetId; - - /// Returns the amount of active validator sets within the global validator set. - #[ink(extension = 1, handle_status = false, returns_result = false)] - fn validator_sets() -> u8; - - /// Returns the amount of key shares used within the specified validator set. - #[ink(extension = 2, handle_status = false, returns_result = false)] - fn validator_set_shares(set: ValidatorSetIndex) -> u16; - - /// Returns the validator set the specified account is in, along with their amount of shares in - /// that validator set, if they are in a current validator - #[ink(extension = 3, handle_status = false, returns_result = false)] - fn active_validator(account: &AccountId) -> Option<(ValidatorSetIndex, u16)>; -} - -pub struct SeraiEnvironment; -impl Environment for SeraiEnvironment { - const MAX_EVENT_TOPICS: usize = ::MAX_EVENT_TOPICS; - - type AccountId = ::AccountId; - type Balance = ::Balance; - type Hash = ::Hash; - type BlockNumber = ::BlockNumber; - type Timestamp = ::Timestamp; - - type ChainExtension = SeraiExtension; -} - -pub fn test_validators() -> Vec { - vec![ - AccountId::from([1; 32]), - AccountId::from([2; 32]), - AccountId::from([3; 32]), - AccountId::from([4; 32]), - AccountId::from([5; 32]), - ] -} - -pub fn test_register() { - struct ExtensionId; - impl ink_env::test::ChainExtension for ExtensionId { - fn func_id(&self) -> u32 { - 0 - } - - fn call(&mut self, _: &[u8], output: &mut Vec) -> u32 { - // Non-0 global validator set ID - scale::Encode::encode_to(&1u32, output); - 0 - } - } - ink_env::test::register_chain_extension(ExtensionId); - - struct ExtensionSets; - impl ink_env::test::ChainExtension for ExtensionSets { - fn func_id(&self) -> u32 { - 1 - } - - fn call(&mut self, _: &[u8], output: &mut Vec) -> u32 { - // 1 validator set - scale::Encode::encode_to(&1u8, output); - 0 - } - } - ink_env::test::register_chain_extension(ExtensionSets); - - struct ExtensionShares; - impl ink_env::test::ChainExtension for ExtensionShares { - fn func_id(&self) -> u32 { - 2 - } - - fn call(&mut self, _: &[u8], output: &mut Vec) -> u32 { - // 1 key share per validator - scale::Encode::encode_to(&u16::try_from(test_validators().len()).unwrap(), output); - 0 - } - } - ink_env::test::register_chain_extension(ExtensionShares); - - struct ExtensionActive; - impl ink_env::test::ChainExtension for ExtensionActive { - fn func_id(&self) -> u32 { - 3 - } - - fn call(&mut self, input: &[u8], output: &mut Vec) -> u32 { - use scale::Decode; - let potential = AccountId::decode(&mut &input[1 ..]).unwrap(); // TODO: Why is this [1 ..]? - - let mut presence = false; - for validator in test_validators() { - if potential == validator { - presence = true; - } - } - // Validator set 0, 1 key share - scale::Encode::encode_to(&Some((0u8, 1u16)).filter(|_| presence), output); - 0 - } - } - ink_env::test::register_chain_extension(ExtensionActive); -} diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml deleted file mode 100644 index 6fb4d08b..00000000 --- a/contracts/multisig/Cargo.toml +++ /dev/null @@ -1,48 +0,0 @@ -[package] -name = "serai-multisig" -version = "0.1.0" -description = "An ink! tracker for Serai's current multisig" -license = "AGPL-3.0-only" -repository = "https://github.com/serai-dex/serai/tree/develop/contracts/multisig" -authors = ["Luke Parker "] -edition = "2021" -publish = false - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[lib] -name = "serai_multisig" -path = "lib.rs" -crate-type = ["cdylib"] - -[dependencies] -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2", default-features = false, features = ["derive"], optional = true } - -ink_primitives = { version = "3", default-features = false } -ink_metadata = { version = "3", default-features = false, features = ["derive"], optional = true } -ink_env = { version = "3", default-features = false } -ink_storage = { version = "3", default-features = false } -ink_lang = { version = "3", default-features = false } - -serai-extension = { path = "../extension", default-features = false } - -[dev-dependencies] -lazy_static = "1" - -[features] -default = ["std"] -std = [ - "scale/std", - "scale-info/std", - - "ink_primitives/std", - "ink_metadata/std", - "ink_env/std", - "ink_storage/std", - - "serai-extension/std", -] -ink-as-dependency = [] diff --git a/contracts/multisig/lib.rs b/contracts/multisig/lib.rs deleted file mode 100644 index 62167a42..00000000 --- a/contracts/multisig/lib.rs +++ /dev/null @@ -1,356 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -use ink_lang as ink; - -use serai_extension::{Curve, GlobalValidatorSetId, ValidatorSetIndex, Key}; - -type KeysHash = [u8; 32]; - -#[allow(clippy::all)] -#[ink::contract(env = serai_extension::SeraiEnvironment)] -mod multisig { - use scale::Encode; - - use ink_storage::{traits::SpreadAllocate, Mapping}; - use ink_env::{hash::Blake2x256, hash_encoded}; - - use super::*; - - /// A contract which tracks the current multisig keys. - /// Mapping of each validator set to their multisigs. - #[ink(storage)] - #[derive(SpreadAllocate)] - pub struct Multisig { - /// Global validator set ID under which this multisig was updated. - /// Used to track if the multisig has been updated to the latest instantiation of a validator - /// set or not. - /// May be behind, and still healthy, if a validator set didn't change despite the global - /// validator set doing so. - updated_at: Mapping, - /// Mapping from a curve's index to the multisig's current public key for it, if it has one. - // This is a mapping due to ink's eager loading. Considering we're right now only considering - // Secp256k1 and Ed25519, it may be notably more efficient to use a Vec here. - // In practice, we're likely discussing up to 7 curves in total, so it may always be better to - // simply use a Vec here, especially since it'd be Vec>. - keys: Mapping<(ValidatorSetIndex, Curve), Key>, - /// Validator + Keys -> Voted already or not. - /// Prevents voting multiple times on the same set of keys. - voted: Mapping<(AccountId, KeysHash), ()>, - /// Global Validator Set ID + Validator + Keys -> Vote Count. - /// Including the GVSID locks it to a specific time period, preventing a validator from joining - /// a set, voting on old keys, and then moving their bond to a new account to vote again. - votes: Mapping<(GlobalValidatorSetId, ValidatorSetIndex, KeysHash), u16>, - } - - /// Event emitted when a new set of multisig keys is voted on. - #[ink(event)] - pub struct Vote { - /// Validator who issued the vote. - #[ink(topic)] - validator: AccountId, - /// Global validator set ID under which keys are being generated. - #[ink(topic)] - global_validator_set: GlobalValidatorSetId, - /// Validator set for which keys are being generated. - #[ink(topic)] - validator_set: ValidatorSetIndex, - /// Hash of the keys voted on. - #[ink(topic)] - hash: KeysHash, - /// Keys voted on. Only present in the first event for a given set of keys. - keys: Option>>, - } - - /// Event emitted when the new keys are fully generated for a validator set, having been fully - /// voted on. - #[ink(event)] - pub struct KeyGen { - #[ink(topic)] - global_validator_set: GlobalValidatorSetId, - #[ink(topic)] - validator_set: ValidatorSetIndex, - #[ink(topic)] - hash: KeysHash, - } - - /// The Multisig error types. - #[derive(Debug, PartialEq, Eq, scale::Encode, scale::Decode)] - #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] - pub enum Error { - /// Returned if a validator set hasn't had keys registered for it yet. - NonExistentValidatorSet, - /// Returned if a validator set and curve index doesn't have a key registered for it. - NonExistentKey, - /// Returned if a curve index doesn't exist. - NonExistentCurve, - /// Returned if a non-validator is voting. - NotValidator, - /// Returned if this validator set already generated keys. - AlreadyGeneratedKeys, - /// Returned if this validator has already voted for these keys. - AlreadyVoted, - } - - /// The Multisig result type. - pub type Result = core::result::Result; - - impl Multisig { - /// Deploys the Multisig contract. - #[ink(constructor)] - pub fn new() -> Self { - ink_lang::utils::initialize_contract(|_| {}) - } - - /// Global validator set ID under which a validator set updated their multisig. - #[ink(message)] - pub fn updated_at(&self, validator_set: ValidatorSetIndex) -> Result { - self.updated_at.get(validator_set).ok_or(Error::NonExistentValidatorSet) - } - - /// Returns the key currently in-use for a given validator set and curve. - /// This is then bound to a given chain by applying a network-specific additive offset, as done - /// by the processor. Each chain then has its own way of receiving funds to these keys, leaving - /// this not for usage by wallets, nor the processor which is expected to track events for this - /// information. This is really solely for debugging purposes. - #[ink(message)] - pub fn key(&self, validator_set: ValidatorSetIndex, curve: Curve) -> Result { - self.keys.get((validator_set, curve)).ok_or(Error::NonExistentKey) - } - - // TODO: voted - // TODO: votes - - fn hash(value: &T) -> KeysHash { - let mut output = KeysHash::default(); - hash_encoded::(value, &mut output); - output - } - - /// Vote for a given set of keys. - #[ink(message)] - pub fn vote(&mut self, keys: Vec>) -> Result<()> { - if keys.len() > 256 { - Err(Error::NonExistentCurve)?; - } - - // Make sure they're a valid validator. - let validator = self.env().caller(); - let active_validator = self.env().extension().active_validator(&validator); - if active_validator.is_none() { - Err(Error::NotValidator)?; - } - let (validator_set, shares) = active_validator.unwrap(); - - // Prevent a validator set from generating keys multiple times. Only the first-voted-in keys - // should be acknowledged. - let global_validator_set = self.env().extension().global_validator_set_id(); - if self.updated_at.get(validator_set) == Some(global_validator_set) { - Err(Error::AlreadyGeneratedKeys)?; - } - - // Prevent a validator from voting on keys multiple times. - let keys_hash = Self::hash(&keys); - if self.voted.get((validator, keys_hash)).is_some() { - Err(Error::AlreadyVoted)?; - } - self.voted.insert((validator, keys_hash), &()); - - let votes = - if let Some(votes) = self.votes.get((global_validator_set, validator_set, keys_hash)) { - self.env().emit_event(Vote { - validator, - global_validator_set, - validator_set, - hash: keys_hash, - keys: None, - }); - votes + shares - } else { - self.env().emit_event(Vote { - validator, - global_validator_set, - validator_set, - hash: keys_hash, - keys: Some(keys.clone()), - }); - shares - }; - // We could skip writing this if we've reached consensus, yet best to keep our ducks in a row - self.votes.insert((global_validator_set, validator_set, keys_hash), &votes); - - // If we've reached consensus, action this. - if votes == self.env().extension().validator_set_shares(validator_set) { - self.updated_at.insert(validator_set, &global_validator_set); - for (k, key) in keys.iter().enumerate() { - if let Some(key) = key { - self.keys.insert((validator_set, Curve::try_from(k).unwrap()), key); - } - } - self.env().emit_event(KeyGen { global_validator_set, validator_set, hash: keys_hash }); - } - - Ok(()) - } - } - - #[cfg(test)] - mod tests { - use lazy_static::lazy_static; - - use ink_env::{ - hash::{CryptoHash, Blake2x256}, - AccountId, - topics::PrefixedValue, - }; - use ink_lang as ink; - - use serai_extension::{test_validators, test_register}; - - use super::*; - - type Event = ::Type; - - lazy_static! { - static ref EXPECTED_GLOBAL_VALIDATOR_SET: GlobalValidatorSetId = 1; - static ref EXPECTED_VALIDATOR_SET: ValidatorSetIndex = 0; - static ref KEYS: Vec> = vec![Some(vec![0, 1]), Some(vec![2, 3])]; - static ref EXPECTED_HASH: KeysHash = { - let mut hash = KeysHash::default(); - ink_env::hash_encoded::(&*KEYS, &mut hash); - hash - }; - } - - fn hash_prefixed(prefixed: PrefixedValue) -> [u8; 32] { - let encoded = prefixed.encode(); - let mut hash = KeysHash::default(); - if encoded.len() < 32 { - hash[.. encoded.len()].copy_from_slice(&encoded); - } else { - Blake2x256::hash(&encoded, &mut hash); - } - hash - } - - fn assert_vote( - event: &ink_env::test::EmittedEvent, - expected_validator: AccountId, - expected_keys: Option<()>, - ) { - let decoded_event = ::decode(&mut &event.data[..]) - .expect("encountered invalid contract event data buffer"); - - if let Event::Vote(Vote { - validator, - global_validator_set, - validator_set, - hash, - keys: actual_keys, - }) = decoded_event - { - assert_eq!(validator, expected_validator); - assert_eq!(global_validator_set, *EXPECTED_GLOBAL_VALIDATOR_SET); - assert_eq!(validator_set, *EXPECTED_VALIDATOR_SET); - assert_eq!(hash, *EXPECTED_HASH); - assert_eq!(actual_keys.as_ref(), expected_keys.map(|_| &*KEYS)); - } else { - panic!("invalid Vote event") - } - - let expected_topics = vec![ - hash_prefixed(PrefixedValue { prefix: b"", value: b"Multisig::Vote" }), - hash_prefixed(PrefixedValue { - prefix: b"Multisig::Vote::validator", - value: &expected_validator, - }), - hash_prefixed(PrefixedValue { - prefix: b"Multisig::Vote::global_validator_set", - value: &*EXPECTED_GLOBAL_VALIDATOR_SET, - }), - hash_prefixed(PrefixedValue { - prefix: b"Multisig::Vote::validator_set", - value: &*EXPECTED_VALIDATOR_SET, - }), - hash_prefixed(PrefixedValue { prefix: b"Multisig::Vote::hash", value: &*EXPECTED_HASH }), - ]; - - for (n, (actual_topic, expected_topic)) in - event.topics.iter().zip(expected_topics).enumerate() - { - assert_eq!(actual_topic, &expected_topic, "encountered invalid topic at {}", n); - } - } - - fn assert_key_gen(event: &ink_env::test::EmittedEvent) { - let decoded_event = ::decode(&mut &event.data[..]) - .expect("encountered invalid contract event data buffer"); - - if let Event::KeyGen(KeyGen { global_validator_set, validator_set, hash }) = decoded_event { - assert_eq!(global_validator_set, *EXPECTED_GLOBAL_VALIDATOR_SET); - assert_eq!(validator_set, *EXPECTED_VALIDATOR_SET); - assert_eq!(hash, *EXPECTED_HASH); - } else { - panic!("invalid KeyGen event") - } - - let expected_topics = vec![ - hash_prefixed(PrefixedValue { prefix: b"", value: b"Multisig::KeyGen" }), - hash_prefixed(PrefixedValue { - prefix: b"Multisig::KeyGen::global_validator_set", - value: &*EXPECTED_GLOBAL_VALIDATOR_SET, - }), - hash_prefixed(PrefixedValue { - prefix: b"Multisig::KeyGen::validator_set", - value: &*EXPECTED_VALIDATOR_SET, - }), - hash_prefixed(PrefixedValue { prefix: b"Multisig::KeyGen::hash", value: &*EXPECTED_HASH }), - ]; - - for (n, (actual_topic, expected_topic)) in - event.topics.iter().zip(expected_topics).enumerate() - { - assert_eq!(actual_topic, &expected_topic, "encountered invalid topic at {}", n); - } - } - - /// The default constructor does its job. - #[ink::test] - fn new() { - let multisig = Multisig::new(); - assert_eq!(multisig.updated_at(0), Err(Error::NonExistentValidatorSet)); - } - - /// Non-existent keys error accordingly. - #[ink::test] - fn non_existent_key() { - assert_eq!(Multisig::new().key(0, 0), Err(Error::NonExistentKey)); - } - - #[ink::test] - fn success() { - test_register(); - let mut multisig = Multisig::new(); - - // Test voting on keys works without issue, emitting the keys for the first vote - let mut emitted_events = vec![]; - for (i, validator) in test_validators().iter().enumerate() { - ink_env::test::set_caller::(*validator); - multisig.vote(KEYS.clone()).unwrap(); - - emitted_events = ink_env::test::recorded_events().collect::>(); - // If this is the last validator, it should also trigger a keygen event, hence the + 1 - assert_eq!(emitted_events.len(), (i + 1) + (i / (test_validators().len() - 1))); - assert_vote( - &emitted_events[i], - *validator, - // Only the first event for this hash should have the keys - Some(()).filter(|_| i == 0), - ); - } - - // Since this should have key gen'd, verify that - assert_eq!(multisig.updated_at(0).unwrap(), *EXPECTED_GLOBAL_VALIDATOR_SET); - assert_key_gen(&emitted_events[test_validators().len()]); - } - } -} diff --git a/deny.toml b/deny.toml index 0909db18..ca7751f0 100644 --- a/deny.toml +++ b/deny.toml @@ -42,8 +42,10 @@ exceptions = [ { allow = ["AGPL-3.0"], name = "ethereum-serai" }, { allow = ["AGPL-3.0"], name = "serai-processor" }, - { allow = ["AGPL-3.0"], name = "serai-extension" }, - { allow = ["AGPL-3.0"], name = "serai-multisig" }, + { allow = ["AGPL-3.0"], name = "serai-primitives" }, + + { allow = ["AGPL-3.0"], name = "validator-sets-primitives" }, + { allow = ["AGPL-3.0"], name = "validator-sets-pallet" }, { allow = ["AGPL-3.0"], name = "sp-tendermint" }, { allow = ["AGPL-3.0"], name = "pallet-tendermint" }, diff --git a/docs/Serai.md b/docs/Serai.md index 683bc897..d2e21d2e 100644 --- a/docs/Serai.md +++ b/docs/Serai.md @@ -5,29 +5,10 @@ for various connected networks, offering secure decentralized custody of foreign assets to applications built on it. Serai is exemplified by Serai DEX, an automated-market-maker (AMM) decentralized -exchange, allowing swapping BTC, ETH, USDC, DAI, and XMR. It is the premier +exchange, allowing swapping Bitcoin, Ether, DAI, and Monero. It is the premier application of Serai. ### Substrate Serai is based on [Substrate](https://docs.substrate.io), a blockchain framework offering a robust infrastructure. - -### Smart Contracts - -Serai offers WASM-based smart contracts. All applications are built over these -contracts, enabling composable interactions within a mutual layer. These -contracts are primarily written in [ink!](https://ink.substrate.io/), a -framework for building contracts in Rust. - -Initially, smart contract deployment will not be enabled. Solely Serai DEX will -be available, due to the variety of economic considerations around securing the -multisig. Serai may expand in the future with more explicitly added -applications, each with tailored economic models, or may enable arbitrary -contract deployment. At this time, we solely plan for Serai DEX's availabiliy. - -### Application Calls - -Applications, such as Serai DEX, may be called via calling their relevant smart -contracts. At a low level, this is done via specifying the address of the -contract being interacted with, along with SCALE-encoded calldata. diff --git a/docs/protocol/Constants.md b/docs/protocol/Constants.md index 2cbe45b9..88c09f4e 100644 --- a/docs/protocol/Constants.md +++ b/docs/protocol/Constants.md @@ -5,41 +5,30 @@ These are the list of types used to represent various properties within the protocol. -| Alias | Shorthand | Type | -|-------------------------|-----------|----------| -| Amount | Amount | u64 | -| Curve | Curve | u16 | -| Coin | Coin | u32 | -| Global Validator Set ID | GVSID | u32 | -| Validator Set Index | VS | u8 | -| Key | Key | Vec\ | - -### Curves - -Integer IDs for various curves. It should be noted some curves may be the same, -yet have distinct IDs due to having different basepoints, and accordingly -different keys. For such cases, the processor is expected to create one secret -per curve, and then use DLEq proofs to port keys to other basepoints as needed. - -| Curve | ID | -|-----------|----| -| Secp256k1 | 0 | -| Ed25519 | 1 | +| Alias | Type | +|------------------------|--------------------------------| +| Amount | u64 | +| Coin | u32 | +| Session | u32 | +| Validator Set Index | u16 | +| Validator Set Instance | (Session, Validator Set Index) | +| Key | Vec\ | ### Networks -Every network connected to Serai operates over a specific curve. While the -processor generates keys for curves, these keys are bound to specific networks -via an additive offset created by hashing the network's name (among other -things). The network's key is used for all coins on that network. +Every network connected to Serai operates over a specific curve. The processor +generates a distinct set of keys per network. Beyond the key-generation itself +being isolated, the generated keys are further bound to their respective +networks via an additive offset created by hashing the network's name (among +other properties). The network's key is used for all coins on that network. Networks are not acknowledged by the Serai network, solely by the processor. -| Network | Curve | -|----------|-------| -| Bitcoin | 0 | -| Ethereum | 0 | -| Monero | 1 | +| Network | Curve | +|----------|-----------| +| Bitcoin | Secp256k1 | +| Ethereum | Secp256k1 | +| Monero | Ed25519 | ### Coins @@ -48,7 +37,6 @@ Coins exist over a network and have a distinct integer ID. | Coin | Network | ID | |----------|----------|----| | Bitcoin | Bitcoin | 0 | -| Ethereum | Ethereum | 1 | -| USDC | Ethereum | 2 | -| DAI | Ethereum | 3 | -| Monero | Monero | 4 | +| Ether | Ethereum | 1 | +| DAI | Ethereum | 2 | +| Monero | Monero | 3 | diff --git a/docs/protocol/Multisig.md b/docs/protocol/Multisig.md deleted file mode 100644 index 7a572a98..00000000 --- a/docs/protocol/Multisig.md +++ /dev/null @@ -1,35 +0,0 @@ -# Multisig - -Multisigs are confirmed on-chain by the `Multisig` contract. While the processor -does create the multisig, and sign for it, making it irrelevant to the chain, -confirming it on-chain solves the question of if the multisig was successfully -created or not. If each processor simply asked all other processors for -confirmation, votes lost to the network would create an inconsistent view. This -is a form of the Byzantine Generals Problem, which can be resolved by placing -votes within a BFT system. - -Confirmation requires all participants confirm the new set of keys. While this -isn't BFT, despite the voting process being BFT, it avoids the scenario where -only t (where t is the BFT threshold, as used in the t-of-n multisig) -successfully generated shares, actually creating a t-of-t multisig in practice, -which is not BFT. This does mean a single node can delay a churn, which is -expected to be handled via a combination of slashing, and if necessary, removal. - -Validators are allowed to vote multiple times across sets of keys, with the -first set to be confirmed becoming the set of keys for that validator set. These -keys remain valid for the validator set until it is changed. If a validator set -remains consistent despite the global validator set updating, their keys carry. -If a validator set adds a new member, and then loses them, their historical keys -are not reused. - -Once new keys are confirmed for a given validator set, they become tracked and -the recommended set of keys for incoming funds. The old keys are still eligible -to receive funds for a provided grace period, requiring the current validator -set to track both sets of keys. The old keys are also still used to handle all -outgoing payments as well, until the end of the grace period, at which point -they're no longer eligible to receive funds and they forward all of their funds -to the new set of keys. - -### `vote(keys: Vec>)` - -Lets a validator vote on a set of keys for their validator set. diff --git a/docs/protocol/Staking.md b/docs/protocol/Staking.md new file mode 100644 index 00000000..f84fb035 --- /dev/null +++ b/docs/protocol/Staking.md @@ -0,0 +1,19 @@ +# Staking + +Serai's staking pallet offers a DPoS system. All stake which enters the system +is delegated somewhere. Delegates can then bond their stake to different +validator sets, justifying their inclusion and providing financial security. + +Delegators may transfer stake whenever, so long as that stake isn't actively +bonded. Delegators may also unstake whenever, so long as the prior condition +is still met. + +### Stake (message) + + - `delegate` (Address): Address to delegate the newly added stake to. + - `amount` (Amount): Amount to stake and delegate. + +### Unstake (message) + + - `delegate` (Address): Address the stake is currently delegated to. + - `amount` (Amount): Amount to unstake. diff --git a/docs/protocol/Validator Sets.md b/docs/protocol/Validator Sets.md index d89510cd..eb6abd7c 100644 --- a/docs/protocol/Validator Sets.md +++ b/docs/protocol/Validator Sets.md @@ -2,29 +2,80 @@ Validator Sets are defined at the protocol level, with the following parameters: - - `index` (VS): Validator set index, a global key atomically increasing -from 0. - - `bond` (Amount): Amount of bond per key-share of this validator set. - - `coins` (Vec\): Coins managed by this validator set. + - `bond` (Amount): Amount of bond per key-share. + - `coins` (Vec\): List of coins within this set. + - `participants` (Vec\): List of participants within this set. -At launch, there will solely be validator set 0, managing Bitcoin, Ethereum, -USDC, DAI, and Monero. +Validator Sets are referred to by `ValidatorSetIndex` yet have their data +accessible via `ValidatorSetInstance`. -### Multisig Management - -Every validator set is expected to form a t-of-n multisig, where n is the amount -of key shares in the validator set and t is `n / 3 * 2 + 1`, per curve required -by its coins. This multisig is secure to hold funds up to 67% of the validator -set's bond value. If funds exceed that threshold, there's more value in the -multisig than in the supermajority of bond that must be put forth to control it. +At launch, there will solely be Validator Set 0, managing Bitcoin, Ether, DAI, +and Monero. ### Participation in the BFT process -All validator sets participate in the BFT process. Specifically, a block -containing `Oraclization`s for a coin must be approved by the BFT majority of -the validator set responsible for it, along with the BFT majority of the network -by bond. +All Validator Sets participate in the BFT process described under +[Consensus](./Consensus.md). Specifically, a block containing In Instructions +for a coin must be approved by the BFT majority of the Validator Set responsible +for it, along with the BFT majority of the network by bond. -At this time, `Oraclization`s for a coin are only expected to be included when a -validator from the validator set managing the coin is the producer of the block +At this time, In Instructions for a coin are only expected to be included when a +validator from the Validator Set managing the coin is the producer of the block in question. + +Since there is currently only one Validator Set, the aforementioned BFT +conditions collapse to simply the BFT majority by bond. Ensuring BFT majority +per responsible Validator Set is accordingly unimplemented for now. + +### Multisig + +Every Validator Set is expected to form a `t`-of-`n` multisig, where `n` is the +amount of key shares in the Validator Set and `t` is `n * 2 / 3 + 1`, for each +of its networks. This multisig is secure to hold coins up to 67% of the +Validator Set's bonded value. If the coins exceed that threshold, there's more +value in the multisig than in the supermajority of bond that must be put forth +to control it. Accordingly, it'd be no longer financially secure, and it MUST +reject newly added coins which would cross that threshold. + +### Multisig Creation + +Multisigs are created by processors, communicating via their Coordinators. +They're then confirmed on chain via the `validator-sets` pallet. This is done by +having 100% of participants agree on the resulting group key. While this isn't +fault tolerant, a malicious actor who forces a `t`-of-`n` multisig to be +`t`-of-`n-1` reduces the fault tolerance of the multisig which is a greater +issue. If a node does prevent multisig creation, other validators should issue +slashes for it/remove it from the Validator Set entirely. + +Due to the fact multiple key generations may occur to account for +faulty/malicious nodes, voting on multiple keys for a single coin is allowed, +with the first key to be confirmed becoming the key for that coin. + +Placing it on chain also solves the question of if the multisig was successfully +created or not. Processors cannot simply ask each other if they succeeded +without creating an instance of the Byzantine Generals Problem. Placing results +within a Byzantine Fault Tolerant system resolves this. + +### Multisig Lifetime + +The keys for a Validator Set remain valid until its participants change. If a +Validator Set adds a new member, and then they leave, the set's historical keys +are not reused. + +### Multisig Handoffs + +Once new keys are confirmed for a given Validator Set, they become tracked and +the recommended set of keys for incoming coins. The old keys are still eligible +to receive coins for a provided grace period, requiring the current Validator +Set to track both sets of keys. The old keys are also prioritized for handling +outbound transfers, until the end of the grace period, at which point they're +no longer eligible to receive coins and they forward all of their coins to the +new set of keys. It is only then that validators in the previous instance of the +set, yet not the current instance, may unbond their stake. + +### Vote (message) + + - `coin` (Coin): Coin whose key is being voted for. + - `key` (Key): Key being voted on. + +Once a key is voted on by every member, it's adopted as detailed above. diff --git a/docs/protocol/Validators.md b/docs/protocol/Validators.md deleted file mode 100644 index c750a1a9..00000000 --- a/docs/protocol/Validators.md +++ /dev/null @@ -1,44 +0,0 @@ -# Validators - -### Register (message) - - - `validator` (signer): Address which will be the validator on Substrate. - - `manager` (signer): Address which will manage this validator. - - `set` (VS): Validator set being joined. - -Marks `validator` as a validator candidate for the specified validator set, -enabling delegation. - -### Delegate (message) - - - `delegator` (signer): Address delegating funds to `validator`. - - `validator` (address): Registered validator being delegated to. - - `amount` (Amount): Amount of funds being delegated to `validator`. - -Delegated funds will be removed from `delegator`'s wallet and moved to -`validator`'s bond. `amount` must be a multiple of the validator set's bond, and -`delegator` must be `validator`'s manager. - -### Undelegate (message) - - - `delegator` (signer): Address removing delegated funds from `validator`. - - `validator` (address): Registered validator no longer being delegated to. - - `amount` (Amount): Amount of funds no longer being delegated to -`validator`. - -`delegator` must be `validator`'s manager, and `amount` must be a multiple of -the validator set's bond. `validator` is scheduled to lose an according amount -of key shares at the next churn, and once they do, the specified amount will be -moved from `validator`'s bond to `delegator`'s wallet. - -`validator`'s bond must be at least the validator set's bond after the -undelegation. - -### Resign (message) - - - `manager` (signer): Manager of `validator`. - - `validator` (address): Validator being removed from the pool/candidacy. - -If `validator` is active, they will be removed at the next churn. If they are -solely a candidate, they will no longer be eligible for delegations. All bond is -refunded after their removal. diff --git a/substrate/node/Cargo.toml b/substrate/node/Cargo.toml index 6f12d087..f83eb24e 100644 --- a/substrate/node/Cargo.toml +++ b/substrate/node/Cargo.toml @@ -59,6 +59,10 @@ sc-rpc-api = { git = "https://github.com/serai-dex/substrate" } substrate-frame-rpc-system = { git = "https://github.com/serai-dex/substrate" } pallet-transaction-payment-rpc = { git = "https://github.com/serai-dex/substrate" } +serai-primitives = { path = "../serai/primitives" } + +validator-sets-pallet = { path = "../validator-sets/pallet" } + sp-tendermint = { path = "../tendermint/primitives" } pallet-tendermint = { path = "../tendermint/pallet", default-features = false } serai-runtime = { path = "../runtime" } @@ -73,5 +77,5 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-benchmarking-cli/runtime-benchmarks", - "serai-runtime/runtime-benchmarks" + "serai-runtime/runtime-benchmarks", ] diff --git a/substrate/node/src/chain_spec.rs b/substrate/node/src/chain_spec.rs index 1d45002f..bb7dd0e7 100644 --- a/substrate/node/src/chain_spec.rs +++ b/substrate/node/src/chain_spec.rs @@ -1,11 +1,12 @@ +use sp_core::{Pair as PairTrait, sr25519::Pair}; use sc_service::ChainType; -use sp_core::{Pair as PairTrait, sr25519::Pair}; +use serai_primitives::{Amount, COIN, Coin}; use pallet_tendermint::crypto::Public; use serai_runtime::{ WASM_BINARY, AccountId, opaque::SessionKeys, GenesisConfig, SystemConfig, BalancesConfig, - SessionConfig, + ValidatorSetsConfig, SessionConfig, }; pub type ChainSpec = sc_service::GenericChainSpec; @@ -34,6 +35,12 @@ fn testnet_genesis( balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), }, transaction_payment: Default::default(), + + validator_sets: ValidatorSetsConfig { + bond: Amount(1_000_000) * COIN, + coins: Coin(4), + participants: validators.iter().map(|name| account_id_from_name(name)).collect(), + }, session: SessionConfig { keys: validators.iter().map(|name| session_key(*name)).collect() }, } } diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index bfa4b172..7960b012 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -37,13 +37,10 @@ frame-executive = { git = "https://github.com/serai-dex/substrate", default-feat frame-benchmarking = { git = "https://github.com/serai-dex/substrate", default-features = false, optional = true } pallet-timestamp = { git = "https://github.com/serai-dex/substrate", default-features = false } -pallet-randomness-collective-flip = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-balances = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", default-features = false } -pallet-contracts-primitives = { git = "https://github.com/serai-dex/substrate", default-features = false } -pallet-contracts = { git = "https://github.com/serai-dex/substrate", default-features = false } - +validator-sets-pallet = { path = "../validator-sets/pallet", default-features = false } pallet-session = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-tendermint = { path = "../tendermint/pallet", default-features = false } @@ -77,13 +74,10 @@ std = [ "frame-executive/std", "pallet-timestamp/std", - "pallet-randomness-collective-flip/std", "pallet-balances/std", "pallet-transaction-payment/std", - "pallet-contracts/std", - "pallet-contracts-primitives/std", - + "validator-sets-pallet/std", "pallet-session/std", "pallet-tendermint/std", diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 2b397ab0..4afc9d47 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -18,7 +18,7 @@ use sp_version::NativeVersion; use sp_version::RuntimeVersion; use frame_support::{ - traits::{ConstBool, ConstU8, ConstU32, ConstU64}, + traits::{ConstU8, ConstU32, ConstU64}, weights::{ constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND}, IdentityFee, Weight, @@ -130,7 +130,6 @@ parameter_types! { .get(DispatchClass::Normal) .max_total .unwrap_or(BlockWeights::get().max_block); - pub Schedule: pallet_contracts::Schedule = Default::default(); } impl frame_system::Config for Runtime { @@ -163,8 +162,6 @@ impl frame_system::Config for Runtime { type MaxConsumers = frame_support::traits::ConstU32<16>; } -impl pallet_randomness_collective_flip::Config for Runtime {} - impl pallet_timestamp::Config for Runtime { type Moment = u64; type OnTimestampSet = (); @@ -193,34 +190,6 @@ impl pallet_transaction_payment::Config for Runtime { type FeeMultiplierUpdate = (); } -impl pallet_contracts::Config for Runtime { - type Time = Timestamp; - type Randomness = RandomnessCollectiveFlip; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - - type CallFilter = frame_support::traits::Nothing; - type DepositPerItem = DepositPerItem; - type DepositPerByte = DepositPerByte; - type CallStack = [pallet_contracts::Frame; 31]; - type WeightPrice = pallet_transaction_payment::Pallet; - type WeightInfo = pallet_contracts::weights::SubstrateWeight; - type ChainExtension = (); - type DeletionQueueDepth = DeletionQueueDepth; - type DeletionWeightLimit = DeletionWeightLimit; - type Schedule = Schedule; - type AddressGenerator = pallet_contracts::DefaultAddressGenerator; - - type MaxCodeLen = ConstU32<{ 128 * 1024 }>; - type MaxStorageKeyLen = ConstU32<128>; - - type UnsafeUnstableInterface = ConstBool; - type MaxDebugBufferLen = ConstU32<255>; -} - -impl pallet_tendermint::Config for Runtime {} - const SESSION_LENGTH: BlockNumber = 5 * DAYS; type Sessions = PeriodicSessions, ConstU32<{ SESSION_LENGTH }>>; @@ -231,6 +200,10 @@ impl Convert> for IdentityValidatorIdOf { } } +impl validator_sets_pallet::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} + impl pallet_session::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ValidatorId = AccountId; @@ -243,6 +216,8 @@ impl pallet_session::Config for Runtime { type WeightInfo = pallet_session::weights::SubstrateWeight; } +impl pallet_tendermint::Config for Runtime {} + pub type Address = AccountId; pub type Header = generic::Header; pub type Block = generic::Block; @@ -274,11 +249,11 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system, - RandomnessCollectiveFlip: pallet_randomness_collective_flip, Timestamp: pallet_timestamp, Balances: pallet_balances, TransactionPayment: pallet_transaction_payment, - Contracts: pallet_contracts, + + ValidatorSets: validator_sets_pallet, Session: pallet_session, Tendermint: pallet_tendermint, } diff --git a/substrate/serai/primitives/Cargo.toml b/substrate/serai/primitives/Cargo.toml new file mode 100644 index 00000000..24231788 --- /dev/null +++ b/substrate/serai/primitives/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "serai-primitives" +version = "0.1.0" +description = "Primitives for the Serai blockchain" +license = "AGPL-3.0-only" +repository = "https://github.com/serai-dex/serai/tree/develop/substrate/serai/primitives" +authors = ["Luke Parker "] +edition = "2021" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2", default-features = false, features = ["derive"] } + +serde = { version = "1.0", features = ["derive"], optional = true } + +sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } +sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } + +[features] +std = ["scale/std", "scale-info/std", "serde", "sp-core/std", "sp-std/std"] +default = ["std"] diff --git a/contracts/extension/LICENSE b/substrate/serai/primitives/LICENSE similarity index 100% rename from contracts/extension/LICENSE rename to substrate/serai/primitives/LICENSE diff --git a/substrate/serai/primitives/src/lib.rs b/substrate/serai/primitives/src/lib.rs new file mode 100644 index 00000000..829942d3 --- /dev/null +++ b/substrate/serai/primitives/src/lib.rs @@ -0,0 +1,36 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +use core::ops::{Add, Mul}; + +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +/// The type used for amounts. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Amount(pub u64); + +impl Add for Amount { + type Output = Amount; + fn add(self, other: Amount) -> Amount { + Amount(self.0 + other.0) + } +} + +impl Mul for Amount { + type Output = Amount; + fn mul(self, other: Amount) -> Amount { + Amount(self.0 * other.0) + } +} + +/// One whole coin with eight decimals. +#[allow(clippy::inconsistent_digit_grouping)] +pub const COIN: Amount = Amount(1_000_000_00); + +/// The type used to identify coins. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Coin(pub u32); diff --git a/substrate/validator-sets/pallet/Cargo.toml b/substrate/validator-sets/pallet/Cargo.toml new file mode 100644 index 00000000..e5f423e4 --- /dev/null +++ b/substrate/validator-sets/pallet/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "validator-sets-pallet" +version = "0.1.0" +description = "Validator sets pallet" +license = "AGPL-3.0-only" +repository = "https://github.com/serai-dex/serai/tree/develop/substrate/validator-sets/pallet" +authors = ["Luke Parker "] +edition = "2021" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2", default-features = false, features = ["derive"] } + +frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false } +frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false } + +serai-primitives = { path = "../../serai/primitives", default-features = false } +validator-sets-primitives = { path = "../primitives", default-features = false } + +[features] +std = [ + "scale/std", + "scale-info/std", + + "frame-system/std", + "frame-support/std", + + "serai-primitives/std", + "validator-sets-primitives/std", +] + +runtime-benchmarks = [ + "frame-system/runtime-benchmarks", + "frame-support/runtime-benchmarks", +] + +default = ["std"] diff --git a/contracts/multisig/LICENSE b/substrate/validator-sets/pallet/LICENSE similarity index 100% rename from contracts/multisig/LICENSE rename to substrate/validator-sets/pallet/LICENSE diff --git a/substrate/validator-sets/pallet/src/lib.rs b/substrate/validator-sets/pallet/src/lib.rs new file mode 100644 index 00000000..7ac8a700 --- /dev/null +++ b/substrate/validator-sets/pallet/src/lib.rs @@ -0,0 +1,207 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +#[frame_support::pallet] +pub mod pallet { + use scale::{Encode, Decode}; + use scale_info::TypeInfo; + + use frame_system::pallet_prelude::*; + use frame_support::pallet_prelude::*; + + use serai_primitives::*; + use validator_sets_primitives::*; + + #[pallet::config] + pub trait Config: frame_system::Config + TypeInfo { + type RuntimeEvent: IsType<::RuntimeEvent> + From>; + } + + #[pallet::genesis_config] + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen)] + pub struct GenesisConfig { + /// Bond requirement to join the initial validator set. + /// Every participant at genesis will automatically be assumed to have this much bond. + /// This bond cannot be withdrawn however as there's no stake behind it. + pub bond: Amount, + /// Amount of coins to spawn the network with in the initial validator set. + pub coins: Coin, + /// List of participants to place in the genesis set. + pub participants: Vec, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { bond: Amount(1), coins: Coin(0), participants: vec![] } + } + } + + // Max of 16 coins per validator set + // At launch, we'll have BTC, ETH, DAI, and XMR + // In the future, these will be split into separate validator sets, so we're already not + // planning expansion beyond just a few coins per validator set + // The only case which really makes sense for multiple coins in a validator set is: + // 1) The coins are small, easy to run, and make no sense to be in their own set + // In this case, it's still hard to ask validators to run 16 different nodes + // 2) The coins are all on the same network yet there's no DEX on-chain + // In these cases, it'd be hard to find and justify 16 different coins from that single chain + // This could probably be just 8, yet 16 is a hedge for the unforseen + // If necessary, this can be increased with a fork + type MaxCoinsPerSet = ConstU32<16>; + + // Support keys up to 96 bytes (BLS12-381 G2) + const MAX_KEY_LEN: u32 = 96; + type MaxKeyLen = ConstU32; + + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub struct ValidatorSet { + bond: Amount, + coins: BoundedVec, + + // Participant and their amount bonded to this set + // Limit each set to 100 participants for now + participants: BoundedVec<(T::AccountId, Amount), ConstU32<100>>, + } + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(PhantomData); + + /// The details of a validator set instance. + #[pallet::storage] + #[pallet::getter(fn validator_set)] + pub type ValidatorSets = + StorageMap<_, Twox64Concat, ValidatorSetInstance, ValidatorSet, OptionQuery>; + + type Key = BoundedVec; + + /// The key for a given validator set instance coin. + #[pallet::storage] + #[pallet::getter(fn key)] + pub type Keys = + StorageMap<_, Twox64Concat, (ValidatorSetInstance, Coin), Key, OptionQuery>; + + /// If an account has voted for a specific key or not. Prevents them from voting multiple times. + #[pallet::storage] + #[pallet::getter(fn voted)] + pub type Voted = StorageMap<_, Blake2_128Concat, (T::AccountId, Key), (), OptionQuery>; + + /// How many times a key has been voted for. Once consensus is reached, the keys will be adopted. + #[pallet::storage] + #[pallet::getter(fn vote_count)] + pub type VoteCount = + StorageMap<_, Blake2_128Concat, (ValidatorSetInstance, Coin, Key), u16, ValueQuery>; + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + let mut coins = Vec::new(); + for coin in 0 .. self.coins.0 { + coins.push(Coin(coin)); + } + + let mut participants = Vec::new(); + for participant in self.participants.clone() { + participants.push((participant, self.bond)); + } + + ValidatorSets::::set( + ValidatorSetInstance(Session(0), ValidatorSetIndex(0)), + Some(ValidatorSet { + bond: self.bond, + coins: BoundedVec::try_from(coins).unwrap(), + participants: BoundedVec::try_from(participants).unwrap(), + }), + ); + } + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + Vote { + voter: T::AccountId, + instance: ValidatorSetInstance, + coin: Coin, + key: Key, + // Amount of votes the key now has + votes: u16, + }, + KeyGen { + instance: ValidatorSetInstance, + coin: Coin, + key: Key, + }, + } + + #[pallet::error] + pub enum Error { + /// Validator Set doesn't exist. + NonExistentValidatorSet, + /// Non-validator is voting. + NotValidator, + /// Validator Set already generated keys. + AlreadyGeneratedKeys, + /// Vvalidator has already voted for these keys. + AlreadyVoted, + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(0)] // TODO + pub fn vote( + origin: OriginFor, + index: ValidatorSetIndex, + coin: Coin, + key: Key, + ) -> DispatchResult { + let signer = ensure_signed(origin)?; + // TODO: Do we need to check the key is within the length bounds? + // The docs suggest the BoundedVec will create/write, yet not read, which could be an issue + // if it can be passed in + + // TODO: Get session + let session: Session = Session(0); + + // Confirm a key hasn't been set for this set instance + let instance = ValidatorSetInstance(session, index); + if Keys::::get((instance, coin)).is_some() { + Err(Error::::AlreadyGeneratedKeys)?; + } + + // Confirm the signer is a validator in the set + let set = ValidatorSets::::get(instance).ok_or(Error::::NonExistentValidatorSet)?; + + if set.participants.iter().any(|participant| participant.0 == signer) { + Err(Error::::NotValidator)?; + } + + // Confirm this signer hasn't already voted for these keys + if Voted::::get((&signer, &key)).is_some() { + Err(Error::::AlreadyVoted)?; + } + Voted::::set((&signer, &key), Some(())); + + // Add their vote + let votes = VoteCount::::mutate((instance, coin, &key), |value| { + *value += 1; + *value + }); + + Self::deposit_event(Event::Vote { voter: signer, instance, coin, key: key.clone(), votes }); + + // If we've reached consensus, set the key + if usize::try_from(votes).unwrap() == set.participants.len() { + Keys::::set((instance, coin), Some(key.clone())); + Self::deposit_event(Event::KeyGen { instance, coin, key }); + } + + Ok(()) + } + } + + // TODO: Support session rotation +} + +pub use pallet::*; diff --git a/substrate/validator-sets/primitives/Cargo.toml b/substrate/validator-sets/primitives/Cargo.toml new file mode 100644 index 00000000..7ddca4ad --- /dev/null +++ b/substrate/validator-sets/primitives/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "validator-sets-primitives" +version = "0.1.0" +description = "Primitives for validator sets" +license = "AGPL-3.0-only" +repository = "https://github.com/serai-dex/serai/tree/develop/substrate/validator-sets/primitives" +authors = ["Luke Parker "] +edition = "2021" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2", default-features = false, features = ["derive"] } + +serde = { version = "1.0", features = ["derive"], optional = true } + +sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } +sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } + +[features] +std = ["scale/std", "scale-info/std", "serde", "sp-core/std", "sp-std/std"] +default = ["std"] diff --git a/substrate/validator-sets/primitives/LICENSE b/substrate/validator-sets/primitives/LICENSE new file mode 100644 index 00000000..d6e1814a --- /dev/null +++ b/substrate/validator-sets/primitives/LICENSE @@ -0,0 +1,15 @@ +AGPL-3.0-only license + +Copyright (c) 2022 Luke Parker + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License Version 3 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . diff --git a/substrate/validator-sets/primitives/src/lib.rs b/substrate/validator-sets/primitives/src/lib.rs new file mode 100644 index 00000000..642d2800 --- /dev/null +++ b/substrate/validator-sets/primitives/src/lib.rs @@ -0,0 +1,21 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +/// The type used to identify a specific session of validators. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Session(pub u32); + +/// The type used to identify a validator set. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct ValidatorSetIndex(pub u16); + +/// The type used to identify a specific validator set during a specific session. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct ValidatorSetInstance(pub Session, pub ValidatorSetIndex); From daa88a051f6f86499344cd8279d29c8f2924bfe8 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 4 Jan 2023 23:09:58 -0500 Subject: [PATCH 05/74] Remove the timestamp pallet It was needed for contracts, which has since been removed. We now no longer need it. --- Cargo.lock | 2 -- substrate/node/Cargo.toml | 1 - substrate/node/src/command_helper.rs | 12 +++--------- substrate/node/src/service.rs | 4 ++-- substrate/runtime/Cargo.toml | 3 --- substrate/runtime/src/lib.rs | 10 ---------- 6 files changed, 5 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb4880b7..ab8ee761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7262,7 +7262,6 @@ dependencies = [ "sp-keystore", "sp-runtime", "sp-tendermint", - "sp-timestamp", "substrate-build-script-utils", "substrate-frame-rpc-system", "validator-sets-pallet", @@ -7313,7 +7312,6 @@ dependencies = [ "pallet-balances", "pallet-session", "pallet-tendermint", - "pallet-timestamp", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", diff --git a/substrate/node/Cargo.toml b/substrate/node/Cargo.toml index f83eb24e..c20ddee2 100644 --- a/substrate/node/Cargo.toml +++ b/substrate/node/Cargo.toml @@ -27,7 +27,6 @@ sp-application-crypto = { git = "https://github.com/serai-dex/substrate" } sp-keystore = { git = "https://github.com/serai-dex/substrate" } sp-keyring = { git = "https://github.com/serai-dex/substrate" } sp-inherents = { git = "https://github.com/serai-dex/substrate" } -sp-timestamp = { git = "https://github.com/serai-dex/substrate" } sp-runtime = { git = "https://github.com/serai-dex/substrate" } sp-blockchain = { git = "https://github.com/serai-dex/substrate" } sp-api = { git = "https://github.com/serai-dex/substrate" } diff --git a/substrate/node/src/command_helper.rs b/substrate/node/src/command_helper.rs index 664a894c..fc649357 100644 --- a/substrate/node/src/command_helper.rs +++ b/substrate/node/src/command_helper.rs @@ -1,8 +1,8 @@ -use std::{sync::Arc, time::Duration}; +use std::sync::Arc; use sp_core::{Encode, Pair}; use sp_keyring::Sr25519Keyring; -use sp_inherents::{InherentData, InherentDataProvider}; +use sp_inherents::InherentData; use sp_runtime::OpaqueExtrinsic; @@ -87,11 +87,5 @@ pub fn create_benchmark_extrinsic( } pub fn inherent_benchmark_data() -> Result { - let mut inherent_data = InherentData::new(); - futures::executor::block_on( - sp_timestamp::InherentDataProvider::new(Duration::from_millis(0).into()) - .provide_inherent_data(&mut inherent_data), - ) - .map_err(|e| format!("creating inherent data: {e:?}"))?; - Ok(inherent_data) + Ok(InherentData::new()) } diff --git a/substrate/node/src/service.rs b/substrate/node/src/service.rs index 6179c0e2..f063641d 100644 --- a/substrate/node/src/service.rs +++ b/substrate/node/src/service.rs @@ -57,13 +57,13 @@ impl NativeExecutionDispatch for ExecutorDispatch { pub struct Cidp; #[async_trait::async_trait] impl CreateInherentDataProviders for Cidp { - type InherentDataProviders = (sp_timestamp::InherentDataProvider,); + type InherentDataProviders = (); async fn create_inherent_data_providers( &self, _: ::Hash, _: (), ) -> Result> { - Ok((sp_timestamp::InherentDataProvider::from_system_time(),)) + Ok(()) } } diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index 7960b012..f964fa7a 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -36,7 +36,6 @@ frame-support = { git = "https://github.com/serai-dex/substrate", default-featur frame-executive = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-benchmarking = { git = "https://github.com/serai-dex/substrate", default-features = false, optional = true } -pallet-timestamp = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-balances = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -73,7 +72,6 @@ std = [ "frame-support/std", "frame-executive/std", - "pallet-timestamp/std", "pallet-balances/std", "pallet-transaction-payment/std", @@ -94,7 +92,6 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", - "pallet-timestamp/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-tendermint/runtime-benchmarks", diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 4afc9d47..d4a40c37 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -28,7 +28,6 @@ use frame_support::{ }; pub use frame_system::Call as SystemCall; -pub use pallet_timestamp::Call as TimestampCall; pub use pallet_balances::Call as BalancesCall; use pallet_transaction_payment::CurrencyAdapter; @@ -162,13 +161,6 @@ impl frame_system::Config for Runtime { type MaxConsumers = frame_support::traits::ConstU32<16>; } -impl pallet_timestamp::Config for Runtime { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = ConstU64<{ TARGET_BLOCK_TIME / 2 }>; - type WeightInfo = (); -} - impl pallet_balances::Config for Runtime { type MaxLocks = ConstU32<50>; type MaxReserves = (); @@ -249,7 +241,6 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system, - Timestamp: pallet_timestamp, Balances: pallet_balances, TransactionPayment: pallet_transaction_payment, @@ -269,7 +260,6 @@ mod benches { [frame_benchmarking, BaselineBench::] [frame_system, SystemBench::] [pallet_balances, Balances] - [pallet_timestamp, Timestamp] ); } From f760c09006831c87f0f6d7efa21a2e4f9bad9b09 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Thu, 5 Jan 2023 19:36:49 -0500 Subject: [PATCH 06/74] Add Substrate "assets" pallet While over-engineered for our purposes, it's still usable. Also cleans the runtime a bit. --- Cargo.lock | 17 +++++++ substrate/node/src/chain_spec.rs | 22 +++++++-- substrate/runtime/Cargo.toml | 9 +++- substrate/runtime/src/lib.rs | 61 ++++++++++++++++-------- substrate/serai/primitives/src/amount.rs | 31 ++++++++++++ substrate/serai/primitives/src/coins.rs | 19 ++++++++ substrate/serai/primitives/src/lib.rs | 37 ++------------ 7 files changed, 139 insertions(+), 57 deletions(-) create mode 100644 substrate/serai/primitives/src/amount.rs create mode 100644 substrate/serai/primitives/src/coins.rs diff --git a/Cargo.lock b/Cargo.lock index ab8ee761..4afb2368 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4889,6 +4889,21 @@ dependencies = [ "libm 0.1.4", ] +[[package]] +name = "pallet-assets" +version = "4.0.0-dev" +source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-balances" version = "4.0.0-dev" @@ -7309,6 +7324,7 @@ dependencies = [ "frame-system", "frame-system-rpc-runtime-api", "hex-literal", + "pallet-assets", "pallet-balances", "pallet-session", "pallet-tendermint", @@ -7316,6 +7332,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "scale-info", + "serai-primitives", "sp-api", "sp-application-crypto", "sp-block-builder", diff --git a/substrate/node/src/chain_spec.rs b/substrate/node/src/chain_spec.rs index bb7dd0e7..58aa9321 100644 --- a/substrate/node/src/chain_spec.rs +++ b/substrate/node/src/chain_spec.rs @@ -1,12 +1,14 @@ -use sp_core::{Pair as PairTrait, sr25519::Pair}; +use sp_core::{Decode, Pair as PairTrait, sr25519::Pair}; +use sp_runtime::traits::TrailingZeroInput; + use sc_service::ChainType; -use serai_primitives::{Amount, COIN, Coin}; +use serai_primitives::*; use pallet_tendermint::crypto::Public; use serai_runtime::{ WASM_BINARY, AccountId, opaque::SessionKeys, GenesisConfig, SystemConfig, BalancesConfig, - ValidatorSetsConfig, SessionConfig, + AssetsConfig, ValidatorSetsConfig, SessionConfig, }; pub type ChainSpec = sc_service::GenericChainSpec; @@ -29,11 +31,25 @@ fn testnet_genesis( (key, key, SessionKeys { tendermint: Public::from(key) }) }; + // TODO: Replace with a call to the pallet to ask for its account + let owner = AccountId::decode(&mut TrailingZeroInput::new(b"tokens")).unwrap(); + GenesisConfig { system: SystemConfig { code: wasm_binary.to_vec() }, balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), }, + assets: AssetsConfig { + assets: [BITCOIN, ETHER, DAI, MONERO].iter().map(|coin| (*coin, owner, true, 1)).collect(), + metadata: vec![ + (BITCOIN, b"Bitcoin".to_vec(), b"BTC".to_vec(), 8), + // Reduce to 8 decimals to feasibly fit within u64 (instead of its native u256) + (ETHER, b"Ether".to_vec(), b"ETH".to_vec(), 8), + (DAI, b"Dai Stablecoin".to_vec(), b"DAI".to_vec(), 8), + (MONERO, b"Monero".to_vec(), b"XMR".to_vec(), 12), + ], + accounts: vec![], + }, transaction_payment: Default::default(), validator_sets: ValidatorSetsConfig { diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index f964fa7a..78a5f32f 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -25,7 +25,7 @@ sp-inherents = { git = "https://github.com/serai-dex/substrate", default-feature sp-offchain = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-session = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-transaction-pool = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-block-builder = { git = "https://github.com/serai-dex/substrate", default-features = false} +sp-block-builder = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-api = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -36,7 +36,10 @@ frame-support = { git = "https://github.com/serai-dex/substrate", default-featur frame-executive = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-benchmarking = { git = "https://github.com/serai-dex/substrate", default-features = false, optional = true } +serai-primitives = { path = "../serai/primitives", default-features = false } + pallet-balances = { git = "https://github.com/serai-dex/substrate", default-features = false } +pallet-assets = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", default-features = false } validator-sets-pallet = { path = "../validator-sets/pallet", default-features = false } @@ -72,7 +75,10 @@ std = [ "frame-support/std", "frame-executive/std", + "serai-primitives/std", + "pallet-balances/std", + "pallet-assets/std", "pallet-transaction-payment/std", "validator-sets-pallet/std", @@ -93,6 +99,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", "pallet-tendermint/runtime-benchmarks", ] diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index d4a40c37..3140fc03 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -28,7 +28,10 @@ use frame_support::{ }; pub use frame_system::Call as SystemCall; +use serai_primitives::Coin; + pub use pallet_balances::Call as BalancesCall; +pub use pallet_assets::Call as AssetsCall; use pallet_transaction_payment::CurrencyAdapter; use pallet_session::PeriodicSessions; @@ -40,6 +43,11 @@ pub type BlockNumber = u32; pub type AccountId = Public; /// Balance of an account. +// Distinct from serai-primitives Amount due to Substrate's requirements on this type. +// If Amount could be dropped in here, it would be. +// While Amount could have all the necessary traits implemented, not only are they many, yet it'd +// make Amount a larger type, providing more operations than desired. +// The current type's minimalism sets clear bounds on usage. pub type Balance = u64; /// Index of a transaction in the chain, for a given account. @@ -69,8 +77,7 @@ use opaque::SessionKeys; #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("serai"), - // TODO: "core"? - impl_name: create_runtime_str!("turoctocrab"), + impl_name: create_runtime_str!("core"), authoring_version: 1, // TODO: 1? Do we prefer some level of compatibility or our own path? spec_version: 100, @@ -97,14 +104,6 @@ pub fn native_version() -> NativeVersion { const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); -// Unit = the base number of indivisible units for balances -const UNIT: Balance = 1_000_000_000_000; -const MILLIUNIT: Balance = 1_000_000_000; - -const fn deposit(items: u32, bytes: u32) -> Balance { - (items as Balance * UNIT + (bytes as Balance) * (5 * MILLIUNIT / 100)) / 10 -} - parameter_types! { pub const BlockHashCount: BlockNumber = 2400; pub const Version: RuntimeVersion = VERSION; @@ -119,16 +118,6 @@ parameter_types! { Weight::from_ref_time(2u64 * WEIGHT_REF_TIME_PER_SECOND).set_proof_size(u64::MAX), NORMAL_DISPATCH_RATIO, ); - - pub const DepositPerItem: Balance = deposit(1, 0); - pub const DepositPerByte: Balance = deposit(0, 1); - pub const DeletionQueueDepth: u32 = 128; - // The lazy deletion runs inside on_initialize. - pub DeletionWeightLimit: Weight = BlockWeights::get() - .per_class - .get(DispatchClass::Normal) - .max_total - .unwrap_or(BlockWeights::get().max_block); } impl frame_system::Config for Runtime { @@ -173,6 +162,37 @@ impl pallet_balances::Config for Runtime { type WeightInfo = pallet_balances::weights::SubstrateWeight; } +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type Currency = Balances; + + type AssetId = Coin; + type AssetIdParameter = Coin; + type StringLimit = ConstU32<32>; + + // Don't allow anyone to create assets + type CreateOrigin = + frame_support::traits::AsEnsureOriginWithArg>; + type ForceOrigin = frame_system::EnsureRoot; + + // Don't charge fees nor kill accounts + type RemoveItemsLimit = ConstU32<0>; + type AssetDeposit = ConstU64<0>; + type AssetAccountDeposit = ConstU64<0>; + type MetadataDepositBase = ConstU64<0>; + type MetadataDepositPerByte = ConstU64<0>; + type ApprovalDeposit = ConstU64<0>; + + // Unused hooks + type Freezer = (); + type Extra = (); + + type WeightInfo = pallet_assets::weights::SubstrateWeight; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + impl pallet_transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter; @@ -242,6 +262,7 @@ construct_runtime!( { System: frame_system, Balances: pallet_balances, + Assets: pallet_assets, TransactionPayment: pallet_transaction_payment, ValidatorSets: validator_sets_pallet, diff --git a/substrate/serai/primitives/src/amount.rs b/substrate/serai/primitives/src/amount.rs new file mode 100644 index 00000000..e2d3594f --- /dev/null +++ b/substrate/serai/primitives/src/amount.rs @@ -0,0 +1,31 @@ +use core::{ops::{Add, Mul}}; + +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +/// The type used for amounts. +#[derive( + Clone, Copy, PartialEq, Eq, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Amount(pub u64); + +/// One whole coin with eight decimals. +#[allow(clippy::inconsistent_digit_grouping)] +pub const COIN: Amount = Amount(1_000_000_00); + +impl Add for Amount { + type Output = Amount; + fn add(self, other: Amount) -> Amount { + Amount(self.0 + other.0) + } +} + +impl Mul for Amount { + type Output = Amount; + fn mul(self, other: Amount) -> Amount { + Amount(self.0 * other.0) + } +} diff --git a/substrate/serai/primitives/src/coins.rs b/substrate/serai/primitives/src/coins.rs new file mode 100644 index 00000000..a1a7af3c --- /dev/null +++ b/substrate/serai/primitives/src/coins.rs @@ -0,0 +1,19 @@ +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +/// The type used to identify coins. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Coin(pub u32); +impl From for Coin { + fn from(coin: u32) -> Coin { + Coin(coin) + } +} + +pub const BITCOIN: Coin = Coin(0); +pub const ETHER: Coin = Coin(1); +pub const DAI: Coin = Coin(2); +pub const MONERO: Coin = Coin(3); diff --git a/substrate/serai/primitives/src/lib.rs b/substrate/serai/primitives/src/lib.rs index 829942d3..65e860b3 100644 --- a/substrate/serai/primitives/src/lib.rs +++ b/substrate/serai/primitives/src/lib.rs @@ -1,36 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use core::ops::{Add, Mul}; +mod amount; +pub use amount::*; -use scale::{Encode, Decode, MaxEncodedLen}; -use scale_info::TypeInfo; -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; - -/// The type used for amounts. -#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct Amount(pub u64); - -impl Add for Amount { - type Output = Amount; - fn add(self, other: Amount) -> Amount { - Amount(self.0 + other.0) - } -} - -impl Mul for Amount { - type Output = Amount; - fn mul(self, other: Amount) -> Amount { - Amount(self.0 * other.0) - } -} - -/// One whole coin with eight decimals. -#[allow(clippy::inconsistent_digit_grouping)] -pub const COIN: Amount = Amount(1_000_000_00); - -/// The type used to identify coins. -#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct Coin(pub u32); +mod coins; +pub use coins::*; From e0deaa55399851e2257430c55573e75e502b7d72 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 6 Jan 2023 01:35:02 -0500 Subject: [PATCH 07/74] fmt/clippy from last commit --- substrate/runtime/src/lib.rs | 1 - substrate/serai/primitives/src/amount.rs | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 3140fc03..3e39aba6 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -23,7 +23,6 @@ use frame_support::{ constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND}, IdentityFee, Weight, }, - dispatch::DispatchClass, parameter_types, construct_runtime, }; pub use frame_system::Call as SystemCall; diff --git a/substrate/serai/primitives/src/amount.rs b/substrate/serai/primitives/src/amount.rs index e2d3594f..e125e339 100644 --- a/substrate/serai/primitives/src/amount.rs +++ b/substrate/serai/primitives/src/amount.rs @@ -1,4 +1,6 @@ -use core::{ops::{Add, Mul}}; +use core::{ + ops::{Add, Mul}, +}; use scale::{Encode, Decode, MaxEncodedLen}; use scale_info::TypeInfo; From a646ec5aaaf816887874c8311bf8bd9c02d2a33f Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 6 Jan 2023 04:33:17 -0500 Subject: [PATCH 08/74] Squashed commit of the following: commit e0a9e8825d6c22c797fb84e26ed6ef10136ca9c2 Author: Luke Parker Date: Fri Jan 6 04:24:08 2023 -0500 Remove Scanner::address It either needed to return an Option, panic on misconfiguration, or return a distinct Scanner type based on burning bug immunity to offer this API properly. Panicking wouldn't be proper, and the Option
would've been... awkward. The new register_subaddress function, maintaining the needed functionality, also provides further clarity on the intended side effect of the previously present Scanner::address function. commit 7359360ab2fc8c9255c6f58250c214252ce217a4 Author: Luke Parker Date: Fri Jan 6 01:35:02 2023 -0500 fmt/clippy from last commit commit 80d912fc19cd268f3b019a9d9961a48b2c45e828 Author: Luke Parker Date: Thu Jan 5 19:36:49 2023 -0500 Add Substrate "assets" pallet While over-engineered for our purposes, it's still usable. Also cleans the runtime a bit. commit 2ed2944b6598d75bdc3c995aaf39b717846207de Author: Luke Parker Date: Wed Jan 4 23:09:58 2023 -0500 Remove the timestamp pallet It was needed for contracts, which has since been removed. We now no longer need it. commit 7fc1fc2dccecebe1d94cb7b4c00f2b5cb271c87b Author: Luke Parker Date: Wed Jan 4 22:52:41 2023 -0500 Initial validator sets pallet (#187) * Initial work on a Validator Sets pallet * Update Validator Set docs per current discussions * Update validator-sets primitives and storage handling * Add validator set pallets to deny.toml * Remove Curve from primitives Since we aren't reusing keys across coins, there's no reason for it to be on-chain (as previously planned). * Update documentation on Validator Sets * Use Twox64Concat instead of Identity Ensures an even distribution of keys. While xxhash is breakable, these keys aren't manipulatable by users. * Add math ops on Amount and define a coin as 1e8 * Add validator-sets to the runtime and remove contracts Also removes the randomness pallet which was only required by the contracts runtime. Does not remove the contracts folder yet so they can still be referred to while validator-sets is under development. Does remove them from Cargo.toml. * Add vote function to validator-sets * Remove contracts folder * Create an event for the Validator Sets pallet * Remove old contracts crates from deny.toml * Remove line from staking branch * Remove staking from runtime * Correct VS Config in runtime * cargo update * Resolve a few PR comments on terminology * Create a serai-primitives crate Move types such as Amount/Coin out of validator-sets. Will be expanded in the future. * Fixes for last commit * Don't reserve set 0 * Further fixes * Add files meant for last commit * Remove Staking transfer commit 3309295911d22177bd68972d138aea2f8658eb5f Author: Luke Parker Date: Wed Jan 4 06:17:00 2023 -0500 Reorder coins in README by market cap commit db5d19cad33ccf067d876b7f5b7cca47c228e2fc Author: Luke Parker Date: Wed Jan 4 06:07:58 2023 -0500 Update README commit 606484d744b1c6cc408382994c77f1def25d3e7d Author: Luke Parker Date: Wed Jan 4 03:17:36 2023 -0500 cargo update commit 3a319b229fabd110cc28e5cc0cf718aa88b908bf Author: akildemir Date: Wed Jan 4 16:26:25 2023 +0300 update address public API design commit d9fa88fa76eb361da79f81a1f7758ad19432aca7 Author: akildemir Date: Mon Jan 2 13:35:06 2023 +0300 fix clippy error commit cc722e897b34afc1e517ece2fc5020d190d97804 Merge: cafa9b3 eeca440 Author: akildemir Date: Mon Jan 2 11:39:04 2023 +0300 Merge https://github.com/serai-dex/serai into develop commit cafa9b361e16a37981d45bf3031573c7bc48c5a0 Author: akildemir Date: Mon Jan 2 11:38:26 2023 +0300 fix build errors commit ce5b5f2b37e7cc5a8ca84cbe64e3cefdbf0fe104 Merge: f502d67 49c4acf Author: akildemir Date: Sun Jan 1 15:16:25 2023 +0300 Merge https://github.com/serai-dex/serai into develop commit f502d67282fe4951e3756f041e240c089a945a85 Author: akildemir Date: Thu Dec 22 13:13:09 2022 +0300 fix pr issues commit 26ffb226d457ebf0d2f222c4ee6608971b4a8ffc Author: akildemir Date: Thu Dec 22 13:11:43 2022 +0300 remove extraneous rpc call commit 0e829f853151c06c54d9077b2477e59ac7a1e6e4 Author: akildemir Date: Thu Dec 15 13:56:53 2022 +0300 add scan tests commit 5123c7f121a6823d5e03eeae7eff024a6b6d38c8 Author: akildemir Date: Thu Dec 15 13:56:13 2022 +0300 add new address functions & comments --- coins/monero/src/wallet/address.rs | 9 + coins/monero/src/wallet/mod.rs | 102 ++++++------ coins/monero/src/wallet/scan.rs | 2 +- coins/monero/tests/add_data.rs | 11 +- coins/monero/tests/runner.rs | 51 +++--- coins/monero/tests/scan.rs | 257 +++++++++++++++++++++++++++++ processor/src/coin/monero.rs | 33 ++-- 7 files changed, 371 insertions(+), 94 deletions(-) create mode 100644 coins/monero/tests/scan.rs diff --git a/coins/monero/src/wallet/address.rs b/coins/monero/src/wallet/address.rs index 063c7e6f..09ff5aca 100644 --- a/coins/monero/src/wallet/address.rs +++ b/coins/monero/src/wallet/address.rs @@ -27,6 +27,15 @@ pub enum AddressType { Featured(bool, Option<[u8; 8]>, bool), } +/// Address specification. Used internally to create addresses. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] +pub enum AddressSpec { + Standard, + Integrated([u8; 8]), + Subaddress(u32, u32), + Featured(Option<(u32, u32)>, Option<[u8; 8]>, bool), +} + impl AddressType { pub fn subaddress(&self) -> bool { matches!(self, AddressType::Subaddress) || matches!(self, AddressType::Featured(true, ..)) diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index 5b776d2d..ae393ab4 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -16,7 +16,7 @@ pub(crate) use extra::{PaymentId, ExtraField, Extra}; /// Address encoding and decoding functionality. pub mod address; -use address::{Network, AddressType, AddressMeta, MoneroAddress}; +use address::{Network, AddressType, AddressSpec, AddressMeta, MoneroAddress}; mod scan; pub use scan::{ReceivedOutput, SpendableOutput}; @@ -106,7 +106,7 @@ impl ViewPair { ViewPair { spend, view } } - pub(crate) fn subaddress(&self, index: (u32, u32)) -> Scalar { + fn subaddress_derivation(&self, index: (u32, u32)) -> Scalar { if index == (0, 0) { return Scalar::zero(); } @@ -121,6 +121,49 @@ impl ViewPair { .concat(), )) } + + fn subaddress_keys(&self, index: (u32, u32)) -> Option<(EdwardsPoint, EdwardsPoint)> { + if index == (0, 0) { + return None; + } + + let scalar = self.subaddress_derivation(index); + let spend = self.spend + (&scalar * &ED25519_BASEPOINT_TABLE); + let view = self.view.deref() * spend; + Some((spend, view)) + } + + /// Returns an address with the provided specification. + pub fn address(&self, network: Network, spec: AddressSpec) -> MoneroAddress { + let mut spend = self.spend; + let mut view: EdwardsPoint = self.view.deref() * &ED25519_BASEPOINT_TABLE; + + // construct the address meta + let meta = match spec { + AddressSpec::Standard => AddressMeta::new(network, AddressType::Standard), + AddressSpec::Integrated(payment_id) => { + AddressMeta::new(network, AddressType::Integrated(payment_id)) + } + AddressSpec::Subaddress(i1, i2) => { + if let Some(keys) = self.subaddress_keys((i1, i2)) { + (spend, view) = keys; + AddressMeta::new(network, AddressType::Subaddress) + } else { + AddressMeta::new(network, AddressType::Standard) + } + } + AddressSpec::Featured(subaddress, payment_id, guaranteed) => { + let mut is_subaddress = false; + if let Some(Some(keys)) = subaddress.map(|subaddress| self.subaddress_keys(subaddress)) { + (spend, view) = keys; + is_subaddress = true; + } + AddressMeta::new(network, AddressType::Featured(is_subaddress, payment_id, guaranteed)) + } + }; + + MoneroAddress::new(meta, spend, view) + } } /// Transaction scanner. @@ -130,7 +173,6 @@ impl ViewPair { #[derive(Clone)] pub struct Scanner { pair: ViewPair, - network: Network, pub(crate) subaddresses: HashMap, pub(crate) burning_bug: Option>, } @@ -138,7 +180,6 @@ pub struct Scanner { impl Zeroize for Scanner { fn zeroize(&mut self) { self.pair.zeroize(); - self.network.zeroize(); // These may not be effective, unfortunately for (mut key, mut value) in self.subaddresses.drain() { @@ -163,59 +204,26 @@ impl ZeroizeOnDrop for Scanner {} impl Scanner { /// Create a Scanner from a ViewPair. - /// The network is used for generating subaddresses. /// burning_bug is a HashSet of used keys, intended to prevent key reuse which would burn funds. /// When an output is successfully scanned, the output key MUST be saved to disk. /// When a new scanner is created, ALL saved output keys must be passed in to be secure. /// If None is passed, a modified shared key derivation is used which is immune to the burning /// bug (specifically the Guaranteed feature from Featured Addresses). // TODO: Should this take in a DB access handle to ensure output keys are saved? - pub fn from_view( - pair: ViewPair, - network: Network, - burning_bug: Option>, - ) -> Scanner { + pub fn from_view(pair: ViewPair, burning_bug: Option>) -> Scanner { let mut subaddresses = HashMap::new(); subaddresses.insert(pair.spend.compress(), (0, 0)); - Scanner { pair, network, subaddresses, burning_bug } + Scanner { pair, subaddresses, burning_bug } } - /// Return the main address for this view pair. - pub fn address(&self) -> MoneroAddress { - MoneroAddress::new( - AddressMeta::new( - self.network, - if self.burning_bug.is_none() { - AddressType::Featured(false, None, true) - } else { - AddressType::Standard - }, - ), - self.pair.spend, - self.pair.view.deref() * &ED25519_BASEPOINT_TABLE, - ) - } - - /// Return the specified subaddress for this view pair. - pub fn subaddress(&mut self, index: (u32, u32)) -> MoneroAddress { - if index == (0, 0) { - return self.address(); + /// Register a subaddress. + // There used to be an address function here, yet it wasn't safe. It could generate addresses + // incompatible with the Scanner. While we could return None for that, then we have the issue + // of runtime failures to generate an address. + // Removing that API was the simplest option. + pub fn register_subaddress(&mut self, subaddress: (u32, u32)) { + if let Some((spend, _)) = self.pair.subaddress_keys(subaddress) { + self.subaddresses.insert(spend.compress(), subaddress); } - - let spend = self.pair.spend + (&self.pair.subaddress(index) * &ED25519_BASEPOINT_TABLE); - self.subaddresses.insert(spend.compress(), index); - - MoneroAddress::new( - AddressMeta::new( - self.network, - if self.burning_bug.is_none() { - AddressType::Featured(true, None, true) - } else { - AddressType::Subaddress - }, - ), - spend, - self.pair.view.deref() * spend, - ) } } diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index 2dff5ed5..cefa3d1e 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -293,7 +293,7 @@ impl Scanner { // If we did though, it'd enable bypassing the included burning bug protection debug_assert!(output_key.is_torsion_free()); - let key_offset = shared_key + self.pair.subaddress(subaddress); + let key_offset = shared_key + self.pair.subaddress_derivation(subaddress); // Since we've found an output to us, get its amount let mut commitment = Commitment::zero(); diff --git a/coins/monero/tests/add_data.rs b/coins/monero/tests/add_data.rs index 1808472a..a620a73d 100644 --- a/coins/monero/tests/add_data.rs +++ b/coins/monero/tests/add_data.rs @@ -1,4 +1,4 @@ -use monero_serai::{rpc::Rpc, wallet::TransactionError, transaction::Transaction}; +use monero_serai::{wallet::TransactionError, transaction::Transaction}; mod runner; @@ -15,8 +15,7 @@ test!( builder.add_payment(addr, 5); (builder.build().unwrap(), (arbitrary_data,)) }, - |rpc: Rpc, signed: Transaction, mut scanner: Scanner, data: (Vec,)| async move { - let tx = rpc.get_transaction(signed.hash()).await.unwrap(); + |_, tx: Transaction, mut scanner: Scanner, data: (Vec,)| async move { let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0); assert_eq!(output.commitment().amount, 5); assert_eq!(output.arbitrary_data()[0], data.0); @@ -39,8 +38,7 @@ test!( builder.add_payment(addr, 5); (builder.build().unwrap(), data) }, - |rpc: Rpc, signed: Transaction, mut scanner: Scanner, data: Vec| async move { - let tx = rpc.get_transaction(signed.hash()).await.unwrap(); + |_, tx: Transaction, mut scanner: Scanner, data: Vec| async move { let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0); assert_eq!(output.commitment().amount, 5); assert_eq!(output.arbitrary_data(), vec![data; 5]); @@ -65,8 +63,7 @@ test!( builder.add_payment(addr, 5); (builder.build().unwrap(), data) }, - |rpc: Rpc, signed: Transaction, mut scanner: Scanner, data: Vec| async move { - let tx = rpc.get_transaction(signed.hash()).await.unwrap(); + |_, tx: Transaction, mut scanner: Scanner, data: Vec| async move { let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0); assert_eq!(output.commitment().amount, 5); assert_eq!(output.arbitrary_data(), vec![data]); diff --git a/coins/monero/tests/runner.rs b/coins/monero/tests/runner.rs index fe9239d7..8c202422 100644 --- a/coins/monero/tests/runner.rs +++ b/coins/monero/tests/runner.rs @@ -1,4 +1,5 @@ use core::ops::Deref; +use std::collections::HashSet; use lazy_static::lazy_static; @@ -12,8 +13,9 @@ use tokio::sync::Mutex; use monero_serai::{ Protocol, random_scalar, wallet::{ - ViewPair, - address::{Network, AddressType, AddressMeta, MoneroAddress}, + ViewPair, Scanner, + address::{Network, AddressType, AddressSpec, AddressMeta, MoneroAddress}, + SpendableOutput, }, rpc::Rpc, }; @@ -56,6 +58,21 @@ pub async fn mine_until_unlocked(rpc: &Rpc, addr: &str, tx_hash: [u8; 32]) { rpc.generate_blocks(addr, 9).await.unwrap(); } +// Mines 60 blocks and returns an unlocked miner TX output. +pub async fn get_miner_tx_output(rpc: &Rpc, view: &ViewPair) -> SpendableOutput { + let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); + + // Mine 60 blocks to unlock a miner TX + let start = rpc.get_height().await.unwrap(); + rpc + .generate_blocks(&view.address(Network::Mainnet, AddressSpec::Standard).to_string(), 60) + .await + .unwrap(); + + let block = rpc.get_block(start).await.unwrap(); + scanner.scan(rpc, &block).await.unwrap().swap_remove(0).ignore_timelock().swap_remove(0) +} + pub async fn rpc() -> Rpc { let rpc = Rpc::new("http://127.0.0.1:18081".to_string()).unwrap(); @@ -137,12 +154,12 @@ macro_rules! test { use monero_serai::{ random_scalar, wallet::{ - address::Network, ViewPair, Scanner, SignableTransaction, + address::{Network, AddressSpec}, ViewPair, Scanner, SignableTransaction, SignableTransactionBuilder, }, }; - use runner::{random_address, rpc, mine_until_unlocked}; + use runner::{random_address, rpc, mine_until_unlocked, get_miner_tx_output}; type Builder = SignableTransactionBuilder; @@ -168,28 +185,12 @@ macro_rules! test { keys[&1].group_key().0 }; - let view = ViewPair::new(spend_pub, Zeroizing::new(random_scalar(&mut OsRng))); - let rpc = rpc().await; - let (addr, miner_tx) = { - let mut scanner = - Scanner::from_view(view.clone(), Network::Mainnet, Some(HashSet::new())); - let addr = scanner.address(); + let view = ViewPair::new(spend_pub, Zeroizing::new(random_scalar(&mut OsRng))); + let addr = view.address(Network::Mainnet, AddressSpec::Standard); - // mine 60 blocks to unlock a miner tx - let start = rpc.get_height().await.unwrap(); - rpc.generate_blocks(&addr.to_string(), 60).await.unwrap(); - - let block = rpc.get_block(start).await.unwrap(); - ( - addr, - scanner.scan( - &rpc, - &block - ).await.unwrap().swap_remove(0).ignore_timelock().swap_remove(0) - ) - }; + let miner_tx = get_miner_tx_output(&rpc, &view).await; let builder = SignableTransactionBuilder::new( rpc.get_protocol().await.unwrap(), @@ -246,7 +247,7 @@ macro_rules! test { mine_until_unlocked(&rpc, &random_address().2.to_string(), signed.hash()).await; let tx = rpc.get_transaction(signed.hash()).await.unwrap(); let scanner = - Scanner::from_view(view.clone(), Network::Mainnet, Some(HashSet::new())); + Scanner::from_view(view.clone(), Some(HashSet::new())); ($first_checks)(rpc.clone(), tx, scanner, state).await }); #[allow(unused_variables, unused_mut, unused_assignments)] @@ -267,7 +268,7 @@ macro_rules! test { #[allow(unused_assignments)] { let scanner = - Scanner::from_view(view.clone(), Network::Mainnet, Some(HashSet::new())); + Scanner::from_view(view.clone(), Some(HashSet::new())); carried_state = Box::new(($checks)(rpc.clone(), tx, scanner, state).await); } diff --git a/coins/monero/tests/scan.rs b/coins/monero/tests/scan.rs new file mode 100644 index 00000000..ccc2f906 --- /dev/null +++ b/coins/monero/tests/scan.rs @@ -0,0 +1,257 @@ +use rand::RngCore; + +use monero_serai::transaction::Transaction; + +mod runner; + +test!( + scan_standard_address, + ( + |_, mut builder: Builder, _| async move { + let view = runner::random_address().1; + let scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); + builder.add_payment(view.address(Network::Mainnet, AddressSpec::Standard), 5); + (builder.build().unwrap(), scanner) + }, + |_, tx: Transaction, _, mut state: Scanner| async move { + let output = state.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + }, + ), +); + +test!( + scan_subaddress, + ( + |_, mut builder: Builder, _| async move { + let subaddress = (0, 1); + + let view = runner::random_address().1; + let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); + scanner.register_subaddress(subaddress); + + builder.add_payment( + view.address(Network::Mainnet, AddressSpec::Subaddress(subaddress.0, subaddress.1)), + 5, + ); + (builder.build().unwrap(), (scanner, subaddress)) + }, + |_, tx: Transaction, _, mut state: (Scanner, (u32, u32))| async move { + let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + assert_eq!(output.metadata.subaddress, state.1); + }, + ), +); + +test!( + scan_integrated_address, + ( + |_, mut builder: Builder, _| async move { + let view = runner::random_address().1; + let scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); + + let mut payment_id = [0u8; 8]; + OsRng.fill_bytes(&mut payment_id); + + builder.add_payment(view.address(Network::Mainnet, AddressSpec::Integrated(payment_id)), 5); + (builder.build().unwrap(), (scanner, payment_id)) + }, + |_, tx: Transaction, _, mut state: (Scanner, [u8; 8])| async move { + let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + assert_eq!(output.metadata.payment_id, state.1); + }, + ), +); + +test!( + scan_featured_standard, + ( + |_, mut builder: Builder, _| async move { + let view = runner::random_address().1; + let scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); + builder + .add_payment(view.address(Network::Mainnet, AddressSpec::Featured(None, None, false)), 5); + (builder.build().unwrap(), scanner) + }, + |_, tx: Transaction, _, mut state: Scanner| async move { + let output = state.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + }, + ), +); + +test!( + scan_featured_subaddress, + ( + |_, mut builder: Builder, _| async move { + let subaddress = (0, 2); + + let view = runner::random_address().1; + let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); + scanner.register_subaddress(subaddress); + + builder.add_payment( + view.address(Network::Mainnet, AddressSpec::Featured(Some(subaddress), None, false)), + 5, + ); + (builder.build().unwrap(), (scanner, subaddress)) + }, + |_, tx: Transaction, _, mut state: (Scanner, (u32, u32))| async move { + let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + assert_eq!(output.metadata.subaddress, state.1); + }, + ), +); + +test!( + scan_featured_integrated, + ( + |_, mut builder: Builder, _| async move { + let view = runner::random_address().1; + let scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); + let mut payment_id = [0u8; 8]; + OsRng.fill_bytes(&mut payment_id); + + builder.add_payment( + view.address(Network::Mainnet, AddressSpec::Featured(None, Some(payment_id), false)), + 5, + ); + (builder.build().unwrap(), (scanner, payment_id)) + }, + |_, tx: Transaction, _, mut state: (Scanner, [u8; 8])| async move { + let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + assert_eq!(output.metadata.payment_id, state.1); + }, + ), +); + +test!( + scan_featured_integrated_subaddress, + ( + |_, mut builder: Builder, _| async move { + let subaddress = (0, 3); + + let view = runner::random_address().1; + let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); + scanner.register_subaddress(subaddress); + + let mut payment_id = [0u8; 8]; + OsRng.fill_bytes(&mut payment_id); + + builder.add_payment( + view.address( + Network::Mainnet, + AddressSpec::Featured(Some(subaddress), Some(payment_id), false), + ), + 5, + ); + (builder.build().unwrap(), (scanner, payment_id, subaddress)) + }, + |_, tx: Transaction, _, mut state: (Scanner, [u8; 8], (u32, u32))| async move { + let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + assert_eq!(output.metadata.payment_id, state.1); + assert_eq!(output.metadata.subaddress, state.2); + }, + ), +); + +test!( + scan_guaranteed_standard, + ( + |_, mut builder: Builder, _| async move { + let view = runner::random_address().1; + let scanner = Scanner::from_view(view.clone(), None); + + builder + .add_payment(view.address(Network::Mainnet, AddressSpec::Featured(None, None, true)), 5); + (builder.build().unwrap(), scanner) + }, + |_, tx: Transaction, _, mut state: Scanner| async move { + let output = state.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + }, + ), +); + +test!( + scan_guaranteed_subaddress, + ( + |_, mut builder: Builder, _| async move { + let subaddress = (1, 0); + + let view = runner::random_address().1; + let mut scanner = Scanner::from_view(view.clone(), None); + scanner.register_subaddress(subaddress); + + builder.add_payment( + view.address(Network::Mainnet, AddressSpec::Featured(Some(subaddress), None, true)), + 5, + ); + (builder.build().unwrap(), (scanner, subaddress)) + }, + |_, tx: Transaction, _, mut state: (Scanner, (u32, u32))| async move { + let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + assert_eq!(output.metadata.subaddress, state.1); + }, + ), +); + +test!( + scan_guaranteed_integrated, + ( + |_, mut builder: Builder, _| async move { + let view = runner::random_address().1; + let scanner = Scanner::from_view(view.clone(), None); + let mut payment_id = [0u8; 8]; + OsRng.fill_bytes(&mut payment_id); + + builder.add_payment( + view.address(Network::Mainnet, AddressSpec::Featured(None, Some(payment_id), true)), + 5, + ); + (builder.build().unwrap(), (scanner, payment_id)) + }, + |_, tx: Transaction, _, mut state: (Scanner, [u8; 8])| async move { + let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + assert_eq!(output.metadata.payment_id, state.1); + }, + ), +); + +test!( + scan_guaranteed_integrated_subaddress, + ( + |_, mut builder: Builder, _| async move { + let subaddress = (1, 1); + + let view = runner::random_address().1; + let mut scanner = Scanner::from_view(view.clone(), None); + scanner.register_subaddress(subaddress); + + let mut payment_id = [0u8; 8]; + OsRng.fill_bytes(&mut payment_id); + + builder.add_payment( + view.address( + Network::Mainnet, + AddressSpec::Featured(Some(subaddress), Some(payment_id), true), + ), + 5, + ); + (builder.build().unwrap(), (scanner, payment_id, subaddress)) + }, + |_, tx: Transaction, _, mut state: (Scanner, [u8; 8], (u32, u32))| async move { + let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); + assert_eq!(output.commitment().amount, 5); + assert_eq!(output.metadata.payment_id, state.1); + assert_eq!(output.metadata.subaddress, state.2); + }, + ), +); diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index b1656194..dc14fc0d 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -14,7 +14,7 @@ use monero_serai::{ rpc::Rpc, wallet::{ ViewPair, Scanner, - address::{Network, MoneroAddress}, + address::{Network, AddressSpec, MoneroAddress}, Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine, }, }; @@ -75,23 +75,28 @@ impl Monero { Monero { rpc: Rpc::new(url).unwrap(), view: Zeroizing::new(additional_key::(0).0) } } + fn view_pair(&self, spend: dfg::EdwardsPoint) -> ViewPair { + ViewPair::new(spend.0, self.view.clone()) + } + fn scanner(&self, spend: dfg::EdwardsPoint) -> Scanner { - Scanner::from_view(ViewPair::new(spend.0, self.view.clone()), Network::Mainnet, None) + Scanner::from_view(self.view_pair(spend), None) } #[cfg(test)] - fn empty_scanner() -> Scanner { + fn test_view_pair() -> ViewPair { use group::Group; - Scanner::from_view( - ViewPair::new(*dfg::EdwardsPoint::generator(), Zeroizing::new(Scalar::one())), - Network::Mainnet, - Some(std::collections::HashSet::new()), - ) + ViewPair::new(*dfg::EdwardsPoint::generator(), Zeroizing::new(Scalar::one())) } #[cfg(test)] - fn empty_address() -> MoneroAddress { - Self::empty_scanner().address() + fn test_scanner() -> Scanner { + Scanner::from_view(Self::test_view_pair(), Some(std::collections::HashSet::new())) + } + + #[cfg(test)] + fn test_address() -> MoneroAddress { + Self::test_view_pair().address(Network::Mainnet, AddressSpec::Standard) } } @@ -121,7 +126,7 @@ impl Coin for Monero { const MAX_OUTPUTS: usize = 16; fn address(&self, key: dfg::EdwardsPoint) -> Self::Address { - self.scanner(key).address() + self.view_pair(key).address(Network::Mainnet, AddressSpec::Featured(None, None, true)) } async fn get_latest_block_number(&self) -> Result { @@ -228,7 +233,7 @@ impl Coin for Monero { Some(serde_json::json!({ "method": "generateblocks", "params": { - "wallet_address": Self::empty_address().to_string(), + "wallet_address": Self::test_address().to_string(), "amount_of_blocks": 10 }, })), @@ -249,7 +254,7 @@ impl Coin for Monero { self.mine_block().await; } - let outputs = Self::empty_scanner() + let outputs = Self::test_scanner() .scan(&self.rpc, &self.rpc.get_block(new_block).await.unwrap()) .await .unwrap() @@ -262,7 +267,7 @@ impl Coin for Monero { self.rpc.get_protocol().await.unwrap(), outputs, vec![(address, amount - fee)], - Some(Self::empty_address()), + Some(Self::test_address()), vec![], self.rpc.get_fee().await.unwrap(), ) From b303649f9dfbeadaa5a655dc845582553325deae Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 7 Jan 2023 02:39:50 -0500 Subject: [PATCH 09/74] Add OutputType, either external, branch, or change Used to delineate, by address received to, the intention of the output. --- processor/src/coin/mod.rs | 19 ++++++++--- processor/src/coin/monero.rs | 62 +++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/processor/src/coin/mod.rs b/processor/src/coin/mod.rs index 136df59b..6cb19509 100644 --- a/processor/src/coin/mod.rs +++ b/processor/src/coin/mod.rs @@ -13,15 +13,24 @@ use frost::{ pub mod monero; pub use self::monero::Monero; -#[derive(Clone, Error, Debug)] +#[derive(Clone, Copy, Error, Debug)] pub enum CoinError { #[error("failed to connect to coin daemon")] ConnectionError, } +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum OutputType { + External, + Branch, + Change, +} + pub trait Output: Sized + Clone { type Id: AsRef<[u8]>; + fn kind(&self) -> OutputType; + fn id(&self) -> Self::Id; fn amount(&self) -> u64; @@ -48,8 +57,11 @@ pub trait Coin { const MAX_INPUTS: usize; const MAX_OUTPUTS: usize; // TODO: Decide if this includes change or not + /// Address for the given group key to receive external coins to. // Doesn't have to take self, enables some level of caching which is pleasant fn address(&self, key: ::G) -> Self::Address; + /// Address for the given group key to use for scheduled branches. + fn branch_address(&self, key: ::G) -> Self::Address; async fn get_latest_block_number(&self) -> Result; async fn get_block(&self, number: usize) -> Result; @@ -59,9 +71,7 @@ pub trait Coin { key: ::G, ) -> Result, CoinError>; - // TODO: Remove - async fn is_confirmed(&self, tx: &[u8]) -> Result; - + #[allow(clippy::too_many_arguments)] async fn prepare_send( &self, keys: ThresholdKeys, @@ -69,6 +79,7 @@ pub trait Coin { block_number: usize, inputs: Vec, payments: &[(Self::Address, u64)], + change: Option<::G>, fee: Self::Fee, ) -> Result; diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index dc14fc0d..1a132147 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -21,7 +21,7 @@ use monero_serai::{ use crate::{ additional_key, - coin::{CoinError, Output as OutputTrait, Coin}, + coin::{CoinError, OutputType, Output as OutputTrait, Coin}, }; #[derive(Clone, Debug)] @@ -32,12 +32,25 @@ impl From for Output { } } +const EXTERNAL_SUBADDRESS: (u32, u32) = (0, 0); +const BRANCH_SUBADDRESS: (u32, u32) = (1, 0); +const CHANGE_SUBADDRESS: (u32, u32) = (2, 0); + impl OutputTrait for Output { // While we could use (tx, o), using the key ensures we won't be susceptible to the burning bug. - // While the Monero library offers a variant which allows senders to ensure their TXs have unique - // output keys, Serai can still be targeted using the classic burning bug + // While we already are immune, thanks to using featured address, this doesn't hurt and is + // technically more efficient. type Id = [u8; 32]; + fn kind(&self) -> OutputType { + match self.0.output.metadata.subaddress { + EXTERNAL_SUBADDRESS => OutputType::External, + BRANCH_SUBADDRESS => OutputType::Branch, + CHANGE_SUBADDRESS => OutputType::Change, + _ => panic!("unrecognized address was scanned for"), + } + } + fn id(&self) -> Self::Id { self.0.output.data.key.compress().to_bytes() } @@ -79,8 +92,18 @@ impl Monero { ViewPair::new(spend.0, self.view.clone()) } + fn address_internal(&self, spend: dfg::EdwardsPoint, subaddress: (u32, u32)) -> MoneroAddress { + self + .view_pair(spend) + .address(Network::Mainnet, AddressSpec::Featured(Some(subaddress), None, true)) + } + fn scanner(&self, spend: dfg::EdwardsPoint) -> Scanner { - Scanner::from_view(self.view_pair(spend), None) + let mut scanner = Scanner::from_view(self.view_pair(spend), None); + scanner.register_subaddress(EXTERNAL_SUBADDRESS); // Pointless as (0, 0) is already registered + scanner.register_subaddress(BRANCH_SUBADDRESS); + scanner.register_subaddress(CHANGE_SUBADDRESS); + scanner } #[cfg(test)] @@ -126,7 +149,11 @@ impl Coin for Monero { const MAX_OUTPUTS: usize = 16; fn address(&self, key: dfg::EdwardsPoint) -> Self::Address { - self.view_pair(key).address(Network::Mainnet, AddressSpec::Featured(None, None, true)) + self.address_internal(key, EXTERNAL_SUBADDRESS) + } + + fn branch_address(&self, key: dfg::EdwardsPoint) -> Self::Address { + self.address_internal(key, BRANCH_SUBADDRESS) } async fn get_latest_block_number(&self) -> Result { @@ -151,21 +178,20 @@ impl Coin for Monero { .map_err(|_| CoinError::ConnectionError)? .iter() .flat_map(|outputs| outputs.not_locked()) - .map(Output::from) + // This should be pointless as we shouldn't be able to scan for any other subaddress + // This just ensures nothing invalid makes it in + .filter_map(|output| { + if ![EXTERNAL_SUBADDRESS, BRANCH_SUBADDRESS, CHANGE_SUBADDRESS] + .contains(&output.output.metadata.subaddress) + { + return None; + } + Some(Output::from(output)) + }) .collect(), ) } - async fn is_confirmed(&self, tx: &[u8]) -> Result { - let tx_block_number = self - .rpc - .get_transaction_block_number(tx) - .await - .map_err(|_| CoinError::ConnectionError)? - .unwrap_or(usize::MAX); - Ok((self.get_latest_block_number().await?.saturating_sub(tx_block_number) + 1) >= 10) - } - async fn prepare_send( &self, keys: ThresholdKeys, @@ -173,9 +199,9 @@ impl Coin for Monero { block_number: usize, mut inputs: Vec, payments: &[(MoneroAddress, u64)], + change: Option, fee: Fee, ) -> Result { - let spend = keys.group_key(); Ok(SignableTransaction { keys, transcript, @@ -184,7 +210,7 @@ impl Coin for Monero { self.rpc.get_protocol().await.unwrap(), // TODO: Make this deterministic inputs.drain(..).map(|input| input.0).collect(), payments.to_vec(), - Some(self.address(spend)), + change.map(|change| self.address_internal(change, CHANGE_SUBADDRESS)), vec![], fee, ) From 9662e9e1afc5ef80acaf5d5386d2bdaa587b6872 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 7 Jan 2023 03:13:54 -0500 Subject: [PATCH 10/74] Have Coin::get_outputs return by transaction, not by block --- processor/src/coin/mod.rs | 2 +- processor/src/coin/monero.rs | 42 +++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/processor/src/coin/mod.rs b/processor/src/coin/mod.rs index 6cb19509..1bc609b2 100644 --- a/processor/src/coin/mod.rs +++ b/processor/src/coin/mod.rs @@ -69,7 +69,7 @@ pub trait Coin { &self, block: &Self::Block, key: ::G, - ) -> Result, CoinError>; + ) -> Result>, CoinError>; #[allow(clippy::too_many_arguments)] async fn prepare_send( diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index 1a132147..78a6751a 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -169,25 +169,33 @@ impl Coin for Monero { &self, block: &Self::Block, key: dfg::EdwardsPoint, - ) -> Result, CoinError> { - Ok( - self - .scanner(key) - .scan(&self.rpc, block) - .await - .map_err(|_| CoinError::ConnectionError)? - .iter() - .flat_map(|outputs| outputs.not_locked()) - // This should be pointless as we shouldn't be able to scan for any other subaddress - // This just ensures nothing invalid makes it in - .filter_map(|output| { - if ![EXTERNAL_SUBADDRESS, BRANCH_SUBADDRESS, CHANGE_SUBADDRESS] + ) -> Result>, CoinError> { + let mut transactions = self + .scanner(key) + .scan(&self.rpc, block) + .await + .map_err(|_| CoinError::ConnectionError)? + .iter() + .map(|outputs| outputs.not_locked()) + .collect::>(); + + // This should be pointless as we shouldn't be able to scan for any other subaddress + // This just ensures nothing invalid makes it through + for transaction in transactions.iter_mut() { + *transaction = transaction + .drain(..) + .filter(|output| { + [EXTERNAL_SUBADDRESS, BRANCH_SUBADDRESS, CHANGE_SUBADDRESS] .contains(&output.output.metadata.subaddress) - { - return None; - } - Some(Output::from(output)) }) + .collect(); + } + transactions = transactions.drain(..).filter(|outputs| !outputs.is_empty()).collect(); + + Ok( + transactions + .drain(..) + .map(|mut transaction| transaction.drain(..).map(Output::from).collect()) .collect(), ) } From 814a9a8d359ba379e846f6090356e89a14ae9b49 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 7 Jan 2023 03:21:06 -0500 Subject: [PATCH 11/74] Revert the previous commit's API change --- processor/src/coin/mod.rs | 2 +- processor/src/coin/monero.rs | 5 ++--- processor/src/wallet.rs | 15 +++++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/processor/src/coin/mod.rs b/processor/src/coin/mod.rs index 1bc609b2..6cb19509 100644 --- a/processor/src/coin/mod.rs +++ b/processor/src/coin/mod.rs @@ -69,7 +69,7 @@ pub trait Coin { &self, block: &Self::Block, key: ::G, - ) -> Result>, CoinError>; + ) -> Result, CoinError>; #[allow(clippy::too_many_arguments)] async fn prepare_send( diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index 78a6751a..ca44ad2b 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -169,7 +169,7 @@ impl Coin for Monero { &self, block: &Self::Block, key: dfg::EdwardsPoint, - ) -> Result>, CoinError> { + ) -> Result, CoinError> { let mut transactions = self .scanner(key) .scan(&self.rpc, block) @@ -190,12 +190,11 @@ impl Coin for Monero { }) .collect(); } - transactions = transactions.drain(..).filter(|outputs| !outputs.is_empty()).collect(); Ok( transactions .drain(..) - .map(|mut transaction| transaction.drain(..).map(Output::from).collect()) + .flat_map(|mut outputs| outputs.drain(..).map(Output::from).collect::>()) .collect(), ) } diff --git a/processor/src/wallet.rs b/processor/src/wallet.rs index f117e41c..340bccea 100644 --- a/processor/src/wallet.rs +++ b/processor/src/wallet.rs @@ -232,11 +232,6 @@ impl Wallet { self.coin.address(self.keys[self.keys.len() - 1].0.group_key()) } - // TODO: Remove - pub async fn is_confirmed(&mut self, tx: &[u8]) -> Result { - self.coin.is_confirmed(tx).await - } - pub async fn poll(&mut self) -> Result<(), CoinError> { if self.coin.get_latest_block_number().await? < (C::CONFIRMATIONS - 1) { return Ok(()); @@ -325,7 +320,15 @@ impl Wallet { let tx = self .coin - .prepare_send(keys.clone(), transcript, acknowledged_block, inputs, &outputs, fee) + .prepare_send( + keys.clone(), + transcript, + acknowledged_block, + inputs, + &outputs, + Some(keys.group_key()), + fee, + ) .await?; // self.db.save_tx(tx) // TODO txs.push(tx); From 1d6df0099ce62a5f80c00791668e8b7a46e43ffd Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 7 Jan 2023 04:00:12 -0500 Subject: [PATCH 12/74] Exposed a hash-based API for accessing blocks Also corrects a few panics, which shouldn't have been present, and unnecessary Cursor uses. --- coins/monero/src/rpc.rs | 59 ++++++++++++++++++++++---------- coins/monero/src/wallet/extra.rs | 4 +-- coins/monero/src/wallet/scan.rs | 4 +-- coins/monero/tests/runner.rs | 4 +-- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/coins/monero/src/rpc.rs b/coins/monero/src/rpc.rs index 94bf84ff..ae4b6a80 100644 --- a/coins/monero/src/rpc.rs +++ b/coins/monero/src/rpc.rs @@ -249,9 +249,10 @@ impl Rpc { .txs .iter() .map(|res| { - let tx = Transaction::deserialize(&mut std::io::Cursor::new(rpc_hex( - if !res.as_hex.is_empty() { &res.as_hex } else { &res.pruned_as_hex }, - )?)) + let tx = Transaction::deserialize::<&[u8]>( + &mut rpc_hex(if !res.as_hex.is_empty() { &res.as_hex } else { &res.pruned_as_hex })? + .as_ref(), + ) .map_err(|_| match hash_hex(&res.tx_hash) { Ok(hash) => RpcError::InvalidTransaction(hash), Err(err) => err, @@ -287,27 +288,52 @@ impl Rpc { Ok(txs.txs[0].block_height) } - pub async fn get_block(&self, height: usize) -> Result { + pub async fn get_block_hash(&self, number: usize) -> Result<[u8; 32], RpcError> { + #[derive(Deserialize, Debug)] + struct BlockHeaderResponse { + hash: String, + } + #[derive(Deserialize, Debug)] + struct BlockHeaderByHeightResponse { + block_header: BlockHeaderResponse, + } + + let header: BlockHeaderByHeightResponse = + self.json_rpc_call("get_block_header_by_height", Some(json!({ "height": number }))).await?; + rpc_hex(&header.block_header.hash)?.try_into().map_err(|_| RpcError::InvalidNode) + } + + pub async fn get_block(&self, hash: [u8; 32]) -> Result { #[derive(Deserialize, Debug)] struct BlockResponse { blob: String, } - let block: BlockResponse = - self.json_rpc_call("get_block", Some(json!({ "height": height }))).await?; - Ok( - Block::deserialize(&mut std::io::Cursor::new(rpc_hex(&block.blob)?)) - .expect("Monero returned a block we couldn't deserialize"), - ) + let res: BlockResponse = + self.json_rpc_call("get_block", Some(json!({ "hash": hex::encode(hash) }))).await?; + + Block::deserialize::<&[u8]>(&mut rpc_hex(&res.blob)?.as_ref()) + .map_err(|_| RpcError::InvalidNode) } - pub async fn get_block_transactions(&self, height: usize) -> Result, RpcError> { - let block = self.get_block(height).await?; + pub async fn get_block_by_number(&self, number: usize) -> Result { + self.get_block(self.get_block_hash(number).await?).await + } + + pub async fn get_block_transactions(&self, hash: [u8; 32]) -> Result, RpcError> { + let block = self.get_block(hash).await?; let mut res = vec![block.miner_tx]; res.extend(self.get_transactions(&block.txs).await?); Ok(res) } + pub async fn get_block_transactions_by_number( + &self, + number: usize, + ) -> Result, RpcError> { + self.get_block_transactions(self.get_block_hash(number).await?).await + } + /// Get the output indexes of the specified transaction. pub async fn get_o_indexes(&self, hash: [u8; 32]) -> Result, RpcError> { #[derive(Serialize, Debug)] @@ -407,13 +433,8 @@ impl Rpc { &outs .outs .iter() - .map(|out| { - rpc_hex(&out.txid) - .expect("Monero returned an invalidly encoded hash") - .try_into() - .expect("Monero returned an invalid sized hash") - }) - .collect::>(), + .map(|out| rpc_hex(&out.txid)?.try_into().map_err(|_| RpcError::InvalidNode)) + .collect::, _>>()?, ) .await?; diff --git a/coins/monero/src/wallet/extra.rs b/coins/monero/src/wallet/extra.rs index ac8924a4..dda72f53 100644 --- a/coins/monero/src/wallet/extra.rs +++ b/coins/monero/src/wallet/extra.rs @@ -1,5 +1,5 @@ use core::ops::BitXor; -use std::io::{self, Read, Write, Cursor}; +use std::io::{self, Read, Write}; use zeroize::Zeroize; @@ -127,7 +127,7 @@ impl Extra { pub(crate) fn payment_id(&self) -> Option { for field in &self.0 { if let ExtraField::Nonce(data) = field { - return PaymentId::deserialize(&mut Cursor::new(data)).ok(); + return PaymentId::deserialize::<&[u8]>(&mut data.as_ref()).ok(); } } None diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index cefa3d1e..29dfdd07 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -1,5 +1,3 @@ -use std::io::Cursor; - use zeroize::{Zeroize, ZeroizeOnDrop}; use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint}; @@ -232,7 +230,7 @@ impl Timelocked { impl Scanner { /// Scan a transaction to discover the received outputs. pub fn scan_transaction(&mut self, tx: &Transaction) -> Timelocked { - let extra = Extra::deserialize(&mut Cursor::new(&tx.prefix.extra)); + let extra = Extra::deserialize::<&[u8]>(&mut tx.prefix.extra.as_ref()); let keys; let extra = if let Ok(extra) = extra { keys = extra.keys(); diff --git a/coins/monero/tests/runner.rs b/coins/monero/tests/runner.rs index 8c202422..6861889a 100644 --- a/coins/monero/tests/runner.rs +++ b/coins/monero/tests/runner.rs @@ -43,7 +43,7 @@ pub async fn mine_until_unlocked(rpc: &Rpc, addr: &str, tx_hash: [u8; 32]) { let mut height = rpc.get_height().await.unwrap(); let mut found = false; while !found { - let block = rpc.get_block(height - 1).await.unwrap(); + let block = rpc.get_block_by_number(height - 1).await.unwrap(); found = match block.txs.iter().find(|&&x| x == tx_hash) { Some(_) => true, None => { @@ -69,7 +69,7 @@ pub async fn get_miner_tx_output(rpc: &Rpc, view: &ViewPair) -> SpendableOutput .await .unwrap(); - let block = rpc.get_block(start).await.unwrap(); + let block = rpc.get_block_by_number(start).await.unwrap(); scanner.scan(rpc, &block).await.unwrap().swap_remove(0).ignore_timelock().swap_remove(0) } From ccf4ca2215e1b83ffe2bfdfcd1bf392aea02b97f Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 7 Jan 2023 04:03:11 -0500 Subject: [PATCH 13/74] Add an ID function to Coin::Block Also updates to the latest Monero lib API. --- processor/src/coin/mod.rs | 9 +++++++-- processor/src/coin/monero.rs | 21 ++++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/processor/src/coin/mod.rs b/processor/src/coin/mod.rs index 6cb19509..313dd2b3 100644 --- a/processor/src/coin/mod.rs +++ b/processor/src/coin/mod.rs @@ -19,6 +19,11 @@ pub enum CoinError { ConnectionError, } +pub trait Block: Sized + Clone { + type Id: Clone + Copy + AsRef<[u8]>; + fn id(&self) -> Self::Id; +} + #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum OutputType { External, @@ -27,7 +32,7 @@ pub enum OutputType { } pub trait Output: Sized + Clone { - type Id: AsRef<[u8]>; + type Id: Clone + Copy + AsRef<[u8]>; fn kind(&self) -> OutputType; @@ -44,7 +49,7 @@ pub trait Coin { type Fee: Copy; type Transaction; - type Block; + type Block: Block; type Output: Output; type SignableTransaction; diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index ca44ad2b..94f270c2 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -10,7 +10,7 @@ use frost::{curve::Ed25519, ThresholdKeys}; use monero_serai::{ transaction::Transaction, - block::Block, + block::Block as MBlock, rpc::Rpc, wallet::{ ViewPair, Scanner, @@ -21,9 +21,18 @@ use monero_serai::{ use crate::{ additional_key, - coin::{CoinError, OutputType, Output as OutputTrait, Coin}, + coin::{CoinError, Block as BlockTrait, OutputType, Output as OutputTrait, Coin}, }; +#[derive(Clone, Debug)] +pub struct Block([u8; 32], MBlock); +impl BlockTrait for Block { + type Id = [u8; 32]; + fn id(&self) -> Self::Id { + self.0 + } +} + #[derive(Clone, Debug)] pub struct Output(SpendableOutput); impl From for Output { @@ -162,7 +171,9 @@ impl Coin for Monero { } async fn get_block(&self, number: usize) -> Result { - self.rpc.get_block(number).await.map_err(|_| CoinError::ConnectionError) + let hash = self.rpc.get_block_hash(number).await.map_err(|_| CoinError::ConnectionError)?; + let block = self.rpc.get_block(hash).await.map_err(|_| CoinError::ConnectionError)?; + Ok(Block(hash, block)) } async fn get_outputs( @@ -172,7 +183,7 @@ impl Coin for Monero { ) -> Result, CoinError> { let mut transactions = self .scanner(key) - .scan(&self.rpc, block) + .scan(&self.rpc, &block.1) .await .map_err(|_| CoinError::ConnectionError)? .iter() @@ -288,7 +299,7 @@ impl Coin for Monero { } let outputs = Self::test_scanner() - .scan(&self.rpc, &self.rpc.get_block(new_block).await.unwrap()) + .scan(&self.rpc, &self.rpc.get_block_by_number(new_block).await.unwrap()) .await .unwrap() .swap_remove(0) From 7508106650d545948e8bbe147a782c82c4052998 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 7 Jan 2023 04:44:23 -0500 Subject: [PATCH 14/74] Use an explicit SubaddressIndex type --- coins/monero/src/wallet/address.rs | 27 +++++++++++++-- coins/monero/src/wallet/mod.rs | 53 ++++++++++++------------------ coins/monero/src/wallet/scan.rs | 51 +++++++++++++++++++--------- coins/monero/tests/scan.rs | 37 ++++++++++----------- processor/src/coin/mod.rs | 2 +- processor/src/coin/monero.rs | 28 ++++++++-------- 6 files changed, 115 insertions(+), 83 deletions(-) diff --git a/coins/monero/src/wallet/address.rs b/coins/monero/src/wallet/address.rs index 09ff5aca..b0f09927 100644 --- a/coins/monero/src/wallet/address.rs +++ b/coins/monero/src/wallet/address.rs @@ -27,13 +27,36 @@ pub enum AddressType { Featured(bool, Option<[u8; 8]>, bool), } +#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] +pub struct SubaddressIndex { + pub(crate) account: u32, + pub(crate) address: u32, +} + +impl SubaddressIndex { + pub const fn new(account: u32, address: u32) -> Option { + if (account == 0) && (address == 0) { + return None; + } + Some(SubaddressIndex { account, address }) + } + + pub fn account(&self) -> u32 { + self.account + } + + pub fn address(&self) -> u32 { + self.address + } +} + /// Address specification. Used internally to create addresses. #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] pub enum AddressSpec { Standard, Integrated([u8; 8]), - Subaddress(u32, u32), - Featured(Option<(u32, u32)>, Option<[u8; 8]>, bool), + Subaddress(SubaddressIndex), + Featured(Option, Option<[u8; 8]>, bool), } impl AddressType { diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index ae393ab4..48ee3a34 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -16,7 +16,7 @@ pub(crate) use extra::{PaymentId, ExtraField, Extra}; /// Address encoding and decoding functionality. pub mod address; -use address::{Network, AddressType, AddressSpec, AddressMeta, MoneroAddress}; +use address::{Network, AddressType, SubaddressIndex, AddressSpec, AddressMeta, MoneroAddress}; mod scan; pub use scan::{ReceivedOutput, SpendableOutput}; @@ -106,31 +106,23 @@ impl ViewPair { ViewPair { spend, view } } - fn subaddress_derivation(&self, index: (u32, u32)) -> Scalar { - if index == (0, 0) { - return Scalar::zero(); - } - + fn subaddress_derivation(&self, index: SubaddressIndex) -> Scalar { hash_to_scalar(&Zeroizing::new( [ b"SubAddr\0".as_ref(), Zeroizing::new(self.view.to_bytes()).as_ref(), - &index.0.to_le_bytes(), - &index.1.to_le_bytes(), + &index.account().to_le_bytes(), + &index.address().to_le_bytes(), ] .concat(), )) } - fn subaddress_keys(&self, index: (u32, u32)) -> Option<(EdwardsPoint, EdwardsPoint)> { - if index == (0, 0) { - return None; - } - + fn subaddress_keys(&self, index: SubaddressIndex) -> (EdwardsPoint, EdwardsPoint) { let scalar = self.subaddress_derivation(index); let spend = self.spend + (&scalar * &ED25519_BASEPOINT_TABLE); let view = self.view.deref() * spend; - Some((spend, view)) + (spend, view) } /// Returns an address with the provided specification. @@ -144,21 +136,18 @@ impl ViewPair { AddressSpec::Integrated(payment_id) => { AddressMeta::new(network, AddressType::Integrated(payment_id)) } - AddressSpec::Subaddress(i1, i2) => { - if let Some(keys) = self.subaddress_keys((i1, i2)) { - (spend, view) = keys; - AddressMeta::new(network, AddressType::Subaddress) - } else { - AddressMeta::new(network, AddressType::Standard) - } + AddressSpec::Subaddress(index) => { + (spend, view) = self.subaddress_keys(index); + AddressMeta::new(network, AddressType::Subaddress) } AddressSpec::Featured(subaddress, payment_id, guaranteed) => { - let mut is_subaddress = false; - if let Some(Some(keys)) = subaddress.map(|subaddress| self.subaddress_keys(subaddress)) { - (spend, view) = keys; - is_subaddress = true; + if let Some(index) = subaddress { + (spend, view) = self.subaddress_keys(index); } - AddressMeta::new(network, AddressType::Featured(is_subaddress, payment_id, guaranteed)) + AddressMeta::new( + network, + AddressType::Featured(subaddress.is_some(), payment_id, guaranteed), + ) } }; @@ -173,7 +162,8 @@ impl ViewPair { #[derive(Clone)] pub struct Scanner { pair: ViewPair, - pub(crate) subaddresses: HashMap, + // Also contains the spend key as None + pub(crate) subaddresses: HashMap>, pub(crate) burning_bug: Option>, } @@ -212,7 +202,7 @@ impl Scanner { // TODO: Should this take in a DB access handle to ensure output keys are saved? pub fn from_view(pair: ViewPair, burning_bug: Option>) -> Scanner { let mut subaddresses = HashMap::new(); - subaddresses.insert(pair.spend.compress(), (0, 0)); + subaddresses.insert(pair.spend.compress(), None); Scanner { pair, subaddresses, burning_bug } } @@ -221,9 +211,8 @@ impl Scanner { // incompatible with the Scanner. While we could return None for that, then we have the issue // of runtime failures to generate an address. // Removing that API was the simplest option. - pub fn register_subaddress(&mut self, subaddress: (u32, u32)) { - if let Some((spend, _)) = self.pair.subaddress_keys(subaddress) { - self.subaddresses.insert(spend.compress(), subaddress); - } + pub fn register_subaddress(&mut self, subaddress: SubaddressIndex) { + let (spend, _) = self.pair.subaddress_keys(subaddress); + self.subaddresses.insert(spend.compress(), Some(subaddress)); } } diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index 29dfdd07..5b80dbaf 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -1,3 +1,5 @@ +use std::io; + use zeroize::{Zeroize, ZeroizeOnDrop}; use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint}; @@ -8,7 +10,10 @@ use crate::{ transaction::{Input, Timelock, Transaction}, block::Block, rpc::{Rpc, RpcError}, - wallet::{PaymentId, Extra, Scanner, uniqueness, shared_key, amount_decryption, commitment_mask}, + wallet::{ + PaymentId, Extra, address::SubaddressIndex, Scanner, uniqueness, shared_key, amount_decryption, + commitment_mask, + }, }; /// An absolute output ID, defined as its transaction hash and output index. @@ -26,7 +31,7 @@ impl AbsoluteId { res } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn read(r: &mut R) -> io::Result { Ok(AbsoluteId { tx: read_bytes(r)?, o: read_byte(r)? }) } } @@ -50,7 +55,7 @@ impl OutputData { res } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn read(r: &mut R) -> io::Result { Ok(OutputData { key: read_point(r)?, key_offset: read_scalar(r)?, @@ -62,9 +67,8 @@ impl OutputData { /// The metadata for an output. #[derive(Clone, PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)] pub struct Metadata { - // Does not have to be an Option since the 0 subaddress is the main address /// The subaddress this output was sent to. - pub subaddress: (u32, u32), + pub subaddress: Option, /// The payment ID included with this output. /// This will be gibberish if the payment ID wasn't intended for the recipient or wasn't included. // Could be an Option, as extra doesn't necessarily have a payment ID, yet all Monero TXs should @@ -77,8 +81,13 @@ pub struct Metadata { impl Metadata { pub fn serialize(&self) -> Vec { let mut res = Vec::with_capacity(4 + 4 + 8 + 1); - res.extend(self.subaddress.0.to_le_bytes()); - res.extend(self.subaddress.1.to_le_bytes()); + if let Some(subaddress) = self.subaddress { + res.push(1); + res.extend(subaddress.account().to_le_bytes()); + res.extend(subaddress.address().to_le_bytes()); + } else { + res.push(0); + } res.extend(self.payment_id); res.extend(u32::try_from(self.arbitrary_data.len()).unwrap().to_le_bytes()); @@ -89,9 +98,18 @@ impl Metadata { res } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn read(r: &mut R) -> io::Result { + let subaddress = if read_byte(r)? == 1 { + Some( + SubaddressIndex::new(read_u32(r)?, read_u32(r)?) + .ok_or(io::Error::new(io::ErrorKind::Other, "invalid subaddress in metadata"))?, + ) + } else { + None + }; + Ok(Metadata { - subaddress: (read_u32(r)?, read_u32(r)?), + subaddress, payment_id: read_bytes(r)?, arbitrary_data: { let mut data = vec![]; @@ -137,11 +155,11 @@ impl ReceivedOutput { serialized } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn deserialize(r: &mut R) -> io::Result { Ok(ReceivedOutput { - absolute: AbsoluteId::deserialize(r)?, - data: OutputData::deserialize(r)?, - metadata: Metadata::deserialize(r)?, + absolute: AbsoluteId::read(r)?, + data: OutputData::read(r)?, + metadata: Metadata::read(r)?, }) } } @@ -188,7 +206,7 @@ impl SpendableOutput { serialized } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn read(r: &mut R) -> io::Result { Ok(SpendableOutput { output: ReceivedOutput::deserialize(r)?, global_index: read_u64(r)? }) } } @@ -291,7 +309,10 @@ impl Scanner { // If we did though, it'd enable bypassing the included burning bug protection debug_assert!(output_key.is_torsion_free()); - let key_offset = shared_key + self.pair.subaddress_derivation(subaddress); + let mut key_offset = shared_key; + if let Some(subaddress) = subaddress { + key_offset += self.pair.subaddress_derivation(subaddress); + } // Since we've found an output to us, get its amount let mut commitment = Commitment::zero(); diff --git a/coins/monero/tests/scan.rs b/coins/monero/tests/scan.rs index ccc2f906..af42ea96 100644 --- a/coins/monero/tests/scan.rs +++ b/coins/monero/tests/scan.rs @@ -1,6 +1,6 @@ use rand::RngCore; -use monero_serai::transaction::Transaction; +use monero_serai::{transaction::Transaction, wallet::address::SubaddressIndex}; mod runner; @@ -24,22 +24,19 @@ test!( scan_subaddress, ( |_, mut builder: Builder, _| async move { - let subaddress = (0, 1); + let subaddress = SubaddressIndex::new(0, 1).unwrap(); let view = runner::random_address().1; let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); scanner.register_subaddress(subaddress); - builder.add_payment( - view.address(Network::Mainnet, AddressSpec::Subaddress(subaddress.0, subaddress.1)), - 5, - ); + builder.add_payment(view.address(Network::Mainnet, AddressSpec::Subaddress(subaddress)), 5); (builder.build().unwrap(), (scanner, subaddress)) }, - |_, tx: Transaction, _, mut state: (Scanner, (u32, u32))| async move { + |_, tx: Transaction, _, mut state: (Scanner, SubaddressIndex)| async move { let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); assert_eq!(output.commitment().amount, 5); - assert_eq!(output.metadata.subaddress, state.1); + assert_eq!(output.metadata.subaddress, Some(state.1)); }, ), ); @@ -86,7 +83,7 @@ test!( scan_featured_subaddress, ( |_, mut builder: Builder, _| async move { - let subaddress = (0, 2); + let subaddress = SubaddressIndex::new(0, 2).unwrap(); let view = runner::random_address().1; let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); @@ -98,10 +95,10 @@ test!( ); (builder.build().unwrap(), (scanner, subaddress)) }, - |_, tx: Transaction, _, mut state: (Scanner, (u32, u32))| async move { + |_, tx: Transaction, _, mut state: (Scanner, SubaddressIndex)| async move { let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); assert_eq!(output.commitment().amount, 5); - assert_eq!(output.metadata.subaddress, state.1); + assert_eq!(output.metadata.subaddress, Some(state.1)); }, ), ); @@ -133,7 +130,7 @@ test!( scan_featured_integrated_subaddress, ( |_, mut builder: Builder, _| async move { - let subaddress = (0, 3); + let subaddress = SubaddressIndex::new(0, 3).unwrap(); let view = runner::random_address().1; let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); @@ -151,11 +148,11 @@ test!( ); (builder.build().unwrap(), (scanner, payment_id, subaddress)) }, - |_, tx: Transaction, _, mut state: (Scanner, [u8; 8], (u32, u32))| async move { + |_, tx: Transaction, _, mut state: (Scanner, [u8; 8], SubaddressIndex)| async move { let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); assert_eq!(output.commitment().amount, 5); assert_eq!(output.metadata.payment_id, state.1); - assert_eq!(output.metadata.subaddress, state.2); + assert_eq!(output.metadata.subaddress, Some(state.2)); }, ), ); @@ -182,7 +179,7 @@ test!( scan_guaranteed_subaddress, ( |_, mut builder: Builder, _| async move { - let subaddress = (1, 0); + let subaddress = SubaddressIndex::new(1, 0).unwrap(); let view = runner::random_address().1; let mut scanner = Scanner::from_view(view.clone(), None); @@ -194,10 +191,10 @@ test!( ); (builder.build().unwrap(), (scanner, subaddress)) }, - |_, tx: Transaction, _, mut state: (Scanner, (u32, u32))| async move { + |_, tx: Transaction, _, mut state: (Scanner, SubaddressIndex)| async move { let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); assert_eq!(output.commitment().amount, 5); - assert_eq!(output.metadata.subaddress, state.1); + assert_eq!(output.metadata.subaddress, Some(state.1)); }, ), ); @@ -229,7 +226,7 @@ test!( scan_guaranteed_integrated_subaddress, ( |_, mut builder: Builder, _| async move { - let subaddress = (1, 1); + let subaddress = SubaddressIndex::new(1, 1).unwrap(); let view = runner::random_address().1; let mut scanner = Scanner::from_view(view.clone(), None); @@ -247,11 +244,11 @@ test!( ); (builder.build().unwrap(), (scanner, payment_id, subaddress)) }, - |_, tx: Transaction, _, mut state: (Scanner, [u8; 8], (u32, u32))| async move { + |_, tx: Transaction, _, mut state: (Scanner, [u8; 8], SubaddressIndex)| async move { let output = state.0.scan_transaction(&tx).not_locked().swap_remove(0); assert_eq!(output.commitment().amount, 5); assert_eq!(output.metadata.payment_id, state.1); - assert_eq!(output.metadata.subaddress, state.2); + assert_eq!(output.metadata.subaddress, Some(state.2)); }, ), ); diff --git a/processor/src/coin/mod.rs b/processor/src/coin/mod.rs index 313dd2b3..b5fb9065 100644 --- a/processor/src/coin/mod.rs +++ b/processor/src/coin/mod.rs @@ -40,7 +40,7 @@ pub trait Output: Sized + Clone { fn amount(&self) -> u64; fn serialize(&self) -> Vec; - fn deserialize(reader: &mut R) -> std::io::Result; + fn read(reader: &mut R) -> std::io::Result; } #[async_trait] diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index 94f270c2..58afe3d8 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -14,7 +14,7 @@ use monero_serai::{ rpc::Rpc, wallet::{ ViewPair, Scanner, - address::{Network, AddressSpec, MoneroAddress}, + address::{Network, SubaddressIndex, AddressSpec, MoneroAddress}, Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine, }, }; @@ -41,9 +41,9 @@ impl From for Output { } } -const EXTERNAL_SUBADDRESS: (u32, u32) = (0, 0); -const BRANCH_SUBADDRESS: (u32, u32) = (1, 0); -const CHANGE_SUBADDRESS: (u32, u32) = (2, 0); +const EXTERNAL_SUBADDRESS: Option = SubaddressIndex::new(0, 0); +const BRANCH_SUBADDRESS: Option = SubaddressIndex::new(1, 0); +const CHANGE_SUBADDRESS: Option = SubaddressIndex::new(2, 0); impl OutputTrait for Output { // While we could use (tx, o), using the key ensures we won't be susceptible to the burning bug. @@ -72,8 +72,8 @@ impl OutputTrait for Output { self.0.serialize() } - fn deserialize(reader: &mut R) -> std::io::Result { - SpendableOutput::deserialize(reader).map(Output) + fn read(reader: &mut R) -> std::io::Result { + SpendableOutput::read(reader).map(Output) } } @@ -101,17 +101,19 @@ impl Monero { ViewPair::new(spend.0, self.view.clone()) } - fn address_internal(&self, spend: dfg::EdwardsPoint, subaddress: (u32, u32)) -> MoneroAddress { - self - .view_pair(spend) - .address(Network::Mainnet, AddressSpec::Featured(Some(subaddress), None, true)) + fn address_internal( + &self, + spend: dfg::EdwardsPoint, + subaddress: Option, + ) -> MoneroAddress { + self.view_pair(spend).address(Network::Mainnet, AddressSpec::Featured(subaddress, None, true)) } fn scanner(&self, spend: dfg::EdwardsPoint) -> Scanner { let mut scanner = Scanner::from_view(self.view_pair(spend), None); - scanner.register_subaddress(EXTERNAL_SUBADDRESS); // Pointless as (0, 0) is already registered - scanner.register_subaddress(BRANCH_SUBADDRESS); - scanner.register_subaddress(CHANGE_SUBADDRESS); + debug_assert!(EXTERNAL_SUBADDRESS.is_none()); + scanner.register_subaddress(BRANCH_SUBADDRESS.unwrap()); + scanner.register_subaddress(CHANGE_SUBADDRESS.unwrap()); scanner } From 7b0b8a20ec97628a3b9f80516eca587a19695103 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 7 Jan 2023 05:18:35 -0500 Subject: [PATCH 15/74] Standardize serialization within the Monero lib read for R: Read write for W: Write serialize for -> Vec Also uses std::io::{self, Read, Write} consistently. --- coins/monero/generators/src/varint.rs | 4 +- coins/monero/src/block.rs | 30 ++++-- coins/monero/src/ringct/bulletproofs/mod.rs | 28 ++++-- coins/monero/src/ringct/clsag/mod.rs | 5 +- coins/monero/src/ringct/clsag/multisig.rs | 11 +- coins/monero/src/ringct/mod.rs | 63 ++++++------ coins/monero/src/rpc.rs | 7 +- coins/monero/src/serialize.rs | 34 +++---- coins/monero/src/transaction.rs | 106 +++++++++----------- coins/monero/src/wallet/extra.rs | 18 ++-- coins/monero/src/wallet/scan.rs | 95 +++++++++++------- coins/monero/src/wallet/send/mod.rs | 4 +- 12 files changed, 219 insertions(+), 186 deletions(-) diff --git a/coins/monero/generators/src/varint.rs b/coins/monero/generators/src/varint.rs index e0aa6a3b..632f658d 100644 --- a/coins/monero/generators/src/varint.rs +++ b/coins/monero/generators/src/varint.rs @@ -1,7 +1,7 @@ -use std::io; +use std::io::{self, Write}; const VARINT_CONTINUATION_MASK: u8 = 0b1000_0000; -pub(crate) fn write_varint(varint: &u64, w: &mut W) -> io::Result<()> { +pub(crate) fn write_varint(varint: &u64, w: &mut W) -> io::Result<()> { let mut varint = *varint; while { let mut b = u8::try_from(varint & u64::from(!VARINT_CONTINUATION_MASK)).unwrap(); diff --git a/coins/monero/src/block.rs b/coins/monero/src/block.rs index ea4f3b98..72178d17 100644 --- a/coins/monero/src/block.rs +++ b/coins/monero/src/block.rs @@ -1,3 +1,5 @@ +use std::io::{self, Read, Write}; + use crate::{serialize::*, transaction::Transaction}; #[derive(Clone, PartialEq, Eq, Debug)] @@ -10,7 +12,7 @@ pub struct BlockHeader { } impl BlockHeader { - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { write_varint(&self.major_version, w)?; write_varint(&self.minor_version, w)?; write_varint(&self.timestamp, w)?; @@ -18,7 +20,13 @@ impl BlockHeader { w.write_all(&self.nonce.to_le_bytes()) } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn serialize(&self) -> Vec { + let mut serialized = vec![]; + self.write(&mut serialized).unwrap(); + serialized + } + + pub fn read(r: &mut R) -> io::Result { Ok(BlockHeader { major_version: read_varint(r)?, minor_version: read_varint(r)?, @@ -37,9 +45,9 @@ pub struct Block { } impl Block { - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { - self.header.serialize(w)?; - self.miner_tx.serialize(w)?; + pub fn write(&self, w: &mut W) -> io::Result<()> { + self.header.write(w)?; + self.miner_tx.write(w)?; write_varint(&self.txs.len().try_into().unwrap(), w)?; for tx in &self.txs { w.write_all(tx)?; @@ -47,10 +55,16 @@ impl Block { Ok(()) } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn serialize(&self) -> Vec { + let mut serialized = vec![]; + self.write(&mut serialized).unwrap(); + serialized + } + + pub fn read(r: &mut R) -> io::Result { Ok(Block { - header: BlockHeader::deserialize(r)?, - miner_tx: Transaction::deserialize(r)?, + header: BlockHeader::read(r)?, + miner_tx: Transaction::read(r)?, txs: (0 .. read_varint(r)?).map(|_| read_bytes(r)).collect::>()?, }) } diff --git a/coins/monero/src/ringct/bulletproofs/mod.rs b/coins/monero/src/ringct/bulletproofs/mod.rs index 227890d3..866f9018 100644 --- a/coins/monero/src/ringct/bulletproofs/mod.rs +++ b/coins/monero/src/ringct/bulletproofs/mod.rs @@ -1,5 +1,7 @@ #![allow(non_snake_case)] +use std::io::{self, Read, Write}; + use rand_core::{RngCore, CryptoRng}; use zeroize::Zeroize; @@ -93,11 +95,11 @@ impl Bulletproofs { } } - fn serialize_core std::io::Result<()>>( + fn write_core io::Result<()>>( &self, w: &mut W, specific_write_vec: F, - ) -> std::io::Result<()> { + ) -> io::Result<()> { match self { Bulletproofs::Original(bp) => { write_point(&bp.A, w)?; @@ -126,16 +128,22 @@ impl Bulletproofs { } } - pub(crate) fn signature_serialize(&self, w: &mut W) -> std::io::Result<()> { - self.serialize_core(w, |points, w| write_raw_vec(write_point, points, w)) + pub(crate) fn signature_write(&self, w: &mut W) -> io::Result<()> { + self.write_core(w, |points, w| write_raw_vec(write_point, points, w)) } - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { - self.serialize_core(w, |points, w| write_vec(write_point, points, w)) + pub fn write(&self, w: &mut W) -> io::Result<()> { + self.write_core(w, |points, w| write_vec(write_point, points, w)) } - /// Deserialize non-plus Bulletproofs. - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn serialize(&self) -> Vec { + let mut serialized = vec![]; + self.write(&mut serialized).unwrap(); + serialized + } + + /// Read Bulletproofs. + pub fn read(r: &mut R) -> io::Result { Ok(Bulletproofs::Original(OriginalStruct { A: read_point(r)?, S: read_point(r)?, @@ -151,8 +159,8 @@ impl Bulletproofs { })) } - /// Deserialize Bulletproofs+. - pub fn deserialize_plus(r: &mut R) -> std::io::Result { + /// Read Bulletproofs+. + pub fn read_plus(r: &mut R) -> io::Result { Ok(Bulletproofs::Plus(PlusStruct { A: read_point(r)?, A1: read_point(r)?, diff --git a/coins/monero/src/ringct/clsag/mod.rs b/coins/monero/src/ringct/clsag/mod.rs index 2d9ba830..249661f9 100644 --- a/coins/monero/src/ringct/clsag/mod.rs +++ b/coins/monero/src/ringct/clsag/mod.rs @@ -1,6 +1,7 @@ #![allow(non_snake_case)] use core::ops::Deref; +use std::io::{self, Read, Write}; use lazy_static::lazy_static; use thiserror::Error; @@ -313,13 +314,13 @@ impl Clsag { (ring_len * 32) + 32 + 32 } - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { write_raw_vec(write_scalar, &self.s, w)?; w.write_all(&self.c1.to_bytes())?; write_point(&self.D, w) } - pub fn deserialize(decoys: usize, r: &mut R) -> std::io::Result { + pub fn read(decoys: usize, r: &mut R) -> io::Result { Ok(Clsag { s: read_raw_vec(read_scalar, decoys, r)?, c1: read_scalar(r)?, D: read_point(r)? }) } } diff --git a/coins/monero/src/ringct/clsag/multisig.rs b/coins/monero/src/ringct/clsag/multisig.rs index cec1cbd6..0b3472e0 100644 --- a/coins/monero/src/ringct/clsag/multisig.rs +++ b/coins/monero/src/ringct/clsag/multisig.rs @@ -41,18 +41,17 @@ impl ClsagInput { // Doesn't domain separate as this is considered part of the larger CLSAG proof // Ring index - transcript.append_message(b"ring_index", [self.decoys.i]); + transcript.append_message(b"real_spend", [self.decoys.i]); // Ring - let mut ring = vec![]; - for pair in &self.decoys.ring { + for (i, pair) in self.decoys.ring.iter().enumerate() { // Doesn't include global output indexes as CLSAG doesn't care and won't be affected by it // They're just a unreliable reference to this data which will be included in the message // if in use - ring.extend(pair[0].compress().to_bytes()); - ring.extend(pair[1].compress().to_bytes()); + transcript.append_message(b"member", [u8::try_from(i).expect("ring size exceeded 255")]); + transcript.append_message(b"key", pair[0].compress().to_bytes()); + transcript.append_message(b"commitment", pair[1].compress().to_bytes()) } - transcript.append_message(b"ring", ring); // Doesn't include the commitment's parts as the above ring + index includes the commitment // The only potential malleability would be if the G/H relationship is known breaking the diff --git a/coins/monero/src/ringct/mod.rs b/coins/monero/src/ringct/mod.rs index b81e8651..d289b6f1 100644 --- a/coins/monero/src/ringct/mod.rs +++ b/coins/monero/src/ringct/mod.rs @@ -1,4 +1,5 @@ use core::ops::Deref; +use std::io::{self, Read, Write}; use zeroize::Zeroizing; @@ -35,7 +36,7 @@ impl RctBase { 1 + 8 + (outputs * (8 + 32)) } - pub fn serialize(&self, w: &mut W, rct_type: u8) -> std::io::Result<()> { + pub fn write(&self, w: &mut W, rct_type: u8) -> io::Result<()> { w.write_all(&[rct_type])?; match rct_type { 0 => Ok(()), @@ -50,10 +51,7 @@ impl RctBase { } } - pub fn deserialize( - outputs: usize, - r: &mut R, - ) -> std::io::Result<(RctBase, u8)> { + pub fn read(outputs: usize, r: &mut R) -> io::Result<(RctBase, u8)> { let rct_type = read_byte(r)?; Ok(( if rct_type == 0 { @@ -96,46 +94,43 @@ impl RctPrunable { (inputs * (Clsag::fee_weight(protocol.ring_len()) + 32)) } - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { match self { RctPrunable::Null => Ok(()), RctPrunable::Clsag { bulletproofs, clsags, pseudo_outs, .. } => { - write_vec(Bulletproofs::serialize, bulletproofs, w)?; - write_raw_vec(Clsag::serialize, clsags, w)?; + write_vec(Bulletproofs::write, bulletproofs, w)?; + write_raw_vec(Clsag::write, clsags, w)?; write_raw_vec(write_point, pseudo_outs, w) } } } - pub fn deserialize( - rct_type: u8, - decoys: &[usize], - r: &mut R, - ) -> std::io::Result { + pub fn serialize(&self) -> Vec { + let mut serialized = vec![]; + self.write(&mut serialized).unwrap(); + serialized + } + + pub fn read(rct_type: u8, decoys: &[usize], r: &mut R) -> io::Result { Ok(match rct_type { 0 => RctPrunable::Null, 5 | 6 => RctPrunable::Clsag { bulletproofs: read_vec( - if rct_type == 5 { Bulletproofs::deserialize } else { Bulletproofs::deserialize_plus }, + if rct_type == 5 { Bulletproofs::read } else { Bulletproofs::read_plus }, r, )?, - clsags: (0 .. decoys.len()) - .map(|o| Clsag::deserialize(decoys[o], r)) - .collect::>()?, + clsags: (0 .. decoys.len()).map(|o| Clsag::read(decoys[o], r)).collect::>()?, pseudo_outs: read_raw_vec(read_point, decoys.len(), r)?, }, - _ => Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Tried to deserialize unknown RCT type", - ))?, + _ => Err(io::Error::new(io::ErrorKind::Other, "Tried to deserialize unknown RCT type"))?, }) } - pub(crate) fn signature_serialize(&self, w: &mut W) -> std::io::Result<()> { + pub(crate) fn signature_write(&self, w: &mut W) -> io::Result<()> { match self { RctPrunable::Null => panic!("Serializing RctPrunable::Null for a signature"), RctPrunable::Clsag { bulletproofs, .. } => { - bulletproofs.iter().try_for_each(|bp| bp.signature_serialize(w)) + bulletproofs.iter().try_for_each(|bp| bp.signature_write(w)) } } } @@ -152,17 +147,19 @@ impl RctSignatures { RctBase::fee_weight(outputs) + RctPrunable::fee_weight(protocol, inputs, outputs) } - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { - self.base.serialize(w, self.prunable.rct_type())?; - self.prunable.serialize(w) + pub fn write(&self, w: &mut W) -> io::Result<()> { + self.base.write(w, self.prunable.rct_type())?; + self.prunable.write(w) } - pub fn deserialize( - decoys: Vec, - outputs: usize, - r: &mut R, - ) -> std::io::Result { - let base = RctBase::deserialize(outputs, r)?; - Ok(RctSignatures { base: base.0, prunable: RctPrunable::deserialize(base.1, &decoys, r)? }) + pub fn serialize(&self) -> Vec { + let mut serialized = vec![]; + self.write(&mut serialized).unwrap(); + serialized + } + + pub fn read(decoys: Vec, outputs: usize, r: &mut R) -> io::Result { + let base = RctBase::read(outputs, r)?; + Ok(RctSignatures { base: base.0, prunable: RctPrunable::read(base.1, &decoys, r)? }) } } diff --git a/coins/monero/src/rpc.rs b/coins/monero/src/rpc.rs index ae4b6a80..06395b31 100644 --- a/coins/monero/src/rpc.rs +++ b/coins/monero/src/rpc.rs @@ -249,7 +249,7 @@ impl Rpc { .txs .iter() .map(|res| { - let tx = Transaction::deserialize::<&[u8]>( + let tx = Transaction::read::<&[u8]>( &mut rpc_hex(if !res.as_hex.is_empty() { &res.as_hex } else { &res.pruned_as_hex })? .as_ref(), ) @@ -312,8 +312,7 @@ impl Rpc { let res: BlockResponse = self.json_rpc_call("get_block", Some(json!({ "hash": hex::encode(hash) }))).await?; - Block::deserialize::<&[u8]>(&mut rpc_hex(&res.blob)?.as_ref()) - .map_err(|_| RpcError::InvalidNode) + Block::read::<&[u8]>(&mut rpc_hex(&res.blob)?.as_ref()).map_err(|_| RpcError::InvalidNode) } pub async fn get_block_by_number(&self, number: usize) -> Result { @@ -487,7 +486,7 @@ impl Rpc { } let mut buf = Vec::with_capacity(2048); - tx.serialize(&mut buf).unwrap(); + tx.write(&mut buf).unwrap(); let res: SendRawResponse = self .rpc_call("send_raw_transaction", Some(json!({ "tx_as_hex": hex::encode(&buf) }))) .await?; diff --git a/coins/monero/src/serialize.rs b/coins/monero/src/serialize.rs index 0767d7f2..bc548737 100644 --- a/coins/monero/src/serialize.rs +++ b/coins/monero/src/serialize.rs @@ -1,4 +1,4 @@ -use std::io; +use std::io::{self, Read, Write}; use curve25519_dalek::{ scalar::Scalar, @@ -11,11 +11,11 @@ pub(crate) fn varint_len(varint: usize) -> usize { ((usize::try_from(usize::BITS - varint.leading_zeros()).unwrap().saturating_sub(1)) / 7) + 1 } -pub(crate) fn write_byte(byte: &u8, w: &mut W) -> io::Result<()> { +pub(crate) fn write_byte(byte: &u8, w: &mut W) -> io::Result<()> { w.write_all(&[*byte]) } -pub(crate) fn write_varint(varint: &u64, w: &mut W) -> io::Result<()> { +pub(crate) fn write_varint(varint: &u64, w: &mut W) -> io::Result<()> { let mut varint = *varint; while { let mut b = u8::try_from(varint & u64::from(!VARINT_CONTINUATION_MASK)).unwrap(); @@ -29,15 +29,15 @@ pub(crate) fn write_varint(varint: &u64, w: &mut W) -> io::Result< Ok(()) } -pub(crate) fn write_scalar(scalar: &Scalar, w: &mut W) -> io::Result<()> { +pub(crate) fn write_scalar(scalar: &Scalar, w: &mut W) -> io::Result<()> { w.write_all(&scalar.to_bytes()) } -pub(crate) fn write_point(point: &EdwardsPoint, w: &mut W) -> io::Result<()> { +pub(crate) fn write_point(point: &EdwardsPoint, w: &mut W) -> io::Result<()> { w.write_all(&point.compress().to_bytes()) } -pub(crate) fn write_raw_vec io::Result<()>>( +pub(crate) fn write_raw_vec io::Result<()>>( f: F, values: &[T], w: &mut W, @@ -48,7 +48,7 @@ pub(crate) fn write_raw_vec io::Result<()> Ok(()) } -pub(crate) fn write_vec io::Result<()>>( +pub(crate) fn write_vec io::Result<()>>( f: F, values: &[T], w: &mut W, @@ -57,25 +57,25 @@ pub(crate) fn write_vec io::Result<()>>( write_raw_vec(f, values, w) } -pub(crate) fn read_bytes(r: &mut R) -> io::Result<[u8; N]> { +pub(crate) fn read_bytes(r: &mut R) -> io::Result<[u8; N]> { let mut res = [0; N]; r.read_exact(&mut res)?; Ok(res) } -pub(crate) fn read_byte(r: &mut R) -> io::Result { +pub(crate) fn read_byte(r: &mut R) -> io::Result { Ok(read_bytes::<_, 1>(r)?[0]) } -pub(crate) fn read_u64(r: &mut R) -> io::Result { +pub(crate) fn read_u64(r: &mut R) -> io::Result { read_bytes(r).map(u64::from_le_bytes) } -pub(crate) fn read_u32(r: &mut R) -> io::Result { +pub(crate) fn read_u32(r: &mut R) -> io::Result { read_bytes(r).map(u32::from_le_bytes) } -pub(crate) fn read_varint(r: &mut R) -> io::Result { +pub(crate) fn read_varint(r: &mut R) -> io::Result { let mut bits = 0; let mut res = 0; while { @@ -100,12 +100,12 @@ pub(crate) fn read_varint(r: &mut R) -> io::Result { // for now. There's also further edge cases as noted by // https://github.com/monero-project/monero/issues/8438, where some scalars had an archaic // reduction applied -pub(crate) fn read_scalar(r: &mut R) -> io::Result { +pub(crate) fn read_scalar(r: &mut R) -> io::Result { Scalar::from_canonical_bytes(read_bytes(r)?) .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "unreduced scalar")) } -pub(crate) fn read_point(r: &mut R) -> io::Result { +pub(crate) fn read_point(r: &mut R) -> io::Result { let bytes = read_bytes(r)?; CompressedEdwardsY(bytes) .decompress() @@ -114,14 +114,14 @@ pub(crate) fn read_point(r: &mut R) -> io::Result { .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point")) } -pub(crate) fn read_torsion_free_point(r: &mut R) -> io::Result { +pub(crate) fn read_torsion_free_point(r: &mut R) -> io::Result { read_point(r) .ok() .filter(|point| point.is_torsion_free()) .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point")) } -pub(crate) fn read_raw_vec io::Result>( +pub(crate) fn read_raw_vec io::Result>( f: F, len: usize, r: &mut R, @@ -133,7 +133,7 @@ pub(crate) fn read_raw_vec io::Result>( Ok(res) } -pub(crate) fn read_vec io::Result>( +pub(crate) fn read_vec io::Result>( f: F, r: &mut R, ) -> io::Result> { diff --git a/coins/monero/src/transaction.rs b/coins/monero/src/transaction.rs index 6314a97c..e981792a 100644 --- a/coins/monero/src/transaction.rs +++ b/coins/monero/src/transaction.rs @@ -1,4 +1,5 @@ use core::cmp::Ordering; +use std::io::{self, Read, Write}; use zeroize::Zeroize; @@ -27,7 +28,7 @@ impl Input { 1 + 1 + 1 + (8 * ring_len) + 32 } - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { match self { Input::Gen(height) => { w.write_all(&[255])?; @@ -43,7 +44,7 @@ impl Input { } } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn read(r: &mut R) -> io::Result { Ok(match read_byte(r)? { 255 => Input::Gen(read_varint(r)?), 2 => Input::ToKey { @@ -51,10 +52,9 @@ impl Input { key_offsets: read_vec(read_varint, r)?, key_image: read_torsion_free_point(r)?, }, - _ => Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Tried to deserialize unknown/unused input type", - ))?, + _ => { + Err(io::Error::new(io::ErrorKind::Other, "Tried to deserialize unknown/unused input type"))? + } }) } } @@ -72,7 +72,7 @@ impl Output { 1 + 1 + 32 + 1 } - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { write_varint(&self.amount, w)?; w.write_all(&[2 + u8::from(self.view_tag.is_some())])?; w.write_all(&self.key.to_bytes())?; @@ -82,13 +82,13 @@ impl Output { Ok(()) } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn read(r: &mut R) -> io::Result { let amount = read_varint(r)?; let view_tag = match read_byte(r)? { 2 => false, 3 => true, - _ => Err(std::io::Error::new( - std::io::ErrorKind::Other, + _ => Err(io::Error::new( + io::ErrorKind::Other, "Tried to deserialize unknown/unused output type", ))?, }; @@ -119,7 +119,7 @@ impl Timelock { } } - fn serialize(&self, w: &mut W) -> std::io::Result<()> { + fn write(&self, w: &mut W) -> io::Result<()> { write_varint( &match self { Timelock::None => 0, @@ -163,21 +163,21 @@ impl TransactionPrefix { extra } - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { write_varint(&self.version, w)?; - self.timelock.serialize(w)?; - write_vec(Input::serialize, &self.inputs, w)?; - write_vec(Output::serialize, &self.outputs, w)?; + self.timelock.write(w)?; + write_vec(Input::write, &self.inputs, w)?; + write_vec(Output::write, &self.outputs, w)?; write_varint(&self.extra.len().try_into().unwrap(), w)?; w.write_all(&self.extra) } - pub fn deserialize(r: &mut R) -> std::io::Result { + pub fn read(r: &mut R) -> io::Result { let mut prefix = TransactionPrefix { version: read_varint(r)?, timelock: Timelock::from_raw(read_varint(r)?), - inputs: read_vec(Input::deserialize, r)?, - outputs: read_vec(Output::deserialize, r)?, + inputs: read_vec(Input::read, r)?, + outputs: read_vec(Output::read, r)?, extra: vec![], }; prefix.extra = read_vec(read_byte, r)?; @@ -204,8 +204,8 @@ impl Transaction { RctSignatures::fee_weight(protocol, inputs, outputs) } - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { - self.prefix.serialize(w)?; + pub fn write(&self, w: &mut W) -> io::Result<()> { + self.prefix.write(w)?; if self.prefix.version == 1 { for sig in &self.signatures { write_scalar(&sig.0, w)?; @@ -213,14 +213,14 @@ impl Transaction { } Ok(()) } else if self.prefix.version == 2 { - self.rct_signatures.serialize(w) + self.rct_signatures.write(w) } else { panic!("Serializing a transaction with an unknown version"); } } - pub fn deserialize(r: &mut R) -> std::io::Result { - let prefix = TransactionPrefix::deserialize(r)?; + pub fn read(r: &mut R) -> io::Result { + let prefix = TransactionPrefix::read(r)?; let mut signatures = vec![]; let mut rct_signatures = RctSignatures { base: RctBase { fee: 0, ecdh_info: vec![], commitments: vec![] }, @@ -241,7 +241,7 @@ impl Transaction { .sum::() .saturating_sub(prefix.outputs.iter().map(|output| output.amount).sum()); } else if prefix.version == 2 { - rct_signatures = RctSignatures::deserialize( + rct_signatures = RctSignatures::read( prefix .inputs .iter() @@ -254,64 +254,56 @@ impl Transaction { r, )?; } else { - Err(std::io::Error::new(std::io::ErrorKind::Other, "Tried to deserialize unknown version"))?; + Err(io::Error::new(io::ErrorKind::Other, "Tried to deserialize unknown version"))?; } Ok(Transaction { prefix, signatures, rct_signatures }) } pub fn hash(&self) -> [u8; 32] { - let mut serialized = Vec::with_capacity(2048); + let mut buf = Vec::with_capacity(2048); if self.prefix.version == 1 { - self.serialize(&mut serialized).unwrap(); - hash(&serialized) + self.write(&mut buf).unwrap(); + hash(&buf) } else { - let mut sig_hash = Vec::with_capacity(96); + let mut hashes = Vec::with_capacity(96); - self.prefix.serialize(&mut serialized).unwrap(); - sig_hash.extend(hash(&serialized)); - serialized.clear(); + self.prefix.write(&mut buf).unwrap(); + hashes.extend(hash(&buf)); + buf.clear(); - self - .rct_signatures - .base - .serialize(&mut serialized, self.rct_signatures.prunable.rct_type()) - .unwrap(); - sig_hash.extend(hash(&serialized)); - serialized.clear(); + self.rct_signatures.base.write(&mut buf, self.rct_signatures.prunable.rct_type()).unwrap(); + hashes.extend(hash(&buf)); + buf.clear(); match self.rct_signatures.prunable { - RctPrunable::Null => serialized.resize(32, 0), + RctPrunable::Null => buf.resize(32, 0), _ => { - self.rct_signatures.prunable.serialize(&mut serialized).unwrap(); - serialized = hash(&serialized).to_vec(); + self.rct_signatures.prunable.write(&mut buf).unwrap(); + buf = hash(&buf).to_vec(); } } - sig_hash.extend(&serialized); + hashes.extend(&buf); - hash(&sig_hash) + hash(&hashes) } } /// Calculate the hash of this transaction as needed for signing it. pub fn signature_hash(&self) -> [u8; 32] { - let mut serialized = Vec::with_capacity(2048); + let mut buf = Vec::with_capacity(2048); let mut sig_hash = Vec::with_capacity(96); - self.prefix.serialize(&mut serialized).unwrap(); - sig_hash.extend(hash(&serialized)); - serialized.clear(); + self.prefix.write(&mut buf).unwrap(); + sig_hash.extend(hash(&buf)); + buf.clear(); - self - .rct_signatures - .base - .serialize(&mut serialized, self.rct_signatures.prunable.rct_type()) - .unwrap(); - sig_hash.extend(hash(&serialized)); - serialized.clear(); + self.rct_signatures.base.write(&mut buf, self.rct_signatures.prunable.rct_type()).unwrap(); + sig_hash.extend(hash(&buf)); + buf.clear(); - self.rct_signatures.prunable.signature_serialize(&mut serialized).unwrap(); - sig_hash.extend(hash(&serialized)); + self.rct_signatures.prunable.signature_write(&mut buf).unwrap(); + sig_hash.extend(hash(&buf)); hash(&sig_hash) } diff --git a/coins/monero/src/wallet/extra.rs b/coins/monero/src/wallet/extra.rs index dda72f53..2a0b9aa2 100644 --- a/coins/monero/src/wallet/extra.rs +++ b/coins/monero/src/wallet/extra.rs @@ -32,7 +32,7 @@ impl BitXor<[u8; 8]> for PaymentId { } impl PaymentId { - pub(crate) fn serialize(&self, w: &mut W) -> io::Result<()> { + pub(crate) fn write(&self, w: &mut W) -> io::Result<()> { match self { PaymentId::Unencrypted(id) => { w.write_all(&[0])?; @@ -46,7 +46,7 @@ impl PaymentId { Ok(()) } - fn deserialize(r: &mut R) -> io::Result { + fn read(r: &mut R) -> io::Result { Ok(match read_byte(r)? { 0 => PaymentId::Unencrypted(read_bytes(r)?), 1 => PaymentId::Encrypted(read_bytes(r)?), @@ -65,7 +65,7 @@ pub(crate) enum ExtraField { } impl ExtraField { - fn serialize(&self, w: &mut W) -> io::Result<()> { + fn write(&self, w: &mut W) -> io::Result<()> { match self { ExtraField::PublicKey(key) => { w.write_all(&[1])?; @@ -88,7 +88,7 @@ impl ExtraField { Ok(()) } - fn deserialize(r: &mut R) -> io::Result { + fn read(r: &mut R) -> io::Result { Ok(match read_byte(r)? { 1 => ExtraField::PublicKey(read_point(r)?), 2 => ExtraField::Nonce({ @@ -127,7 +127,7 @@ impl Extra { pub(crate) fn payment_id(&self) -> Option { for field in &self.0 { if let ExtraField::Nonce(data) = field { - return PaymentId::deserialize::<&[u8]>(&mut data.as_ref()).ok(); + return PaymentId::read::<&[u8]>(&mut data.as_ref()).ok(); } } None @@ -176,18 +176,18 @@ impl Extra { data.iter().map(|v| 1 + varint_len(v.len()) + v.len()).sum::() } - pub(crate) fn serialize(&self, w: &mut W) -> io::Result<()> { + pub(crate) fn write(&self, w: &mut W) -> io::Result<()> { for field in &self.0 { - field.serialize(w)?; + field.write(w)?; } Ok(()) } - pub(crate) fn deserialize(r: &mut R) -> io::Result { + pub(crate) fn read(r: &mut R) -> io::Result { let mut res = Extra(vec![]); let mut field; while { - field = ExtraField::deserialize(r); + field = ExtraField::read(r); field.is_ok() } { res.0.push(field.unwrap()); diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index 5b80dbaf..6ac13f7a 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -1,4 +1,4 @@ -use std::io; +use std::io::{self, Read, Write}; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -24,14 +24,18 @@ pub struct AbsoluteId { } impl AbsoluteId { - pub fn serialize(&self) -> Vec { - let mut res = Vec::with_capacity(32 + 1); - res.extend(self.tx); - res.push(self.o); - res + pub fn write(&self, w: &mut W) -> io::Result<()> { + w.write_all(&self.tx)?; + w.write_all(&[self.o]) } - pub fn read(r: &mut R) -> io::Result { + pub fn serialize(&self) -> Vec { + let mut serialized = Vec::with_capacity(32 + 1); + self.write(&mut serialized).unwrap(); + serialized + } + + pub fn read(r: &mut R) -> io::Result { Ok(AbsoluteId { tx: read_bytes(r)?, o: read_byte(r)? }) } } @@ -46,16 +50,20 @@ pub struct OutputData { } impl OutputData { - pub fn serialize(&self) -> Vec { - let mut res = Vec::with_capacity(32 + 32 + 40); - res.extend(self.key.compress().to_bytes()); - res.extend(self.key_offset.to_bytes()); - res.extend(self.commitment.mask.to_bytes()); - res.extend(self.commitment.amount.to_le_bytes()); - res + pub fn write(&self, w: &mut W) -> io::Result<()> { + w.write_all(&self.key.compress().to_bytes())?; + w.write_all(&self.key_offset.to_bytes())?; + w.write_all(&self.commitment.mask.to_bytes())?; + w.write_all(&self.commitment.amount.to_le_bytes()) } - pub fn read(r: &mut R) -> io::Result { + pub fn serialize(&self) -> Vec { + let mut serialized = Vec::with_capacity(32 + 32 + 32 + 8); + self.write(&mut serialized).unwrap(); + serialized + } + + pub fn read(r: &mut R) -> io::Result { Ok(OutputData { key: read_point(r)?, key_offset: read_scalar(r)?, @@ -79,26 +87,31 @@ pub struct Metadata { } impl Metadata { - pub fn serialize(&self) -> Vec { - let mut res = Vec::with_capacity(4 + 4 + 8 + 1); + pub fn write(&self, w: &mut W) -> io::Result<()> { if let Some(subaddress) = self.subaddress { - res.push(1); - res.extend(subaddress.account().to_le_bytes()); - res.extend(subaddress.address().to_le_bytes()); + w.write_all(&[1])?; + w.write_all(&subaddress.account().to_le_bytes())?; + w.write_all(&subaddress.address().to_le_bytes())?; } else { - res.push(0); + w.write_all(&[0])?; } - res.extend(self.payment_id); + w.write_all(&self.payment_id)?; - res.extend(u32::try_from(self.arbitrary_data.len()).unwrap().to_le_bytes()); + w.write_all(&u32::try_from(self.arbitrary_data.len()).unwrap().to_le_bytes())?; for part in &self.arbitrary_data { - res.extend([u8::try_from(part.len()).unwrap()]); - res.extend(part); + w.write_all(&[u8::try_from(part.len()).unwrap()])?; + w.write_all(part)?; } - res + Ok(()) } - pub fn read(r: &mut R) -> io::Result { + pub fn serialize(&self) -> Vec { + let mut serialized = Vec::with_capacity(1 + 8 + 1); + self.write(&mut serialized).unwrap(); + serialized + } + + pub fn read(r: &mut R) -> io::Result { let subaddress = if read_byte(r)? == 1 { Some( SubaddressIndex::new(read_u32(r)?, read_u32(r)?) @@ -148,14 +161,19 @@ impl ReceivedOutput { &self.metadata.arbitrary_data } + pub fn write(&self, w: &mut W) -> io::Result<()> { + self.absolute.write(w)?; + self.data.write(w)?; + self.metadata.write(w) + } + pub fn serialize(&self) -> Vec { - let mut serialized = self.absolute.serialize(); - serialized.extend(&self.data.serialize()); - serialized.extend(&self.metadata.serialize()); + let mut serialized = vec![]; + self.write(&mut serialized).unwrap(); serialized } - pub fn deserialize(r: &mut R) -> io::Result { + pub fn read(r: &mut R) -> io::Result { Ok(ReceivedOutput { absolute: AbsoluteId::read(r)?, data: OutputData::read(r)?, @@ -200,14 +218,19 @@ impl SpendableOutput { self.output.commitment() } + pub fn write(&self, w: &mut W) -> io::Result<()> { + self.output.write(w)?; + w.write_all(&self.global_index.to_le_bytes()) + } + pub fn serialize(&self) -> Vec { - let mut serialized = self.output.serialize(); - serialized.extend(self.global_index.to_le_bytes()); + let mut serialized = vec![]; + self.write(&mut serialized).unwrap(); serialized } - pub fn read(r: &mut R) -> io::Result { - Ok(SpendableOutput { output: ReceivedOutput::deserialize(r)?, global_index: read_u64(r)? }) + pub fn read(r: &mut R) -> io::Result { + Ok(SpendableOutput { output: ReceivedOutput::read(r)?, global_index: read_u64(r)? }) } } @@ -248,7 +271,7 @@ impl Timelocked { impl Scanner { /// Scan a transaction to discover the received outputs. pub fn scan_transaction(&mut self, tx: &Transaction) -> Timelocked { - let extra = Extra::deserialize::<&[u8]>(&mut tx.prefix.extra.as_ref()); + let extra = Extra::read::<&[u8]>(&mut tx.prefix.extra.as_ref()); let keys; let extra = if let Ok(extra) = extra { keys = extra.keys(); diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index 9732c051..9aa3e8b8 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -311,7 +311,7 @@ impl SignableTransaction { let mut extra = Extra::new(outputs.iter().map(|output| output.R).collect()); let mut id_vec = Vec::with_capacity(1 + 8); - PaymentId::Encrypted(id).serialize(&mut id_vec).unwrap(); + PaymentId::Encrypted(id).write(&mut id_vec).unwrap(); extra.push(ExtraField::Nonce(id_vec)); // Include data if present @@ -320,7 +320,7 @@ impl SignableTransaction { } let mut serialized = Vec::with_capacity(Extra::fee_weight(outputs.len(), self.data.as_ref())); - extra.serialize(&mut serialized).unwrap(); + extra.write(&mut serialized).unwrap(); serialized }; From 4be3290e408ddd138fd47e5db95a31b0419dfd20 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 7 Jan 2023 05:37:43 -0500 Subject: [PATCH 16/74] Convert the FeaturedAddress tuple to a struct Not only did we already have multiple booleans in it, yet it theoretically could expand in the future. Not only is this more explicit, it actually cleans some existing code. --- coins/monero/src/tests/address.rs | 17 +++++--- coins/monero/src/wallet/address.rs | 34 ++++++++------- coins/monero/src/wallet/mod.rs | 4 +- coins/monero/tests/scan.rs | 66 +++++++++++++++++++++++++----- processor/src/coin/monero.rs | 5 ++- 5 files changed, 93 insertions(+), 33 deletions(-) diff --git a/coins/monero/src/tests/address.rs b/coins/monero/src/tests/address.rs index 3c005735..3950d6d1 100644 --- a/coins/monero/src/tests/address.rs +++ b/coins/monero/src/tests/address.rs @@ -83,13 +83,14 @@ fn featured() { let subaddress = (features & SUBADDRESS_FEATURE_BIT) == SUBADDRESS_FEATURE_BIT; - let mut id = [0; 8]; - OsRng.fill_bytes(&mut id); - let id = Some(id).filter(|_| (features & INTEGRATED_FEATURE_BIT) == INTEGRATED_FEATURE_BIT); + let mut payment_id = [0; 8]; + OsRng.fill_bytes(&mut payment_id); + let payment_id = Some(payment_id) + .filter(|_| (features & INTEGRATED_FEATURE_BIT) == INTEGRATED_FEATURE_BIT); let guaranteed = (features & GUARANTEED_FEATURE_BIT) == GUARANTEED_FEATURE_BIT; - let kind = AddressType::Featured(subaddress, id, guaranteed); + let kind = AddressType::Featured { subaddress, payment_id, guaranteed }; let meta = AddressMeta::new(network, kind); let addr = MoneroAddress::new(meta, spend, view); @@ -100,7 +101,7 @@ fn featured() { assert_eq!(addr.view, view); assert_eq!(addr.subaddress(), subaddress); - assert_eq!(addr.payment_id(), id); + assert_eq!(addr.payment_id(), payment_id); assert_eq!(addr.guaranteed(), guaranteed); } } @@ -159,7 +160,11 @@ fn featured_vectors() { MoneroAddress::new( AddressMeta::new( network, - AddressType::Featured(vector.subaddress, vector.payment_id, vector.guaranteed) + AddressType::Featured { + subaddress: vector.subaddress, + payment_id: vector.payment_id, + guaranteed: vector.guaranteed + } ), spend, view diff --git a/coins/monero/src/wallet/address.rs b/coins/monero/src/wallet/address.rs index b0f09927..ad7777d2 100644 --- a/coins/monero/src/wallet/address.rs +++ b/coins/monero/src/wallet/address.rs @@ -24,7 +24,7 @@ pub enum AddressType { Standard, Integrated([u8; 8]), Subaddress, - Featured(bool, Option<[u8; 8]>, bool), + Featured { subaddress: bool, payment_id: Option<[u8; 8]>, guaranteed: bool }, } #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] @@ -56,26 +56,27 @@ pub enum AddressSpec { Standard, Integrated([u8; 8]), Subaddress(SubaddressIndex), - Featured(Option, Option<[u8; 8]>, bool), + Featured { subaddress: Option, payment_id: Option<[u8; 8]>, guaranteed: bool }, } impl AddressType { pub fn subaddress(&self) -> bool { - matches!(self, AddressType::Subaddress) || matches!(self, AddressType::Featured(true, ..)) + matches!(self, AddressType::Subaddress) || + matches!(self, AddressType::Featured { subaddress: true, .. }) } pub fn payment_id(&self) -> Option<[u8; 8]> { if let AddressType::Integrated(id) = self { Some(*id) - } else if let AddressType::Featured(_, id, _) = self { - *id + } else if let AddressType::Featured { payment_id, .. } = self { + *payment_id } else { None } } pub fn guaranteed(&self) -> bool { - matches!(self, AddressType::Featured(_, _, true)) + matches!(self, AddressType::Featured { guaranteed: true, .. }) } } @@ -137,7 +138,7 @@ impl AddressMeta { AddressType::Standard => bytes.0, AddressType::Integrated(_) => bytes.1, AddressType::Subaddress => bytes.2, - AddressType::Featured(..) => bytes.3, + AddressType::Featured { .. } => bytes.3, } } @@ -146,7 +147,7 @@ impl AddressMeta { AddressMeta { _bytes: PhantomData, network, kind } } - // Returns an incomplete type in the case of Integrated/Featured addresses + // Returns an incomplete instantiation in the case of Integrated/Featured addresses fn from_byte(byte: u8) -> Result { let mut meta = None; for network in [Network::Mainnet, Network::Testnet, Network::Stagenet] { @@ -155,7 +156,9 @@ impl AddressMeta { _ if byte == standard => Some(AddressType::Standard), _ if byte == integrated => Some(AddressType::Integrated([0; 8])), _ if byte == subaddress => Some(AddressType::Subaddress), - _ if byte == featured => Some(AddressType::Featured(false, None, false)), + _ if byte == featured => { + Some(AddressType::Featured { subaddress: false, payment_id: None, guaranteed: false }) + } _ => None, } { meta = Some(AddressMeta::new(network, kind)); @@ -200,7 +203,7 @@ impl ToString for Address { let mut data = vec![self.meta.to_byte()]; data.extend(self.spend.compress().to_bytes()); data.extend(self.view.compress().to_bytes()); - if let AddressType::Featured(subaddress, payment_id, guaranteed) = self.meta.kind { + if let AddressType::Featured { subaddress, payment_id, guaranteed } = self.meta.kind { // Technically should be a VarInt, yet we don't have enough features it's needed data.push( u8::from(subaddress) + (u8::from(payment_id.is_some()) << 1) + (u8::from(guaranteed) << 2), @@ -233,7 +236,7 @@ impl Address { .ok_or(AddressError::InvalidKey)?; let mut read = 65; - if matches!(meta.kind, AddressType::Featured(..)) { + if matches!(meta.kind, AddressType::Featured { .. }) { if raw[read] >= (2 << 3) { Err(AddressError::UnknownFeatures)?; } @@ -242,8 +245,11 @@ impl Address { let integrated = ((raw[read] >> 1) & 1) == 1; let guaranteed = ((raw[read] >> 2) & 1) == 1; - meta.kind = - AddressType::Featured(subaddress, Some([0; 8]).filter(|_| integrated), guaranteed); + meta.kind = AddressType::Featured { + subaddress, + payment_id: Some([0; 8]).filter(|_| integrated), + guaranteed, + }; read += 1; } @@ -258,7 +264,7 @@ impl Address { if let AddressType::Integrated(ref mut id) = meta.kind { id.copy_from_slice(&raw[(read - 8) .. read]); } - if let AddressType::Featured(_, Some(ref mut id), _) = meta.kind { + if let AddressType::Featured { payment_id: Some(ref mut id), .. } = meta.kind { id.copy_from_slice(&raw[(read - 8) .. read]); } diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index 48ee3a34..a30f6be0 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -140,13 +140,13 @@ impl ViewPair { (spend, view) = self.subaddress_keys(index); AddressMeta::new(network, AddressType::Subaddress) } - AddressSpec::Featured(subaddress, payment_id, guaranteed) => { + AddressSpec::Featured { subaddress, payment_id, guaranteed } => { if let Some(index) = subaddress { (spend, view) = self.subaddress_keys(index); } AddressMeta::new( network, - AddressType::Featured(subaddress.is_some(), payment_id, guaranteed), + AddressType::Featured { subaddress: subaddress.is_some(), payment_id, guaranteed }, ) } }; diff --git a/coins/monero/tests/scan.rs b/coins/monero/tests/scan.rs index af42ea96..0938b95b 100644 --- a/coins/monero/tests/scan.rs +++ b/coins/monero/tests/scan.rs @@ -68,8 +68,13 @@ test!( |_, mut builder: Builder, _| async move { let view = runner::random_address().1; let scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); - builder - .add_payment(view.address(Network::Mainnet, AddressSpec::Featured(None, None, false)), 5); + builder.add_payment( + view.address( + Network::Mainnet, + AddressSpec::Featured { subaddress: None, payment_id: None, guaranteed: false }, + ), + 5, + ); (builder.build().unwrap(), scanner) }, |_, tx: Transaction, _, mut state: Scanner| async move { @@ -90,7 +95,14 @@ test!( scanner.register_subaddress(subaddress); builder.add_payment( - view.address(Network::Mainnet, AddressSpec::Featured(Some(subaddress), None, false)), + view.address( + Network::Mainnet, + AddressSpec::Featured { + subaddress: Some(subaddress), + payment_id: None, + guaranteed: false, + }, + ), 5, ); (builder.build().unwrap(), (scanner, subaddress)) @@ -113,7 +125,14 @@ test!( OsRng.fill_bytes(&mut payment_id); builder.add_payment( - view.address(Network::Mainnet, AddressSpec::Featured(None, Some(payment_id), false)), + view.address( + Network::Mainnet, + AddressSpec::Featured { + subaddress: None, + payment_id: Some(payment_id), + guaranteed: false, + }, + ), 5, ); (builder.build().unwrap(), (scanner, payment_id)) @@ -142,7 +161,11 @@ test!( builder.add_payment( view.address( Network::Mainnet, - AddressSpec::Featured(Some(subaddress), Some(payment_id), false), + AddressSpec::Featured { + subaddress: Some(subaddress), + payment_id: Some(payment_id), + guaranteed: false, + }, ), 5, ); @@ -164,8 +187,13 @@ test!( let view = runner::random_address().1; let scanner = Scanner::from_view(view.clone(), None); - builder - .add_payment(view.address(Network::Mainnet, AddressSpec::Featured(None, None, true)), 5); + builder.add_payment( + view.address( + Network::Mainnet, + AddressSpec::Featured { subaddress: None, payment_id: None, guaranteed: true }, + ), + 5, + ); (builder.build().unwrap(), scanner) }, |_, tx: Transaction, _, mut state: Scanner| async move { @@ -186,7 +214,14 @@ test!( scanner.register_subaddress(subaddress); builder.add_payment( - view.address(Network::Mainnet, AddressSpec::Featured(Some(subaddress), None, true)), + view.address( + Network::Mainnet, + AddressSpec::Featured { + subaddress: Some(subaddress), + payment_id: None, + guaranteed: true, + }, + ), 5, ); (builder.build().unwrap(), (scanner, subaddress)) @@ -209,7 +244,14 @@ test!( OsRng.fill_bytes(&mut payment_id); builder.add_payment( - view.address(Network::Mainnet, AddressSpec::Featured(None, Some(payment_id), true)), + view.address( + Network::Mainnet, + AddressSpec::Featured { + subaddress: None, + payment_id: Some(payment_id), + guaranteed: true, + }, + ), 5, ); (builder.build().unwrap(), (scanner, payment_id)) @@ -238,7 +280,11 @@ test!( builder.add_payment( view.address( Network::Mainnet, - AddressSpec::Featured(Some(subaddress), Some(payment_id), true), + AddressSpec::Featured { + subaddress: Some(subaddress), + payment_id: Some(payment_id), + guaranteed: true, + }, ), 5, ); diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index 58afe3d8..5f364f7e 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -106,7 +106,10 @@ impl Monero { spend: dfg::EdwardsPoint, subaddress: Option, ) -> MoneroAddress { - self.view_pair(spend).address(Network::Mainnet, AddressSpec::Featured(subaddress, None, true)) + self.view_pair(spend).address( + Network::Mainnet, + AddressSpec::Featured { subaddress, payment_id: None, guaranteed: true }, + ) } fn scanner(&self, spend: dfg::EdwardsPoint) -> Scanner { From 6b591c0df9e8fc0af76032aa64c4ae2b99968a90 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 8 Jan 2023 09:09:03 -0500 Subject: [PATCH 17/74] Export Timelocked so documentation for it is generated --- coins/monero/src/wallet/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index a30f6be0..11aaff41 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -19,7 +19,7 @@ pub mod address; use address::{Network, AddressType, SubaddressIndex, AddressSpec, AddressMeta, MoneroAddress}; mod scan; -pub use scan::{ReceivedOutput, SpendableOutput}; +pub use scan::{ReceivedOutput, SpendableOutput, Timelocked}; pub(crate) mod decoys; pub(crate) use decoys::Decoys; From 97a94a0bf8b587bbbf984aebbb1af98adbe84f7e Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 8 Jan 2023 09:10:17 -0500 Subject: [PATCH 18/74] cargo update Fixes an irrelevant security issue in tokio. --- Cargo.lock | 71 +++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4afb2368..16bdcacb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,9 +252,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3" +checksum = "705339e0e4a9690e2908d2b3d049d85682cf19fbd5782494498fbf7003a6a282" dependencies = [ "proc-macro2", "quote", @@ -600,11 +600,12 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bstr" -version = "0.2.17" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" dependencies = [ "memchr", + "serde", ] [[package]] @@ -651,9 +652,9 @@ dependencies = [ [[package]] name = "bzip2" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" dependencies = [ "bzip2-sys", "libc", @@ -672,9 +673,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" +checksum = "c77df041dc383319cc661b428b6961a005db4d6808d5e12536931b1ca9556055" dependencies = [ "serde", ] @@ -1388,9 +1389,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" +checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" dependencies = [ "cc", "cxxbridge-flags", @@ -1400,9 +1401,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" +checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" dependencies = [ "cc", "codespan-reporting", @@ -1415,15 +1416,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" +checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" [[package]] name = "cxxbridge-macro" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" +checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" dependencies = [ "proc-macro2", "quote", @@ -1819,12 +1820,12 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", @@ -2275,9 +2276,9 @@ checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" [[package]] name = "file-per-thread-logger" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e16290574b39ee41c71aeb90ae960c504ebaf1e2a1c87bd52aa56ed6e1a02f" +checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866" dependencies = [ "env_logger", "log", @@ -2297,9 +2298,9 @@ dependencies = [ [[package]] name = "finality-grandpa" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b22349c6a11563a202d95772a68e0fcf56119e74ea8a2a19cf2301460fcd0df5" +checksum = "e24e6c429951433ccb7c87fd528c60084834dcd14763182c1f83291bcde24c34" dependencies = [ "either", "futures", @@ -2847,15 +2848,15 @@ checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" [[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.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" dependencies = [ "aho-corasick", "bstr", @@ -5453,9 +5454,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8992a85d8e93a28bdf76137db888d3874e3b230dee5ed8bebac4c9f7617773" +checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78" dependencies = [ "proc-macro2", "syn", @@ -8228,9 +8229,9 @@ dependencies = [ [[package]] name = "ss58-registry" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d92659e7d18d82b803824a9ba5a6022cff101c3491d027c1c1d8d30e749284" +checksum = "d44528162f980c0e03c71e005d334332c8da0aec9f2b0b4bdc557ed4a9f24776" dependencies = [ "Inflector", "num-format", @@ -8707,9 +8708,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.23.0" +version = "1.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" dependencies = [ "autocfg", "bytes", @@ -8990,9 +8991,9 @@ dependencies = [ [[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 = "tt-call" From ea7c281a47f7acd43fa8a9719e18f1214979ddef Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 9 Jan 2023 17:21:31 -0500 Subject: [PATCH 19/74] Move to dtolnay/toolchain (#211) * Move to dtolnay/toolchain * Correct dtolnay/toolchain to rust-roolchain * Pass toolchain by argument instead of revision Introduces malleability by referring to HEAD of dtolnay, yet GHA errored on the prior syntax. --- .github/actions/build-dependencies/action.yml | 7 ++-- .github/actions/cached-rust/action.yml | 34 ------------------- .github/workflows/daily-deny.yml | 5 +-- .github/workflows/tests.yml | 9 ++--- 4 files changed, 6 insertions(+), 49 deletions(-) delete mode 100644 .github/actions/cached-rust/action.yml diff --git a/.github/actions/build-dependencies/action.yml b/.github/actions/build-dependencies/action.yml index 15db381e..44f9c1cd 100644 --- a/.github/actions/build-dependencies/action.yml +++ b/.github/actions/build-dependencies/action.yml @@ -33,7 +33,7 @@ runs: solc-select use 0.8.16 - name: Install Rust - uses: ./.github/actions/cached-rust + uses: dtolnay/rust-toolchain@master with: toolchain: ${{ inputs.rust-toolchain }} components: ${{ inputs.rust-components }} @@ -44,8 +44,7 @@ runs: run: echo "version=$(cat .github/nightly-version)" >> $GITHUB_OUTPUT - name: Install WASM toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@master with: toolchain: ${{ steps.nightly.outputs.version }} - profile: minimal - target: wasm32-unknown-unknown + targets: wasm32-unknown-unknown diff --git a/.github/actions/cached-rust/action.yml b/.github/actions/cached-rust/action.yml deleted file mode 100644 index 09ae995e..00000000 --- a/.github/actions/cached-rust/action.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: cached-rust -description: Installs Rust, caching ~/.cargo and ./target - -inputs: - toolchain: - description: "Toolchain to install" - required: false - default: stable - - components: - description: "Components to install" - required: false - default: - -runs: - using: "composite" - steps: - - name: Rust Cache - uses: actions/cache@v3 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - ./target - key: ${{ runner.os }}-${{ runner.arch }}-rust-${{ steps.install-rust.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: ${{ runner.os }}-${{ runner.arch }}-rust-${{ steps.install-rust.outputs.rustc_hash }}- - - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ inputs.toolchain }} - profile: minimal - default: true - components: ${{ inputs.components }} diff --git a/.github/workflows/daily-deny.yml b/.github/workflows/daily-deny.yml index 01e8e6a7..460f4b5a 100644 --- a/.github/workflows/daily-deny.yml +++ b/.github/workflows/daily-deny.yml @@ -18,10 +18,7 @@ jobs: key: rust-advisory-db - name: Install cargo - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal + uses: dtolnay/rust-toolchain@stable - name: Install cargo deny run: cargo install --locked cargo-deny diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 07581c51..079e1fa1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,10 +40,7 @@ jobs: key: rust-advisory-db - name: Install cargo - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal + uses: dtolnay/rust-toolchain@stable - name: Install cargo deny run: cargo install --locked cargo-deny @@ -73,12 +70,10 @@ jobs: id: nightly run: echo "version=$(cat .github/nightly-version)" >> $GITHUB_OUTPUT - # Doesn't grab the cache as it's not needed - name: Install rustfmt - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@master with: toolchain: ${{ steps.nightly.outputs.version }} - profile: minimal components: rustfmt - name: Run rustfmt From 422a562c788799eea054ca1bd74c52aff3ec4ef8 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 10 Jan 2023 00:32:35 -0500 Subject: [PATCH 20/74] Use arduino/setup-protoc@master instead of the tagged v1 The tag is ancient and uses the now-deprecated NodeJS v12. master uses 16. --- .github/actions/build-dependencies/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build-dependencies/action.yml b/.github/actions/build-dependencies/action.yml index 44f9c1cd..754daea3 100644 --- a/.github/actions/build-dependencies/action.yml +++ b/.github/actions/build-dependencies/action.yml @@ -21,7 +21,7 @@ runs: using: "composite" steps: - name: Install Protobuf - uses: arduino/setup-protoc@v1 + uses: arduino/setup-protoc@master with: repo-token: ${{ inputs.github-token }} From 8ffa5553fffc4dfc5fcbb4da84c24e590ab27652 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 10 Jan 2023 06:57:25 -0500 Subject: [PATCH 21/74] Use ok_or_else instead of ok_or in a couple places in Monero --- coins/monero/src/wallet/scan.rs | 2 +- coins/monero/src/wallet/send/multisig.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index 6ac13f7a..7fd1a027 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -115,7 +115,7 @@ impl Metadata { let subaddress = if read_byte(r)? == 1 { Some( SubaddressIndex::new(read_u32(r)?, read_u32(r)?) - .ok_or(io::Error::new(io::ErrorKind::Other, "invalid subaddress in metadata"))?, + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid subaddress in metadata"))?, ) } else { None diff --git a/coins/monero/src/wallet/send/multisig.rs b/coins/monero/src/wallet/send/multisig.rs index 7dcb6f13..3ba990f4 100644 --- a/coins/monero/src/wallet/send/multisig.rs +++ b/coins/monero/src/wallet/send/multisig.rs @@ -123,7 +123,7 @@ impl SignableTransaction { let clsag = ClsagMultisig::new(transcript.clone(), input.key(), inputs[i].clone()); key_images.push(( clsag.H, - keys.current_offset().unwrap_or(dfg::Scalar::zero()).0 + self.inputs[i].key_offset(), + keys.current_offset().unwrap_or_else(dfg::Scalar::zero).0 + self.inputs[i].key_offset(), )); clsags.push(AlgorithmMachine::new(clsag, offset).map_err(TransactionError::FrostError)?); } From 375887bb29819bd17f47866538c0b61bd16e4c87 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 11 Jan 2023 23:05:31 -0500 Subject: [PATCH 22/74] Update licenses --- .github/actions/LICENSE | 21 +++++++++++++++++++++ LICENSE | 2 ++ coins/ethereum/LICENSE | 2 +- coins/monero/LICENSE | 2 +- coins/monero/generators/LICENSE | 2 +- common/zalloc/LICENSE | 2 +- crypto/ciphersuite/LICENSE | 2 +- crypto/dalek-ff-group/LICENSE | 2 +- crypto/dkg/LICENSE | 2 +- crypto/dleq/LICENSE | 2 +- crypto/ed448/LICENSE | 2 +- crypto/ff-group-tests/LICENSE | 2 +- crypto/frost/LICENSE | 2 +- crypto/multiexp/LICENSE | 2 +- crypto/schnorr/LICENSE | 2 +- crypto/transcript/LICENSE | 2 +- processor/LICENSE | 2 +- substrate/node/LICENSE | 2 +- substrate/runtime/LICENSE | 2 +- substrate/serai/primitives/LICENSE | 2 +- substrate/tendermint/client/LICENSE | 2 +- substrate/tendermint/machine/LICENSE | 2 +- substrate/tendermint/pallet/LICENSE | 2 +- substrate/tendermint/primitives/LICENSE | 2 +- substrate/validator-sets/pallet/LICENSE | 2 +- substrate/validator-sets/primitives/LICENSE | 2 +- 26 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 .github/actions/LICENSE diff --git a/.github/actions/LICENSE b/.github/actions/LICENSE new file mode 100644 index 00000000..6779f0ec --- /dev/null +++ b/.github/actions/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2023 Luke Parker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSE b/LICENSE index 0b4b21fc..34f2feb2 100644 --- a/LICENSE +++ b/LICENSE @@ -4,3 +4,5 @@ depending on the crate in question. Each crate declares their license in their a full copy of the AGPL-3.0 License is included in the root of this repository as a reference text. This copy should be provided with any distribution of a crate licensed under the AGPL-3.0, as per its terms. + +The GitHub actions (`.github/actions`) are licensed under the MIT license. diff --git a/coins/ethereum/LICENSE b/coins/ethereum/LICENSE index d6e1814a..c425427c 100644 --- a/coins/ethereum/LICENSE +++ b/coins/ethereum/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/coins/monero/LICENSE b/coins/monero/LICENSE index f05b748b..6779f0ec 100644 --- a/coins/monero/LICENSE +++ b/coins/monero/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/coins/monero/generators/LICENSE b/coins/monero/generators/LICENSE index f05b748b..6779f0ec 100644 --- a/coins/monero/generators/LICENSE +++ b/coins/monero/generators/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/common/zalloc/LICENSE b/common/zalloc/LICENSE index f05b748b..6779f0ec 100644 --- a/common/zalloc/LICENSE +++ b/common/zalloc/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/ciphersuite/LICENSE b/crypto/ciphersuite/LICENSE index c0617e57..be67c32f 100644 --- a/crypto/ciphersuite/LICENSE +++ b/crypto/ciphersuite/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2022 Luke Parker +Copyright (c) 2021-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/dalek-ff-group/LICENSE b/crypto/dalek-ff-group/LICENSE index f05b748b..6779f0ec 100644 --- a/crypto/dalek-ff-group/LICENSE +++ b/crypto/dalek-ff-group/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/dkg/LICENSE b/crypto/dkg/LICENSE index c0617e57..be67c32f 100644 --- a/crypto/dkg/LICENSE +++ b/crypto/dkg/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2022 Luke Parker +Copyright (c) 2021-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/dleq/LICENSE b/crypto/dleq/LICENSE index c1f47de3..78ab2d01 100644 --- a/crypto/dleq/LICENSE +++ b/crypto/dleq/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020-2022 Luke Parker, Lee Bousfield +Copyright (c) 2020-2023 Luke Parker, Lee Bousfield Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/ed448/LICENSE b/crypto/ed448/LICENSE index f05b748b..6779f0ec 100644 --- a/crypto/ed448/LICENSE +++ b/crypto/ed448/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/ff-group-tests/LICENSE b/crypto/ff-group-tests/LICENSE index f05b748b..6779f0ec 100644 --- a/crypto/ff-group-tests/LICENSE +++ b/crypto/ff-group-tests/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/frost/LICENSE b/crypto/frost/LICENSE index c0617e57..be67c32f 100644 --- a/crypto/frost/LICENSE +++ b/crypto/frost/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2022 Luke Parker +Copyright (c) 2021-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/multiexp/LICENSE b/crypto/multiexp/LICENSE index f05b748b..6779f0ec 100644 --- a/crypto/multiexp/LICENSE +++ b/crypto/multiexp/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/schnorr/LICENSE b/crypto/schnorr/LICENSE index c0617e57..be67c32f 100644 --- a/crypto/schnorr/LICENSE +++ b/crypto/schnorr/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2022 Luke Parker +Copyright (c) 2021-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/crypto/transcript/LICENSE b/crypto/transcript/LICENSE index f05b748b..6779f0ec 100644 --- a/crypto/transcript/LICENSE +++ b/crypto/transcript/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/processor/LICENSE b/processor/LICENSE index d6e1814a..c425427c 100644 --- a/processor/LICENSE +++ b/processor/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/substrate/node/LICENSE b/substrate/node/LICENSE index d6e1814a..c425427c 100644 --- a/substrate/node/LICENSE +++ b/substrate/node/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/substrate/runtime/LICENSE b/substrate/runtime/LICENSE index d6e1814a..c425427c 100644 --- a/substrate/runtime/LICENSE +++ b/substrate/runtime/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/substrate/serai/primitives/LICENSE b/substrate/serai/primitives/LICENSE index d6e1814a..c425427c 100644 --- a/substrate/serai/primitives/LICENSE +++ b/substrate/serai/primitives/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/substrate/tendermint/client/LICENSE b/substrate/tendermint/client/LICENSE index d6e1814a..c425427c 100644 --- a/substrate/tendermint/client/LICENSE +++ b/substrate/tendermint/client/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/substrate/tendermint/machine/LICENSE b/substrate/tendermint/machine/LICENSE index f05b748b..6779f0ec 100644 --- a/substrate/tendermint/machine/LICENSE +++ b/substrate/tendermint/machine/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/substrate/tendermint/pallet/LICENSE b/substrate/tendermint/pallet/LICENSE index d6e1814a..c425427c 100644 --- a/substrate/tendermint/pallet/LICENSE +++ b/substrate/tendermint/pallet/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/substrate/tendermint/primitives/LICENSE b/substrate/tendermint/primitives/LICENSE index d6e1814a..c425427c 100644 --- a/substrate/tendermint/primitives/LICENSE +++ b/substrate/tendermint/primitives/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/substrate/validator-sets/pallet/LICENSE b/substrate/validator-sets/pallet/LICENSE index d6e1814a..c425427c 100644 --- a/substrate/validator-sets/pallet/LICENSE +++ b/substrate/validator-sets/pallet/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as diff --git a/substrate/validator-sets/primitives/LICENSE b/substrate/validator-sets/primitives/LICENSE index d6e1814a..c425427c 100644 --- a/substrate/validator-sets/primitives/LICENSE +++ b/substrate/validator-sets/primitives/LICENSE @@ -1,6 +1,6 @@ AGPL-3.0-only license -Copyright (c) 2022 Luke Parker +Copyright (c) 2022-2023 Luke Parker This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as From d37aff515dfdc869714d5091c587f53d271ce173 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 13 Jan 2023 17:42:53 -0500 Subject: [PATCH 23/74] Update advisories in deny.toml --- deny.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/deny.toml b/deny.toml index ca7751f0..c4d8f391 100644 --- a/deny.toml +++ b/deny.toml @@ -9,6 +9,11 @@ unmaintained = "warn" ignore = [ "RUSTSEC-2020-0071", # https://github.com/chronotope/chrono/issues/602 + "RUSTSEC-2021-0139". # https://github.com/serai-dex/serai/228 + "RUSTSEC-2021-0145". # https://github.com/serai-dex/serai/225 + "RUSTSEC-2022-0061". # https://github.com/serai-dex/serai/227 + "RUSTSEC-2022-0075", # https://github.com/serai-dex/serai/226 + "RUSTSEC-2022-0076". # https://github.com/serai-dex/serai/226 ] [licenses] @@ -74,5 +79,4 @@ unknown-git = "deny" allow-registry = ["https://github.com/rust-lang/crates.io-index"] allow-git = [ "https://github.com/serai-dex/substrate", - "https://github.com/hack-ink/array-bytes" ] From 50a4f5938acfca4d8ef4f99e11cae471673d44a3 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 13 Jan 2023 17:44:20 -0500 Subject: [PATCH 24/74] Correct syntax in prior commit --- deny.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deny.toml b/deny.toml index c4d8f391..59376eeb 100644 --- a/deny.toml +++ b/deny.toml @@ -9,11 +9,11 @@ unmaintained = "warn" ignore = [ "RUSTSEC-2020-0071", # https://github.com/chronotope/chrono/issues/602 - "RUSTSEC-2021-0139". # https://github.com/serai-dex/serai/228 - "RUSTSEC-2021-0145". # https://github.com/serai-dex/serai/225 - "RUSTSEC-2022-0061". # https://github.com/serai-dex/serai/227 + "RUSTSEC-2021-0139", # https://github.com/serai-dex/serai/228 + "RUSTSEC-2021-0145", # https://github.com/serai-dex/serai/225 + "RUSTSEC-2022-0061", # https://github.com/serai-dex/serai/227 "RUSTSEC-2022-0075", # https://github.com/serai-dex/serai/226 - "RUSTSEC-2022-0076". # https://github.com/serai-dex/serai/226 + "RUSTSEC-2022-0076", # https://github.com/serai-dex/serai/226 ] [licenses] From 8ef8b5ca6fb2c16f21dd069ffc17a27ef32ba9eb Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 13 Jan 2023 18:52:38 -0500 Subject: [PATCH 25/74] Implement a FROST algorithm for Schnorrkel --- Cargo.lock | 64 +++++++++++++++- Cargo.toml | 1 + crypto/schnorrkel/Cargo.toml | 28 +++++++ crypto/schnorrkel/LICENSE | 21 ++++++ crypto/schnorrkel/src/lib.rs | 133 +++++++++++++++++++++++++++++++++ crypto/schnorrkel/src/tests.rs | 14 ++++ 6 files changed, 258 insertions(+), 3 deletions(-) create mode 100644 crypto/schnorrkel/Cargo.toml create mode 100644 crypto/schnorrkel/LICENSE create mode 100644 crypto/schnorrkel/src/lib.rs create mode 100644 crypto/schnorrkel/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 16bdcacb..d10974f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1387,6 +1387,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + [[package]] name = "cxx" version = "1.0.86" @@ -2601,6 +2614,19 @@ dependencies = [ "sp-api", ] +[[package]] +name = "frost-schnorrkel" +version = "0.1.0" +dependencies = [ + "ciphersuite", + "group", + "modular-frost", + "rand_core 0.6.4", + "schnorr-signatures", + "schnorrkel 0.10.2", + "zeroize", +] + [[package]] name = "fs2" version = "0.4.3" @@ -7107,6 +7133,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "schnorrkel" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "844b7645371e6ecdf61ff246ba1958c29e802881a749ae3fb1993675d210d28d" +dependencies = [ + "arrayref", + "arrayvec 0.7.2", + "curve25519-dalek-ng", + "merlin 3.0.0", + "rand_core 0.6.4", + "serde_bytes", + "sha2 0.9.9", + "subtle-ng", + "zeroize", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -7369,6 +7412,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "serde_bytes" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.152" @@ -7752,7 +7804,7 @@ dependencies = [ "rand 0.7.3", "regex", "scale-info", - "schnorrkel", + "schnorrkel 0.9.1", "secp256k1", "secrecy", "serde", @@ -7905,7 +7957,7 @@ dependencies = [ "merlin 2.0.1", "parity-scale-codec", "parking_lot 0.12.1", - "schnorrkel", + "schnorrkel 0.9.1", "serde", "sp-core", "sp-externalities", @@ -8344,7 +8396,7 @@ checksum = "49eee6965196b32f882dd2ee85a92b1dbead41b04e53907f269de3b0dc04733c" dependencies = [ "hmac 0.11.0", "pbkdf2 0.8.0", - "schnorrkel", + "schnorrkel 0.9.1", "sha2 0.9.9", "zeroize", ] @@ -8414,6 +8466,12 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "svm-rs" version = "0.2.18" diff --git a/Cargo.toml b/Cargo.toml index 7cdec0c1..520f1b5e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ members = [ "crypto/dleq", "crypto/dkg", "crypto/frost", + "crypto/schnorrkel", "coins/ethereum", "coins/monero/generators", diff --git a/crypto/schnorrkel/Cargo.toml b/crypto/schnorrkel/Cargo.toml new file mode 100644 index 00000000..533c07a3 --- /dev/null +++ b/crypto/schnorrkel/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "frost-schnorrkel" +version = "0.1.0" +description = "modular-frost Algorithm compatible with Schnorrkel" +license = "MIT" +repository = "https://github.com/serai-dex/serai/tree/develop/crypto/schnorrkel" +authors = ["Luke Parker "] +keywords = ["frost", "multisig", "threshold", "schnorrkel"] +edition = "2021" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +rand_core = "0.6" +zeroize = "1.5" + +group = "0.12" + +ciphersuite = { path = "../ciphersuite", version = "0.1", features = ["std", "ristretto"] } +schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "0.2" } +frost = { path = "../frost", package = "modular-frost", version = "0.5", features = ["ristretto"] } + +schnorrkel = "0.10" + +[dev-dependencies] +frost = { path = "../frost", package = "modular-frost", version = "0.5", features = ["ristretto", "tests"] } diff --git a/crypto/schnorrkel/LICENSE b/crypto/schnorrkel/LICENSE new file mode 100644 index 00000000..e6bff13c --- /dev/null +++ b/crypto/schnorrkel/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Luke Parker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crypto/schnorrkel/src/lib.rs b/crypto/schnorrkel/src/lib.rs new file mode 100644 index 00000000..b2476aef --- /dev/null +++ b/crypto/schnorrkel/src/lib.rs @@ -0,0 +1,133 @@ +use std::io::{self, Read}; + +use rand_core::{RngCore, CryptoRng}; + +use zeroize::Zeroizing; + +use group::{ff::PrimeField, GroupEncoding}; +use ciphersuite::{Ciphersuite, Ristretto}; +use schnorr::SchnorrSignature; +use frost::{ + ThresholdKeys, ThresholdView, FrostError, + algorithm::{IetfTranscript, Hram, Algorithm, Schnorr}, +}; + +use schnorrkel::{PublicKey, Signature, context::SigningTranscript, signing_context}; + +type RistrettoPoint = ::G; +type Scalar = ::F; + +#[cfg(test)] +mod tests; + +#[derive(Clone)] +struct SchnorrkelHram; +impl Hram for SchnorrkelHram { + #[allow(non_snake_case)] + fn hram(R: &RistrettoPoint, A: &RistrettoPoint, m: &[u8]) -> Scalar { + let ctx_len = + usize::try_from(u32::from_le_bytes(m[0 .. 4].try_into().expect("malformed message"))) + .unwrap(); + let mut t = signing_context(&m[4 .. (4 + ctx_len)]).bytes(&m[(4 + ctx_len) ..]); + t.proto_name(b"Schnorr-sig"); + let convert = + |point: &RistrettoPoint| PublicKey::from_bytes(&point.to_bytes()).unwrap().into_compressed(); + t.commit_point(b"sign:pk", &convert(A)); + t.commit_point(b"sign:R", &convert(R)); + Scalar::from_repr(t.challenge_scalar(b"sign:c").to_bytes()).unwrap() + } +} + +#[derive(Clone)] +pub struct Schnorrkel { + context: &'static [u8], + schnorr: Schnorr, + msg: Option>, +} + +impl Schnorrkel { + pub fn new(context: &'static [u8]) -> Schnorrkel { + Schnorrkel { context, schnorr: Schnorr::new(), msg: None } + } +} + +impl Algorithm for Schnorrkel { + type Transcript = IetfTranscript; + type Addendum = (); + type Signature = Signature; + + fn transcript(&mut self) -> &mut Self::Transcript { + self.schnorr.transcript() + } + + fn nonces(&self) -> Vec::G>> { + self.schnorr.nonces() + } + + fn preprocess_addendum( + &mut self, + _: &mut R, + _: &ThresholdKeys, + ) { + } + + fn read_addendum(&self, _: &mut R) -> io::Result { + Ok(()) + } + + fn process_addendum( + &mut self, + _: &ThresholdView, + _: u16, + _: (), + ) -> Result<(), FrostError> { + Ok(()) + } + + fn sign_share( + &mut self, + params: &ThresholdView, + nonce_sums: &[Vec<::G>], + nonces: Vec::F>>, + msg: &[u8], + ) -> ::F { + self.msg = Some(msg.to_vec()); + self.schnorr.sign_share( + params, + nonce_sums, + nonces, + &[ + &u32::try_from(self.context.len()).expect("context exceeded 2^32 bytes").to_le_bytes(), + self.context, + msg, + ] + .concat(), + ) + } + + #[must_use] + fn verify( + &self, + group_key: ::G, + nonces: &[Vec<::G>], + sum: ::F, + ) -> Option { + let mut sig = (SchnorrSignature:: { R: nonces[0][0], s: sum }).serialize(); + sig[63] |= 1 << 7; + Some(Signature::from_bytes(&sig).unwrap()).filter(|sig| { + PublicKey::from_bytes(&group_key.to_bytes()) + .unwrap() + .verify(&mut signing_context(self.context).bytes(self.msg.as_ref().unwrap()), sig) + .is_ok() + }) + } + + fn verify_share( + &self, + verification_share: ::G, + nonces: &[Vec<::G>], + share: ::F, + ) -> Result::F, ::G)>, ()> { + self.schnorr.verify_share(verification_share, nonces, share) + } +} diff --git a/crypto/schnorrkel/src/tests.rs b/crypto/schnorrkel/src/tests.rs new file mode 100644 index 00000000..8b36ce42 --- /dev/null +++ b/crypto/schnorrkel/src/tests.rs @@ -0,0 +1,14 @@ +use rand_core::OsRng; + +use frost::tests::{key_gen, algorithm_machines, sign}; + +use crate::Schnorrkel; + +#[test] +fn test() { + let keys = key_gen(&mut OsRng); + const CONTEXT: &[u8] = b"FROST Schnorrkel Test"; + let machines = algorithm_machines(&mut OsRng, Schnorrkel::new(CONTEXT), &keys); + const MSG: &[u8] = b"Hello, World!"; + sign(&mut OsRng, Schnorrkel::new(CONTEXT), keys, machines, MSG); +} From be05e0dd4724e40d3410f60ed3a6fe5631268d5d Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 13 Jan 2023 18:57:07 -0500 Subject: [PATCH 26/74] Revert "Implement a FROST algorithm for Schnorrkel" This reverts commit 8ef8b5ca6fb2c16f21dd069ffc17a27ef32ba9eb. --- Cargo.lock | 64 +--------------- Cargo.toml | 1 - crypto/schnorrkel/Cargo.toml | 28 ------- crypto/schnorrkel/LICENSE | 21 ------ crypto/schnorrkel/src/lib.rs | 133 --------------------------------- crypto/schnorrkel/src/tests.rs | 14 ---- 6 files changed, 3 insertions(+), 258 deletions(-) delete mode 100644 crypto/schnorrkel/Cargo.toml delete mode 100644 crypto/schnorrkel/LICENSE delete mode 100644 crypto/schnorrkel/src/lib.rs delete mode 100644 crypto/schnorrkel/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index d10974f5..16bdcacb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1387,19 +1387,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "curve25519-dalek-ng" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.6.4", - "subtle-ng", - "zeroize", -] - [[package]] name = "cxx" version = "1.0.86" @@ -2614,19 +2601,6 @@ dependencies = [ "sp-api", ] -[[package]] -name = "frost-schnorrkel" -version = "0.1.0" -dependencies = [ - "ciphersuite", - "group", - "modular-frost", - "rand_core 0.6.4", - "schnorr-signatures", - "schnorrkel 0.10.2", - "zeroize", -] - [[package]] name = "fs2" version = "0.4.3" @@ -7133,23 +7107,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "schnorrkel" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "844b7645371e6ecdf61ff246ba1958c29e802881a749ae3fb1993675d210d28d" -dependencies = [ - "arrayref", - "arrayvec 0.7.2", - "curve25519-dalek-ng", - "merlin 3.0.0", - "rand_core 0.6.4", - "serde_bytes", - "sha2 0.9.9", - "subtle-ng", - "zeroize", -] - [[package]] name = "scopeguard" version = "1.1.0" @@ -7412,15 +7369,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "serde_bytes" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" -dependencies = [ - "serde", -] - [[package]] name = "serde_derive" version = "1.0.152" @@ -7804,7 +7752,7 @@ dependencies = [ "rand 0.7.3", "regex", "scale-info", - "schnorrkel 0.9.1", + "schnorrkel", "secp256k1", "secrecy", "serde", @@ -7957,7 +7905,7 @@ dependencies = [ "merlin 2.0.1", "parity-scale-codec", "parking_lot 0.12.1", - "schnorrkel 0.9.1", + "schnorrkel", "serde", "sp-core", "sp-externalities", @@ -8396,7 +8344,7 @@ checksum = "49eee6965196b32f882dd2ee85a92b1dbead41b04e53907f269de3b0dc04733c" dependencies = [ "hmac 0.11.0", "pbkdf2 0.8.0", - "schnorrkel 0.9.1", + "schnorrkel", "sha2 0.9.9", "zeroize", ] @@ -8466,12 +8414,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" -[[package]] -name = "subtle-ng" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" - [[package]] name = "svm-rs" version = "0.2.18" diff --git a/Cargo.toml b/Cargo.toml index 520f1b5e..7cdec0c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,6 @@ members = [ "crypto/dleq", "crypto/dkg", "crypto/frost", - "crypto/schnorrkel", "coins/ethereum", "coins/monero/generators", diff --git a/crypto/schnorrkel/Cargo.toml b/crypto/schnorrkel/Cargo.toml deleted file mode 100644 index 533c07a3..00000000 --- a/crypto/schnorrkel/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "frost-schnorrkel" -version = "0.1.0" -description = "modular-frost Algorithm compatible with Schnorrkel" -license = "MIT" -repository = "https://github.com/serai-dex/serai/tree/develop/crypto/schnorrkel" -authors = ["Luke Parker "] -keywords = ["frost", "multisig", "threshold", "schnorrkel"] -edition = "2021" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[dependencies] -rand_core = "0.6" -zeroize = "1.5" - -group = "0.12" - -ciphersuite = { path = "../ciphersuite", version = "0.1", features = ["std", "ristretto"] } -schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "0.2" } -frost = { path = "../frost", package = "modular-frost", version = "0.5", features = ["ristretto"] } - -schnorrkel = "0.10" - -[dev-dependencies] -frost = { path = "../frost", package = "modular-frost", version = "0.5", features = ["ristretto", "tests"] } diff --git a/crypto/schnorrkel/LICENSE b/crypto/schnorrkel/LICENSE deleted file mode 100644 index e6bff13c..00000000 --- a/crypto/schnorrkel/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Luke Parker - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/crypto/schnorrkel/src/lib.rs b/crypto/schnorrkel/src/lib.rs deleted file mode 100644 index b2476aef..00000000 --- a/crypto/schnorrkel/src/lib.rs +++ /dev/null @@ -1,133 +0,0 @@ -use std::io::{self, Read}; - -use rand_core::{RngCore, CryptoRng}; - -use zeroize::Zeroizing; - -use group::{ff::PrimeField, GroupEncoding}; -use ciphersuite::{Ciphersuite, Ristretto}; -use schnorr::SchnorrSignature; -use frost::{ - ThresholdKeys, ThresholdView, FrostError, - algorithm::{IetfTranscript, Hram, Algorithm, Schnorr}, -}; - -use schnorrkel::{PublicKey, Signature, context::SigningTranscript, signing_context}; - -type RistrettoPoint = ::G; -type Scalar = ::F; - -#[cfg(test)] -mod tests; - -#[derive(Clone)] -struct SchnorrkelHram; -impl Hram for SchnorrkelHram { - #[allow(non_snake_case)] - fn hram(R: &RistrettoPoint, A: &RistrettoPoint, m: &[u8]) -> Scalar { - let ctx_len = - usize::try_from(u32::from_le_bytes(m[0 .. 4].try_into().expect("malformed message"))) - .unwrap(); - let mut t = signing_context(&m[4 .. (4 + ctx_len)]).bytes(&m[(4 + ctx_len) ..]); - t.proto_name(b"Schnorr-sig"); - let convert = - |point: &RistrettoPoint| PublicKey::from_bytes(&point.to_bytes()).unwrap().into_compressed(); - t.commit_point(b"sign:pk", &convert(A)); - t.commit_point(b"sign:R", &convert(R)); - Scalar::from_repr(t.challenge_scalar(b"sign:c").to_bytes()).unwrap() - } -} - -#[derive(Clone)] -pub struct Schnorrkel { - context: &'static [u8], - schnorr: Schnorr, - msg: Option>, -} - -impl Schnorrkel { - pub fn new(context: &'static [u8]) -> Schnorrkel { - Schnorrkel { context, schnorr: Schnorr::new(), msg: None } - } -} - -impl Algorithm for Schnorrkel { - type Transcript = IetfTranscript; - type Addendum = (); - type Signature = Signature; - - fn transcript(&mut self) -> &mut Self::Transcript { - self.schnorr.transcript() - } - - fn nonces(&self) -> Vec::G>> { - self.schnorr.nonces() - } - - fn preprocess_addendum( - &mut self, - _: &mut R, - _: &ThresholdKeys, - ) { - } - - fn read_addendum(&self, _: &mut R) -> io::Result { - Ok(()) - } - - fn process_addendum( - &mut self, - _: &ThresholdView, - _: u16, - _: (), - ) -> Result<(), FrostError> { - Ok(()) - } - - fn sign_share( - &mut self, - params: &ThresholdView, - nonce_sums: &[Vec<::G>], - nonces: Vec::F>>, - msg: &[u8], - ) -> ::F { - self.msg = Some(msg.to_vec()); - self.schnorr.sign_share( - params, - nonce_sums, - nonces, - &[ - &u32::try_from(self.context.len()).expect("context exceeded 2^32 bytes").to_le_bytes(), - self.context, - msg, - ] - .concat(), - ) - } - - #[must_use] - fn verify( - &self, - group_key: ::G, - nonces: &[Vec<::G>], - sum: ::F, - ) -> Option { - let mut sig = (SchnorrSignature:: { R: nonces[0][0], s: sum }).serialize(); - sig[63] |= 1 << 7; - Some(Signature::from_bytes(&sig).unwrap()).filter(|sig| { - PublicKey::from_bytes(&group_key.to_bytes()) - .unwrap() - .verify(&mut signing_context(self.context).bytes(self.msg.as_ref().unwrap()), sig) - .is_ok() - }) - } - - fn verify_share( - &self, - verification_share: ::G, - nonces: &[Vec<::G>], - share: ::F, - ) -> Result::F, ::G)>, ()> { - self.schnorr.verify_share(verification_share, nonces, share) - } -} diff --git a/crypto/schnorrkel/src/tests.rs b/crypto/schnorrkel/src/tests.rs deleted file mode 100644 index 8b36ce42..00000000 --- a/crypto/schnorrkel/src/tests.rs +++ /dev/null @@ -1,14 +0,0 @@ -use rand_core::OsRng; - -use frost::tests::{key_gen, algorithm_machines, sign}; - -use crate::Schnorrkel; - -#[test] -fn test() { - let keys = key_gen(&mut OsRng); - const CONTEXT: &[u8] = b"FROST Schnorrkel Test"; - let machines = algorithm_machines(&mut OsRng, Schnorrkel::new(CONTEXT), &keys); - const MSG: &[u8] = b"Hello, World!"; - sign(&mut OsRng, Schnorrkel::new(CONTEXT), keys, machines, MSG); -} From ced89332d29f03c8259eaa39794079fd2abf5393 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 16 Jan 2023 10:42:31 -0500 Subject: [PATCH 27/74] cargo update Necessary due to https://github.com/RustCrypto/signatures/issues/615. Opportunity taken to update Substrate. --- Cargo.lock | 1660 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 1246 insertions(+), 414 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 16bdcacb..a2deb9bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" +dependencies = [ + "generic-array 0.14.6", +] + [[package]] name = "aead" version = "0.4.3" @@ -43,6 +52,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ "generic-array 0.14.6", + "rand_core 0.6.4", +] + +[[package]] +name = "aes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" +dependencies = [ + "aes-soft", + "aesni", + "cipher 0.2.5", ] [[package]] @@ -68,20 +89,54 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "aes-gcm" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" +dependencies = [ + "aead 0.3.2", + "aes 0.6.0", + "cipher 0.2.5", + "ctr 0.6.0", + "ghash 0.3.1", + "subtle", +] + [[package]] name = "aes-gcm" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" dependencies = [ - "aead", + "aead 0.4.3", "aes 0.7.5", "cipher 0.3.0", "ctr 0.8.0", - "ghash", + "ghash 0.4.4", "subtle", ] +[[package]] +name = "aes-soft" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" +dependencies = [ + "cipher 0.2.5", + "opaque-debug 0.3.0", +] + +[[package]] +name = "aesni" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +dependencies = [ + "cipher 0.2.5", + "opaque-debug 0.3.0", +] + [[package]] name = "ahash" version = "0.7.6" @@ -135,6 +190,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + [[package]] name = "array-bytes" version = "4.2.0" @@ -168,52 +229,79 @@ dependencies = [ "term", ] +[[package]] +name = "asn1-rs" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" +dependencies = [ + "asn1-rs-derive 0.1.0", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time 0.3.17", +] + +[[package]] +name = "asn1-rs" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf6690c370453db30743b373a60ba498fc0d6d83b11f4abfd87a84a075db5dd4" +dependencies = [ + "asn1-rs-derive 0.4.0", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time 0.3.17", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "asn1_der" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e22d1f4b888c298a027c99dc9048015fac177587de20fc30232a057dfbe24a21" -[[package]] -name = "async-channel" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" -dependencies = [ - "async-lock", - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - [[package]] name = "async-io" version = "1.12.0" @@ -244,12 +332,6 @@ dependencies = [ "futures-lite", ] -[[package]] -name = "async-task" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" - [[package]] name = "async-trait" version = "0.1.61" @@ -287,9 +369,9 @@ dependencies = [ [[package]] name = "atomic-waker" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" +checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" [[package]] name = "atty" @@ -343,7 +425,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object 0.30.1", + "object 0.30.2", "rustc-demangle", ] @@ -403,6 +485,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + [[package]] name = "base64ct" version = "1.5.3" @@ -545,7 +633,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding", + "block-padding 0.1.5", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -569,6 +657,16 @@ dependencies = [ "generic-array 0.14.6", ] +[[package]] +name = "block-modes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +dependencies = [ + "block-padding 0.2.1", + "cipher 0.2.5", +] + [[package]] name = "block-padding" version = "0.1.5" @@ -579,18 +677,10 @@ dependencies = [ ] [[package]] -name = "blocking" -version = "1.3.0" +name = "block-padding" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8" -dependencies = [ - "async-channel", - "async-lock", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", -] +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "bs58" @@ -725,6 +815,17 @@ dependencies = [ "jobserver", ] +[[package]] +name = "ccm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca1a8fbc20b50ac9673ff014abfb2b5f4085ee1a850d408f14a159c5853ac7" +dependencies = [ + "aead 0.3.2", + "cipher 0.2.5", + "subtle", +] + [[package]] name = "cexpr" version = "0.6.0" @@ -784,7 +885,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" dependencies = [ - "aead", + "aead 0.4.3", "chacha20 0.8.2", "cipher 0.3.0", "poly1305", @@ -819,6 +920,15 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "cipher" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +dependencies = [ + "generic-array 0.14.6", +] + [[package]] name = "cipher" version = "0.3.0" @@ -890,13 +1000,13 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.32" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39" +checksum = "4ec7a4128863c188deefe750ac1d1dfe66c236909f845af04beed823638dc1b2" dependencies = [ "bitflags", - "clap_derive 4.0.21", - "clap_lex 0.3.0", + "clap_derive 4.1.0", + "clap_lex 0.3.1", "is-terminal", "once_cell", "strsim", @@ -918,9 +1028,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.0.21" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" dependencies = [ "heck", "proc-macro-error", @@ -940,9 +1050,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" dependencies = [ "os_str_bytes", ] @@ -1027,9 +1137,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" dependencies = [ "crossbeam-utils", ] @@ -1051,9 +1161,9 @@ dependencies = [ [[package]] name = "console" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b6515d269224923b26b5febea2ed42b2d5f2ce37284a4dd670fedd6cb8347a" +checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" dependencies = [ "encode_unicode", "lazy_static", @@ -1131,6 +1241,12 @@ dependencies = [ "libc", ] +[[package]] +name = "cpuid-bool" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" + [[package]] name = "cranelift-bforest" version = "0.88.2" @@ -1229,6 +1345,21 @@ dependencies = [ "wasmtime-types", ] +[[package]] +name = "crc" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + [[package]] name = "crc32fast" version = "1.3.2" @@ -1319,6 +1450,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "crypto-mac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +dependencies = [ + "generic-array 0.14.6", + "subtle", +] + [[package]] name = "crypto-mac" version = "0.11.1" @@ -1329,6 +1470,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "ctr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" +dependencies = [ + "cipher 0.2.5", +] + [[package]] name = "ctr" version = "0.8.0" @@ -1446,6 +1596,41 @@ dependencies = [ "zeroize", ] +[[package]] +name = "darling" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "data-encoding" version = "2.3.3" @@ -1479,9 +1664,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] +[[package]] +name = "der-parser" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" +dependencies = [ + "asn1-rs 0.3.1", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der-parser" +version = "8.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d4bc9b0db0a0df9ae64634ac5bdefb7afcb534e182275ca0beadbe486701c1" +dependencies = [ + "asn1-rs 0.5.1", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "derive_builder" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" +dependencies = [ + "derive_builder_core", + "syn", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -1610,6 +1855,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "displaydoc" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dkg" version = "0.2.0" @@ -1646,16 +1902,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "dns-parser" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" -dependencies = [ - "byteorder", - "quick-error", -] - [[package]] name = "downcast" version = "0.11.0" @@ -1721,9 +1967,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "signature", ] @@ -1775,6 +2021,8 @@ dependencies = [ "ff", "generic-array 0.14.6", "group", + "hkdf", + "pem-rfc7468", "pkcs8", "rand_core 0.6.4", "sec1", @@ -1877,7 +2125,7 @@ dependencies = [ "sha2 0.10.6", "sha3", "thiserror", - "uuid", + "uuid 0.8.2", ] [[package]] @@ -2383,7 +2631,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", ] @@ -2406,7 +2654,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-support", "frame-system", @@ -2429,28 +2677,25 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "Inflector", "array-bytes", "chrono", - "clap 4.0.32", + "clap 4.1.1", "comfy-table", "frame-benchmarking", "frame-support", "frame-system", "gethostname", "handlebars", - "hash-db", "itertools", - "kvdb", "lazy_static", "linked-hash-map", "log", - "memory-db", "parity-scale-codec", "rand 0.8.5", - "rand_pcg 0.3.1", + "rand_pcg", "sc-block-builder", "sc-cli", "sc-client-api", @@ -2460,7 +2705,6 @@ dependencies = [ "sc-sysinfo", "serde", "serde_json", - "serde_nanos", "sp-api", "sp-blockchain", "sp-core", @@ -2473,7 +2717,6 @@ dependencies = [ "sp-std", "sp-storage", "sp-trie", - "tempfile", "thiserror", "thousands", ] @@ -2481,7 +2724,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-support", "frame-system", @@ -2509,7 +2752,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "bitflags", "frame-metadata", @@ -2541,7 +2784,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "Inflector", "cfg-expr", @@ -2555,7 +2798,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -2567,7 +2810,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "proc-macro2", "quote", @@ -2577,7 +2820,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-support", "log", @@ -2595,7 +2838,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", "sp-api", @@ -2715,8 +2958,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" dependencies = [ "futures-io", - "rustls", - "webpki", + "rustls 0.20.8", + "webpki 0.22.0", ] [[package]] @@ -2800,10 +3043,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -2819,6 +3060,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "ghash" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" +dependencies = [ + "opaque-debug 0.3.0", + "polyval 0.4.5", +] + [[package]] name = "ghash" version = "0.4.4" @@ -2826,7 +3077,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" dependencies = [ "opaque-debug 0.3.0", - "polyval", + "polyval 0.5.3", ] [[package]] @@ -2997,6 +3248,16 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac 0.10.1", + "digest 0.9.0", +] + [[package]] name = "hmac" version = "0.11.0" @@ -3126,7 +3387,7 @@ dependencies = [ "http", "hyper", "log", - "rustls", + "rustls 0.20.8", "rustls-native-certs", "tokio", "tokio-rustls", @@ -3169,6 +3430,12 @@ dependencies = [ "cxx-build", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.2.3" @@ -3202,9 +3469,9 @@ dependencies = [ [[package]] name = "if-watch" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065c008e570a43c00de6aed9714035e5ea6a498c255323db9091722af6ee67dd" +checksum = "ba7abdbb86e485125dad06c2691e1e393bf3b08c7b743b43aa162a00fd39062e" dependencies = [ "async-io", "core-foundation", @@ -3215,6 +3482,7 @@ dependencies = [ "log", "rtnetlink", "system-configuration", + "tokio", "windows", ] @@ -3279,7 +3547,7 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" dependencies = [ - "console 0.15.4", + "console 0.15.5", "lazy_static", "number_prefix", "regex", @@ -3315,6 +3583,25 @@ dependencies = [ "num-traits", ] +[[package]] +name = "interceptor" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8a11ae2da61704edada656798b61c94b35ecac2c58eb955156987d5e6be90b" +dependencies = [ + "async-trait", + "bytes", + "log", + "rand 0.8.5", + "rtcp", + "rtp", + "thiserror", + "tokio", + "waitgroup", + "webrtc-srtp", + "webrtc-util", +] + [[package]] name = "io-lifetimes" version = "0.7.5" @@ -3323,9 +3610,9 @@ checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074" [[package]] name = "io-lifetimes" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" dependencies = [ "libc", "windows-sys 0.42.0", @@ -3351,9 +3638,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" +checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" [[package]] name = "is-terminal" @@ -3362,7 +3649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" dependencies = [ "hermit-abi 0.2.6", - "io-lifetimes 1.0.3", + "io-lifetimes 1.0.4", "rustix 0.36.6", "windows-sys 0.42.0", ] @@ -3617,16 +3904,15 @@ checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" [[package]] name = "libp2p" -version = "0.49.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec878fda12ebec479186b3914ebc48ff180fa4c51847e11a1a68bf65249e02c1" +checksum = "2e0a0d2f693675f49ded13c5d510c48b78069e23cbd9108d7ccd59f6dc568819" dependencies = [ "bytes", "futures", "futures-timer", "getrandom 0.2.8", "instant", - "lazy_static", "libp2p-core", "libp2p-dns", "libp2p-identify", @@ -3636,11 +3922,12 @@ dependencies = [ "libp2p-mplex", "libp2p-noise", "libp2p-ping", + "libp2p-quic", "libp2p-request-response", "libp2p-swarm", - "libp2p-swarm-derive", "libp2p-tcp", "libp2p-wasm-ext", + "libp2p-webrtc", "libp2p-websocket", "libp2p-yamux", "multiaddr", @@ -3651,9 +3938,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799676bb0807c788065e57551c6527d461ad572162b0519d1958946ff9e0539d" +checksum = "b6a8fcd392ff67af6cc3f03b1426c41f7f26b6b9aff2dc632c1c56dd649e571f" dependencies = [ "asn1_der", "bs58", @@ -3663,17 +3950,18 @@ dependencies = [ "futures", "futures-timer", "instant", - "lazy_static", "log", "multiaddr", "multihash", "multistream-select", + "once_cell", "parking_lot 0.12.1", "pin-project", "prost", "prost-build", "rand 0.8.5", "rw-stream-sink", + "sec1", "sha2 0.10.6", "smallvec", "thiserror", @@ -3684,9 +3972,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2322c9fb40d99101def6a01612ee30500c89abbbecb6297b3cd252903a4c1720" +checksum = "8e42a271c1b49f789b92f7fc87749fa79ce5c7bdc88cbdfacb818a4bca47fec5" dependencies = [ "futures", "libp2p-core", @@ -3698,9 +3986,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.40.0" +version = "0.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf9a121f699e8719bda2e6e9e9b6ddafc6cff4602471d6481c1067930ccb29b" +checksum = "c052d0026f4817b44869bfb6810f4e1112f43aec8553f2cb38881c524b563abf" dependencies = [ "asynchronous-codec", "futures", @@ -3719,9 +4007,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.41.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6721c200e2021f6c3fab8b6cf0272ead8912d871610ee194ebd628cecf428f22" +checksum = "2766dcd2be8c87d5e1f35487deb22d765f49c6ae1251b3633efe3b25698bd3d2" dependencies = [ "arrayvec 0.7.2", "asynchronous-codec", @@ -3747,12 +4035,11 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.41.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "761704e727f7d68d58d7bc2231eafae5fc1b9814de24290f126df09d4bd37a15" +checksum = "04f378264aade9872d6ccd315c0accc18be3a35d15fc1b9c36e5b6f983b62b5b" dependencies = [ "data-encoding", - "dns-parser", "futures", "if-watch", "libp2p-core", @@ -3762,14 +4049,15 @@ dependencies = [ "smallvec", "socket2", "tokio", + "trust-dns-proto", "void", ] [[package]] name = "libp2p-metrics" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee31b08e78b7b8bfd1c4204a9dd8a87b4fcdf6dafc57eb51701c1c264a81cb9" +checksum = "5ad8a64f29da86005c86a4d2728b8a0719e9b192f4092b609fd8790acb9dec55" dependencies = [ "libp2p-core", "libp2p-identify", @@ -3781,9 +4069,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692664acfd98652de739a8acbb0a0d670f1d67190a49be6b4395e22c37337d89" +checksum = "03805b44107aa013e7cbbfa5627b31c36cbedfdfb00603c0311998882bc4bace" dependencies = [ "asynchronous-codec", "bytes", @@ -3799,31 +4087,32 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.40.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048155686bd81fe6cb5efdef0c6290f25ad32a0a42e8f4f72625cf6a505a206f" +checksum = "a978cb57efe82e892ec6f348a536bfbd9fee677adbe5689d7a93ad3a9bffbf2e" dependencies = [ "bytes", "curve25519-dalek 3.2.0", "futures", - "lazy_static", "libp2p-core", "log", + "once_cell", "prost", "prost-build", "rand 0.8.5", "sha2 0.10.6", "snow", "static_assertions", - "x25519-dalek", + "thiserror", + "x25519-dalek 1.1.1", "zeroize", ] [[package]] name = "libp2p-ping" -version = "0.40.1" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7228b9318d34689521349a86eb39a3c3a802c9efc99a0568062ffb80913e3f91" +checksum = "929fcace45a112536e22b3dcfd4db538723ef9c3cb79f672b98be2cc8e25f37f" dependencies = [ "futures", "futures-timer", @@ -3836,10 +4125,31 @@ dependencies = [ ] [[package]] -name = "libp2p-request-response" -version = "0.22.1" +name = "libp2p-quic" +version = "0.7.0-alpha" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8827af16a017b65311a410bb626205a9ad92ec0473967618425039fa5231adc1" +checksum = "01e7c867e95c8130667b24409d236d37598270e6da69b3baf54213ba31ffca59" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "if-watch", + "libp2p-core", + "libp2p-tls", + "log", + "parking_lot 0.12.1", + "quinn-proto", + "rand 0.8.5", + "rustls 0.20.8", + "thiserror", + "tokio", +] + +[[package]] +name = "libp2p-request-response" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3236168796727bfcf4927f766393415361e2c644b08bedb6a6b13d957c9a4884" dependencies = [ "async-trait", "bytes", @@ -3855,9 +4165,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.40.1" +version = "0.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46d13df7c37807965d82930c0e4b04a659efcb6cca237373b206043db5398ecf" +checksum = "b2a35472fe3276b3855c00f1c032ea8413615e030256429ad5349cdf67c6e1a0" dependencies = [ "either", "fnv", @@ -3865,19 +4175,21 @@ dependencies = [ "futures-timer", "instant", "libp2p-core", + "libp2p-swarm-derive", "log", "pin-project", "rand 0.8.5", "smallvec", "thiserror", + "tokio", "void", ] [[package]] name = "libp2p-swarm-derive" -version = "0.30.1" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0eddc4497a8b5a506013c40e8189864f9c3a00db2b25671f428ae9007f3ba32" +checksum = "9d527d5827582abd44a6d80c07ff8b50b4ee238a8979e05998474179e79dc400" dependencies = [ "heck", "quote", @@ -3886,9 +4198,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9839d96761491c6d3e238e70554b856956fca0ab60feb9de2cd08eed4473fa92" +checksum = "b4b257baf6df8f2df39678b86c578961d48cc8b68642a12f0f763f56c8e5858d" dependencies = [ "futures", "futures-timer", @@ -3901,10 +4213,28 @@ dependencies = [ ] [[package]] -name = "libp2p-wasm-ext" -version = "0.37.0" +name = "libp2p-tls" +version = "0.1.0-alpha" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b5b8e7a73e379e47b1b77f8a82c4721e97eca01abcd18e9cd91a23ca6ce97" +checksum = "f7905ce0d040576634e8a3229a7587cc8beab83f79db6023800f1792895defa8" +dependencies = [ + "futures", + "futures-rustls", + "libp2p-core", + "rcgen 0.10.0", + "ring", + "rustls 0.20.8", + "thiserror", + "webpki 0.22.0", + "x509-parser 0.14.0", + "yasna", +] + +[[package]] +name = "libp2p-wasm-ext" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb1a35299860e0d4b3c02a3e74e3b293ad35ae0cee8a056363b0c862d082069" dependencies = [ "futures", "js-sys", @@ -3915,10 +4245,41 @@ dependencies = [ ] [[package]] -name = "libp2p-websocket" -version = "0.39.0" +name = "libp2p-webrtc" +version = "0.4.0-alpha" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3758ae6f89b2531a24b6d9f5776bda6a626b60a57600d7185d43dfa75ca5ecc4" +checksum = "cdb6cd86dd68cba72308ea05de1cebf3ba0ae6e187c40548167955d4e3970f6a" +dependencies = [ + "async-trait", + "asynchronous-codec", + "bytes", + "futures", + "futures-timer", + "hex", + "if-watch", + "libp2p-core", + "libp2p-noise", + "log", + "multihash", + "prost", + "prost-build", + "prost-codec", + "rand 0.8.5", + "rcgen 0.9.3", + "serde", + "stun", + "thiserror", + "tinytemplate", + "tokio", + "tokio-util", + "webrtc", +] + +[[package]] +name = "libp2p-websocket" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d705506030d5c0aaf2882437c70dab437605f21c5f9811978f694e6917a3b54" dependencies = [ "either", "futures", @@ -3935,9 +4296,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.41.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6874d66543c4f7e26e3b8ca9a6bead351563a13ab4fafd43c7927f7c0d6c12" +checksum = "4f63594a0aa818642d9d4915c791945053877253f08a3626f13416b5cd928a29" dependencies = [ "futures", "libp2p-core", @@ -4425,14 +4786,14 @@ dependencies = [ [[package]] name = "multiaddr" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c580bfdd8803cce319b047d239559a22f809094aaea4ac13902a1fdcfcd4261" +checksum = "a4aebdb21e90f81d13ed01dc84123320838e53963c2ca94b60b305d3fa64f31e" dependencies = [ "arrayref", - "bs58", "byteorder", "data-encoding", + "multibase", "multihash", "percent-encoding", "serde", @@ -4630,11 +4991,11 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92b654097027250401127914afb37cb1f311df6610a9891ff07a757e94199027" dependencies = [ - "async-io", "bytes", "futures", "libc", "log", + "tokio", ] [[package]] @@ -4652,6 +5013,7 @@ dependencies = [ "bitflags", "cfg-if", "libc", + "memoffset 0.6.5", ] [[package]] @@ -4662,9 +5024,9 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nom" -version = "7.1.2" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", @@ -4768,13 +5130,31 @@ dependencies = [ [[package]] name = "object" -version = "0.30.1" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d864c91689fdc196779b98dba0aceac6118594c2df6ee5d943eb6a8df4d107a" +checksum = "2b8c786513eb403643f2a88c244c2aaa270ef2153f55094587d0c48a3cf22a83" dependencies = [ "memchr", ] +[[package]] +name = "oid-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" +dependencies = [ + "asn1-rs 0.3.1", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs 0.5.1", +] + [[package]] name = "once_cell" version = "1.17.0" @@ -4880,6 +5260,17 @@ dependencies = [ "sha2 0.10.6", ] +[[package]] +name = "p384" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +dependencies = [ + "ecdsa", + "elliptic-curve", + "sha2 0.10.6", +] + [[package]] name = "packed_simd_2" version = "0.3.8" @@ -4893,7 +5284,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-benchmarking", "frame-support", @@ -4908,7 +5299,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-benchmarking", "frame-support", @@ -4923,7 +5314,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-support", "frame-system", @@ -4957,7 +5348,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-benchmarking", "frame-support", @@ -4975,7 +5366,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-support", "frame-system", @@ -4991,7 +5382,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -5007,7 +5398,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -5098,7 +5489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.5", + "parking_lot_core 0.9.6", ] [[package]] @@ -5117,9 +5508,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" dependencies = [ "cfg-if", "libc", @@ -5151,15 +5542,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" -[[package]] -name = "pbkdf2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" -dependencies = [ - "crypto-mac 0.8.0", -] - [[package]] name = "pbkdf2" version = "0.8.0" @@ -5187,6 +5569,24 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.2.0" @@ -5195,9 +5595,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6e86fb9e7026527a0d46bc308b841d73170ef8f443e1807f6ef88526a816d4" +checksum = "4257b4a04d91f7e9e6290be5d3da4804dd5784fafde3a497d73eb2b4a158c30a" dependencies = [ "thiserror", "ucd-trie", @@ -5205,9 +5605,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96504449aa860c8dcde14f9fba5c58dc6658688ca1fe363589d6327b8662c603" +checksum = "241cda393b0cdd65e62e07e12454f1f25d57017dcc514b1514cd3c4645e3a0a6" dependencies = [ "pest", "pest_generator", @@ -5215,9 +5615,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "798e0220d1111ae63d66cb66a5dcb3fc2d986d520b98e49e1852bfdb11d7c5e7" +checksum = "46b53634d8c8196302953c74d5352f33d0c512a9499bd2ce468fc9f4128fa27c" dependencies = [ "pest", "pest_meta", @@ -5228,13 +5628,13 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "984298b75898e30a843e278a9f2452c31e349a073a0ce6fd950a12a74464e065" +checksum = "0ef4f1332a8d4678b41966bb4cc1d0676880e84183a1ecc3f4b69f03e99c7a51" dependencies = [ "once_cell", "pest", - "sha1", + "sha2 0.10.6", ] [[package]] @@ -5398,6 +5798,17 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "polyval" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" +dependencies = [ + "cpuid-bool", + "opaque-debug 0.3.0", + "universal-hash", +] + [[package]] name = "polyval" version = "0.5.3" @@ -5565,9 +5976,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c01db6702aa05baa3f57dec92b8eeeeb4cb19e894e73996b32a4093289e54592" +checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" dependencies = [ "bytes", "prost-derive", @@ -5575,9 +5986,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5320c680de74ba083512704acb90fe00f28f79207286a848e730c45dd73ed6" +checksum = "a3f8ad728fb08fe212df3c05169e940fbb6d9d16a877ddde14644a983ba2012e" dependencies = [ "bytes", "heck", @@ -5597,9 +6008,9 @@ dependencies = [ [[package]] name = "prost-codec" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "011ae9ff8359df7915f97302d591cdd9e0e27fbd5a4ddc5bd13b71079bb20987" +checksum = "0dc34979ff898b6e141106178981ce2596c387ea6e62533facfc61a37fc879c0" dependencies = [ "asynchronous-codec", "bytes", @@ -5610,9 +6021,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8842bad1a5419bca14eac663ba798f6bc19c413c2fdceb5f3ba3b0932d96720" +checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" dependencies = [ "anyhow", "itertools", @@ -5623,9 +6034,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "017f79637768cde62820bc2d4fe0e45daaa027755c323ad077767c6c5f173091" +checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" dependencies = [ "bytes", "prost", @@ -5657,6 +6068,24 @@ dependencies = [ "pin-project-lite 0.1.12", ] +[[package]] +name = "quinn-proto" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4ced82a24bb281af338b9e8f94429b6eca01b4e66d899f40031f074e74c9" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls 0.20.8", + "slab", + "thiserror", + "tinyvec", + "tracing", + "webpki 0.22.0", +] + [[package]] name = "quote" version = "1.0.23" @@ -5689,7 +6118,6 @@ dependencies = [ "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc", - "rand_pcg 0.2.1", ] [[package]] @@ -5760,15 +6188,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "rand_pcg" version = "0.3.1" @@ -5806,6 +6225,31 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "rcgen" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" +dependencies = [ + "pem", + "ring", + "time 0.3.17", + "x509-parser 0.13.2", + "yasna", +] + +[[package]] +name = "rcgen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +dependencies = [ + "pem", + "ring", + "time 0.3.17", + "yasna", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -5860,9 +6304,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "aho-corasick", "memchr", @@ -5918,7 +6362,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.9", - "rustls", + "rustls 0.20.8", "rustls-pemfile", "serde", "serde_json", @@ -6022,19 +6466,30 @@ dependencies = [ "winapi", ] +[[package]] +name = "rtcp" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1919efd6d4a6a85d13388f9487549bb8e359f17198cc03ffd72f79b553873691" +dependencies = [ + "bytes", + "thiserror", + "webrtc-util", +] + [[package]] name = "rtnetlink" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" dependencies = [ - "async-global-executor", "futures", "log", "netlink-packet-route", "netlink-proto", "nix", "thiserror", + "tokio", ] [[package]] @@ -6047,6 +6502,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "rtp" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a095411ff00eed7b12e4c6a118ba984d113e1079582570d56a5ee723f11f80" +dependencies = [ + "async-trait", + "bytes", + "rand 0.8.5", + "serde", + "thiserror", + "webrtc-util", +] + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -6074,6 +6543,15 @@ dependencies = [ "semver 1.0.16", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + [[package]] name = "rustix" version = "0.35.13" @@ -6096,7 +6574,7 @@ checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" dependencies = [ "bitflags", "errno", - "io-lifetimes 1.0.3", + "io-lifetimes 1.0.4", "libc", "linux-raw-sys 0.1.4", "windows-sys 0.42.0", @@ -6104,14 +6582,27 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.7" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.1", + "log", + "ring", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log", "ring", - "sct", - "webpki", + "sct 0.7.0", + "webpki 0.22.0", ] [[package]] @@ -6128,11 +6619,11 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64 0.13.1", + "base64 0.21.0", ] [[package]] @@ -6179,7 +6670,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "log", "sp-core", @@ -6190,7 +6681,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "futures", "futures-timer", @@ -6213,7 +6704,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -6229,11 +6720,9 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ - "impl-trait-for-tuples", "memmap2", - "parity-scale-codec", "sc-chain-spec-derive", "sc-network-common", "sc-telemetry", @@ -6246,7 +6735,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6257,18 +6746,18 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "array-bytes", "chrono", - "clap 4.0.32", + "clap 4.1.1", "fdlimit", "futures", "libp2p", "log", "names", "parity-scale-codec", - "rand 0.7.3", + "rand 0.8.5", "regex", "rpassword", "sc-client-api", @@ -6297,11 +6786,10 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "fnv", "futures", - "hash-db", "log", "parity-scale-codec", "parking_lot 0.12.1", @@ -6318,14 +6806,13 @@ dependencies = [ "sp-runtime", "sp-state-machine", "sp-storage", - "sp-trie", "substrate-prometheus-endpoint", ] [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "hash-db", "kvdb", @@ -6350,7 +6837,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "futures", @@ -6375,7 +6862,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "lru", "parity-scale-codec", @@ -6399,7 +6886,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", @@ -6412,7 +6899,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "log", "sc-allocator", @@ -6425,7 +6912,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "cfg-if", "libc", @@ -6442,7 +6929,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "ansi_term", "futures", @@ -6450,7 +6937,6 @@ dependencies = [ "log", "sc-client-api", "sc-network-common", - "sc-transaction-pool-api", "sp-blockchain", "sp-runtime", ] @@ -6458,7 +6944,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "array-bytes", "async-trait", @@ -6473,30 +6959,25 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "array-bytes", "async-trait", "asynchronous-codec", - "bitflags", + "backtrace", "bytes", - "cid", "either", "fnv", - "fork-tree", "futures", "futures-timer", "ip_network", "libp2p", - "linked-hash-map", - "linked_hash_set", "log", "lru", "parity-scale-codec", "parking_lot 0.12.1", "pin-project", - "prost", - "rand 0.7.3", + "rand 0.8.5", "sc-block-builder", "sc-client-api", "sc-consensus", @@ -6520,7 +7001,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "cid", "futures", @@ -6534,13 +7015,12 @@ dependencies = [ "sp-runtime", "thiserror", "unsigned-varint", - "void", ] [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "bitflags", @@ -6566,7 +7046,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "ahash", "futures", @@ -6584,7 +7064,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "array-bytes", "futures", @@ -6605,7 +7085,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "array-bytes", "async-trait", @@ -6637,17 +7117,17 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "array-bytes", "futures", - "hex", "libp2p", "log", "parity-scale-codec", "pin-project", "sc-network-common", "sc-peerset", + "sc-utils", "sp-consensus", "sp-runtime", "substrate-prometheus-endpoint", @@ -6656,7 +7136,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "array-bytes", "bytes", @@ -6670,7 +7150,7 @@ dependencies = [ "once_cell", "parity-scale-codec", "parking_lot 0.12.1", - "rand 0.7.3", + "rand 0.8.5", "sc-client-api", "sc-network-common", "sc-peerset", @@ -6686,7 +7166,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "futures", "libp2p", @@ -6699,7 +7179,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -6708,10 +7188,9 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "futures", - "hash-db", "jsonrpsee", "log", "parity-scale-codec", @@ -6738,13 +7217,10 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ - "futures", "jsonrpsee", - "log", "parity-scale-codec", - "parking_lot 0.12.1", "sc-chain-spec", "sc-transaction-pool-api", "scale-info", @@ -6753,7 +7229,6 @@ dependencies = [ "sp-core", "sp-rpc", "sp-runtime", - "sp-tracing", "sp-version", "thiserror", ] @@ -6761,9 +7236,8 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ - "futures", "http", "jsonrpsee", "log", @@ -6777,39 +7251,45 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ + "array-bytes", "futures", + "futures-util", "hex", "jsonrpsee", + "log", "parity-scale-codec", + "parking_lot 0.12.1", "sc-chain-spec", + "sc-client-api", "sc-transaction-pool-api", "serde", "sp-api", "sp-blockchain", "sp-core", "sp-runtime", + "sp-version", "thiserror", + "tokio-stream", ] [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "directories", "exit-future", "futures", "futures-timer", - "hash-db", "jsonrpsee", "log", "parity-scale-codec", "parking_lot 0.12.1", "pin-project", - "rand 0.7.3", + "rand 0.8.5", "sc-block-builder", "sc-chain-spec", "sc-client-api", @@ -6837,19 +7317,15 @@ dependencies = [ "serde", "serde_json", "sp-api", - "sp-application-crypto", - "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-core", "sp-externalities", - "sp-inherents", "sp-keystore", "sp-runtime", "sp-session", "sp-state-machine", "sp-storage", - "sp-tracing", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", @@ -6866,25 +7342,24 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "sc-client-api", "sp-core", ] [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "futures", "libc", "log", - "rand 0.7.3", - "rand_pcg 0.2.1", + "rand 0.8.5", + "rand_pcg", "regex", "sc-telemetry", "serde", @@ -6897,7 +7372,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "chrono", "futures", @@ -6905,7 +7380,8 @@ dependencies = [ "log", "parking_lot 0.12.1", "pin-project", - "rand 0.7.3", + "rand 0.8.5", + "sc-utils", "serde", "serde_json", "thiserror", @@ -6947,7 +7423,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "ansi_term", "atty", @@ -6978,7 +7454,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6989,7 +7465,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "futures", @@ -7015,7 +7491,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "futures", @@ -7029,8 +7505,9 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ + "backtrace", "futures", "futures-timer", "lazy_static", @@ -7067,12 +7544,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] @@ -7131,6 +7607,16 @@ dependencies = [ "sha2 0.10.6", ] +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sct" version = "0.7.0" @@ -7141,6 +7627,18 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sdp" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d22a5ef407871893fd72b4562ee15e4742269b173959db4b8df6f538c414e13" +dependencies = [ + "rand 0.8.5", + "substring", + "thiserror", + "url", +] + [[package]] name = "sec1" version = "0.3.0" @@ -7157,9 +7655,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9512ffd81e3a3503ed401f79c33168b9148c75038956039166cd750eaa037c3" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ "secp256k1-sys", ] @@ -7240,7 +7738,7 @@ name = "serai-node" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.0.32", + "clap 4.1.1", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", @@ -7391,15 +7889,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_nanos" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e44969a61f5d316be20a42ff97816efb3b407a924d06824c3d8a49fa8450de0e" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -7567,7 +8056,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "774d05a3edae07ce6d68ea6984f3c05e9bba8927e3dd591e3b479e5b03213d0d" dependencies = [ - "aes-gcm", + "aes-gcm 0.9.4", "blake2", "chacha20poly1305", "curve25519-dalek 4.0.0-pre.5", @@ -7621,7 +8110,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "hash-db", "log", @@ -7639,7 +8128,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "blake2", "proc-macro-crate", @@ -7651,7 +8140,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", "scale-info", @@ -7664,14 +8153,13 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "integer-sqrt", "num-traits", "parity-scale-codec", "scale-info", "serde", - "sp-debug-derive", "sp-std", "static_assertions", ] @@ -7679,7 +8167,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", "sp-api", @@ -7691,7 +8179,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "futures", "log", @@ -7709,11 +8197,10 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "futures", - "futures-timer", "log", "parity-scale-codec", "sp-core", @@ -7728,13 +8215,12 @@ dependencies = [ [[package]] name = "sp-core" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "array-bytes", "base58 0.2.0", "bitflags", "blake2", - "byteorder", "dyn-clonable", "ed25519-zebra", "futures", @@ -7745,11 +8231,10 @@ dependencies = [ "libsecp256k1", "log", "merlin 2.0.1", - "num-traits", "parity-scale-codec", "parking_lot 0.12.1", "primitive-types", - "rand 0.7.3", + "rand 0.8.5", "regex", "scale-info", "schnorrkel", @@ -7766,14 +8251,13 @@ dependencies = [ "substrate-bip39", "thiserror", "tiny-bip39", - "wasmi", "zeroize", ] [[package]] name = "sp-core-hashing" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "blake2", "byteorder", @@ -7787,7 +8271,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "proc-macro2", "quote", @@ -7798,7 +8282,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -7807,7 +8291,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "proc-macro2", "quote", @@ -7817,7 +8301,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "environmental", "parity-scale-codec", @@ -7828,7 +8312,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "finality-grandpa", "log", @@ -7846,7 +8330,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -7860,16 +8344,15 @@ dependencies = [ [[package]] name = "sp-io" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "bytes", + "ed25519", "ed25519-dalek", "futures", - "hash-db", "libsecp256k1", "log", "parity-scale-codec", - "parking_lot 0.12.1", "secp256k1", "sp-core", "sp-externalities", @@ -7879,7 +8362,6 @@ dependencies = [ "sp-std", "sp-tracing", "sp-trie", - "sp-wasm-interface", "tracing", "tracing-core", ] @@ -7887,7 +8369,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "lazy_static", "sp-core", @@ -7898,7 +8380,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "futures", @@ -7915,7 +8397,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "thiserror", "zstd", @@ -7924,7 +8406,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "sp-api", "sp-core", @@ -7934,7 +8416,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "backtrace", "lazy_static", @@ -7944,7 +8426,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "rustc-hash", "serde", @@ -7954,7 +8436,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "either", "hash256-std-hasher", @@ -7962,7 +8444,7 @@ dependencies = [ "log", "parity-scale-codec", "paste", - "rand 0.7.3", + "rand 0.8.5", "scale-info", "serde", "sp-application-crypto", @@ -7976,7 +8458,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -7994,7 +8476,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "Inflector", "proc-macro-crate", @@ -8006,7 +8488,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", "scale-info", @@ -8020,7 +8502,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", "scale-info", @@ -8032,14 +8514,13 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "hash-db", "log", - "num-traits", "parity-scale-codec", "parking_lot 0.12.1", - "rand 0.7.3", + "rand 0.8.5", "smallvec", "sp-core", "sp-externalities", @@ -8048,18 +8529,17 @@ dependencies = [ "sp-trie", "thiserror", "tracing", - "trie-root", ] [[package]] name = "sp-std" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" [[package]] name = "sp-storage" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8081,13 +8561,12 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "futures-timer", "log", "parity-scale-codec", - "sp-api", "sp-inherents", "sp-runtime", "sp-std", @@ -8097,7 +8576,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", "sp-std", @@ -8109,7 +8588,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "sp-api", "sp-runtime", @@ -8118,7 +8597,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "async-trait", "log", @@ -8134,7 +8613,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "ahash", "hash-db", @@ -8157,7 +8636,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8174,7 +8653,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -8185,7 +8664,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "impl-trait-for-tuples", "log", @@ -8198,9 +8677,8 @@ dependencies = [ [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ - "impl-trait-for-tuples", "parity-scale-codec", "scale-info", "serde", @@ -8336,6 +8814,25 @@ dependencies = [ "syn", ] +[[package]] +name = "stun" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7e94b1ec00bad60e6410e058b52f1c66de3dc5fe4d62d09b3e52bb7d3b73e25" +dependencies = [ + "base64 0.13.1", + "crc", + "lazy_static", + "md-5 0.10.5", + "rand 0.8.5", + "ring", + "subtle", + "thiserror", + "tokio", + "url", + "webrtc-util", +] + [[package]] name = "substrate-bip39" version = "0.4.4" @@ -8352,7 +8849,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "platforms 2.0.0", ] @@ -8360,17 +8857,15 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "frame-system-rpc-runtime-api", "futures", "jsonrpsee", "log", "parity-scale-codec", - "sc-client-api", "sc-rpc-api", "sc-transaction-pool-api", - "serde_json", "sp-api", "sp-block-builder", "sp-blockchain", @@ -8381,9 +8876,8 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ - "futures-util", "hyper", "log", "prometheus", @@ -8394,7 +8888,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#6dc38b0ba11dff62c1042ab0fa21d0b55a64bf6e" +source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" dependencies = [ "ansi_term", "build-helper", @@ -8408,6 +8902,15 @@ dependencies = [ "wasm-opt", ] +[[package]] +name = "substring" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +dependencies = [ + "autocfg", +] + [[package]] name = "subtle" version = "2.4.1" @@ -8416,9 +8919,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "svm-rs" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4cdcf91153dc0e4e0637f26f042ada32a3b552bc8115935c7bf96f80132b0a" +checksum = "e18bbb2b229a2cc0d8ba58603adb0e460ad49a3451b1540fd6f7a5d37fd03b80" dependencies = [ "anyhow", "cfg-if", @@ -8541,9 +9044,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -8665,17 +9168,17 @@ dependencies = [ [[package]] name = "tiny-bip39" -version = "0.8.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" dependencies = [ "anyhow", - "hmac 0.8.1", + "hmac 0.12.1", "once_cell", - "pbkdf2 0.4.0", - "rand 0.7.3", + "pbkdf2 0.11.0", + "rand 0.8.5", "rustc-hash", - "sha2 0.9.9", + "sha2 0.10.6", "thiserror", "unicode-normalization", "wasm-bindgen", @@ -8691,6 +9194,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -8753,9 +9266,9 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls", + "rustls 0.20.8", "tokio", - "webpki", + "webpki 0.22.0", ] [[package]] @@ -8767,6 +9280,7 @@ dependencies = [ "futures-core", "pin-project-lite 0.2.9", "tokio", + "tokio-util", ] [[package]] @@ -8962,6 +9476,7 @@ dependencies = [ "lazy_static", "rand 0.8.5", "smallvec", + "socket2", "thiserror", "tinyvec", "tokio", @@ -9001,6 +9516,25 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4f195fd851901624eee5a58c4bb2b4f06399148fcd0ed336e6f1cb60a9881df" +[[package]] +name = "turn" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4712ee30d123ec7ae26d1e1b218395a16c87cdbaf4b3925d170d684af62ea5e8" +dependencies = [ + "async-trait", + "base64 0.13.1", + "futures", + "log", + "md-5 0.10.5", + "rand 0.8.5", + "ring", + "stun", + "thiserror", + "tokio", + "webrtc-util", +] + [[package]] name = "twox-hash" version = "1.6.3" @@ -9125,6 +9659,15 @@ dependencies = [ "serde", ] +[[package]] +name = "uuid" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +dependencies = [ + "getrandom 0.2.8", +] + [[package]] name = "validator-sets-pallet" version = "0.1.0" @@ -9172,6 +9715,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "waitgroup" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292" +dependencies = [ + "atomic-waker", +] + [[package]] name = "waker-fn" version = "1.1.0" @@ -9570,6 +10122,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "webpki" version = "0.22.0" @@ -9586,7 +10148,219 @@ version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ - "webpki", + "webpki 0.22.0", +] + +[[package]] +name = "webrtc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3bc9049bdb2cea52f5fd4f6f728184225bdb867ed0dc2410eab6df5bdd67bb" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "hex", + "interceptor", + "lazy_static", + "log", + "rand 0.8.5", + "rcgen 0.9.3", + "regex", + "ring", + "rtcp", + "rtp", + "rustls 0.19.1", + "sdp", + "serde", + "serde_json", + "sha2 0.10.6", + "stun", + "thiserror", + "time 0.3.17", + "tokio", + "turn", + "url", + "waitgroup", + "webrtc-data", + "webrtc-dtls", + "webrtc-ice", + "webrtc-mdns", + "webrtc-media", + "webrtc-sctp", + "webrtc-srtp", + "webrtc-util", +] + +[[package]] +name = "webrtc-data" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef36a4d12baa6e842582fe9ec16a57184ba35e1a09308307b67d43ec8883100" +dependencies = [ + "bytes", + "derive_builder", + "log", + "thiserror", + "tokio", + "webrtc-sctp", + "webrtc-util", +] + +[[package]] +name = "webrtc-dtls" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7021987ae0a2ed6c8cd33f68e98e49bb6e74ffe9543310267b48a1bbe3900e5f" +dependencies = [ + "aes 0.6.0", + "aes-gcm 0.8.0", + "async-trait", + "bincode", + "block-modes", + "byteorder", + "ccm", + "curve25519-dalek 3.2.0", + "der-parser 8.1.0", + "elliptic-curve", + "hkdf", + "hmac 0.10.1", + "log", + "oid-registry 0.6.1", + "p256", + "p384", + "rand 0.8.5", + "rand_core 0.6.4", + "rcgen 0.9.3", + "ring", + "rustls 0.19.1", + "sec1", + "serde", + "sha-1", + "sha2 0.9.9", + "signature", + "subtle", + "thiserror", + "tokio", + "webpki 0.21.4", + "webrtc-util", + "x25519-dalek 2.0.0-pre.1", + "x509-parser 0.13.2", +] + +[[package]] +name = "webrtc-ice" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494483fbb2f5492620871fdc78b084aed8807377f6e3fe88b2e49f0a9c9c41d7" +dependencies = [ + "arc-swap", + "async-trait", + "crc", + "log", + "rand 0.8.5", + "serde", + "serde_json", + "stun", + "thiserror", + "tokio", + "turn", + "url", + "uuid 1.2.2", + "waitgroup", + "webrtc-mdns", + "webrtc-util", +] + +[[package]] +name = "webrtc-mdns" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" +dependencies = [ + "log", + "socket2", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-media" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a3c157a040324e5049bcbd644ffc9079e6738fa2cfab2bcff64e5cc4c00d7" +dependencies = [ + "byteorder", + "bytes", + "derive_builder", + "displaydoc", + "rand 0.8.5", + "rtp", + "thiserror", + "webrtc-util", +] + +[[package]] +name = "webrtc-sctp" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d47adcd9427eb3ede33d5a7f3424038f63c965491beafcc20bc650a2f6679c0" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "crc", + "log", + "rand 0.8.5", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-srtp" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6183edc4c1c6c0175f8812eefdce84dfa0aea9c3ece71c2bf6ddd3c964de3da5" +dependencies = [ + "aead 0.4.3", + "aes 0.7.5", + "aes-gcm 0.9.4", + "async-trait", + "byteorder", + "bytes", + "ctr 0.8.0", + "hmac 0.11.0", + "log", + "rtcp", + "rtp", + "sha-1", + "subtle", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-util" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" +dependencies = [ + "async-trait", + "bitflags", + "bytes", + "cc", + "ipnet", + "lazy_static", + "libc", + "log", + "nix", + "rand 0.8.5", + "thiserror", + "tokio", + "winapi", ] [[package]] @@ -9679,19 +10453,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_x86_64_msvc 0.42.1", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" @@ -9707,9 +10481,9 @@ checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" @@ -9725,9 +10499,9 @@ checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" @@ -9743,9 +10517,9 @@ checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" @@ -9761,15 +10535,15 @@ checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" @@ -9785,9 +10559,9 @@ checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "winreg" @@ -9836,6 +10610,54 @@ dependencies = [ "zeroize", ] +[[package]] +name = "x25519-dalek" +version = "2.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" +dependencies = [ + "curve25519-dalek 3.2.0", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "x509-parser" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" +dependencies = [ + "asn1-rs 0.3.1", + "base64 0.13.1", + "data-encoding", + "der-parser 7.0.0", + "lazy_static", + "nom", + "oid-registry 0.4.0", + "ring", + "rusticata-macros", + "thiserror", + "time 0.3.17", +] + +[[package]] +name = "x509-parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +dependencies = [ + "asn1-rs 0.5.1", + "base64 0.13.1", + "data-encoding", + "der-parser 8.1.0", + "lazy_static", + "nom", + "oid-registry 0.6.1", + "rusticata-macros", + "thiserror", + "time 0.3.17", +] + [[package]] name = "yamux" version = "0.10.2" @@ -9856,6 +10678,15 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yasna" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aed2e7a52e3744ab4d0c05c20aa065258e84c49fd4226f5191b2ed29712710b4" +dependencies = [ + "time 0.3.17", +] + [[package]] name = "zalloc" version = "0.1.0" @@ -9925,10 +10756,11 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.4+zstd.1.5.2" +version = "2.0.5+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa202f2ef00074143e219d15b62ffc317d17cc33909feac471c044087cad7b0" +checksum = "edc50ffce891ad571e9f9afe5039c4837bede781ac4bb13052ed7ae695518596" dependencies = [ "cc", "libc", + "pkg-config", ] From 19ab49cb8cdf2f32abaf8084f1743b6775f8decc Mon Sep 17 00:00:00 2001 From: VRx <106933224+vrx00@users.noreply.github.com> Date: Mon, 16 Jan 2023 16:51:50 +0100 Subject: [PATCH 28/74] delete compromised key from dockerfile (#231) --- deploy/coins/bitcoin/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/coins/bitcoin/Dockerfile b/deploy/coins/bitcoin/Dockerfile index 8bd04599..75016e9c 100644 --- a/deploy/coins/bitcoin/Dockerfile +++ b/deploy/coins/bitcoin/Dockerfile @@ -22,7 +22,7 @@ RUN wget https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/bitcoin-${B # Serai recognizes the builder keys for 16/17 signatures # from the 23.0 release ENV KEYS 152812300785C96444D3334D17565732E08E5E41 0AD83877C1F0CD1EE9BD660AD7CC770B81FD22A8 590B7292695AFFA5B672CBB2E13FC145CD3F4304 948444FCE03B05BA5AB0591EC37B1C1D44C786EE 9EDAFF80E080659604F4A76B2EBB056FD847F8A7 E777299FC265DD04793070EB944D35F9AC3DB76A F4FC70F07310028424EFC20A8E4256593F177720 D1DBF2C4B96F2DEBF4C16654410108112E7EA81F -ENV KEYS2 4DAF18FE948E7A965B30F9457E296D555E7F63A7 28E72909F1717FE9607754F8A7BEB2621678D37D 74E2DEF5D77260B98BC19438099BAD163C70FBFA 71A3B16735405025D447E8F274810B012346C9A6 E463A93F5F3117EEDE6C7316BD02942421F4889F 9D3CC86A72F8494342EA5FD10A41BDC3F4FAFF1C 287AE4CA1187C68C08B49CB2D11BD4F33F1DB499 F9A8737BF4FF5C89C903DF31DD78544CF91B1514 +ENV KEYS2 4DAF18FE948E7A965B30F9457E296D555E7F63A7 28E72909F1717FE9607754F8A7BEB2621678D37D 74E2DEF5D77260B98BC19438099BAD163C70FBFA 71A3B16735405025D447E8F274810B012346C9A6 9D3CC86A72F8494342EA5FD10A41BDC3F4FAFF1C 287AE4CA1187C68C08B49CB2D11BD4F33F1DB499 F9A8737BF4FF5C89C903DF31DD78544CF91B1514 # Use hardcoded prints to get keys from servers. 2 Different servers used. RUN gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys ${KEYS} \ From a1ecdbf2f38c28b436a3e7fef4314803d7ad484b Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 16 Jan 2023 15:52:11 -0500 Subject: [PATCH 29/74] Update substrate/ to latest substrate --- substrate/runtime/src/lib.rs | 1 + substrate/tendermint/client/src/authority/mod.rs | 5 +---- substrate/tendermint/client/src/block_import.rs | 6 ++---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 3e39aba6..2f792076 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -184,6 +184,7 @@ impl pallet_assets::Config for Runtime { type ApprovalDeposit = ConstU64<0>; // Unused hooks + type CallbackHandle = (); type Freezer = (); type Extra = (); diff --git a/substrate/tendermint/client/src/authority/mod.rs b/substrate/tendermint/client/src/authority/mod.rs index 09242fce..519dbd72 100644 --- a/substrate/tendermint/client/src/authority/mod.rs +++ b/substrate/tendermint/client/src/authority/mod.rs @@ -21,7 +21,6 @@ use sp_runtime::{ Digest, }; use sp_blockchain::HeaderBackend; -use sp_api::BlockId; use sp_consensus::{Error, BlockOrigin, Proposer, Environment}; use sc_consensus::import_queue::IncomingBlock; @@ -200,9 +199,7 @@ impl TendermintAuthority { }; // Get our first proposal - let proposal = authority - .get_proposal(&import.client.header(BlockId::Hash(last_hash)).unwrap().unwrap()) - .await; + let proposal = authority.get_proposal(&import.client.header(last_hash).unwrap().unwrap()).await; // Create the gossip network // This has to be spawning the machine, else gossip fails for some reason diff --git a/substrate/tendermint/client/src/block_import.rs b/substrate/tendermint/client/src/block_import.rs index 681fbd8c..84fc8dab 100644 --- a/substrate/tendermint/client/src/block_import.rs +++ b/substrate/tendermint/client/src/block_import.rs @@ -2,7 +2,6 @@ use std::{marker::PhantomData, sync::Arc, collections::HashMap}; use async_trait::async_trait; -use sp_api::BlockId; use sp_runtime::traits::{Header, Block}; use sp_blockchain::{BlockStatus, HeaderBackend, Backend as BlockchainBackend}; use sp_consensus::{Error, CacheKeyId, BlockOrigin, SelectChain}; @@ -15,13 +14,12 @@ use crate::{TendermintValidator, tendermint::TendermintImport}; impl TendermintImport { fn check_already_in_chain(&self, hash: ::Hash) -> bool { - let id = BlockId::Hash(hash); // If it's in chain, with justifications, return it's already on chain // If it's in chain, without justifications, continue the block import process to import its // justifications // This can be triggered if the validators add a block, without justifications, yet the p2p // process then broadcasts it with its justifications - (self.client.status(id).unwrap() == BlockStatus::InChain) && + (self.client.status(hash).unwrap() == BlockStatus::InChain) && self.client.justifications(hash).unwrap().is_some() } } @@ -173,7 +171,7 @@ impl> SelectChain for TendermintSelectChain { .0 .blockchain() // There should always be a finalized block - .header(BlockId::Hash(self.0.blockchain().last_finalized().unwrap())) + .header(self.0.blockchain().last_finalized().unwrap()) // There should not be an error in retrieving it and since it's finalized, it should exist .unwrap() .unwrap(), From 757adda2e04eb34b8f94e8b0bf8931fbf6f43fac Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 16 Jan 2023 16:16:55 -0500 Subject: [PATCH 30/74] cargo fmt --- substrate/tendermint/client/src/authority/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/substrate/tendermint/client/src/authority/mod.rs b/substrate/tendermint/client/src/authority/mod.rs index 519dbd72..379784f0 100644 --- a/substrate/tendermint/client/src/authority/mod.rs +++ b/substrate/tendermint/client/src/authority/mod.rs @@ -199,7 +199,8 @@ impl TendermintAuthority { }; // Get our first proposal - let proposal = authority.get_proposal(&import.client.header(last_hash).unwrap().unwrap()).await; + let proposal = + authority.get_proposal(&import.client.header(last_hash).unwrap().unwrap()).await; // Create the gossip network // This has to be spawning the machine, else gossip fails for some reason From 3b920ad471df150e2d871a3963f4677b3d1d05ed Mon Sep 17 00:00:00 2001 From: akildemir <34187742+akildemir@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:17:54 +0300 Subject: [PATCH 31/74] Monerolib Improvements (#224) * convert AddressSpec subbaddress to tuple * add wallet-rpc tests * fix payment id decryption bug * run fmt * fix CI * use monero-rs wallet-rpc for tests * update the subaddress index type * fix wallet-rpc CI * fix monero-wallet-rpc CI actions * pull latest monero for CI * fix pr issues * detach monero wallet rpc Co-authored-by: Luke Parker --- .github/actions/monero-wallet-rpc/action.yml | 44 +++++++++ .github/actions/monero/action.yml | 2 +- .github/actions/test-dependencies/action.yml | 3 + .github/workflows/monero-tests.yaml | 4 +- coins/monero/Cargo.toml | 1 + coins/monero/src/wallet/mod.rs | 16 +++- .../monero/tests/wallet-rpc-compatibility.rs | 91 +++++++++++++++++++ 7 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 .github/actions/monero-wallet-rpc/action.yml create mode 100644 coins/monero/tests/wallet-rpc-compatibility.rs diff --git a/.github/actions/monero-wallet-rpc/action.yml b/.github/actions/monero-wallet-rpc/action.yml new file mode 100644 index 00000000..ebbd2171 --- /dev/null +++ b/.github/actions/monero-wallet-rpc/action.yml @@ -0,0 +1,44 @@ +name: monero-wallet-rpc +description: Spawns a Monero Wallet-RPC. + +inputs: + version: + description: "Version to download and run" + required: false + default: v0.18.1.2 + +runs: + using: "composite" + steps: + - name: Monero Wallet RPC Cache + id: cache-monero-wallet-rpc + uses: actions/cache@v3 + with: + path: monero-wallet-rpc + key: monero-wallet-rpc-${{ runner.os }}-${{ runner.arch }}-${{ inputs.version }} + + - name: Download the Monero Wallet RPC + if: steps.cache-monero-wallet-rpc.outputs.cache-hit != 'true' + # Calculates OS/ARCH to demonstrate it, yet then locks to linux-x64 due + # to the contained folder not following the same naming scheme and + # requiring further expansion not worth doing right now + shell: bash + run: | + RUNNER_OS=${{ runner.os }} + RUNNER_ARCH=${{ runner.arch }} + + RUNNER_OS=${RUNNER_OS,,} + RUNNER_ARCH=${RUNNER_ARCH,,} + + RUNNER_OS=linux + RUNNER_ARCH=x64 + + FILE=monero-$RUNNER_OS-$RUNNER_ARCH-${{ inputs.version }}.tar.bz2 + wget https://downloads.getmonero.org/cli/$FILE + tar -xvf $FILE + + mv monero-x86_64-linux-gnu-${{ inputs.version }}/monero-wallet-rpc monero-wallet-rpc + + - name: Monero Wallet RPC + shell: bash + run: ./monero-wallet-rpc --disable-rpc-login --rpc-bind-port 6061 --allow-mismatched-daemon-version --wallet-dir ./ --detach diff --git a/.github/actions/monero/action.yml b/.github/actions/monero/action.yml index 10ec5056..8985a548 100644 --- a/.github/actions/monero/action.yml +++ b/.github/actions/monero/action.yml @@ -5,7 +5,7 @@ inputs: version: description: "Version to download and run" required: false - default: v0.18.0.0 + default: v0.18.1.2 runs: using: "composite" diff --git a/.github/actions/test-dependencies/action.yml b/.github/actions/test-dependencies/action.yml index 9af81eef..9ce95eaf 100644 --- a/.github/actions/test-dependencies/action.yml +++ b/.github/actions/test-dependencies/action.yml @@ -29,3 +29,6 @@ runs: uses: ./.github/actions/monero with: version: ${{ inputs.monero-version }} + + - name: Run a Monero Wallet-RPC + uses: ./.github/actions/monero-wallet-rpc diff --git a/.github/workflows/monero-tests.yaml b/.github/workflows/monero-tests.yaml index d5c66acc..37595084 100644 --- a/.github/workflows/monero-tests.yaml +++ b/.github/workflows/monero-tests.yaml @@ -33,7 +33,7 @@ jobs: # Test against all supported protocol versions strategy: matrix: - version: [v0.17.3.2, v0.18.0.0] + version: [v0.17.3.2, v0.18.1.2] steps: - uses: actions/checkout@v3 @@ -50,7 +50,7 @@ jobs: - name: Run Integration Tests # Don't run if the the tests workflow also will - if: ${{ matrix.version != 'v0.18.0.0' }} + if: ${{ matrix.version != 'v0.18.1.2' }} run: | cargo test --package monero-serai --all-features --test '*' cargo test --package serai-processor monero diff --git a/coins/monero/Cargo.toml b/coins/monero/Cargo.toml index 6525ab25..50f95958 100644 --- a/coins/monero/Cargo.toml +++ b/coins/monero/Cargo.toml @@ -55,6 +55,7 @@ monero-generators = { path = "generators", version = "0.1" } [dev-dependencies] tokio = { version = "1", features = ["full"] } +monero-rpc = "0.3" frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.5", features = ["ed25519", "tests"] } diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index 11aaff41..383eb09a 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -60,13 +60,15 @@ pub(crate) fn shared_key( ) -> (u8, Scalar, [u8; 8]) { // 8Ra let mut output_derivation = (s * P).mul_by_cofactor().compress().to_bytes().to_vec(); + + let mut payment_id_xor = [0; 8]; + payment_id_xor + .copy_from_slice(&hash(&[output_derivation.as_ref(), [0x8d].as_ref()].concat())[.. 8]); + // || o write_varint(&o.try_into().unwrap(), &mut output_derivation).unwrap(); let view_tag = hash(&[b"view_tag".as_ref(), &output_derivation].concat())[0]; - let mut payment_id_xor = [0; 8]; - payment_id_xor - .copy_from_slice(&hash(&[output_derivation.as_ref(), [0x8d].as_ref()].concat())[.. 8]); // uniqueness || let shared_key = if let Some(uniqueness) = uniqueness { @@ -106,6 +108,14 @@ impl ViewPair { ViewPair { spend, view } } + pub fn spend(&self) -> EdwardsPoint { + self.spend + } + + pub fn view(&self) -> EdwardsPoint { + self.view.deref() * &ED25519_BASEPOINT_TABLE + } + fn subaddress_derivation(&self, index: SubaddressIndex) -> Scalar { hash_to_scalar(&Zeroizing::new( [ diff --git a/coins/monero/tests/wallet-rpc-compatibility.rs b/coins/monero/tests/wallet-rpc-compatibility.rs new file mode 100644 index 00000000..12353db8 --- /dev/null +++ b/coins/monero/tests/wallet-rpc-compatibility.rs @@ -0,0 +1,91 @@ +use std::{ + collections::{HashSet, HashMap}, + str::FromStr, +}; + +use rand_core::{RngCore, OsRng}; + +use monero_rpc::{ + monero::{Amount, Address}, + TransferOptions, +}; + +use monero_serai::{ + wallet::address::{Network, AddressSpec, SubaddressIndex}, + wallet::Scanner, +}; + +mod runner; + +async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { + let wallet_rpc = + monero_rpc::RpcClientBuilder::new().build("http://127.0.0.1:6061").unwrap().wallet(); + let daemon_rpc = runner::rpc().await; + + // initialize wallet rpc + let address_resp = wallet_rpc.get_address(0, None).await; + let wallet_rpc_addr = if address_resp.is_ok() { + address_resp.unwrap().address + } else { + wallet_rpc.create_wallet("test_wallet".to_string(), None, "English".to_string()).await.unwrap(); + let addr = wallet_rpc.get_address(0, None).await.unwrap().address; + daemon_rpc.generate_blocks(&addr.to_string(), 70).await.unwrap(); + addr + }; + + // make an addr + let (_, view_pair, _) = runner::random_address(); + let addr = Address::from_str(&view_pair.address(Network::Mainnet, spec).to_string()[..]).unwrap(); + + // refresh & make a tx + wallet_rpc.refresh(None).await.unwrap(); + let tx = wallet_rpc + .transfer( + HashMap::from([(addr, Amount::ONE_XMR)]), + monero_rpc::TransferPriority::Default, + TransferOptions::default(), + ) + .await + .unwrap(); + let tx_hash: [u8; 32] = tx.tx_hash.0.try_into().unwrap(); + + // unlock it + runner::mine_until_unlocked(&daemon_rpc, &wallet_rpc_addr.to_string(), tx_hash).await; + + // create the scanner + let mut scanner = Scanner::from_view(view_pair, Some(HashSet::new())); + if let AddressSpec::Subaddress(index) = spec { + scanner.register_subaddress(index); + } + + // retrieve it and confirm + let tx = daemon_rpc.get_transaction(tx_hash).await.unwrap(); + let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0); + + match spec { + AddressSpec::Subaddress(index) => assert_eq!(output.metadata.subaddress, Some(index)), + AddressSpec::Integrated(payment_id) => { + assert_eq!(output.metadata.payment_id, payment_id); + assert_eq!(output.metadata.subaddress, None); + } + _ => assert_eq!(output.metadata.subaddress, None), + } + assert_eq!(output.commitment().amount, 1000000000000); +} + +async_sequential!( + async fn test_receipt_of_wallet_rpc_tx_standard() { + test_from_wallet_rpc_to_self(AddressSpec::Standard).await; + } + + async fn test_receipt_of_wallet_rpc_tx_subaddress() { + test_from_wallet_rpc_to_self(AddressSpec::Subaddress(SubaddressIndex::new(0, 1).unwrap())) + .await; + } + + async fn test_receipt_of_wallet_rpc_tx_integrated() { + let mut payment_id = [0u8; 8]; + OsRng.fill_bytes(&mut payment_id); + test_from_wallet_rpc_to_self(AddressSpec::Integrated(payment_id)).await; + } +); From 7f8bb1aa9f2b7f4bbb84317bea97ffa2db5c152a Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 17 Jan 2023 02:17:45 -0500 Subject: [PATCH 32/74] Make validators archive nodes per #157 --- substrate/node/src/command.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/substrate/node/src/command.rs b/substrate/node/src/command.rs index 43c67a3f..73fc1b31 100644 --- a/substrate/node/src/command.rs +++ b/substrate/node/src/command.rs @@ -1,4 +1,4 @@ -use sc_service::PartialComponents; +use sc_service::{PruningMode, PartialComponents}; use frame_benchmarking_cli::{ExtrinsicFactory, BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli}; @@ -135,7 +135,10 @@ pub fn run() -> sc_cli::Result<()> { cli.create_runner(cmd)?.sync_run(|config| cmd.run::(&config)) } - None => cli.create_runner(&cli.run)?.run_node_until_exit(|config| async { + None => cli.create_runner(&cli.run)?.run_node_until_exit(|mut config| async { + if config.role.is_authority() { + config.state_pruning = Some(PruningMode::ArchiveAll); + } service::new_full(config).await.map_err(sc_cli::Error::Service) }), } From 0346aa6964688d67d27c68a9fab60449b78bb86c Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 17 Jan 2023 02:26:32 -0500 Subject: [PATCH 33/74] Make serai-primitives and vs-primitives MIT --- deny.toml | 4 +--- substrate/serai/primitives/Cargo.toml | 2 +- substrate/validator-sets/primitives/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/deny.toml b/deny.toml index 59376eeb..18354eda 100644 --- a/deny.toml +++ b/deny.toml @@ -45,11 +45,9 @@ default = "deny" exceptions = [ { allow = ["AGPL-3.0"], name = "ethereum-serai" }, + { allow = ["AGPL-3.0"], name = "serai-processor" }, - { allow = ["AGPL-3.0"], name = "serai-primitives" }, - - { allow = ["AGPL-3.0"], name = "validator-sets-primitives" }, { allow = ["AGPL-3.0"], name = "validator-sets-pallet" }, { allow = ["AGPL-3.0"], name = "sp-tendermint" }, diff --git a/substrate/serai/primitives/Cargo.toml b/substrate/serai/primitives/Cargo.toml index 24231788..5d063638 100644 --- a/substrate/serai/primitives/Cargo.toml +++ b/substrate/serai/primitives/Cargo.toml @@ -2,7 +2,7 @@ name = "serai-primitives" version = "0.1.0" description = "Primitives for the Serai blockchain" -license = "AGPL-3.0-only" +license = "MIT" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/serai/primitives" authors = ["Luke Parker "] edition = "2021" diff --git a/substrate/validator-sets/primitives/Cargo.toml b/substrate/validator-sets/primitives/Cargo.toml index 7ddca4ad..7da45dd2 100644 --- a/substrate/validator-sets/primitives/Cargo.toml +++ b/substrate/validator-sets/primitives/Cargo.toml @@ -2,7 +2,7 @@ name = "validator-sets-primitives" version = "0.1.0" description = "Primitives for validator sets" -license = "AGPL-3.0-only" +license = "MIT" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/validator-sets/primitives" authors = ["Luke Parker "] edition = "2021" From e13cf52c4981b0a2ccd7b5fac17e41abe43da5c5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 17 Jan 2023 02:35:22 -0500 Subject: [PATCH 34/74] Update Cargo.lock It appears to have changed with the recent Monero tests yet not have been included in that PR. --- Cargo.lock | 131 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2deb9bf..5b3d0ec6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -902,6 +902,7 @@ dependencies = [ "js-sys", "num-integer", "num-traits", + "serde", "time 0.1.45", "wasm-bindgen", "winapi", @@ -1019,7 +1020,7 @@ version = "3.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" dependencies = [ - "heck", + "heck 0.4.0", "proc-macro-error", "proc-macro2", "quote", @@ -1032,7 +1033,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" dependencies = [ - "heck", + "heck 0.4.0", "proc-macro-error", "proc-macro2", "quote", @@ -1519,6 +1520,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", + "serde", "subtle", "zeroize", ] @@ -2060,7 +2062,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ - "heck", + "heck 0.4.0", "proc-macro2", "quote", "syn", @@ -2152,7 +2154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" dependencies = [ "crunchy", - "fixed-hash", + "fixed-hash 0.8.0", "impl-codec", "impl-rlp", "impl-serde", @@ -2186,7 +2188,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ "ethbloom", - "fixed-hash", + "fixed-hash 0.8.0", "impl-codec", "impl-rlp", "impl-serde", @@ -2560,6 +2562,18 @@ dependencies = [ "scale-info", ] +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -3193,6 +3207,15 @@ dependencies = [ "fxhash", ] +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "heck" version = "0.4.0" @@ -3687,6 +3710,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "jsonrpsee" version = "0.16.2" @@ -3732,7 +3770,7 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa6da1e4199c10d7b1d0a6e5e8bd8e55f351163b6f4b3cbb044672a69bd4c1c" dependencies = [ - "heck", + "heck 0.4.0", "proc-macro-crate", "proc-macro2", "quote", @@ -4191,7 +4229,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d527d5827582abd44a6d80c07ff8b50b4ee238a8979e05998474179e79dc400" dependencies = [ - "heck", + "heck 0.4.0", "quote", "syn", ] @@ -4729,6 +4767,24 @@ dependencies = [ "zeroize", ] +[[package]] +name = "monero" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403883d12972e916dd9754cdb90c25441a9abcf435f8e09c3146de100150eeb0" +dependencies = [ + "base58-monero", + "curve25519-dalek 3.2.0", + "fixed-hash 0.7.0", + "hex", + "hex-literal", + "sealed", + "serde", + "serde-big-array", + "thiserror", + "tiny-keccak", +] + [[package]] name = "monero-epee-bin-serde" version = "1.0.1" @@ -4751,6 +4807,26 @@ dependencies = [ "subtle", ] +[[package]] +name = "monero-rpc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e016b5ed7dbf76e123516b22f35653a95d8c4b784d2ce2113395863dfd9f482f" +dependencies = [ + "anyhow", + "chrono", + "fixed-hash 0.8.0", + "hex", + "http", + "jsonrpc-core", + "monero", + "reqwest", + "serde", + "serde_json", + "tracing", + "uuid 1.2.2", +] + [[package]] name = "monero-serai" version = "0.1.2-alpha" @@ -4769,6 +4845,7 @@ dependencies = [ "modular-frost", "monero-epee-bin-serde", "monero-generators", + "monero-rpc", "multiexp", "rand 0.8.5", "rand_chacha 0.3.1", @@ -5879,7 +5956,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" dependencies = [ - "fixed-hash", + "fixed-hash 0.8.0", "impl-codec", "impl-rlp", "impl-serde", @@ -5991,7 +6068,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3f8ad728fb08fe212df3c05169e940fbb6d9d16a877ddde14644a983ba2012e" dependencies = [ "bytes", - "heck", + "heck 0.4.0", "itertools", "lazy_static", "log", @@ -6370,6 +6447,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls", + "tokio-socks", "tower-service", "url", "wasm-bindgen", @@ -7639,6 +7717,18 @@ dependencies = [ "url", ] +[[package]] +name = "sealed" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b5e421024b5e5edfbaa8e60ecf90bda9dbffc602dbb230e6028763f85f0c68c" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "sec1" version = "0.3.0" @@ -7867,6 +7957,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "serde-big-array" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3323f09a748af288c3dc2474ea6803ee81f118321775bffa3ac8f7e65c5e90e7" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.152" @@ -8807,7 +8906,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.0", "proc-macro2", "quote", "rustversion", @@ -9271,6 +9370,18 @@ dependencies = [ "webpki 0.22.0", ] +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.11" From 8ca90e7905e3d55b883b7cf06bbdd37d9b98c355 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 20 Jan 2023 11:00:18 -0500 Subject: [PATCH 35/74] Initial In Instructions pallet and Serai client lib (#233) * Initial work on an In Inherents pallet * Add an event for when a batch is executed * Add a dummy provider for InInstructions * Add in-instructions to the node * Add the Serai runtime API to the processor * Move processor tests around * Build a subxt Client around Serai * Successfully get Batch events from Serai Renamed processor/substrate to processor/serai. * Much more robust InInstruction pallet * Implement the workaround from https://github.com/paritytech/subxt/issues/602 * Initial prototype of processor generated InInstructions * Correct PendingCoins data flow for InInstructions * Minor lint to in-instructions * Remove the global Serai connection for a partial re-impl * Correct ID handling of the processor test * Workaround the delay in the subscription * Make an unwrap an if let Some, remove old comments * Lint the processor toml * Rebase and update * Move substrate/in-instructions to substrate/in-instructions/pallet * Start an in-instructions primitives lib * Properly update processor to subxt 0.24 Also corrects failures from the rebase. * in-instructions cargo update * Implement IsFatalError * is_inherent -> true * Rename in-instructions crates and misc cleanup * Update documentation * cargo update * Misc update fixes * Replace height with block_number * Update processor src to latest subxt * Correct pipeline for InInstructions testing * Remove runtime::AccountId for serai_primitives::NativeAddress * Rewrite the in-instructions pallet Complete with respect to the currently written docs. Drops the custom serializer for just using SCALE. Makes slight tweaks as relevant. * Move instructions' InherentDataProvider to a client crate * Correct doc gen * Add serde to in-instructions-primitives * Add in-instructions-primitives to pallet * Heights -> BlockNumbers * Get batch pub test loop working * Update in instructions pallet terminology Removes the ambiguous Coin for Update. Removes pending/artificial latency for furture client work. Also moves to using serai_primitives::Coin. * Add a BlockNumber primitive * Belated cargo fmt * Further document why DifferentBatch isn't fatal * Correct processor sleeps * Remove metadata at compile time, add test framework for Serai nodes * Remove manual RPC client * Simplify update test * Improve re-exporting behavior of serai-runtime It now re-exports all pallets underneath it. * Add a function to get storage values to the Serai RPC * Update substrate/ to latest substrate * Create a dedicated crate for the Serai RPC * Remove unused dependencies in substrate/ * Remove unused dependencies in coins/ Out of scope for this branch, just minor and path of least resistance. * Use substrate/serai/client for the Serai RPC lib It's a bit out of place, since these client folders are intended for the node to access pallets and so on. This is for end-users to access Serai as a whole. In that sense, it made more sense as a top level folder, yet that also felt out of place. * Move InInstructions test to serai-client for now * Final cleanup * Update deny.toml * Cargo.lock update from merging develop * Update nightly Attempt to work around the current CI failure, which is a Rust ICE. We previously didn't upgrade due to clippy 10134, yet that's been reverted. * clippy * clippy * fmt * NativeAddress -> SeraiAddress * Sec fix on non-provided updates and doc fixes * Add Serai as a Coin Necessary in order to swap to Serai. * Add a BlockHash type, used for batch IDs * Remove origin from InInstruction Makes InInstructionTarget. Adds RefundableInInstruction with origin. * Document storage items in in-instructions * Rename serai/client/tests/serai.rs to updates.rs It only tested publishing updates and their successful acceptance. --- .github/actions/test-dependencies/action.yml | 15 ++ .github/nightly-version | 2 +- .github/workflows/tests.yml | 5 + Cargo.lock | 254 ++++++++++++++++-- Cargo.toml | 12 +- coins/ethereum/Cargo.toml | 1 - coins/monero/Cargo.toml | 5 +- coins/monero/src/tests/clsag.rs | 8 +- coins/monero/src/wallet/send/multisig.rs | 2 +- coins/monero/tests/runner.rs | 1 + deny.toml | 5 + docs/Serai.md | 4 +- docs/integrations/Ethereum.md | 4 +- docs/integrations/Instructions.md | 122 +++++---- docs/protocol/Constants.md | 28 +- processor/Cargo.toml | 10 +- processor/src/tests/mod.rs | 115 +------- processor/src/tests/monero.rs | 11 + processor/src/tests/send.rs | 106 ++++++++ substrate/in-instructions/client/Cargo.toml | 24 ++ substrate/in-instructions/client/LICENSE | 15 ++ substrate/in-instructions/client/src/lib.rs | 47 ++++ substrate/in-instructions/pallet/Cargo.toml | 51 ++++ substrate/in-instructions/pallet/LICENSE | 15 ++ substrate/in-instructions/pallet/src/lib.rs | 240 +++++++++++++++++ .../in-instructions/primitives/Cargo.toml | 25 ++ substrate/in-instructions/primitives/LICENSE | 21 ++ .../primitives/src/incoming.rs | 38 +++ .../in-instructions/primitives/src/lib.rs | 47 ++++ .../primitives/src/outgoing.rs | 25 ++ .../primitives/src/shorthand.rs | 54 ++++ substrate/node/Cargo.toml | 25 +- substrate/node/src/chain_spec.rs | 67 +++-- substrate/node/src/command.rs | 9 +- substrate/node/src/command_helper.rs | 39 +-- substrate/node/src/rpc.rs | 8 +- substrate/node/src/service.rs | 10 +- substrate/runtime/Cargo.toml | 8 +- substrate/runtime/src/lib.rs | 154 ++++++----- substrate/serai/client/Cargo.toml | 33 +++ substrate/serai/client/LICENSE | 15 ++ substrate/serai/client/src/in_instructions.rs | 49 ++++ substrate/serai/client/src/lib.rs | 77 ++++++ substrate/serai/client/tests/runner.rs | 50 ++++ substrate/serai/client/tests/updates.rs | 60 +++++ substrate/serai/primitives/Cargo.toml | 5 +- substrate/serai/primitives/src/amount.rs | 2 +- substrate/serai/primitives/src/coins.rs | 11 +- substrate/serai/primitives/src/lib.rs | 56 ++++ substrate/tendermint/client/Cargo.toml | 2 - substrate/tendermint/machine/Cargo.toml | 2 +- substrate/validator-sets/pallet/src/lib.rs | 15 +- .../validator-sets/primitives/Cargo.toml | 7 +- 53 files changed, 1613 insertions(+), 403 deletions(-) create mode 100644 processor/src/tests/monero.rs create mode 100644 processor/src/tests/send.rs create mode 100644 substrate/in-instructions/client/Cargo.toml create mode 100644 substrate/in-instructions/client/LICENSE create mode 100644 substrate/in-instructions/client/src/lib.rs create mode 100644 substrate/in-instructions/pallet/Cargo.toml create mode 100644 substrate/in-instructions/pallet/LICENSE create mode 100644 substrate/in-instructions/pallet/src/lib.rs create mode 100644 substrate/in-instructions/primitives/Cargo.toml create mode 100644 substrate/in-instructions/primitives/LICENSE create mode 100644 substrate/in-instructions/primitives/src/incoming.rs create mode 100644 substrate/in-instructions/primitives/src/lib.rs create mode 100644 substrate/in-instructions/primitives/src/outgoing.rs create mode 100644 substrate/in-instructions/primitives/src/shorthand.rs create mode 100644 substrate/serai/client/Cargo.toml create mode 100644 substrate/serai/client/LICENSE create mode 100644 substrate/serai/client/src/in_instructions.rs create mode 100644 substrate/serai/client/src/lib.rs create mode 100644 substrate/serai/client/tests/runner.rs create mode 100644 substrate/serai/client/tests/updates.rs diff --git a/.github/actions/test-dependencies/action.yml b/.github/actions/test-dependencies/action.yml index 9ce95eaf..6340e946 100644 --- a/.github/actions/test-dependencies/action.yml +++ b/.github/actions/test-dependencies/action.yml @@ -12,6 +12,11 @@ inputs: required: false default: v0.18.0.0 + serai: + description: "Run a Serai development node in the background" + required: false + default: false + runs: using: "composite" steps: @@ -32,3 +37,13 @@ runs: - name: Run a Monero Wallet-RPC uses: ./.github/actions/monero-wallet-rpc + + - name: Run a Serai Development Node + if: ${{ inputs.serai }} + shell: bash + run: | + cd substrate/node + cargo build + cd ../.. + + ./target/debug/serai-node --dev & diff --git a/.github/nightly-version b/.github/nightly-version index e9bf8776..14a3253f 100644 --- a/.github/nightly-version +++ b/.github/nightly-version @@ -1 +1 @@ -nightly-2022-12-01 +nightly-2023-01-16 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 079e1fa1..d7e7ff80 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -58,6 +58,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Build node + run: | + cd substrate/node + cargo build + - name: Run Tests run: cargo test --all-features diff --git a/Cargo.lock b/Cargo.lock index 5b3d0ec6..0487ff80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1698,6 +1698,17 @@ dependencies = [ "rusticata-macros", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "derive_builder" version = "0.11.2" @@ -2170,7 +2181,6 @@ dependencies = [ "ethers-solc", "eyre", "group", - "hex-literal", "k256", "modular-frost", "rand_core 0.6.4", @@ -3414,6 +3424,7 @@ dependencies = [ "rustls-native-certs", "tokio", "tokio-rustls", + "webpki-roots", ] [[package]] @@ -3547,6 +3558,46 @@ dependencies = [ "syn", ] +[[package]] +name = "in-instructions-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "in-instructions-pallet", + "jsonrpsee-core", + "jsonrpsee-http-client", + "parity-scale-codec", + "sp-inherents", +] + +[[package]] +name = "in-instructions-pallet" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "in-instructions-primitives", + "parity-scale-codec", + "scale-info", + "serai-primitives", + "serde", + "sp-inherents", + "sp-runtime", + "sp-std", + "thiserror", +] + +[[package]] +name = "in-instructions-primitives" +version = "0.1.0" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serai-primitives", + "serde", + "sp-core", +] + [[package]] name = "indenter" version = "0.3.3" @@ -3731,13 +3782,36 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d291e3a5818a2384645fd9756362e6d89cf0541b0b916fa7702ea4a9833608e" dependencies = [ + "jsonrpsee-client-transport", "jsonrpsee-core", + "jsonrpsee-http-client", "jsonrpsee-proc-macros", "jsonrpsee-server", "jsonrpsee-types", "tracing", ] +[[package]] +name = "jsonrpsee-client-transport" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965de52763f2004bc91ac5bcec504192440f0b568a5d621c59d9dbd6f886c3fb" +dependencies = [ + "futures-util", + "http", + "jsonrpsee-core", + "jsonrpsee-types", + "pin-project", + "rustls-native-certs", + "soketto", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "webpki-roots", +] + [[package]] name = "jsonrpsee-core" version = "0.16.2" @@ -3746,9 +3820,11 @@ checksum = "a4e70b4439a751a5de7dd5ed55eacff78ebf4ffe0fc009cb1ebb11417f5b536b" dependencies = [ "anyhow", "arrayvec 0.7.2", + "async-lock", "async-trait", "beef", "futures-channel", + "futures-timer", "futures-util", "globset", "hyper", @@ -3764,6 +3840,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "jsonrpsee-http-client" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc345b0a43c6bc49b947ebeb936e886a419ee3d894421790c969cc56040542ad" +dependencies = [ + "async-trait", + "hyper", + "hyper-rustls", + "jsonrpsee-core", + "jsonrpsee-types", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "jsonrpsee-proc-macros" version = "0.16.2" @@ -4832,7 +4927,6 @@ name = "monero-serai" version = "0.1.2-alpha" dependencies = [ "base58-monero", - "blake2", "curve25519-dalek 3.2.0", "dalek-ff-group", "digest_auth", @@ -7477,12 +7571,10 @@ dependencies = [ "sc-block-builder", "sc-client-api", "sc-consensus", - "sc-executor", "sc-network", "sc-network-common", "sc-network-gossip", "sc-service", - "sc-transaction-pool", "sp-api", "sp-application-crypto", "sp-blockchain", @@ -7594,6 +7686,29 @@ dependencies = [ "prometheus", ] +[[package]] +name = "scale-bits" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd7aca73785181cc41f0bbe017263e682b585ca660540ba569133901d013ecf" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "scale-decode" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d823d4be477fc33321f93d08fb6c2698273d044f01362dc27573a750deb7c233" +dependencies = [ + "parity-scale-codec", + "scale-bits", + "scale-info", + "thiserror", +] + [[package]] name = "scale-info" version = "2.3.1" @@ -7620,6 +7735,23 @@ dependencies = [ "syn", ] +[[package]] +name = "scale-value" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a5e7810815bd295da73e4216d1dfbced3c7c7c7054d70fa5f6e4c58123fff4" +dependencies = [ + "either", + "frame-metadata", + "parity-scale-codec", + "scale-bits", + "scale-decode", + "scale-info", + "serde", + "thiserror", + "yap", +] + [[package]] name = "schannel" version = "0.1.21" @@ -7823,6 +7955,23 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7" +[[package]] +name = "serai-client" +version = "0.1.0" +dependencies = [ + "in-instructions-primitives", + "jsonrpsee-server", + "lazy_static", + "parity-scale-codec", + "scale-value", + "serai-primitives", + "serai-runtime", + "serde", + "subxt", + "thiserror", + "tokio", +] + [[package]] name = "serai-node" version = "0.1.0" @@ -7831,12 +7980,8 @@ dependencies = [ "clap 4.1.1", "frame-benchmarking", "frame-benchmarking-cli", - "frame-system", - "futures", + "in-instructions-client", "jsonrpsee", - "log", - "pallet-tendermint", - "pallet-transaction-payment", "pallet-transaction-payment-rpc", "sc-basic-authorship", "sc-cli", @@ -7844,31 +7989,24 @@ dependencies = [ "sc-client-db", "sc-consensus", "sc-executor", - "sc-keystore", "sc-network", - "sc-rpc", "sc-rpc-api", "sc-service", "sc-telemetry", "sc-tendermint", "sc-transaction-pool", "sc-transaction-pool-api", - "serai-primitives", "serai-runtime", "sp-api", - "sp-application-crypto", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-core", "sp-inherents", "sp-keyring", - "sp-keystore", "sp-runtime", - "sp-tendermint", "substrate-build-script-utils", "substrate-frame-rpc-system", - "validator-sets-pallet", ] [[package]] @@ -7879,7 +8017,6 @@ dependencies = [ "scale-info", "serde", "sp-core", - "sp-std", ] [[package]] @@ -7913,6 +8050,7 @@ dependencies = [ "frame-system", "frame-system-rpc-runtime-api", "hex-literal", + "in-instructions-pallet", "pallet-assets", "pallet-balances", "pallet-session", @@ -7923,7 +8061,6 @@ dependencies = [ "scale-info", "serai-primitives", "sp-api", - "sp-application-crypto", "sp-block-builder", "sp-core", "sp-inherents", @@ -9016,6 +9153,79 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "subxt" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3cbc78fd36035a24883eada29e0205b9b1416172530a7d00a60c07d0337db0c" +dependencies = [ + "bitvec 1.0.1", + "derivative", + "frame-metadata", + "futures", + "getrandom 0.2.8", + "hex", + "jsonrpsee", + "parity-scale-codec", + "parking_lot 0.12.1", + "scale-decode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-core", + "sp-runtime", + "subxt-macro", + "subxt-metadata", + "thiserror", + "tracing", +] + +[[package]] +name = "subxt-codegen" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7722c31febf55eb300c73d977da5d65cfd6fb443419b1185b9abcdd9925fd7be" +dependencies = [ + "darling", + "frame-metadata", + "heck 0.4.0", + "hex", + "jsonrpsee", + "parity-scale-codec", + "proc-macro-error", + "proc-macro2", + "quote", + "scale-info", + "subxt-metadata", + "syn", + "tokio", +] + +[[package]] +name = "subxt-macro" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f64826f2c4ba20e3b2a86ec81a6ae8655ca6b6a4c2a6ccc888b6615efc2df14" +dependencies = [ + "darling", + "proc-macro-error", + "subxt-codegen", + "syn", +] + +[[package]] +name = "subxt-metadata" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869af75e23513538ad0af046af4a97b8d684e8d202e35ff4127ee061c1110813" +dependencies = [ + "frame-metadata", + "parity-scale-codec", + "scale-info", + "sp-core", +] + [[package]] name = "svm-rs" version = "0.2.19" @@ -9798,8 +10008,6 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-std", ] [[package]] @@ -10789,6 +10997,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yap" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc77f52dc9e9b10d55d3f4462c3b7fc393c4f17975d641542833ab2d3bc26ef" + [[package]] name = "yasna" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 7cdec0c1..34f7afce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,11 @@ members = [ "processor", "substrate/serai/primitives", + "substrate/serai/client", + + "substrate/in-instructions/primitives", + "substrate/in-instructions/pallet", + "substrate/in-instructions/client", "substrate/validator-sets/primitives", "substrate/validator-sets/pallet", @@ -37,7 +42,7 @@ members = [ ] # Always compile Monero (and a variety of dependencies) with optimizations due -# to the unoptimized performance of Bulletproofs +# to the extensive operations required for Bulletproofs [profile.dev.package] subtle = { opt-level = 3 } curve25519-dalek = { opt-level = 3 } @@ -55,3 +60,8 @@ monero-serai = { opt-level = 3 } [profile.release] panic = "unwind" + +# Required for subxt +[patch.crates-io] +sp-core = { git = "https://github.com/serai-dex/substrate" } +sp-runtime = { git = "https://github.com/serai-dex/substrate" } diff --git a/coins/ethereum/Cargo.toml b/coins/ethereum/Cargo.toml index 9d59efd8..aaf4f41b 100644 --- a/coins/ethereum/Cargo.toml +++ b/coins/ethereum/Cargo.toml @@ -13,7 +13,6 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -hex-literal = "0.3" thiserror = "1" rand_core = "0.6" diff --git a/coins/monero/Cargo.toml b/coins/monero/Cargo.toml index 50f95958..9aa30105 100644 --- a/coins/monero/Cargo.toml +++ b/coins/monero/Cargo.toml @@ -25,11 +25,10 @@ zeroize = { version = "1.5", features = ["zeroize_derive"] } subtle = "2.4" sha3 = "0.10" -blake2 = { version = "0.10", optional = true } curve25519-dalek = { version = "3", features = ["std"] } -group = { version = "0.12" } +group = "0.12" dalek-ff-group = { path = "../../crypto/dalek-ff-group", version = "0.1" } multiexp = { path = "../../crypto/multiexp", version = "0.2", features = ["batch"] } @@ -60,4 +59,4 @@ monero-rpc = "0.3" frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.5", features = ["ed25519", "tests"] } [features] -multisig = ["rand_chacha", "blake2", "transcript", "frost", "dleq"] +multisig = ["rand_chacha", "transcript", "frost", "dleq"] diff --git a/coins/monero/src/tests/clsag.rs b/coins/monero/src/tests/clsag.rs index 3becb414..258457d6 100644 --- a/coins/monero/src/tests/clsag.rs +++ b/coins/monero/src/tests/clsag.rs @@ -63,7 +63,7 @@ fn clsag() { Commitment::new(secrets.1, AMOUNT), Decoys { i: u8::try_from(real).unwrap(), - offsets: (1 ..= RING_LEN).into_iter().collect(), + offsets: (1 ..= RING_LEN).collect(), ring: ring.clone(), }, ) @@ -107,11 +107,7 @@ fn clsag_multisig() { Arc::new(RwLock::new(Some(ClsagDetails::new( ClsagInput::new( Commitment::new(randomness, AMOUNT), - Decoys { - i: RING_INDEX, - offsets: (1 ..= RING_LEN).into_iter().collect(), - ring: ring.clone(), - }, + Decoys { i: RING_INDEX, offsets: (1 ..= RING_LEN).collect(), ring: ring.clone() }, ) .unwrap(), mask_sum, diff --git a/coins/monero/src/wallet/send/multisig.rs b/coins/monero/src/wallet/send/multisig.rs index 3ba990f4..d665928e 100644 --- a/coins/monero/src/wallet/send/multisig.rs +++ b/coins/monero/src/wallet/send/multisig.rs @@ -248,7 +248,7 @@ impl SignMachine for TransactionSignMachine { // Find out who's included // This may not be a valid set of signers yet the algorithm machine will error if it's not commitments.remove(&self.i); // Remove, if it was included for some reason - let mut included = commitments.keys().into_iter().cloned().collect::>(); + let mut included = commitments.keys().cloned().collect::>(); included.push(self.i); included.sort_unstable(); diff --git a/coins/monero/tests/runner.rs b/coins/monero/tests/runner.rs index 6861889a..5eac16b5 100644 --- a/coins/monero/tests/runner.rs +++ b/coins/monero/tests/runner.rs @@ -59,6 +59,7 @@ pub async fn mine_until_unlocked(rpc: &Rpc, addr: &str, tx_hash: [u8; 32]) { } // Mines 60 blocks and returns an unlocked miner TX output. +#[allow(dead_code)] pub async fn get_miner_tx_output(rpc: &Rpc, view: &ViewPair) -> SpendableOutput { let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new())); diff --git a/deny.toml b/deny.toml index 18354eda..336ab699 100644 --- a/deny.toml +++ b/deny.toml @@ -48,6 +48,9 @@ exceptions = [ { allow = ["AGPL-3.0"], name = "serai-processor" }, + { allow = ["AGPL-3.0"], name = "in-instructions-pallet" }, + { allow = ["AGPL-3.0"], name = "in-instructions-client" }, + { allow = ["AGPL-3.0"], name = "validator-sets-pallet" }, { allow = ["AGPL-3.0"], name = "sp-tendermint" }, @@ -56,6 +59,8 @@ exceptions = [ { allow = ["AGPL-3.0"], name = "serai-runtime" }, { allow = ["AGPL-3.0"], name = "serai-node" }, + + { allow = ["AGPL-3.0"], name = "serai-client" }, ] [[licenses.clarify]] diff --git a/docs/Serai.md b/docs/Serai.md index d2e21d2e..04043f16 100644 --- a/docs/Serai.md +++ b/docs/Serai.md @@ -1,8 +1,8 @@ # Serai Serai is a decentralized execution layer whose validators form multisig wallets -for various connected networks, offering secure decentralized custody of foreign -assets to applications built on it. +for various connected networks, offering secure decentralized control of foreign +coins to applications built on it. Serai is exemplified by Serai DEX, an automated-market-maker (AMM) decentralized exchange, allowing swapping Bitcoin, Ether, DAI, and Monero. It is the premier diff --git a/docs/integrations/Ethereum.md b/docs/integrations/Ethereum.md index 48dbec75..e66a1f5b 100644 --- a/docs/integrations/Ethereum.md +++ b/docs/integrations/Ethereum.md @@ -9,11 +9,11 @@ Ethereum addresses are 20-byte hashes. Ethereum In Instructions are present via being appended to the calldata transferring funds to Serai. `origin` is automatically set to the party from which funds are being transferred. For an ERC20, this is `from`. For ETH, this -is the caller. `data` is limited to 255 bytes. +is the caller. ### Out Instructions -`data` is limited to 255 bytes. +`data` is limited to 512 bytes. If `data` is provided, the Ethereum Router will call a contract-calling child contract in order to sandbox it. The first byte of `data` designates which child diff --git a/docs/integrations/Instructions.md b/docs/integrations/Instructions.md index 18c82396..cec67eb2 100644 --- a/docs/integrations/Instructions.md +++ b/docs/integrations/Instructions.md @@ -3,90 +3,94 @@ Instructions are used to communicate with networks connected to Serai, and they come in two forms: - - In Instructions are [Application Calls](../Serai.md#application-calls), -paired with incoming funds. Encoded in transactions on connected networks, -Serai will parse out instructions when it receives funds, executing the included -calls. + - In Instructions are programmable specifications paired with incoming coins, +encoded into transactions on connected networks. Serai will parse included +instructions when it receives coins, executing the included specs. - - Out Instructions detail how to transfer assets, either to a Serai address or -an address native to the asset in question. + - Out Instructions detail how to transfer coins, either to a Serai address or +an address native to the coin in question. A transaction containing an In Instruction and an Out Instruction (to a native -address) will receive funds to Serai and send funds from Serai, without +address) will receive coins to Serai and send coins from Serai, without requiring directly performing any transactions on Serai itself. All instructions are encoded under [Shorthand](#shorthand). Shorthand provides frequent use cases to create minimal data representations on connected networks. Instructions are interpreted according to their non-Serai network. Addresses -have no validation performed, beyond being a valid enum entry (when applicable) -of the correct length, unless otherwise noted. If the processor is instructed to -act on invalid data, or send to itself, it will drop the entire instruction. +have no validation performed unless otherwise noted. If the processor is +instructed to act on invalid data, it will drop the entire instruction. ### Serialization - - Numbers are exclusively unsigned and encoded as compact integers under -SCALE. - - Enums are prefixed by an ordinal byte of their type, followed by their -actual values. - - Vectors are prefixed by their length. - - In Instruction fields are numbered and sequentially encoded, allowing -omission, each prefixed by an ordinal byte. This is due to its fields being more -frequently omitted than not, making their presence what's notable. - - All other types have their fields sequentially encoded with no markers. +Instructions are SCALE encoded. -Certain fields may be omitted depending on the network in question. +### Application Call -### In Instructions + - `application` (u16): The application of Serai to call. Currently, only 0, +Serai DEX is valid. + - `data` (Data): The data to call the application with. - - `origin` (Address): Address from the network of origin which sent funds in. - - `target` (Address): The ink! contract to transfer the incoming funds to. - - `data` (Vec\): The data to call `target` with. +### In Instruction + +InInstruction is an enum of SeraiAddress and ApplicationCall. + +The specified target will be minted an appropriate amount of the respective +Serai token. If an Application Call, the encoded call will be executed. + +### Refundable In Instruction + + - `origin` (Option\): Address, from the network of origin, +which sent coins in. + - `instruction` (InInstruction): The action to perform with the incoming +coins. Networks may automatically provide `origin`. If they do, the instruction may -still provide `origin`, overriding the automatically provided value. If no -`origin` is provided, the instruction is dropped. +still provide `origin`, overriding the automatically provided value. -Upon receiving funds, the respective Serai Asset contract is called, minting the -appropriate amount of coins, and transferring them to `target`, calling it with -the attached data. +If the instruction fails, coins are scheduled to be returned to `origin`, +if provided. -If the instruction fails, funds are scheduled to be returned to `origin`. +### Destination -### Out Instructions +Destination is an enum of SeraiAddress and ExternalAddress. - - `destination` (Enum { Native(Address), Serai(Address) }): Address to receive -funds to. - - `data` (Option\>): The data to call -the target with. +### Out Instruction -Transfer the funds included with this instruction to the specified address with -the specified data. Asset contracts perform no validation on native -addresses/data. + - `destination` (Destination): Address to receive coins to. + - `data` (Option\): The data to call the destination with. + +Transfer the coins included with this instruction to the specified address with +the specified data. No validation of external addresses/data is performed +on-chain. If data is specified for a chain not supporting data, it is silently +dropped. ### Shorthand -Shorthand is an enum which expands to an In Instruction. +Shorthand is an enum which expands to an Refundable In Instruction. ##### Raw -Raw Shorthand encodes a raw In Instruction with no further processing. This is -a verbose fallback option for infrequent use cases not covered by Shorthand. +Raw Shorthand encodes a raw Refundable In Instruction in a Data, with no further +processing. This is a verbose fallback option for infrequent use cases not +covered by Shorthand. ##### Swap - - `origin` (Option\
): In Instruction's `origin`. - - `coin` (Coin): Coin to swap funds for. - - `minimum` (Amount): Minimum amount of `coin` to receive. - - `out` (Out Instruction): Final destination for funds. + - `origin` (Option\): Refundable In Instruction's `origin`. + - `coin` (Coin): Coin to swap funds for. + - `minimum` (Amount): Minimum amount of `coin` to receive. + - `out` (Out Instruction): Final destination for funds. which expands to: ``` -In Instruction { +RefundableInInstruction { origin, - target: Router, - data: swap(Incoming Asset, out, minimum) + instruction: ApplicationCall { + application: DEX, + data: swap(Incoming Asset, coin, minimum, out) + } } ``` @@ -99,19 +103,23 @@ where `swap` is a function which: ##### Add Liquidity - - `origin` (Option\
): In Instruction's `origin`. - - `minimum` (Amount): Minimum amount of SRI to receive. - - `gas` (Amount): Amount of SRI to send to `address` to cover -gas in the future. - - `address` (Address): Account to send the created liquidity tokens. + - `origin` (Option\): Refundable In Instruction's `origin`. + - `minimum` (Amount): Minimum amount of SRI tokens to swap +half for. + - `gas` (Amount): Amount of SRI to send to `address` to +cover gas in the future. + - `address` (Address): Account to send the created liquidity +tokens. which expands to: ``` -In Instruction { +RefundableInInstruction { origin, - target: Router, - data: swap_and_add_liquidity(Incoming Asset, address, minimum, gas) + instruction: ApplicationCall { + application: DEX, + data: swap_and_add_liquidity(Incoming Asset, minimum, gas, address) + } } ``` @@ -120,5 +128,5 @@ where `swap_and_add_liquidity` is a function which: 1) Swaps half of the incoming funds for SRI. 2) Checks the amount of SRI received is greater than `minimum`. 3) Calls `swap_and_add_liquidity` with the amount of SRI received - `gas`, and -a matching amount of the incoming asset. +a matching amount of the incoming coin. 4) Transfers any leftover funds to `address`. diff --git a/docs/protocol/Constants.md b/docs/protocol/Constants.md index 88c09f4e..8ed0524f 100644 --- a/docs/protocol/Constants.md +++ b/docs/protocol/Constants.md @@ -5,14 +5,17 @@ These are the list of types used to represent various properties within the protocol. -| Alias | Type | -|------------------------|--------------------------------| -| Amount | u64 | -| Coin | u32 | -| Session | u32 | -| Validator Set Index | u16 | -| Validator Set Instance | (Session, Validator Set Index) | -| Key | Vec\ | +| Alias | Type | +|------------------------|----------------------------------------------| +| SeraiAddress | sr25519::Public (unchecked [u8; 32] wrapper) | +| Amount | u64 | +| Coin | u32 | +| Session | u32 | +| Validator Set Index | u16 | +| Validator Set Instance | (Session, Validator Set Index) | +| Key | BoundedVec\ | +| ExternalAddress | BoundedVec\ | +| Data | BoundedVec\ | ### Networks @@ -36,7 +39,8 @@ Coins exist over a network and have a distinct integer ID. | Coin | Network | ID | |----------|----------|----| -| Bitcoin | Bitcoin | 0 | -| Ether | Ethereum | 1 | -| DAI | Ethereum | 2 | -| Monero | Monero | 3 | +| Serai | Serai | 0 | +| Bitcoin | Bitcoin | 1 | +| Ether | Ethereum | 2 | +| DAI | Ethereum | 3 | +| Monero | Monero | 4 | diff --git a/processor/Cargo.toml b/processor/Cargo.toml index 695b16e4..c7760bab 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -14,26 +14,28 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] +# Macros async-trait = "0.1" zeroize = "1.5" thiserror = "1" rand_core = "0.6" +# Cryptography group = "0.12" - curve25519-dalek = { version = "3", features = ["std"] } - -transcript = { package = "flexible-transcript", path = "../crypto/transcript", features = ["recommended"] } dalek-ff-group = { path = "../crypto/dalek-ff-group" } + +transcript = { package = "flexible-transcript", path = "../crypto/transcript" } frost = { package = "modular-frost", path = "../crypto/frost", features = ["ed25519"] } +# Monero monero-serai = { path = "../coins/monero", features = ["multisig"] } [dev-dependencies] rand_core = "0.6" hex = "0.4" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1", features = ["derive"] } serde_json = "1.0" futures = "0.3" diff --git a/processor/src/tests/mod.rs b/processor/src/tests/mod.rs index 577fb205..e8abeade 100644 --- a/processor/src/tests/mod.rs +++ b/processor/src/tests/mod.rs @@ -1,113 +1,4 @@ -use std::{ - sync::{Arc, RwLock}, - collections::HashMap, -}; +mod send; +pub(crate) use send::test_send; -use async_trait::async_trait; - -use rand_core::OsRng; - -use crate::{ - NetworkError, Network, - coin::{Coin, Monero}, - wallet::{WalletKeys, MemCoinDb, Wallet}, -}; - -#[derive(Clone)] -struct LocalNetwork { - i: u16, - size: u16, - round: usize, - #[allow(clippy::type_complexity)] - rounds: Arc>>>>, -} - -impl LocalNetwork { - fn new(size: u16) -> Vec { - let rounds = Arc::new(RwLock::new(vec![])); - let mut res = vec![]; - for i in 1 ..= size { - res.push(LocalNetwork { i, size, round: 0, rounds: rounds.clone() }); - } - res - } -} - -#[async_trait] -impl Network for LocalNetwork { - async fn round(&mut self, data: Vec) -> Result>, NetworkError> { - { - let mut rounds = self.rounds.write().unwrap(); - if rounds.len() == self.round { - rounds.push(HashMap::new()); - } - rounds[self.round].insert(self.i, data); - } - - while { - let read = self.rounds.try_read().unwrap(); - read[self.round].len() != usize::from(self.size) - } { - tokio::task::yield_now().await; - } - - let mut res = self.rounds.try_read().unwrap()[self.round].clone(); - res.remove(&self.i); - self.round += 1; - Ok(res) - } -} - -async fn test_send(coin: C, fee: C::Fee) { - // Mine blocks so there's a confirmed block - coin.mine_block().await; - let latest = coin.get_latest_block_number().await.unwrap(); - - let mut keys = frost::tests::key_gen::<_, C::Curve>(&mut OsRng); - let threshold = keys[&1].params().t(); - let mut networks = LocalNetwork::new(threshold); - - let mut wallets = vec![]; - for i in 1 ..= threshold { - let mut wallet = Wallet::new(MemCoinDb::new(), coin.clone()); - wallet.acknowledge_block(0, latest); - wallet.add_keys(&WalletKeys::new(keys.remove(&i).unwrap(), 0)); - wallets.push(wallet); - } - - // Get the chain to a length where blocks have sufficient confirmations - while (latest + (C::CONFIRMATIONS - 1)) > coin.get_latest_block_number().await.unwrap() { - coin.mine_block().await; - } - - for wallet in wallets.iter_mut() { - // Poll to activate the keys - wallet.poll().await.unwrap(); - } - - coin.test_send(wallets[0].address()).await; - - let mut futures = vec![]; - for (network, wallet) in networks.iter_mut().zip(wallets.iter_mut()) { - wallet.poll().await.unwrap(); - - let latest = coin.get_latest_block_number().await.unwrap(); - wallet.acknowledge_block(1, latest - (C::CONFIRMATIONS - 1)); - let signable = wallet - .prepare_sends(1, vec![(wallet.address(), 10000000000)], fee) - .await - .unwrap() - .1 - .swap_remove(0); - futures.push(wallet.attempt_send(network, signable)); - } - - println!("{:?}", hex::encode(futures::future::join_all(futures).await.swap_remove(0).unwrap().0)); -} - -#[tokio::test] -async fn monero() { - let monero = Monero::new("http://127.0.0.1:18081".to_string()).await; - let fee = monero.get_fee().await; - test_send(monero, fee).await; -} +mod monero; diff --git a/processor/src/tests/monero.rs b/processor/src/tests/monero.rs new file mode 100644 index 00000000..68b8a621 --- /dev/null +++ b/processor/src/tests/monero.rs @@ -0,0 +1,11 @@ +use crate::{ + coin::{Coin, Monero}, + tests::test_send, +}; + +#[tokio::test] +async fn monero() { + let monero = Monero::new("http://127.0.0.1:18081".to_string()).await; + let fee = monero.get_fee().await; + test_send(monero, fee).await; +} diff --git a/processor/src/tests/send.rs b/processor/src/tests/send.rs new file mode 100644 index 00000000..3f0a5b55 --- /dev/null +++ b/processor/src/tests/send.rs @@ -0,0 +1,106 @@ +use std::{ + sync::{Arc, RwLock}, + collections::HashMap, +}; + +use async_trait::async_trait; + +use rand_core::OsRng; + +use crate::{ + NetworkError, Network, + coin::Coin, + wallet::{WalletKeys, MemCoinDb, Wallet}, +}; + +#[derive(Clone)] +struct LocalNetwork { + i: u16, + size: u16, + round: usize, + #[allow(clippy::type_complexity)] + rounds: Arc>>>>, +} + +impl LocalNetwork { + fn new(size: u16) -> Vec { + let rounds = Arc::new(RwLock::new(vec![])); + let mut res = vec![]; + for i in 1 ..= size { + res.push(LocalNetwork { i, size, round: 0, rounds: rounds.clone() }); + } + res + } +} + +#[async_trait] +impl Network for LocalNetwork { + async fn round(&mut self, data: Vec) -> Result>, NetworkError> { + { + let mut rounds = self.rounds.write().unwrap(); + if rounds.len() == self.round { + rounds.push(HashMap::new()); + } + rounds[self.round].insert(self.i, data); + } + + while { + let read = self.rounds.try_read().unwrap(); + read[self.round].len() != usize::from(self.size) + } { + tokio::task::yield_now().await; + } + + let mut res = self.rounds.try_read().unwrap()[self.round].clone(); + res.remove(&self.i); + self.round += 1; + Ok(res) + } +} + +pub async fn test_send(coin: C, fee: C::Fee) { + // Mine blocks so there's a confirmed block + coin.mine_block().await; + let latest = coin.get_latest_block_number().await.unwrap(); + + let mut keys = frost::tests::key_gen::<_, C::Curve>(&mut OsRng); + let threshold = keys[&1].params().t(); + let mut networks = LocalNetwork::new(threshold); + + let mut wallets = vec![]; + for i in 1 ..= threshold { + let mut wallet = Wallet::new(MemCoinDb::new(), coin.clone()); + wallet.acknowledge_block(0, latest); + wallet.add_keys(&WalletKeys::new(keys.remove(&i).unwrap(), 0)); + wallets.push(wallet); + } + + // Get the chain to a length where blocks have sufficient confirmations + while (latest + (C::CONFIRMATIONS - 1)) > coin.get_latest_block_number().await.unwrap() { + coin.mine_block().await; + } + + for wallet in wallets.iter_mut() { + // Poll to activate the keys + wallet.poll().await.unwrap(); + } + + coin.test_send(wallets[0].address()).await; + + let mut futures = vec![]; + for (network, wallet) in networks.iter_mut().zip(wallets.iter_mut()) { + wallet.poll().await.unwrap(); + + let latest = coin.get_latest_block_number().await.unwrap(); + wallet.acknowledge_block(1, latest - (C::CONFIRMATIONS - 1)); + let signable = wallet + .prepare_sends(1, vec![(wallet.address(), 10000000000)], fee) + .await + .unwrap() + .1 + .swap_remove(0); + futures.push(wallet.attempt_send(network, signable)); + } + + println!("{:?}", hex::encode(futures::future::join_all(futures).await.swap_remove(0).unwrap().0)); +} diff --git a/substrate/in-instructions/client/Cargo.toml b/substrate/in-instructions/client/Cargo.toml new file mode 100644 index 00000000..d5cda871 --- /dev/null +++ b/substrate/in-instructions/client/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "in-instructions-client" +version = "0.1.0" +description = "Package In Instructions into inherent transactions" +license = "AGPL-3.0-only" +authors = ["Luke Parker "] +edition = "2021" +publish = false + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +async-trait = "0.1" + +scale = { package = "parity-scale-codec", version = "3", features = ["derive", "max-encoded-len"] } + +jsonrpsee-core = "0.16" +jsonrpsee-http-client = "0.16" + +sp-inherents = { git = "https://github.com/serai-dex/substrate" } + +in-instructions-pallet = { path = "../pallet" } diff --git a/substrate/in-instructions/client/LICENSE b/substrate/in-instructions/client/LICENSE new file mode 100644 index 00000000..c425427c --- /dev/null +++ b/substrate/in-instructions/client/LICENSE @@ -0,0 +1,15 @@ +AGPL-3.0-only license + +Copyright (c) 2022-2023 Luke Parker + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License Version 3 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . diff --git a/substrate/in-instructions/client/src/lib.rs b/substrate/in-instructions/client/src/lib.rs new file mode 100644 index 00000000..1571f999 --- /dev/null +++ b/substrate/in-instructions/client/src/lib.rs @@ -0,0 +1,47 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] + +use scale::Decode; + +use jsonrpsee_core::client::ClientT; +use jsonrpsee_http_client::HttpClientBuilder; + +use sp_inherents::{Error, InherentData, InherentIdentifier}; + +use in_instructions_pallet::{INHERENT_IDENTIFIER, Updates, InherentError}; + +pub struct InherentDataProvider; +impl InherentDataProvider { + #[allow(clippy::new_without_default)] // This isn't planned to forever have empty arguments + pub fn new() -> InherentDataProvider { + InherentDataProvider + } +} + +#[async_trait::async_trait] +impl sp_inherents::InherentDataProvider for InherentDataProvider { + async fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), Error> { + let updates: Updates = (|| async { + let client = HttpClientBuilder::default().build("http://127.0.0.1:5134")?; + client.request("processor_coinUpdates", Vec::::new()).await + })() + .await + .map_err(|e| { + Error::Application(Box::from(format!("couldn't communicate with processor: {e}"))) + })?; + inherent_data.put_data(INHERENT_IDENTIFIER, &updates)?; + Ok(()) + } + + async fn try_handle_error( + &self, + identifier: &InherentIdentifier, + mut error: &[u8], + ) -> Option> { + if *identifier != INHERENT_IDENTIFIER { + return None; + } + + Some(Err(Error::Application(Box::from(::decode(&mut error).ok()?)))) + } +} diff --git a/substrate/in-instructions/pallet/Cargo.toml b/substrate/in-instructions/pallet/Cargo.toml new file mode 100644 index 00000000..7895997e --- /dev/null +++ b/substrate/in-instructions/pallet/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "in-instructions-pallet" +version = "0.1.0" +description = "Execute calls via In Instructions from inherent transactions" +license = "AGPL-3.0-only" +authors = ["Luke Parker "] +edition = "2021" +publish = false + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +thiserror = { version = "1", optional = true } + +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2", default-features = false, features = ["derive"] } + +serde = { version = "1", optional = true } + +sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } +sp-inherents = { git = "https://github.com/serai-dex/substrate", default-features = false } +sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false } + +frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false } +frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false } + +serai-primitives = { path = "../../serai/primitives", default-features = false } +in-instructions-primitives = { path = "../primitives", default-features = false } + +[features] +std = [ + "thiserror", + + "scale/std", + "scale-info/std", + + "serde", + + "sp-std/std", + "sp-inherents/std", + "sp-runtime/std", + + "frame-system/std", + "frame-support/std", + + "serai-primitives/std", + "in-instructions-primitives/std", +] +default = ["std"] diff --git a/substrate/in-instructions/pallet/LICENSE b/substrate/in-instructions/pallet/LICENSE new file mode 100644 index 00000000..c425427c --- /dev/null +++ b/substrate/in-instructions/pallet/LICENSE @@ -0,0 +1,15 @@ +AGPL-3.0-only license + +Copyright (c) 2022-2023 Luke Parker + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License Version 3 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . diff --git a/substrate/in-instructions/pallet/src/lib.rs b/substrate/in-instructions/pallet/src/lib.rs new file mode 100644 index 00000000..7b5d5f8b --- /dev/null +++ b/substrate/in-instructions/pallet/src/lib.rs @@ -0,0 +1,240 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +use scale::{Encode, Decode}; +use scale_info::TypeInfo; + +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use sp_std::vec::Vec; +use sp_inherents::{InherentIdentifier, IsFatalError}; + +use sp_runtime::RuntimeDebug; + +use serai_primitives::{BlockNumber, BlockHash, Coin}; + +pub use in_instructions_primitives as primitives; +use primitives::InInstruction; + +pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"ininstrs"; + +#[derive(Clone, PartialEq, Eq, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Batch { + pub id: BlockHash, + pub instructions: Vec, +} + +#[derive(Clone, PartialEq, Eq, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Update { + // Coin's latest block number + pub block_number: BlockNumber, + pub batches: Vec, +} + +// None if the current block producer isn't operating over this coin or otherwise failed to get +// data +pub type Updates = Vec>; + +#[derive(Clone, Copy, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, thiserror::Error))] +pub enum InherentError { + #[cfg_attr(feature = "std", error("invalid call"))] + InvalidCall, + #[cfg_attr(feature = "std", error("inherent has {0} updates despite us having {1} coins"))] + InvalidUpdateQuantity(u32, u32), + #[cfg_attr( + feature = "std", + error("inherent for coin {0:?} has block number {1:?} despite us having {2:?}") + )] + UnrecognizedBlockNumber(Coin, BlockNumber, BlockNumber), + #[cfg_attr( + feature = "std", + error("inherent for coin {0:?} has block number {1:?} which doesn't succeed {2:?}") + )] + InvalidBlockNumber(Coin, BlockNumber, BlockNumber), + #[cfg_attr(feature = "std", error("coin {0:?} has {1} more batches than we do"))] + UnrecognizedBatches(Coin, u32), + #[cfg_attr(feature = "std", error("coin {0:?} has a different batch (ID {1:?})"))] + DifferentBatch(Coin, BlockHash), +} + +impl IsFatalError for InherentError { + fn is_fatal_error(&self) -> bool { + match self { + InherentError::InvalidCall | InherentError::InvalidUpdateQuantity(..) => true, + InherentError::UnrecognizedBlockNumber(..) => false, + InherentError::InvalidBlockNumber(..) => true, + InherentError::UnrecognizedBatches(..) => false, + // One of our nodes is definitively wrong. If it's ours (signified by it passing consensus), + // we should panic. If it's theirs, they should be slashed + // Unfortunately, we can't return fatal here to trigger a slash as fatal should only be used + // for undeniable, technical invalidity + // TODO: Code a way in which this still triggers a slash vote + InherentError::DifferentBatch(..) => false, + } + } +} + +fn coin_from_index(index: usize) -> Coin { + // Offset by 1 since Serai is the first coin, yet Serai doesn't have updates + Coin::from(1 + u32::try_from(index).unwrap()) +} + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event { + Batch { coin: Coin, id: BlockHash }, + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData); + + // Used to only allow one set of updates per block, preventing double updating + #[pallet::storage] + pub(crate) type Once = StorageValue<_, bool, ValueQuery>; + // Latest block number agreed upon for a coin + #[pallet::storage] + #[pallet::getter(fn block_number)] + pub(crate) type BlockNumbers = + StorageMap<_, Blake2_256, Coin, BlockNumber, ValueQuery>; + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_finalize(_: BlockNumberFor) { + Once::::take(); + } + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight((0, DispatchClass::Mandatory))] // TODO + pub fn execute(origin: OriginFor, updates: Updates) -> DispatchResult { + ensure_none(origin)?; + assert!(!Once::::exists()); + Once::::put(true); + + for (coin, update) in updates.iter().enumerate() { + if let Some(update) = update { + let coin = coin_from_index(coin); + BlockNumbers::::insert(coin, update.block_number); + + for batch in &update.batches { + // TODO: EXECUTE + Self::deposit_event(Event::Batch { coin, id: batch.id }); + } + } + } + + Ok(()) + } + } + + #[pallet::inherent] + impl ProvideInherent for Pallet { + type Call = Call; + type Error = InherentError; + const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; + + fn create_inherent(data: &InherentData) -> Option { + data + .get_data::(&INHERENT_IDENTIFIER) + .unwrap() + .map(|updates| Call::execute { updates }) + } + + // Assumes that only not yet handled batches are provided as inherent data + fn check_inherent(call: &Self::Call, data: &InherentData) -> Result<(), Self::Error> { + // First unwrap is for the Result of fetching/decoding the Updates + // Second unwrap is for the Option of if they exist + let expected = data.get_data::(&INHERENT_IDENTIFIER).unwrap().unwrap(); + // Match to be exhaustive + let updates = match call { + Call::execute { ref updates } => updates, + _ => Err(InherentError::InvalidCall)?, + }; + + // The block producer should've provided one update per coin + // We, an honest node, did provide one update per coin + // Accordingly, we should have the same amount of updates + if updates.len() != expected.len() { + Err(InherentError::InvalidUpdateQuantity( + updates.len().try_into().unwrap(), + expected.len().try_into().unwrap(), + ))?; + } + + // This zip is safe since we verified they're equally sized + // This should be written as coins.zip(updates.iter().zip(&expected)), where coins is the + // validator set's coins + // That'd require having context on the validator set right now which isn't worth pulling in + // right now, when we only have one validator set + for (coin, both) in updates.iter().zip(&expected).enumerate() { + let coin = coin_from_index(coin); + match both { + // Block producer claims there's an update for this coin, as do we + (Some(update), Some(expected)) => { + if update.block_number.0 > expected.block_number.0 { + Err(InherentError::UnrecognizedBlockNumber( + coin, + update.block_number, + expected.block_number, + ))?; + } + + let prev = BlockNumbers::::get(coin); + if update.block_number.0 <= prev.0 { + Err(InherentError::InvalidBlockNumber(coin, update.block_number, prev))?; + } + + if update.batches.len() > expected.batches.len() { + Err(InherentError::UnrecognizedBatches( + coin, + (update.batches.len() - expected.batches.len()).try_into().unwrap(), + ))?; + } + + for (batch, expected) in update.batches.iter().zip(&expected.batches) { + if batch != expected { + Err(InherentError::DifferentBatch(coin, batch.id))?; + } + } + } + + // Block producer claims there's an update for this coin, yet we don't + (Some(update), None) => { + Err(InherentError::UnrecognizedBatches(coin, update.batches.len().try_into().unwrap()))? + } + + // Block producer didn't include update for this coin + (None, _) => (), + }; + } + + Ok(()) + } + + fn is_inherent(_: &Self::Call) -> bool { + true + } + } +} + +pub use pallet::*; diff --git a/substrate/in-instructions/primitives/Cargo.toml b/substrate/in-instructions/primitives/Cargo.toml new file mode 100644 index 00000000..c2d4c788 --- /dev/null +++ b/substrate/in-instructions/primitives/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "in-instructions-primitives" +version = "0.1.0" +description = "Serai instructions library, enabling encoding and decoding" +license = "MIT" +authors = ["Luke Parker "] +edition = "2021" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2", default-features = false, features = ["derive"] } + +serde = { version = "1", features = ["derive"], optional = true } + +sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } + +serai-primitives = { path = "../../serai/primitives", default-features = false } + +[features] +std = ["scale/std", "scale-info/std", "serde", "sp-core/std", "serai-primitives/std"] +default = ["std"] diff --git a/substrate/in-instructions/primitives/LICENSE b/substrate/in-instructions/primitives/LICENSE new file mode 100644 index 00000000..6779f0ec --- /dev/null +++ b/substrate/in-instructions/primitives/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2023 Luke Parker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/substrate/in-instructions/primitives/src/incoming.rs b/substrate/in-instructions/primitives/src/incoming.rs new file mode 100644 index 00000000..0a685a11 --- /dev/null +++ b/substrate/in-instructions/primitives/src/incoming.rs @@ -0,0 +1,38 @@ +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; + +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use sp_core::{ConstU32, bounded::BoundedVec}; + +use serai_primitives::SeraiAddress; + +use crate::{MAX_DATA_LEN, ExternalAddress}; + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum Application { + DEX, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct ApplicationCall { + application: Application, + data: BoundedVec>, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum InInstruction { + Transfer(SeraiAddress), + Call(ApplicationCall), +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct RefundableInInstruction { + pub origin: Option, + pub instruction: InInstruction, +} diff --git a/substrate/in-instructions/primitives/src/lib.rs b/substrate/in-instructions/primitives/src/lib.rs new file mode 100644 index 00000000..befc593e --- /dev/null +++ b/substrate/in-instructions/primitives/src/lib.rs @@ -0,0 +1,47 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; + +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use sp_core::{ConstU32, bounded::BoundedVec}; + +// Monero, our current longest address candidate, has a longest address of featured with payment ID +// 1 (enum) + 1 (flags) + 64 (two keys) + 8 (payment ID) = 74 +pub const MAX_ADDRESS_LEN: u32 = 74; +// Should be enough for a Uniswap v3 call +pub const MAX_DATA_LEN: u32 = 512; + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct ExternalAddress(BoundedVec>); +impl ExternalAddress { + #[cfg(feature = "std")] + pub fn new(address: Vec) -> Result { + Ok(ExternalAddress(address.try_into().map_err(|_| "address length exceeds {MAX_ADDRESS_LEN}")?)) + } + + pub fn address(&self) -> &[u8] { + self.0.as_ref() + } + + #[cfg(feature = "std")] + pub fn consume(self) -> Vec { + self.0.into_inner() + } +} + +// Not "in" as "in" is a keyword +mod incoming; +pub use incoming::*; + +// Not "out" to match in +mod outgoing; +pub use outgoing::*; + +mod shorthand; +pub use shorthand::*; diff --git a/substrate/in-instructions/primitives/src/outgoing.rs b/substrate/in-instructions/primitives/src/outgoing.rs new file mode 100644 index 00000000..2e8cf426 --- /dev/null +++ b/substrate/in-instructions/primitives/src/outgoing.rs @@ -0,0 +1,25 @@ +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; + +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use sp_core::{ConstU32, bounded::BoundedVec}; + +use serai_primitives::SeraiAddress; + +use crate::{MAX_DATA_LEN, ExternalAddress}; + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum Destination { + Native(SeraiAddress), + External(ExternalAddress), +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct OutInstruction { + destination: Destination, + data: Option>>, +} diff --git a/substrate/in-instructions/primitives/src/shorthand.rs b/substrate/in-instructions/primitives/src/shorthand.rs new file mode 100644 index 00000000..e3944510 --- /dev/null +++ b/substrate/in-instructions/primitives/src/shorthand.rs @@ -0,0 +1,54 @@ +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; + +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use sp_core::{ConstU32, bounded::BoundedVec}; + +use serai_primitives::{SeraiAddress, Coin, Amount}; + +use crate::{MAX_DATA_LEN, ExternalAddress, RefundableInInstruction, InInstruction, OutInstruction}; + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum Shorthand { + Raw(BoundedVec>), + Swap { + origin: Option, + coin: Coin, + minimum: Amount, + out: OutInstruction, + }, + AddLiquidity { + origin: Option, + minimum: Amount, + gas: Amount, + address: SeraiAddress, + }, +} + +impl Shorthand { + pub fn transfer(origin: Option, address: SeraiAddress) -> Option { + Some(Self::Raw( + BoundedVec::try_from( + (RefundableInInstruction { origin, instruction: InInstruction::Transfer(address) }) + .encode(), + ) + .ok()?, + )) + } +} + +impl TryFrom for RefundableInInstruction { + type Error = &'static str; + fn try_from(shorthand: Shorthand) -> Result { + Ok(match shorthand { + Shorthand::Raw(raw) => { + RefundableInInstruction::decode(&mut raw.as_ref()).map_err(|_| "invalid raw instruction")? + } + Shorthand::Swap { .. } => todo!(), + Shorthand::AddLiquidity { .. } => todo!(), + }) + } +} diff --git a/substrate/node/Cargo.toml b/substrate/node/Cargo.toml index c20ddee2..dd51b15c 100644 --- a/substrate/node/Cargo.toml +++ b/substrate/node/Cargo.toml @@ -14,17 +14,11 @@ name = "serai-node" [dependencies] async-trait = "0.1" -log = "0.4" - -futures = { version = "0.3" } - clap = { version = "4", features = ["derive"] } jsonrpsee = { version = "0.16", features = ["server"] } sp-core = { git = "https://github.com/serai-dex/substrate" } -sp-application-crypto = { git = "https://github.com/serai-dex/substrate" } -sp-keystore = { git = "https://github.com/serai-dex/substrate" } sp-keyring = { git = "https://github.com/serai-dex/substrate" } sp-inherents = { git = "https://github.com/serai-dex/substrate" } sp-runtime = { git = "https://github.com/serai-dex/substrate" } @@ -33,7 +27,11 @@ sp-api = { git = "https://github.com/serai-dex/substrate" } sp-block-builder = { git = "https://github.com/serai-dex/substrate" } sp-consensus = { git = "https://github.com/serai-dex/substrate" } -sc-keystore = { git = "https://github.com/serai-dex/substrate" } +frame-benchmarking = { git = "https://github.com/serai-dex/substrate" } +frame-benchmarking-cli = { git = "https://github.com/serai-dex/substrate" } + +serai-runtime = { path = "../runtime" } + sc-transaction-pool = { git = "https://github.com/serai-dex/substrate" } sc-transaction-pool-api = { git = "https://github.com/serai-dex/substrate" } sc-basic-authorship = { git = "https://github.com/serai-dex/substrate" } @@ -47,24 +45,13 @@ sc-consensus = { git = "https://github.com/serai-dex/substrate" } sc-telemetry = { git = "https://github.com/serai-dex/substrate" } sc-cli = { git = "https://github.com/serai-dex/substrate" } -frame-system = { git = "https://github.com/serai-dex/substrate" } -frame-benchmarking = { git = "https://github.com/serai-dex/substrate" } -frame-benchmarking-cli = { git = "https://github.com/serai-dex/substrate" } -pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", default-features = false } - -sc-rpc = { git = "https://github.com/serai-dex/substrate" } sc-rpc-api = { git = "https://github.com/serai-dex/substrate" } substrate-frame-rpc-system = { git = "https://github.com/serai-dex/substrate" } pallet-transaction-payment-rpc = { git = "https://github.com/serai-dex/substrate" } -serai-primitives = { path = "../serai/primitives" } +in-instructions-client = { path = "../in-instructions/client" } -validator-sets-pallet = { path = "../validator-sets/pallet" } - -sp-tendermint = { path = "../tendermint/primitives" } -pallet-tendermint = { path = "../tendermint/pallet", default-features = false } -serai-runtime = { path = "../runtime" } sc-tendermint = { path = "../tendermint/client" } [build-dependencies] diff --git a/substrate/node/src/chain_spec.rs b/substrate/node/src/chain_spec.rs index 58aa9321..63ca7a05 100644 --- a/substrate/node/src/chain_spec.rs +++ b/substrate/node/src/chain_spec.rs @@ -3,12 +3,9 @@ use sp_runtime::traits::TrailingZeroInput; use sc_service::ChainType; -use serai_primitives::*; -use pallet_tendermint::crypto::Public; - use serai_runtime::{ - WASM_BINARY, AccountId, opaque::SessionKeys, GenesisConfig, SystemConfig, BalancesConfig, - AssetsConfig, ValidatorSetsConfig, SessionConfig, + primitives::*, tendermint::crypto::Public, WASM_BINARY, opaque::SessionKeys, GenesisConfig, + SystemConfig, BalancesConfig, AssetsConfig, ValidatorSetsConfig, SessionConfig, }; pub type ChainSpec = sc_service::GenericChainSpec; @@ -17,22 +14,22 @@ fn insecure_pair_from_name(name: &'static str) -> Pair { Pair::from_string(&format!("//{name}"), None).unwrap() } -fn account_id_from_name(name: &'static str) -> AccountId { +fn address_from_name(name: &'static str) -> SeraiAddress { insecure_pair_from_name(name).public() } fn testnet_genesis( wasm_binary: &[u8], validators: &[&'static str], - endowed_accounts: Vec, + endowed_accounts: Vec, ) -> GenesisConfig { let session_key = |name| { - let key = account_id_from_name(name); + let key = address_from_name(name); (key, key, SessionKeys { tendermint: Public::from(key) }) }; // TODO: Replace with a call to the pallet to ask for its account - let owner = AccountId::decode(&mut TrailingZeroInput::new(b"tokens")).unwrap(); + let owner = SeraiAddress::decode(&mut TrailingZeroInput::new(b"tokens")).unwrap(); GenesisConfig { system: SystemConfig { code: wasm_binary.to_vec() }, @@ -54,8 +51,8 @@ fn testnet_genesis( validator_sets: ValidatorSetsConfig { bond: Amount(1_000_000) * COIN, - coins: Coin(4), - participants: validators.iter().map(|name| account_id_from_name(name)).collect(), + coins: vec![BITCOIN, ETHER, DAI, MONERO], + participants: validators.iter().map(|name| address_from_name(name)).collect(), }, session: SessionConfig { keys: validators.iter().map(|name| session_key(*name)).collect() }, } @@ -75,18 +72,18 @@ pub fn development_config() -> Result { wasm_binary, &["Alice"], vec![ - account_id_from_name("Alice"), - account_id_from_name("Bob"), - account_id_from_name("Charlie"), - account_id_from_name("Dave"), - account_id_from_name("Eve"), - account_id_from_name("Ferdie"), - account_id_from_name("Alice//stash"), - account_id_from_name("Bob//stash"), - account_id_from_name("Charlie//stash"), - account_id_from_name("Dave//stash"), - account_id_from_name("Eve//stash"), - account_id_from_name("Ferdie//stash"), + address_from_name("Alice"), + address_from_name("Bob"), + address_from_name("Charlie"), + address_from_name("Dave"), + address_from_name("Eve"), + address_from_name("Ferdie"), + address_from_name("Alice//stash"), + address_from_name("Bob//stash"), + address_from_name("Charlie//stash"), + address_from_name("Dave//stash"), + address_from_name("Eve//stash"), + address_from_name("Ferdie//stash"), ], ) }, @@ -119,18 +116,18 @@ pub fn testnet_config() -> Result { wasm_binary, &["Alice", "Bob", "Charlie"], vec![ - account_id_from_name("Alice"), - account_id_from_name("Bob"), - account_id_from_name("Charlie"), - account_id_from_name("Dave"), - account_id_from_name("Eve"), - account_id_from_name("Ferdie"), - account_id_from_name("Alice//stash"), - account_id_from_name("Bob//stash"), - account_id_from_name("Charlie//stash"), - account_id_from_name("Dave//stash"), - account_id_from_name("Eve//stash"), - account_id_from_name("Ferdie//stash"), + address_from_name("Alice"), + address_from_name("Bob"), + address_from_name("Charlie"), + address_from_name("Dave"), + address_from_name("Eve"), + address_from_name("Ferdie"), + address_from_name("Alice//stash"), + address_from_name("Bob//stash"), + address_from_name("Charlie//stash"), + address_from_name("Dave//stash"), + address_from_name("Eve//stash"), + address_from_name("Ferdie//stash"), ], ) }, diff --git a/substrate/node/src/command.rs b/substrate/node/src/command.rs index 73fc1b31..20cd0e29 100644 --- a/substrate/node/src/command.rs +++ b/substrate/node/src/command.rs @@ -1,9 +1,10 @@ -use sc_service::{PruningMode, PartialComponents}; -use frame_benchmarking_cli::{ExtrinsicFactory, BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; -use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli}; - use serai_runtime::Block; +use sc_service::{PruningMode, PartialComponents}; + +use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli}; +use frame_benchmarking_cli::{ExtrinsicFactory, BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; + use crate::{ chain_spec, cli::{Cli, Subcommand}, diff --git a/substrate/node/src/command_helper.rs b/substrate/node/src/command_helper.rs index fc649357..7d944b69 100644 --- a/substrate/node/src/command_helper.rs +++ b/substrate/node/src/command_helper.rs @@ -9,8 +9,11 @@ use sp_runtime::OpaqueExtrinsic; use sc_cli::Result; use sc_client_api::BlockBackend; -use serai_runtime as runtime; -use runtime::SystemCall; +use serai_runtime::{ + VERSION, BlockHashCount, + system::{self, Call as SystemCall}, + transaction_payment, RuntimeCall, UncheckedExtrinsic, SignedPayload, Runtime, +}; use crate::service::FullClient; @@ -45,35 +48,33 @@ impl frame_benchmarking_cli::ExtrinsicBuilder for RemarkBuilder { pub fn create_benchmark_extrinsic( client: &FullClient, sender: sp_core::sr25519::Pair, - call: runtime::RuntimeCall, + call: RuntimeCall, nonce: u32, -) -> runtime::UncheckedExtrinsic { +) -> UncheckedExtrinsic { let extra = ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(sp_runtime::generic::Era::mortal( - u64::from( - runtime::BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2), - ), + system::CheckNonZeroSender::::new(), + system::CheckSpecVersion::::new(), + system::CheckTxVersion::::new(), + system::CheckGenesis::::new(), + system::CheckEra::::from(sp_runtime::generic::Era::mortal( + u64::from(BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2)), client.chain_info().best_number.into(), )), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), + system::CheckNonce::::from(nonce), + system::CheckWeight::::new(), + transaction_payment::ChargeTransactionPayment::::from(0), ); - runtime::UncheckedExtrinsic::new_signed( + UncheckedExtrinsic::new_signed( call.clone(), sender.public(), - runtime::SignedPayload::from_raw( + SignedPayload::from_raw( call, extra.clone(), ( (), - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, + VERSION.spec_version, + VERSION.transaction_version, client.block_hash(0).ok().flatten().unwrap(), client.chain_info().best_hash, (), diff --git a/substrate/node/src/rpc.rs b/substrate/node/src/rpc.rs index 076c8dc2..c5df739d 100644 --- a/substrate/node/src/rpc.rs +++ b/substrate/node/src/rpc.rs @@ -3,13 +3,13 @@ use std::sync::Arc; use jsonrpsee::RpcModule; use sp_blockchain::{Error as BlockchainError, HeaderBackend, HeaderMetadata}; -use sc_transaction_pool_api::TransactionPool; use sp_block_builder::BlockBuilder; use sp_api::ProvideRuntimeApi; -pub use sc_rpc_api::DenyUnsafe; +use serai_runtime::{primitives::SeraiAddress, opaque::Block, Balance, Index}; -use serai_runtime::{opaque::Block, AccountId, Balance, Index}; +pub use sc_rpc_api::DenyUnsafe; +use sc_transaction_pool_api::TransactionPool; pub struct FullDeps { pub client: Arc, @@ -29,7 +29,7 @@ pub fn create_full< deps: FullDeps, ) -> Result, Box> where - C::Api: substrate_frame_rpc_system::AccountNonceApi + C::Api: substrate_frame_rpc_system::AccountNonceApi + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + BlockBuilder, { diff --git a/substrate/node/src/service.rs b/substrate/node/src/service.rs index f063641d..f6aa1e1f 100644 --- a/substrate/node/src/service.rs +++ b/substrate/node/src/service.rs @@ -11,6 +11,8 @@ use sp_inherents::CreateInherentDataProviders; use sp_consensus::DisableProofRecording; use sp_api::ProvideRuntimeApi; +use in_instructions_client::InherentDataProvider as InstructionsProvider; + use sc_executor::{NativeVersion, NativeExecutionDispatch, NativeElseWasmExecutor}; use sc_transaction_pool::FullPool; use sc_network::NetworkService; @@ -24,7 +26,7 @@ pub(crate) use sc_tendermint::{ TendermintClientMinimal, TendermintValidator, TendermintImport, TendermintAuthority, TendermintSelectChain, import_queue, }; -use serai_runtime::{self, BLOCK_SIZE, TARGET_BLOCK_TIME, opaque::Block, RuntimeApi}; +use serai_runtime::{self as runtime, BLOCK_SIZE, TARGET_BLOCK_TIME, opaque::Block, RuntimeApi}; type FullBackend = sc_service::TFullBackend; pub type FullClient = TFullClient>; @@ -46,7 +48,7 @@ impl NativeExecutionDispatch for ExecutorDispatch { type ExtendHostFunctions = (); fn dispatch(method: &str, data: &[u8]) -> Option> { - serai_runtime::api::dispatch(method, data) + runtime::api::dispatch(method, data) } fn native_version() -> NativeVersion { @@ -57,13 +59,13 @@ impl NativeExecutionDispatch for ExecutorDispatch { pub struct Cidp; #[async_trait::async_trait] impl CreateInherentDataProviders for Cidp { - type InherentDataProviders = (); + type InherentDataProviders = (InstructionsProvider,); async fn create_inherent_data_providers( &self, _: ::Hash, _: (), ) -> Result> { - Ok(()) + Ok((InstructionsProvider::new(),)) } } diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index 78a5f32f..a379fdb9 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -12,13 +12,12 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -hex-literal = { version = "0.3.4", optional = true } +hex-literal = { version = "0.3", optional = true } codec = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } scale-info = { version = "2", default-features = false, features = ["derive"] } sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-application-crypto = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-version = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-inherents = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -42,6 +41,8 @@ pallet-balances = { git = "https://github.com/serai-dex/substrate", default-feat pallet-assets = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", default-features = false } +in-instructions-pallet = { path = "../in-instructions/pallet", default-features = false } + validator-sets-pallet = { path = "../validator-sets/pallet", default-features = false } pallet-session = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-tendermint = { path = "../tendermint/pallet", default-features = false } @@ -58,7 +59,6 @@ std = [ "scale-info/std", "sp-core/std", - "sp-application-crypto/std", "sp-std/std", "sp-version/std", "sp-inherents/std", @@ -81,6 +81,8 @@ std = [ "pallet-assets/std", "pallet-transaction-payment/std", + "in-instructions-pallet/std", + "validator-sets-pallet/std", "pallet-session/std", "pallet-tendermint/std", diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 2f792076..91d48750 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -1,23 +1,46 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit = "256"] #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +// Re-export all components +pub use serai_primitives as primitives; + +pub use frame_system as system; +pub use frame_support as support; + +pub use pallet_balances as balances; +pub use pallet_transaction_payment as transaction_payment; + +pub use pallet_assets as assets; +pub use in_instructions_pallet as in_instructions; + +pub use validator_sets_pallet as validator_sets; + +pub use pallet_session as session; +pub use pallet_tendermint as tendermint; + +// Actually used by the runtime use sp_core::OpaqueMetadata; -pub use sp_core::sr25519::{Public, Signature}; +use sp_std::prelude::*; + +use sp_version::RuntimeVersion; +#[cfg(feature = "std")] +use sp_version::NativeVersion; + use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, KeyTypeId, traits::{Convert, OpaqueKeys, IdentityLookup, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, }; -use sp_std::prelude::*; -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; -use frame_support::{ +use primitives::{PublicKey, Signature, SeraiAddress, Coin}; + +use support::{ traits::{ConstU8, ConstU32, ConstU64}, weights::{ constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND}, @@ -25,22 +48,14 @@ use frame_support::{ }, parameter_types, construct_runtime, }; -pub use frame_system::Call as SystemCall; -use serai_primitives::Coin; +use transaction_payment::CurrencyAdapter; -pub use pallet_balances::Call as BalancesCall; -pub use pallet_assets::Call as AssetsCall; -use pallet_transaction_payment::CurrencyAdapter; - -use pallet_session::PeriodicSessions; +use session::PeriodicSessions; /// An index to a block. pub type BlockNumber = u32; -/// Account ID type, equivalent to a public key -pub type AccountId = Public; - /// Balance of an account. // Distinct from serai-primitives Amount due to Substrate's requirements on this type. // If Amount could be dropped in here, it would be. @@ -58,7 +73,7 @@ pub type Hash = sp_core::H256; pub mod opaque { use super::*; - pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; pub type Header = generic::Header; pub type Block = generic::Block; @@ -110,22 +125,22 @@ parameter_types! { pub const SS58Prefix: u8 = 42; // TODO: Remove for Bech32m // 1 MB block size limit - pub BlockLength: frame_system::limits::BlockLength = - frame_system::limits::BlockLength::max_with_normal_ratio(BLOCK_SIZE, NORMAL_DISPATCH_RATIO); - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::with_sensible_defaults( + pub BlockLength: system::limits::BlockLength = + system::limits::BlockLength::max_with_normal_ratio(BLOCK_SIZE, NORMAL_DISPATCH_RATIO); + pub BlockWeights: system::limits::BlockWeights = + system::limits::BlockWeights::with_sensible_defaults( Weight::from_ref_time(2u64 * WEIGHT_REF_TIME_PER_SECOND).set_proof_size(u64::MAX), NORMAL_DISPATCH_RATIO, ); } -impl frame_system::Config for Runtime { - type BaseCallFilter = frame_support::traits::Everything; +impl system::Config for Runtime { + type BaseCallFilter = support::traits::Everything; type BlockWeights = BlockWeights; type BlockLength = BlockLength; - type AccountId = AccountId; + type AccountId = SeraiAddress; type RuntimeCall = RuntimeCall; - type Lookup = IdentityLookup; + type Lookup = IdentityLookup; type Index = Index; type BlockNumber = BlockNumber; type Hash = Hash; @@ -142,14 +157,14 @@ impl frame_system::Config for Runtime { type OnKilledAccount = (); type OnSetCode = (); - type AccountData = pallet_balances::AccountData; + type AccountData = balances::AccountData; type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; // TODO: Remove for Bech32m - type MaxConsumers = frame_support::traits::ConstU32<16>; + type MaxConsumers = support::traits::ConstU32<16>; } -impl pallet_balances::Config for Runtime { +impl balances::Config for Runtime { type MaxLocks = ConstU32<50>; type MaxReserves = (); type ReserveIdentifier = [u8; 8]; @@ -158,10 +173,10 @@ impl pallet_balances::Config for Runtime { type DustRemoval = (); type ExistentialDeposit = ConstU64<500>; type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; + type WeightInfo = balances::weights::SubstrateWeight; } -impl pallet_assets::Config for Runtime { +impl assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type Currency = Balances; @@ -171,9 +186,8 @@ impl pallet_assets::Config for Runtime { type StringLimit = ConstU32<32>; // Don't allow anyone to create assets - type CreateOrigin = - frame_support::traits::AsEnsureOriginWithArg>; - type ForceOrigin = frame_system::EnsureRoot; + type CreateOrigin = support::traits::AsEnsureOriginWithArg>; + type ForceOrigin = system::EnsureRoot; // Don't charge fees nor kill accounts type RemoveItemsLimit = ConstU32<0>; @@ -188,12 +202,12 @@ impl pallet_assets::Config for Runtime { type Freezer = (); type Extra = (); - type WeightInfo = pallet_assets::weights::SubstrateWeight; + type WeightInfo = assets::weights::SubstrateWeight; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = (); } -impl pallet_transaction_payment::Config for Runtime { +impl transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter; type OperationalFeeMultiplier = ConstU8<5>; @@ -202,54 +216,57 @@ impl pallet_transaction_payment::Config for Runtime { type FeeMultiplierUpdate = (); } +impl in_instructions::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} + const SESSION_LENGTH: BlockNumber = 5 * DAYS; type Sessions = PeriodicSessions, ConstU32<{ SESSION_LENGTH }>>; pub struct IdentityValidatorIdOf; -impl Convert> for IdentityValidatorIdOf { - fn convert(key: Public) -> Option { +impl Convert> for IdentityValidatorIdOf { + fn convert(key: PublicKey) -> Option { Some(key) } } -impl validator_sets_pallet::Config for Runtime { +impl validator_sets::Config for Runtime { type RuntimeEvent = RuntimeEvent; } -impl pallet_session::Config for Runtime { +impl session::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type ValidatorId = AccountId; + type ValidatorId = SeraiAddress; type ValidatorIdOf = IdentityValidatorIdOf; type ShouldEndSession = Sessions; type NextSessionRotation = Sessions; type SessionManager = (); type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; - type WeightInfo = pallet_session::weights::SubstrateWeight; + type WeightInfo = session::weights::SubstrateWeight; } -impl pallet_tendermint::Config for Runtime {} +impl tendermint::Config for Runtime {} -pub type Address = AccountId; pub type Header = generic::Header; pub type Block = generic::Block; pub type SignedExtra = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, + system::CheckNonZeroSender, + system::CheckSpecVersion, + system::CheckTxVersion, + system::CheckGenesis, + system::CheckEra, + system::CheckNonce, + system::CheckWeight, + transaction_payment::ChargeTransactionPayment, ); pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type SignedPayload = generic::SignedPayload; pub type Executive = frame_executive::Executive< Runtime, Block, - frame_system::ChainContext, + system::ChainContext, Runtime, AllPalletsWithSystem, >; @@ -260,14 +277,18 @@ construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: frame_system, - Balances: pallet_balances, - Assets: pallet_assets, - TransactionPayment: pallet_transaction_payment, + System: system, - ValidatorSets: validator_sets_pallet, - Session: pallet_session, - Tendermint: pallet_tendermint, + Balances: balances, + TransactionPayment: transaction_payment, + + Assets: assets, + InInstructions: in_instructions, + + ValidatorSets: validator_sets, + + Session: session, + Tendermint: tendermint, } ); @@ -279,8 +300,8 @@ extern crate frame_benchmarking; mod benches { define_benchmarks!( [frame_benchmarking, BaselineBench::] - [frame_system, SystemBench::] - [pallet_balances, Balances] + [system, SystemBench::] + [balances, Balances] ); } @@ -359,13 +380,13 @@ sp_api::impl_runtime_apis! { Tendermint::session() } - fn validators() -> Vec { + fn validators() -> Vec { Session::validators() } } - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Index { + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: SeraiAddress) -> Index { System::account_nonce(account) } } @@ -380,10 +401,11 @@ sp_api::impl_runtime_apis! { ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { TransactionPayment::query_info(uxt, len) } + fn query_fee_details( uxt: ::Extrinsic, len: u32, - ) -> pallet_transaction_payment::FeeDetails { + ) -> transaction_payment::FeeDetails { TransactionPayment::query_fee_details(uxt, len) } } diff --git a/substrate/serai/client/Cargo.toml b/substrate/serai/client/Cargo.toml new file mode 100644 index 00000000..ca35be61 --- /dev/null +++ b/substrate/serai/client/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "serai-client" +version = "0.1.0" +description = "Client library for the Serai network" +license = "AGPL-3.0-only" +repository = "https://github.com/serai-dex/serai/tree/develop/client" +authors = ["Luke Parker "] +keywords = ["serai"] +edition = "2021" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +thiserror = "1" + +serde = { version = "1", features = ["derive"] } + +scale = { package = "parity-scale-codec", version = "3" } +scale-value = "0.6" +subxt = "0.25" + +serai-primitives = { path = "../primitives", version = "0.1" } +in-instructions-primitives = { path = "../../in-instructions/primitives", version = "0.1" } +serai-runtime = { path = "../../runtime", version = "0.1" } + +[dev-dependencies] +lazy_static = "1" + +tokio = "1" + +jsonrpsee-server = "0.16" diff --git a/substrate/serai/client/LICENSE b/substrate/serai/client/LICENSE new file mode 100644 index 00000000..c425427c --- /dev/null +++ b/substrate/serai/client/LICENSE @@ -0,0 +1,15 @@ +AGPL-3.0-only license + +Copyright (c) 2022-2023 Luke Parker + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License Version 3 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . diff --git a/substrate/serai/client/src/in_instructions.rs b/substrate/serai/client/src/in_instructions.rs new file mode 100644 index 00000000..8c26b80a --- /dev/null +++ b/substrate/serai/client/src/in_instructions.rs @@ -0,0 +1,49 @@ +use scale::Decode; + +use serai_runtime::{ + support::traits::PalletInfo as PalletInfoTrait, PalletInfo, in_instructions, InInstructions, + Runtime, +}; + +pub use in_instructions_primitives as primitives; + +use crate::{ + primitives::{Coin, BlockNumber}, + Serai, SeraiError, +}; + +const PALLET: &str = "InInstructions"; + +pub type InInstructionsEvent = in_instructions::Event; + +impl Serai { + pub async fn get_batch_events( + &self, + block: [u8; 32], + ) -> Result, SeraiError> { + let mut res = vec![]; + for event in + self.0.events().at(Some(block.into())).await.map_err(|_| SeraiError::RpcError)?.iter() + { + let event = event.map_err(|_| SeraiError::InvalidRuntime)?; + if PalletInfo::index::().unwrap() == usize::from(event.pallet_index()) { + let mut with_variant: &[u8] = + &[[event.variant_index()].as_ref(), event.field_bytes()].concat(); + let event = + InInstructionsEvent::decode(&mut with_variant).map_err(|_| SeraiError::InvalidRuntime)?; + if matches!(event, InInstructionsEvent::Batch { .. }) { + res.push(event); + } + } + } + Ok(res) + } + + pub async fn get_coin_block_number( + &self, + coin: Coin, + block: [u8; 32], + ) -> Result { + Ok(self.storage(PALLET, "BlockNumbers", Some(coin), block).await?.unwrap_or(BlockNumber(0))) + } +} diff --git a/substrate/serai/client/src/lib.rs b/substrate/serai/client/src/lib.rs new file mode 100644 index 00000000..36bfd8a5 --- /dev/null +++ b/substrate/serai/client/src/lib.rs @@ -0,0 +1,77 @@ +use thiserror::Error; + +use serde::Serialize; +use scale::Decode; + +use subxt::{tx::BaseExtrinsicParams, Config as SubxtConfig, OnlineClient}; + +pub use serai_primitives as primitives; +use primitives::{Signature, SeraiAddress}; + +use serai_runtime::{system::Config, Runtime}; + +pub mod in_instructions; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub(crate) struct SeraiConfig; +impl SubxtConfig for SeraiConfig { + type BlockNumber = ::BlockNumber; + + type Hash = ::Hash; + type Hashing = ::Hashing; + + type Index = ::Index; + type AccountId = ::AccountId; + // TODO: Bech32m + type Address = SeraiAddress; + + type Header = ::Header; + type Signature = Signature; + + type ExtrinsicParams = BaseExtrinsicParams; +} + +#[derive(Clone, Error, Debug)] +pub enum SeraiError { + #[error("failed to connect to serai")] + RpcError, + #[error("serai-client library was intended for a different runtime version")] + InvalidRuntime, +} + +#[derive(Clone)] +pub struct Serai(OnlineClient); + +impl Serai { + pub async fn new(url: &str) -> Result { + Ok(Serai(OnlineClient::::from_url(url).await.map_err(|_| SeraiError::RpcError)?)) + } + + async fn storage( + &self, + pallet: &'static str, + name: &'static str, + key: Option, + block: [u8; 32], + ) -> Result, SeraiError> { + let mut keys = vec![]; + if let Some(key) = key { + keys.push(scale_value::serde::to_value(key).unwrap()); + } + + let storage = self.0.storage(); + let address = subxt::dynamic::storage(pallet, name, keys); + debug_assert!(storage.validate(&address).is_ok()); + + storage + .fetch(&address, Some(block.into())) + .await + .map_err(|_| SeraiError::RpcError)? + .map(|res| R::decode(&mut res.encoded()).map_err(|_| SeraiError::InvalidRuntime)) + .transpose() + } + + pub async fn get_latest_block_hash(&self) -> Result<[u8; 32], SeraiError> { + Ok(self.0.rpc().finalized_head().await.map_err(|_| SeraiError::RpcError)?.into()) + } +} diff --git a/substrate/serai/client/tests/runner.rs b/substrate/serai/client/tests/runner.rs new file mode 100644 index 00000000..e5ed4542 --- /dev/null +++ b/substrate/serai/client/tests/runner.rs @@ -0,0 +1,50 @@ +use lazy_static::lazy_static; + +use tokio::sync::Mutex; + +pub const URL: &str = "ws://127.0.0.1:9944"; + +lazy_static! { + pub static ref SEQUENTIAL: Mutex<()> = Mutex::new(()); +} + +#[macro_export] +macro_rules! serai_test { + ($(async fn $name: ident() $body: block)*) => { + $( + #[tokio::test] + async fn $name() { + let guard = runner::SEQUENTIAL.lock().await; + + // Spawn a fresh Serai node + let mut command = { + use core::time::Duration; + use std::{path::Path, process::Command}; + + let node = { + let this_crate = Path::new(env!("CARGO_MANIFEST_DIR")); + let top_level = this_crate.join("../../../"); + top_level.join("target/debug/serai-node") + }; + + let command = Command::new(node).arg("--dev").spawn().unwrap(); + while Serai::new(URL).await.is_err() { + tokio::time::sleep(Duration::from_secs(1)).await; + } + command + }; + + let local = tokio::task::LocalSet::new(); + local.run_until(async move { + if let Err(err) = tokio::task::spawn_local(async move { $body }).await { + drop(guard); + let _ = command.kill(); + Err(err).unwrap() + } else { + command.kill().unwrap(); + } + }).await; + } + )* + } +} diff --git a/substrate/serai/client/tests/updates.rs b/substrate/serai/client/tests/updates.rs new file mode 100644 index 00000000..ba97bc73 --- /dev/null +++ b/substrate/serai/client/tests/updates.rs @@ -0,0 +1,60 @@ +use core::time::Duration; + +use tokio::time::sleep; + +use serai_runtime::in_instructions::{Batch, Update}; + +use jsonrpsee_server::RpcModule; + +use serai_client::{ + primitives::{BlockNumber, BlockHash, SeraiAddress, BITCOIN}, + in_instructions::{primitives::InInstruction, InInstructionsEvent}, + Serai, +}; + +mod runner; +use runner::URL; + +serai_test!( + async fn publish_update() { + let mut rpc = RpcModule::new(()); + rpc + .register_async_method("processor_coinUpdates", |_, _| async move { + let batch = Batch { + id: BlockHash([0xaa; 32]), + instructions: vec![InInstruction::Transfer(SeraiAddress::from_raw([0xff; 32]))], + }; + + Ok(vec![Some(Update { block_number: BlockNumber(123), batches: vec![batch] })]) + }) + .unwrap(); + + let _handle = jsonrpsee_server::ServerBuilder::default() + .build("127.0.0.1:5134") + .await + .unwrap() + .start(rpc) + .unwrap(); + + let serai = Serai::new(URL).await.unwrap(); + loop { + let latest = serai.get_latest_block_hash().await.unwrap(); + let batches = serai.get_batch_events(latest).await.unwrap(); + if let Some(batch) = batches.get(0) { + match batch { + InInstructionsEvent::Batch { coin, id } => { + assert_eq!(coin, &BITCOIN); + assert_eq!(id, &BlockHash([0xaa; 32])); + assert_eq!( + serai.get_coin_block_number(BITCOIN, latest).await.unwrap(), + BlockNumber(123) + ); + return; + } + _ => panic!("get_batches returned non-batch"), + } + } + sleep(Duration::from_millis(50)).await; + } + } +); diff --git a/substrate/serai/primitives/Cargo.toml b/substrate/serai/primitives/Cargo.toml index 5d063638..5d6a1490 100644 --- a/substrate/serai/primitives/Cargo.toml +++ b/substrate/serai/primitives/Cargo.toml @@ -15,11 +15,10 @@ rustdoc-args = ["--cfg", "docsrs"] scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } scale-info = { version = "2", default-features = false, features = ["derive"] } -serde = { version = "1.0", features = ["derive"], optional = true } +serde = { version = "1", features = ["derive"], optional = true } sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } [features] -std = ["scale/std", "scale-info/std", "serde", "sp-core/std", "sp-std/std"] +std = ["scale/std", "scale-info/std", "serde", "sp-core/std"] default = ["std"] diff --git a/substrate/serai/primitives/src/amount.rs b/substrate/serai/primitives/src/amount.rs index e125e339..e3f0fcaf 100644 --- a/substrate/serai/primitives/src/amount.rs +++ b/substrate/serai/primitives/src/amount.rs @@ -9,7 +9,7 @@ use serde::{Serialize, Deserialize}; /// The type used for amounts. #[derive( - Clone, Copy, PartialEq, Eq, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, + Clone, Copy, PartialEq, Eq, PartialOrd, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, )] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct Amount(pub u64); diff --git a/substrate/serai/primitives/src/coins.rs b/substrate/serai/primitives/src/coins.rs index a1a7af3c..6a587df4 100644 --- a/substrate/serai/primitives/src/coins.rs +++ b/substrate/serai/primitives/src/coins.rs @@ -4,7 +4,7 @@ use scale_info::TypeInfo; use serde::{Serialize, Deserialize}; /// The type used to identify coins. -#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct Coin(pub u32); impl From for Coin { @@ -13,7 +13,8 @@ impl From for Coin { } } -pub const BITCOIN: Coin = Coin(0); -pub const ETHER: Coin = Coin(1); -pub const DAI: Coin = Coin(2); -pub const MONERO: Coin = Coin(3); +pub const SERAI: Coin = Coin(0); +pub const BITCOIN: Coin = Coin(1); +pub const ETHER: Coin = Coin(2); +pub const DAI: Coin = Coin(3); +pub const MONERO: Coin = Coin(4); diff --git a/substrate/serai/primitives/src/lib.rs b/substrate/serai/primitives/src/lib.rs index 65e860b3..2d4dc14b 100644 --- a/substrate/serai/primitives/src/lib.rs +++ b/substrate/serai/primitives/src/lib.rs @@ -1,7 +1,63 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(not(feature = "std"), no_std)] +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use sp_core::{ + H256, + sr25519::{Public, Signature as RistrettoSignature}, +}; + mod amount; pub use amount::*; mod coins; pub use coins::*; + +pub type PublicKey = Public; +pub type SeraiAddress = PublicKey; +pub type Signature = RistrettoSignature; + +/// The type used to identify block numbers. +// Doesn't re-export tendermint-machine's due to traits. +#[derive( + Clone, Copy, Default, PartialEq, Eq, Hash, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, +)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct BlockNumber(pub u32); +impl From for BlockNumber { + fn from(number: u32) -> BlockNumber { + BlockNumber(number) + } +} + +/// The type used to identify block hashes. +// This may not be universally compatible +// If a block exists with a hash which isn't 32-bytes, it can be hashed into a value with 32-bytes +// This would require the processor to maintain a mapping of 32-byte IDs to actual hashes, which +// would be fine +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct BlockHash(pub [u8; 32]); + +impl AsRef<[u8]> for BlockHash { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl From<[u8; 32]> for BlockHash { + fn from(hash: [u8; 32]) -> BlockHash { + BlockHash(hash) + } +} + +impl From for BlockHash { + fn from(hash: H256) -> BlockHash { + BlockHash(hash.into()) + } +} diff --git a/substrate/tendermint/client/Cargo.toml b/substrate/tendermint/client/Cargo.toml index 0698f633..e78f99bb 100644 --- a/substrate/tendermint/client/Cargo.toml +++ b/substrate/tendermint/client/Cargo.toml @@ -33,8 +33,6 @@ sp-consensus = { git = "https://github.com/serai-dex/substrate" } sp-tendermint = { path = "../primitives" } -sc-transaction-pool = { git = "https://github.com/serai-dex/substrate" } -sc-executor = { git = "https://github.com/serai-dex/substrate" } sc-network-common = { git = "https://github.com/serai-dex/substrate" } sc-network = { git = "https://github.com/serai-dex/substrate" } sc-network-gossip = { git = "https://github.com/serai-dex/substrate" } diff --git a/substrate/tendermint/machine/Cargo.toml b/substrate/tendermint/machine/Cargo.toml index 7184e057..4ba9337d 100644 --- a/substrate/tendermint/machine/Cargo.toml +++ b/substrate/tendermint/machine/Cargo.toml @@ -13,7 +13,7 @@ thiserror = "1" log = "0.4" -parity-scale-codec = { version = "3.2", features = ["derive"] } +parity-scale-codec = { version = "3", features = ["derive"] } futures = "0.3" tokio = { version = "1", features = ["macros", "sync", "time", "rt"] } diff --git a/substrate/validator-sets/pallet/src/lib.rs b/substrate/validator-sets/pallet/src/lib.rs index 7ac8a700..b99fc2f5 100644 --- a/substrate/validator-sets/pallet/src/lib.rs +++ b/substrate/validator-sets/pallet/src/lib.rs @@ -17,14 +17,14 @@ pub mod pallet { } #[pallet::genesis_config] - #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen)] + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] pub struct GenesisConfig { /// Bond requirement to join the initial validator set. /// Every participant at genesis will automatically be assumed to have this much bond. /// This bond cannot be withdrawn however as there's no stake behind it. pub bond: Amount, - /// Amount of coins to spawn the network with in the initial validator set. - pub coins: Coin, + /// Coins to spawn the network with in the initial validator set. + pub coins: Vec, /// List of participants to place in the genesis set. pub participants: Vec, } @@ -32,7 +32,7 @@ pub mod pallet { #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { - GenesisConfig { bond: Amount(1), coins: Coin(0), participants: vec![] } + GenesisConfig { bond: Amount(1), coins: vec![], participants: vec![] } } } @@ -95,11 +95,6 @@ pub mod pallet { #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { - let mut coins = Vec::new(); - for coin in 0 .. self.coins.0 { - coins.push(Coin(coin)); - } - let mut participants = Vec::new(); for participant in self.participants.clone() { participants.push((participant, self.bond)); @@ -109,7 +104,7 @@ pub mod pallet { ValidatorSetInstance(Session(0), ValidatorSetIndex(0)), Some(ValidatorSet { bond: self.bond, - coins: BoundedVec::try_from(coins).unwrap(), + coins: BoundedVec::try_from(self.coins.clone()).unwrap(), participants: BoundedVec::try_from(participants).unwrap(), }), ); diff --git a/substrate/validator-sets/primitives/Cargo.toml b/substrate/validator-sets/primitives/Cargo.toml index 7da45dd2..e458ae95 100644 --- a/substrate/validator-sets/primitives/Cargo.toml +++ b/substrate/validator-sets/primitives/Cargo.toml @@ -15,11 +15,8 @@ rustdoc-args = ["--cfg", "docsrs"] scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } scale-info = { version = "2", default-features = false, features = ["derive"] } -serde = { version = "1.0", features = ["derive"], optional = true } - -sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } +serde = { version = "1", features = ["derive"], optional = true } [features] -std = ["scale/std", "scale-info/std", "serde", "sp-core/std", "sp-std/std"] +std = ["scale/std", "scale-info/std", "serde"] default = ["std"] From 27f5881553393175d2feac57b41ac9e20406bead Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 20 Jan 2023 08:08:20 -0500 Subject: [PATCH 36/74] Ensure Amount uses checked ops --- substrate/serai/primitives/src/amount.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/substrate/serai/primitives/src/amount.rs b/substrate/serai/primitives/src/amount.rs index e3f0fcaf..daf40abe 100644 --- a/substrate/serai/primitives/src/amount.rs +++ b/substrate/serai/primitives/src/amount.rs @@ -1,6 +1,4 @@ -use core::{ - ops::{Add, Mul}, -}; +use core::ops::{Add, Sub, Mul}; use scale::{Encode, Decode, MaxEncodedLen}; use scale_info::TypeInfo; @@ -21,13 +19,21 @@ pub const COIN: Amount = Amount(1_000_000_00); impl Add for Amount { type Output = Amount; fn add(self, other: Amount) -> Amount { - Amount(self.0 + other.0) + // Explicitly use checked_add so even if range checks are disabled, this is still checked + Amount(self.0.checked_add(other.0).unwrap()) + } +} + +impl Sub for Amount { + type Output = Amount; + fn sub(self, other: Amount) -> Amount { + Amount(self.0.checked_sub(other.0).unwrap()) } } impl Mul for Amount { type Output = Amount; fn mul(self, other: Amount) -> Amount { - Amount(self.0 * other.0) + Amount(self.0.checked_mul(other.0).unwrap()) } } From 19664967ed936b92d8b87dab19bda63c473716ed Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 21 Jan 2023 01:24:13 -0500 Subject: [PATCH 37/74] Use Monero-compatible additional TX keys This still sends a fingerprinting flare up if you send to a subaddress which needs to be fixed. Despite that, Monero no should no longer fail to scan TXs from monero-serai regarding additional keys. Previously it failed becuase we supplied one key as THE key, and n-1 as additional. Monero expects n for additional. This does correctly select when to use THE key versus when to use the additional key when sending. That removes the ability for recipients to fingerprint monero-serai by receiving to a standard address yet needing to use an additional key. --- coins/monero/src/tests/address.rs | 20 ++++++++-------- coins/monero/src/wallet/address.rs | 20 ++++++++-------- coins/monero/src/wallet/extra.rs | 10 ++++---- coins/monero/src/wallet/mod.rs | 4 ++-- coins/monero/src/wallet/scan.rs | 1 + coins/monero/src/wallet/send/mod.rs | 37 ++++++++++++++++++++++------- 6 files changed, 55 insertions(+), 37 deletions(-) diff --git a/coins/monero/src/tests/address.rs b/coins/monero/src/tests/address.rs index 3950d6d1..76f75a3e 100644 --- a/coins/monero/src/tests/address.rs +++ b/coins/monero/src/tests/address.rs @@ -33,9 +33,9 @@ fn standard_address() { let addr = MoneroAddress::from_str(Network::Mainnet, STANDARD).unwrap(); assert_eq!(addr.meta.network, Network::Mainnet); assert_eq!(addr.meta.kind, AddressType::Standard); - assert!(!addr.meta.kind.subaddress()); + assert!(!addr.meta.kind.is_subaddress()); assert_eq!(addr.meta.kind.payment_id(), None); - assert!(!addr.meta.kind.guaranteed()); + assert!(!addr.meta.kind.is_guaranteed()); assert_eq!(addr.spend.compress().to_bytes(), SPEND); assert_eq!(addr.view.compress().to_bytes(), VIEW); assert_eq!(addr.to_string(), STANDARD); @@ -46,9 +46,9 @@ fn integrated_address() { let addr = MoneroAddress::from_str(Network::Mainnet, INTEGRATED).unwrap(); assert_eq!(addr.meta.network, Network::Mainnet); assert_eq!(addr.meta.kind, AddressType::Integrated(PAYMENT_ID)); - assert!(!addr.meta.kind.subaddress()); + assert!(!addr.meta.kind.is_subaddress()); assert_eq!(addr.meta.kind.payment_id(), Some(PAYMENT_ID)); - assert!(!addr.meta.kind.guaranteed()); + assert!(!addr.meta.kind.is_guaranteed()); assert_eq!(addr.spend.compress().to_bytes(), SPEND); assert_eq!(addr.view.compress().to_bytes(), VIEW); assert_eq!(addr.to_string(), INTEGRATED); @@ -59,9 +59,9 @@ fn subaddress() { let addr = MoneroAddress::from_str(Network::Mainnet, SUBADDRESS).unwrap(); assert_eq!(addr.meta.network, Network::Mainnet); assert_eq!(addr.meta.kind, AddressType::Subaddress); - assert!(addr.meta.kind.subaddress()); + assert!(addr.meta.kind.is_subaddress()); assert_eq!(addr.meta.kind.payment_id(), None); - assert!(!addr.meta.kind.guaranteed()); + assert!(!addr.meta.kind.is_guaranteed()); assert_eq!(addr.spend.compress().to_bytes(), SUB_SPEND); assert_eq!(addr.view.compress().to_bytes(), SUB_VIEW); assert_eq!(addr.to_string(), SUBADDRESS); @@ -100,9 +100,9 @@ fn featured() { assert_eq!(addr.spend, spend); assert_eq!(addr.view, view); - assert_eq!(addr.subaddress(), subaddress); + assert_eq!(addr.is_subaddress(), subaddress); assert_eq!(addr.payment_id(), payment_id); - assert_eq!(addr.guaranteed(), guaranteed); + assert_eq!(addr.is_guaranteed(), guaranteed); } } } @@ -151,10 +151,10 @@ fn featured_vectors() { assert_eq!(addr.spend, spend); assert_eq!(addr.view, view); - assert_eq!(addr.subaddress(), vector.subaddress); + assert_eq!(addr.is_subaddress(), vector.subaddress); assert_eq!(vector.integrated, vector.payment_id.is_some()); assert_eq!(addr.payment_id(), vector.payment_id); - assert_eq!(addr.guaranteed(), vector.guaranteed); + assert_eq!(addr.is_guaranteed(), vector.guaranteed); assert_eq!( MoneroAddress::new( diff --git a/coins/monero/src/wallet/address.rs b/coins/monero/src/wallet/address.rs index ad7777d2..9a232d2a 100644 --- a/coins/monero/src/wallet/address.rs +++ b/coins/monero/src/wallet/address.rs @@ -60,7 +60,7 @@ pub enum AddressSpec { } impl AddressType { - pub fn subaddress(&self) -> bool { + pub fn is_subaddress(&self) -> bool { matches!(self, AddressType::Subaddress) || matches!(self, AddressType::Featured { subaddress: true, .. }) } @@ -75,7 +75,7 @@ impl AddressType { } } - pub fn guaranteed(&self) -> bool { + pub fn is_guaranteed(&self) -> bool { matches!(self, AddressType::Featured { guaranteed: true, .. }) } } @@ -169,16 +169,16 @@ impl AddressMeta { meta.ok_or(AddressError::InvalidByte) } - pub fn subaddress(&self) -> bool { - self.kind.subaddress() + pub fn is_subaddress(&self) -> bool { + self.kind.is_subaddress() } pub fn payment_id(&self) -> Option<[u8; 8]> { self.kind.payment_id() } - pub fn guaranteed(&self) -> bool { - self.kind.guaranteed() + pub fn is_guaranteed(&self) -> bool { + self.kind.is_guaranteed() } } @@ -285,16 +285,16 @@ impl Address { self.meta.network } - pub fn subaddress(&self) -> bool { - self.meta.subaddress() + pub fn is_subaddress(&self) -> bool { + self.meta.is_subaddress() } pub fn payment_id(&self) -> Option<[u8; 8]> { self.meta.payment_id() } - pub fn guaranteed(&self) -> bool { - self.meta.guaranteed() + pub fn is_guaranteed(&self) -> bool { + self.meta.is_guaranteed() } } diff --git a/coins/monero/src/wallet/extra.rs b/coins/monero/src/wallet/extra.rs index 2a0b9aa2..f213fecf 100644 --- a/coins/monero/src/wallet/extra.rs +++ b/coins/monero/src/wallet/extra.rs @@ -149,13 +149,11 @@ impl Extra { res } - pub(crate) fn new(mut keys: Vec) -> Extra { + pub(crate) fn new(key: EdwardsPoint, additional: Vec) -> Extra { let mut res = Extra(Vec::with_capacity(3)); - if !keys.is_empty() { - res.push(ExtraField::PublicKey(keys[0])); - } - if keys.len() > 1 { - res.push(ExtraField::PublicKeys(keys.drain(1 ..).collect())); + res.push(ExtraField::PublicKey(key)); + if !additional.is_empty() { + res.push(ExtraField::PublicKeys(additional)); } res } diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index 383eb09a..511b5be3 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -54,12 +54,12 @@ pub(crate) fn uniqueness(inputs: &[Input]) -> [u8; 32] { #[allow(non_snake_case)] pub(crate) fn shared_key( uniqueness: Option<[u8; 32]>, - s: &Scalar, + s: &Zeroizing, P: &EdwardsPoint, o: usize, ) -> (u8, Scalar, [u8; 8]) { // 8Ra - let mut output_derivation = (s * P).mul_by_cofactor().compress().to_bytes().to_vec(); + let mut output_derivation = (s.deref() * P).mul_by_cofactor().compress().to_bytes().to_vec(); let mut payment_id_xor = [0; 8]; payment_id_xor diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index 7fd1a027..a86cbf9b 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -296,6 +296,7 @@ impl Scanner { } let output_key = output_key.unwrap(); + // TODO: Only use THE key or the matching additional key. Not any key for key in &keys { let (view_tag, shared_key, payment_id_xor) = shared_key( if self.burning_bug.is_none() { Some(uniqueness(&tx.prefix.inputs)) } else { None }, diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index 9aa3e8b8..bf169299 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -7,7 +7,9 @@ use rand::seq::SliceRandom; use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; +use group::Group; use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint}; +use dalek_ff_group as dfg; #[cfg(feature = "multisig")] use frost::FrostError; @@ -47,24 +49,23 @@ struct SendOutput { } impl SendOutput { - fn new( - rng: &mut R, + fn new( + r: &Zeroizing, unique: [u8; 32], output: (usize, (MoneroAddress, u64)), ) -> (SendOutput, Option<[u8; 8]>) { let o = output.0; let output = output.1; - let r = random_scalar(rng); let (view_tag, shared_key, payment_id_xor) = - shared_key(Some(unique).filter(|_| output.0.meta.kind.guaranteed()), &r, &output.0.view, o); + shared_key(Some(unique).filter(|_| output.0.is_guaranteed()), r, &output.0.view, o); ( SendOutput { - R: if !output.0.meta.kind.subaddress() { - &r * &ED25519_BASEPOINT_TABLE + R: if !output.0.is_subaddress() { + r.deref() * &ED25519_BASEPOINT_TABLE } else { - r * output.0.spend + r.deref() * output.0.spend }, view_tag, dest: ((&shared_key * &ED25519_BASEPOINT_TABLE) + output.0.spend), @@ -281,11 +282,26 @@ impl SignableTransaction { // Shuffle the payments self.payments.shuffle(rng); + // Used for all non-subaddress outputs, or if there's only one subaddress output and a change + let tx_key = Zeroizing::new(random_scalar(rng)); + // TODO: Support not needing additional when one subaddress and non-subaddress change + let additional = self.payments.iter().filter(|payment| payment.0.is_subaddress()).count() != 0; + // Actually create the outputs let mut outputs = Vec::with_capacity(self.payments.len()); let mut id = None; for payment in self.payments.drain(..).enumerate() { - let (output, payment_id) = SendOutput::new(rng, uniqueness, payment); + // If this is a subaddress, generate a dedicated r. Else, reuse the TX key + let dedicated = Zeroizing::new(random_scalar(&mut *rng)); + let use_dedicated = additional && payment.1 .0.is_subaddress(); + let r = if use_dedicated { &dedicated } else { &tx_key }; + + let (mut output, payment_id) = SendOutput::new(r, uniqueness, payment); + // If this used the tx_key, randomize its R + if !use_dedicated { + output.R = dfg::EdwardsPoint::random(&mut *rng).0; + } + outputs.push(output); id = id.or(payment_id); } @@ -308,7 +324,10 @@ impl SignableTransaction { // Create the TX extra let extra = { - let mut extra = Extra::new(outputs.iter().map(|output| output.R).collect()); + let mut extra = Extra::new( + tx_key.deref() * &ED25519_BASEPOINT_TABLE, + if additional { outputs.iter().map(|output| output.R).collect() } else { vec![] }, + ); let mut id_vec = Vec::with_capacity(1 + 8); PaymentId::Encrypted(id).write(&mut id_vec).unwrap(); From f12cc2cca661e7bd10ae343b4297c27ea5d37970 Mon Sep 17 00:00:00 2001 From: akildemir <34187742+akildemir@users.noreply.github.com> Date: Tue, 24 Jan 2023 23:22:07 +0300 Subject: [PATCH 38/74] Add more tests (#240) * add wallet-rpc-compatibility tests * fmt + clippy * add wallet-rpc receive tests * add (0,0) subaddress check to standard address --- .../monero/tests/wallet-rpc-compatibility.rs | 123 +++++++++++++++++- 1 file changed, 117 insertions(+), 6 deletions(-) diff --git a/coins/monero/tests/wallet-rpc-compatibility.rs b/coins/monero/tests/wallet-rpc-compatibility.rs index 12353db8..230faec2 100644 --- a/coins/monero/tests/wallet-rpc-compatibility.rs +++ b/coins/monero/tests/wallet-rpc-compatibility.rs @@ -3,26 +3,52 @@ use std::{ str::FromStr, }; -use rand_core::{RngCore, OsRng}; +use rand_core::{OsRng, RngCore}; + +use serde::Deserialize; +use serde_json::json; use monero_rpc::{ - monero::{Amount, Address}, - TransferOptions, + monero::{ + Amount, Address, + cryptonote::{hash::Hash, subaddress::Index}, + util::address::PaymentId, + }, + TransferOptions, WalletClient, }; use monero_serai::{ wallet::address::{Network, AddressSpec, SubaddressIndex}, - wallet::Scanner, + wallet::{Scanner, address::MoneroAddress}, + rpc::Rpc, + transaction::Transaction, }; mod runner; -async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { +async fn make_integrated_address(payment_id: [u8; 8]) -> String { + #[derive(Deserialize, Debug)] + struct IntegratedAddressResponse { + integrated_address: String, + } + + let rpc = Rpc::new("http://127.0.0.1:6061".to_string()).unwrap(); + let res = rpc + .json_rpc_call::( + "make_integrated_address", + Some(json!({ "payment_id": hex::encode(payment_id) })), + ) + .await + .unwrap(); + + res.integrated_address +} + +async fn initialize_rpcs() -> (WalletClient, Rpc, monero_rpc::monero::Address) { let wallet_rpc = monero_rpc::RpcClientBuilder::new().build("http://127.0.0.1:6061").unwrap().wallet(); let daemon_rpc = runner::rpc().await; - // initialize wallet rpc let address_resp = wallet_rpc.get_address(0, None).await; let wallet_rpc_addr = if address_resp.is_ok() { address_resp.unwrap().address @@ -32,6 +58,12 @@ async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { daemon_rpc.generate_blocks(&addr.to_string(), 70).await.unwrap(); addr }; + (wallet_rpc, daemon_rpc, wallet_rpc_addr) +} + +async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { + // initialize rpc + let (wallet_rpc, daemon_rpc, wallet_rpc_addr) = initialize_rpcs().await; // make an addr let (_, view_pair, _) = runner::random_address(); @@ -89,3 +121,82 @@ async_sequential!( test_from_wallet_rpc_to_self(AddressSpec::Integrated(payment_id)).await; } ); + +test!( + test_send_to_wallet_rpc_standard, + ( + |_, mut builder: Builder, _| async move { + // initialize rpc + let (wallet_rpc, _, wallet_rpc_addr) = initialize_rpcs().await; + + // add destination + builder.add_payment( + MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr.to_string()).unwrap(), + 1000000, + ); + (builder.build().unwrap(), (wallet_rpc,)) + }, + |_, tx: Transaction, _, data: (WalletClient,)| async move { + // confirm receipt + data.0.refresh(None).await.unwrap(); + let transfer = + data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); + assert_eq!(transfer.amount.as_pico(), 1000000); + assert_eq!(transfer.subaddr_index, Index { major: 0, minor: 0 }); + }, + ), +); + +test!( + test_send_to_wallet_rpc_subaddress, + ( + |_, mut builder: Builder, _| async move { + // initialize rpc + let (wallet_rpc, _, _) = initialize_rpcs().await; + + // make the addr + let (subaddress, index) = wallet_rpc.create_address(0, None).await.unwrap(); + + builder.add_payment( + MoneroAddress::from_str(Network::Mainnet, &subaddress.to_string()).unwrap(), + 1000000, + ); + (builder.build().unwrap(), (wallet_rpc, index)) + }, + |_, tx: Transaction, _, data: (WalletClient, u32)| async move { + // confirm receipt + data.0.refresh(None).await.unwrap(); + let transfer = + data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); + assert_eq!(transfer.amount.as_pico(), 1000000); + assert_eq!(transfer.subaddr_index, Index { major: 0, minor: data.1 }); + }, + ), +); + +test!( + test_send_to_wallet_rpc_integrated, + ( + |_, mut builder: Builder, _| async move { + // initialize rpc + let (wallet_rpc, _, _) = initialize_rpcs().await; + + // make the addr + let mut payment_id = [0u8; 8]; + OsRng.fill_bytes(&mut payment_id); + let addr = make_integrated_address(payment_id).await; + + builder.add_payment(MoneroAddress::from_str(Network::Mainnet, &addr).unwrap(), 1000000); + (builder.build().unwrap(), (wallet_rpc, payment_id)) + }, + |_, tx: Transaction, _, data: (WalletClient, [u8; 8])| async move { + // confirm receipt + data.0.refresh(None).await.unwrap(); + let transfer = + data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); + assert_eq!(transfer.amount.as_pico(), 1000000); + assert_eq!(transfer.subaddr_index, Index { major: 0, minor: 0 }); + assert_eq!(transfer.payment_id.0, PaymentId::from_slice(&data.1)); + }, + ), +); From 2ace339975eeb79176dd008d3838884fd7a116db Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 28 Jan 2023 01:47:13 -0500 Subject: [PATCH 39/74] Tokens pallet (#243) * Use Monero-compatible additional TX keys This still sends a fingerprinting flare up if you send to a subaddress which needs to be fixed. Despite that, Monero no should no longer fail to scan TXs from monero-serai regarding additional keys. Previously it failed becuase we supplied one key as THE key, and n-1 as additional. Monero expects n for additional. This does correctly select when to use THE key versus when to use the additional key when sending. That removes the ability for recipients to fingerprint monero-serai by receiving to a standard address yet needing to use an additional key. * Add tokens_primitives Moves OutInstruction from in-instructions. Turns Destination into OutInstruction. * Correct in-instructions DispatchClass * Add initial tokens pallet * Don't allow pallet addresses to equal identity * Add support for InInstruction::transfer Requires a cargo update due to modifications made to serai-dex/substrate. Successfully mints a token to a SeraiAddress. * Bind InInstructions to an amount * Add a call filter to the runtime Prevents worrying about calls to the assets pallet/generally tightens things up. * Restore Destination It was meged into OutInstruction, yet it didn't make sense for OutInstruction to contain a SeraiAddress. Also deletes the excessively dated Scenarios doc. * Split PublicKey/SeraiAddress Lets us define a custom Display/ToString for SeraiAddress. Also resolves an oddity where PublicKey would be encoded as String, not [u8; 32]. * Test burning tokens/retrieving OutInstructions Modularizes processor_coinUpdates into a shared testing utility. * Misc lint * Don't use PolkadotExtrinsicParams --- Cargo.lock | 328 ++++++++++-------- Cargo.toml | 3 + deny.toml | 2 + docs/integrations/Instructions.md | 29 +- docs/integrations/Scenarios.md | 98 ------ substrate/in-instructions/pallet/Cargo.toml | 4 + substrate/in-instructions/pallet/src/lib.rs | 43 ++- .../in-instructions/primitives/Cargo.toml | 5 +- .../primitives/src/incoming.rs | 38 -- .../in-instructions/primitives/src/lib.rs | 62 ++-- .../primitives/src/outgoing.rs | 25 -- .../primitives/src/shorthand.rs | 15 +- substrate/node/src/chain_spec.rs | 88 +++-- substrate/node/src/command_helper.rs | 2 +- substrate/node/src/rpc.rs | 10 +- substrate/node/src/service.rs | 6 +- substrate/runtime/Cargo.toml | 4 +- substrate/runtime/src/lib.rs | 97 ++++-- substrate/serai/client/Cargo.toml | 11 +- substrate/serai/client/metadata.json | 0 substrate/serai/client/src/in_instructions.rs | 40 +-- substrate/serai/client/src/lib.rs | 81 ++++- substrate/serai/client/src/scale_value.rs | 18 + substrate/serai/client/src/tokens.rs | 68 ++++ substrate/serai/client/tests/burn.rs | 79 +++++ substrate/serai/client/tests/runner.rs | 77 +++- substrate/serai/client/tests/updates.rs | 71 ++-- substrate/serai/primitives/Cargo.toml | 3 +- substrate/serai/primitives/src/account.rs | 93 +++++ substrate/serai/primitives/src/amount.rs | 26 +- substrate/serai/primitives/src/balance.rs | 37 ++ substrate/serai/primitives/src/block.rs | 46 +++ substrate/serai/primitives/src/lib.rs | 82 +++-- substrate/tokens/pallet/Cargo.toml | 38 ++ substrate/tokens/pallet/LICENSE | 15 + substrate/tokens/pallet/src/lib.rs | 83 +++++ substrate/tokens/primitives/Cargo.toml | 26 ++ substrate/tokens/primitives/LICENSE | 21 ++ substrate/tokens/primitives/src/lib.rs | 33 ++ 39 files changed, 1213 insertions(+), 594 deletions(-) delete mode 100644 docs/integrations/Scenarios.md delete mode 100644 substrate/in-instructions/primitives/src/incoming.rs delete mode 100644 substrate/in-instructions/primitives/src/outgoing.rs create mode 100644 substrate/serai/client/metadata.json create mode 100644 substrate/serai/client/src/scale_value.rs create mode 100644 substrate/serai/client/src/tokens.rs create mode 100644 substrate/serai/client/tests/burn.rs create mode 100644 substrate/serai/primitives/src/account.rs create mode 100644 substrate/serai/primitives/src/balance.rs create mode 100644 substrate/serai/primitives/src/block.rs create mode 100644 substrate/tokens/pallet/Cargo.toml create mode 100644 substrate/tokens/pallet/LICENSE create mode 100644 substrate/tokens/pallet/src/lib.rs create mode 100644 substrate/tokens/primitives/Cargo.toml create mode 100644 substrate/tokens/primitives/LICENSE create mode 100644 substrate/tokens/primitives/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 0487ff80..ba40c8c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,7 +27,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.27.0", + "gimli 0.27.1", ] [[package]] @@ -334,9 +334,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705339e0e4a9690e2908d2b3d049d85682cf19fbd5782494498fbf7003a6a282" +checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1" dependencies = [ "proc-macro2", "quote", @@ -425,7 +425,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object 0.30.2", + "object 0.30.3", "rustc-demangle", ] @@ -709,9 +709,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byte-slice-cast" @@ -1541,9 +1541,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" +checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e" dependencies = [ "cc", "cxxbridge-flags", @@ -1553,9 +1553,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" +checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200" dependencies = [ "cc", "codespan-reporting", @@ -1568,15 +1568,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" +checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea" [[package]] name = "cxxbridge-macro" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" +checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e" dependencies = [ "proc-macro2", "quote", @@ -2655,7 +2655,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", ] @@ -2678,7 +2678,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-support", "frame-system", @@ -2701,7 +2701,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "Inflector", "array-bytes", @@ -2748,7 +2748,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-support", "frame-system", @@ -2776,7 +2776,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "bitflags", "frame-metadata", @@ -2808,7 +2808,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "Inflector", "cfg-expr", @@ -2822,7 +2822,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -2834,7 +2834,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "proc-macro2", "quote", @@ -2844,7 +2844,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-support", "log", @@ -2862,7 +2862,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "sp-api", @@ -3117,9 +3117,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" [[package]] name = "glob" @@ -3585,6 +3585,7 @@ dependencies = [ "sp-runtime", "sp-std", "thiserror", + "tokens-pallet", ] [[package]] @@ -3595,7 +3596,7 @@ dependencies = [ "scale-info", "serai-primitives", "serde", - "sp-core", + "tokens-primitives", ] [[package]] @@ -3724,7 +3725,7 @@ checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" dependencies = [ "hermit-abi 0.2.6", "io-lifetimes 1.0.4", - "rustix 0.36.6", + "rustix 0.36.7", "windows-sys 0.42.0", ] @@ -4644,9 +4645,9 @@ dependencies = [ [[package]] name = "matches" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matrixmultiply" @@ -4689,7 +4690,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb" dependencies = [ - "rustix 0.36.6", + "rustix 0.36.7", ] [[package]] @@ -5222,9 +5223,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" dependencies = [ "num-traits", ] @@ -5301,9 +5302,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.2" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c786513eb403643f2a88c244c2aaa270ef2153f55094587d0c48a3cf22a83" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] @@ -5455,7 +5456,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-benchmarking", "frame-support", @@ -5470,7 +5471,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-benchmarking", "frame-support", @@ -5485,7 +5486,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-support", "frame-system", @@ -5519,7 +5520,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-benchmarking", "frame-support", @@ -5537,7 +5538,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-support", "frame-system", @@ -5553,7 +5554,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -5569,7 +5570,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -5599,9 +5600,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.2.1" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366e44391a8af4cfd6002ef6ba072bae071a96aafca98d7d448a34c5dca38b6a" +checksum = "e7ab01d0f889e957861bc65888d5ccbe82c158d0270136ba46820d43837cdf72" dependencies = [ "arrayvec 0.7.2", "bitvec 1.0.1", @@ -5614,9 +5615,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.3" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" +checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6101,9 +6102,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] @@ -6386,9 +6387,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -6510,11 +6511,11 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.13" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" dependencies = [ - "base64 0.13.1", + "base64 0.21.0", "bytes", "encoding_rs", "futures-core", @@ -6740,9 +6741,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.6" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" dependencies = [ "bitflags", "errno", @@ -6842,7 +6843,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "log", "sp-core", @@ -6853,7 +6854,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "futures", "futures-timer", @@ -6876,7 +6877,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -6892,7 +6893,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "memmap2", "sc-chain-spec-derive", @@ -6907,7 +6908,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6918,7 +6919,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "chrono", @@ -6958,7 +6959,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "fnv", "futures", @@ -6984,7 +6985,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "hash-db", "kvdb", @@ -7009,7 +7010,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "futures", @@ -7034,7 +7035,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "lru", "parity-scale-codec", @@ -7058,7 +7059,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", @@ -7071,7 +7072,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "log", "sc-allocator", @@ -7084,7 +7085,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "cfg-if", "libc", @@ -7101,7 +7102,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "ansi_term", "futures", @@ -7116,7 +7117,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "async-trait", @@ -7131,7 +7132,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "async-trait", @@ -7173,7 +7174,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "cid", "futures", @@ -7192,7 +7193,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "bitflags", @@ -7218,7 +7219,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "ahash", "futures", @@ -7236,7 +7237,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "futures", @@ -7257,7 +7258,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "async-trait", @@ -7289,7 +7290,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "futures", @@ -7308,7 +7309,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "bytes", @@ -7338,7 +7339,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "futures", "libp2p", @@ -7351,7 +7352,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -7360,7 +7361,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "futures", "jsonrpsee", @@ -7389,7 +7390,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -7408,7 +7409,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "http", "jsonrpsee", @@ -7423,7 +7424,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "futures", @@ -7449,7 +7450,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "directories", @@ -7514,7 +7515,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "log", "parity-scale-codec", @@ -7525,7 +7526,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "futures", "libc", @@ -7544,7 +7545,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "chrono", "futures", @@ -7593,7 +7594,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "ansi_term", "atty", @@ -7624,7 +7625,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7635,7 +7636,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "futures", @@ -7661,7 +7662,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "futures", @@ -7675,7 +7676,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "backtrace", "futures", @@ -7904,9 +7905,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "645926f31b250a2dca3c232496c2d898d91036e45ca0e97e0e2390c54e11be36" dependencies = [ "bitflags", "core-foundation", @@ -7917,9 +7918,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -7959,14 +7960,15 @@ checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7" name = "serai-client" version = "0.1.0" dependencies = [ - "in-instructions-primitives", "jsonrpsee-server", "lazy_static", "parity-scale-codec", + "rand_core 0.6.4", + "scale-info", "scale-value", "serai-primitives", "serai-runtime", - "serde", + "sp-core", "subxt", "thiserror", "tokio", @@ -8017,6 +8019,7 @@ dependencies = [ "scale-info", "serde", "sp-core", + "sp-runtime", ] [[package]] @@ -8072,6 +8075,7 @@ dependencies = [ "sp-transaction-pool", "sp-version", "substrate-wasm-builder", + "tokens-pallet", "validator-sets-pallet", ] @@ -8346,7 +8350,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "hash-db", "log", @@ -8364,7 +8368,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "blake2", "proc-macro-crate", @@ -8376,7 +8380,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "scale-info", @@ -8389,7 +8393,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "integer-sqrt", "num-traits", @@ -8403,7 +8407,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "sp-api", @@ -8415,7 +8419,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "futures", "log", @@ -8433,7 +8437,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "futures", @@ -8451,7 +8455,7 @@ dependencies = [ [[package]] name = "sp-core" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "array-bytes", "base58 0.2.0", @@ -8493,7 +8497,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "blake2", "byteorder", @@ -8507,7 +8511,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "proc-macro2", "quote", @@ -8518,7 +8522,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -8527,7 +8531,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "proc-macro2", "quote", @@ -8537,7 +8541,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "environmental", "parity-scale-codec", @@ -8548,7 +8552,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "finality-grandpa", "log", @@ -8566,7 +8570,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -8580,7 +8584,7 @@ dependencies = [ [[package]] name = "sp-io" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "bytes", "ed25519", @@ -8605,7 +8609,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "lazy_static", "sp-core", @@ -8616,7 +8620,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "futures", @@ -8633,7 +8637,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "thiserror", "zstd", @@ -8642,7 +8646,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "sp-api", "sp-core", @@ -8652,7 +8656,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "backtrace", "lazy_static", @@ -8662,7 +8666,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "rustc-hash", "serde", @@ -8672,7 +8676,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "either", "hash256-std-hasher", @@ -8694,7 +8698,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -8712,7 +8716,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "Inflector", "proc-macro-crate", @@ -8724,7 +8728,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "scale-info", @@ -8738,7 +8742,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "scale-info", @@ -8750,7 +8754,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "hash-db", "log", @@ -8770,12 +8774,12 @@ dependencies = [ [[package]] name = "sp-std" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" [[package]] name = "sp-storage" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8797,7 +8801,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "futures-timer", @@ -8812,7 +8816,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "sp-std", @@ -8824,7 +8828,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "sp-api", "sp-runtime", @@ -8833,7 +8837,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "async-trait", "log", @@ -8849,7 +8853,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "ahash", "hash-db", @@ -8872,7 +8876,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8889,7 +8893,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -8900,7 +8904,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "impl-trait-for-tuples", "log", @@ -8913,7 +8917,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "parity-scale-codec", "scale-info", @@ -9085,7 +9089,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "platforms 2.0.0", ] @@ -9093,7 +9097,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -9112,7 +9116,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "hyper", "log", @@ -9124,7 +9128,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#c35dde519b8ee3ee0c57e452de471843a1b99339" +source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" dependencies = [ "ansi_term", "build-helper", @@ -9528,11 +9532,35 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tokens-pallet" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "pallet-assets", + "parity-scale-codec", + "scale-info", + "serai-primitives", + "tokens-primitives", +] + +[[package]] +name = "tokens-primitives" +version = "0.1.0" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serai-primitives", + "serde", + "sp-runtime", +] + [[package]] name = "tokio" -version = "1.24.1" +version = "1.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" +checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" dependencies = [ "autocfg", "bytes", @@ -9621,9 +9649,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] @@ -9894,9 +9922,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" @@ -10693,9 +10721,9 @@ dependencies = [ [[package]] name = "which" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", "libc", diff --git a/Cargo.toml b/Cargo.toml index 34f7afce..2d1aea59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,9 @@ members = [ "substrate/serai/primitives", "substrate/serai/client", + "substrate/tokens/primitives", + "substrate/tokens/pallet", + "substrate/in-instructions/primitives", "substrate/in-instructions/pallet", "substrate/in-instructions/client", diff --git a/deny.toml b/deny.toml index 336ab699..a289c911 100644 --- a/deny.toml +++ b/deny.toml @@ -48,6 +48,8 @@ exceptions = [ { allow = ["AGPL-3.0"], name = "serai-processor" }, + { allow = ["AGPL-3.0"], name = "tokens-pallet" }, + { allow = ["AGPL-3.0"], name = "in-instructions-pallet" }, { allow = ["AGPL-3.0"], name = "in-instructions-client" }, diff --git a/docs/integrations/Instructions.md b/docs/integrations/Instructions.md index cec67eb2..12f1753d 100644 --- a/docs/integrations/Instructions.md +++ b/docs/integrations/Instructions.md @@ -40,10 +40,10 @@ Serai token. If an Application Call, the encoded call will be executed. ### Refundable In Instruction - - `origin` (Option\): Address, from the network of origin, -which sent coins in. - - `instruction` (InInstruction): The action to perform with the incoming -coins. + - `origin` (Option\): Address, from the network of +origin, which sent coins in. + - `instruction` (InInstruction): The action to perform with the +incoming coins. Networks may automatically provide `origin`. If they do, the instruction may still provide `origin`, overriding the automatically provided value. @@ -51,19 +51,18 @@ still provide `origin`, overriding the automatically provided value. If the instruction fails, coins are scheduled to be returned to `origin`, if provided. -### Destination - -Destination is an enum of SeraiAddress and ExternalAddress. - ### Out Instruction - - `destination` (Destination): Address to receive coins to. - - `data` (Option\): The data to call the destination with. + - `address` (ExternalAddress): Address to transfer the coins included with +this instruction to. + - `data` (Option): Data to include when transferring coins. -Transfer the coins included with this instruction to the specified address with -the specified data. No validation of external addresses/data is performed -on-chain. If data is specified for a chain not supporting data, it is silently -dropped. +No validation of external addresses/data is performed on-chain. If data is +specified for a chain not supporting data, it is silently dropped. + +### Destination + +Destination is an enum of SeraiAddress and OutInstruction. ### Shorthand @@ -80,7 +79,7 @@ covered by Shorthand. - `origin` (Option\): Refundable In Instruction's `origin`. - `coin` (Coin): Coin to swap funds for. - `minimum` (Amount): Minimum amount of `coin` to receive. - - `out` (Out Instruction): Final destination for funds. + - `out` (Destination): Final destination for funds. which expands to: diff --git a/docs/integrations/Scenarios.md b/docs/integrations/Scenarios.md deleted file mode 100644 index 5a7c8c75..00000000 --- a/docs/integrations/Scenarios.md +++ /dev/null @@ -1,98 +0,0 @@ -# Scenarios - -### Pong - -Pong has Serai receive funds, just to return them. It's a demonstration of the -in/out flow. - -``` -Shorthand::Raw( - In Instruction { - target: Incoming Asset Contract, - data: native_transfer(Incoming Asset Sender) - } -) -``` - -### Wrap - -Wrap wraps an asset from a connected chain into a Serai Asset, making it usable -with applications on Serai, such as Serai DEX. - -``` -Shorthand::Raw( - In Instruction { - target: Serai Address - } -) -``` - -### Swap SRI to Bitcoin - -For a SRI to Bitcoin swap, a SRI holder would perform an -[Application Call](../Serai.md#application-calls) to Serai DEX, purchasing -seraiBTC. Once they have seraiBTC, they are able to call `native_transfer`, -transferring the BTC underlying the seraiBTC to a specified Bitcoin address. - -### Swap Bitcoin to Monero - -For a Bitcoin to Monero swap, the following Shorthand would be used. - -``` -Shorthand::Swap { - coin: Monero, - minimum: Minimum Monero from Swap, - out: Monero Address -} -``` - - This Shorthand is expected to generally take: - - - 1 byte to identify as Swap. - - 1 byte to not override `origin`. - - 1 byte for `coin`. - - 4 bytes for `minimum`. - - 1 byte for `out`'s `destination`'s ordinal byte. - - 65 bytes for `out`'s `destination`'s address. - - 1 byte to not include `data` in `out`. - -Or 74 bytes. - -### Add Liquidity (Fresh) - -For a user who has never used Serai before, they have three requirements to add -liquidity: - - - Minting the Serai asset they wish to add liquidity for - - Acquiring Serai, as liquidity is symmetric - - Acquiring Serai for gas fees - -The Add Liquidity Shorthand enables all three of these actions, and actually -adding the liquidity, in just one transaction from a connected network. - -``` -Shorthand::AddLiquidity { - minimum: Minimum SRI from Swap, - gas: Amount of SRI to keep for gas - address: Serai address for the liquidity tokens and gas -} -``` - -For adding liquidity from Bitcoin, this Shorthand is expected to generally take: - - - 1 byte to identify as Add Liquidity. - - 1 byte to not override `origin`. - - 5 bytes for `minimum`. - - 4 bytes for `gas`. - - 32 bytes for `address`. - -Or 43 bytes. - -### Add Liquidity (SRI Holder) - -For a user who already has SRI, they solely need to have the asset they wish to -add liquidity for via their SRI. They can either purchase it from Serai DEX, or -wrap it as detailed above. - -Once they have both their SRI and the asset they wish to provide liquidity for, -they would use a Serai transaction to call the DEX, adding the liquidity. diff --git a/substrate/in-instructions/pallet/Cargo.toml b/substrate/in-instructions/pallet/Cargo.toml index 7895997e..c8c3657d 100644 --- a/substrate/in-instructions/pallet/Cargo.toml +++ b/substrate/in-instructions/pallet/Cargo.toml @@ -29,6 +29,8 @@ frame-support = { git = "https://github.com/serai-dex/substrate", default-featur serai-primitives = { path = "../../serai/primitives", default-features = false } in-instructions-primitives = { path = "../primitives", default-features = false } +tokens-pallet = { path = "../../tokens/pallet", default-features = false } + [features] std = [ "thiserror", @@ -47,5 +49,7 @@ std = [ "serai-primitives/std", "in-instructions-primitives/std", + + "tokens-pallet/std", ] default = ["std"] diff --git a/substrate/in-instructions/pallet/src/lib.rs b/substrate/in-instructions/pallet/src/lib.rs index 7b5d5f8b..ab48d564 100644 --- a/substrate/in-instructions/pallet/src/lib.rs +++ b/substrate/in-instructions/pallet/src/lib.rs @@ -13,7 +13,7 @@ use sp_inherents::{InherentIdentifier, IsFatalError}; use sp_runtime::RuntimeDebug; -use serai_primitives::{BlockNumber, BlockHash, Coin}; +use serai_primitives::{BlockNumber, BlockHash, Coin, WithAmount, Balance}; pub use in_instructions_primitives as primitives; use primitives::InInstruction; @@ -24,7 +24,7 @@ pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"ininstrs"; #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct Batch { pub id: BlockHash, - pub instructions: Vec, + pub instructions: Vec>, } #[derive(Clone, PartialEq, Eq, Encode, Decode, TypeInfo, RuntimeDebug)] @@ -89,10 +89,12 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; + use tokens_pallet::{Config as TokensConfig, Pallet as Tokens}; + use super::*; #[pallet::config] - pub trait Config: frame_system::Config { + pub trait Config: frame_system::Config + TokensConfig { type RuntimeEvent: From> + IsType<::RuntimeEvent>; } @@ -100,6 +102,7 @@ pub mod pallet { #[pallet::generate_deposit(fn deposit_event)] pub enum Event { Batch { coin: Coin, id: BlockHash }, + Failure { coin: Coin, id: BlockHash, index: u32 }, } #[pallet::pallet] @@ -122,23 +125,43 @@ pub mod pallet { } } + impl Pallet { + fn execute(coin: Coin, instruction: WithAmount) -> Result<(), ()> { + match instruction.data { + InInstruction::Transfer(address) => { + Tokens::::mint(address, Balance { coin, amount: instruction.amount }) + } + _ => panic!("unsupported instruction"), + } + Ok(()) + } + } + #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight((0, DispatchClass::Mandatory))] // TODO - pub fn execute(origin: OriginFor, updates: Updates) -> DispatchResult { + #[pallet::weight((0, DispatchClass::Operational))] // TODO + pub fn update(origin: OriginFor, mut updates: Updates) -> DispatchResult { ensure_none(origin)?; assert!(!Once::::exists()); Once::::put(true); - for (coin, update) in updates.iter().enumerate() { + for (coin, update) in updates.iter_mut().enumerate() { if let Some(update) = update { let coin = coin_from_index(coin); BlockNumbers::::insert(coin, update.block_number); - for batch in &update.batches { - // TODO: EXECUTE + for batch in update.batches.iter_mut() { Self::deposit_event(Event::Batch { coin, id: batch.id }); + for (i, instruction) in batch.instructions.drain(..).enumerate() { + if Self::execute(coin, instruction).is_err() { + Self::deposit_event(Event::Failure { + coin, + id: batch.id, + index: u32::try_from(i).unwrap(), + }); + } + } } } } @@ -157,7 +180,7 @@ pub mod pallet { data .get_data::(&INHERENT_IDENTIFIER) .unwrap() - .map(|updates| Call::execute { updates }) + .map(|updates| Call::update { updates }) } // Assumes that only not yet handled batches are provided as inherent data @@ -167,7 +190,7 @@ pub mod pallet { let expected = data.get_data::(&INHERENT_IDENTIFIER).unwrap().unwrap(); // Match to be exhaustive let updates = match call { - Call::execute { ref updates } => updates, + Call::update { ref updates } => updates, _ => Err(InherentError::InvalidCall)?, }; diff --git a/substrate/in-instructions/primitives/Cargo.toml b/substrate/in-instructions/primitives/Cargo.toml index c2d4c788..fff968ce 100644 --- a/substrate/in-instructions/primitives/Cargo.toml +++ b/substrate/in-instructions/primitives/Cargo.toml @@ -16,10 +16,9 @@ scale-info = { version = "2", default-features = false, features = ["derive"] } serde = { version = "1", features = ["derive"], optional = true } -sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } - serai-primitives = { path = "../../serai/primitives", default-features = false } +tokens-primitives = { path = "../../tokens/primitives", default-features = false } [features] -std = ["scale/std", "scale-info/std", "serde", "sp-core/std", "serai-primitives/std"] +std = ["scale/std", "scale-info/std", "serde", "serai-primitives/std", "tokens-primitives/std"] default = ["std"] diff --git a/substrate/in-instructions/primitives/src/incoming.rs b/substrate/in-instructions/primitives/src/incoming.rs deleted file mode 100644 index 0a685a11..00000000 --- a/substrate/in-instructions/primitives/src/incoming.rs +++ /dev/null @@ -1,38 +0,0 @@ -use scale::{Encode, Decode, MaxEncodedLen}; -use scale_info::TypeInfo; - -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; - -use sp_core::{ConstU32, bounded::BoundedVec}; - -use serai_primitives::SeraiAddress; - -use crate::{MAX_DATA_LEN, ExternalAddress}; - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum Application { - DEX, -} - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct ApplicationCall { - application: Application, - data: BoundedVec>, -} - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum InInstruction { - Transfer(SeraiAddress), - Call(ApplicationCall), -} - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct RefundableInInstruction { - pub origin: Option, - pub instruction: InInstruction, -} diff --git a/substrate/in-instructions/primitives/src/lib.rs b/substrate/in-instructions/primitives/src/lib.rs index befc593e..efcb85fa 100644 --- a/substrate/in-instructions/primitives/src/lib.rs +++ b/substrate/in-instructions/primitives/src/lib.rs @@ -8,40 +8,34 @@ use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use sp_core::{ConstU32, bounded::BoundedVec}; - -// Monero, our current longest address candidate, has a longest address of featured with payment ID -// 1 (enum) + 1 (flags) + 64 (two keys) + 8 (payment ID) = 74 -pub const MAX_ADDRESS_LEN: u32 = 74; -// Should be enough for a Uniswap v3 call -pub const MAX_DATA_LEN: u32 = 512; - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct ExternalAddress(BoundedVec>); -impl ExternalAddress { - #[cfg(feature = "std")] - pub fn new(address: Vec) -> Result { - Ok(ExternalAddress(address.try_into().map_err(|_| "address length exceeds {MAX_ADDRESS_LEN}")?)) - } - - pub fn address(&self) -> &[u8] { - self.0.as_ref() - } - - #[cfg(feature = "std")] - pub fn consume(self) -> Vec { - self.0.into_inner() - } -} - -// Not "in" as "in" is a keyword -mod incoming; -pub use incoming::*; - -// Not "out" to match in -mod outgoing; -pub use outgoing::*; +use serai_primitives::{SeraiAddress, ExternalAddress, Data}; mod shorthand; pub use shorthand::*; + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum Application { + DEX, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct ApplicationCall { + application: Application, + data: Data, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum InInstruction { + Transfer(SeraiAddress), + Call(ApplicationCall), +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct RefundableInInstruction { + pub origin: Option, + pub instruction: InInstruction, +} diff --git a/substrate/in-instructions/primitives/src/outgoing.rs b/substrate/in-instructions/primitives/src/outgoing.rs deleted file mode 100644 index 2e8cf426..00000000 --- a/substrate/in-instructions/primitives/src/outgoing.rs +++ /dev/null @@ -1,25 +0,0 @@ -use scale::{Encode, Decode, MaxEncodedLen}; -use scale_info::TypeInfo; - -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; - -use sp_core::{ConstU32, bounded::BoundedVec}; - -use serai_primitives::SeraiAddress; - -use crate::{MAX_DATA_LEN, ExternalAddress}; - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum Destination { - Native(SeraiAddress), - External(ExternalAddress), -} - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct OutInstruction { - destination: Destination, - data: Option>>, -} diff --git a/substrate/in-instructions/primitives/src/shorthand.rs b/substrate/in-instructions/primitives/src/shorthand.rs index e3944510..618787b4 100644 --- a/substrate/in-instructions/primitives/src/shorthand.rs +++ b/substrate/in-instructions/primitives/src/shorthand.rs @@ -4,16 +4,18 @@ use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use sp_core::{ConstU32, bounded::BoundedVec}; +use serai_primitives::{Coin, Amount, SeraiAddress, ExternalAddress, Data}; -use serai_primitives::{SeraiAddress, Coin, Amount}; +use tokens_primitives::OutInstruction; -use crate::{MAX_DATA_LEN, ExternalAddress, RefundableInInstruction, InInstruction, OutInstruction}; +use crate::RefundableInInstruction; +#[cfg(feature = "std")] +use crate::InInstruction; #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum Shorthand { - Raw(BoundedVec>), + Raw(Data), Swap { origin: Option, coin: Coin, @@ -29,9 +31,10 @@ pub enum Shorthand { } impl Shorthand { + #[cfg(feature = "std")] pub fn transfer(origin: Option, address: SeraiAddress) -> Option { Some(Self::Raw( - BoundedVec::try_from( + Data::new( (RefundableInInstruction { origin, instruction: InInstruction::Transfer(address) }) .encode(), ) @@ -45,7 +48,7 @@ impl TryFrom for RefundableInInstruction { fn try_from(shorthand: Shorthand) -> Result { Ok(match shorthand { Shorthand::Raw(raw) => { - RefundableInInstruction::decode(&mut raw.as_ref()).map_err(|_| "invalid raw instruction")? + RefundableInInstruction::decode(&mut raw.data()).map_err(|_| "invalid raw instruction")? } Shorthand::Swap { .. } => todo!(), Shorthand::AddLiquidity { .. } => todo!(), diff --git a/substrate/node/src/chain_spec.rs b/substrate/node/src/chain_spec.rs index 63ca7a05..b440b49e 100644 --- a/substrate/node/src/chain_spec.rs +++ b/substrate/node/src/chain_spec.rs @@ -1,43 +1,42 @@ -use sp_core::{Decode, Pair as PairTrait, sr25519::Pair}; -use sp_runtime::traits::TrailingZeroInput; +use sp_core::Pair as PairTrait; use sc_service::ChainType; use serai_runtime::{ - primitives::*, tendermint::crypto::Public, WASM_BINARY, opaque::SessionKeys, GenesisConfig, - SystemConfig, BalancesConfig, AssetsConfig, ValidatorSetsConfig, SessionConfig, + primitives::*, tokens::primitives::ADDRESS as TOKENS_ADDRESS, tendermint::crypto::Public, + WASM_BINARY, opaque::SessionKeys, GenesisConfig, SystemConfig, BalancesConfig, AssetsConfig, + ValidatorSetsConfig, SessionConfig, }; pub type ChainSpec = sc_service::GenericChainSpec; -fn insecure_pair_from_name(name: &'static str) -> Pair { - Pair::from_string(&format!("//{name}"), None).unwrap() -} - -fn address_from_name(name: &'static str) -> SeraiAddress { +fn account_from_name(name: &'static str) -> PublicKey { insecure_pair_from_name(name).public() } fn testnet_genesis( wasm_binary: &[u8], validators: &[&'static str], - endowed_accounts: Vec, + endowed_accounts: Vec, ) -> GenesisConfig { let session_key = |name| { - let key = address_from_name(name); + let key = account_from_name(name); (key, key, SessionKeys { tendermint: Public::from(key) }) }; - // TODO: Replace with a call to the pallet to ask for its account - let owner = SeraiAddress::decode(&mut TrailingZeroInput::new(b"tokens")).unwrap(); - GenesisConfig { system: SystemConfig { code: wasm_binary.to_vec() }, + balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), }, + transaction_payment: Default::default(), + assets: AssetsConfig { - assets: [BITCOIN, ETHER, DAI, MONERO].iter().map(|coin| (*coin, owner, true, 1)).collect(), + assets: [BITCOIN, ETHER, DAI, MONERO] + .iter() + .map(|coin| (*coin, TOKENS_ADDRESS.into(), true, 1)) + .collect(), metadata: vec![ (BITCOIN, b"Bitcoin".to_vec(), b"BTC".to_vec(), 8), // Reduce to 8 decimals to feasibly fit within u64 (instead of its native u256) @@ -47,14 +46,13 @@ fn testnet_genesis( ], accounts: vec![], }, - transaction_payment: Default::default(), - validator_sets: ValidatorSetsConfig { - bond: Amount(1_000_000) * COIN, - coins: vec![BITCOIN, ETHER, DAI, MONERO], - participants: validators.iter().map(|name| address_from_name(name)).collect(), - }, session: SessionConfig { keys: validators.iter().map(|name| session_key(*name)).collect() }, + validator_sets: ValidatorSetsConfig { + bond: Amount(1_000_000 * 10_u64.pow(8)), + coins: vec![BITCOIN, ETHER, DAI, MONERO], + participants: validators.iter().map(|name| account_from_name(name)).collect(), + }, } } @@ -72,18 +70,18 @@ pub fn development_config() -> Result { wasm_binary, &["Alice"], vec![ - address_from_name("Alice"), - address_from_name("Bob"), - address_from_name("Charlie"), - address_from_name("Dave"), - address_from_name("Eve"), - address_from_name("Ferdie"), - address_from_name("Alice//stash"), - address_from_name("Bob//stash"), - address_from_name("Charlie//stash"), - address_from_name("Dave//stash"), - address_from_name("Eve//stash"), - address_from_name("Ferdie//stash"), + account_from_name("Alice"), + account_from_name("Bob"), + account_from_name("Charlie"), + account_from_name("Dave"), + account_from_name("Eve"), + account_from_name("Ferdie"), + account_from_name("Alice//stash"), + account_from_name("Bob//stash"), + account_from_name("Charlie//stash"), + account_from_name("Dave//stash"), + account_from_name("Eve//stash"), + account_from_name("Ferdie//stash"), ], ) }, @@ -116,18 +114,18 @@ pub fn testnet_config() -> Result { wasm_binary, &["Alice", "Bob", "Charlie"], vec![ - address_from_name("Alice"), - address_from_name("Bob"), - address_from_name("Charlie"), - address_from_name("Dave"), - address_from_name("Eve"), - address_from_name("Ferdie"), - address_from_name("Alice//stash"), - address_from_name("Bob//stash"), - address_from_name("Charlie//stash"), - address_from_name("Dave//stash"), - address_from_name("Eve//stash"), - address_from_name("Ferdie//stash"), + account_from_name("Alice"), + account_from_name("Bob"), + account_from_name("Charlie"), + account_from_name("Dave"), + account_from_name("Eve"), + account_from_name("Ferdie"), + account_from_name("Alice//stash"), + account_from_name("Bob//stash"), + account_from_name("Charlie//stash"), + account_from_name("Dave//stash"), + account_from_name("Eve//stash"), + account_from_name("Ferdie//stash"), ], ) }, diff --git a/substrate/node/src/command_helper.rs b/substrate/node/src/command_helper.rs index 7d944b69..beea5b12 100644 --- a/substrate/node/src/command_helper.rs +++ b/substrate/node/src/command_helper.rs @@ -67,7 +67,7 @@ pub fn create_benchmark_extrinsic( UncheckedExtrinsic::new_signed( call.clone(), - sender.public(), + sender.public().into(), SignedPayload::from_raw( call, extra.clone(), diff --git a/substrate/node/src/rpc.rs b/substrate/node/src/rpc.rs index c5df739d..e0a6c16c 100644 --- a/substrate/node/src/rpc.rs +++ b/substrate/node/src/rpc.rs @@ -6,7 +6,11 @@ use sp_blockchain::{Error as BlockchainError, HeaderBackend, HeaderMetadata}; use sp_block_builder::BlockBuilder; use sp_api::ProvideRuntimeApi; -use serai_runtime::{primitives::SeraiAddress, opaque::Block, Balance, Index}; +use serai_runtime::{ + primitives::{SubstrateAmount, PublicKey}, + opaque::Block, + Index, +}; pub use sc_rpc_api::DenyUnsafe; use sc_transaction_pool_api::TransactionPool; @@ -29,8 +33,8 @@ pub fn create_full< deps: FullDeps, ) -> Result, Box> where - C::Api: substrate_frame_rpc_system::AccountNonceApi - + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + C::Api: substrate_frame_rpc_system::AccountNonceApi + + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + BlockBuilder, { use substrate_frame_rpc_system::{System, SystemApiServer}; diff --git a/substrate/node/src/service.rs b/substrate/node/src/service.rs index f6aa1e1f..d4a6b4f9 100644 --- a/substrate/node/src/service.rs +++ b/substrate/node/src/service.rs @@ -76,9 +76,9 @@ impl TendermintClientMinimal for TendermintValidatorFirm { // guaranteed not to grow the block? const PROPOSED_BLOCK_SIZE_LIMIT: usize = { BLOCK_SIZE as usize }; // 3 seconds - const BLOCK_PROCESSING_TIME_IN_SECONDS: u32 = { (TARGET_BLOCK_TIME / 2 / 1000) as u32 }; + const BLOCK_PROCESSING_TIME_IN_SECONDS: u32 = { (TARGET_BLOCK_TIME / 2) as u32 }; // 1 second - const LATENCY_TIME_IN_SECONDS: u32 = { (TARGET_BLOCK_TIME / 2 / 3 / 1000) as u32 }; + const LATENCY_TIME_IN_SECONDS: u32 = { (TARGET_BLOCK_TIME / 2 / 3) as u32 }; type Block = Block; type Backend = sc_client_db::Backend; @@ -101,7 +101,7 @@ impl TendermintValidator for TendermintValidatorFirm { pub fn new_partial( config: &Configuration, ) -> Result<(TendermintImport, PartialComponents), ServiceError> { - debug_assert_eq!(TARGET_BLOCK_TIME, 6000); + debug_assert_eq!(TARGET_BLOCK_TIME, 6); if config.keystore_remote.is_some() { return Err(ServiceError::Other("Remote Keystores are not supported".to_string())); diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index a379fdb9..74c305e7 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -41,6 +41,7 @@ pallet-balances = { git = "https://github.com/serai-dex/substrate", default-feat pallet-assets = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", default-features = false } +tokens-pallet = { path = "../tokens/pallet", default-features = false } in-instructions-pallet = { path = "../in-instructions/pallet", default-features = false } validator-sets-pallet = { path = "../validator-sets/pallet", default-features = false } @@ -78,9 +79,10 @@ std = [ "serai-primitives/std", "pallet-balances/std", - "pallet-assets/std", "pallet-transaction-payment/std", + "pallet-assets/std", + "tokens-pallet/std", "in-instructions-pallet/std", "validator-sets-pallet/std", diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 91d48750..cd5c6c91 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -16,6 +16,7 @@ pub use pallet_balances as balances; pub use pallet_transaction_payment as transaction_payment; pub use pallet_assets as assets; +pub use tokens_pallet as tokens; pub use in_instructions_pallet as in_instructions; pub use validator_sets_pallet as validator_sets; @@ -33,15 +34,15 @@ use sp_version::NativeVersion; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, KeyTypeId, - traits::{Convert, OpaqueKeys, IdentityLookup, BlakeTwo256, Block as BlockT}, + traits::{Convert, OpaqueKeys, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, }; -use primitives::{PublicKey, Signature, SeraiAddress, Coin}; +use primitives::{PublicKey, SeraiAddress, AccountLookup, Signature, SubstrateAmount, Coin}; use support::{ - traits::{ConstU8, ConstU32, ConstU64}, + traits::{ConstU8, ConstU32, ConstU64, Contains}, weights::{ constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND}, IdentityFee, Weight, @@ -56,14 +57,6 @@ use session::PeriodicSessions; /// An index to a block. pub type BlockNumber = u32; -/// Balance of an account. -// Distinct from serai-primitives Amount due to Substrate's requirements on this type. -// If Amount could be dropped in here, it would be. -// While Amount could have all the necessary traits implemented, not only are they many, yet it'd -// make Amount a larger type, providing more operations than desired. -// The current type's minimalism sets clear bounds on usage. -pub type Balance = u64; - /// Index of a transaction in the chain, for a given account. pub type Index = u32; @@ -104,10 +97,10 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // 1 MB pub const BLOCK_SIZE: u32 = 1024 * 1024; // 6 seconds -pub const TARGET_BLOCK_TIME: u64 = 6000; +pub const TARGET_BLOCK_TIME: u64 = 6; /// Measured in blocks. -pub const MINUTES: BlockNumber = 60_000 / (TARGET_BLOCK_TIME as BlockNumber); +pub const MINUTES: BlockNumber = 60 / (TARGET_BLOCK_TIME as BlockNumber); pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; @@ -134,13 +127,44 @@ parameter_types! { ); } +pub struct CallFilter; +impl Contains for CallFilter { + fn contains(call: &RuntimeCall) -> bool { + if let RuntimeCall::Balances(call) = call { + return matches!(call, balances::Call::transfer { .. } | balances::Call::transfer_all { .. }); + } + + if let RuntimeCall::Assets(call) = call { + return matches!( + call, + assets::Call::approve_transfer { .. } | + assets::Call::cancel_approval { .. } | + assets::Call::transfer { .. } | + assets::Call::transfer_approved { .. } + ); + } + if let RuntimeCall::Tokens(call) = call { + return matches!(call, tokens::Call::burn { .. }); + } + if let RuntimeCall::InInstructions(call) = call { + return matches!(call, in_instructions::Call::update { .. }); + } + + if let RuntimeCall::ValidatorSets(call) = call { + return matches!(call, validator_sets::Call::vote { .. }); + } + + false + } +} + impl system::Config for Runtime { - type BaseCallFilter = support::traits::Everything; + type BaseCallFilter = CallFilter; type BlockWeights = BlockWeights; type BlockLength = BlockLength; - type AccountId = SeraiAddress; + type AccountId = PublicKey; type RuntimeCall = RuntimeCall; - type Lookup = IdentityLookup; + type Lookup = AccountLookup; type Index = Index; type BlockNumber = BlockNumber; type Hash = Hash; @@ -157,7 +181,7 @@ impl system::Config for Runtime { type OnKilledAccount = (); type OnSetCode = (); - type AccountData = balances::AccountData; + type AccountData = balances::AccountData; type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; // TODO: Remove for Bech32m @@ -168,7 +192,7 @@ impl balances::Config for Runtime { type MaxLocks = ConstU32<50>; type MaxReserves = (); type ReserveIdentifier = [u8; 8]; - type Balance = Balance; + type Balance = SubstrateAmount; type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ConstU64<500>; @@ -176,9 +200,18 @@ impl balances::Config for Runtime { type WeightInfo = balances::weights::SubstrateWeight; } +impl transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = IdentityFee; + type FeeMultiplierUpdate = (); +} + impl assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type Balance = Balance; + type Balance = SubstrateAmount; type Currency = Balances; type AssetId = Coin; @@ -186,8 +219,8 @@ impl assets::Config for Runtime { type StringLimit = ConstU32<32>; // Don't allow anyone to create assets - type CreateOrigin = support::traits::AsEnsureOriginWithArg>; - type ForceOrigin = system::EnsureRoot; + type CreateOrigin = support::traits::AsEnsureOriginWithArg>; + type ForceOrigin = system::EnsureRoot; // Don't charge fees nor kill accounts type RemoveItemsLimit = ConstU32<0>; @@ -207,13 +240,8 @@ impl assets::Config for Runtime { type BenchmarkHelper = (); } -impl transaction_payment::Config for Runtime { +impl tokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = CurrencyAdapter; - type OperationalFeeMultiplier = ConstU8<5>; - type WeightToFee = IdentityFee; - type LengthToFee = IdentityFee; - type FeeMultiplierUpdate = (); } impl in_instructions::Config for Runtime { @@ -236,7 +264,7 @@ impl validator_sets::Config for Runtime { impl session::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type ValidatorId = SeraiAddress; + type ValidatorId = PublicKey; type ValidatorIdOf = IdentityValidatorIdOf; type ShouldEndSession = Sessions; type NextSessionRotation = Sessions; @@ -283,6 +311,7 @@ construct_runtime!( TransactionPayment: transaction_payment, Assets: assets, + Tokens: tokens, InInstructions: in_instructions, ValidatorSets: validator_sets, @@ -381,31 +410,31 @@ sp_api::impl_runtime_apis! { } fn validators() -> Vec { - Session::validators() + Session::validators().drain(..).map(Into::into).collect() } } - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: SeraiAddress) -> Index { + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: PublicKey) -> Index { System::account_nonce(account) } } impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< Block, - Balance + SubstrateAmount > for Runtime { fn query_info( uxt: ::Extrinsic, len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { TransactionPayment::query_info(uxt, len) } fn query_fee_details( uxt: ::Extrinsic, len: u32, - ) -> transaction_payment::FeeDetails { + ) -> transaction_payment::FeeDetails { TransactionPayment::query_fee_details(uxt, len) } } diff --git a/substrate/serai/client/Cargo.toml b/substrate/serai/client/Cargo.toml index ca35be61..f26f2485 100644 --- a/substrate/serai/client/Cargo.toml +++ b/substrate/serai/client/Cargo.toml @@ -15,19 +15,22 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] thiserror = "1" -serde = { version = "1", features = ["derive"] } - scale = { package = "parity-scale-codec", version = "3" } +scale-info = "2" scale-value = "0.6" -subxt = "0.25" + +sp-core = { git = "https://github.com/serai-dex/substrate", version = "7" } serai-primitives = { path = "../primitives", version = "0.1" } -in-instructions-primitives = { path = "../../in-instructions/primitives", version = "0.1" } serai-runtime = { path = "../../runtime", version = "0.1" } +subxt = "0.25" + [dev-dependencies] lazy_static = "1" +rand_core = "0.6" + tokio = "1" jsonrpsee-server = "0.16" diff --git a/substrate/serai/client/metadata.json b/substrate/serai/client/metadata.json new file mode 100644 index 00000000..e69de29b diff --git a/substrate/serai/client/src/in_instructions.rs b/substrate/serai/client/src/in_instructions.rs index 8c26b80a..9187d7a4 100644 --- a/substrate/serai/client/src/in_instructions.rs +++ b/substrate/serai/client/src/in_instructions.rs @@ -1,15 +1,9 @@ -use scale::Decode; - -use serai_runtime::{ - support::traits::PalletInfo as PalletInfoTrait, PalletInfo, in_instructions, InInstructions, - Runtime, -}; - -pub use in_instructions_primitives as primitives; +use serai_runtime::{in_instructions, InInstructions, Runtime}; +pub use in_instructions::primitives; use crate::{ primitives::{Coin, BlockNumber}, - Serai, SeraiError, + Serai, SeraiError, scale_value, }; const PALLET: &str = "InInstructions"; @@ -21,22 +15,11 @@ impl Serai { &self, block: [u8; 32], ) -> Result, SeraiError> { - let mut res = vec![]; - for event in - self.0.events().at(Some(block.into())).await.map_err(|_| SeraiError::RpcError)?.iter() - { - let event = event.map_err(|_| SeraiError::InvalidRuntime)?; - if PalletInfo::index::().unwrap() == usize::from(event.pallet_index()) { - let mut with_variant: &[u8] = - &[[event.variant_index()].as_ref(), event.field_bytes()].concat(); - let event = - InInstructionsEvent::decode(&mut with_variant).map_err(|_| SeraiError::InvalidRuntime)?; - if matches!(event, InInstructionsEvent::Batch { .. }) { - res.push(event); - } - } - } - Ok(res) + self + .events::(block, |event| { + matches!(event, InInstructionsEvent::Batch { .. }) + }) + .await } pub async fn get_coin_block_number( @@ -44,6 +27,11 @@ impl Serai { coin: Coin, block: [u8; 32], ) -> Result { - Ok(self.storage(PALLET, "BlockNumbers", Some(coin), block).await?.unwrap_or(BlockNumber(0))) + Ok( + self + .storage(PALLET, "BlockNumbers", Some(vec![scale_value(coin)]), block) + .await? + .unwrap_or(BlockNumber(0)), + ) } } diff --git a/substrate/serai/client/src/lib.rs b/substrate/serai/client/src/lib.rs index 36bfd8a5..8cf6dec8 100644 --- a/substrate/serai/client/src/lib.rs +++ b/substrate/serai/client/src/lib.rs @@ -1,19 +1,36 @@ use thiserror::Error; -use serde::Serialize; -use scale::Decode; +use scale::{Encode, Decode}; +mod scale_value; +pub(crate) use crate::scale_value::{scale_value, scale_composite}; +use ::scale_value::Value; -use subxt::{tx::BaseExtrinsicParams, Config as SubxtConfig, OnlineClient}; +use subxt::{ + utils::Encoded, + tx::{ + Signer, DynamicTxPayload, BaseExtrinsicParams, BaseExtrinsicParamsBuilder, TxClient, + }, + Config as SubxtConfig, OnlineClient, +}; pub use serai_primitives as primitives; use primitives::{Signature, SeraiAddress}; -use serai_runtime::{system::Config, Runtime}; +use serai_runtime::{ + system::Config, support::traits::PalletInfo as PalletInfoTrait, PalletInfo, Runtime, +}; +pub mod tokens; pub mod in_instructions; +#[derive(Clone, Copy, PartialEq, Eq, Default, Debug, Encode, Decode)] +pub struct Tip { + #[codec(compact)] + pub tip: u64, +} + #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub(crate) struct SeraiConfig; +pub struct SeraiConfig; impl SubxtConfig for SeraiConfig { type BlockNumber = ::BlockNumber; @@ -28,7 +45,7 @@ impl SubxtConfig for SeraiConfig { type Header = ::Header; type Signature = Signature; - type ExtrinsicParams = BaseExtrinsicParams; + type ExtrinsicParams = BaseExtrinsicParams; } #[derive(Clone, Error, Debug)] @@ -47,21 +64,16 @@ impl Serai { Ok(Serai(OnlineClient::::from_url(url).await.map_err(|_| SeraiError::RpcError)?)) } - async fn storage( + async fn storage( &self, pallet: &'static str, name: &'static str, - key: Option, + keys: Option>, block: [u8; 32], ) -> Result, SeraiError> { - let mut keys = vec![]; - if let Some(key) = key { - keys.push(scale_value::serde::to_value(key).unwrap()); - } - let storage = self.0.storage(); - let address = subxt::dynamic::storage(pallet, name, keys); - debug_assert!(storage.validate(&address).is_ok()); + let address = subxt::dynamic::storage(pallet, name, keys.unwrap_or(vec![])); + debug_assert!(storage.validate(&address).is_ok(), "invalid storage address"); storage .fetch(&address, Some(block.into())) @@ -71,7 +83,46 @@ impl Serai { .transpose() } + async fn events( + &self, + block: [u8; 32], + filter: impl Fn(&E) -> bool, + ) -> Result, SeraiError> { + let mut res = vec![]; + for event in + self.0.events().at(Some(block.into())).await.map_err(|_| SeraiError::RpcError)?.iter() + { + let event = event.map_err(|_| SeraiError::InvalidRuntime)?; + if PalletInfo::index::

().unwrap() == usize::from(event.pallet_index()) { + let mut with_variant: &[u8] = + &[[event.variant_index()].as_ref(), event.field_bytes()].concat(); + let event = E::decode(&mut with_variant).map_err(|_| SeraiError::InvalidRuntime)?; + if filter(&event) { + res.push(event); + } + } + } + Ok(res) + } + pub async fn get_latest_block_hash(&self) -> Result<[u8; 32], SeraiError> { Ok(self.0.rpc().finalized_head().await.map_err(|_| SeraiError::RpcError)?.into()) } + + pub fn sign>( + &self, + signer: &S, + payload: &DynamicTxPayload<'static>, + nonce: u32, + params: BaseExtrinsicParamsBuilder, + ) -> Result { + TxClient::new(self.0.offline()) + .create_signed_with_nonce(payload, signer, nonce, params) + .map(|tx| Encoded(tx.into_encoded())) + .map_err(|_| SeraiError::InvalidRuntime) + } + + pub async fn publish(&self, tx: &Encoded) -> Result<[u8; 32], SeraiError> { + self.0.rpc().submit_extrinsic(tx).await.map(Into::into).map_err(|_| SeraiError::RpcError) + } } diff --git a/substrate/serai/client/src/scale_value.rs b/substrate/serai/client/src/scale_value.rs new file mode 100644 index 00000000..0e74b1b2 --- /dev/null +++ b/substrate/serai/client/src/scale_value.rs @@ -0,0 +1,18 @@ +use ::scale::Encode; +use scale_info::{MetaType, TypeInfo, Registry, PortableRegistry}; +use scale_value::{Composite, ValueDef, Value, scale}; + +pub(crate) fn scale_value(value: V) -> Value { + let mut registry = Registry::new(); + let id = registry.register_type(&MetaType::new::()).id(); + let registry = PortableRegistry::from(registry); + scale::decode_as_type(&mut value.encode().as_ref(), id, ®istry).unwrap().remove_context() +} + +pub(crate) fn scale_composite(value: V) -> Composite<()> { + match scale_value(value).value { + ValueDef::Composite(composite) => composite, + ValueDef::Variant(variant) => variant.values, + _ => panic!("not composite"), + } +} diff --git a/substrate/serai/client/src/tokens.rs b/substrate/serai/client/src/tokens.rs new file mode 100644 index 00000000..f77e34e1 --- /dev/null +++ b/substrate/serai/client/src/tokens.rs @@ -0,0 +1,68 @@ +use serai_runtime::{ + primitives::{SeraiAddress, SubstrateAmount, Amount, Coin, Balance}, + assets::{AssetDetails, AssetAccount}, + tokens, Tokens, Runtime, +}; +pub use tokens::primitives; +use primitives::OutInstruction; + +use subxt::tx::{self, DynamicTxPayload}; + +use crate::{Serai, SeraiError, scale_value, scale_composite}; + +const PALLET: &str = "Tokens"; + +pub type TokensEvent = tokens::Event; + +impl Serai { + pub async fn get_mint_events(&self, block: [u8; 32]) -> Result, SeraiError> { + self.events::(block, |event| matches!(event, TokensEvent::Mint { .. })).await + } + + pub async fn get_token_supply(&self, block: [u8; 32], coin: Coin) -> Result { + Ok(Amount( + self + .storage::>( + "Assets", + "Asset", + Some(vec![scale_value(coin)]), + block, + ) + .await? + .map(|token| token.supply) + .unwrap_or(0), + )) + } + + pub async fn get_token_balance( + &self, + block: [u8; 32], + coin: Coin, + address: SeraiAddress, + ) -> Result { + Ok(Amount( + self + .storage::>( + "Assets", + "Account", + Some(vec![scale_value(coin), scale_value(address)]), + block, + ) + .await? + .map(|account| account.balance) + .unwrap_or(0), + )) + } + + pub fn burn(balance: Balance, instruction: OutInstruction) -> DynamicTxPayload<'static> { + tx::dynamic( + PALLET, + "burn", + scale_composite(tokens::Call::::burn { balance, instruction }), + ) + } + + pub async fn get_burn_events(&self, block: [u8; 32]) -> Result, SeraiError> { + self.events::(block, |event| matches!(event, TokensEvent::Burn { .. })).await + } +} diff --git a/substrate/serai/client/tests/burn.rs b/substrate/serai/client/tests/burn.rs new file mode 100644 index 00000000..9e58ed4b --- /dev/null +++ b/substrate/serai/client/tests/burn.rs @@ -0,0 +1,79 @@ +use core::time::Duration; + +use rand_core::{RngCore, OsRng}; + +use sp_core::Pair; +use serai_runtime::in_instructions::{Batch, Update}; + +use tokio::time::sleep; + +use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; + +use serai_client::{ + primitives::{ + BITCOIN, BlockNumber, BlockHash, SeraiAddress, Amount, WithAmount, Balance, Data, + ExternalAddress, insecure_pair_from_name, + }, + in_instructions::primitives::InInstruction, + tokens::{primitives::OutInstruction, TokensEvent}, + Serai, +}; + +mod runner; +use runner::{URL, provide_updates}; + +serai_test!( + async fn burn() { + let coin = BITCOIN; + let mut id = BlockHash([0; 32]); + OsRng.fill_bytes(&mut id.0); + let block_number = BlockNumber(u32::try_from(OsRng.next_u64() >> 32).unwrap()); + + let pair = insecure_pair_from_name("Alice"); + let public = pair.public(); + let address = SeraiAddress::from(public); + + let amount = Amount(OsRng.next_u64()); + let balance = Balance { coin, amount }; + + let mut rand_bytes = vec![0; 32]; + OsRng.fill_bytes(&mut rand_bytes); + let external_address = ExternalAddress::new(rand_bytes).unwrap(); + + let mut rand_bytes = vec![0; 32]; + OsRng.fill_bytes(&mut rand_bytes); + let data = Data::new(rand_bytes).unwrap(); + + let batch = Batch { + id, + instructions: vec![WithAmount { data: InInstruction::Transfer(address), amount }], + }; + let update = Update { block_number, batches: vec![batch] }; + let block = provide_updates(vec![Some(update)]).await; + + let serai = Serai::new(URL).await.unwrap(); + assert_eq!(serai.get_token_balance(block, coin, address).await.unwrap(), amount); + + let out = OutInstruction { address: external_address, data: Some(data) }; + let burn = Serai::burn(balance, out.clone()); + + let signer = PairSigner::new(pair); + serai + .publish(&serai.sign(&signer, &burn, 0, BaseExtrinsicParamsBuilder::new()).unwrap()) + .await + .unwrap(); + + loop { + let block = serai.get_latest_block_hash().await.unwrap(); + let events = serai.get_burn_events(block).await.unwrap(); + if events.is_empty() { + sleep(Duration::from_millis(50)).await; + continue; + } + assert_eq!(events, vec![TokensEvent::Burn { address, balance, instruction: out }]); + assert_eq!(serai.get_token_supply(block, coin).await.unwrap(), Amount(0)); + assert_eq!(serai.get_token_balance(block, coin, address).await.unwrap(), Amount(0)); + break; + } + } +); diff --git a/substrate/serai/client/tests/runner.rs b/substrate/serai/client/tests/runner.rs index e5ed4542..1e9e7444 100644 --- a/substrate/serai/client/tests/runner.rs +++ b/substrate/serai/client/tests/runner.rs @@ -1,6 +1,14 @@ +use core::time::Duration; +use std::sync::Arc; + use lazy_static::lazy_static; -use tokio::sync::Mutex; +use tokio::{sync::Mutex, time::sleep}; + +use serai_runtime::in_instructions::Update; +use serai_client::{primitives::Coin, in_instructions::InInstructionsEvent, Serai}; + +use jsonrpsee_server::RpcModule; pub const URL: &str = "ws://127.0.0.1:9944"; @@ -8,6 +16,73 @@ lazy_static! { pub static ref SEQUENTIAL: Mutex<()> = Mutex::new(()); } +#[allow(dead_code)] +pub async fn provide_updates(updates: Vec>) -> [u8; 32] { + let done = Arc::new(Mutex::new(false)); + let done_clone = done.clone(); + let updates_clone = updates.clone(); + + let mut rpc = RpcModule::new(()); + rpc + .register_async_method("processor_coinUpdates", move |_, _| { + let done_clone = done_clone.clone(); + let updates_clone = updates_clone.clone(); + async move { + // Sleep to prevent a race condition where we submit the inherents for this block and the + // next one, then remove them, making them unverifiable, causing the node to panic for + // being self-malicious + sleep(Duration::from_millis(500)).await; + if !*done_clone.lock().await { + Ok(updates_clone) + } else { + Ok(vec![]) + } + } + }) + .unwrap(); + let _handle = jsonrpsee_server::ServerBuilder::default() + .build("127.0.0.1:5134") + .await + .unwrap() + .start(rpc) + .unwrap(); + + let serai = Serai::new(URL).await.unwrap(); + loop { + let latest = serai.get_latest_block_hash().await.unwrap(); + let mut batches = serai.get_batch_events(latest).await.unwrap(); + if batches.is_empty() { + sleep(Duration::from_millis(50)).await; + continue; + } + *done.lock().await = true; + + for (index, update) in updates.iter().enumerate() { + if let Some(update) = update { + let coin_by_index = Coin(u32::try_from(index).unwrap() + 1); + + for expected in &update.batches { + match batches.swap_remove(0) { + InInstructionsEvent::Batch { coin, id } => { + assert_eq!(coin, coin_by_index); + assert_eq!(expected.id, id); + } + _ => panic!("get_batches returned non-batch"), + } + } + assert_eq!( + serai.get_coin_block_number(coin_by_index, latest).await.unwrap(), + update.block_number + ); + } + } + // This will fail if there were more batch events than expected + assert!(batches.is_empty()); + + return latest; + } +} + #[macro_export] macro_rules! serai_test { ($(async fn $name: ident() $body: block)*) => { diff --git a/substrate/serai/client/tests/updates.rs b/substrate/serai/client/tests/updates.rs index ba97bc73..05c30c83 100644 --- a/substrate/serai/client/tests/updates.rs +++ b/substrate/serai/client/tests/updates.rs @@ -1,60 +1,45 @@ -use core::time::Duration; - -use tokio::time::sleep; +use rand_core::{RngCore, OsRng}; use serai_runtime::in_instructions::{Batch, Update}; -use jsonrpsee_server::RpcModule; - use serai_client::{ - primitives::{BlockNumber, BlockHash, SeraiAddress, BITCOIN}, + primitives::{BITCOIN, BlockNumber, BlockHash, SeraiAddress, Amount, WithAmount, Balance}, + tokens::TokensEvent, in_instructions::{primitives::InInstruction, InInstructionsEvent}, Serai, }; mod runner; -use runner::URL; +use runner::{URL, provide_updates}; serai_test!( - async fn publish_update() { - let mut rpc = RpcModule::new(()); - rpc - .register_async_method("processor_coinUpdates", |_, _| async move { - let batch = Batch { - id: BlockHash([0xaa; 32]), - instructions: vec![InInstruction::Transfer(SeraiAddress::from_raw([0xff; 32]))], - }; + async fn publish_updates() { + let coin = BITCOIN; + let mut id = BlockHash([0; 32]); + OsRng.fill_bytes(&mut id.0); + let block_number = BlockNumber(u32::try_from(OsRng.next_u64() >> 32).unwrap()); - Ok(vec![Some(Update { block_number: BlockNumber(123), batches: vec![batch] })]) - }) - .unwrap(); + let mut address = SeraiAddress::new([0; 32]); + OsRng.fill_bytes(&mut address.0); + let amount = Amount(OsRng.next_u64()); - let _handle = jsonrpsee_server::ServerBuilder::default() - .build("127.0.0.1:5134") - .await - .unwrap() - .start(rpc) - .unwrap(); + let batch = Batch { + id, + instructions: vec![WithAmount { data: InInstruction::Transfer(address), amount }], + }; + let update = Update { block_number, batches: vec![batch] }; + let block = provide_updates(vec![Some(update)]).await; let serai = Serai::new(URL).await.unwrap(); - loop { - let latest = serai.get_latest_block_hash().await.unwrap(); - let batches = serai.get_batch_events(latest).await.unwrap(); - if let Some(batch) = batches.get(0) { - match batch { - InInstructionsEvent::Batch { coin, id } => { - assert_eq!(coin, &BITCOIN); - assert_eq!(id, &BlockHash([0xaa; 32])); - assert_eq!( - serai.get_coin_block_number(BITCOIN, latest).await.unwrap(), - BlockNumber(123) - ); - return; - } - _ => panic!("get_batches returned non-batch"), - } - } - sleep(Duration::from_millis(50)).await; - } + let batches = serai.get_batch_events(block).await.unwrap(); + assert_eq!(batches, vec![InInstructionsEvent::Batch { coin, id }]); + assert_eq!(serai.get_coin_block_number(coin, block).await.unwrap(), block_number); + + assert_eq!( + serai.get_mint_events(block).await.unwrap(), + vec![TokensEvent::Mint { address, balance: Balance { coin, amount } }] + ); + assert_eq!(serai.get_token_supply(block, coin).await.unwrap(), amount); + assert_eq!(serai.get_token_balance(block, coin, address).await.unwrap(), amount); } ); diff --git a/substrate/serai/primitives/Cargo.toml b/substrate/serai/primitives/Cargo.toml index 5d6a1490..303a27b0 100644 --- a/substrate/serai/primitives/Cargo.toml +++ b/substrate/serai/primitives/Cargo.toml @@ -18,7 +18,8 @@ scale-info = { version = "2", default-features = false, features = ["derive"] } serde = { version = "1", features = ["derive"], optional = true } sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } +sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false } [features] -std = ["scale/std", "scale-info/std", "serde", "sp-core/std"] +std = ["scale/std", "scale-info/std", "serde", "sp-core/std", "sp-runtime/std"] default = ["std"] diff --git a/substrate/serai/primitives/src/account.rs b/substrate/serai/primitives/src/account.rs new file mode 100644 index 00000000..4fcd2390 --- /dev/null +++ b/substrate/serai/primitives/src/account.rs @@ -0,0 +1,93 @@ +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use sp_core::sr25519::{Public, Signature as RistrettoSignature}; +#[cfg(feature = "std")] +use sp_core::{Pair as PairTrait, sr25519::Pair}; + +use sp_runtime::traits::{LookupError, Lookup, StaticLookup}; + +pub type PublicKey = Public; + +#[derive( + Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, +)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct SeraiAddress(pub [u8; 32]); +impl SeraiAddress { + pub fn new(key: [u8; 32]) -> SeraiAddress { + SeraiAddress(key) + } +} + +impl From<[u8; 32]> for SeraiAddress { + fn from(key: [u8; 32]) -> SeraiAddress { + SeraiAddress(key) + } +} + +impl From for SeraiAddress { + fn from(key: PublicKey) -> SeraiAddress { + SeraiAddress(key.0) + } +} + +impl From for PublicKey { + fn from(address: SeraiAddress) -> PublicKey { + PublicKey::from_raw(address.0) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for SeraiAddress { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // TODO: Bech32 + write!(f, "{:?}", self.0) + } +} + +#[cfg(feature = "std")] +pub fn insecure_pair_from_name(name: &'static str) -> Pair { + Pair::from_string(&format!("//{name}"), None).unwrap() +} + +pub struct AccountLookup; +impl Lookup for AccountLookup { + type Source = SeraiAddress; + type Target = PublicKey; + fn lookup(&self, source: SeraiAddress) -> Result { + Ok(PublicKey::from_raw(source.0)) + } +} +impl StaticLookup for AccountLookup { + type Source = SeraiAddress; + type Target = PublicKey; + fn lookup(source: SeraiAddress) -> Result { + Ok(source.into()) + } + fn unlookup(source: PublicKey) -> SeraiAddress { + source.into() + } +} + +pub type Signature = RistrettoSignature; + +pub const fn pallet_address(pallet: &'static [u8]) -> SeraiAddress { + let mut address = [0; 32]; + let mut set = false; + // Implement a while loop since we can't use a for loop + let mut i = 0; + while i < pallet.len() { + address[i] = pallet[i]; + if address[i] != 0 { + set = true; + } + i += 1; + } + // Make sure this address isn't the identity point + // Doesn't do address != [0; 32] since that's not const + assert!(set, "address is the identity point"); + SeraiAddress(address) +} diff --git a/substrate/serai/primitives/src/amount.rs b/substrate/serai/primitives/src/amount.rs index daf40abe..5d1875c5 100644 --- a/substrate/serai/primitives/src/amount.rs +++ b/substrate/serai/primitives/src/amount.rs @@ -1,20 +1,25 @@ -use core::ops::{Add, Sub, Mul}; +use core::{ + ops::{Add, Sub, Mul}, + fmt::Debug, +}; use scale::{Encode, Decode, MaxEncodedLen}; use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; +/// The type used for amounts within Substrate. +// Distinct from Amount due to Substrate's requirements on this type. +// While Amount could have all the necessary traits implemented, not only are they many, it'd make +// Amount a large type with a variety of misc functions. +// The current type's minimalism sets clear bounds on usage. +pub type SubstrateAmount = u64; /// The type used for amounts. #[derive( Clone, Copy, PartialEq, Eq, PartialOrd, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, )] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct Amount(pub u64); - -/// One whole coin with eight decimals. -#[allow(clippy::inconsistent_digit_grouping)] -pub const COIN: Amount = Amount(1_000_000_00); +pub struct Amount(pub SubstrateAmount); impl Add for Amount { type Output = Amount; @@ -37,3 +42,12 @@ impl Mul for Amount { Amount(self.0.checked_mul(other.0).unwrap()) } } + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct WithAmount< + T: Clone + PartialEq + Eq + Debug + Encode + Decode + MaxEncodedLen + TypeInfo, +> { + pub data: T, + pub amount: Amount, +} diff --git a/substrate/serai/primitives/src/balance.rs b/substrate/serai/primitives/src/balance.rs new file mode 100644 index 00000000..7842a213 --- /dev/null +++ b/substrate/serai/primitives/src/balance.rs @@ -0,0 +1,37 @@ +use core::ops::{Add, Sub, Mul}; + +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use crate::{Coin, Amount}; + +/// The type used for balances (a Coin and Balance). +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Balance { + pub coin: Coin, + pub amount: Amount, +} + +impl Add for Balance { + type Output = Balance; + fn add(self, other: Amount) -> Balance { + Balance { coin: self.coin, amount: self.amount + other } + } +} + +impl Sub for Balance { + type Output = Balance; + fn sub(self, other: Amount) -> Balance { + Balance { coin: self.coin, amount: self.amount - other } + } +} + +impl Mul for Balance { + type Output = Balance; + fn mul(self, other: Amount) -> Balance { + Balance { coin: self.coin, amount: self.amount * other } + } +} diff --git a/substrate/serai/primitives/src/block.rs b/substrate/serai/primitives/src/block.rs new file mode 100644 index 00000000..a31b8a3d --- /dev/null +++ b/substrate/serai/primitives/src/block.rs @@ -0,0 +1,46 @@ +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use sp_core::H256; + +/// The type used to identify block numbers. +// Doesn't re-export tendermint-machine's due to traits. +#[derive( + Clone, Copy, Default, PartialEq, Eq, Hash, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, +)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct BlockNumber(pub u32); +impl From for BlockNumber { + fn from(number: u32) -> BlockNumber { + BlockNumber(number) + } +} + +/// The type used to identify block hashes. +// This may not be universally compatible +// If a block exists with a hash which isn't 32-bytes, it can be hashed into a value with 32-bytes +// This would require the processor to maintain a mapping of 32-byte IDs to actual hashes, which +// would be fine +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct BlockHash(pub [u8; 32]); + +impl AsRef<[u8]> for BlockHash { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl From<[u8; 32]> for BlockHash { + fn from(hash: [u8; 32]) -> BlockHash { + BlockHash(hash) + } +} + +impl From for BlockHash { + fn from(hash: H256) -> BlockHash { + BlockHash(hash.into()) + } +} diff --git a/substrate/serai/primitives/src/lib.rs b/substrate/serai/primitives/src/lib.rs index 2d4dc14b..b77dd249 100644 --- a/substrate/serai/primitives/src/lib.rs +++ b/substrate/serai/primitives/src/lib.rs @@ -7,57 +7,75 @@ use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use sp_core::{ - H256, - sr25519::{Public, Signature as RistrettoSignature}, -}; +use sp_core::{ConstU32, bounded::BoundedVec}; mod amount; pub use amount::*; +mod block; +pub use block::*; + mod coins; pub use coins::*; -pub type PublicKey = Public; -pub type SeraiAddress = PublicKey; -pub type Signature = RistrettoSignature; +mod balance; +pub use balance::*; -/// The type used to identify block numbers. -// Doesn't re-export tendermint-machine's due to traits. -#[derive( - Clone, Copy, Default, PartialEq, Eq, Hash, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, -)] +mod account; +pub use account::*; + +// Monero, our current longest address candidate, has a longest address of featured with payment ID +// 1 (enum) + 1 (flags) + 64 (two keys) + 8 (payment ID) = 74 +pub const MAX_ADDRESS_LEN: u32 = 74; + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct BlockNumber(pub u32); -impl From for BlockNumber { - fn from(number: u32) -> BlockNumber { - BlockNumber(number) +pub struct ExternalAddress(BoundedVec>); +impl ExternalAddress { + #[cfg(feature = "std")] + pub fn new(address: Vec) -> Result { + Ok(ExternalAddress(address.try_into().map_err(|_| "address length exceeds {MAX_ADDRESS_LEN}")?)) + } + + pub fn address(&self) -> &[u8] { + self.0.as_ref() + } + + #[cfg(feature = "std")] + pub fn consume(self) -> Vec { + self.0.into_inner() } } -/// The type used to identify block hashes. -// This may not be universally compatible -// If a block exists with a hash which isn't 32-bytes, it can be hashed into a value with 32-bytes -// This would require the processor to maintain a mapping of 32-byte IDs to actual hashes, which -// would be fine -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct BlockHash(pub [u8; 32]); - -impl AsRef<[u8]> for BlockHash { +impl AsRef<[u8]> for ExternalAddress { fn as_ref(&self) -> &[u8] { self.0.as_ref() } } -impl From<[u8; 32]> for BlockHash { - fn from(hash: [u8; 32]) -> BlockHash { - BlockHash(hash) +// Should be enough for a Uniswap v3 call +pub const MAX_DATA_LEN: u32 = 512; +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Data(BoundedVec>); +impl Data { + #[cfg(feature = "std")] + pub fn new(data: Vec) -> Result { + Ok(Data(data.try_into().map_err(|_| "data length exceeds {MAX_DATA_LEN}")?)) + } + + pub fn data(&self) -> &[u8] { + self.0.as_ref() + } + + #[cfg(feature = "std")] + pub fn consume(self) -> Vec { + self.0.into_inner() } } -impl From for BlockHash { - fn from(hash: H256) -> BlockHash { - BlockHash(hash.into()) +impl AsRef<[u8]> for Data { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() } } diff --git a/substrate/tokens/pallet/Cargo.toml b/substrate/tokens/pallet/Cargo.toml new file mode 100644 index 00000000..4f7bb8b7 --- /dev/null +++ b/substrate/tokens/pallet/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "tokens-pallet" +version = "0.1.0" +description = "Mint and burn Serai tokens" +license = "AGPL-3.0-only" +authors = ["Luke Parker "] +edition = "2021" +publish = false + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2", default-features = false, features = ["derive"] } + +frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false } +frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false } + +pallet-assets = { git = "https://github.com/serai-dex/substrate", default-features = false } + +serai-primitives = { path = "../../serai/primitives", default-features = false } +tokens-primitives = { path = "../primitives", default-features = false } + +[features] +std = [ + "scale/std", + "scale-info/std", + + "frame-system/std", + "frame-support/std", + + "pallet-assets/std", + + "serai-primitives/std", +] +default = ["std"] diff --git a/substrate/tokens/pallet/LICENSE b/substrate/tokens/pallet/LICENSE new file mode 100644 index 00000000..f684d027 --- /dev/null +++ b/substrate/tokens/pallet/LICENSE @@ -0,0 +1,15 @@ +AGPL-3.0-only license + +Copyright (c) 2023 Luke Parker + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License Version 3 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . diff --git a/substrate/tokens/pallet/src/lib.rs b/substrate/tokens/pallet/src/lib.rs new file mode 100644 index 00000000..5d0a0845 --- /dev/null +++ b/substrate/tokens/pallet/src/lib.rs @@ -0,0 +1,83 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +pub use tokens_primitives as primitives; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::{pallet_prelude::*, RawOrigin}; + + use pallet_assets::{Config as AssetsConfig, Pallet as AssetsPallet}; + + use serai_primitives::{SubstrateAmount, Coin, Balance, PublicKey, SeraiAddress, AccountLookup}; + use primitives::{ADDRESS, OutInstruction}; + + use super::*; + + #[pallet::config] + pub trait Config: + frame_system::Config + + AssetsConfig + { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event { + // Mint is technically redundant as the assets pallet has the exact same event already + // Providing our own definition here just helps consolidate code + Mint { address: SeraiAddress, balance: Balance }, + Burn { address: SeraiAddress, balance: Balance, instruction: OutInstruction }, + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData); + + impl Pallet { + fn burn_internal( + address: SeraiAddress, + balance: Balance, + instruction: OutInstruction, + ) -> DispatchResult { + AssetsPallet::::burn( + RawOrigin::Signed(ADDRESS.into()).into(), + balance.coin, + address, + balance.amount.0, + )?; + Pallet::::deposit_event(Event::Burn { address, balance, instruction }); + Ok(()) + } + + pub fn mint(address: SeraiAddress, balance: Balance) { + // TODO: Prevent minting when it'd cause an amount exceeding the bond + AssetsPallet::::mint( + RawOrigin::Signed(ADDRESS.into()).into(), + balance.coin, + address, + balance.amount.0, + ) + .unwrap(); + Pallet::::deposit_event(Event::Mint { address, balance }); + } + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight((0, DispatchClass::Normal))] // TODO + pub fn burn( + origin: OriginFor, + balance: Balance, + instruction: OutInstruction, + ) -> DispatchResult { + Self::burn_internal(ensure_signed(origin)?.into(), balance, instruction) + } + } +} + +pub use pallet::*; diff --git a/substrate/tokens/primitives/Cargo.toml b/substrate/tokens/primitives/Cargo.toml new file mode 100644 index 00000000..155376d6 --- /dev/null +++ b/substrate/tokens/primitives/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "tokens-primitives" +version = "0.1.0" +description = "Serai tokens primitives" +license = "MIT" +authors = ["Luke Parker "] +edition = "2021" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2", default-features = false, features = ["derive"] } + +serde = { version = "1", features = ["derive"], optional = true } + +serai-primitives = { path = "../../serai/primitives", default-features = false } + +[dev-dependencies] +sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false } + +[features] +std = ["scale/std", "scale-info/std", "serde", "sp-runtime/std", "serai-primitives/std"] +default = ["std"] diff --git a/substrate/tokens/primitives/LICENSE b/substrate/tokens/primitives/LICENSE new file mode 100644 index 00000000..e6bff13c --- /dev/null +++ b/substrate/tokens/primitives/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Luke Parker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/substrate/tokens/primitives/src/lib.rs b/substrate/tokens/primitives/src/lib.rs new file mode 100644 index 00000000..94c62a5a --- /dev/null +++ b/substrate/tokens/primitives/src/lib.rs @@ -0,0 +1,33 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +use scale::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; + +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use serai_primitives::{SeraiAddress, ExternalAddress, Data, pallet_address}; + +pub const ADDRESS: SeraiAddress = pallet_address(b"Tokens"); + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct OutInstruction { + pub address: ExternalAddress, + pub data: Option, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum Destination { + Native(SeraiAddress), + External(OutInstruction), +} + +#[test] +fn address() { + use sp_runtime::traits::TrailingZeroInput; + assert_eq!(ADDRESS, SeraiAddress::decode(&mut TrailingZeroInput::new(b"Tokens")).unwrap()); +} From b253529413539f14ab262dc7f8fd837da1488abe Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 28 Jan 2023 01:59:42 -0500 Subject: [PATCH 40/74] cargo fmt --- substrate/serai/client/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/substrate/serai/client/src/lib.rs b/substrate/serai/client/src/lib.rs index 8cf6dec8..00af5352 100644 --- a/substrate/serai/client/src/lib.rs +++ b/substrate/serai/client/src/lib.rs @@ -7,9 +7,7 @@ use ::scale_value::Value; use subxt::{ utils::Encoded, - tx::{ - Signer, DynamicTxPayload, BaseExtrinsicParams, BaseExtrinsicParamsBuilder, TxClient, - }, + tx::{Signer, DynamicTxPayload, BaseExtrinsicParams, BaseExtrinsicParamsBuilder, TxClient}, Config as SubxtConfig, OnlineClient, }; From 9241bdc3b5304b74aa5f367f0708a79e10d64361 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 28 Jan 2023 02:35:32 -0500 Subject: [PATCH 41/74] Fix #183 --- .../tendermint/client/src/authority/mod.rs | 36 ++++++++++--------- substrate/tendermint/machine/src/block.rs | 12 +++---- substrate/tendermint/machine/src/ext.rs | 2 +- substrate/tendermint/machine/src/lib.rs | 20 ++++++++--- substrate/tendermint/machine/tests/ext.rs | 4 +-- 5 files changed, 41 insertions(+), 33 deletions(-) diff --git a/substrate/tendermint/client/src/authority/mod.rs b/substrate/tendermint/client/src/authority/mod.rs index 379784f0..4181b5ee 100644 --- a/substrate/tendermint/client/src/authority/mod.rs +++ b/substrate/tendermint/client/src/authority/mod.rs @@ -22,7 +22,7 @@ use sp_runtime::{ }; use sp_blockchain::HeaderBackend; -use sp_consensus::{Error, BlockOrigin, Proposer, Environment}; +use sp_consensus::{Error, BlockOrigin, BlockStatus, Proposer, Environment}; use sc_consensus::import_queue::IncomingBlock; use sc_service::ImportQueue; @@ -86,7 +86,6 @@ async fn get_proposal( env: &Arc>, import: &TendermintImport, header: &::Header, - stub: bool, ) -> T::Block { let proposer = env.lock().await.init(header).await.expect("Failed to create a proposer for the new block"); @@ -95,15 +94,11 @@ async fn get_proposal( .propose( import.inherent_data(*header.parent_hash()).await, Digest::default(), - if stub { - Duration::ZERO - } else { - // The first processing time is to build the block - // The second is for it to be downloaded (assumes a block won't take longer to download - // than it'll take to process) - // The third is for it to actually be processed - Duration::from_secs((T::BLOCK_PROCESSING_TIME_IN_SECONDS / 3).into()) - }, + // The first processing time is to build the block + // The second is for it to be downloaded (assumes a block won't take longer to download + // than it'll take to process) + // The third is for it to actually be processed + Duration::from_secs((T::BLOCK_PROCESSING_TIME_IN_SECONDS / 3).into()), Some(T::PROPOSED_BLOCK_SIZE_LIMIT), ) .await @@ -118,7 +113,7 @@ impl TendermintAuthority { } async fn get_proposal(&self, header: &::Header) -> T::Block { - get_proposal(&self.active.as_ref().unwrap().env, &self.import, header, false).await + get_proposal(&self.active.as_ref().unwrap().env, &self.import, header).await } /// Create and run a new Tendermint Authority, proposing and voting on blocks. @@ -263,9 +258,10 @@ impl TendermintAuthority { step.send(( BlockNumber(number), Commit::decode(&mut justifications.get(CONSENSUS_ID).unwrap().as_ref()).unwrap(), - // This will fail if syncing occurs radically faster than machine stepping takes - // TODO: Set true when initial syncing - get_proposal(&env, &import, ¬if.header, false).await + // Creating a proposal will fail if syncing occurs radically faster than machine + // stepping takes + // Don't create proposals when stepping accordingly + None )).await.unwrap(); } else { debug!( @@ -437,10 +433,16 @@ impl Network for TendermintAuthority { &mut self, block: T::Block, commit: Commit>, - ) -> T::Block { + ) -> Option { // Prevent import_block from being called while we run let _lock = self.import.sync_lock.lock().await; + // If we didn't import this block already, return + // If it's a legitimate block, we'll pick it up in the standard sync loop + if self.import.client.block_status(block.hash()).unwrap() != BlockStatus::InChainWithState { + return None; + } + // Check if we already imported this externally if self.import.client.justifications(block.hash()).unwrap().is_some() { debug!(target: "tendermint", "Machine produced a commit after we already synced it"); @@ -487,6 +489,6 @@ impl Network for TendermintAuthority { // Clear any blocks for the previous slot which we were willing to recheck *self.import.recheck.write().unwrap() = HashSet::new(); - self.get_proposal(block.header()).await + Some(self.get_proposal(block.header()).await) } } diff --git a/substrate/tendermint/machine/src/block.rs b/substrate/tendermint/machine/src/block.rs index 92923ae9..8136f888 100644 --- a/substrate/tendermint/machine/src/block.rs +++ b/substrate/tendermint/machine/src/block.rs @@ -14,7 +14,7 @@ use crate::{ pub(crate) struct BlockData { pub(crate) number: BlockNumber, pub(crate) validator_id: Option, - pub(crate) proposal: N::Block, + pub(crate) proposal: Option, pub(crate) log: MessageLog, pub(crate) slashes: HashSet, @@ -35,7 +35,7 @@ impl BlockData { weights: Arc, number: BlockNumber, validator_id: Option, - proposal: N::Block, + proposal: Option, ) -> BlockData { BlockData { number, @@ -106,12 +106,8 @@ impl BlockData { // 14-21 if Some(proposer) == self.validator_id { - let (round, block) = if let Some((round, block)) = &self.valid { - (Some(*round), block.clone()) - } else { - (None, self.proposal.clone()) - }; - Some(Data::Proposal(round, block)) + let (round, block) = self.valid.clone().unzip(); + block.or_else(|| self.proposal.clone()).map(|block| Data::Proposal(round, block)) } else { self.round_mut().set_timeout(Step::Propose); None diff --git a/substrate/tendermint/machine/src/ext.rs b/substrate/tendermint/machine/src/ext.rs index daa684c3..f78b3608 100644 --- a/substrate/tendermint/machine/src/ext.rs +++ b/substrate/tendermint/machine/src/ext.rs @@ -270,5 +270,5 @@ pub trait Network: Send + Sync { &mut self, block: Self::Block, commit: Commit, - ) -> Self::Block; + ) -> Option; } diff --git a/substrate/tendermint/machine/src/lib.rs b/substrate/tendermint/machine/src/lib.rs index 487f4cbf..4146dbb5 100644 --- a/substrate/tendermint/machine/src/lib.rs +++ b/substrate/tendermint/machine/src/lib.rs @@ -135,7 +135,8 @@ pub struct TendermintMachine { queue: VecDeque>, msg_recv: mpsc::UnboundedReceiver>, - step_recv: mpsc::UnboundedReceiver<(BlockNumber, Commit, N::Block)>, + #[allow(clippy::type_complexity)] + step_recv: mpsc::UnboundedReceiver<(BlockNumber, Commit, Option)>, block: BlockData, } @@ -143,7 +144,7 @@ pub struct TendermintMachine { pub type StepSender = mpsc::UnboundedSender<( BlockNumber, Commit<::SignatureScheme>, - ::Block, + Option<::Block>, )>; pub type MessageSender = mpsc::UnboundedSender>; @@ -186,7 +187,7 @@ impl TendermintMachine { } // 53-54 - async fn reset(&mut self, end_round: RoundNumber, proposal: N::Block) { + async fn reset(&mut self, end_round: RoundNumber, proposal: Option) { // Ensure we have the end time data for the last round self.block.populate_end_time(end_round); @@ -209,7 +210,11 @@ impl TendermintMachine { self.round(RoundNumber(0), Some(round_end)); } - async fn reset_by_commit(&mut self, commit: Commit, proposal: N::Block) { + async fn reset_by_commit( + &mut self, + commit: Commit, + proposal: Option, + ) { let mut round = self.block.round().number; // If this commit is for a round we don't have, jump up to it while self.block.end_time[&round].canonical() < commit.end_time { @@ -271,7 +276,12 @@ impl TendermintMachine { msg_recv, step_recv, - block: BlockData::new(weights, BlockNumber(last_block.0 + 1), validator_id, proposal), + block: BlockData::new( + weights, + BlockNumber(last_block.0 + 1), + validator_id, + Some(proposal), + ), }; // The end time of the last block is the start time for this one diff --git a/substrate/tendermint/machine/tests/ext.rs b/substrate/tendermint/machine/tests/ext.rs index a02afc12..818f2acd 100644 --- a/substrate/tendermint/machine/tests/ext.rs +++ b/substrate/tendermint/machine/tests/ext.rs @@ -140,11 +140,11 @@ impl Network for TestNetwork { &mut self, block: TestBlock, commit: Commit, - ) -> TestBlock { + ) -> Option { dbg!("Adding ", &block); assert!(block.valid.is_ok()); assert!(self.verify_commit(block.id(), &commit)); - TestBlock { id: (u32::from_le_bytes(block.id) + 1).to_le_bytes(), valid: Ok(()) } + Some(TestBlock { id: (u32::from_le_bytes(block.id) + 1).to_le_bytes(), valid: Ok(()) }) } } From a4fdff3e3b6d1091a51f018e4afec0347a0787d5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 28 Jan 2023 03:18:41 -0500 Subject: [PATCH 42/74] Make progress on #235 I'm still not exactly sure where the trap handler in Monero for this is... until then, this remains potentially fingerprintable. --- coins/monero/src/wallet/extra.rs | 14 +++++++++----- coins/monero/src/wallet/scan.rs | 24 ++++++++++++++++++++---- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/coins/monero/src/wallet/extra.rs b/coins/monero/src/wallet/extra.rs index f213fecf..867c5189 100644 --- a/coins/monero/src/wallet/extra.rs +++ b/coins/monero/src/wallet/extra.rs @@ -112,16 +112,20 @@ impl ExtraField { #[derive(Clone, PartialEq, Eq, Debug, Zeroize)] pub(crate) struct Extra(Vec); impl Extra { - pub(crate) fn keys(&self) -> Vec { - let mut keys = Vec::with_capacity(2); + pub(crate) fn keys(&self) -> Option<(EdwardsPoint, Option>)> { + let mut key = None; + let mut additional = None; for field in &self.0 { match field.clone() { - ExtraField::PublicKey(key) => keys.push(key), - ExtraField::PublicKeys(additional) => keys.extend(additional), + ExtraField::PublicKey(this_key) => key = key.or(Some(this_key)), + ExtraField::PublicKeys(these_additional) => { + additional = additional.or(Some(these_additional)) + } _ => (), } } - keys + // Don't return any keys if this was non-standard and didn't include the primary key + key.map(|key| (key, additional)) } pub(crate) fn payment_id(&self) -> Option { diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index a86cbf9b..5d1d4e2b 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -272,13 +272,18 @@ impl Scanner { /// Scan a transaction to discover the received outputs. pub fn scan_transaction(&mut self, tx: &Transaction) -> Timelocked { let extra = Extra::read::<&[u8]>(&mut tx.prefix.extra.as_ref()); - let keys; let extra = if let Ok(extra) = extra { - keys = extra.keys(); extra } else { return Timelocked(tx.prefix.timelock, vec![]); }; + + let (tx_key, additional) = if let Some((tx_key, additional)) = extra.keys() { + (tx_key, additional) + } else { + return Timelocked(tx.prefix.timelock, vec![]); + }; + let payment_id = extra.payment_id(); let mut res = vec![]; @@ -296,8 +301,19 @@ impl Scanner { } let output_key = output_key.unwrap(); - // TODO: Only use THE key or the matching additional key. Not any key - for key in &keys { + for key in [Some(Some(&tx_key)), additional.as_ref().map(|additional| additional.get(o))] { + let key = if let Some(Some(key)) = key { + key + } else if let Some(None) = key { + // This is non-standard. There were additional keys, yet not one for this output + // https://github.com/monero-project/monero/ + // blob/04a1e2875d6e35e27bb21497988a6c822d319c28/ + // src/cryptonote_basic/cryptonote_format_utils.cpp#L1062 + // TODO: Should this return? Where does Monero set the trap handler for this exception? + continue; + } else { + break; + }; let (view_tag, shared_key, payment_id_xor) = shared_key( if self.burning_bug.is_none() { Some(uniqueness(&tx.prefix.inputs)) } else { None }, &self.pair.view, From b0e0fc44cfa44c5a5a677faca9b00e1b76eceb1b Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 28 Jan 2023 03:32:21 -0500 Subject: [PATCH 43/74] Add secondary while loop to serai/client's test runner There's a failing CI run on a node which booted, yet didn't create a genesis yet. Apparently, the RPC is potentially accessible before the chain is in. This attempts to resolve that. --- substrate/serai/client/tests/runner.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/substrate/serai/client/tests/runner.rs b/substrate/serai/client/tests/runner.rs index 1e9e7444..777d5700 100644 --- a/substrate/serai/client/tests/runner.rs +++ b/substrate/serai/client/tests/runner.rs @@ -106,6 +106,9 @@ macro_rules! serai_test { while Serai::new(URL).await.is_err() { tokio::time::sleep(Duration::from_secs(1)).await; } + while Serai::new(URL).await.unwrap().get_latest_block_hash().await.is_err() { + tokio::time::sleep(Duration::from_secs(1)).await; + } command }; From 9e01588b1178511db33089541ab13f7fb55fec33 Mon Sep 17 00:00:00 2001 From: akildemir <34187742+akildemir@users.noreply.github.com> Date: Mon, 30 Jan 2023 12:25:46 +0300 Subject: [PATCH 44/74] add test send to wallet-rpc with arb data (#246) * add test send to wallet-rpc with arb data * convert literals to const --- coins/monero/src/wallet/mod.rs | 2 +- coins/monero/tests/add_data.rs | 17 ++++---- .../monero/tests/wallet-rpc-compatibility.rs | 39 ++++++++++++++++++- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index 511b5be3..c53acddf 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -11,7 +11,7 @@ use curve25519_dalek::{ use crate::{hash, hash_to_scalar, serialize::write_varint, transaction::Input}; -mod extra; +pub mod extra; pub(crate) use extra::{PaymentId, ExtraField, Extra}; /// Address encoding and decoding functionality. diff --git a/coins/monero/tests/add_data.rs b/coins/monero/tests/add_data.rs index a620a73d..918a51af 100644 --- a/coins/monero/tests/add_data.rs +++ b/coins/monero/tests/add_data.rs @@ -1,12 +1,15 @@ -use monero_serai::{wallet::TransactionError, transaction::Transaction}; +use monero_serai::{ + wallet::{TransactionError, extra::MAX_TX_EXTRA_NONCE_SIZE}, + transaction::Transaction, +}; mod runner; test!( - add_single_data_less_than_255, + add_single_data_less_than_max, ( |_, mut builder: Builder, addr| async move { - let arbitrary_data = vec![b'\0', 254]; + let arbitrary_data = vec![b'\0', (MAX_TX_EXTRA_NONCE_SIZE as u8) - 1]; // make sure we can add to tx let result = builder.add_data(arbitrary_data.clone()); @@ -24,10 +27,10 @@ test!( ); test!( - add_multiple_data_less_than_255, + add_multiple_data_less_than_max, ( |_, mut builder: Builder, addr| async move { - let data = vec![b'\0', 254]; + let data = vec![b'\0', (MAX_TX_EXTRA_NONCE_SIZE as u8) - 1]; // Add tx multiple times for _ in 0 .. 5 { @@ -47,11 +50,11 @@ test!( ); test!( - add_single_data_more_than_255, + add_single_data_more_than_max, ( |_, mut builder: Builder, addr| async move { // Make a data that is bigger than 255 bytes - let mut data = vec![b'a'; 256]; + let mut data = vec![b'a'; MAX_TX_EXTRA_NONCE_SIZE + 1]; // Make sure we get an error if we try to add it to the TX assert_eq!(builder.add_data(data.clone()), Err(TransactionError::TooMuchData)); diff --git a/coins/monero/tests/wallet-rpc-compatibility.rs b/coins/monero/tests/wallet-rpc-compatibility.rs index 230faec2..a0e06884 100644 --- a/coins/monero/tests/wallet-rpc-compatibility.rs +++ b/coins/monero/tests/wallet-rpc-compatibility.rs @@ -18,8 +18,11 @@ use monero_rpc::{ }; use monero_serai::{ - wallet::address::{Network, AddressSpec, SubaddressIndex}, - wallet::{Scanner, address::MoneroAddress}, + wallet::{ + address::{Network, AddressSpec, SubaddressIndex, MoneroAddress}, + extra::MAX_TX_EXTRA_NONCE_SIZE, + Scanner, + }, rpc::Rpc, transaction::Transaction, }; @@ -200,3 +203,35 @@ test!( }, ), ); + +test!( + test_send_to_wallet_rpc_with_arb_data, + ( + |_, mut builder: Builder, _| async move { + // initialize rpc + let (wallet_rpc, _, wallet_rpc_addr) = initialize_rpcs().await; + + // add destination + builder.add_payment( + MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr.to_string()).unwrap(), + 1000000, + ); + + // Make 2 data that is full 255 bytes + for _ in 0 .. 2 { + let data = vec![b'a'; MAX_TX_EXTRA_NONCE_SIZE]; + assert!(builder.add_data(data).is_ok()); + } + + (builder.build().unwrap(), (wallet_rpc,)) + }, + |_, tx: Transaction, _, data: (WalletClient,)| async move { + // confirm receipt + data.0.refresh(None).await.unwrap(); + let transfer = + data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); + assert_eq!(transfer.amount.as_pico(), 1000000); + assert_eq!(transfer.subaddr_index, Index { major: 0, minor: 0 }); + }, + ), +); From b6f9a1f8b6c63f68456e6049ab7b0294bcb99c79 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 30 Jan 2023 04:27:39 -0500 Subject: [PATCH 45/74] Rename file with dashes to having underscores --- .../{wallet-rpc-compatibility.rs => wallet2_compatibility.rs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename coins/monero/tests/{wallet-rpc-compatibility.rs => wallet2_compatibility.rs} (100%) diff --git a/coins/monero/tests/wallet-rpc-compatibility.rs b/coins/monero/tests/wallet2_compatibility.rs similarity index 100% rename from coins/monero/tests/wallet-rpc-compatibility.rs rename to coins/monero/tests/wallet2_compatibility.rs index a0e06884..4e6586aa 100644 --- a/coins/monero/tests/wallet-rpc-compatibility.rs +++ b/coins/monero/tests/wallet2_compatibility.rs @@ -18,13 +18,13 @@ use monero_rpc::{ }; use monero_serai::{ + transaction::Transaction, wallet::{ address::{Network, AddressSpec, SubaddressIndex, MoneroAddress}, extra::MAX_TX_EXTRA_NONCE_SIZE, Scanner, }, rpc::Rpc, - transaction::Transaction, }; mod runner; From affe4300e82467ae1c52a4d9ae364d689bb82b23 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 30 Jan 2023 07:30:02 -0500 Subject: [PATCH 46/74] Replace clippy --tests with --all-targets --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d7e7ff80..36819dd4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,7 +26,7 @@ jobs: rust-components: clippy - name: Run Clippy - run: cargo clippy --all-features --tests -- -D warnings -A dead_code + run: cargo clippy --all-features --all-targets -- -D warnings -A dead_code deny: runs-on: ubuntu-latest From fba5b7fed4aafbdf479f500e9053c003fc864afe Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 31 Jan 2023 07:07:27 -0500 Subject: [PATCH 47/74] Attempt workaround for #247 --- substrate/serai/client/tests/runner.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substrate/serai/client/tests/runner.rs b/substrate/serai/client/tests/runner.rs index 777d5700..36d7b98f 100644 --- a/substrate/serai/client/tests/runner.rs +++ b/substrate/serai/client/tests/runner.rs @@ -109,6 +109,8 @@ macro_rules! serai_test { while Serai::new(URL).await.unwrap().get_latest_block_hash().await.is_err() { tokio::time::sleep(Duration::from_secs(1)).await; } + // TODO: https://github.com/serai-dex/serai/247 + tokio::time::sleep(Duration::from_secs(5)).await command }; From c6bd00e7782ecbf63b6a3c73f4e12ec91b6d82f1 Mon Sep 17 00:00:00 2001 From: VRx <106933224+vrx00@users.noreply.github.com> Date: Tue, 31 Jan 2023 13:48:14 +0100 Subject: [PATCH 48/74] Bitcoin processor (#232) * serai Dockerfile & Makefile fixed * added new bitcoin mod & bitcoinhram * couple changes * added odd&even check for bitcoin signing * sign message updated * print_keys commented out * fixed signing process * Added new bitcoin library & added most of bitcoin processor logic * added new crate and refactored the bitcoin coin library * added signing test function * moved signature.rs * publish set to false * tests moved back to the root * added new functions to rpc * added utxo test * added new rpc methods and refactored bitcoin processor * added spendable output & fixed errors & added new logic for sighash & opened port 18443 for bitcoin docker * changed tweak keys * added tweak_keys & publish transaction and refactored bitcoin processor * added new structs and fixed problems for testing purposes * reverted dockerfile back its original * reverted block generation of bitcoin to 5 seconds * deleted unnecessary test function * added new sighash & added new dbg messages & fixed couple errors * fixed couple issue & removed unused functions * fix for signing process * crypto file for bitcoin refactored * disabled test_send & removed some of the debug logs * signing implemented & transaction weight calculation added & change address logic added * refactored tweak_keys * refactored mine_block & fixed change_address logic * implemented new traits to bitcoin processor& refactored bitcoin processor * added new line to tests file * added new line to bitcoin's wallet.rs * deleted Cargo.toml from coins folder * edited bitcoin's Cargo.toml and added LICENSE * added new line to bitcoin's Cargo.toml * added spaces * added spaces * deleted unnecessary object * added spaces * deleted patch numbers * updated sha256 parameter for message * updated tag as const * deleted unnecessary brackets and imports * updated rpc.rs to 2 space indent * deleted unnecessary brackers * deleted unnecessary brackets * changed it to explicit * updated to explicit * deleted unnecessary parsing * added ? for easy return * updated imports * updated height to number * deleted unnecessary brackets * updated clsag to sig & to_vec to as_ref * updated _sig to schnorr_signature * deleted unnecessary variable * updated Cargo.toml of processor and bitcoin * updated imports of bitcoin processor * updated MBlock to BBlock * updated MSignable to BSignable * updated imports * deleted mask from Fee * updated get_block function return * updated comparison logic for scripts * updated assert to debug_assert * updated height to number * updated txid logic * updated tweak_keys definition * updated imports * deleted new line * delete HashMap from monero * deleted old test code parts * updated test amount to a round number * changed the test code part back to its original * updated imports of rpc.rs * deleted unnecessary return assignments * deleted get_fee_per_byte * deleted create_raw_transaction * deleted fund_raw_transaction * deleted sign transaction rpc * delete verify_message rpc * deleted get_balance * deleted decode_raw_transaction rpc * deleted list_transactions rpc * changed test_send to p2wpkh * updated imports of test_send * fixed imports of test_send * updated bitcoin's mine_block function * updated bitcoin's test_send * updated bitcoin's hram and test_signing * deleted 2 rpc function (is_confirmed & get_transaction_block_number) * deleted get_raw_transaction_hex * deleted get_raw_transaction_info * deleted new_address * deleted test_mempool_accept * updated remove(0) to remove(index) * deleted ger_raw_transaction * deleted RawTx trait and converted type to Transaction * reverted raw_hex feature back * added NotEnoughFunds to CoinError * changed Sighash to all * removed lifetime of RpcParams * changed pub to pub(crate) & changed sig_hash line * changed taproot_key_spend_signature_hash to internal * added Clone to RpcError & deleted get_utxo_for * changed to_hex to as_bytes for weight calculation * updated SpendableOutput * deleted unnecessary parentheses * updated serialize of Output s id field * deleted unused crate & added lazy_static * updated RPC init function * added lazy_static for TAG_HASH & updated imported crates * changed get_block_index to get_block_number * deleted get_block_info * updated get_height to get_latest_block_number * removed GetBlockWithDetailResult and get_block_with_transactions * deleted unnecessary imports from rpc_helper * removed lock and unlock_unspent * deleted get_transactions and get_transaction and renamed get_raw_transaction to get_transaction * updated opt_into_json * changed payment_address and amount to output_script and amount for transcript * refactored error logic for rpc & deleted anyhow crate * added a dedicated file for json helper functions * refactored imports and deleted unused code * added clippy::non_snake_case * removed unused Error items * added new line to Cargo * rekmoved Block and used bitcoin::Block direcetly * removed added println and futures.len check * removed HashMap from coin mod.rs * updated Testnet to Regtest * removed unnecessary variable * updated as_str to & * removed RawTx trait * added newline * changed test transaction to p2pkh * updated test_send * updated test_send * updated test_send * reformatted bitcoin processor * moved sighash logic into signmachine * removed generate_to_address * added test_address function to bitcoin processor * updated RpcResponse to enum and added Clone trait * removed old RpcResponse * updated shared_key to internal_key * updated fee part * updated test_send block logic * added a test function for getting spendables * updated tweaking keys logic * updated calculate_weight logic * added todo for BitcoinSchnorr Algorithm * updated calculate_weight * updated calculate_weight * updated calculate_weight * added a TODO for bitcoin's signing process * removed unused code * Finish merging develop * cargo fmt * cargo machete * Handle most clippy lints on bitcoin Doesn't handle the unused transcript due to pending cryptographic considerations. * Rearrange imports and clippy tests * Misc processor lint * Update deny.toml * Remove unnecessary RPC code * updated test_send * added bitcoin ci & updated test-dependencies yml * fixed bitcoin ci * updated bitcoin ci yml * Remove mining from the bitcoin/monero docker files The tests should control block production in order to test various circumstances. The automatic mining disrupts assumptions made in testing. Since we're now using the Bitcoin docker container for testing... * Multiple fixes to the Bitcoin processor Doesn't unwrap on RPC errors. Returns the expected connection error. Fee calculation has a random - 1. This has been removed. Supports the change address being an Option, as it is. This should not have been blindly unwrapped. * Remove unnecessary RPC code * Further RPC simplifications * Simplify Bitcoin action It should not be mining. * cargo fmt * Finish RPC simplifications * Run bitcoind as a daemon * Remove the requirement on txindex Saves tens of GB. Also has attempt_send no longer return a list of outputs. That's incompatible with this and only relevant to old scheduling designs. * Remove number from Bitcoin SignableTransaction Monero requires the current block number for decoy selection. Bitcoin doesn't have a use. * Ban coinbase transactions These are burdened by maturity, so it's critically flawed to support them. This causes the test_send function to fail as its working was premised on a coinbase output. While it does make an actual output, it had insufficient funds for the test's expectations due to regtest halving every 150 blocks. In order to workaround this, the test will invalidate any existing chain, offering a fresh start. Also removes test_get_spendables and simplifies test_send. * Various simplifications Modifies SpendableOutput further to not require RPC calls at time of sign. Removes the need to have get_transaction in the RPC. * Clean prepare_send * Update the Bitcoin TransactionMachine to output a Transaction * Bitcoin TransactionMachine simplifications * Update XOnly key handling * Use a single sighash cache * Move tweak_keys * Remove unnecessary PSBT sets * Restore removed newlines * Other newlines * Replace calculate_weight's custom math with a dummy TX serialize * Move BTC TX construction code from processor to bitcoin * Rename transactions.rs to wallet.rs * Remove unused crate * Note TODO * Clean bitcoin signature test * Make unit test out of BTC FROST signing test * Final lint * Remove usage of PartiallySignedTransaction --------- Co-authored-by: Luke Parker --- .github/actions/bitcoin/action.yml | 41 +++ .github/actions/test-dependencies/action.yml | 10 + Cargo.lock | 55 +++- coins/bitcoin/Cargo.toml | 29 ++ coins/bitcoin/LICENSE | 15 + coins/bitcoin/src/crypto.rs | 58 ++++ coins/bitcoin/src/lib.rs | 6 + coins/bitcoin/src/rpc.rs | 80 +++++ coins/bitcoin/src/tests/mod.rs | 47 +++ coins/bitcoin/src/wallet.rs | 295 +++++++++++++++++++ deny.toml | 1 + deploy/coins/bitcoin/Dockerfile | 5 +- deploy/coins/bitcoin/scripts/entry-dev.sh | 27 +- deploy/coins/monero/Dockerfile | 4 +- deploy/coins/monero/scripts/entry-dev.sh | 7 - deploy/docker-compose.yml | 2 + processor/Cargo.toml | 12 +- processor/src/coin/bitcoin.rs | 283 ++++++++++++++++++ processor/src/coin/mod.rs | 12 +- processor/src/coin/monero.rs | 10 +- processor/src/tests/bitcoin.rs | 12 + processor/src/tests/mod.rs | 1 + processor/src/tests/send.rs | 4 +- processor/src/wallet.rs | 13 +- 24 files changed, 970 insertions(+), 59 deletions(-) create mode 100644 .github/actions/bitcoin/action.yml create mode 100644 coins/bitcoin/Cargo.toml create mode 100644 coins/bitcoin/LICENSE create mode 100644 coins/bitcoin/src/crypto.rs create mode 100644 coins/bitcoin/src/lib.rs create mode 100644 coins/bitcoin/src/rpc.rs create mode 100644 coins/bitcoin/src/tests/mod.rs create mode 100644 coins/bitcoin/src/wallet.rs create mode 100644 processor/src/coin/bitcoin.rs create mode 100644 processor/src/tests/bitcoin.rs diff --git a/.github/actions/bitcoin/action.yml b/.github/actions/bitcoin/action.yml new file mode 100644 index 00000000..4aad4791 --- /dev/null +++ b/.github/actions/bitcoin/action.yml @@ -0,0 +1,41 @@ +name: bitcoin-regtest +description: Spawns a regtest Bitcoin daemon + +inputs: + version: + description: "Version to download and run" + required: false + default: 24.0.1 + +runs: + using: "composite" + steps: + - name: Bitcoin Daemon Cache + id: cache-bitcoind + uses: actions/cache@v3 + with: + path: bitcoind + key: bitcoind-${{ runner.os }}-${{ runner.arch }}-${{ inputs.version }} + + - name: Download the Bitcoin Daemon + if: steps.cache-bitcoind.outputs.cache-hit != 'true' + shell: bash + run: | + RUNNER_OS=linux + RUNNER_ARCH=x86_64 + + BASE=bitcoin-${{ inputs.version }} + FILE=$BASE-$RUNNER_ARCH-$RUNNER_OS-gnu.tar.gz + wget https://bitcoincore.org/bin/bitcoin-core-${{ inputs.version }}/$FILE + tar xzvf $FILE + + cd bitcoin-${{ inputs.version }} + sudo mv bin/* /bin && sudo mv lib/* /lib + + - name: Bitcoin Regtest Daemon + shell: bash + run: | + RPC_USER=serai + RPC_PASS=seraidex + + bitcoind -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS -daemon diff --git a/.github/actions/test-dependencies/action.yml b/.github/actions/test-dependencies/action.yml index 6340e946..2fb500d7 100644 --- a/.github/actions/test-dependencies/action.yml +++ b/.github/actions/test-dependencies/action.yml @@ -12,6 +12,11 @@ inputs: required: false default: v0.18.0.0 + bitcoin-version: + description: "Bitcoin version to download and run as a regtest node" + required: false + default: 24.0.1 + serai: description: "Run a Serai development node in the background" required: false @@ -35,6 +40,11 @@ runs: with: version: ${{ inputs.monero-version }} + - name: Run a Bitcoin Regtest Node + uses: ./.github/actions/bitcoin + with: + version: ${{ inputs.bitcoin-version }} + - name: Run a Monero Wallet-RPC uses: ./.github/actions/monero-wallet-rpc diff --git a/Cargo.lock b/Cargo.lock index ba40c8c7..aa96be02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,6 +503,12 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1" +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "beef" version = "0.5.2" @@ -555,6 +561,46 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bitcoin" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" +dependencies = [ + "bech32 0.9.1", + "bitcoin_hashes", + "secp256k1", + "serde", +] + +[[package]] +name = "bitcoin-serai" +version = "0.1.0" +dependencies = [ + "bitcoin", + "flexible-transcript", + "hex", + "k256", + "lazy_static", + "modular-frost", + "rand_core 0.6.4", + "reqwest", + "secp256k1", + "serde", + "serde_json", + "sha2 0.10.6", + "thiserror", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -1112,7 +1158,7 @@ checksum = "c94090a6663f224feae66ab01e41a2555a8296ee07b5f20dab8888bdefc9f617" dependencies = [ "base58check", "base64 0.12.3", - "bech32", + "bech32 0.7.3", "blake2", "digest 0.10.6", "generic-array 0.14.6", @@ -7882,7 +7928,10 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ + "bitcoin_hashes", + "rand 0.8.5", "secp256k1-sys", + "serde", ] [[package]] @@ -8027,15 +8076,19 @@ name = "serai-processor" version = "0.1.0" dependencies = [ "async-trait", + "bitcoin", + "bitcoin-serai", "curve25519-dalek 3.2.0", "dalek-ff-group", "flexible-transcript", "futures", "group", "hex", + "k256", "modular-frost", "monero-serai", "rand_core 0.6.4", + "secp256k1", "serde", "serde_json", "thiserror", diff --git a/coins/bitcoin/Cargo.toml b/coins/bitcoin/Cargo.toml new file mode 100644 index 00000000..de987bbc --- /dev/null +++ b/coins/bitcoin/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "bitcoin-serai" +version = "0.1.0" +description = "A Bitcoin library for FROST-signing transactions" +license = "AGPL-3.0-only" +repository = "https://github.com/serai-dex/serai/tree/develop/coins/bitcoin" +authors = ["Luke Parker ", "Vrx "] +edition = "2021" +publish = false + +[dependencies] +lazy_static = "1" +thiserror = "1" + +rand_core = "0.6" + +sha2 = "0.10" + +secp256k1 = { version = "0.24", features = ["global-context"] } +bitcoin = { version = "0.29", features = ["serde"] } + +k256 = { version = "0.11", features = ["arithmetic"] } +transcript = { package = "flexible-transcript", path = "../../crypto/transcript", version = "0.2", features = ["recommended"] } +frost = { version = "0.5", package = "modular-frost", path = "../../crypto/frost", features = ["secp256k1", "tests"] } + +hex = "0.4" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +reqwest = { version = "0.11", features = ["json"] } diff --git a/coins/bitcoin/LICENSE b/coins/bitcoin/LICENSE new file mode 100644 index 00000000..c425427c --- /dev/null +++ b/coins/bitcoin/LICENSE @@ -0,0 +1,15 @@ +AGPL-3.0-only license + +Copyright (c) 2022-2023 Luke Parker + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License Version 3 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . diff --git a/coins/bitcoin/src/crypto.rs b/coins/bitcoin/src/crypto.rs new file mode 100644 index 00000000..bea62831 --- /dev/null +++ b/coins/bitcoin/src/crypto.rs @@ -0,0 +1,58 @@ +use lazy_static::lazy_static; + +use sha2::{Digest, Sha256}; + +use k256::{ + elliptic_curve::{ + ops::Reduce, + sec1::{Tag, ToEncodedPoint}, + }, + U256, Scalar, ProjectivePoint, +}; + +use bitcoin::XOnlyPublicKey; + +use frost::{algorithm::Hram, curve::Secp256k1}; + +/// Get the x coordinate of a non-infinity, even point. +pub fn x(key: &ProjectivePoint) -> [u8; 32] { + let encoded = key.to_encoded_point(true); + assert_eq!(encoded.tag(), Tag::CompressedEvenY); + (*encoded.x().expect("point at infinity")).into() +} + +pub fn x_only(key: &ProjectivePoint) -> XOnlyPublicKey { + XOnlyPublicKey::from_slice(&x(key)).unwrap() +} + +pub fn make_even(mut key: ProjectivePoint) -> (ProjectivePoint, u64) { + let mut c = 0; + while key.to_encoded_point(true).tag() == Tag::CompressedOddY { + key += ProjectivePoint::GENERATOR; + c += 1; + } + (key, c) +} + +#[derive(Clone)] +pub struct BitcoinHram {} + +lazy_static! { + static ref TAG_HASH: [u8; 32] = Sha256::digest(b"BIP0340/challenge").into(); +} + +#[allow(non_snake_case)] +impl Hram for BitcoinHram { + fn hram(R: &ProjectivePoint, A: &ProjectivePoint, m: &[u8]) -> Scalar { + let (R, _) = make_even(*R); + + let mut data = Sha256::new(); + data.update(*TAG_HASH); + data.update(*TAG_HASH); + data.update(x(&R)); + data.update(x(A)); + data.update(m); + + Scalar::from_uint_reduced(U256::from_be_slice(&data.finalize())) + } +} diff --git a/coins/bitcoin/src/lib.rs b/coins/bitcoin/src/lib.rs new file mode 100644 index 00000000..22c1c26c --- /dev/null +++ b/coins/bitcoin/src/lib.rs @@ -0,0 +1,6 @@ +pub mod crypto; +pub mod wallet; +pub mod rpc; + +#[cfg(test)] +mod tests; diff --git a/coins/bitcoin/src/rpc.rs b/coins/bitcoin/src/rpc.rs new file mode 100644 index 00000000..1ae84916 --- /dev/null +++ b/coins/bitcoin/src/rpc.rs @@ -0,0 +1,80 @@ +use core::fmt::Debug; + +use thiserror::Error; + +use serde::{Deserialize, de::DeserializeOwned}; +use serde_json::json; + +use bitcoin::{ + hashes::hex::{FromHex, ToHex}, + consensus::encode, + Txid, Transaction, BlockHash, Block, +}; + +#[derive(Clone, Debug, Deserialize)] +#[serde(untagged)] +pub(crate) enum RpcResponse { + Ok { result: T }, + Err { error: String }, +} + +#[derive(Clone, Debug)] +pub struct Rpc(String); + +#[derive(Clone, PartialEq, Eq, Debug, Error)] +pub enum RpcError { + #[error("couldn't connect to node")] + ConnectionError, + #[error("request had an error: {0}")] + RequestError(String), + #[error("node sent an invalid response")] + InvalidResponse, +} + +impl Rpc { + pub fn new(url: String) -> Rpc { + Rpc(url) + } + + pub async fn rpc_call( + &self, + method: &str, + params: serde_json::Value, + ) -> Result { + let client = reqwest::Client::new(); + let res = client + .post(&self.0) + .json(&json!({ "jsonrpc": "2.0", "method": method, "params": params })) + .send() + .await + .map_err(|_| RpcError::ConnectionError)? + .text() + .await + .map_err(|_| RpcError::ConnectionError)?; + + let res: RpcResponse = + serde_json::from_str(&res).map_err(|_| RpcError::InvalidResponse)?; + match res { + RpcResponse::Ok { result } => Ok(result), + RpcResponse::Err { error } => Err(RpcError::RequestError(error)), + } + } + + pub async fn get_latest_block_number(&self) -> Result { + self.rpc_call("getblockcount", json!([])).await + } + + pub async fn get_block_hash(&self, number: usize) -> Result { + self.rpc_call("getblockhash", json!([number])).await + } + + pub async fn get_block(&self, block_hash: &BlockHash) -> Result { + let hex = self.rpc_call::("getblock", json!([block_hash.to_hex(), 0])).await?; + let bytes: Vec = FromHex::from_hex(&hex).map_err(|_| RpcError::InvalidResponse)?; + encode::deserialize(&bytes).map_err(|_| RpcError::InvalidResponse) + } + + pub async fn send_raw_transaction(&self, tx: &Transaction) -> Result { + self.rpc_call("sendrawtransaction", json!([encode::serialize_hex(tx)])).await + } +} diff --git a/coins/bitcoin/src/tests/mod.rs b/coins/bitcoin/src/tests/mod.rs new file mode 100644 index 00000000..20be306a --- /dev/null +++ b/coins/bitcoin/src/tests/mod.rs @@ -0,0 +1,47 @@ +use rand_core::OsRng; + +use sha2::{Digest, Sha256}; + +use secp256k1::{SECP256K1, Message, schnorr::Signature}; +use bitcoin::hashes::{Hash as HashTrait, sha256::Hash}; + +use k256::Scalar; +use frost::{ + curve::Secp256k1, + algorithm::Schnorr, + tests::{algorithm_machines, key_gen, sign}, +}; + +use crate::crypto::{BitcoinHram, x_only, make_even}; + +#[test] +fn test_signing() { + let mut keys = key_gen::<_, Secp256k1>(&mut OsRng); + const MESSAGE: &[u8] = b"Hello, World!"; + + for (_, keys) in keys.iter_mut() { + let (_, offset) = make_even(keys.group_key()); + *keys = keys.offset(Scalar::from(offset)); + } + + let algo = Schnorr::::new(); + let mut sig = sign( + &mut OsRng, + algo, + keys.clone(), + algorithm_machines(&mut OsRng, Schnorr::::new(), &keys), + &Sha256::digest(MESSAGE), + ); + + let offset; + (sig.R, offset) = make_even(sig.R); + sig.s += Scalar::from(offset); + + SECP256K1 + .verify_schnorr( + &Signature::from_slice(&sig.serialize()[1 .. 65]).unwrap(), + &Message::from(Hash::hash(MESSAGE)), + &x_only(&keys[&1].group_key()), + ) + .unwrap() +} diff --git a/coins/bitcoin/src/wallet.rs b/coins/bitcoin/src/wallet.rs new file mode 100644 index 00000000..26d602fb --- /dev/null +++ b/coins/bitcoin/src/wallet.rs @@ -0,0 +1,295 @@ +use std::{ + io::{self, Read}, + collections::HashMap, +}; + +use rand_core::RngCore; + +use transcript::{Transcript, RecommendedTranscript}; + +use k256::{elliptic_curve::sec1::ToEncodedPoint, Scalar}; +use frost::{curve::Secp256k1, ThresholdKeys, FrostError, algorithm::Schnorr, sign::*}; + +use bitcoin::{ + hashes::Hash, + consensus::encode::{Encodable, Decodable, serialize}, + util::sighash::{SchnorrSighashType, SighashCache, Prevouts}, + OutPoint, Script, Sequence, Witness, TxIn, TxOut, PackedLockTime, Transaction, Address, +}; + +use crate::crypto::{BitcoinHram, make_even}; + +#[derive(Clone, Debug)] +pub struct SpendableOutput { + pub output: TxOut, + pub outpoint: OutPoint, +} + +impl SpendableOutput { + pub fn id(&self) -> [u8; 36] { + serialize(&self.outpoint).try_into().unwrap() + } + + pub fn read(r: &mut R) -> io::Result { + Ok(SpendableOutput { + output: TxOut::consensus_decode(r) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid TxOut"))?, + outpoint: OutPoint::consensus_decode(r) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid OutPoint"))?, + }) + } + + pub fn serialize(&self) -> Vec { + let mut res = serialize(&self.output); + self.outpoint.consensus_encode(&mut res).unwrap(); + res + } +} + +#[derive(Clone, Debug)] +pub struct SignableTransaction(Transaction, Vec); + +impl SignableTransaction { + fn calculate_weight(inputs: usize, payments: &[(Address, u64)], change: Option<&Address>) -> u64 { + let mut tx = Transaction { + version: 2, + lock_time: PackedLockTime::ZERO, + input: vec![ + TxIn { + previous_output: OutPoint::default(), + script_sig: Script::new(), + sequence: Sequence::MAX, + witness: Witness::from_vec(vec![vec![0; 64]]) + }; + inputs + ], + output: payments + .iter() + .map(|payment| TxOut { value: payment.1, script_pubkey: payment.0.script_pubkey() }) + .collect(), + }; + if let Some(change) = change { + tx.output.push(TxOut { value: 0, script_pubkey: change.script_pubkey() }); + } + u64::try_from(tx.weight()).unwrap() + } + + pub fn new( + mut inputs: Vec, + payments: &[(Address, u64)], + change: Option

, + fee: u64, + ) -> Option { + let input_sat = inputs.iter().map(|input| input.output.value).sum::(); + let tx_ins = inputs + .iter() + .map(|input| TxIn { + previous_output: input.outpoint, + script_sig: Script::new(), + sequence: Sequence::MAX, + witness: Witness::new(), + }) + .collect::>(); + + let payment_sat = payments.iter().map(|payment| payment.1).sum::(); + let mut tx_outs = payments + .iter() + .map(|payment| TxOut { value: payment.1, script_pubkey: payment.0.script_pubkey() }) + .collect::>(); + + let actual_fee = fee * Self::calculate_weight(tx_ins.len(), payments, None); + if payment_sat > (input_sat - actual_fee) { + return None; + } + + // If there's a change address, check if there's a meaningful change + if let Some(change) = change.as_ref() { + let fee_with_change = fee * Self::calculate_weight(tx_ins.len(), payments, Some(change)); + // If there's a non-zero change, add it + if let Some(value) = input_sat.checked_sub(payment_sat + fee_with_change) { + tx_outs.push(TxOut { value, script_pubkey: change.script_pubkey() }); + } + } + + // TODO: Drop outputs which BTC will consider spam (outputs worth less than the cost to spend + // them) + + Some(SignableTransaction( + Transaction { version: 2, lock_time: PackedLockTime::ZERO, input: tx_ins, output: tx_outs }, + inputs.drain(..).map(|input| input.output).collect(), + )) + } + + pub async fn multisig( + self, + keys: ThresholdKeys, + mut transcript: RecommendedTranscript, + ) -> Result { + transcript.domain_separate(b"bitcoin_transaction"); + transcript.append_message(b"root_key", keys.group_key().to_encoded_point(true).as_bytes()); + + // Transcript the inputs and outputs + let tx = &self.0; + for input in &tx.input { + transcript.append_message(b"input_hash", input.previous_output.txid.as_hash().into_inner()); + transcript.append_message(b"input_output_index", input.previous_output.vout.to_le_bytes()); + } + for payment in &tx.output { + transcript.append_message(b"output_script", payment.script_pubkey.as_bytes()); + transcript.append_message(b"output_amount", payment.value.to_le_bytes()); + } + + let mut sigs = vec![]; + for _ in 0 .. tx.input.len() { + // TODO: Use the above transcript here + sigs.push( + AlgorithmMachine::new(Schnorr::::new(), keys.clone()).unwrap(), + ); + } + + Ok(TransactionMachine { tx: self, transcript, sigs }) + } +} + +pub struct TransactionMachine { + tx: SignableTransaction, + transcript: RecommendedTranscript, + sigs: Vec>>, +} + +impl PreprocessMachine for TransactionMachine { + type Preprocess = Vec>; + type Signature = Transaction; + type SignMachine = TransactionSignMachine; + + fn preprocess( + mut self, + rng: &mut R, + ) -> (Self::SignMachine, Self::Preprocess) { + let mut preprocesses = Vec::with_capacity(self.sigs.len()); + let sigs = self + .sigs + .drain(..) + .map(|sig| { + let (sig, preprocess) = sig.preprocess(rng); + preprocesses.push(preprocess); + sig + }) + .collect(); + + (TransactionSignMachine { tx: self.tx, transcript: self.transcript, sigs }, preprocesses) + } +} + +pub struct TransactionSignMachine { + tx: SignableTransaction, + transcript: RecommendedTranscript, + sigs: Vec>>, +} + +impl SignMachine for TransactionSignMachine { + type Params = (); + type Keys = ThresholdKeys; + type Preprocess = Vec>; + type SignatureShare = Vec>; + type SignatureMachine = TransactionSignatureMachine; + + fn cache(self) -> CachedPreprocess { + unimplemented!( + "Bitcoin transactions don't support caching their preprocesses due to {}", + "being already bound to a specific transaction" + ); + } + + fn from_cache( + _: (), + _: ThresholdKeys, + _: CachedPreprocess, + ) -> Result { + unimplemented!( + "Bitcoin transactions don't support caching their preprocesses due to {}", + "being already bound to a specific transaction" + ); + } + + fn read_preprocess(&self, reader: &mut R) -> io::Result { + self.sigs.iter().map(|sig| sig.read_preprocess(reader)).collect() + } + + fn sign( + mut self, + commitments: HashMap, + msg: &[u8], + ) -> Result<(TransactionSignatureMachine, Self::SignatureShare), FrostError> { + if !msg.is_empty() { + Err(FrostError::InternalError( + "message was passed to the TransactionMachine when it generates its own", + ))?; + } + + let commitments = (0 .. self.sigs.len()) + .map(|c| { + commitments + .iter() + .map(|(l, commitments)| (*l, commitments[c].clone())) + .collect::>() + }) + .collect::>(); + + let mut cache = SighashCache::new(&self.tx.0); + let prevouts = Prevouts::All(&self.tx.1); + + let mut shares = Vec::with_capacity(self.sigs.len()); + let sigs = self + .sigs + .drain(..) + .enumerate() + .map(|(i, sig)| { + let tx_sighash = cache + .taproot_key_spend_signature_hash(i, &prevouts, SchnorrSighashType::Default) + .unwrap(); + + let (sig, share) = sig.sign(commitments[i].clone(), &tx_sighash)?; + shares.push(share); + Ok(sig) + }) + .collect::>()?; + + Ok((TransactionSignatureMachine { tx: self.tx.0, sigs }, shares)) + } +} + +pub struct TransactionSignatureMachine { + tx: Transaction, + sigs: Vec>>, +} + +impl SignatureMachine for TransactionSignatureMachine { + type SignatureShare = Vec>; + + fn read_share(&self, reader: &mut R) -> io::Result { + self.sigs.iter().map(|sig| sig.read_share(reader)).collect() + } + + fn complete( + mut self, + mut shares: HashMap, + ) -> Result { + for (input, schnorr) in self.tx.input.iter_mut().zip(self.sigs.drain(..)) { + let mut sig = schnorr.complete( + shares.iter_mut().map(|(l, shares)| (*l, shares.remove(0))).collect::>(), + )?; + + // TODO: Implement BitcoinSchnorr Algorithm to handle this + let offset; + (sig.R, offset) = make_even(sig.R); + sig.s += Scalar::from(offset); + + let mut witness: Witness = Witness::new(); + witness.push(&sig.serialize()[1 .. 65]); + input.witness = witness; + } + + Ok(self.tx) + } +} diff --git a/deny.toml b/deny.toml index a289c911..5826699d 100644 --- a/deny.toml +++ b/deny.toml @@ -44,6 +44,7 @@ allow-osi-fsf-free = "neither" default = "deny" exceptions = [ + { allow = ["AGPL-3.0"], name = "bitcoin-serai" }, { allow = ["AGPL-3.0"], name = "ethereum-serai" }, { allow = ["AGPL-3.0"], name = "serai-processor" }, diff --git a/deploy/coins/bitcoin/Dockerfile b/deploy/coins/bitcoin/Dockerfile index 75016e9c..bb86757c 100644 --- a/deploy/coins/bitcoin/Dockerfile +++ b/deploy/coins/bitcoin/Dockerfile @@ -8,7 +8,7 @@ ENV BITCOIN_DATA=/home/bitcoin/.bitcoin WORKDIR /home/bitcoin RUN apk update \ - && apk --no-cache add ca-certificates gnupg bash su-exec + && apk --no-cache add ca-certificates gnupg bash su-exec # Get Binary # TODO: When bitcoin.org publishes 23.0, retrieve checksums from there. @@ -49,6 +49,3 @@ COPY ./scripts /scripts EXPOSE 8332 8333 18332 18333 18443 18444 VOLUME ["/home/bitcoin/.bitcoin"] - -# Run -CMD ["bitcoind"] diff --git a/deploy/coins/bitcoin/scripts/entry-dev.sh b/deploy/coins/bitcoin/scripts/entry-dev.sh index eaf10bc8..a8525881 100755 --- a/deploy/coins/bitcoin/scripts/entry-dev.sh +++ b/deploy/coins/bitcoin/scripts/entry-dev.sh @@ -1,29 +1,6 @@ #!/bin/sh + RPC_USER="${RPC_USER:=serai}" RPC_PASS="${RPC_PASS:=seraidex}" -# address: bcrt1q7kc7tm3a4qljpw4gg5w73cgya6g9nfydtessgs -# private key: cV9X6E3J9jq7R1XR8uPED2JqFxqcd6KrC8XWPy1GchZj7MA7G9Wx -MINER="${MINER:=bcrt1q7kc7tm3a4qljpw4gg5w73cgya6g9nfydtessgs}" -PRIV_KEY="${PRIV_KEY:=cV9X6E3J9jq7R1XR8uPED2JqFxqcd6KrC8XWPy1GchZj7MA7G9Wx}" -BLOCK_TIME=${BLOCK_TIME:=5} - -bitcoind -regtest -txindex -fallbackfee=0.000001 -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS -rpcallowip=0.0.0.0/0 -rpcbind=127.0.0.1 -rpcbind=$(hostname) & - -# give time to bitcoind to start -while true -do - bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS generatetoaddress 100 $MINER && break - sleep 5 -done - -bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS createwallet "miner" false false $RPC_PASS false false true && -bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS walletpassphrase $RPC_PASS 60 && -bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS importprivkey $PRIV_KEY - -# mine a new block every BLOCK_TIME -while true -do - bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS generatetoaddress 1 $MINER - sleep $BLOCK_TIME -done +bitcoind -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS -rpcallowip=0.0.0.0/0 -rpcbind=127.0.0.1 -rpcbind=$(hostname) diff --git a/deploy/coins/monero/Dockerfile b/deploy/coins/monero/Dockerfile index 3a91ba41..5ca3ccf8 100644 --- a/deploy/coins/monero/Dockerfile +++ b/deploy/coins/monero/Dockerfile @@ -1,5 +1,5 @@ -# Prepare Environment FROM alpine:latest as builder + # https://downloads.getmonero.org/cli/monero-linux-x64-v0.18.1.0.tar.bz2 # Verification will fail if MONERO_VERSION doesn't match the latest # due to the way monero publishes releases. They overwrite a single hashes.txt file @@ -38,5 +38,3 @@ COPY ./scripts /scripts EXPOSE 18080 18081 VOLUME /home/monero/.bitmonero - -CMD ["monerod"] diff --git a/deploy/coins/monero/scripts/entry-dev.sh b/deploy/coins/monero/scripts/entry-dev.sh index 0f14cea1..262c2c21 100755 --- a/deploy/coins/monero/scripts/entry-dev.sh +++ b/deploy/coins/monero/scripts/entry-dev.sh @@ -9,10 +9,3 @@ BLOCK_TIME=${BLOCK_TIME:=5} monerod --regtest --rpc-access-control-origins * --confirm-external-bind \ --rpc-bind-ip=0.0.0.0 --offline --fixed-difficulty=1 \ --non-interactive --mining-threads 1 --detach - -# give time to monerod to start -while true; do - sleep 5 -done - -# Create wallet from PRIV_KEY in monero wallet diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index 23cae952..772a5da1 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -152,6 +152,8 @@ services: volumes: - "./coins/bitcoin/scripts:/scripts" entrypoint: /scripts/entry-dev.sh + ports: + - "18443:18443" ethereum: profiles: diff --git a/processor/Cargo.toml b/processor/Cargo.toml index c7760bab..6aec28f0 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -26,10 +26,18 @@ curve25519-dalek = { version = "3", features = ["std"] } dalek-ff-group = { path = "../crypto/dalek-ff-group" } transcript = { package = "flexible-transcript", path = "../crypto/transcript" } -frost = { package = "modular-frost", path = "../crypto/frost", features = ["ed25519"] } +frost = { package = "modular-frost", path = "../crypto/frost", features = ["secp256k1", "ed25519"] } # Monero monero-serai = { path = "../coins/monero", features = ["multisig"] } +bitcoin-serai = { path = "../coins/bitcoin" } + +k256 = { version = "0.11", features = ["arithmetic"] } +bitcoin = "0.29" +hex = "0.4" +secp256k1 = { version = "0.24", features = ["global-context", "rand-std"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" [dev-dependencies] rand_core = "0.6" @@ -41,4 +49,4 @@ serde_json = "1.0" futures = "0.3" tokio = { version = "1", features = ["full"] } -frost = { package = "modular-frost", path = "../crypto/frost", features = ["ed25519", "tests"] } +frost = { package = "modular-frost", path = "../crypto/frost", features = ["tests"] } diff --git a/processor/src/coin/bitcoin.rs b/processor/src/coin/bitcoin.rs new file mode 100644 index 00000000..f5352aee --- /dev/null +++ b/processor/src/coin/bitcoin.rs @@ -0,0 +1,283 @@ +use std::io; + +use async_trait::async_trait; + +#[rustfmt::skip] +use bitcoin::{ + hashes::Hash, schnorr::TweakedPublicKey, OutPoint, Transaction, Block, Network, Address +}; + +#[cfg(test)] +use bitcoin::{ + secp256k1::{SECP256K1, SecretKey, Message}, + PrivateKey, PublicKey, EcdsaSighashType, + blockdata::script::Builder, + PackedLockTime, Sequence, Script, Witness, TxIn, TxOut, +}; + +use transcript::RecommendedTranscript; +use k256::{ + ProjectivePoint, Scalar, + elliptic_curve::sec1::{ToEncodedPoint, Tag}, +}; +use frost::{curve::Secp256k1, ThresholdKeys}; + +use bitcoin_serai::{ + crypto::{x_only, make_even}, + wallet::{SpendableOutput, TransactionMachine, SignableTransaction as BSignableTransaction}, + rpc::Rpc, +}; + +use crate::coin::{CoinError, Block as BlockTrait, OutputType, Output as OutputTrait, Coin}; + +impl BlockTrait for Block { + type Id = [u8; 32]; + fn id(&self) -> Self::Id { + self.block_hash().as_hash().into_inner() + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct Fee(u64); + +#[derive(Clone, Debug)] +pub struct Output(SpendableOutput); +impl OutputTrait for Output { + type Id = [u8; 36]; + + // TODO: Implement later + fn kind(&self) -> OutputType { + OutputType::External + } + + fn id(&self) -> Self::Id { + self.0.id() + } + + fn amount(&self) -> u64 { + self.0.output.value + } + + fn serialize(&self) -> Vec { + self.0.serialize() + } + + fn read(reader: &mut R) -> io::Result { + SpendableOutput::read(reader).map(Output) + } +} + +#[derive(Debug)] +pub struct SignableTransaction { + keys: ThresholdKeys, + transcript: RecommendedTranscript, + actual: BSignableTransaction, +} + +#[derive(Clone, Debug)] +pub struct Bitcoin { + pub(crate) rpc: Rpc, +} +impl Bitcoin { + pub async fn new(url: String) -> Bitcoin { + Bitcoin { rpc: Rpc::new(url) } + } + + #[cfg(test)] + pub async fn fresh_chain(&self) { + if self.rpc.get_latest_block_number().await.unwrap() > 0 { + self + .rpc + .rpc_call("invalidateblock", serde_json::json!([self.rpc.get_block_hash(1).await.unwrap()])) + .await + .unwrap() + } + } +} + +#[async_trait] +impl Coin for Bitcoin { + type Curve = Secp256k1; + + type Fee = Fee; + type Transaction = Transaction; + type Block = Block; + + type Output = Output; + type SignableTransaction = SignableTransaction; + type TransactionMachine = TransactionMachine; + + type Address = Address; + + const ID: &'static [u8] = b"Bitcoin"; + const CONFIRMATIONS: usize = 3; + + // TODO: Get hard numbers and tune + const MAX_INPUTS: usize = 128; + const MAX_OUTPUTS: usize = 16; + + fn tweak_keys(&self, key: &mut ThresholdKeys) { + let (_, offset) = make_even(key.group_key()); + *key = key.offset(Scalar::from(offset)); + } + + fn address(&self, key: ProjectivePoint) -> Self::Address { + debug_assert!(key.to_encoded_point(true).tag() == Tag::CompressedEvenY, "YKey is odd"); + Address::p2tr_tweaked( + TweakedPublicKey::dangerous_assume_tweaked(x_only(&key)), + Network::Regtest, + ) + } + + // TODO: Implement later + fn branch_address(&self, key: ProjectivePoint) -> Self::Address { + self.address(key) + } + + async fn get_latest_block_number(&self) -> Result { + Ok(self.rpc.get_latest_block_number().await.map_err(|_| CoinError::ConnectionError)?) + } + + async fn get_block(&self, number: usize) -> Result { + let block_hash = + self.rpc.get_block_hash(number).await.map_err(|_| CoinError::ConnectionError)?; + self.rpc.get_block(&block_hash).await.map_err(|_| CoinError::ConnectionError) + } + + async fn get_outputs( + &self, + block: &Self::Block, + key: ProjectivePoint, + ) -> Result, CoinError> { + let main_addr = self.address(key); + + let mut outputs = Vec::new(); + // Skip the coinbase transaction which is burdened by maturity + for tx in &block.txdata[1 ..] { + for (vout, output) in tx.output.iter().enumerate() { + if output.script_pubkey == main_addr.script_pubkey() { + outputs.push(Output(SpendableOutput { + output: output.clone(), + outpoint: OutPoint { txid: tx.txid(), vout: u32::try_from(vout).unwrap() }, + })); + } + } + } + + Ok(outputs) + } + + async fn prepare_send( + &self, + keys: ThresholdKeys, + transcript: RecommendedTranscript, + _: usize, + mut inputs: Vec, + payments: &[(Address, u64)], + change: Option, + fee: Fee, + ) -> Result { + Ok(SignableTransaction { + keys, + transcript, + actual: BSignableTransaction::new( + inputs.drain(..).map(|input| input.0).collect(), + payments, + // TODO: Diversify to a proper change address + change.map(|change| self.address(change)), + fee.0, + ) + .ok_or(CoinError::NotEnoughFunds)?, + }) + } + + async fn attempt_send( + &self, + transaction: Self::SignableTransaction, + ) -> Result { + transaction + .actual + .clone() + .multisig(transaction.keys.clone(), transaction.transcript.clone()) + .await + .map_err(|_| CoinError::ConnectionError) + } + + async fn publish_transaction(&self, tx: &Self::Transaction) -> Result, CoinError> { + Ok(self.rpc.send_raw_transaction(tx).await.unwrap().to_vec()) + } + + #[cfg(test)] + async fn get_fee(&self) -> Self::Fee { + Fee(1) + } + + #[cfg(test)] + async fn mine_block(&self) { + self + .rpc + .rpc_call::>( + "generatetoaddress", + serde_json::json!([ + 1, + Address::p2sh(&Script::new(), Network::Regtest).unwrap().to_string() + ]), + ) + .await + .unwrap(); + } + + #[cfg(test)] + async fn test_send(&self, address: Self::Address) { + let secret_key = SecretKey::new(&mut rand_core::OsRng); + let private_key = PrivateKey::new(secret_key, Network::Regtest); + let public_key = PublicKey::from_private_key(SECP256K1, &private_key); + let main_addr = Address::p2pkh(&public_key, Network::Regtest); + + let new_block = self.get_latest_block_number().await.unwrap() + 1; + self + .rpc + .rpc_call::>("generatetoaddress", serde_json::json!([1, main_addr])) + .await + .unwrap(); + + for _ in 0 .. 100 { + self.mine_block().await; + } + + // TODO: Consider grabbing bdk as a dev dependency + let tx = self.get_block(new_block).await.unwrap().txdata.swap_remove(0); + let mut tx = Transaction { + version: 2, + lock_time: PackedLockTime::ZERO, + input: vec![TxIn { + previous_output: OutPoint { txid: tx.txid(), vout: 0 }, + script_sig: Script::default(), + sequence: Sequence(u32::MAX), + witness: Witness::default(), + }], + output: vec![TxOut { + value: tx.output[0].value - 10000, + script_pubkey: address.script_pubkey(), + }], + }; + + let mut der = SECP256K1 + .sign_ecdsa_low_r( + &Message::from( + tx.signature_hash(0, &main_addr.script_pubkey(), EcdsaSighashType::All.to_u32()) + .as_hash(), + ), + &private_key.inner, + ) + .serialize_der() + .to_vec(); + der.push(1); + tx.input[0].script_sig = Builder::new().push_slice(&der).push_key(&public_key).into_script(); + + self.rpc.send_raw_transaction(&tx).await.unwrap(); + for _ in 0 .. Self::CONFIRMATIONS { + self.mine_block().await; + } + } +} diff --git a/processor/src/coin/mod.rs b/processor/src/coin/mod.rs index b5fb9065..aa742a98 100644 --- a/processor/src/coin/mod.rs +++ b/processor/src/coin/mod.rs @@ -10,6 +10,9 @@ use frost::{ sign::PreprocessMachine, }; +pub mod bitcoin; +pub use self::bitcoin::Bitcoin; + pub mod monero; pub use self::monero::Monero; @@ -17,6 +20,8 @@ pub use self::monero::Monero; pub enum CoinError { #[error("failed to connect to coin daemon")] ConnectionError, + #[error("not enough funds")] + NotEnoughFunds, } pub trait Block: Sized + Clone { @@ -62,6 +67,8 @@ pub trait Coin { const MAX_INPUTS: usize; const MAX_OUTPUTS: usize; // TODO: Decide if this includes change or not + fn tweak_keys(&self, key: &mut ThresholdKeys); + /// Address for the given group key to receive external coins to. // Doesn't have to take self, enables some level of caching which is pleasant fn address(&self, key: ::G) -> Self::Address; @@ -93,10 +100,7 @@ pub trait Coin { transaction: Self::SignableTransaction, ) -> Result; - async fn publish_transaction( - &self, - tx: &Self::Transaction, - ) -> Result<(Vec, Vec<::Id>), CoinError>; + async fn publish_transaction(&self, tx: &Self::Transaction) -> Result, CoinError>; #[cfg(test)] async fn get_fee(&self) -> Self::Fee; diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index 5f364f7e..67329a74 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -162,6 +162,9 @@ impl Coin for Monero { const MAX_INPUTS: usize = 128; const MAX_OUTPUTS: usize = 16; + // Monero doesn't require/benefit from tweaking + fn tweak_keys(&self, _: &mut ThresholdKeys) {} + fn address(&self, key: dfg::EdwardsPoint) -> Self::Address { self.address_internal(key, EXTERNAL_SUBADDRESS) } @@ -258,12 +261,9 @@ impl Coin for Monero { .map_err(|_| CoinError::ConnectionError) } - async fn publish_transaction( - &self, - tx: &Self::Transaction, - ) -> Result<(Vec, Vec<::Id>), CoinError> { + async fn publish_transaction(&self, tx: &Self::Transaction) -> Result, CoinError> { self.rpc.publish_transaction(tx).await.map_err(|_| CoinError::ConnectionError)?; - Ok((tx.hash().to_vec(), tx.prefix.outputs.iter().map(|output| output.key.to_bytes()).collect())) + Ok(tx.hash().to_vec()) } #[cfg(test)] diff --git a/processor/src/tests/bitcoin.rs b/processor/src/tests/bitcoin.rs new file mode 100644 index 00000000..dcf3aeed --- /dev/null +++ b/processor/src/tests/bitcoin.rs @@ -0,0 +1,12 @@ +use crate::{ + coin::{Coin, Bitcoin}, + tests::test_send, +}; + +#[tokio::test] +async fn bitcoin() { + let bitcoin = Bitcoin::new("http://serai:seraidex@127.0.0.1:18443".to_string()).await; + bitcoin.fresh_chain().await; + let fee = bitcoin.get_fee().await; + test_send(bitcoin, fee).await; +} diff --git a/processor/src/tests/mod.rs b/processor/src/tests/mod.rs index e8abeade..4f07d090 100644 --- a/processor/src/tests/mod.rs +++ b/processor/src/tests/mod.rs @@ -1,4 +1,5 @@ mod send; pub(crate) use send::test_send; +mod bitcoin; mod monero; diff --git a/processor/src/tests/send.rs b/processor/src/tests/send.rs index 3f0a5b55..066bed55 100644 --- a/processor/src/tests/send.rs +++ b/processor/src/tests/send.rs @@ -94,7 +94,7 @@ pub async fn test_send(coin: C, fee: C::Fee) { let latest = coin.get_latest_block_number().await.unwrap(); wallet.acknowledge_block(1, latest - (C::CONFIRMATIONS - 1)); let signable = wallet - .prepare_sends(1, vec![(wallet.address(), 10000000000)], fee) + .prepare_sends(1, vec![(wallet.address(), 100000000)], fee) .await .unwrap() .1 @@ -102,5 +102,5 @@ pub async fn test_send(coin: C, fee: C::Fee) { futures.push(wallet.attempt_send(network, signable)); } - println!("{:?}", hex::encode(futures::future::join_all(futures).await.swap_remove(0).unwrap().0)); + println!("{:?}", hex::encode(futures::future::join_all(futures).await.swap_remove(0).unwrap())); } diff --git a/processor/src/wallet.rs b/processor/src/wallet.rs index 340bccea..73a90bb9 100644 --- a/processor/src/wallet.rs +++ b/processor/src/wallet.rs @@ -225,7 +225,10 @@ impl Wallet { } pub fn add_keys(&mut self, keys: &WalletKeys) { - self.pending.push((self.acknowledged_block(keys.creation_block), keys.bind(C::ID))); + let creation_block = keys.creation_block; + let mut keys = keys.bind(C::ID); + self.coin.tweak_keys(&mut keys); + self.pending.push((self.acknowledged_block(creation_block), keys)); } pub fn address(&self) -> C::Address { @@ -262,8 +265,7 @@ impl Wallet { .coin .get_outputs(&block, keys.group_key()) .await? - .iter() - .cloned() + .drain(..) .filter(|output| self.db.add_output(output)), ); } @@ -282,7 +284,7 @@ impl Wallet { pub async fn prepare_sends( &mut self, canonical: usize, - payments: Vec<(C::Address, u64)>, + mut payments: Vec<(C::Address, u64)>, fee: C::Fee, ) -> Result<(Vec<(C::Address, u64)>, Vec), CoinError> { if payments.is_empty() { @@ -296,7 +298,6 @@ impl Wallet { // As each payment re-appears, let mut payments = schedule[payment] where the only input is // the source payment // let (mut payments, schedule) = schedule(payments); - let mut payments = payments; let mut txs = vec![]; for (keys, outputs) in self.keys.iter_mut() { @@ -342,7 +343,7 @@ impl Wallet { &mut self, network: &mut N, prepared: C::SignableTransaction, - ) -> Result<(Vec, Vec<::Id>), SignError> { + ) -> Result, SignError> { let attempt = self.coin.attempt_send(prepared).await.map_err(SignError::CoinError)?; let (attempt, commitments) = attempt.preprocess(&mut OsRng); From a3267034b6368b8914abc728de26fac513f18145 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 31 Jan 2023 08:10:28 -0500 Subject: [PATCH 49/74] Bitcoin External/Branch/Change addresses Adds support for offset inputs to the Bitcoin lib --- coins/bitcoin/src/wallet.rs | 26 ++++++++++--- processor/src/coin/bitcoin.rs | 69 ++++++++++++++++++++++++++--------- processor/src/coin/mod.rs | 23 +++++++++++- 3 files changed, 94 insertions(+), 24 deletions(-) diff --git a/coins/bitcoin/src/wallet.rs b/coins/bitcoin/src/wallet.rs index 26d602fb..e641e7c1 100644 --- a/coins/bitcoin/src/wallet.rs +++ b/coins/bitcoin/src/wallet.rs @@ -8,7 +8,12 @@ use rand_core::RngCore; use transcript::{Transcript, RecommendedTranscript}; use k256::{elliptic_curve::sec1::ToEncodedPoint, Scalar}; -use frost::{curve::Secp256k1, ThresholdKeys, FrostError, algorithm::Schnorr, sign::*}; +use frost::{ + curve::{Ciphersuite, Secp256k1}, + ThresholdKeys, FrostError, + algorithm::Schnorr, + sign::*, +}; use bitcoin::{ hashes::Hash, @@ -21,6 +26,7 @@ use crate::crypto::{BitcoinHram, make_even}; #[derive(Clone, Debug)] pub struct SpendableOutput { + pub offset: Scalar, pub output: TxOut, pub outpoint: OutPoint, } @@ -32,6 +38,7 @@ impl SpendableOutput { pub fn read(r: &mut R) -> io::Result { Ok(SpendableOutput { + offset: Secp256k1::read_F(r)?, output: TxOut::consensus_decode(r) .map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid TxOut"))?, outpoint: OutPoint::consensus_decode(r) @@ -40,14 +47,15 @@ impl SpendableOutput { } pub fn serialize(&self) -> Vec { - let mut res = serialize(&self.output); + let mut res = self.offset.to_bytes().to_vec(); + self.output.consensus_encode(&mut res).unwrap(); self.outpoint.consensus_encode(&mut res).unwrap(); res } } #[derive(Clone, Debug)] -pub struct SignableTransaction(Transaction, Vec); +pub struct SignableTransaction(Transaction, Vec, Vec); impl SignableTransaction { fn calculate_weight(inputs: usize, payments: &[(Address, u64)], change: Option<&Address>) -> u64 { @@ -81,6 +89,7 @@ impl SignableTransaction { fee: u64, ) -> Option { let input_sat = inputs.iter().map(|input| input.output.value).sum::(); + let offsets = inputs.iter().map(|input| input.offset).collect(); let tx_ins = inputs .iter() .map(|input| TxIn { @@ -116,6 +125,7 @@ impl SignableTransaction { Some(SignableTransaction( Transaction { version: 2, lock_time: PackedLockTime::ZERO, input: tx_ins, output: tx_outs }, + offsets, inputs.drain(..).map(|input| input.output).collect(), )) } @@ -140,10 +150,14 @@ impl SignableTransaction { } let mut sigs = vec![]; - for _ in 0 .. tx.input.len() { + for i in 0 .. tx.input.len() { // TODO: Use the above transcript here sigs.push( - AlgorithmMachine::new(Schnorr::::new(), keys.clone()).unwrap(), + AlgorithmMachine::new( + Schnorr::::new(), + keys.clone().offset(self.1[i]), + ) + .unwrap(), ); } @@ -237,7 +251,7 @@ impl SignMachine for TransactionSignMachine { .collect::>(); let mut cache = SighashCache::new(&self.tx.0); - let prevouts = Prevouts::All(&self.tx.1); + let prevouts = Prevouts::All(&self.tx.2); let mut shares = Vec::with_capacity(self.sigs.len()); let sigs = self diff --git a/processor/src/coin/bitcoin.rs b/processor/src/coin/bitcoin.rs index f5352aee..57f925b7 100644 --- a/processor/src/coin/bitcoin.rs +++ b/processor/src/coin/bitcoin.rs @@ -1,4 +1,4 @@ -use std::io; +use std::{io, collections::HashMap}; use async_trait::async_trait; @@ -41,13 +41,12 @@ impl BlockTrait for Block { pub struct Fee(u64); #[derive(Clone, Debug)] -pub struct Output(SpendableOutput); +pub struct Output(SpendableOutput, OutputType); impl OutputTrait for Output { type Id = [u8; 36]; - // TODO: Implement later fn kind(&self) -> OutputType { - OutputType::External + self.1 } fn id(&self) -> Self::Id { @@ -59,11 +58,13 @@ impl OutputTrait for Output { } fn serialize(&self) -> Vec { - self.0.serialize() + let mut res = self.0.serialize(); + self.1.write(&mut res).unwrap(); + res } fn read(reader: &mut R) -> io::Result { - SpendableOutput::read(reader).map(Output) + Ok(Output(SpendableOutput::read(reader)?, OutputType::read(reader)?)) } } @@ -74,10 +75,32 @@ pub struct SignableTransaction { actual: BSignableTransaction, } +fn next_key(mut key: ProjectivePoint, i: usize) -> (ProjectivePoint, Scalar) { + let mut offset = Scalar::ZERO; + for _ in 0 .. i { + key += ProjectivePoint::GENERATOR; + offset += Scalar::ONE; + + let even_offset; + (key, even_offset) = make_even(key); + offset += Scalar::from(even_offset); + } + (key, offset) +} + +fn branch(key: ProjectivePoint) -> (ProjectivePoint, Scalar) { + next_key(key, 1) +} + +fn change(key: ProjectivePoint) -> (ProjectivePoint, Scalar) { + next_key(key, 2) +} + #[derive(Clone, Debug)] pub struct Bitcoin { pub(crate) rpc: Rpc, } + impl Bitcoin { pub async fn new(url: String) -> Bitcoin { Bitcoin { rpc: Rpc::new(url) } @@ -129,9 +152,8 @@ impl Coin for Bitcoin { ) } - // TODO: Implement later fn branch_address(&self, key: ProjectivePoint) -> Self::Address { - self.address(key) + self.address(branch(key).0) } async fn get_latest_block_number(&self) -> Result { @@ -149,17 +171,31 @@ impl Coin for Bitcoin { block: &Self::Block, key: ProjectivePoint, ) -> Result, CoinError> { - let main_addr = self.address(key); + let external = (key, Scalar::ZERO); + let branch = branch(key); + let change = change(key); + + let entry = + |pair: (_, _), kind| (self.address(pair.0).script_pubkey().to_bytes(), (pair.1, kind)); + let scripts = HashMap::from([ + entry(external, OutputType::External), + entry(branch, OutputType::Branch), + entry(change, OutputType::Change), + ]); let mut outputs = Vec::new(); // Skip the coinbase transaction which is burdened by maturity for tx in &block.txdata[1 ..] { for (vout, output) in tx.output.iter().enumerate() { - if output.script_pubkey == main_addr.script_pubkey() { - outputs.push(Output(SpendableOutput { - output: output.clone(), - outpoint: OutPoint { txid: tx.txid(), vout: u32::try_from(vout).unwrap() }, - })); + if let Some(info) = scripts.get(&output.script_pubkey.to_bytes()) { + outputs.push(Output( + SpendableOutput { + offset: info.0, + output: output.clone(), + outpoint: OutPoint { txid: tx.txid(), vout: u32::try_from(vout).unwrap() }, + }, + info.1, + )); } } } @@ -174,7 +210,7 @@ impl Coin for Bitcoin { _: usize, mut inputs: Vec, payments: &[(Address, u64)], - change: Option, + change_key: Option, fee: Fee, ) -> Result { Ok(SignableTransaction { @@ -183,8 +219,7 @@ impl Coin for Bitcoin { actual: BSignableTransaction::new( inputs.drain(..).map(|input| input.0).collect(), payments, - // TODO: Diversify to a proper change address - change.map(|change| self.address(change)), + change_key.map(|change_key| self.address(change(change_key).0)), fee.0, ) .ok_or(CoinError::NotEnoughFunds)?, diff --git a/processor/src/coin/mod.rs b/processor/src/coin/mod.rs index aa742a98..3a81731e 100644 --- a/processor/src/coin/mod.rs +++ b/processor/src/coin/mod.rs @@ -1,4 +1,4 @@ -use std::marker::Send; +use std::io; use async_trait::async_trait; use thiserror::Error; @@ -36,6 +36,27 @@ pub enum OutputType { Change, } +impl OutputType { + fn write(&self, writer: &mut W) -> io::Result<()> { + writer.write_all(&[match self { + OutputType::External => 0, + OutputType::Branch => 1, + OutputType::Change => 2, + }]) + } + + fn read(reader: &mut R) -> io::Result { + let mut byte = [0; 1]; + reader.read_exact(&mut byte)?; + Ok(match byte[0] { + 0 => OutputType::External, + 1 => OutputType::Branch, + 2 => OutputType::Change, + _ => Err(io::Error::new(io::ErrorKind::Other, "invalid OutputType"))?, + }) + } +} + pub trait Output: Sized + Clone { type Id: Clone + Copy + AsRef<[u8]>; From 86ad9472611080327d47e9169277f58e80dfead4 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 31 Jan 2023 08:15:00 -0500 Subject: [PATCH 50/74] Add missing semicolon --- substrate/serai/client/tests/runner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/serai/client/tests/runner.rs b/substrate/serai/client/tests/runner.rs index 36d7b98f..c618d1e2 100644 --- a/substrate/serai/client/tests/runner.rs +++ b/substrate/serai/client/tests/runner.rs @@ -110,7 +110,7 @@ macro_rules! serai_test { tokio::time::sleep(Duration::from_secs(1)).await; } // TODO: https://github.com/serai-dex/serai/247 - tokio::time::sleep(Duration::from_secs(5)).await + tokio::time::sleep(Duration::from_secs(5)).await; command }; From df75782e54892e99672d8778a38a1aebcb51d71c Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 31 Jan 2023 09:28:03 -0500 Subject: [PATCH 51/74] Re-license bitcoin-serai to MIT It's pretty basic code, yet would still be quite pleasant to the larger community. Also adds documentation. --- coins/bitcoin/Cargo.toml | 8 +++++--- coins/bitcoin/LICENSE | 26 ++++++++++++++++---------- coins/bitcoin/src/crypto.rs | 7 +++++-- coins/bitcoin/src/lib.rs | 3 +++ coins/bitcoin/src/wallet.rs | 28 +++++++++++++++++++++++----- 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/coins/bitcoin/Cargo.toml b/coins/bitcoin/Cargo.toml index de987bbc..e9d33c72 100644 --- a/coins/bitcoin/Cargo.toml +++ b/coins/bitcoin/Cargo.toml @@ -2,11 +2,10 @@ name = "bitcoin-serai" version = "0.1.0" description = "A Bitcoin library for FROST-signing transactions" -license = "AGPL-3.0-only" +license = "MIT" repository = "https://github.com/serai-dex/serai/tree/develop/coins/bitcoin" authors = ["Luke Parker ", "Vrx "] edition = "2021" -publish = false [dependencies] lazy_static = "1" @@ -21,9 +20,12 @@ bitcoin = { version = "0.29", features = ["serde"] } k256 = { version = "0.11", features = ["arithmetic"] } transcript = { package = "flexible-transcript", path = "../../crypto/transcript", version = "0.2", features = ["recommended"] } -frost = { version = "0.5", package = "modular-frost", path = "../../crypto/frost", features = ["secp256k1", "tests"] } +frost = { version = "0.5", package = "modular-frost", path = "../../crypto/frost", features = ["secp256k1"] } hex = "0.4" serde = { version = "1", features = ["derive"] } serde_json = "1" reqwest = { version = "0.11", features = ["json"] } + +[dev-dependencies] +frost = { version = "0.5", package = "modular-frost", path = "../../crypto/frost", features = ["tests"] } diff --git a/coins/bitcoin/LICENSE b/coins/bitcoin/LICENSE index c425427c..6779f0ec 100644 --- a/coins/bitcoin/LICENSE +++ b/coins/bitcoin/LICENSE @@ -1,15 +1,21 @@ -AGPL-3.0-only license +MIT License Copyright (c) 2022-2023 Luke Parker -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License Version 3 as -published by the Free Software Foundation. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/coins/bitcoin/src/crypto.rs b/coins/bitcoin/src/crypto.rs index bea62831..73e2077d 100644 --- a/coins/bitcoin/src/crypto.rs +++ b/coins/bitcoin/src/crypto.rs @@ -14,17 +14,19 @@ use bitcoin::XOnlyPublicKey; use frost::{algorithm::Hram, curve::Secp256k1}; -/// Get the x coordinate of a non-infinity, even point. +/// Get the x coordinate of a non-infinity, even point. Panics on invalid input. pub fn x(key: &ProjectivePoint) -> [u8; 32] { let encoded = key.to_encoded_point(true); assert_eq!(encoded.tag(), Tag::CompressedEvenY); (*encoded.x().expect("point at infinity")).into() } +/// Convert a non-infinite even point to a XOnlyPublicKey. Panics on invalid input. pub fn x_only(key: &ProjectivePoint) -> XOnlyPublicKey { XOnlyPublicKey::from_slice(&x(key)).unwrap() } +/// Make a point even, returning the even version and the offset required for it to be even. pub fn make_even(mut key: ProjectivePoint) -> (ProjectivePoint, u64) { let mut c = 0; while key.to_encoded_point(true).tag() == Tag::CompressedOddY { @@ -34,7 +36,8 @@ pub fn make_even(mut key: ProjectivePoint) -> (ProjectivePoint, u64) { (key, c) } -#[derive(Clone)] +/// A BIP-340 compatible HRAm for use with the modular-frost Schnorr Algorithm. +#[derive(Clone, Copy, Debug)] pub struct BitcoinHram {} lazy_static! { diff --git a/coins/bitcoin/src/lib.rs b/coins/bitcoin/src/lib.rs index 22c1c26c..cdd28b9c 100644 --- a/coins/bitcoin/src/lib.rs +++ b/coins/bitcoin/src/lib.rs @@ -1,5 +1,8 @@ +/// Cryptographic helpers. pub mod crypto; +/// Wallet functionality to create transactions. pub mod wallet; +/// A minimal async RPC. pub mod rpc; #[cfg(test)] diff --git a/coins/bitcoin/src/wallet.rs b/coins/bitcoin/src/wallet.rs index e641e7c1..d5905db9 100644 --- a/coins/bitcoin/src/wallet.rs +++ b/coins/bitcoin/src/wallet.rs @@ -1,5 +1,5 @@ use std::{ - io::{self, Read}, + io::{self, Read, Write}, collections::HashMap, }; @@ -17,25 +17,32 @@ use frost::{ use bitcoin::{ hashes::Hash, - consensus::encode::{Encodable, Decodable, serialize}, + consensus::encode::{Decodable, serialize}, util::sighash::{SchnorrSighashType, SighashCache, Prevouts}, OutPoint, Script, Sequence, Witness, TxIn, TxOut, PackedLockTime, Transaction, Address, }; use crate::crypto::{BitcoinHram, make_even}; +/// A spendable output. #[derive(Clone, Debug)] pub struct SpendableOutput { + /// The scalar offset to obtain the key usable to spend this output. + /// Enables HDKD systems. pub offset: Scalar, + /// The output to spend. pub output: TxOut, + /// The TX ID and vout of the output to spend. pub outpoint: OutPoint, } impl SpendableOutput { + /// Obtain a unique ID for this output. pub fn id(&self) -> [u8; 36] { serialize(&self.outpoint).try_into().unwrap() } + /// Read a SpendableOutput from a generic satisfying Read. pub fn read(r: &mut R) -> io::Result { Ok(SpendableOutput { offset: Secp256k1::read_F(r)?, @@ -46,14 +53,22 @@ impl SpendableOutput { }) } + /// Write a SpendableOutput to a generic satisfying Write. + pub fn write(&self, w: &mut W) -> io::Result<()> { + w.write_all(&self.offset.to_bytes())?; + w.write_all(&serialize(&self.output))?; + w.write_all(&serialize(&self.outpoint)) + } + + /// Serialize a SpendableOutput to a Vec. pub fn serialize(&self) -> Vec { - let mut res = self.offset.to_bytes().to_vec(); - self.output.consensus_encode(&mut res).unwrap(); - self.outpoint.consensus_encode(&mut res).unwrap(); + let mut res = vec![]; + self.write(&mut res).unwrap(); res } } +/// A signable transaction, clone-able across attempts. #[derive(Clone, Debug)] pub struct SignableTransaction(Transaction, Vec, Vec); @@ -82,6 +97,7 @@ impl SignableTransaction { u64::try_from(tx.weight()).unwrap() } + /// Create a new signable-transaction. pub fn new( mut inputs: Vec, payments: &[(Address, u64)], @@ -130,6 +146,7 @@ impl SignableTransaction { )) } + /// Create a multisig machine for this transaction. pub async fn multisig( self, keys: ThresholdKeys, @@ -165,6 +182,7 @@ impl SignableTransaction { } } +/// A FROST signing machine to produce a Bitcoin transaction. pub struct TransactionMachine { tx: SignableTransaction, transcript: RecommendedTranscript, From 264174644f1199167d4c36a8bb0d767b87953051 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 31 Jan 2023 10:48:19 -0500 Subject: [PATCH 52/74] Further workaround #247 --- .github/workflows/tests.yml | 2 +- substrate/serai/client/tests/runner.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 36819dd4..0cf8c04c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -64,7 +64,7 @@ jobs: cargo build - name: Run Tests - run: cargo test --all-features + run: GITHUB_CI=true cargo test --all-features fmt: runs-on: ubuntu-latest diff --git a/substrate/serai/client/tests/runner.rs b/substrate/serai/client/tests/runner.rs index c618d1e2..61a56ceb 100644 --- a/substrate/serai/client/tests/runner.rs +++ b/substrate/serai/client/tests/runner.rs @@ -110,7 +110,9 @@ macro_rules! serai_test { tokio::time::sleep(Duration::from_secs(1)).await; } // TODO: https://github.com/serai-dex/serai/247 - tokio::time::sleep(Duration::from_secs(5)).await; + if std::env::var("GITHUB_CI") == Ok("true".to_string()) { + tokio::time::sleep(Duration::from_secs(60)).await; + } command }; From c540f52dda4a41444a7b363bb6a4a99a1c5e9008 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 22:46:53 -0500 Subject: [PATCH 53/74] Update nightly (#248) Co-authored-by: GitHub Actions <> --- .github/nightly-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/nightly-version b/.github/nightly-version index 14a3253f..d6ab1143 100644 --- a/.github/nightly-version +++ b/.github/nightly-version @@ -1 +1 @@ -nightly-2023-01-16 +nightly-2023-02-01 From 82a096e90eb06db59d06fba67a7247d12b134499 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 14 Feb 2023 15:49:16 -0500 Subject: [PATCH 54/74] Scanner assert on is_torsion_free --- coins/monero/src/wallet/scan.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index 5d1d4e2b..f4a1f580 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -347,7 +347,7 @@ impl Scanner { // We will not have a torsioned key in our HashMap of keys, so we wouldn't identify it as // ours // If we did though, it'd enable bypassing the included burning bug protection - debug_assert!(output_key.is_torsion_free()); + assert!(output_key.is_torsion_free()); let mut key_offset = shared_key; if let Some(subaddress) = subaddress { From 5de8bf32952acc3b8bacdfaf6b9b6bfc3374c840 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 15 Feb 2023 01:56:36 -0500 Subject: [PATCH 55/74] Add additional checks/documentation to monero --- coins/monero/src/rpc.rs | 43 +++++++++++++++++++------------ coins/monero/src/wallet/decoys.rs | 3 +++ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/coins/monero/src/rpc.rs b/coins/monero/src/rpc.rs index 06395b31..61d9922d 100644 --- a/coins/monero/src/rpc.rs +++ b/coins/monero/src/rpc.rs @@ -27,7 +27,6 @@ pub struct JsonRpcResponse { #[derive(Deserialize, Debug)] struct TransactionResponse { tx_hash: String, - block_height: Option, as_hex: String, pruned_as_hex: String, } @@ -248,7 +247,8 @@ impl Rpc { txs .txs .iter() - .map(|res| { + .enumerate() + .map(|(i, res)| { let tx = Transaction::read::<&[u8]>( &mut rpc_hex(if !res.as_hex.is_empty() { &res.as_hex } else { &res.pruned_as_hex })? .as_ref(), @@ -266,6 +266,12 @@ impl Rpc { } } + // This does run a few keccak256 hashes, which is pointless if the node is trusted + // In exchange, this provides resilience against invalid/malicious nodes + if tx.hash() != hashes[i] { + Err(RpcError::InvalidNode)?; + } + Ok(tx) }) .collect() @@ -275,19 +281,8 @@ impl Rpc { self.get_transactions(&[tx]).await.map(|mut txs| txs.swap_remove(0)) } - pub async fn get_transaction_block_number(&self, tx: &[u8]) -> Result, RpcError> { - let txs: TransactionsResponse = - self.rpc_call("get_transactions", Some(json!({ "txs_hashes": [hex::encode(tx)] }))).await?; - - if !txs.missed_tx.is_empty() { - Err(RpcError::TransactionsNotFound( - txs.missed_tx.iter().map(|hash| hash_hex(hash)).collect::>()?, - ))?; - } - - Ok(txs.txs[0].block_height) - } - + /// Get the hash of a block from the node by the block's numbers. + /// This function does not verify the returned block hash is actually for the number in question. pub async fn get_block_hash(&self, number: usize) -> Result<[u8; 32], RpcError> { #[derive(Deserialize, Debug)] struct BlockHeaderResponse { @@ -303,6 +298,8 @@ impl Rpc { rpc_hex(&header.block_header.hash)?.try_into().map_err(|_| RpcError::InvalidNode) } + /// Get a block from the node by its hash. + /// This function does not verify the returned block actually has the hash in question. pub async fn get_block(&self, hash: [u8; 32]) -> Result { #[derive(Deserialize, Debug)] struct BlockResponse { @@ -312,11 +309,25 @@ impl Rpc { let res: BlockResponse = self.json_rpc_call("get_block", Some(json!({ "hash": hex::encode(hash) }))).await?; + // TODO: Verify the TXs included are actually committed to by the header Block::read::<&[u8]>(&mut rpc_hex(&res.blob)?.as_ref()).map_err(|_| RpcError::InvalidNode) } pub async fn get_block_by_number(&self, number: usize) -> Result { - self.get_block(self.get_block_hash(number).await?).await + match self.get_block(self.get_block_hash(number).await?).await { + Ok(block) => { + // Make sure this is actually the block for this number + match block.miner_tx.prefix.inputs[0] { + Input::Gen(actual) => if usize::try_from(actual).unwrap() == number { + Ok(block) + } else { + Err(RpcError::InvalidNode) + }, + _ => Err(RpcError::InvalidNode), + } + }, + e => e, + } } pub async fn get_block_transactions(&self, hash: [u8; 32]) -> Result, RpcError> { diff --git a/coins/monero/src/wallet/decoys.rs b/coins/monero/src/wallet/decoys.rs index a0dd32bd..d9b7703c 100644 --- a/coins/monero/src/wallet/decoys.rs +++ b/coins/monero/src/wallet/decoys.rs @@ -23,6 +23,9 @@ const TIP_APPLICATION: f64 = (LOCK_WINDOW * BLOCK_TIME) as f64; lazy_static! { static ref GAMMA: Gamma = Gamma::new(19.28, 1.0 / 1.61).unwrap(); + // TODO: Expose an API to reset this in case a reorg occurs/the RPC fails/returns garbage + // TODO: This is not currently thread-safe. This needs to be a tokio Mutex held by select until + // it returns static ref DISTRIBUTION: Mutex> = Mutex::new(Vec::with_capacity(3000000)); } From 07f424b484f4741ba09875bf8fdc0eaea84322a5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 15 Feb 2023 20:39:22 -0500 Subject: [PATCH 56/74] cargo fmt --- coins/monero/src/rpc.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/coins/monero/src/rpc.rs b/coins/monero/src/rpc.rs index 61d9922d..ccf56b24 100644 --- a/coins/monero/src/rpc.rs +++ b/coins/monero/src/rpc.rs @@ -318,14 +318,16 @@ impl Rpc { Ok(block) => { // Make sure this is actually the block for this number match block.miner_tx.prefix.inputs[0] { - Input::Gen(actual) => if usize::try_from(actual).unwrap() == number { - Ok(block) - } else { - Err(RpcError::InvalidNode) - }, + Input::Gen(actual) => { + if usize::try_from(actual).unwrap() == number { + Ok(block) + } else { + Err(RpcError::InvalidNode) + } + } _ => Err(RpcError::InvalidNode), } - }, + } e => e, } } From 8260ec1a9e16f41adaecfe86abc9f10d542369ec Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 15 Feb 2023 20:44:53 -0500 Subject: [PATCH 57/74] Add another TODO --- coins/monero/src/wallet/decoys.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/coins/monero/src/wallet/decoys.rs b/coins/monero/src/wallet/decoys.rs index d9b7703c..e9ab7280 100644 --- a/coins/monero/src/wallet/decoys.rs +++ b/coins/monero/src/wallet/decoys.rs @@ -26,6 +26,7 @@ lazy_static! { // TODO: Expose an API to reset this in case a reorg occurs/the RPC fails/returns garbage // TODO: This is not currently thread-safe. This needs to be a tokio Mutex held by select until // it returns + // TODO: Update this when scanning a block, as possible. static ref DISTRIBUTION: Mutex> = Mutex::new(Vec::with_capacity(3000000)); } From 8144956f8a85261fb89013e7ea7758ffa54787ef Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Thu, 2 Mar 2023 05:31:22 -0500 Subject: [PATCH 58/74] Further document get_unlocked_outputs --- coins/monero/src/rpc.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coins/monero/src/rpc.rs b/coins/monero/src/rpc.rs index ccf56b24..73386829 100644 --- a/coins/monero/src/rpc.rs +++ b/coins/monero/src/rpc.rs @@ -408,8 +408,9 @@ impl Rpc { Ok(distributions.distributions.swap_remove(0).distribution) } - /// Get the specified outputs from the RingCT (zero-amount) pool, but only return them if they're - /// unlocked. + /// Get the specified outputs from the RingCT (zero-amount) pool, but only return them if their + /// timelock has been satisfied. This is distinct from being free of the 10-block lock applied to + /// all Monero transactions. pub async fn get_unlocked_outputs( &self, indexes: &[u64], From 943438628dad07a1a41028b5e6dc1d688e784d08 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 6 Mar 2023 07:39:43 -0500 Subject: [PATCH 59/74] cargo update --- Cargo.lock | 1660 ++++++++++++++++++++++++++++------------------------ 1 file changed, 911 insertions(+), 749 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa96be02..a97d3c4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,7 +27,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.27.1", + "gimli 0.27.2", ] [[package]] @@ -55,6 +55,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "aead" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" +dependencies = [ + "crypto-common", + "generic-array 0.14.6", +] + [[package]] name = "aes" version = "0.6.0" @@ -89,20 +99,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "aes-gcm" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" -dependencies = [ - "aead 0.3.2", - "aes 0.6.0", - "cipher 0.2.5", - "ctr 0.6.0", - "ghash 0.3.1", - "subtle", -] - [[package]] name = "aes-gcm" version = "0.9.4" @@ -117,6 +113,20 @@ dependencies = [ "subtle", ] +[[package]] +name = "aes-gcm" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +dependencies = [ + "aead 0.5.1", + "aes 0.8.2", + "cipher 0.4.3", + "ctr 0.9.2", + "ghash 0.5.0", + "subtle", +] + [[package]] name = "aes-soft" version = "0.6.4" @@ -148,6 +158,18 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom 0.2.8", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.20" @@ -177,9 +199,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" [[package]] name = "approx" @@ -242,7 +264,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.17", + "time 0.3.20", ] [[package]] @@ -258,7 +280,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.17", + "time 0.3.20", ] [[package]] @@ -324,19 +346,18 @@ dependencies = [ [[package]] name = "async-lock" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" dependencies = [ "event-listener", - "futures-lite", ] [[package]] name = "async-trait" -version = "0.1.63" +version = "0.1.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1" +checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc" dependencies = [ "proc-macro2", "quote", @@ -384,18 +405,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "auto_impl" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7862e21c893d65a1650125d157eaeec691439379a1cee17ee49031b79236ada4" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "auto_impl" version = "1.0.1" @@ -493,9 +502,9 @@ checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bech32" @@ -529,9 +538,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.60.1" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" dependencies = [ "bitflags", "cexpr", @@ -544,6 +553,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", + "syn", ] [[package]] @@ -640,24 +650,24 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" +checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq 0.1.5", + "constant_time_eq 0.2.4", ] [[package]] name = "blake2s_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq 0.1.5", + "constant_time_eq 0.2.4", ] [[package]] @@ -728,6 +738,18 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "bounded-collections" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a071c348a5ef6da1d3a87166b408170b46002382b1dda83992b5c2208cefb370" +dependencies = [ + "log", + "parity-scale-codec", + "scale-info", + "serde", +] + [[package]] name = "bs58" version = "0.4.0" @@ -736,9 +758,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bstr" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" +checksum = "5ffdb39cb703212f3c11973452c2861b972f757b021158f3516ba10f2fa8b2c1" dependencies = [ "memchr", "serde", @@ -771,6 +793,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + [[package]] name = "byteorder" version = "1.4.3" @@ -779,9 +807,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" dependencies = [ "serde", ] @@ -809,9 +837,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77df041dc383319cc661b428b6961a005db4d6808d5e12536931b1ca9556055" +checksum = "6031a462f977dd38968b6f23378356512feeace69cef817e1a4475108093cec3" dependencies = [ "serde", ] @@ -827,22 +855,9 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.14.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" -dependencies = [ - "camino", - "cargo-platform", - "semver 1.0.16", - "serde", - "serde_json", -] - -[[package]] -name = "cargo_metadata" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a" +checksum = "08a1ec454bc3eead8719cb56e15dbbfecdbc14e4b3a3ae4936cc6e31f5fc0d07" dependencies = [ "camino", "cargo-platform", @@ -854,9 +869,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" dependencies = [ "jobserver", ] @@ -962,7 +977,7 @@ checksum = "f6ed9c8b2d17acb8110c46f1da5bf4a696d745e1474a16db0cd2b49cd0249bf2" dependencies = [ "core2", "multibase", - "multihash", + "multihash 0.16.3", "serde", "unsigned-varint", ] @@ -1019,9 +1034,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.4.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a" dependencies = [ "glob", "libc", @@ -1047,13 +1062,13 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.1" +version = "4.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec7a4128863c188deefe750ac1d1dfe66c236909f845af04beed823638dc1b2" +checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5" dependencies = [ "bitflags", - "clap_derive 4.1.0", - "clap_lex 0.3.1", + "clap_derive 4.1.8", + "clap_lex 0.3.2", "is-terminal", "once_cell", "strsim", @@ -1066,7 +1081,7 @@ version = "3.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" dependencies = [ - "heck 0.4.0", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", @@ -1075,11 +1090,11 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.1.0" +version = "4.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0" dependencies = [ - "heck 0.4.0", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", @@ -1097,9 +1112,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09" dependencies = [ "os_str_bytes", ] @@ -1220,9 +1235,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" @@ -1288,26 +1303,20 @@ dependencies = [ "libc", ] -[[package]] -name = "cpuid-bool" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" - [[package]] name = "cranelift-bforest" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52056f6d0584484b57fa6c1a65c1fcb15f3780d8b6a758426d9e3084169b2ddd" +checksum = "91b18cf92869a6ae85cde3af4bc4beb6154efa8adef03b18db2ad413d5bce3a2" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fed94c8770dc25d01154c3ffa64ed0b3ba9d583736f305fed7beebe5d9cf74" +checksum = "567d9f6e919bac076f39b902a072686eaf9e6d015baa34d10a61b85105b7af59" dependencies = [ "arrayvec 0.7.2", "bumpalo", @@ -1317,6 +1326,7 @@ dependencies = [ "cranelift-entity", "cranelift-isle", "gimli 0.26.2", + "hashbrown 0.12.3", "log", "regalloc2", "smallvec", @@ -1325,33 +1335,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c451b81faf237d11c7e4f3165eeb6bac61112762c5cfe7b4c0fb7241474358f" +checksum = "1e72b2d5ec8917b2971fe83850187373d0a186db4748a7c23a5f48691b8d92bb" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c940133198426d26128f08be2b40b0bd117b84771fd36798969c4d712d81fc" +checksum = "3461c0e0c2ebbeb92533aacb27e219289f60dc84134ef34fbf2d77c9eddf07ef" [[package]] name = "cranelift-entity" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87a0f1b2fdc18776956370cf8d9b009ded3f855350c480c1c52142510961f352" +checksum = "af684f7f7b01427b1942c7102673322a51b9d6f261e9663dc5e5595786775531" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34897538b36b216cc8dd324e73263596d51b8cf610da6498322838b2546baf8a" +checksum = "7d361ed0373cf5f086b49c499aa72227b646a64f899f32e34312f97c0fadff75" dependencies = [ "cranelift-codegen", "log", @@ -1361,15 +1371,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b2629a569fae540f16a76b70afcc87ad7decb38dc28fa6c648ac73b51e78470" +checksum = "cef4f8f3984d772c199a48896d2fb766f96301bf71b371e03a2b99f4f3b7b931" [[package]] name = "cranelift-native" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20937dab4e14d3e225c5adfc9c7106bafd4ac669bdb43027b911ff794c6fb318" +checksum = "f98e4e99a353703475d5acb402b9c13482d41d8a4008b352559bd560afb90363" dependencies = [ "cranelift-codegen", "libc", @@ -1378,9 +1388,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.88.2" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80fc2288957a94fd342a015811479de1837850924166d1f1856d8406e6f3609b" +checksum = "a1e3f4f0779a1b0f286a6ef19835d8665f88326e656a6d7d84fa9a39fa38ca32" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1394,9 +1404,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" dependencies = [ "crc-catalog", ] @@ -1418,9 +1428,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1428,9 +1438,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -1439,22 +1449,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.8.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -1484,6 +1494,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array 0.14.6", + "rand_core 0.6.4", "typenum", ] @@ -1497,16 +1508,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "crypto-mac" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" -dependencies = [ - "generic-array 0.14.6", - "subtle", -] - [[package]] name = "crypto-mac" version = "0.11.1" @@ -1517,15 +1518,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ctr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" -dependencies = [ - "cipher 0.2.5", -] - [[package]] name = "ctr" version = "0.8.0" @@ -1573,9 +1565,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0-pre.5" +version = "4.0.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67bc65846be335cb20f4e52d49a437b773a2c1fdb42b19fc84e79e6f6771536f" +checksum = "8da00a7a9a4eb92a0a0f8e75660926d48f0d0f3c537e455c457bcdaa1e16b1ac" dependencies = [ "cfg-if", "fiat-crypto", @@ -1587,9 +1579,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.87" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e" +checksum = "9a140f260e6f3f79013b8bfc65e7ce630c9ab4388c6a89c71e07226f49487b72" dependencies = [ "cc", "cxxbridge-flags", @@ -1599,9 +1591,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.87" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200" +checksum = "da6383f459341ea689374bf0a42979739dc421874f112ff26f829b8040b8e613" dependencies = [ "cc", "codespan-reporting", @@ -1614,15 +1606,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.87" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea" +checksum = "90201c1a650e95ccff1c8c0bb5a343213bdd317c6e600a93075bca2eff54ec97" [[package]] name = "cxxbridge-macro" -version = "1.0.87" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e" +checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56" dependencies = [ "proc-macro2", "quote", @@ -1646,9 +1638,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8" dependencies = [ "darling_core", "darling_macro", @@ -1656,9 +1648,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb" dependencies = [ "fnv", "ident_case", @@ -1670,9 +1662,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" dependencies = [ "darling_core", "quote", @@ -1755,6 +1747,17 @@ dependencies = [ "syn", ] +[[package]] +name = "derive-syn-parse" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79116f119dd1dba1abf1f3405f03b9b0e79a27a3883864bfebded8a3dc768cd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "derive_builder" version = "0.11.2" @@ -1975,9 +1978,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "dtoa" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00704156a7de8df8da0911424e30c2049957b0a714542a44e05fe693dd85313" +checksum = "65d09067bfacaa79114679b279d7f5885b53295b1e2cfb4e79c8e4bd3d633169" [[package]] name = "dunce" @@ -2008,9 +2011,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" @@ -2054,7 +2057,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ "curve25519-dalek 3.2.0", - "hashbrown", + "hashbrown 0.12.3", "hex", "rand_core 0.6.4", "sha2 0.9.9", @@ -2063,9 +2066,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" @@ -2091,9 +2094,9 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3" +checksum = "b2e5d13ca2353ab7d0230988629def93914a8c4015f621f9b13ed2955614731d" dependencies = [ "log", ] @@ -2106,20 +2109,39 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if", ] +[[package]] +name = "enr" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "492a7e5fc2504d5fdce8e124d3e263b244a68b283cac67a69eda0cd43e0aebad" +dependencies = [ + "base64 0.13.1", + "bs58", + "bytes", + "hex", + "k256", + "log", + "rand 0.8.5", + "rlp", + "serde", + "sha3", + "zeroize", +] + [[package]] name = "enum-as-inner" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ - "heck 0.4.0", + "heck 0.4.1", "proc-macro2", "quote", "syn", @@ -2271,9 +2293,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4be54dd2260945d784e06ccdeb5ad573e8f1541838cee13a1ab885485eaa0b" +checksum = "a6fef0375eef9f126f5c9fa41a4d1f8cc109e41160f2757f74e1d0b485fd069b" dependencies = [ "ethers-core", "once_cell", @@ -2283,9 +2305,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c3c3e119a89f0a9a1e539e7faecea815f74ddcf7c90d0b00d1f524db2fdc9c" +checksum = "6fc3d7048cfc56615edf05cdfb38a38c8bc6108e2f51a0f2959a9397bd271b3c" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", @@ -2302,17 +2324,19 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4e5ad46aede34901f71afdb7bb555710ed9613d88d644245c657dc371aa228" +checksum = "651115f37eb5a2c91289c184174f67bb9053c052b2189e3f162044e84ac5e505" dependencies = [ "Inflector", "cfg-if", "dunce", "ethers-core", + "ethers-etherscan", "eyre", "getrandom 0.2.8", "hex", + "prettyplease", "proc-macro2", "quote", "regex", @@ -2320,6 +2344,7 @@ dependencies = [ "serde", "serde_json", "syn", + "tokio", "toml", "url", "walkdir", @@ -2327,12 +2352,13 @@ dependencies = [ [[package]] name = "ethers-contract-derive" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f192e8e4cf2b038318aae01e94e7644e0659a76219e94bcd3203df744341d61f" +checksum = "96b3385c9daa450bbcef5da438ed99e9361019f1242f7c3f635f132ecc961cd3" dependencies = [ "ethers-contract-abigen", "ethers-core", + "eyre", "hex", "proc-macro2", "quote", @@ -2342,20 +2368,22 @@ dependencies = [ [[package]] name = "ethers-core" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade3e9c97727343984e1ceada4fdab11142d2ee3472d2c67027d56b1251d4f15" +checksum = "94573efbaddb420037ffc2be6540d86ec17efd715ae8c1b4792ac6d6865b157f" dependencies = [ "arrayvec 0.7.2", "bytes", - "cargo_metadata 0.15.2", + "cargo_metadata", "chrono", "convert_case", "elliptic-curve", "ethabi", "generic-array 0.14.6", + "getrandom 0.2.8", "hex", "k256", + "num_enum", "once_cell", "open-fastrlp", "proc-macro2", @@ -2366,6 +2394,7 @@ dependencies = [ "serde_json", "strum", "syn", + "tempfile", "thiserror", "tiny-keccak", "unicode-xid", @@ -2373,9 +2402,9 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9713f525348e5dde025d09b0a4217429f8074e8ff22c886263cc191e87d8216" +checksum = "cb663dde0a44aba855cc9b7d3ec17ea9ffb3659914933a170a46954896edb339" dependencies = [ "ethers-core", "getrandom 0.2.8", @@ -2390,12 +2419,12 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e71df7391b0a9a51208ffb5c7f2d068900e99d6b3128d3a4849d138f194778b7" +checksum = "5d2b2e125feb05c17909919c30385b012ce33330c1522426c116929063b9f924" dependencies = [ "async-trait", - "auto_impl 0.5.0", + "auto_impl", "ethers-contract", "ethers-core", "ethers-etherscan", @@ -2416,13 +2445,14 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a9e0597aa6b2fdc810ff58bc95e4eeaa2c219b3e615ed025106ecb027407d8" +checksum = "585c96fbae569931aa0fab963a010d4c98d2757028ec840809b98032d9543d18" dependencies = [ "async-trait", - "auto_impl 1.0.1", - "base64 0.13.1", + "auto_impl", + "base64 0.21.0", + "enr", "ethers-core", "futures-core", "futures-timer", @@ -2451,9 +2481,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f41ced186867f64773db2e55ffdd92959e094072a1d09a5e5e831d443204f98" +checksum = "52b8308a63f1c00ecf001a75c9b192499d87324c310c6fd9e772d20bdfbf366b" dependencies = [ "async-trait", "coins-bip32", @@ -2465,13 +2495,14 @@ dependencies = [ "rand 0.8.5", "sha2 0.10.6", "thiserror", + "tracing", ] [[package]] name = "ethers-solc" -version = "1.0.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbe9c0a6d296c57191e5f8a613a3b5e816812c28f4a28d6178a17c21db903d77" +checksum = "9482f0e65b8e09e3d3e86a1ea5e558a8b5e7da3597a97fc588ff4a0bdaf0e148" dependencies = [ "cfg-if", "dunce", @@ -2538,9 +2569,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -2576,9 +2607,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" +checksum = "54b2f3c51e4dd999930845da5d10a48775b8fe4ca9f4f9ec1f9161f334da5dfe" [[package]] name = "file-per-thread-logger" @@ -2592,14 +2623,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" +checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" dependencies = [ "cfg-if", "libc", "redox_syscall", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -2701,7 +2732,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", ] @@ -2724,9 +2755,10 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-support", + "frame-support-procedural", "frame-system", "linregress", "log", @@ -2742,17 +2774,18 @@ dependencies = [ "sp-runtime-interface", "sp-std", "sp-storage", + "static_assertions", ] [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "Inflector", "array-bytes", "chrono", - "clap 4.1.1", + "clap 4.1.8", "comfy-table", "frame-benchmarking", "frame-support", @@ -2794,7 +2827,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-support", "frame-system", @@ -2822,7 +2855,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "bitflags", "frame-metadata", @@ -2854,10 +2887,11 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "Inflector", "cfg-expr", + "derive-syn-parse", "frame-support-procedural-tools", "itertools", "proc-macro2", @@ -2868,7 +2902,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -2880,7 +2914,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "proc-macro2", "quote", @@ -2890,7 +2924,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-support", "log", @@ -2908,7 +2942,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "sp-api", @@ -2924,12 +2958,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "fs_extra" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" - [[package]] name = "funty" version = "2.0.0" @@ -2938,9 +2966,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" dependencies = [ "futures-channel", "futures-core", @@ -2953,9 +2981,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" dependencies = [ "futures-core", "futures-sink", @@ -2963,15 +2991,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" [[package]] name = "futures-executor" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" dependencies = [ "futures-core", "futures-task", @@ -2981,9 +3009,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" [[package]] name = "futures-lite" @@ -3012,9 +3040,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ "proc-macro2", "quote", @@ -3034,15 +3062,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" [[package]] name = "futures-timer" @@ -3052,9 +3080,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" dependencies = [ "futures-channel", "futures-core", @@ -3130,16 +3158,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghash" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" -dependencies = [ - "opaque-debug 0.3.0", - "polyval 0.4.5", -] - [[package]] name = "ghash" version = "0.4.4" @@ -3150,6 +3168,16 @@ dependencies = [ "polyval 0.5.3", ] +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug 0.3.0", + "polyval 0.6.0", +] + [[package]] name = "gimli" version = "0.26.2" @@ -3163,9 +3191,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "glob" @@ -3199,9 +3227,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" dependencies = [ "bytes", "fnv", @@ -3251,7 +3279,16 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", ] [[package]] @@ -3274,9 +3311,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" @@ -3296,6 +3333,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -3327,16 +3370,6 @@ dependencies = [ "digest 0.9.0", ] -[[package]] -name = "hmac" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" -dependencies = [ - "crypto-mac 0.10.1", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.11.0" @@ -3389,9 +3422,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -3435,9 +3468,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.23" +version = "0.14.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c" dependencies = [ "bytes", "futures-channel", @@ -3658,7 +3691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", "serde", ] @@ -3725,18 +3758,12 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "0.7.5" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074" - -[[package]] -name = "io-lifetimes" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3765,14 +3792,14 @@ checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" [[package]] name = "is-terminal" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" dependencies = [ - "hermit-abi 0.2.6", - "io-lifetimes 1.0.4", - "rustix 0.36.7", - "windows-sys 0.42.0", + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.45.0", ] [[package]] @@ -3786,24 +3813,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "jobserver" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] @@ -3912,7 +3939,7 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa6da1e4199c10d7b1d0a6e5e8bd8e55f351163b6f4b3cbb044672a69bd4c1c" dependencies = [ - "heck 0.4.0", + "heck 0.4.1", "proc-macro-crate", "proc-macro2", "quote", @@ -4084,16 +4111,16 @@ checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" [[package]] name = "libp2p" -version = "0.50.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e0a0d2f693675f49ded13c5d510c48b78069e23cbd9108d7ccd59f6dc568819" +checksum = "9c7b0104790be871edcf97db9bd2356604984e623a08d825c3f27852290266b8" dependencies = [ "bytes", "futures", "futures-timer", "getrandom 0.2.8", "instant", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-dns", "libp2p-identify", "libp2p-kad", @@ -4110,7 +4137,7 @@ dependencies = [ "libp2p-webrtc", "libp2p-websocket", "libp2p-yamux", - "multiaddr", + "multiaddr 0.16.0", "parking_lot 0.12.1", "pin-project", "smallvec", @@ -4131,8 +4158,42 @@ dependencies = [ "futures-timer", "instant", "log", - "multiaddr", - "multihash", + "multiaddr 0.16.0", + "multihash 0.16.3", + "multistream-select", + "once_cell", + "parking_lot 0.12.1", + "pin-project", + "prost", + "prost-build", + "rand 0.8.5", + "rw-stream-sink", + "sec1", + "sha2 0.10.6", + "smallvec", + "thiserror", + "unsigned-varint", + "void", + "zeroize", +] + +[[package]] +name = "libp2p-core" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881d9a54e97d97cdaa4125d48269d97ca8c40e5fefec6b85b30440dc60cc551f" +dependencies = [ + "asn1_der", + "bs58", + "ed25519-dalek", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "log", + "multiaddr 0.17.0", + "multihash 0.17.0", "multistream-select", "once_cell", "parking_lot 0.12.1", @@ -4157,7 +4218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e42a271c1b49f789b92f7fc87749fa79ce5c7bdc88cbdfacb818a4bca47fec5" dependencies = [ "futures", - "libp2p-core", + "libp2p-core 0.38.0", "log", "parking_lot 0.12.1", "smallvec", @@ -4173,7 +4234,7 @@ dependencies = [ "asynchronous-codec", "futures", "futures-timer", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-swarm", "log", "lru", @@ -4199,7 +4260,7 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-swarm", "log", "prost", @@ -4222,7 +4283,7 @@ dependencies = [ "data-encoding", "futures", "if-watch", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-swarm", "log", "rand 0.8.5", @@ -4239,7 +4300,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ad8a64f29da86005c86a4d2728b8a0719e9b192f4092b609fd8790acb9dec55" dependencies = [ - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-identify", "libp2p-kad", "libp2p-ping", @@ -4256,7 +4317,7 @@ dependencies = [ "asynchronous-codec", "bytes", "futures", - "libp2p-core", + "libp2p-core 0.38.0", "log", "nohash-hasher", "parking_lot 0.12.1", @@ -4274,7 +4335,7 @@ dependencies = [ "bytes", "curve25519-dalek 3.2.0", "futures", - "libp2p-core", + "libp2p-core 0.38.0", "log", "once_cell", "prost", @@ -4297,7 +4358,7 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-swarm", "log", "rand 0.8.5", @@ -4314,7 +4375,7 @@ dependencies = [ "futures", "futures-timer", "if-watch", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-tls", "log", "parking_lot 0.12.1", @@ -4335,7 +4396,7 @@ dependencies = [ "bytes", "futures", "instant", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-swarm", "log", "rand 0.8.5", @@ -4354,7 +4415,7 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-swarm-derive", "log", "pin-project", @@ -4371,7 +4432,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d527d5827582abd44a6d80c07ff8b50b4ee238a8979e05998474179e79dc400" dependencies = [ - "heck 0.4.0", + "heck 0.4.1", "quote", "syn", ] @@ -4386,7 +4447,7 @@ dependencies = [ "futures-timer", "if-watch", "libc", - "libp2p-core", + "libp2p-core 0.38.0", "log", "socket2", "tokio", @@ -4394,13 +4455,13 @@ dependencies = [ [[package]] name = "libp2p-tls" -version = "0.1.0-alpha" +version = "0.1.0-alpha.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7905ce0d040576634e8a3229a7587cc8beab83f79db6023800f1792895defa8" +checksum = "e9baf6f6292149e124ee737d9a79dbee783f29473fc368c7faad9d157841078a" dependencies = [ "futures", "futures-rustls", - "libp2p-core", + "libp2p-core 0.39.0", "rcgen 0.10.0", "ring", "rustls 0.20.8", @@ -4418,7 +4479,7 @@ checksum = "1bb1a35299860e0d4b3c02a3e74e3b293ad35ae0cee8a056363b0c862d082069" dependencies = [ "futures", "js-sys", - "libp2p-core", + "libp2p-core 0.38.0", "parity-send-wrapper", "wasm-bindgen", "wasm-bindgen-futures", @@ -4437,10 +4498,10 @@ dependencies = [ "futures-timer", "hex", "if-watch", - "libp2p-core", + "libp2p-core 0.38.0", "libp2p-noise", "log", - "multihash", + "multihash 0.16.3", "prost", "prost-build", "prost-codec", @@ -4464,7 +4525,7 @@ dependencies = [ "either", "futures", "futures-rustls", - "libp2p-core", + "libp2p-core 0.38.0", "log", "parking_lot 0.12.1", "quicksink", @@ -4481,7 +4542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f63594a0aa818642d9d4915c791945053877253f08a3626f13416b5cd928a29" dependencies = [ "futures", - "libp2p-core", + "libp2p-core 0.38.0", "log", "parking_lot 0.12.1", "thiserror", @@ -4490,9 +4551,9 @@ dependencies = [ [[package]] name = "librocksdb-sys" -version = "0.8.0+7.4.4" +version = "0.8.3+7.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611804e4666a25136fcc5f8cf425ab4d26c7f74ea245ffe92ea23b85b6420b5d" +checksum = "557b255ff04123fcc176162f56ed0c9cd42d8f357cf55b3fabeb60f7413741b3" dependencies = [ "bindgen", "bzip2-sys", @@ -4588,20 +4649,13 @@ dependencies = [ [[package]] name = "linregress" -version = "0.4.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c601a85f5ecd1aba625247bca0031585fb1c446461b142878a16f8245ddeb8" +checksum = "475015a7f8f017edb28d2e69813be23500ad4b32cfe3421c4148efc97324ee52" dependencies = [ "nalgebra", - "statrs", ] -[[package]] -name = "linux-raw-sys" -version = "0.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" - [[package]] name = "linux-raw-sys" version = "0.1.4" @@ -4633,7 +4687,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6e8aaa3f231bb4bd57b84b2d5dc3ae7f350265df8aa96492e0bc394a1571909" dependencies = [ - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -4736,14 +4790,14 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb" dependencies = [ - "rustix 0.36.7", + "rustix", ] [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] @@ -4766,6 +4820,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + [[package]] name = "memory-db" version = "0.31.0" @@ -4773,7 +4836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e0c7cba9ce19ac7ffd2053ac9f49843bbd3f4318feedfd74e85c19d5fb0ba66" dependencies = [ "hash-db", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -4847,14 +4910,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -4966,7 +5029,7 @@ dependencies = [ "serde", "serde_json", "tracing", - "uuid 1.2.2", + "uuid 1.3.0", ] [[package]] @@ -5012,7 +5075,25 @@ dependencies = [ "byteorder", "data-encoding", "multibase", - "multihash", + "multihash 0.16.3", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + +[[package]] +name = "multiaddr" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b53e0cc5907a5c216ba6584bf74be8ab47d6d6289f72793b2dddbf15dc3bf8c" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "multibase", + "multihash 0.17.0", "percent-encoding", "serde", "static_assertions", @@ -5061,10 +5142,23 @@ dependencies = [ ] [[package]] -name = "multihash-derive" -version = "0.8.0" +name = "multihash" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "core2", + "digest 0.10.6", + "multihash-derive", + "sha2 0.10.6", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ "proc-macro-crate", "proc-macro-error", @@ -5096,9 +5190,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.27.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462fffe4002f4f2e1f6a9dcf12cc1a6fc0e15989014efc02a941d3e0f5dc2120" +checksum = "f6515c882ebfddccaa73ead7320ca28036c4bc84c9bcca3cc0cbba8efe89223a" dependencies = [ "approx", "matrixmultiply", @@ -5106,17 +5200,15 @@ dependencies = [ "num-complex", "num-rational", "num-traits", - "rand 0.8.5", - "rand_distr", "simba", "typenum", ] [[package]] name = "nalgebra-macros" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" +checksum = "d232c68884c0c99810a5a4d333ef7e47689cfd0edc85efc9e54e1e6bf5212766" dependencies = [ "proc-macro2", "quote", @@ -5178,9 +5270,9 @@ dependencies = [ [[package]] name = "netlink-packet-utils" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25af9cf0dc55498b7bd94a1508af7a78706aa0ab715a73c5169273e03c84845e" +checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" dependencies = [ "anyhow", "byteorder", @@ -5205,9 +5297,9 @@ dependencies = [ [[package]] name = "netlink-sys" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92b654097027250401127914afb37cb1f311df6610a9891ff07a757e94199027" +checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" dependencies = [ "bytes", "futures", @@ -5234,6 +5326,20 @@ dependencies = [ "memoffset 0.6.5", ] +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", + "static_assertions", +] + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -5328,6 +5434,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -5341,7 +5468,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "crc32fast", - "hashbrown", + "hashbrown 0.12.3", "indexmap", "memchr", ] @@ -5375,9 +5502,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -5398,7 +5525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" dependencies = [ "arrayvec 0.7.2", - "auto_impl 1.0.1", + "auto_impl", "bytes", "ethereum-types", "open-fastrlp-derive", @@ -5502,7 +5629,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-benchmarking", "frame-support", @@ -5517,7 +5644,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-benchmarking", "frame-support", @@ -5532,7 +5659,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-support", "frame-system", @@ -5566,7 +5693,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-benchmarking", "frame-support", @@ -5584,7 +5711,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-support", "frame-system", @@ -5600,7 +5727,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -5616,7 +5743,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -5627,9 +5754,9 @@ dependencies = [ [[package]] name = "parity-db" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a7511a0bec4a336b5929999d02b560d2439c993cccf98c26481484e811adc43" +checksum = "df89dd8311063c54ae4e03d9aeb597b04212a57e82c339344130a9cad9b3e2d9" dependencies = [ "blake2", "crc32fast", @@ -5641,14 +5768,15 @@ dependencies = [ "memmap2", "parking_lot 0.12.1", "rand 0.8.5", + "siphasher", "snap", ] [[package]] name = "parity-scale-codec" -version = "3.2.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ab01d0f889e957861bc65888d5ccbe82c158d0270136ba46820d43837cdf72" +checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" dependencies = [ "arrayvec 0.7.2", "bitvec 1.0.1", @@ -5707,7 +5835,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.6", + "parking_lot_core 0.9.7", ] [[package]] @@ -5726,15 +5854,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -5750,9 +5878,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "path-slash" @@ -5813,9 +5941,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.3" +version = "2.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4257b4a04d91f7e9e6290be5d3da4804dd5784fafde3a497d73eb2b4a158c30a" +checksum = "8cbd939b234e95d72bc393d51788aec68aeeb5d51e748ca08ff3aad58cb722f7" dependencies = [ "thiserror", "ucd-trie", @@ -5823,9 +5951,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.5.3" +version = "2.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241cda393b0cdd65e62e07e12454f1f25d57017dcc514b1514cd3c4645e3a0a6" +checksum = "a81186863f3d0a27340815be8f2078dd8050b14cd71913db9fbda795e5f707d7" dependencies = [ "pest", "pest_generator", @@ -5833,9 +5961,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.3" +version = "2.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46b53634d8c8196302953c74d5352f33d0c512a9499bd2ce468fc9f4128fa27c" +checksum = "75a1ef20bf3193c15ac345acb32e26b3dc3223aff4d77ae4fc5359567683796b" dependencies = [ "pest", "pest_meta", @@ -5846,9 +5974,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.5.3" +version = "2.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef4f1332a8d4678b41966bb4cc1d0676880e84183a1ecc3f4b69f03e99c7a51" +checksum = "5e3b284b1f13a20dc5ebc90aff59a51b8d7137c221131b52a7260c08cbc1cc80" dependencies = [ "once_cell", "pest", @@ -5857,9 +5985,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", "indexmap", @@ -5877,34 +6005,32 @@ dependencies = [ [[package]] name = "phf" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" dependencies = [ "phf_macros", - "phf_shared", - "proc-macro-hack", + "phf_shared 0.11.1", ] [[package]] name = "phf_generator" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" dependencies = [ - "phf_shared", + "phf_shared 0.11.1", "rand 0.8.5", ] [[package]] name = "phf_macros" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" dependencies = [ "phf_generator", - "phf_shared", - "proc-macro-hack", + "phf_shared 0.11.1", "proc-macro2", "quote", "syn", @@ -5919,6 +6045,15 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", +] + [[package]] name = "pico-args" version = "0.4.2" @@ -6013,18 +6148,7 @@ checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ "cpufeatures", "opaque-debug 0.3.0", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" -dependencies = [ - "cpuid-bool", - "opaque-debug 0.3.0", - "universal-hash", + "universal-hash 0.4.1", ] [[package]] @@ -6036,7 +6160,19 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug 0.3.0", - "universal-hash", + "universal-hash 0.4.1", +] + +[[package]] +name = "polyval" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash 0.5.0", ] [[package]] @@ -6083,9 +6219,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78" +checksum = "4ebcd279d20a4a0a2404a33056388e950504d891c855c7975b9a8fef75f3bf04" dependencies = [ "proc-macro2", "syn", @@ -6107,11 +6243,10 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.2.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "once_cell", "thiserror", "toml", ] @@ -6140,17 +6275,11 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] @@ -6194,9 +6323,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" +checksum = "e48e50df39172a3e7eb17e14642445da64996989bc212b583015435d39a58537" dependencies = [ "bytes", "prost-derive", @@ -6204,12 +6333,12 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f8ad728fb08fe212df3c05169e940fbb6d9d16a877ddde14644a983ba2012e" +checksum = "2c828f93f5ca4826f97fedcbd3f9a536c16b12cff3dbbb4a007f932bbad95b12" dependencies = [ "bytes", - "heck 0.4.0", + "heck 0.4.1", "itertools", "lazy_static", "log", @@ -6239,9 +6368,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" +checksum = "4ea9b0f8cbe5e15a8a042d030bd96668db28ecb567ec37d691971ff5731d2b1b" dependencies = [ "anyhow", "itertools", @@ -6252,11 +6381,10 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" +checksum = "379119666929a1afd7a043aa6cf96fa67a6dce9af60c88095a4686dbce4c9c88" dependencies = [ - "bytes", "prost", ] @@ -6423,9 +6551,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" dependencies = [ "either", "rayon-core", @@ -6433,9 +6561,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -6451,7 +6579,7 @@ checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", "ring", - "time 0.3.17", + "time 0.3.20", "x509-parser 0.13.2", "yasna", ] @@ -6464,7 +6592,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", - "time 0.3.17", + "time 0.3.20", "yasna", ] @@ -6490,18 +6618,18 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c78fb8c9293bcd48ef6fce7b4ca950ceaf21210de6e105a883ee280c0f7b9ed" +checksum = "a9af2cf09ef80e610097515e80095b7f76660a92743c4185aff5406cd5ce3dd5" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9c0c92af03644e4806106281fe2e068ac5bc0ae74a707266d06ea27bccee5f" +checksum = "9c501201393982e275433bc55de7d6ae6f00e7699cd5572c5b57581cd69c881b" dependencies = [ "proc-macro2", "quote", @@ -6510,9 +6638,9 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.3.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ "fxhash", "log", @@ -6547,11 +6675,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "region" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" dependencies = [ + "bitflags", + "libc", + "mach", "winapi", ] @@ -6706,7 +6837,7 @@ dependencies = [ "log", "netlink-packet-route", "netlink-proto", - "nix", + "nix 0.24.3", "thiserror", "tokio", ] @@ -6773,30 +6904,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.35.13" +version = "0.36.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727a1a6d65f786ec22df8a81ca3121107f235970dc1705ed681d3e6e8b9cd5f9" +checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" dependencies = [ "bitflags", "errno", - "io-lifetimes 0.7.5", + "io-lifetimes", "libc", - "linux-raw-sys 0.0.46", - "windows-sys 0.42.0", -] - -[[package]] -name = "rustix" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes 1.0.4", - "libc", - "linux-raw-sys 0.1.4", - "windows-sys 0.42.0", + "linux-raw-sys", + "windows-sys 0.45.0", ] [[package]] @@ -6847,9 +6964,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "rw-stream-sink" @@ -6864,9 +6981,18 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "safe_arch" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794821e4ccb0d9f979512f9c1973480123f9bd62a90d74ab0f9426fcf8f4a529" +dependencies = [ + "bytemuck", +] [[package]] name = "salsa20" @@ -6889,7 +7015,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "log", "sp-core", @@ -6900,7 +7026,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "futures", "futures-timer", @@ -6923,7 +7049,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -6939,7 +7065,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "memmap2", "sc-chain-spec-derive", @@ -6954,7 +7080,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6965,11 +7091,11 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "chrono", - "clap 4.1.1", + "clap 4.1.8", "fdlimit", "futures", "libp2p", @@ -7005,7 +7131,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "fnv", "futures", @@ -7031,7 +7157,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "hash-db", "kvdb", @@ -7044,6 +7170,7 @@ dependencies = [ "parking_lot 0.12.1", "sc-client-api", "sc-state-db", + "schnellru", "sp-arithmetic", "sp-blockchain", "sp-core", @@ -7056,7 +7183,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "futures", @@ -7081,7 +7208,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "lru", "parity-scale-codec", @@ -7105,7 +7232,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", @@ -7118,7 +7245,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "log", "sc-allocator", @@ -7131,13 +7258,14 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ + "anyhow", "cfg-if", "libc", "log", "once_cell", - "rustix 0.35.13", + "rustix", "sc-allocator", "sc-executor-common", "sp-runtime-interface", @@ -7148,7 +7276,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "ansi_term", "futures", @@ -7163,7 +7291,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "async-trait", @@ -7178,7 +7306,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "async-trait", @@ -7193,6 +7321,7 @@ dependencies = [ "libp2p", "log", "lru", + "mockall", "parity-scale-codec", "parking_lot 0.12.1", "pin-project", @@ -7220,7 +7349,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "cid", "futures", @@ -7239,7 +7368,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "bitflags", @@ -7265,9 +7394,9 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ - "ahash", + "ahash 0.8.3", "futures", "futures-timer", "libp2p", @@ -7283,7 +7412,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "futures", @@ -7304,7 +7433,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "async-trait", @@ -7336,7 +7465,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "futures", @@ -7355,7 +7484,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "bytes", @@ -7385,7 +7514,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "futures", "libp2p", @@ -7398,7 +7527,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -7407,7 +7536,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "futures", "jsonrpsee", @@ -7431,12 +7560,13 @@ dependencies = [ "sp-runtime", "sp-session", "sp-version", + "tokio", ] [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -7455,7 +7585,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "http", "jsonrpsee", @@ -7470,7 +7600,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "futures", @@ -7496,7 +7626,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "directories", @@ -7527,6 +7657,7 @@ dependencies = [ "sc-rpc", "sc-rpc-server", "sc-rpc-spec-v2", + "sc-storage-monitor", "sc-sysinfo", "sc-telemetry", "sc-tracing", @@ -7561,7 +7692,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "log", "parity-scale-codec", @@ -7569,10 +7700,26 @@ dependencies = [ "sp-core", ] +[[package]] +name = "sc-storage-monitor" +version = "0.1.0" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +dependencies = [ + "clap 4.1.8", + "futures", + "log", + "nix 0.26.2", + "sc-client-db", + "sc-utils", + "sp-core", + "thiserror", + "tokio", +] + [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "futures", "libc", @@ -7591,7 +7738,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "chrono", "futures", @@ -7640,7 +7787,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "ansi_term", "atty", @@ -7671,7 +7818,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7682,13 +7829,14 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "futures", "futures-timer", "linked-hash-map", "log", + "num-traits", "parity-scale-codec", "parking_lot 0.12.1", "sc-client-api", @@ -7708,7 +7856,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "futures", @@ -7722,7 +7870,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "backtrace", "futures", @@ -7808,6 +7956,17 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "schnellru" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" +dependencies = [ + "ahash 0.8.3", + "cfg-if", + "hashbrown 0.13.2", +] + [[package]] name = "schnorr-signatures" version = "0.2.0" @@ -7848,9 +8007,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scratch" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" [[package]] name = "scrypt" @@ -7954,9 +8113,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645926f31b250a2dca3c232496c2d898d91036e45ca0e97e0e2390c54e11be36" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", @@ -8001,9 +8160,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "send_wrapper" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serai-client" @@ -8028,7 +8187,7 @@ name = "serai-node" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.1.1", + "clap 4.1.8", "frame-benchmarking", "frame-benchmarking-cli", "in-instructions-client", @@ -8173,9 +8332,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" dependencies = [ "itoa", "ryu", @@ -8281,9 +8440,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[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", ] @@ -8300,14 +8459,15 @@ dependencies = [ [[package]] name = "simba" -version = "0.5.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e82063457853d00243beda9952e910b82593e4b07ae9f721b9278a99a0d3d5c" +checksum = "50582927ed6f77e4ac020c057f37a268fc6aebc29225050365aacbb9deeeddc4" dependencies = [ "approx", "num-complex", "num-traits", "paste", + "wide", ] [[package]] @@ -8318,9 +8478,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -8345,14 +8505,14 @@ checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" [[package]] name = "snow" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774d05a3edae07ce6d68ea6984f3c05e9bba8927e3dd591e3b479e5b03213d0d" +checksum = "12ba5f4d4ff12bdb6a169ed51b7c48c0e0ac4b0b4b31012b2571e97d78d3201d" dependencies = [ "aes-gcm 0.9.4", "blake2", "chacha20poly1305", - "curve25519-dalek 4.0.0-pre.5", + "curve25519-dalek 4.0.0-rc.0", "rand_core 0.6.4", "ring", "rustc_version", @@ -8362,9 +8522,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -8389,9 +8549,9 @@ dependencies = [ [[package]] name = "solang-parser" -version = "0.1.18" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac8ac4bfef383f368bd9bb045107a501cd9cd0b64ad1983e1b7e839d6a44ecad" +checksum = "58feb14d4002859db0b744b0915840bae403b8a5675efded3e8adddb6beb85b2" dependencies = [ "itertools", "lalrpop", @@ -8403,7 +8563,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "hash-db", "log", @@ -8421,7 +8581,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "blake2", "proc-macro-crate", @@ -8433,7 +8593,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "scale-info", @@ -8446,7 +8606,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "integer-sqrt", "num-traits", @@ -8460,7 +8620,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "sp-api", @@ -8472,7 +8632,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "futures", "log", @@ -8490,7 +8650,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "futures", @@ -8508,12 +8668,13 @@ dependencies = [ [[package]] name = "sp-core" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "array-bytes", "base58 0.2.0", "bitflags", "blake2", + "bounded-collections", "dyn-clonable", "ed25519-zebra", "futures", @@ -8550,7 +8711,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "blake2", "byteorder", @@ -8564,7 +8725,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "proc-macro2", "quote", @@ -8575,7 +8736,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -8584,7 +8745,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "proc-macro2", "quote", @@ -8594,7 +8755,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "environmental", "parity-scale-codec", @@ -8605,7 +8766,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "finality-grandpa", "log", @@ -8623,11 +8784,12 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "impl-trait-for-tuples", "parity-scale-codec", + "scale-info", "sp-core", "sp-runtime", "sp-std", @@ -8637,7 +8799,7 @@ dependencies = [ [[package]] name = "sp-io" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "bytes", "ed25519", @@ -8662,7 +8824,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "lazy_static", "sp-core", @@ -8673,7 +8835,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "futures", @@ -8690,7 +8852,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "thiserror", "zstd", @@ -8699,7 +8861,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "sp-api", "sp-core", @@ -8709,7 +8871,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "backtrace", "lazy_static", @@ -8719,7 +8881,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "rustc-hash", "serde", @@ -8729,7 +8891,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "either", "hash256-std-hasher", @@ -8751,7 +8913,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -8769,7 +8931,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "Inflector", "proc-macro-crate", @@ -8781,7 +8943,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "scale-info", @@ -8795,7 +8957,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "scale-info", @@ -8807,7 +8969,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "hash-db", "log", @@ -8827,12 +8989,12 @@ dependencies = [ [[package]] name = "sp-std" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" [[package]] name = "sp-storage" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8854,7 +9016,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "futures-timer", @@ -8869,7 +9031,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "sp-std", @@ -8881,7 +9043,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "sp-api", "sp-runtime", @@ -8890,7 +9052,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "async-trait", "log", @@ -8906,18 +9068,18 @@ dependencies = [ [[package]] name = "sp-trie" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ - "ahash", + "ahash 0.8.3", "hash-db", - "hashbrown", + "hashbrown 0.12.3", "lazy_static", - "lru", "memory-db", "nohash-hasher", "parity-scale-codec", "parking_lot 0.12.1", "scale-info", + "schnellru", "sp-core", "sp-std", "thiserror", @@ -8929,7 +9091,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8946,7 +9108,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -8957,8 +9119,9 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ + "anyhow", "impl-trait-for-tuples", "log", "parity-scale-codec", @@ -8970,7 +9133,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "parity-scale-codec", "scale-info", @@ -9000,9 +9163,9 @@ dependencies = [ [[package]] name = "ss58-registry" -version = "1.37.0" +version = "1.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d44528162f980c0e03c71e005d334332c8da0aec9f2b0b4bdc557ed4a9f24776" +checksum = "ecf0bd63593ef78eca595a7fc25e9a443ca46fe69fd472f8f09f5245cdcd769d" dependencies = [ "Inflector", "num-format", @@ -9053,29 +9216,16 @@ dependencies = [ "syn", ] -[[package]] -name = "statrs" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05bdbb8e4e78216a85785a85d3ec3183144f98d0097b9281802c019bb07a6f05" -dependencies = [ - "approx", - "lazy_static", - "nalgebra", - "num-traits", - "rand 0.8.5", -] - [[package]] name = "string_cache" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" +checksum = "7d69e88b23f23030bf4d0e9ca7b07434f70e1c1f4d3ca7e93ce958b373654d9f" dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot 0.12.1", - "phf_shared", + "phf_shared 0.10.0", "precomputed-hash", ] @@ -9100,7 +9250,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck 0.4.0", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -9142,7 +9292,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "platforms 2.0.0", ] @@ -9150,7 +9300,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -9169,7 +9319,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "hyper", "log", @@ -9181,11 +9331,11 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#ffc7ad1791f90147a3f14f4305134dbc6f8e1d76" +source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" dependencies = [ "ansi_term", "build-helper", - "cargo_metadata 0.14.2", + "cargo_metadata", "filetime", "sp-maybe-compressed-blob", "strum", @@ -9246,7 +9396,7 @@ checksum = "7722c31febf55eb300c73d977da5d65cfd6fb443419b1185b9abcdd9925fd7be" dependencies = [ "darling", "frame-metadata", - "heck 0.4.0", + "heck 0.4.1", "hex", "jsonrpsee", "parity-scale-codec", @@ -9285,9 +9435,9 @@ dependencies = [ [[package]] name = "svm-rs" -version = "0.2.19" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e18bbb2b229a2cc0d8ba58603adb0e460ad49a3451b1540fd6f7a5d37fd03b80" +checksum = "01afefe60c02f4a2271fb15d1965c37856712cebb338330b06649d12afec42df" dependencies = [ "anyhow", "cfg-if", @@ -9316,9 +9466,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -9366,22 +9516,21 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" [[package]] name = "tempfile" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.42.0", ] [[package]] @@ -9441,18 +9590,18 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" dependencies = [ "proc-macro2", "quote", @@ -9467,10 +9616,11 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if", "once_cell", ] @@ -9485,12 +9635,11 @@ dependencies = [ [[package]] name = "tikv-jemalloc-sys" -version = "0.5.2+5.3.0-patched" +version = "0.5.3+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec45c14da997d0925c7835883e4d5c181f196fa142f8c19d7643d1e9af2592c3" +checksum = "a678df20055b43e57ef8cddde41cdfda9a3c1a060b67f4c5836dfb1d78543ba8" dependencies = [ "cc", - "fs_extra", "libc", ] @@ -9507,9 +9656,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.17" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" dependencies = [ "itoa", "serde", @@ -9525,9 +9674,9 @@ checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" [[package]] name = "time-macros" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" dependencies = [ "time-core", ] @@ -9581,9 +9730,9 @@ dependencies = [ [[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 = "tokens-pallet" @@ -9611,9 +9760,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.24.2" +version = "1.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" +checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" dependencies = [ "autocfg", "bytes", @@ -9626,7 +9775,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -9642,9 +9791,9 @@ dependencies = [ [[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", @@ -9675,9 +9824,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" dependencies = [ "futures-core", "pin-project-lite 0.2.9", @@ -9687,9 +9836,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" dependencies = [ "bytes", "futures-core", @@ -9840,12 +9989,12 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.24.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004e1e8f92535694b4cb1444dc5a8073ecf0815e3357f729638b9f8fc4062908" +checksum = "3390c0409daaa6027d6681393316f4ccd3ff82e1590a1e4725014e3ae2bf1920" dependencies = [ "hash-db", - "hashbrown", + "hashbrown 0.13.2", "log", "rustc-hex", "smallvec", @@ -9981,9 +10130,9 @@ checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -9996,9 +10145,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" @@ -10022,6 +10171,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "universal-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "unsigned-varint" version = "0.7.1" @@ -10063,9 +10222,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.2.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ "getrandom 0.2.8", ] @@ -10171,9 +10330,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -10181,9 +10340,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", @@ -10196,9 +10355,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ "cfg-if", "js-sys", @@ -10208,9 +10367,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10218,9 +10377,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", @@ -10231,9 +10390,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "wasm-instrument" @@ -10246,9 +10405,9 @@ dependencies = [ [[package]] name = "wasm-opt" -version = "0.110.2" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68e8037b4daf711393f4be2056246d12d975651b14d581520ad5d1f19219cec" +checksum = "84a303793cbc01fb96551badfc7367db6007396bba6bac97936b3c8b6f7fdb41" dependencies = [ "anyhow", "libc", @@ -10262,9 +10421,9 @@ dependencies = [ [[package]] name = "wasm-opt-cxx-sys" -version = "0.110.2" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91adbad477e97bba3fbd21dd7bfb594e7ad5ceb9169ab1c93ab9cb0ada636b6f" +checksum = "d9c9deb56f8a9f2ec177b3bd642a8205621835944ed5da55f2388ef216aca5a4" dependencies = [ "anyhow", "cxx", @@ -10274,9 +10433,9 @@ dependencies = [ [[package]] name = "wasm-opt-sys" -version = "0.110.2" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4fa5a322a4e6ac22fd141f498d56afbdbf9df5debeac32380d2dcaa3e06941" +checksum = "4432e28b542738a9776cedf92e8a99d8991c7b4667ee2c7ccddfb479dd2856a7" dependencies = [ "anyhow", "cc", @@ -10331,22 +10490,24 @@ dependencies = [ "memory_units", "num-rational", "num-traits", + "region", ] [[package]] name = "wasmparser" -version = "0.89.1" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5d3e08b13876f96dd55608d03cd4883a0545884932d5adf11925876c96daef" +checksum = "64b20236ab624147dfbb62cf12a19aaf66af0e41b8398838b66e997d07d269d4" dependencies = [ "indexmap", + "url", ] [[package]] name = "wasmtime" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad5af6ba38311282f2a21670d96e78266e8c8e2f38cbcd52c254df6ccbc7731" +checksum = "9010891d0b8e367c3be94ca35d7bc25c1de3240463bb1d61bcfc8c2233c4e0d0" dependencies = [ "anyhow", "bincode", @@ -10367,23 +10528,23 @@ dependencies = [ "wasmtime-environ", "wasmtime-jit", "wasmtime-runtime", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] name = "wasmtime-asm-macros" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45de63ddfc8b9223d1adc8f7b2ee5f35d1f6d112833934ad7ea66e4f4339e597" +checksum = "65805c663eaa8257b910666f6d4b056b5c7329750da754ba5df54f3af7dbf35c" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-cache" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd849399d17d2270141cfe47fa0d91ee52d5f8ea9b98cf7ddde0d53e5f79882" +checksum = "2049ddfc1b10efc3c5591d0e84b9570ca50478f8818f3bfabb1a467918f53fb4" dependencies = [ "anyhow", "base64 0.13.1", @@ -10391,19 +10552,19 @@ dependencies = [ "directories-next", "file-per-thread-logger", "log", - "rustix 0.35.13", + "rustix", "serde", - "sha2 0.9.9", + "sha2 0.10.6", "toml", - "windows-sys 0.36.1", + "windows-sys 0.42.0", "zstd", ] [[package]] name = "wasmtime-cranelift" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd91339b742ff20bfed4532a27b73c86b5bcbfedd6bea2dcdf2d64471e1b5c6" +checksum = "3f9065cad6a724fa838ec8497567e0b23acc26417bb2449f8d9d2021925c72f2" dependencies = [ "anyhow", "cranelift-codegen", @@ -10422,9 +10583,9 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb881c61f4f627b5d45c54e629724974f8a8890d455bcbe634330cc27309644" +checksum = "4f964bb0b91fa021b8d1b488c62cc77b346c1dae6e3ebd010050b57c1f2ca657" dependencies = [ "anyhow", "cranelift-entity", @@ -10441,9 +10602,9 @@ dependencies = [ [[package]] name = "wasmtime-jit" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1985c628011fe26adf5e23a5301bdc79b245e0e338f14bb58b39e4e25e4d8681" +checksum = "b7a1d06f5d109539e0168fc74fa65e3948ac8dac3bb8cdbd08b62b36a0ae27b8" dependencies = [ "addr2line 0.17.0", "anyhow", @@ -10454,32 +10615,42 @@ dependencies = [ "log", "object 0.29.0", "rustc-demangle", - "rustix 0.35.13", "serde", "target-lexicon", - "thiserror", "wasmtime-environ", "wasmtime-jit-debug", + "wasmtime-jit-icache-coherence", "wasmtime-runtime", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] name = "wasmtime-jit-debug" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f671b588486f5ccec8c5a3dba6b4c07eac2e66ab8c60e6f4e53717c77f709731" +checksum = "f76ef2e410329aaf8555ac6571d6fe07711be0646dcdf7ff3ab750a42ed2e583" dependencies = [ "object 0.29.0", "once_cell", - "rustix 0.35.13", + "rustix", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1fd0f0dd79e7cc0f55b102e320d7c77ab76cd272008a8fd98e25b5777e2636" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.42.0", ] [[package]] name = "wasmtime-runtime" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8f92ad4b61736339c29361da85769ebc200f184361959d1792832e592a1afd" +checksum = "271aef9b4ca2e953a866293683f2db33cda46f6933c5e431e68d8373723d4ab6" dependencies = [ "anyhow", "cc", @@ -10492,19 +10663,18 @@ dependencies = [ "memoffset 0.6.5", "paste", "rand 0.8.5", - "rustix 0.35.13", - "thiserror", + "rustix", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] name = "wasmtime-types" -version = "1.0.2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23d61cb4c46e837b431196dd06abb11731541021916d03476a178b54dc07aeb" +checksum = "b18144b0e45479a830ac9fcebfc71a16d90dc72d8ebd5679700eb3bfe974d7df" dependencies = [ "cranelift-entity", "serde", @@ -10514,9 +10684,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" dependencies = [ "js-sys", "wasm-bindgen", @@ -10577,7 +10747,7 @@ dependencies = [ "sha2 0.10.6", "stun", "thiserror", - "time 0.3.17", + "time 0.3.20", "tokio", "turn", "url", @@ -10609,12 +10779,12 @@ dependencies = [ [[package]] name = "webrtc-dtls" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7021987ae0a2ed6c8cd33f68e98e49bb6e74ffe9543310267b48a1bbe3900e5f" +checksum = "942be5bd85f072c3128396f6e5a9bfb93ca8c1939ded735d177b7bcba9a13d05" dependencies = [ "aes 0.6.0", - "aes-gcm 0.8.0", + "aes-gcm 0.10.1", "async-trait", "bincode", "block-modes", @@ -10624,7 +10794,7 @@ dependencies = [ "der-parser 8.1.0", "elliptic-curve", "hkdf", - "hmac 0.10.1", + "hmac 0.12.1", "log", "oid-registry 0.6.1", "p256", @@ -10636,8 +10806,8 @@ dependencies = [ "rustls 0.19.1", "sec1", "serde", - "sha-1", - "sha2 0.9.9", + "sha1", + "sha2 0.10.6", "signature", "subtle", "thiserror", @@ -10650,9 +10820,9 @@ dependencies = [ [[package]] name = "webrtc-ice" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494483fbb2f5492620871fdc78b084aed8807377f6e3fe88b2e49f0a9c9c41d7" +checksum = "465a03cc11e9a7d7b4f9f99870558fe37a102b65b93f8045392fef7c67b39e80" dependencies = [ "arc-swap", "async-trait", @@ -10666,7 +10836,7 @@ dependencies = [ "tokio", "turn", "url", - "uuid 1.2.2", + "uuid 1.3.0", "waitgroup", "webrtc-mdns", "webrtc-util", @@ -10756,7 +10926,7 @@ dependencies = [ "lazy_static", "libc", "log", - "nix", + "nix 0.24.3", "rand 0.8.5", "thiserror", "tokio", @@ -10783,6 +10953,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "wide" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b689b6c49d6549434bf944e6b0f39238cf63693cb7a147e9d887507fffa3b223" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "widestring" version = "0.5.1" @@ -10835,22 +11015,33 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", ] [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc 0.42.1", @@ -10873,12 +11064,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - [[package]] name = "windows_aarch64_msvc" version = "0.42.1" @@ -10891,12 +11076,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - [[package]] name = "windows_i686_gnu" version = "0.42.1" @@ -10909,12 +11088,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - [[package]] name = "windows_i686_msvc" version = "0.42.1" @@ -10927,12 +11100,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - [[package]] name = "windows_x86_64_gnu" version = "0.42.1" @@ -10951,12 +11118,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - [[package]] name = "windows_x86_64_msvc" version = "0.42.1" @@ -10974,13 +11135,14 @@ dependencies = [ [[package]] name = "ws_stream_wasm" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47ca1ab42f5afed7fc332b22b6e932ca5414b209465412c8cdf0ad23bc0de645" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" dependencies = [ "async_io_stream", "futures", "js-sys", + "log", "pharos", "rustc_version", "send_wrapper", @@ -11037,7 +11199,7 @@ dependencies = [ "ring", "rusticata-macros", "thiserror", - "time 0.3.17", + "time 0.3.20", ] [[package]] @@ -11055,7 +11217,7 @@ dependencies = [ "oid-registry 0.6.1", "rusticata-macros", "thiserror", - "time 0.3.17", + "time 0.3.20", ] [[package]] @@ -11090,7 +11252,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aed2e7a52e3744ab4d0c05c20aa065258e84c49fd4226f5191b2ed29712710b4" dependencies = [ - "time 0.3.17", + "time 0.3.20", ] [[package]] @@ -11123,9 +11285,9 @@ dependencies = [ [[package]] name = "zip" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080" +checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef" dependencies = [ "aes 0.7.5", "byteorder", @@ -11137,7 +11299,7 @@ dependencies = [ "hmac 0.12.1", "pbkdf2 0.11.0", "sha1", - "time 0.3.17", + "time 0.3.20", "zstd", ] @@ -11162,9 +11324,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.5+zstd.1.5.2" +version = "2.0.7+zstd.1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc50ffce891ad571e9f9afe5039c4837bede781ac4bb13052ed7ae695518596" +checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" dependencies = [ "cc", "libc", From 4a81640ab8983158f746823c02e57f36f045a9ef Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 6 Mar 2023 08:14:22 -0500 Subject: [PATCH 60/74] Update runtime to latest substrate --- substrate/runtime/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index cd5c6c91..bf402cfe 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -437,5 +437,13 @@ sp_api::impl_runtime_apis! { ) -> transaction_payment::FeeDetails { TransactionPayment::query_fee_details(uxt, len) } + + fn query_weight_to_fee(weight: Weight) -> SubstrateAmount { + TransactionPayment::weight_to_fee(weight) + } + + fn query_length_to_fee(length: u32) -> SubstrateAmount { + TransactionPayment::length_to_fee(length) + } } } From db1fefe7c1a7ed79e674d7f0b108a952ba9d318a Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 6 Mar 2023 08:20:01 -0500 Subject: [PATCH 61/74] Update tendermint/node to latest substrate --- substrate/node/src/service.rs | 2 +- substrate/tendermint/client/src/tendermint.rs | 4 ++-- substrate/tendermint/client/src/validators.rs | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/substrate/node/src/service.rs b/substrate/node/src/service.rs index d4a6b4f9..24457e29 100644 --- a/substrate/node/src/service.rs +++ b/substrate/node/src/service.rs @@ -202,7 +202,7 @@ pub async fn new_full(mut config: Configuration) -> Result TendermintImport { let err = self .client .runtime_api() - .check_inherents(&BlockId::Hash(self.client.info().finalized_hash), block, inherent_data) + .check_inherents(self.client.info().finalized_hash, block, inherent_data) .map_err(|_| Error::Other(BlockError::Fatal.into()))?; if err.ok() { diff --git a/substrate/tendermint/client/src/validators.rs b/substrate/tendermint/client/src/validators.rs index d60f179e..c38b2f29 100644 --- a/substrate/tendermint/client/src/validators.rs +++ b/substrate/tendermint/client/src/validators.rs @@ -11,7 +11,7 @@ use sp_application_crypto::{ use sp_keystore::CryptoStore; use sp_staking::SessionIndex; -use sp_api::{BlockId, ProvideRuntimeApi}; +use sp_api::ProvideRuntimeApi; use sc_client_api::HeaderBackend; @@ -34,8 +34,8 @@ impl TendermintValidatorsStruct { fn from_module(client: &Arc) -> Self { let last = client.info().finalized_hash; let api = client.runtime_api(); - let session = api.current_session(&BlockId::Hash(last)).unwrap(); - let validators = api.validators(&BlockId::Hash(last)).unwrap(); + let session = api.current_session(last).unwrap(); + let validators = api.validators(last).unwrap(); Self { session, @@ -59,8 +59,7 @@ impl Refresh { // If the session has changed, re-create the struct with the data on it fn refresh(&self) { let session = self._refresh.read().unwrap().session; - let current_block = BlockId::Hash(self.client.info().finalized_hash); - if session != self.client.runtime_api().current_session(¤t_block).unwrap() { + if session != self.client.runtime_api().current_session(self.client.info().finalized_hash).unwrap() { *self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module::(&self.client); } } From 8307d4f6c8a8ecc20a9dbc4a8cbfb8f7f292b03b Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 6 Mar 2023 08:23:14 -0500 Subject: [PATCH 62/74] cargo fmt --- substrate/tendermint/client/src/validators.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/substrate/tendermint/client/src/validators.rs b/substrate/tendermint/client/src/validators.rs index c38b2f29..9bd0b338 100644 --- a/substrate/tendermint/client/src/validators.rs +++ b/substrate/tendermint/client/src/validators.rs @@ -59,7 +59,9 @@ impl Refresh { // If the session has changed, re-create the struct with the data on it fn refresh(&self) { let session = self._refresh.read().unwrap().session; - if session != self.client.runtime_api().current_session(self.client.info().finalized_hash).unwrap() { + if session != + self.client.runtime_api().current_session(self.client.info().finalized_hash).unwrap() + { *self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module::(&self.client); } } From 77de28f77a940882670f4d51bd5628132d35be40 Mon Sep 17 00:00:00 2001 From: akildemir <34187742+akildemir@users.noreply.github.com> Date: Fri, 10 Mar 2023 22:16:00 +0300 Subject: [PATCH 63/74] add monero seed support (#252) * add monero seed support * fix some of the pr comments * remove languages module and unnecessary error returns * Clean classic seed impl Fixes a few issues regarding Zeroize usage/API safety. Mainly a cleanup. --------- Co-authored-by: Luke Parker --- Cargo.lock | 1 + coins/monero/Cargo.toml | 1 + coins/monero/src/tests/mod.rs | 1 + coins/monero/src/tests/seed.rs | 177 ++ coins/monero/src/wallet/mod.rs | 3 + coins/monero/src/wallet/seed/classic.rs | 262 +++ coins/monero/src/wallet/seed/classic/ang.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/de.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/en.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/eo.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/es.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/fr.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/it.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/ja.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/jbo.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/nl.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/pt.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/ru.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/classic/zh.json | 1628 +++++++++++++++++ coins/monero/src/wallet/seed/mod.rs | 92 + 20 files changed, 21701 insertions(+) create mode 100644 coins/monero/src/tests/seed.rs create mode 100644 coins/monero/src/wallet/seed/classic.rs create mode 100644 coins/monero/src/wallet/seed/classic/ang.json create mode 100644 coins/monero/src/wallet/seed/classic/de.json create mode 100644 coins/monero/src/wallet/seed/classic/en.json create mode 100644 coins/monero/src/wallet/seed/classic/eo.json create mode 100644 coins/monero/src/wallet/seed/classic/es.json create mode 100644 coins/monero/src/wallet/seed/classic/fr.json create mode 100644 coins/monero/src/wallet/seed/classic/it.json create mode 100644 coins/monero/src/wallet/seed/classic/ja.json create mode 100644 coins/monero/src/wallet/seed/classic/jbo.json create mode 100644 coins/monero/src/wallet/seed/classic/nl.json create mode 100644 coins/monero/src/wallet/seed/classic/pt.json create mode 100644 coins/monero/src/wallet/seed/classic/ru.json create mode 100644 coins/monero/src/wallet/seed/classic/zh.json create mode 100644 coins/monero/src/wallet/seed/mod.rs diff --git a/Cargo.lock b/Cargo.lock index a97d3c4d..8e088349 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5037,6 +5037,7 @@ name = "monero-serai" version = "0.1.2-alpha" dependencies = [ "base58-monero", + "crc", "curve25519-dalek 3.2.0", "dalek-ff-group", "digest_auth", diff --git a/coins/monero/Cargo.toml b/coins/monero/Cargo.toml index 9aa30105..fb480b9f 100644 --- a/coins/monero/Cargo.toml +++ b/coins/monero/Cargo.toml @@ -15,6 +15,7 @@ rustdoc-args = ["--cfg", "docsrs"] hex-literal = "0.3" lazy_static = "1" thiserror = "1" +crc = "3" rand_core = "0.6" rand_chacha = { version = "0.3", optional = true } diff --git a/coins/monero/src/tests/mod.rs b/coins/monero/src/tests/mod.rs index f92473c4..835b77ca 100644 --- a/coins/monero/src/tests/mod.rs +++ b/coins/monero/src/tests/mod.rs @@ -1,3 +1,4 @@ mod clsag; mod bulletproofs; mod address; +mod seed; diff --git a/coins/monero/src/tests/seed.rs b/coins/monero/src/tests/seed.rs new file mode 100644 index 00000000..96bd176d --- /dev/null +++ b/coins/monero/src/tests/seed.rs @@ -0,0 +1,177 @@ +use zeroize::Zeroizing; + +use rand_core::OsRng; + +use curve25519_dalek::scalar::Scalar; + +use crate::{ + hash, + wallet::seed::{Seed, Language, classic::trim_by_lang}, +}; + +#[test] +fn test_classic_seed() { + struct Vector { + language: Language, + seed: String, + spend: String, + view: String, + } + + let vectors = [ + Vector { + language: Language::Chinese, + seed: "摇 曲 艺 武 滴 然 效 似 赏 式 祥 歌 买 疑 小 碧 堆 博 键 房 鲜 悲 付 喷 武".into(), + spend: "a5e4fff1706ef9212993a69f246f5c95ad6d84371692d63e9bb0ea112a58340d".into(), + view: "1176c43ce541477ea2f3ef0b49b25112b084e26b8a843e1304ac4677b74cdf02".into(), + }, + Vector { + language: Language::English, + seed: "washing thirsty occur lectures tuesday fainted toxic adapt \ + abnormal memoir nylon mostly building shrugged online ember northern \ + ruby woes dauntless boil family illness inroads northern" + .into(), + spend: "c0af65c0dd837e666b9d0dfed62745f4df35aed7ea619b2798a709f0fe545403".into(), + view: "513ba91c538a5a9069e0094de90e927c0cd147fa10428ce3ac1afd49f63e3b01".into(), + }, + Vector { + language: Language::Dutch, + seed: "setwinst riphagen vimmetje extase blief tuitelig fuiven meifeest \ + ponywagen zesmaal ripdeal matverf codetaal leut ivoor rotten \ + wisgerhof winzucht typograaf atrium rein zilt traktaat verzaagd setwinst" + .into(), + spend: "e2d2873085c447c2bc7664222ac8f7d240df3aeac137f5ff2022eaa629e5b10a".into(), + view: "eac30b69477e3f68093d131c7fd961564458401b07f8c87ff8f6030c1a0c7301".into(), + }, + Vector { + language: Language::French, + seed: "poids vaseux tarte bazar poivre effet entier nuance \ + sensuel ennui pacte osselet poudre battre alibi mouton \ + stade paquet pliage gibier type question position projet pliage" + .into(), + spend: "2dd39ff1a4628a94b5c2ec3e42fb3dfe15c2b2f010154dc3b3de6791e805b904".into(), + view: "6725b32230400a1032f31d622b44c3a227f88258939b14a7c72e00939e7bdf0e".into(), + }, + Vector { + language: Language::Spanish, + seed: "minero ocupar mirar evadir octubre cal logro miope \ + opaco disco ancla litio clase cuello nasal clase \ + fiar avance deseo mente grumo negro cordón croqueta clase" + .into(), + spend: "ae2c9bebdddac067d73ec0180147fc92bdf9ac7337f1bcafbbe57dd13558eb02".into(), + view: "18deafb34d55b7a43cae2c1c1c206a3c80c12cc9d1f84640b484b95b7fec3e05".into(), + }, + Vector { + language: Language::German, + seed: "Kaliber Gabelung Tapir Liveband Favorit Specht Enklave Nabel \ + Jupiter Foliant Chronik nisten löten Vase Aussage Rekord \ + Yeti Gesetz Eleganz Alraune Künstler Almweide Jahr Kastanie Almweide" + .into(), + spend: "79801b7a1b9796856e2397d862a113862e1fdc289a205e79d8d70995b276db06".into(), + view: "99f0ec556643bd9c038a4ed86edcb9c6c16032c4622ed2e000299d527a792701".into(), + }, + Vector { + language: Language::Italian, + seed: "cavo pancetta auto fulmine alleanza filmato diavolo prato \ + forzare meritare litigare lezione segreto evasione votare buio \ + licenza cliente dorso natale crescere vento tutelare vetta evasione" + .into(), + spend: "5e7fd774eb00fa5877e2a8b4dc9c7ffe111008a3891220b56a6e49ac816d650a".into(), + view: "698a1dce6018aef5516e82ca0cb3e3ec7778d17dfb41a137567bfa2e55e63a03".into(), + }, + Vector { + language: Language::Portuguese, + seed: "agito eventualidade onus itrio holograma sodomizar objetos dobro \ + iugoslavo bcrepuscular odalisca abjeto iuane darwinista eczema acetona \ + cibernetico hoquei gleba driver buffer azoto megera nogueira agito" + .into(), + spend: "13b3115f37e35c6aa1db97428b897e584698670c1b27854568d678e729200c0f".into(), + view: "ad1b4fd35270f5f36c4da7166672b347e75c3f4d41346ec2a06d1d0193632801".into(), + }, + Vector { + language: Language::Japanese, + seed: "ぜんぶ どうぐ おたがい せんきょ おうじ そんちょう じゅしん いろえんぴつ \ + かほう つかれる えらぶ にちじょう くのう にちようび ぬまえび さんきゃく \ + おおや ちぬき うすめる いがく せつでん さうな すいえい せつだん おおや" + .into(), + spend: "c56e895cdb13007eda8399222974cdbab493640663804b93cbef3d8c3df80b0b".into(), + view: "6c3634a313ec2ee979d565c33888fd7c3502d696ce0134a8bc1a2698c7f2c508".into(), + }, + Vector { + language: Language::Russian, + seed: "шатер икра нация ехать получать инерция доза реальный \ + рыжий таможня лопата душа веселый клетка атлас лекция \ + обгонять паек наивный лыжный дурак стать ежик задача паек" + .into(), + spend: "7cb5492df5eb2db4c84af20766391cd3e3662ab1a241c70fc881f3d02c381f05".into(), + view: "fcd53e41ec0df995ab43927f7c44bc3359c93523d5009fb3f5ba87431d545a03".into(), + }, + Vector { + language: Language::Esperanto, + seed: "ukazo klini peco etikedo fabriko imitado onklino urino \ + pudro incidento kumuluso ikono smirgi hirundo uretro krii \ + sparkado super speciala pupo alpinisto cvana vokegi zombio fabriko" + .into(), + spend: "82ebf0336d3b152701964ed41df6b6e9a035e57fc98b84039ed0bd4611c58904".into(), + view: "cd4d120e1ea34360af528f6a3e6156063312d9cefc9aa6b5218d366c0ed6a201".into(), + }, + Vector { + language: Language::Lojban, + seed: "jetnu vensa julne xrotu xamsi julne cutci dakli \ + mlatu xedja muvgau palpi xindo sfubu ciste cinri \ + blabi darno dembi janli blabi fenki bukpu burcu blabi" + .into(), + spend: "e4f8c6819ab6cf792cebb858caabac9307fd646901d72123e0367ebc0a79c200".into(), + view: "c806ce62bafaa7b2d597f1a1e2dbe4a2f96bfd804bf6f8420fc7f4a6bd700c00".into(), + }, + Vector { + language: Language::EnglishOld, + seed: "glorious especially puff son moment add youth nowhere \ + throw glide grip wrong rhythm consume very swear \ + bitter heavy eventually begin reason flirt type unable" + .into(), + spend: "647f4765b66b636ff07170ab6280a9a6804dfbaf19db2ad37d23be024a18730b".into(), + view: "045da65316a906a8c30046053119c18020b07a7a3a6ef5c01ab2a8755416bd02".into(), + }, + ]; + + for vector in vectors { + let trim_seed = |seed: &str| { + seed + .split_whitespace() + .map(|word| trim_by_lang(word, vector.language)) + .collect::>() + .join(" ") + }; + + // Test against Monero + { + let seed = Seed::from_string(Zeroizing::new(vector.seed.clone())).unwrap(); + assert_eq!(seed, Seed::from_string(Zeroizing::new(trim_seed(&vector.seed))).unwrap()); + + let spend: [u8; 32] = hex::decode(vector.spend).unwrap().try_into().unwrap(); + // For classical seeds, Monero directly uses the entropy as a spend key + assert_eq!( + Scalar::from_canonical_bytes(*seed.entropy()), + Scalar::from_canonical_bytes(spend) + ); + + let view: [u8; 32] = hex::decode(vector.view).unwrap().try_into().unwrap(); + // Monero then derives the view key as H(spend) + assert_eq!( + Scalar::from_bytes_mod_order(hash(&spend)), + Scalar::from_canonical_bytes(view).unwrap() + ); + + assert_eq!(Seed::from_entropy(vector.language, Zeroizing::new(spend)).unwrap(), seed); + } + + // Test against ourself + { + let seed = Seed::new(&mut OsRng, vector.language); + assert_eq!(seed, Seed::from_string(Zeroizing::new(trim_seed(&seed.to_string()))).unwrap()); + assert_eq!(seed, Seed::from_entropy(vector.language, seed.entropy()).unwrap()); + assert_eq!(seed, Seed::from_string(seed.to_string()).unwrap()); + } + } +} diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index c53acddf..f0fd398e 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -14,6 +14,9 @@ use crate::{hash, hash_to_scalar, serialize::write_varint, transaction::Input}; pub mod extra; pub(crate) use extra::{PaymentId, ExtraField, Extra}; +/// Seed creation and parsing functionality. +pub mod seed; + /// Address encoding and decoding functionality. pub mod address; use address::{Network, AddressType, SubaddressIndex, AddressSpec, AddressMeta, MoneroAddress}; diff --git a/coins/monero/src/wallet/seed/classic.rs b/coins/monero/src/wallet/seed/classic.rs new file mode 100644 index 00000000..4c9c0073 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic.rs @@ -0,0 +1,262 @@ +use core::ops::Deref; +use std::collections::HashMap; + +use lazy_static::lazy_static; + +use zeroize::{Zeroize, Zeroizing}; +use rand_core::{RngCore, CryptoRng}; + +use crc::{Crc, CRC_32_ISO_HDLC}; + +use curve25519_dalek::scalar::Scalar; + +use crate::{ + random_scalar, + wallet::seed::{SeedError, Language}, +}; + +pub(crate) const CLASSIC_SEED_LENGTH: usize = 24; +pub(crate) const CLASSIC_SEED_LENGTH_WITH_CHECKSUM: usize = 25; + +fn trim(word: &str, len: usize) -> Zeroizing { + Zeroizing::new(word.chars().take(len).collect()) +} + +struct WordList { + word_list: Vec, + word_map: HashMap, + trimmed_word_map: HashMap, + unique_prefix_length: usize, +} + +impl WordList { + fn new(words: &'static str, prefix_length: usize) -> WordList { + let mut lang = WordList { + word_list: serde_json::from_str(words).unwrap(), + word_map: HashMap::new(), + trimmed_word_map: HashMap::new(), + unique_prefix_length: prefix_length, + }; + + for (i, word) in lang.word_list.iter().enumerate() { + lang.word_map.insert(word.clone(), i); + lang.trimmed_word_map.insert(trim(word, lang.unique_prefix_length).deref().clone(), i); + } + + lang + } +} + +lazy_static! { + static ref LANGUAGES: HashMap = HashMap::from([ + (Language::Chinese, WordList::new(include_str!("./classic/zh.json"), 1)), + (Language::English, WordList::new(include_str!("./classic/en.json"), 3)), + (Language::Dutch, WordList::new(include_str!("./classic/nl.json"), 4)), + (Language::French, WordList::new(include_str!("./classic/fr.json"), 4)), + (Language::Spanish, WordList::new(include_str!("./classic/es.json"), 4)), + (Language::German, WordList::new(include_str!("./classic/de.json"), 4)), + (Language::Italian, WordList::new(include_str!("./classic/it.json"), 4)), + (Language::Portuguese, WordList::new(include_str!("./classic/pt.json"), 4)), + (Language::Japanese, WordList::new(include_str!("./classic/ja.json"), 3)), + (Language::Russian, WordList::new(include_str!("./classic/ru.json"), 4)), + (Language::Esperanto, WordList::new(include_str!("./classic/eo.json"), 4)), + (Language::Lojban, WordList::new(include_str!("./classic/jbo.json"), 4)), + (Language::EnglishOld, WordList::new(include_str!("./classic/ang.json"), 4)), + ]); +} + +#[cfg(test)] +pub(crate) fn trim_by_lang(word: &str, lang: Language) -> String { + if lang != Language::EnglishOld { + word.chars().take(LANGUAGES[&lang].unique_prefix_length).collect() + } else { + word.to_string() + } +} + +fn checksum_index(words: &[Zeroizing], lang: &WordList) -> usize { + let mut trimmed_words = Zeroizing::new(String::new()); + for w in words { + *trimmed_words += &trim(w, lang.unique_prefix_length); + } + + let crc = Crc::::new(&CRC_32_ISO_HDLC); + let mut digest = crc.digest(); + digest.update(trimmed_words.as_bytes()); + + usize::try_from(digest.finalize()).unwrap() % words.len() +} + +// Convert a private key to a seed +fn key_to_seed(lang: Language, key: Zeroizing) -> ClassicSeed { + let bytes = Zeroizing::new(key.to_bytes()); + + // get the language words + let words = &LANGUAGES[&lang].word_list; + let list_len = u64::try_from(words.len()).unwrap(); + + // To store the found words & add the checksum word later. + let mut seed = Vec::with_capacity(25); + + // convert to words + // 4 bytes -> 3 words. 8 digits base 16 -> 3 digits base 1626 + let mut segment = [0; 4]; + let mut indices = [0; 4]; + for i in 0 .. 8 { + // convert first 4 byte to u32 & get the word indices + let start = i * 4; + // convert 4 byte to u32 + segment.copy_from_slice(&bytes[start .. (start + 4)]); + // Actually convert to a u64 so we can add without overflowing + indices[0] = u64::from(u32::from_le_bytes(segment)); + indices[1] = indices[0]; + indices[0] /= list_len; + indices[2] = indices[0] + indices[1]; + indices[0] /= list_len; + indices[3] = indices[0] + indices[2]; + + // append words to seed + for i in indices.iter().skip(1) { + let word = usize::try_from(i % list_len).unwrap(); + seed.push(Zeroizing::new(words[word].clone())); + } + } + segment.zeroize(); + indices.zeroize(); + + // create a checksum word for all languages except old english + if lang != Language::EnglishOld { + let checksum = seed[checksum_index(&seed, &LANGUAGES[&lang])].clone(); + seed.push(checksum); + } + + let mut res = Zeroizing::new(String::new()); + for (i, word) in seed.iter().enumerate() { + if i != 0 { + *res += " "; + } + *res += word; + } + ClassicSeed(res) +} + +// Convert a seed to bytes +pub(crate) fn seed_to_bytes(words: &str) -> Result<(Language, Zeroizing<[u8; 32]>), SeedError> { + // get seed words + let words = words.split_whitespace().map(|w| Zeroizing::new(w.to_string())).collect::>(); + if (words.len() != CLASSIC_SEED_LENGTH) && (words.len() != CLASSIC_SEED_LENGTH_WITH_CHECKSUM) { + panic!("invalid seed passed to seed_to_bytes"); + } + + // find the language + let (matched_indices, lang_name, lang) = (|| { + let has_checksum = words.len() == CLASSIC_SEED_LENGTH_WITH_CHECKSUM; + let mut matched_indices = Zeroizing::new(vec![]); + + // Iterate through all the languages + 'language: for (lang_name, lang) in LANGUAGES.iter() { + matched_indices.zeroize(); + matched_indices.clear(); + + let map_in_use = if has_checksum { &lang.trimmed_word_map } else { &lang.word_map }; + + // Iterate through all the words and see if they're all present + for word in &words { + let trimmed = trim(word, lang.unique_prefix_length); + let word = if has_checksum { &trimmed } else { word }; + + if let Some(index) = map_in_use.get(word.deref()) { + matched_indices.push(*index); + } else { + continue 'language; + } + } + + if has_checksum { + if lang_name == &Language::EnglishOld { + Err(SeedError::EnglishOldWithChecksum)?; + } + + // exclude the last word when calculating a checksum. + let last_word = words.last().unwrap().clone(); + let checksum = words[checksum_index(&words[.. words.len() - 1], lang)].clone(); + + // check the trimmed checksum and trimmed last word line up + if trim(&checksum, lang.unique_prefix_length) != trim(&last_word, lang.unique_prefix_length) + { + Err(SeedError::InvalidChecksum)?; + } + } + + return Ok((matched_indices, lang_name, lang)); + } + + Err(SeedError::UnknownLanguage)? + })()?; + + // convert to bytes + let mut res = Zeroizing::new([0; 32]); + let mut indices = Zeroizing::new([0; 4]); + for i in 0 .. 8 { + // read 3 indices at a time + let i3 = i * 3; + indices[1] = matched_indices[i3]; + indices[2] = matched_indices[i3 + 1]; + indices[3] = matched_indices[i3 + 2]; + + let inner = |i| { + let mut base = (lang.word_list.len() - indices[i] + indices[i + 1]) % lang.word_list.len(); + // Shift the index over + for _ in 0 .. i { + base *= lang.word_list.len(); + } + base + }; + // set the last index + indices[0] = indices[1] + inner(1) + inner(2); + if (indices[0] % lang.word_list.len()) != indices[1] { + Err(SeedError::InvalidSeed)?; + } + + let pos = i * 4; + let mut bytes = u32::try_from(indices[0]).unwrap().to_le_bytes(); + res[pos .. (pos + 4)].copy_from_slice(&bytes); + bytes.zeroize(); + } + + Ok((*lang_name, res)) +} + +#[derive(Clone, PartialEq, Eq, Zeroize)] +pub struct ClassicSeed(Zeroizing); +impl ClassicSeed { + pub(crate) fn new(rng: &mut R, lang: Language) -> ClassicSeed { + key_to_seed(lang, Zeroizing::new(random_scalar(rng))) + } + + pub fn from_string(words: Zeroizing) -> Result { + let (lang, entropy) = seed_to_bytes(&words)?; + + // Make sure this is a valid scalar + let mut scalar = Scalar::from_canonical_bytes(*entropy); + if scalar.is_none() { + Err(SeedError::InvalidSeed)?; + } + scalar.zeroize(); + + // Call from_entropy so a trimmed seed becomes a full seed + Ok(Self::from_entropy(lang, entropy).unwrap()) + } + + pub fn from_entropy(lang: Language, entropy: Zeroizing<[u8; 32]>) -> Option { + Scalar::from_canonical_bytes(*entropy).map(|scalar| key_to_seed(lang, Zeroizing::new(scalar))) + } + + pub(crate) fn to_string(&self) -> Zeroizing { + self.0.clone() + } + + pub(crate) fn entropy(&self) -> Zeroizing<[u8; 32]> { + seed_to_bytes(&self.0).unwrap().1 + } +} diff --git a/coins/monero/src/wallet/seed/classic/ang.json b/coins/monero/src/wallet/seed/classic/ang.json new file mode 100644 index 00000000..1b122b65 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/ang.json @@ -0,0 +1,1628 @@ +[ + "like", + "just", + "love", + "know", + "never", + "want", + "time", + "out", + "there", + "make", + "look", + "eye", + "down", + "only", + "think", + "heart", + "back", + "then", + "into", + "about", + "more", + "away", + "still", + "them", + "take", + "thing", + "even", + "through", + "long", + "always", + "world", + "too", + "friend", + "tell", + "try", + "hand", + "thought", + "over", + "here", + "other", + "need", + "smile", + "again", + "much", + "cry", + "been", + "night", + "ever", + "little", + "said", + "end", + "some", + "those", + "around", + "mind", + "people", + "girl", + "leave", + "dream", + "left", + "turn", + "myself", + "give", + "nothing", + "really", + "off", + "before", + "something", + "find", + "walk", + "wish", + "good", + "once", + "place", + "ask", + "stop", + "keep", + "watch", + "seem", + "everything", + "wait", + "got", + "yet", + "made", + "remember", + "start", + "alone", + "run", + "hope", + "maybe", + "believe", + "body", + "hate", + "after", + "close", + "talk", + "stand", + "own", + "each", + "hurt", + "help", + "home", + "god", + "soul", + "new", + "many", + "two", + "inside", + "should", + "true", + "first", + "fear", + "mean", + "better", + "play", + "another", + "gone", + "change", + "use", + "wonder", + "someone", + "hair", + "cold", + "open", + "best", + "any", + "behind", + "happen", + "water", + "dark", + "laugh", + "stay", + "forever", + "name", + "work", + "show", + "sky", + "break", + "came", + "deep", + "door", + "put", + "black", + "together", + "upon", + "happy", + "such", + "great", + "white", + "matter", + "fill", + "past", + "please", + "burn", + "cause", + "enough", + "touch", + "moment", + "soon", + "voice", + "scream", + "anything", + "stare", + "sound", + "red", + "everyone", + "hide", + "kiss", + "truth", + "death", + "beautiful", + "mine", + "blood", + "broken", + "very", + "pass", + "next", + "forget", + "tree", + "wrong", + "air", + "mother", + "understand", + "lip", + "hit", + "wall", + "memory", + "sleep", + "free", + "high", + "realize", + "school", + "might", + "skin", + "sweet", + "perfect", + "blue", + "kill", + "breath", + "dance", + "against", + "fly", + "between", + "grow", + "strong", + "under", + "listen", + "bring", + "sometimes", + "speak", + "pull", + "person", + "become", + "family", + "begin", + "ground", + "real", + "small", + "father", + "sure", + "feet", + "rest", + "young", + "finally", + "land", + "across", + "today", + "different", + "guy", + "line", + "fire", + "reason", + "reach", + "second", + "slowly", + "write", + "eat", + "smell", + "mouth", + "step", + "learn", + "three", + "floor", + "promise", + "breathe", + "darkness", + "push", + "earth", + "guess", + "save", + "song", + "above", + "along", + "both", + "color", + "house", + "almost", + "sorry", + "anymore", + "brother", + "okay", + "dear", + "game", + "fade", + "already", + "apart", + "warm", + "beauty", + "heard", + "notice", + "question", + "shine", + "began", + "piece", + "whole", + "shadow", + "secret", + "street", + "within", + "finger", + "point", + "morning", + "whisper", + "child", + "moon", + "green", + "story", + "glass", + "kid", + "silence", + "since", + "soft", + "yourself", + "empty", + "shall", + "angel", + "answer", + "baby", + "bright", + "dad", + "path", + "worry", + "hour", + "drop", + "follow", + "power", + "war", + "half", + "flow", + "heaven", + "act", + "chance", + "fact", + "least", + "tired", + "children", + "near", + "quite", + "afraid", + "rise", + "sea", + "taste", + "window", + "cover", + "nice", + "trust", + "lot", + "sad", + "cool", + "force", + "peace", + "return", + "blind", + "easy", + "ready", + "roll", + "rose", + "drive", + "held", + "music", + "beneath", + "hang", + "mom", + "paint", + "emotion", + "quiet", + "clear", + "cloud", + "few", + "pretty", + "bird", + "outside", + "paper", + "picture", + "front", + "rock", + "simple", + "anyone", + "meant", + "reality", + "road", + "sense", + "waste", + "bit", + "leaf", + "thank", + "happiness", + "meet", + "men", + "smoke", + "truly", + "decide", + "self", + "age", + "book", + "form", + "alive", + "carry", + "escape", + "damn", + "instead", + "able", + "ice", + "minute", + "throw", + "catch", + "leg", + "ring", + "course", + "goodbye", + "lead", + "poem", + "sick", + "corner", + "desire", + "known", + "problem", + "remind", + "shoulder", + "suppose", + "toward", + "wave", + "drink", + "jump", + "woman", + "pretend", + "sister", + "week", + "human", + "joy", + "crack", + "grey", + "pray", + "surprise", + "dry", + "knee", + "less", + "search", + "bleed", + "caught", + "clean", + "embrace", + "future", + "king", + "son", + "sorrow", + "chest", + "hug", + "remain", + "sat", + "worth", + "blow", + "daddy", + "final", + "parent", + "tight", + "also", + "create", + "lonely", + "safe", + "cross", + "dress", + "evil", + "silent", + "bone", + "fate", + "perhaps", + "anger", + "class", + "scar", + "snow", + "tiny", + "tonight", + "continue", + "control", + "dog", + "edge", + "mirror", + "month", + "suddenly", + "comfort", + "given", + "loud", + "quickly", + "gaze", + "plan", + "rush", + "stone", + "town", + "battle", + "ignore", + "spirit", + "stood", + "stupid", + "yours", + "brown", + "build", + "dust", + "hey", + "kept", + "pay", + "phone", + "twist", + "although", + "ball", + "beyond", + "hidden", + "nose", + "taken", + "fail", + "float", + "pure", + "somehow", + "wash", + "wrap", + "angry", + "cheek", + "creature", + "forgotten", + "heat", + "rip", + "single", + "space", + "special", + "weak", + "whatever", + "yell", + "anyway", + "blame", + "job", + "choose", + "country", + "curse", + "drift", + "echo", + "figure", + "grew", + "laughter", + "neck", + "suffer", + "worse", + "yeah", + "disappear", + "foot", + "forward", + "knife", + "mess", + "somewhere", + "stomach", + "storm", + "beg", + "idea", + "lift", + "offer", + "breeze", + "field", + "five", + "often", + "simply", + "stuck", + "win", + "allow", + "confuse", + "enjoy", + "except", + "flower", + "seek", + "strength", + "calm", + "grin", + "gun", + "heavy", + "hill", + "large", + "ocean", + "shoe", + "sigh", + "straight", + "summer", + "tongue", + "accept", + "crazy", + "everyday", + "exist", + "grass", + "mistake", + "sent", + "shut", + "surround", + "table", + "ache", + "brain", + "destroy", + "heal", + "nature", + "shout", + "sign", + "stain", + "choice", + "doubt", + "glance", + "glow", + "mountain", + "queen", + "stranger", + "throat", + "tomorrow", + "city", + "either", + "fish", + "flame", + "rather", + "shape", + "spin", + "spread", + "ash", + "distance", + "finish", + "image", + "imagine", + "important", + "nobody", + "shatter", + "warmth", + "became", + "feed", + "flesh", + "funny", + "lust", + "shirt", + "trouble", + "yellow", + "attention", + "bare", + "bite", + "money", + "protect", + "amaze", + "appear", + "born", + "choke", + "completely", + "daughter", + "fresh", + "friendship", + "gentle", + "probably", + "six", + "deserve", + "expect", + "grab", + "middle", + "nightmare", + "river", + "thousand", + "weight", + "worst", + "wound", + "barely", + "bottle", + "cream", + "regret", + "relationship", + "stick", + "test", + "crush", + "endless", + "fault", + "itself", + "rule", + "spill", + "art", + "circle", + "join", + "kick", + "mask", + "master", + "passion", + "quick", + "raise", + "smooth", + "unless", + "wander", + "actually", + "broke", + "chair", + "deal", + "favorite", + "gift", + "note", + "number", + "sweat", + "box", + "chill", + "clothes", + "lady", + "mark", + "park", + "poor", + "sadness", + "tie", + "animal", + "belong", + "brush", + "consume", + "dawn", + "forest", + "innocent", + "pen", + "pride", + "stream", + "thick", + "clay", + "complete", + "count", + "draw", + "faith", + "press", + "silver", + "struggle", + "surface", + "taught", + "teach", + "wet", + "bless", + "chase", + "climb", + "enter", + "letter", + "melt", + "metal", + "movie", + "stretch", + "swing", + "vision", + "wife", + "beside", + "crash", + "forgot", + "guide", + "haunt", + "joke", + "knock", + "plant", + "pour", + "prove", + "reveal", + "steal", + "stuff", + "trip", + "wood", + "wrist", + "bother", + "bottom", + "crawl", + "crowd", + "fix", + "forgive", + "frown", + "grace", + "loose", + "lucky", + "party", + "release", + "surely", + "survive", + "teacher", + "gently", + "grip", + "speed", + "suicide", + "travel", + "treat", + "vein", + "written", + "cage", + "chain", + "conversation", + "date", + "enemy", + "however", + "interest", + "million", + "page", + "pink", + "proud", + "sway", + "themselves", + "winter", + "church", + "cruel", + "cup", + "demon", + "experience", + "freedom", + "pair", + "pop", + "purpose", + "respect", + "shoot", + "softly", + "state", + "strange", + "bar", + "birth", + "curl", + "dirt", + "excuse", + "lord", + "lovely", + "monster", + "order", + "pack", + "pants", + "pool", + "scene", + "seven", + "shame", + "slide", + "ugly", + "among", + "blade", + "blonde", + "closet", + "creek", + "deny", + "drug", + "eternity", + "gain", + "grade", + "handle", + "key", + "linger", + "pale", + "prepare", + "swallow", + "swim", + "tremble", + "wheel", + "won", + "cast", + "cigarette", + "claim", + "college", + "direction", + "dirty", + "gather", + "ghost", + "hundred", + "loss", + "lung", + "orange", + "present", + "swear", + "swirl", + "twice", + "wild", + "bitter", + "blanket", + "doctor", + "everywhere", + "flash", + "grown", + "knowledge", + "numb", + "pressure", + "radio", + "repeat", + "ruin", + "spend", + "unknown", + "buy", + "clock", + "devil", + "early", + "false", + "fantasy", + "pound", + "precious", + "refuse", + "sheet", + "teeth", + "welcome", + "add", + "ahead", + "block", + "bury", + "caress", + "content", + "depth", + "despite", + "distant", + "marry", + "purple", + "threw", + "whenever", + "bomb", + "dull", + "easily", + "grasp", + "hospital", + "innocence", + "normal", + "receive", + "reply", + "rhyme", + "shade", + "someday", + "sword", + "toe", + "visit", + "asleep", + "bought", + "center", + "consider", + "flat", + "hero", + "history", + "ink", + "insane", + "muscle", + "mystery", + "pocket", + "reflection", + "shove", + "silently", + "smart", + "soldier", + "spot", + "stress", + "train", + "type", + "view", + "whether", + "bus", + "energy", + "explain", + "holy", + "hunger", + "inch", + "magic", + "mix", + "noise", + "nowhere", + "prayer", + "presence", + "shock", + "snap", + "spider", + "study", + "thunder", + "trail", + "admit", + "agree", + "bag", + "bang", + "bound", + "butterfly", + "cute", + "exactly", + "explode", + "familiar", + "fold", + "further", + "pierce", + "reflect", + "scent", + "selfish", + "sharp", + "sink", + "spring", + "stumble", + "universe", + "weep", + "women", + "wonderful", + "action", + "ancient", + "attempt", + "avoid", + "birthday", + "branch", + "chocolate", + "core", + "depress", + "drunk", + "especially", + "focus", + "fruit", + "honest", + "match", + "palm", + "perfectly", + "pillow", + "pity", + "poison", + "roar", + "shift", + "slightly", + "thump", + "truck", + "tune", + "twenty", + "unable", + "wipe", + "wrote", + "coat", + "constant", + "dinner", + "drove", + "egg", + "eternal", + "flight", + "flood", + "frame", + "freak", + "gasp", + "glad", + "hollow", + "motion", + "peer", + "plastic", + "root", + "screen", + "season", + "sting", + "strike", + "team", + "unlike", + "victim", + "volume", + "warn", + "weird", + "attack", + "await", + "awake", + "built", + "charm", + "crave", + "despair", + "fought", + "grant", + "grief", + "horse", + "limit", + "message", + "ripple", + "sanity", + "scatter", + "serve", + "split", + "string", + "trick", + "annoy", + "blur", + "boat", + "brave", + "clearly", + "cling", + "connect", + "fist", + "forth", + "imagination", + "iron", + "jock", + "judge", + "lesson", + "milk", + "misery", + "nail", + "naked", + "ourselves", + "poet", + "possible", + "princess", + "sail", + "size", + "snake", + "society", + "stroke", + "torture", + "toss", + "trace", + "wise", + "bloom", + "bullet", + "cell", + "check", + "cost", + "darling", + "during", + "footstep", + "fragile", + "hallway", + "hardly", + "horizon", + "invisible", + "journey", + "midnight", + "mud", + "nod", + "pause", + "relax", + "shiver", + "sudden", + "value", + "youth", + "abuse", + "admire", + "blink", + "breast", + "bruise", + "constantly", + "couple", + "creep", + "curve", + "difference", + "dumb", + "emptiness", + "gotta", + "honor", + "plain", + "planet", + "recall", + "rub", + "ship", + "slam", + "soar", + "somebody", + "tightly", + "weather", + "adore", + "approach", + "bond", + "bread", + "burst", + "candle", + "coffee", + "cousin", + "crime", + "desert", + "flutter", + "frozen", + "grand", + "heel", + "hello", + "language", + "level", + "movement", + "pleasure", + "powerful", + "random", + "rhythm", + "settle", + "silly", + "slap", + "sort", + "spoken", + "steel", + "threaten", + "tumble", + "upset", + "aside", + "awkward", + "bee", + "blank", + "board", + "button", + "card", + "carefully", + "complain", + "crap", + "deeply", + "discover", + "drag", + "dread", + "effort", + "entire", + "fairy", + "giant", + "gotten", + "greet", + "illusion", + "jeans", + "leap", + "liquid", + "march", + "mend", + "nervous", + "nine", + "replace", + "rope", + "spine", + "stole", + "terror", + "accident", + "apple", + "balance", + "boom", + "childhood", + "collect", + "demand", + "depression", + "eventually", + "faint", + "glare", + "goal", + "group", + "honey", + "kitchen", + "laid", + "limb", + "machine", + "mere", + "mold", + "murder", + "nerve", + "painful", + "poetry", + "prince", + "rabbit", + "shelter", + "shore", + "shower", + "soothe", + "stair", + "steady", + "sunlight", + "tangle", + "tease", + "treasure", + "uncle", + "begun", + "bliss", + "canvas", + "cheer", + "claw", + "clutch", + "commit", + "crimson", + "crystal", + "delight", + "doll", + "existence", + "express", + "fog", + "football", + "gay", + "goose", + "guard", + "hatred", + "illuminate", + "mass", + "math", + "mourn", + "rich", + "rough", + "skip", + "stir", + "student", + "style", + "support", + "thorn", + "tough", + "yard", + "yearn", + "yesterday", + "advice", + "appreciate", + "autumn", + "bank", + "beam", + "bowl", + "capture", + "carve", + "collapse", + "confusion", + "creation", + "dove", + "feather", + "girlfriend", + "glory", + "government", + "harsh", + "hop", + "inner", + "loser", + "moonlight", + "neighbor", + "neither", + "peach", + "pig", + "praise", + "screw", + "shield", + "shimmer", + "sneak", + "stab", + "subject", + "throughout", + "thrown", + "tower", + "twirl", + "wow", + "army", + "arrive", + "bathroom", + "bump", + "cease", + "cookie", + "couch", + "courage", + "dim", + "guilt", + "howl", + "hum", + "husband", + "insult", + "led", + "lunch", + "mock", + "mostly", + "natural", + "nearly", + "needle", + "nerd", + "peaceful", + "perfection", + "pile", + "price", + "remove", + "roam", + "sanctuary", + "serious", + "shiny", + "shook", + "sob", + "stolen", + "tap", + "vain", + "void", + "warrior", + "wrinkle", + "affection", + "apologize", + "blossom", + "bounce", + "bridge", + "cheap", + "crumble", + "decision", + "descend", + "desperately", + "dig", + "dot", + "flip", + "frighten", + "heartbeat", + "huge", + "lazy", + "lick", + "odd", + "opinion", + "process", + "puzzle", + "quietly", + "retreat", + "score", + "sentence", + "separate", + "situation", + "skill", + "soak", + "square", + "stray", + "taint", + "task", + "tide", + "underneath", + "veil", + "whistle", + "anywhere", + "bedroom", + "bid", + "bloody", + "burden", + "careful", + "compare", + "concern", + "curtain", + "decay", + "defeat", + "describe", + "double", + "dreamer", + "driver", + "dwell", + "evening", + "flare", + "flicker", + "grandma", + "guitar", + "harm", + "horrible", + "hungry", + "indeed", + "lace", + "melody", + "monkey", + "nation", + "object", + "obviously", + "rainbow", + "salt", + "scratch", + "shown", + "shy", + "stage", + "stun", + "third", + "tickle", + "useless", + "weakness", + "worship", + "worthless", + "afternoon", + "beard", + "boyfriend", + "bubble", + "busy", + "certain", + "chin", + "concrete", + "desk", + "diamond", + "doom", + "drawn", + "due", + "felicity", + "freeze", + "frost", + "garden", + "glide", + "harmony", + "hopefully", + "hunt", + "jealous", + "lightning", + "mama", + "mercy", + "peel", + "physical", + "position", + "pulse", + "punch", + "quit", + "rant", + "respond", + "salty", + "sane", + "satisfy", + "savior", + "sheep", + "slept", + "social", + "sport", + "tuck", + "utter", + "valley", + "wolf", + "aim", + "alas", + "alter", + "arrow", + "awaken", + "beaten", + "belief", + "brand", + "ceiling", + "cheese", + "clue", + "confidence", + "connection", + "daily", + "disguise", + "eager", + "erase", + "essence", + "everytime", + "expression", + "fan", + "flag", + "flirt", + "foul", + "fur", + "giggle", + "glorious", + "ignorance", + "law", + "lifeless", + "measure", + "mighty", + "muse", + "north", + "opposite", + "paradise", + "patience", + "patient", + "pencil", + "petal", + "plate", + "ponder", + "possibly", + "practice", + "slice", + "spell", + "stock", + "strife", + "strip", + "suffocate", + "suit", + "tender", + "tool", + "trade", + "velvet", + "verse", + "waist", + "witch", + "aunt", + "bench", + "bold", + "cap", + "certainly", + "click", + "companion", + "creator", + "dart", + "delicate", + "determine", + "dish", + "dragon", + "drama", + "drum", + "dude", + "everybody", + "feast", + "forehead", + "former", + "fright", + "fully", + "gas", + "hook", + "hurl", + "invite", + "juice", + "manage", + "moral", + "possess", + "raw", + "rebel", + "royal", + "scale", + "scary", + "several", + "slight", + "stubborn", + "swell", + "talent", + "tea", + "terrible", + "thread", + "torment", + "trickle", + "usually", + "vast", + "violence", + "weave", + "acid", + "agony", + "ashamed", + "awe", + "belly", + "blend", + "blush", + "character", + "cheat", + "common", + "company", + "coward", + "creak", + "danger", + "deadly", + "defense", + "define", + "depend", + "desperate", + "destination", + "dew", + "duck", + "dusty", + "embarrass", + "engine", + "example", + "explore", + "foe", + "freely", + "frustrate", + "generation", + "glove", + "guilty", + "health", + "hurry", + "idiot", + "impossible", + "inhale", + "jaw", + "kingdom", + "mention", + "mist", + "moan", + "mumble", + "mutter", + "observe", + "ode", + "pathetic", + "pattern", + "pie", + "prefer", + "puff", + "rape", + "rare", + "revenge", + "rude", + "scrape", + "spiral", + "squeeze", + "strain", + "sunset", + "suspend", + "sympathy", + "thigh", + "throne", + "total", + "unseen", + "weapon", + "weary" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/de.json b/coins/monero/src/wallet/seed/classic/de.json new file mode 100644 index 00000000..caaf9c67 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/de.json @@ -0,0 +1,1628 @@ +[ + "Abakus", + "Abart", + "abbilden", + "Abbruch", + "Abdrift", + "Abendrot", + "Abfahrt", + "abfeuern", + "Abflug", + "abfragen", + "Abglanz", + "abhärten", + "abheben", + "Abhilfe", + "Abitur", + "Abkehr", + "Ablauf", + "ablecken", + "Ablösung", + "Abnehmer", + "abnutzen", + "Abonnent", + "Abrasion", + "Abrede", + "abrüsten", + "Absicht", + "Absprung", + "Abstand", + "absuchen", + "Abteil", + "Abundanz", + "abwarten", + "Abwurf", + "Abzug", + "Achse", + "Achtung", + "Acker", + "Aderlass", + "Adler", + "Admiral", + "Adresse", + "Affe", + "Affront", + "Afrika", + "Aggregat", + "Agilität", + "ähneln", + "Ahnung", + "Ahorn", + "Akazie", + "Akkord", + "Akrobat", + "Aktfoto", + "Aktivist", + "Albatros", + "Alchimie", + "Alemanne", + "Alibi", + "Alkohol", + "Allee", + "Allüre", + "Almosen", + "Almweide", + "Aloe", + "Alpaka", + "Alpental", + "Alphabet", + "Alpinist", + "Alraune", + "Altbier", + "Alter", + "Altflöte", + "Altruist", + "Alublech", + "Aludose", + "Amateur", + "Amazonas", + "Ameise", + "Amnesie", + "Amok", + "Ampel", + "Amphibie", + "Ampulle", + "Amsel", + "Amulett", + "Anakonda", + "Analogie", + "Ananas", + "Anarchie", + "Anatomie", + "Anbau", + "Anbeginn", + "anbieten", + "Anblick", + "ändern", + "andocken", + "Andrang", + "anecken", + "Anflug", + "Anfrage", + "Anführer", + "Angebot", + "Angler", + "Anhalter", + "Anhöhe", + "Animator", + "Anis", + "Anker", + "ankleben", + "Ankunft", + "Anlage", + "anlocken", + "Anmut", + "Annahme", + "Anomalie", + "Anonymus", + "Anorak", + "anpeilen", + "Anrecht", + "Anruf", + "Ansage", + "Anschein", + "Ansicht", + "Ansporn", + "Anteil", + "Antlitz", + "Antrag", + "Antwort", + "Anwohner", + "Aorta", + "Apfel", + "Appetit", + "Applaus", + "Aquarium", + "Arbeit", + "Arche", + "Argument", + "Arktis", + "Armband", + "Aroma", + "Asche", + "Askese", + "Asphalt", + "Asteroid", + "Ästhetik", + "Astronom", + "Atelier", + "Athlet", + "Atlantik", + "Atmung", + "Audienz", + "aufatmen", + "Auffahrt", + "aufholen", + "aufregen", + "Aufsatz", + "Auftritt", + "Aufwand", + "Augapfel", + "Auktion", + "Ausbruch", + "Ausflug", + "Ausgabe", + "Aushilfe", + "Ausland", + "Ausnahme", + "Aussage", + "Autobahn", + "Avocado", + "Axthieb", + "Bach", + "backen", + "Badesee", + "Bahnhof", + "Balance", + "Balkon", + "Ballett", + "Balsam", + "Banane", + "Bandage", + "Bankett", + "Barbar", + "Barde", + "Barett", + "Bargeld", + "Barkasse", + "Barriere", + "Bart", + "Bass", + "Bastler", + "Batterie", + "Bauch", + "Bauer", + "Bauholz", + "Baujahr", + "Baum", + "Baustahl", + "Bauteil", + "Bauweise", + "Bazar", + "beachten", + "Beatmung", + "beben", + "Becher", + "Becken", + "bedanken", + "beeilen", + "beenden", + "Beere", + "befinden", + "Befreier", + "Begabung", + "Begierde", + "begrüßen", + "Beiboot", + "Beichte", + "Beifall", + "Beigabe", + "Beil", + "Beispiel", + "Beitrag", + "beizen", + "bekommen", + "beladen", + "Beleg", + "bellen", + "belohnen", + "Bemalung", + "Bengel", + "Benutzer", + "Benzin", + "beraten", + "Bereich", + "Bergluft", + "Bericht", + "Bescheid", + "Besitz", + "besorgen", + "Bestand", + "Besuch", + "betanken", + "beten", + "betören", + "Bett", + "Beule", + "Beute", + "Bewegung", + "bewirken", + "Bewohner", + "bezahlen", + "Bezug", + "biegen", + "Biene", + "Bierzelt", + "bieten", + "Bikini", + "Bildung", + "Billard", + "binden", + "Biobauer", + "Biologe", + "Bionik", + "Biotop", + "Birke", + "Bison", + "Bitte", + "Biwak", + "Bizeps", + "blasen", + "Blatt", + "Blauwal", + "Blende", + "Blick", + "Blitz", + "Blockade", + "Blödelei", + "Blondine", + "Blues", + "Blume", + "Blut", + "Bodensee", + "Bogen", + "Boje", + "Bollwerk", + "Bonbon", + "Bonus", + "Boot", + "Bordarzt", + "Börse", + "Böschung", + "Boudoir", + "Boxkampf", + "Boykott", + "Brahms", + "Brandung", + "Brauerei", + "Brecher", + "Breitaxt", + "Bremse", + "brennen", + "Brett", + "Brief", + "Brigade", + "Brillanz", + "bringen", + "brodeln", + "Brosche", + "Brötchen", + "Brücke", + "Brunnen", + "Brüste", + "Brutofen", + "Buch", + "Büffel", + "Bugwelle", + "Bühne", + "Buletten", + "Bullauge", + "Bumerang", + "bummeln", + "Buntglas", + "Bürde", + "Burgherr", + "Bursche", + "Busen", + "Buslinie", + "Bussard", + "Butangas", + "Butter", + "Cabrio", + "campen", + "Captain", + "Cartoon", + "Cello", + "Chalet", + "Charisma", + "Chefarzt", + "Chiffon", + "Chipsatz", + "Chirurg", + "Chor", + "Chronik", + "Chuzpe", + "Clubhaus", + "Cockpit", + "Codewort", + "Cognac", + "Coladose", + "Computer", + "Coupon", + "Cousin", + "Cracking", + "Crash", + "Curry", + "Dach", + "Dackel", + "daddeln", + "daliegen", + "Dame", + "Dammbau", + "Dämon", + "Dampflok", + "Dank", + "Darm", + "Datei", + "Datsche", + "Datteln", + "Datum", + "Dauer", + "Daunen", + "Deckel", + "Decoder", + "Defekt", + "Degen", + "Dehnung", + "Deiche", + "Dekade", + "Dekor", + "Delfin", + "Demut", + "denken", + "Deponie", + "Design", + "Desktop", + "Dessert", + "Detail", + "Detektiv", + "Dezibel", + "Diadem", + "Diagnose", + "Dialekt", + "Diamant", + "Dichter", + "Dickicht", + "Diesel", + "Diktat", + "Diplom", + "Direktor", + "Dirne", + "Diskurs", + "Distanz", + "Docht", + "Dohle", + "Dolch", + "Domäne", + "Donner", + "Dorade", + "Dorf", + "Dörrobst", + "Dorsch", + "Dossier", + "Dozent", + "Drachen", + "Draht", + "Drama", + "Drang", + "Drehbuch", + "Dreieck", + "Dressur", + "Drittel", + "Drossel", + "Druck", + "Duell", + "Duft", + "Düne", + "Dünung", + "dürfen", + "Duschbad", + "Düsenjet", + "Dynamik", + "Ebbe", + "Echolot", + "Echse", + "Eckball", + "Edding", + "Edelweiß", + "Eden", + "Edition", + "Efeu", + "Effekte", + "Egoismus", + "Ehre", + "Eiablage", + "Eiche", + "Eidechse", + "Eidotter", + "Eierkopf", + "Eigelb", + "Eiland", + "Eilbote", + "Eimer", + "einatmen", + "Einband", + "Eindruck", + "Einfall", + "Eingang", + "Einkauf", + "einladen", + "Einöde", + "Einrad", + "Eintopf", + "Einwurf", + "Einzug", + "Eisbär", + "Eisen", + "Eishöhle", + "Eismeer", + "Eiweiß", + "Ekstase", + "Elan", + "Elch", + "Elefant", + "Eleganz", + "Element", + "Elfe", + "Elite", + "Elixier", + "Ellbogen", + "Eloquenz", + "Emigrant", + "Emission", + "Emotion", + "Empathie", + "Empfang", + "Endzeit", + "Energie", + "Engpass", + "Enkel", + "Enklave", + "Ente", + "entheben", + "Entität", + "entladen", + "Entwurf", + "Episode", + "Epoche", + "erachten", + "Erbauer", + "erblühen", + "Erdbeere", + "Erde", + "Erdgas", + "Erdkunde", + "Erdnuss", + "Erdöl", + "Erdteil", + "Ereignis", + "Eremit", + "erfahren", + "Erfolg", + "erfreuen", + "erfüllen", + "Ergebnis", + "erhitzen", + "erkalten", + "erkennen", + "erleben", + "Erlösung", + "ernähren", + "erneuern", + "Ernte", + "Eroberer", + "eröffnen", + "Erosion", + "Erotik", + "Erpel", + "erraten", + "Erreger", + "erröten", + "Ersatz", + "Erstflug", + "Ertrag", + "Eruption", + "erwarten", + "erwidern", + "Erzbau", + "Erzeuger", + "erziehen", + "Esel", + "Eskimo", + "Eskorte", + "Espe", + "Espresso", + "essen", + "Etage", + "Etappe", + "Etat", + "Ethik", + "Etikett", + "Etüde", + "Eule", + "Euphorie", + "Europa", + "Everest", + "Examen", + "Exil", + "Exodus", + "Extrakt", + "Fabel", + "Fabrik", + "Fachmann", + "Fackel", + "Faden", + "Fagott", + "Fahne", + "Faible", + "Fairness", + "Fakt", + "Fakultät", + "Falke", + "Fallobst", + "Fälscher", + "Faltboot", + "Familie", + "Fanclub", + "Fanfare", + "Fangarm", + "Fantasie", + "Farbe", + "Farmhaus", + "Farn", + "Fasan", + "Faser", + "Fassung", + "fasten", + "Faulheit", + "Fauna", + "Faust", + "Favorit", + "Faxgerät", + "Fazit", + "fechten", + "Federboa", + "Fehler", + "Feier", + "Feige", + "feilen", + "Feinripp", + "Feldbett", + "Felge", + "Fellpony", + "Felswand", + "Ferien", + "Ferkel", + "Fernweh", + "Ferse", + "Fest", + "Fettnapf", + "Feuer", + "Fiasko", + "Fichte", + "Fiktion", + "Film", + "Filter", + "Filz", + "Finanzen", + "Findling", + "Finger", + "Fink", + "Finnwal", + "Fisch", + "Fitness", + "Fixpunkt", + "Fixstern", + "Fjord", + "Flachbau", + "Flagge", + "Flamenco", + "Flanke", + "Flasche", + "Flaute", + "Fleck", + "Flegel", + "flehen", + "Fleisch", + "fliegen", + "Flinte", + "Flirt", + "Flocke", + "Floh", + "Floskel", + "Floß", + "Flöte", + "Flugzeug", + "Flunder", + "Flusstal", + "Flutung", + "Fockmast", + "Fohlen", + "Föhnlage", + "Fokus", + "folgen", + "Foliant", + "Folklore", + "Fontäne", + "Förde", + "Forelle", + "Format", + "Forscher", + "Fortgang", + "Forum", + "Fotograf", + "Frachter", + "Fragment", + "Fraktion", + "fräsen", + "Frauenpo", + "Freak", + "Fregatte", + "Freiheit", + "Freude", + "Frieden", + "Frohsinn", + "Frosch", + "Frucht", + "Frühjahr", + "Fuchs", + "Fügung", + "fühlen", + "Füller", + "Fundbüro", + "Funkboje", + "Funzel", + "Furnier", + "Fürsorge", + "Fusel", + "Fußbad", + "Futteral", + "Gabelung", + "gackern", + "Gage", + "gähnen", + "Galaxie", + "Galeere", + "Galopp", + "Gameboy", + "Gamsbart", + "Gandhi", + "Gang", + "Garage", + "Gardine", + "Garküche", + "Garten", + "Gasthaus", + "Gattung", + "gaukeln", + "Gazelle", + "Gebäck", + "Gebirge", + "Gebräu", + "Geburt", + "Gedanke", + "Gedeck", + "Gedicht", + "Gefahr", + "Gefieder", + "Geflügel", + "Gefühl", + "Gegend", + "Gehirn", + "Gehöft", + "Gehweg", + "Geige", + "Geist", + "Gelage", + "Geld", + "Gelenk", + "Gelübde", + "Gemälde", + "Gemeinde", + "Gemüse", + "genesen", + "Genuss", + "Gepäck", + "Geranie", + "Gericht", + "Germane", + "Geruch", + "Gesang", + "Geschenk", + "Gesetz", + "Gesindel", + "Gesöff", + "Gespan", + "Gestade", + "Gesuch", + "Getier", + "Getränk", + "Getümmel", + "Gewand", + "Geweih", + "Gewitter", + "Gewölbe", + "Geysir", + "Giftzahn", + "Gipfel", + "Giraffe", + "Gitarre", + "glänzen", + "Glasauge", + "Glatze", + "Gleis", + "Globus", + "Glück", + "glühen", + "Glutofen", + "Goldzahn", + "Gondel", + "gönnen", + "Gottheit", + "graben", + "Grafik", + "Grashalm", + "Graugans", + "greifen", + "Grenze", + "grillen", + "Groschen", + "Grotte", + "Grube", + "Grünalge", + "Gruppe", + "gruseln", + "Gulasch", + "Gummibär", + "Gurgel", + "Gürtel", + "Güterzug", + "Haarband", + "Habicht", + "hacken", + "hadern", + "Hafen", + "Hagel", + "Hähnchen", + "Haifisch", + "Haken", + "Halbaffe", + "Halsader", + "halten", + "Halunke", + "Handbuch", + "Hanf", + "Harfe", + "Harnisch", + "härten", + "Harz", + "Hasenohr", + "Haube", + "hauchen", + "Haupt", + "Haut", + "Havarie", + "Hebamme", + "hecheln", + "Heck", + "Hedonist", + "Heiler", + "Heimat", + "Heizung", + "Hektik", + "Held", + "helfen", + "Helium", + "Hemd", + "hemmen", + "Hengst", + "Herd", + "Hering", + "Herkunft", + "Hermelin", + "Herrchen", + "Herzdame", + "Heulboje", + "Hexe", + "Hilfe", + "Himbeere", + "Himmel", + "Hingabe", + "hinhören", + "Hinweis", + "Hirsch", + "Hirte", + "Hitzkopf", + "Hobel", + "Hochform", + "Hocker", + "hoffen", + "Hofhund", + "Hofnarr", + "Höhenzug", + "Hohlraum", + "Hölle", + "Holzboot", + "Honig", + "Honorar", + "horchen", + "Hörprobe", + "Höschen", + "Hotel", + "Hubraum", + "Hufeisen", + "Hügel", + "huldigen", + "Hülle", + "Humbug", + "Hummer", + "Humor", + "Hund", + "Hunger", + "Hupe", + "Hürde", + "Hurrikan", + "Hydrant", + "Hypnose", + "Ibis", + "Idee", + "Idiot", + "Igel", + "Illusion", + "Imitat", + "impfen", + "Import", + "Inferno", + "Ingwer", + "Inhalte", + "Inland", + "Insekt", + "Ironie", + "Irrfahrt", + "Irrtum", + "Isolator", + "Istwert", + "Jacke", + "Jade", + "Jagdhund", + "Jäger", + "Jaguar", + "Jahr", + "Jähzorn", + "Jazzfest", + "Jetpilot", + "jobben", + "Jochbein", + "jodeln", + "Jodsalz", + "Jolle", + "Journal", + "Jubel", + "Junge", + "Junimond", + "Jupiter", + "Jutesack", + "Juwel", + "Kabarett", + "Kabine", + "Kabuff", + "Käfer", + "Kaffee", + "Kahlkopf", + "Kaimauer", + "Kajüte", + "Kaktus", + "Kaliber", + "Kaltluft", + "Kamel", + "kämmen", + "Kampagne", + "Kanal", + "Känguru", + "Kanister", + "Kanone", + "Kante", + "Kanu", + "kapern", + "Kapitän", + "Kapuze", + "Karneval", + "Karotte", + "Käsebrot", + "Kasper", + "Kastanie", + "Katalog", + "Kathode", + "Katze", + "kaufen", + "Kaugummi", + "Kauz", + "Kehle", + "Keilerei", + "Keksdose", + "Kellner", + "Keramik", + "Kerze", + "Kessel", + "Kette", + "keuchen", + "kichern", + "Kielboot", + "Kindheit", + "Kinnbart", + "Kinosaal", + "Kiosk", + "Kissen", + "Klammer", + "Klang", + "Klapprad", + "Klartext", + "kleben", + "Klee", + "Kleinod", + "Klima", + "Klingel", + "Klippe", + "Klischee", + "Kloster", + "Klugheit", + "Klüngel", + "kneten", + "Knie", + "Knöchel", + "knüpfen", + "Kobold", + "Kochbuch", + "Kohlrabi", + "Koje", + "Kokosöl", + "Kolibri", + "Kolumne", + "Kombüse", + "Komiker", + "kommen", + "Konto", + "Konzept", + "Kopfkino", + "Kordhose", + "Korken", + "Korsett", + "Kosename", + "Krabbe", + "Krach", + "Kraft", + "Krähe", + "Kralle", + "Krapfen", + "Krater", + "kraulen", + "Kreuz", + "Krokodil", + "Kröte", + "Kugel", + "Kuhhirt", + "Kühnheit", + "Künstler", + "Kurort", + "Kurve", + "Kurzfilm", + "kuscheln", + "küssen", + "Kutter", + "Labor", + "lachen", + "Lackaffe", + "Ladeluke", + "Lagune", + "Laib", + "Lakritze", + "Lammfell", + "Land", + "Langmut", + "Lappalie", + "Last", + "Laterne", + "Latzhose", + "Laubsäge", + "laufen", + "Laune", + "Lausbub", + "Lavasee", + "Leben", + "Leder", + "Leerlauf", + "Lehm", + "Lehrer", + "leihen", + "Lektüre", + "Lenker", + "Lerche", + "Leseecke", + "Leuchter", + "Lexikon", + "Libelle", + "Libido", + "Licht", + "Liebe", + "liefern", + "Liftboy", + "Limonade", + "Lineal", + "Linoleum", + "List", + "Liveband", + "Lobrede", + "locken", + "Löffel", + "Logbuch", + "Logik", + "Lohn", + "Loipe", + "Lokal", + "Lorbeer", + "Lösung", + "löten", + "Lottofee", + "Löwe", + "Luchs", + "Luder", + "Luftpost", + "Luke", + "Lümmel", + "Lunge", + "lutschen", + "Luxus", + "Macht", + "Magazin", + "Magier", + "Magnet", + "mähen", + "Mahlzeit", + "Mahnmal", + "Maibaum", + "Maisbrei", + "Makel", + "malen", + "Mammut", + "Maniküre", + "Mantel", + "Marathon", + "Marder", + "Marine", + "Marke", + "Marmor", + "Märzluft", + "Maske", + "Maßanzug", + "Maßkrug", + "Mastkorb", + "Material", + "Matratze", + "Mauerbau", + "Maulkorb", + "Mäuschen", + "Mäzen", + "Medium", + "Meinung", + "melden", + "Melodie", + "Mensch", + "Merkmal", + "Messe", + "Metall", + "Meteor", + "Methode", + "Metzger", + "Mieze", + "Milchkuh", + "Mimose", + "Minirock", + "Minute", + "mischen", + "Missetat", + "mitgehen", + "Mittag", + "Mixtape", + "Möbel", + "Modul", + "mögen", + "Möhre", + "Molch", + "Moment", + "Monat", + "Mondflug", + "Monitor", + "Monokini", + "Monster", + "Monument", + "Moorhuhn", + "Moos", + "Möpse", + "Moral", + "Mörtel", + "Motiv", + "Motorrad", + "Möwe", + "Mühe", + "Mulatte", + "Müller", + "Mumie", + "Mund", + "Münze", + "Muschel", + "Muster", + "Mythos", + "Nabel", + "Nachtzug", + "Nackedei", + "Nagel", + "Nähe", + "Nähnadel", + "Namen", + "Narbe", + "Narwal", + "Nasenbär", + "Natur", + "Nebel", + "necken", + "Neffe", + "Neigung", + "Nektar", + "Nenner", + "Neptun", + "Nerz", + "Nessel", + "Nestbau", + "Netz", + "Neubau", + "Neuerung", + "Neugier", + "nicken", + "Niere", + "Nilpferd", + "nisten", + "Nocke", + "Nomade", + "Nordmeer", + "Notdurft", + "Notstand", + "Notwehr", + "Nudismus", + "Nuss", + "Nutzhanf", + "Oase", + "Obdach", + "Oberarzt", + "Objekt", + "Oboe", + "Obsthain", + "Ochse", + "Odyssee", + "Ofenholz", + "öffnen", + "Ohnmacht", + "Ohrfeige", + "Ohrwurm", + "Ökologie", + "Oktave", + "Ölberg", + "Olive", + "Ölkrise", + "Omelett", + "Onkel", + "Oper", + "Optiker", + "Orange", + "Orchidee", + "ordnen", + "Orgasmus", + "Orkan", + "Ortskern", + "Ortung", + "Ostasien", + "Ozean", + "Paarlauf", + "Packeis", + "paddeln", + "Paket", + "Palast", + "Pandabär", + "Panik", + "Panorama", + "Panther", + "Papagei", + "Papier", + "Paprika", + "Paradies", + "Parka", + "Parodie", + "Partner", + "Passant", + "Patent", + "Patzer", + "Pause", + "Pavian", + "Pedal", + "Pegel", + "peilen", + "Perle", + "Person", + "Pfad", + "Pfau", + "Pferd", + "Pfleger", + "Physik", + "Pier", + "Pilotwal", + "Pinzette", + "Piste", + "Plakat", + "Plankton", + "Platin", + "Plombe", + "plündern", + "Pobacke", + "Pokal", + "polieren", + "Popmusik", + "Porträt", + "Posaune", + "Postamt", + "Pottwal", + "Pracht", + "Pranke", + "Preis", + "Primat", + "Prinzip", + "Protest", + "Proviant", + "Prüfung", + "Pubertät", + "Pudding", + "Pullover", + "Pulsader", + "Punkt", + "Pute", + "Putsch", + "Puzzle", + "Python", + "quaken", + "Qualle", + "Quark", + "Quellsee", + "Querkopf", + "Quitte", + "Quote", + "Rabauke", + "Rache", + "Radclub", + "Radhose", + "Radio", + "Radtour", + "Rahmen", + "Rampe", + "Randlage", + "Ranzen", + "Rapsöl", + "Raserei", + "rasten", + "Rasur", + "Rätsel", + "Raubtier", + "Raumzeit", + "Rausch", + "Reaktor", + "Realität", + "Rebell", + "Rede", + "Reetdach", + "Regatta", + "Regen", + "Rehkitz", + "Reifen", + "Reim", + "Reise", + "Reizung", + "Rekord", + "Relevanz", + "Rennboot", + "Respekt", + "Restmüll", + "retten", + "Reue", + "Revolte", + "Rhetorik", + "Rhythmus", + "Richtung", + "Riegel", + "Rindvieh", + "Rippchen", + "Ritter", + "Robbe", + "Roboter", + "Rockband", + "Rohdaten", + "Roller", + "Roman", + "röntgen", + "Rose", + "Rosskur", + "Rost", + "Rotahorn", + "Rotglut", + "Rotznase", + "Rubrik", + "Rückweg", + "Rufmord", + "Ruhe", + "Ruine", + "Rumpf", + "Runde", + "Rüstung", + "rütteln", + "Saaltür", + "Saatguts", + "Säbel", + "Sachbuch", + "Sack", + "Saft", + "sagen", + "Sahneeis", + "Salat", + "Salbe", + "Salz", + "Sammlung", + "Samt", + "Sandbank", + "Sanftmut", + "Sardine", + "Satire", + "Sattel", + "Satzbau", + "Sauerei", + "Saum", + "Säure", + "Schall", + "Scheitel", + "Schiff", + "Schlager", + "Schmied", + "Schnee", + "Scholle", + "Schrank", + "Schulbus", + "Schwan", + "Seeadler", + "Seefahrt", + "Seehund", + "Seeufer", + "segeln", + "Sehnerv", + "Seide", + "Seilzug", + "Senf", + "Sessel", + "Seufzer", + "Sexgott", + "Sichtung", + "Signal", + "Silber", + "singen", + "Sinn", + "Sirup", + "Sitzbank", + "Skandal", + "Skikurs", + "Skipper", + "Skizze", + "Smaragd", + "Socke", + "Sohn", + "Sommer", + "Songtext", + "Sorte", + "Spagat", + "Spannung", + "Spargel", + "Specht", + "Speiseöl", + "Spiegel", + "Sport", + "spülen", + "Stadtbus", + "Stall", + "Stärke", + "Stativ", + "staunen", + "Stern", + "Stiftung", + "Stollen", + "Strömung", + "Sturm", + "Substanz", + "Südalpen", + "Sumpf", + "surfen", + "Tabak", + "Tafel", + "Tagebau", + "takeln", + "Taktung", + "Talsohle", + "Tand", + "Tanzbär", + "Tapir", + "Tarantel", + "Tarnname", + "Tasse", + "Tatnacht", + "Tatsache", + "Tatze", + "Taube", + "tauchen", + "Taufpate", + "Taumel", + "Teelicht", + "Teich", + "teilen", + "Tempo", + "Tenor", + "Terrasse", + "Testflug", + "Theater", + "Thermik", + "ticken", + "Tiefflug", + "Tierart", + "Tigerhai", + "Tinte", + "Tischler", + "toben", + "Toleranz", + "Tölpel", + "Tonband", + "Topf", + "Topmodel", + "Torbogen", + "Torlinie", + "Torte", + "Tourist", + "Tragesel", + "trampeln", + "Trapez", + "Traum", + "treffen", + "Trennung", + "Treue", + "Trick", + "trimmen", + "Trödel", + "Trost", + "Trumpf", + "tüfteln", + "Turban", + "Turm", + "Übermut", + "Ufer", + "Uhrwerk", + "umarmen", + "Umbau", + "Umfeld", + "Umgang", + "Umsturz", + "Unart", + "Unfug", + "Unimog", + "Unruhe", + "Unwucht", + "Uranerz", + "Urlaub", + "Urmensch", + "Utopie", + "Vakuum", + "Valuta", + "Vandale", + "Vase", + "Vektor", + "Ventil", + "Verb", + "Verdeck", + "Verfall", + "Vergaser", + "verhexen", + "Verlag", + "Vers", + "Vesper", + "Vieh", + "Viereck", + "Vinyl", + "Virus", + "Vitrine", + "Vollblut", + "Vorbote", + "Vorrat", + "Vorsicht", + "Vulkan", + "Wachstum", + "Wade", + "Wagemut", + "Wahlen", + "Wahrheit", + "Wald", + "Walhai", + "Wallach", + "Walnuss", + "Walzer", + "wandeln", + "Wanze", + "wärmen", + "Warnruf", + "Wäsche", + "Wasser", + "Weberei", + "wechseln", + "Wegegeld", + "wehren", + "Weiher", + "Weinglas", + "Weißbier", + "Weitwurf", + "Welle", + "Weltall", + "Werkbank", + "Werwolf", + "Wetter", + "wiehern", + "Wildgans", + "Wind", + "Wohl", + "Wohnort", + "Wolf", + "Wollust", + "Wortlaut", + "Wrack", + "Wunder", + "Wurfaxt", + "Wurst", + "Yacht", + "Yeti", + "Zacke", + "Zahl", + "zähmen", + "Zahnfee", + "Zäpfchen", + "Zaster", + "Zaumzeug", + "Zebra", + "zeigen", + "Zeitlupe", + "Zellkern", + "Zeltdach", + "Zensor", + "Zerfall", + "Zeug", + "Ziege", + "Zielfoto", + "Zimteis", + "Zobel", + "Zollhund", + "Zombie", + "Zöpfe", + "Zucht", + "Zufahrt", + "Zugfahrt", + "Zugvogel", + "Zündung", + "Zweck", + "Zyklop" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/en.json b/coins/monero/src/wallet/seed/classic/en.json new file mode 100644 index 00000000..5cb21268 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/en.json @@ -0,0 +1,1628 @@ +[ + "abbey", + "abducts", + "ability", + "ablaze", + "abnormal", + "abort", + "abrasive", + "absorb", + "abyss", + "academy", + "aces", + "aching", + "acidic", + "acoustic", + "acquire", + "across", + "actress", + "acumen", + "adapt", + "addicted", + "adept", + "adhesive", + "adjust", + "adopt", + "adrenalin", + "adult", + "adventure", + "aerial", + "afar", + "affair", + "afield", + "afloat", + "afoot", + "afraid", + "after", + "against", + "agenda", + "aggravate", + "agile", + "aglow", + "agnostic", + "agony", + "agreed", + "ahead", + "aided", + "ailments", + "aimless", + "airport", + "aisle", + "ajar", + "akin", + "alarms", + "album", + "alchemy", + "alerts", + "algebra", + "alkaline", + "alley", + "almost", + "aloof", + "alpine", + "already", + "also", + "altitude", + "alumni", + "always", + "amaze", + "ambush", + "amended", + "amidst", + "ammo", + "amnesty", + "among", + "amply", + "amused", + "anchor", + "android", + "anecdote", + "angled", + "ankle", + "annoyed", + "answers", + "antics", + "anvil", + "anxiety", + "anybody", + "apart", + "apex", + "aphid", + "aplomb", + "apology", + "apply", + "apricot", + "aptitude", + "aquarium", + "arbitrary", + "archer", + "ardent", + "arena", + "argue", + "arises", + "army", + "around", + "arrow", + "arsenic", + "artistic", + "ascend", + "ashtray", + "aside", + "asked", + "asleep", + "aspire", + "assorted", + "asylum", + "athlete", + "atlas", + "atom", + "atrium", + "attire", + "auburn", + "auctions", + "audio", + "august", + "aunt", + "austere", + "autumn", + "avatar", + "avidly", + "avoid", + "awakened", + "awesome", + "awful", + "awkward", + "awning", + "awoken", + "axes", + "axis", + "axle", + "aztec", + "azure", + "baby", + "bacon", + "badge", + "baffles", + "bagpipe", + "bailed", + "bakery", + "balding", + "bamboo", + "banjo", + "baptism", + "basin", + "batch", + "bawled", + "bays", + "because", + "beer", + "befit", + "begun", + "behind", + "being", + "below", + "bemused", + "benches", + "berries", + "bested", + "betting", + "bevel", + "beware", + "beyond", + "bias", + "bicycle", + "bids", + "bifocals", + "biggest", + "bikini", + "bimonthly", + "binocular", + "biology", + "biplane", + "birth", + "biscuit", + "bite", + "biweekly", + "blender", + "blip", + "bluntly", + "boat", + "bobsled", + "bodies", + "bogeys", + "boil", + "boldly", + "bomb", + "border", + "boss", + "both", + "bounced", + "bovine", + "bowling", + "boxes", + "boyfriend", + "broken", + "brunt", + "bubble", + "buckets", + "budget", + "buffet", + "bugs", + "building", + "bulb", + "bumper", + "bunch", + "business", + "butter", + "buying", + "buzzer", + "bygones", + "byline", + "bypass", + "cabin", + "cactus", + "cadets", + "cafe", + "cage", + "cajun", + "cake", + "calamity", + "camp", + "candy", + "casket", + "catch", + "cause", + "cavernous", + "cease", + "cedar", + "ceiling", + "cell", + "cement", + "cent", + "certain", + "chlorine", + "chrome", + "cider", + "cigar", + "cinema", + "circle", + "cistern", + "citadel", + "civilian", + "claim", + "click", + "clue", + "coal", + "cobra", + "cocoa", + "code", + "coexist", + "coffee", + "cogs", + "cohesive", + "coils", + "colony", + "comb", + "cool", + "copy", + "corrode", + "costume", + "cottage", + "cousin", + "cowl", + "criminal", + "cube", + "cucumber", + "cuddled", + "cuffs", + "cuisine", + "cunning", + "cupcake", + "custom", + "cycling", + "cylinder", + "cynical", + "dabbing", + "dads", + "daft", + "dagger", + "daily", + "damp", + "dangerous", + "dapper", + "darted", + "dash", + "dating", + "dauntless", + "dawn", + "daytime", + "dazed", + "debut", + "decay", + "dedicated", + "deepest", + "deftly", + "degrees", + "dehydrate", + "deity", + "dejected", + "delayed", + "demonstrate", + "dented", + "deodorant", + "depth", + "desk", + "devoid", + "dewdrop", + "dexterity", + "dialect", + "dice", + "diet", + "different", + "digit", + "dilute", + "dime", + "dinner", + "diode", + "diplomat", + "directed", + "distance", + "ditch", + "divers", + "dizzy", + "doctor", + "dodge", + "does", + "dogs", + "doing", + "dolphin", + "domestic", + "donuts", + "doorway", + "dormant", + "dosage", + "dotted", + "double", + "dove", + "down", + "dozen", + "dreams", + "drinks", + "drowning", + "drunk", + "drying", + "dual", + "dubbed", + "duckling", + "dude", + "duets", + "duke", + "dullness", + "dummy", + "dunes", + "duplex", + "duration", + "dusted", + "duties", + "dwarf", + "dwelt", + "dwindling", + "dying", + "dynamite", + "dyslexic", + "each", + "eagle", + "earth", + "easy", + "eating", + "eavesdrop", + "eccentric", + "echo", + "eclipse", + "economics", + "ecstatic", + "eden", + "edgy", + "edited", + "educated", + "eels", + "efficient", + "eggs", + "egotistic", + "eight", + "either", + "eject", + "elapse", + "elbow", + "eldest", + "eleven", + "elite", + "elope", + "else", + "eluded", + "emails", + "ember", + "emerge", + "emit", + "emotion", + "empty", + "emulate", + "energy", + "enforce", + "enhanced", + "enigma", + "enjoy", + "enlist", + "enmity", + "enough", + "enraged", + "ensign", + "entrance", + "envy", + "epoxy", + "equip", + "erase", + "erected", + "erosion", + "error", + "eskimos", + "espionage", + "essential", + "estate", + "etched", + "eternal", + "ethics", + "etiquette", + "evaluate", + "evenings", + "evicted", + "evolved", + "examine", + "excess", + "exhale", + "exit", + "exotic", + "exquisite", + "extra", + "exult", + "fabrics", + "factual", + "fading", + "fainted", + "faked", + "fall", + "family", + "fancy", + "farming", + "fatal", + "faulty", + "fawns", + "faxed", + "fazed", + "feast", + "february", + "federal", + "feel", + "feline", + "females", + "fences", + "ferry", + "festival", + "fetches", + "fever", + "fewest", + "fiat", + "fibula", + "fictional", + "fidget", + "fierce", + "fifteen", + "fight", + "films", + "firm", + "fishing", + "fitting", + "five", + "fixate", + "fizzle", + "fleet", + "flippant", + "flying", + "foamy", + "focus", + "foes", + "foggy", + "foiled", + "folding", + "fonts", + "foolish", + "fossil", + "fountain", + "fowls", + "foxes", + "foyer", + "framed", + "friendly", + "frown", + "fruit", + "frying", + "fudge", + "fuel", + "fugitive", + "fully", + "fuming", + "fungal", + "furnished", + "fuselage", + "future", + "fuzzy", + "gables", + "gadget", + "gags", + "gained", + "galaxy", + "gambit", + "gang", + "gasp", + "gather", + "gauze", + "gave", + "gawk", + "gaze", + "gearbox", + "gecko", + "geek", + "gels", + "gemstone", + "general", + "geometry", + "germs", + "gesture", + "getting", + "geyser", + "ghetto", + "ghost", + "giant", + "giddy", + "gifts", + "gigantic", + "gills", + "gimmick", + "ginger", + "girth", + "giving", + "glass", + "gleeful", + "glide", + "gnaw", + "gnome", + "goat", + "goblet", + "godfather", + "goes", + "goggles", + "going", + "goldfish", + "gone", + "goodbye", + "gopher", + "gorilla", + "gossip", + "gotten", + "gourmet", + "governing", + "gown", + "greater", + "grunt", + "guarded", + "guest", + "guide", + "gulp", + "gumball", + "guru", + "gusts", + "gutter", + "guys", + "gymnast", + "gypsy", + "gyrate", + "habitat", + "hacksaw", + "haggled", + "hairy", + "hamburger", + "happens", + "hashing", + "hatchet", + "haunted", + "having", + "hawk", + "haystack", + "hazard", + "hectare", + "hedgehog", + "heels", + "hefty", + "height", + "hemlock", + "hence", + "heron", + "hesitate", + "hexagon", + "hickory", + "hiding", + "highway", + "hijack", + "hiker", + "hills", + "himself", + "hinder", + "hippo", + "hire", + "history", + "hitched", + "hive", + "hoax", + "hobby", + "hockey", + "hoisting", + "hold", + "honked", + "hookup", + "hope", + "hornet", + "hospital", + "hotel", + "hounded", + "hover", + "howls", + "hubcaps", + "huddle", + "huge", + "hull", + "humid", + "hunter", + "hurried", + "husband", + "huts", + "hybrid", + "hydrogen", + "hyper", + "iceberg", + "icing", + "icon", + "identity", + "idiom", + "idled", + "idols", + "igloo", + "ignore", + "iguana", + "illness", + "imagine", + "imbalance", + "imitate", + "impel", + "inactive", + "inbound", + "incur", + "industrial", + "inexact", + "inflamed", + "ingested", + "initiate", + "injury", + "inkling", + "inline", + "inmate", + "innocent", + "inorganic", + "input", + "inquest", + "inroads", + "insult", + "intended", + "inundate", + "invoke", + "inwardly", + "ionic", + "irate", + "iris", + "irony", + "irritate", + "island", + "isolated", + "issued", + "italics", + "itches", + "items", + "itinerary", + "itself", + "ivory", + "jabbed", + "jackets", + "jaded", + "jagged", + "jailed", + "jamming", + "january", + "jargon", + "jaunt", + "javelin", + "jaws", + "jazz", + "jeans", + "jeers", + "jellyfish", + "jeopardy", + "jerseys", + "jester", + "jetting", + "jewels", + "jigsaw", + "jingle", + "jittery", + "jive", + "jobs", + "jockey", + "jogger", + "joining", + "joking", + "jolted", + "jostle", + "journal", + "joyous", + "jubilee", + "judge", + "juggled", + "juicy", + "jukebox", + "july", + "jump", + "junk", + "jury", + "justice", + "juvenile", + "kangaroo", + "karate", + "keep", + "kennel", + "kept", + "kernels", + "kettle", + "keyboard", + "kickoff", + "kidneys", + "king", + "kiosk", + "kisses", + "kitchens", + "kiwi", + "knapsack", + "knee", + "knife", + "knowledge", + "knuckle", + "koala", + "laboratory", + "ladder", + "lagoon", + "lair", + "lakes", + "lamb", + "language", + "laptop", + "large", + "last", + "later", + "launching", + "lava", + "lawsuit", + "layout", + "lazy", + "lectures", + "ledge", + "leech", + "left", + "legion", + "leisure", + "lemon", + "lending", + "leopard", + "lesson", + "lettuce", + "lexicon", + "liar", + "library", + "licks", + "lids", + "lied", + "lifestyle", + "light", + "likewise", + "lilac", + "limits", + "linen", + "lion", + "lipstick", + "liquid", + "listen", + "lively", + "loaded", + "lobster", + "locker", + "lodge", + "lofty", + "logic", + "loincloth", + "long", + "looking", + "lopped", + "lordship", + "losing", + "lottery", + "loudly", + "love", + "lower", + "loyal", + "lucky", + "luggage", + "lukewarm", + "lullaby", + "lumber", + "lunar", + "lurk", + "lush", + "luxury", + "lymph", + "lynx", + "lyrics", + "macro", + "madness", + "magically", + "mailed", + "major", + "makeup", + "malady", + "mammal", + "maps", + "masterful", + "match", + "maul", + "maverick", + "maximum", + "mayor", + "maze", + "meant", + "mechanic", + "medicate", + "meeting", + "megabyte", + "melting", + "memoir", + "menu", + "merger", + "mesh", + "metro", + "mews", + "mice", + "midst", + "mighty", + "mime", + "mirror", + "misery", + "mittens", + "mixture", + "moat", + "mobile", + "mocked", + "mohawk", + "moisture", + "molten", + "moment", + "money", + "moon", + "mops", + "morsel", + "mostly", + "motherly", + "mouth", + "movement", + "mowing", + "much", + "muddy", + "muffin", + "mugged", + "mullet", + "mumble", + "mundane", + "muppet", + "mural", + "musical", + "muzzle", + "myriad", + "mystery", + "myth", + "nabbing", + "nagged", + "nail", + "names", + "nanny", + "napkin", + "narrate", + "nasty", + "natural", + "nautical", + "navy", + "nearby", + "necklace", + "needed", + "negative", + "neither", + "neon", + "nephew", + "nerves", + "nestle", + "network", + "neutral", + "never", + "newt", + "nexus", + "nibs", + "niche", + "niece", + "nifty", + "nightly", + "nimbly", + "nineteen", + "nirvana", + "nitrogen", + "nobody", + "nocturnal", + "nodes", + "noises", + "nomad", + "noodles", + "northern", + "nostril", + "noted", + "nouns", + "novelty", + "nowhere", + "nozzle", + "nuance", + "nucleus", + "nudged", + "nugget", + "nuisance", + "null", + "number", + "nuns", + "nurse", + "nutshell", + "nylon", + "oaks", + "oars", + "oasis", + "oatmeal", + "obedient", + "object", + "obliged", + "obnoxious", + "observant", + "obtains", + "obvious", + "occur", + "ocean", + "october", + "odds", + "odometer", + "offend", + "often", + "oilfield", + "ointment", + "okay", + "older", + "olive", + "olympics", + "omega", + "omission", + "omnibus", + "onboard", + "oncoming", + "oneself", + "ongoing", + "onion", + "online", + "onslaught", + "onto", + "onward", + "oozed", + "opacity", + "opened", + "opposite", + "optical", + "opus", + "orange", + "orbit", + "orchid", + "orders", + "organs", + "origin", + "ornament", + "orphans", + "oscar", + "ostrich", + "otherwise", + "otter", + "ouch", + "ought", + "ounce", + "ourselves", + "oust", + "outbreak", + "oval", + "oven", + "owed", + "owls", + "owner", + "oxidant", + "oxygen", + "oyster", + "ozone", + "pact", + "paddles", + "pager", + "pairing", + "palace", + "pamphlet", + "pancakes", + "paper", + "paradise", + "pastry", + "patio", + "pause", + "pavements", + "pawnshop", + "payment", + "peaches", + "pebbles", + "peculiar", + "pedantic", + "peeled", + "pegs", + "pelican", + "pencil", + "people", + "pepper", + "perfect", + "pests", + "petals", + "phase", + "pheasants", + "phone", + "phrases", + "physics", + "piano", + "picked", + "pierce", + "pigment", + "piloted", + "pimple", + "pinched", + "pioneer", + "pipeline", + "pirate", + "pistons", + "pitched", + "pivot", + "pixels", + "pizza", + "playful", + "pledge", + "pliers", + "plotting", + "plus", + "plywood", + "poaching", + "pockets", + "podcast", + "poetry", + "point", + "poker", + "polar", + "ponies", + "pool", + "popular", + "portents", + "possible", + "potato", + "pouch", + "poverty", + "powder", + "pram", + "present", + "pride", + "problems", + "pruned", + "prying", + "psychic", + "public", + "puck", + "puddle", + "puffin", + "pulp", + "pumpkins", + "punch", + "puppy", + "purged", + "push", + "putty", + "puzzled", + "pylons", + "pyramid", + "python", + "queen", + "quick", + "quote", + "rabbits", + "racetrack", + "radar", + "rafts", + "rage", + "railway", + "raking", + "rally", + "ramped", + "randomly", + "rapid", + "rarest", + "rash", + "rated", + "ravine", + "rays", + "razor", + "react", + "rebel", + "recipe", + "reduce", + "reef", + "refer", + "regular", + "reheat", + "reinvest", + "rejoices", + "rekindle", + "relic", + "remedy", + "renting", + "reorder", + "repent", + "request", + "reruns", + "rest", + "return", + "reunion", + "revamp", + "rewind", + "rhino", + "rhythm", + "ribbon", + "richly", + "ridges", + "rift", + "rigid", + "rims", + "ringing", + "riots", + "ripped", + "rising", + "ritual", + "river", + "roared", + "robot", + "rockets", + "rodent", + "rogue", + "roles", + "romance", + "roomy", + "roped", + "roster", + "rotate", + "rounded", + "rover", + "rowboat", + "royal", + "ruby", + "rudely", + "ruffled", + "rugged", + "ruined", + "ruling", + "rumble", + "runway", + "rural", + "rustled", + "ruthless", + "sabotage", + "sack", + "sadness", + "safety", + "saga", + "sailor", + "sake", + "salads", + "sample", + "sanity", + "sapling", + "sarcasm", + "sash", + "satin", + "saucepan", + "saved", + "sawmill", + "saxophone", + "sayings", + "scamper", + "scenic", + "school", + "science", + "scoop", + "scrub", + "scuba", + "seasons", + "second", + "sedan", + "seeded", + "segments", + "seismic", + "selfish", + "semifinal", + "sensible", + "september", + "sequence", + "serving", + "session", + "setup", + "seventh", + "sewage", + "shackles", + "shelter", + "shipped", + "shocking", + "shrugged", + "shuffled", + "shyness", + "siblings", + "sickness", + "sidekick", + "sieve", + "sifting", + "sighting", + "silk", + "simplest", + "sincerely", + "sipped", + "siren", + "situated", + "sixteen", + "sizes", + "skater", + "skew", + "skirting", + "skulls", + "skydive", + "slackens", + "sleepless", + "slid", + "slower", + "slug", + "smash", + "smelting", + "smidgen", + "smog", + "smuggled", + "snake", + "sneeze", + "sniff", + "snout", + "snug", + "soapy", + "sober", + "soccer", + "soda", + "software", + "soggy", + "soil", + "solved", + "somewhere", + "sonic", + "soothe", + "soprano", + "sorry", + "southern", + "sovereign", + "sowed", + "soya", + "space", + "speedy", + "sphere", + "spiders", + "splendid", + "spout", + "sprig", + "spud", + "spying", + "square", + "stacking", + "stellar", + "stick", + "stockpile", + "strained", + "stunning", + "stylishly", + "subtly", + "succeed", + "suddenly", + "suede", + "suffice", + "sugar", + "suitcase", + "sulking", + "summon", + "sunken", + "superior", + "surfer", + "sushi", + "suture", + "swagger", + "swept", + "swiftly", + "sword", + "swung", + "syllabus", + "symptoms", + "syndrome", + "syringe", + "system", + "taboo", + "tacit", + "tadpoles", + "tagged", + "tail", + "taken", + "talent", + "tamper", + "tanks", + "tapestry", + "tarnished", + "tasked", + "tattoo", + "taunts", + "tavern", + "tawny", + "taxi", + "teardrop", + "technical", + "tedious", + "teeming", + "tell", + "template", + "tender", + "tepid", + "tequila", + "terminal", + "testing", + "tether", + "textbook", + "thaw", + "theatrics", + "thirsty", + "thorn", + "threaten", + "thumbs", + "thwart", + "ticket", + "tidy", + "tiers", + "tiger", + "tilt", + "timber", + "tinted", + "tipsy", + "tirade", + "tissue", + "titans", + "toaster", + "tobacco", + "today", + "toenail", + "toffee", + "together", + "toilet", + "token", + "tolerant", + "tomorrow", + "tonic", + "toolbox", + "topic", + "torch", + "tossed", + "total", + "touchy", + "towel", + "toxic", + "toyed", + "trash", + "trendy", + "tribal", + "trolling", + "truth", + "trying", + "tsunami", + "tubes", + "tucks", + "tudor", + "tuesday", + "tufts", + "tugs", + "tuition", + "tulips", + "tumbling", + "tunnel", + "turnip", + "tusks", + "tutor", + "tuxedo", + "twang", + "tweezers", + "twice", + "twofold", + "tycoon", + "typist", + "tyrant", + "ugly", + "ulcers", + "ultimate", + "umbrella", + "umpire", + "unafraid", + "unbending", + "uncle", + "under", + "uneven", + "unfit", + "ungainly", + "unhappy", + "union", + "unjustly", + "unknown", + "unlikely", + "unmask", + "unnoticed", + "unopened", + "unplugs", + "unquoted", + "unrest", + "unsafe", + "until", + "unusual", + "unveil", + "unwind", + "unzip", + "upbeat", + "upcoming", + "update", + "upgrade", + "uphill", + "upkeep", + "upload", + "upon", + "upper", + "upright", + "upstairs", + "uptight", + "upwards", + "urban", + "urchins", + "urgent", + "usage", + "useful", + "usher", + "using", + "usual", + "utensils", + "utility", + "utmost", + "utopia", + "uttered", + "vacation", + "vague", + "vain", + "value", + "vampire", + "vane", + "vapidly", + "vary", + "vastness", + "vats", + "vaults", + "vector", + "veered", + "vegan", + "vehicle", + "vein", + "velvet", + "venomous", + "verification", + "vessel", + "veteran", + "vexed", + "vials", + "vibrate", + "victim", + "video", + "viewpoint", + "vigilant", + "viking", + "village", + "vinegar", + "violin", + "vipers", + "virtual", + "visited", + "vitals", + "vivid", + "vixen", + "vocal", + "vogue", + "voice", + "volcano", + "vortex", + "voted", + "voucher", + "vowels", + "voyage", + "vulture", + "wade", + "waffle", + "wagtail", + "waist", + "waking", + "wallets", + "wanted", + "warped", + "washing", + "water", + "waveform", + "waxing", + "wayside", + "weavers", + "website", + "wedge", + "weekday", + "weird", + "welders", + "went", + "wept", + "were", + "western", + "wetsuit", + "whale", + "when", + "whipped", + "whole", + "wickets", + "width", + "wield", + "wife", + "wiggle", + "wildly", + "winter", + "wipeout", + "wiring", + "wise", + "withdrawn", + "wives", + "wizard", + "wobbly", + "woes", + "woken", + "wolf", + "womanly", + "wonders", + "woozy", + "worry", + "wounded", + "woven", + "wrap", + "wrist", + "wrong", + "yacht", + "yahoo", + "yanks", + "yard", + "yawning", + "yearbook", + "yellow", + "yesterday", + "yeti", + "yields", + "yodel", + "yoga", + "younger", + "yoyo", + "zapped", + "zeal", + "zebra", + "zero", + "zesty", + "zigzags", + "zinger", + "zippers", + "zodiac", + "zombie", + "zones", + "zoom" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/eo.json b/coins/monero/src/wallet/seed/classic/eo.json new file mode 100644 index 00000000..9ed90934 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/eo.json @@ -0,0 +1,1628 @@ +[ + "abako", + "abdiki", + "abelo", + "abituriento", + "ablativo", + "abnorma", + "abonantoj", + "abrikoto", + "absoluta", + "abunda", + "acetono", + "acida", + "adapti", + "adekvata", + "adheri", + "adicii", + "adjektivo", + "administri", + "adolesko", + "adreso", + "adstringa", + "adulto", + "advokato", + "adzo", + "aeroplano", + "aferulo", + "afgana", + "afiksi", + "aflaba", + "aforismo", + "afranki", + "aftozo", + "afusto", + "agavo", + "agento", + "agiti", + "aglo", + "agmaniero", + "agnoski", + "agordo", + "agrabla", + "agtipo", + "agutio", + "aikido", + "ailanto", + "aina", + "ajatolo", + "ajgenvaloro", + "ajlobulbo", + "ajnlitera", + "ajuto", + "ajzi", + "akademio", + "akcepti", + "akeo", + "akiri", + "aklamado", + "akmeo", + "akno", + "akompani", + "akrobato", + "akselo", + "aktiva", + "akurata", + "akvofalo", + "alarmo", + "albumo", + "alcedo", + "aldoni", + "aleo", + "alfabeto", + "algo", + "alhasti", + "aligatoro", + "alkoholo", + "almozo", + "alnomo", + "alojo", + "alpinisto", + "alrigardi", + "alskribi", + "alta", + "alumeto", + "alveni", + "alzaca", + "amaso", + "ambasado", + "amdeklaro", + "amebo", + "amfibio", + "amhara", + "amiko", + "amkanto", + "amletero", + "amnestio", + "amoranto", + "amplekso", + "amrakonto", + "amsterdama", + "amuzi", + "ananaso", + "androido", + "anekdoto", + "anfrakto", + "angulo", + "anheli", + "animo", + "anjono", + "ankro", + "anonci", + "anpriskribo", + "ansero", + "antikva", + "anuitato", + "aorto", + "aparta", + "aperti", + "apika", + "aplikado", + "apneo", + "apogi", + "aprobi", + "apsido", + "apterigo", + "apudesto", + "araneo", + "arbo", + "ardeco", + "aresti", + "argilo", + "aristokrato", + "arko", + "arlekeno", + "armi", + "arniko", + "aromo", + "arpio", + "arsenalo", + "artisto", + "aruba", + "arvorto", + "asaio", + "asbesto", + "ascendi", + "asekuri", + "asfalto", + "asisti", + "askalono", + "asocio", + "aspekti", + "astro", + "asulo", + "atakonto", + "atendi", + "atingi", + "atleto", + "atmosfero", + "atomo", + "atropino", + "atuto", + "avataro", + "aventuro", + "aviadilo", + "avokado", + "azaleo", + "azbuko", + "azenino", + "azilpetanto", + "azoto", + "azteka", + "babili", + "bacilo", + "badmintono", + "bagatelo", + "bahama", + "bajoneto", + "baki", + "balai", + "bambuo", + "bani", + "baobabo", + "bapti", + "baro", + "bastono", + "batilo", + "bavara", + "bazalto", + "beata", + "bebofono", + "bedo", + "begonio", + "behaviorismo", + "bejlo", + "bekero", + "belarto", + "bemolo", + "benko", + "bereto", + "besto", + "betulo", + "bevelo", + "bezoni", + "biaso", + "biblioteko", + "biciklo", + "bidaro", + "bieno", + "bifsteko", + "bigamiulo", + "bijekcio", + "bikino", + "bildo", + "bimetalismo", + "bindi", + "biografio", + "birdo", + "biskvito", + "bitlibro", + "bivako", + "bizara", + "bjalistoka", + "blanka", + "bleki", + "blinda", + "blovi", + "blua", + "boato", + "bobsledo", + "bocvanano", + "bodisatvo", + "bofratino", + "bogefratoj", + "bohema", + "boji", + "bokalo", + "boli", + "bombono", + "bona", + "bopatrino", + "bordo", + "bosko", + "botelo", + "bovido", + "brakpleno", + "bretaro", + "brikmuro", + "broso", + "brulema", + "bubalo", + "buctrapi", + "budo", + "bufedo", + "bugio", + "bujabeso", + "buklo", + "buldozo", + "bumerango", + "bunta", + "burokrataro", + "busbileto", + "butero", + "buzuko", + "caro", + "cebo", + "ceceo", + "cedro", + "cefalo", + "cejana", + "cekumo", + "celebri", + "cemento", + "cent", + "cepo", + "certa", + "cetera", + "cezio", + "ciano", + "cibeto", + "cico", + "cidro", + "cifero", + "cigaredo", + "ciklo", + "cilindro", + "cimbalo", + "cinamo", + "cipreso", + "cirkonstanco", + "cisterno", + "citrono", + "ciumi", + "civilizado", + "colo", + "congo", + "cunamo", + "cvana", + "dabi", + "daco", + "dadaismo", + "dafodilo", + "dago", + "daimio", + "dajmono", + "daktilo", + "dalio", + "damo", + "danki", + "darmo", + "datumoj", + "dazipo", + "deadmoni", + "debeto", + "decidi", + "dedukti", + "deerigi", + "defendi", + "degeli", + "dehaki", + "deirpunkto", + "deklaracio", + "delikata", + "demandi", + "dento", + "dependi", + "derivi", + "desegni", + "detrui", + "devi", + "deziri", + "dialogo", + "dicentro", + "didaktika", + "dieto", + "diferenci", + "digesti", + "diino", + "dikfingro", + "diligenta", + "dimensio", + "dinamo", + "diodo", + "diplomo", + "direkte", + "diskuti", + "diurno", + "diversa", + "dizajno", + "dobrogitaro", + "docento", + "dogano", + "dojeno", + "doktoro", + "dolori", + "domego", + "donaci", + "dopado", + "dormi", + "dosierujo", + "dotita", + "dozeno", + "drato", + "dresi", + "drinki", + "droni", + "druido", + "duaranga", + "dubi", + "ducent", + "dudek", + "duelo", + "dufoje", + "dugongo", + "duhufa", + "duilo", + "dujare", + "dukato", + "duloka", + "dumtempe", + "dungi", + "duobla", + "dupiedulo", + "dura", + "dusenca", + "dutaga", + "duuma", + "duvalvuloj", + "duzo", + "ebena", + "eblecoj", + "ebono", + "ebria", + "eburo", + "ecaro", + "ecigi", + "ecoj", + "edelvejso", + "editoro", + "edro", + "eduki", + "edzino", + "efektiva", + "efiki", + "efloreski", + "egala", + "egeco", + "egiptologo", + "eglefino", + "egoista", + "egreto", + "ejakuli", + "ejlo", + "ekarto", + "ekbruligi", + "ekceli", + "ekde", + "ekesti", + "ekfirmao", + "ekgliti", + "ekhavi", + "ekipi", + "ekkapti", + "eklezio", + "ekmalsati", + "ekonomio", + "ekpluvi", + "ekrano", + "ekster", + "ektiri", + "ekumeno", + "ekvilibro", + "ekzemplo", + "elasta", + "elbalai", + "elcento", + "eldoni", + "elektro", + "elfari", + "elgliti", + "elhaki", + "elipso", + "elkovi", + "ellasi", + "elmeti", + "elnutri", + "elokventa", + "elparoli", + "elrevigi", + "elstari", + "elteni", + "eluzita", + "elvoki", + "elzasa", + "emajlo", + "embaraso", + "emerito", + "emfazo", + "eminenta", + "emocio", + "empiria", + "emulsio", + "enarkivigi", + "enboteligi", + "enciklopedio", + "endorfino", + "energio", + "enfermi", + "engluti", + "enhavo", + "enigmo", + "enjekcio", + "enketi", + "enlanda", + "enmeti", + "enorma", + "enplanti", + "enradiki", + "enspezo", + "entrepreni", + "enui", + "envolvi", + "enzimo", + "eono", + "eosto", + "epitafo", + "epoko", + "epriskribebla", + "epsilono", + "erari", + "erbio", + "erco", + "erekti", + "ergonomia", + "erikejo", + "ermito", + "erotika", + "erpilo", + "erupcio", + "esameno", + "escepti", + "esenco", + "eskapi", + "esotera", + "esperi", + "estonto", + "etapo", + "etendi", + "etfingro", + "etikedo", + "etlitero", + "etmakleristo", + "etnika", + "etoso", + "etradio", + "etskala", + "etullernejo", + "evakui", + "evento", + "eviti", + "evolui", + "ezoko", + "fabriko", + "facila", + "fadeno", + "fagoto", + "fajro", + "fakto", + "fali", + "familio", + "fanatiko", + "farbo", + "fasko", + "fatala", + "favora", + "fazeolo", + "febro", + "federacio", + "feino", + "fekunda", + "felo", + "femuro", + "fenestro", + "fermi", + "festi", + "fetora", + "fezo", + "fiasko", + "fibro", + "fidela", + "fiera", + "fifama", + "figuro", + "fiherbo", + "fiinsekto", + "fiksa", + "filmo", + "fimensa", + "finalo", + "fiolo", + "fiparoli", + "firmao", + "fisko", + "fitingo", + "fiuzanto", + "fivorto", + "fiziko", + "fjordo", + "flago", + "flegi", + "flirti", + "floro", + "flugi", + "fobio", + "foceno", + "foirejo", + "fojfoje", + "fokuso", + "folio", + "fomenti", + "fonto", + "formulo", + "fosforo", + "fotografi", + "fratino", + "fremda", + "friti", + "frosto", + "frua", + "ftizo", + "fuelo", + "fugo", + "fuksia", + "fulmilo", + "fumanto", + "fundamento", + "fuorto", + "furioza", + "fusilo", + "futbalo", + "fuzio", + "gabardino", + "gado", + "gaela", + "gafo", + "gagato", + "gaja", + "gaki", + "galanta", + "gamao", + "ganto", + "gapulo", + "gardi", + "gasto", + "gavio", + "gazeto", + "geamantoj", + "gebani", + "geedzeco", + "gefratoj", + "geheno", + "gejsero", + "geko", + "gelateno", + "gemisto", + "geniulo", + "geografio", + "gepardo", + "geranio", + "gestolingvo", + "geto", + "geumo", + "gibono", + "giganta", + "gildo", + "gimnastiko", + "ginekologo", + "gipsi", + "girlando", + "gistfungo", + "gitaro", + "glazuro", + "glebo", + "gliti", + "globo", + "gluti", + "gnafalio", + "gnejso", + "gnomo", + "gnuo", + "gobio", + "godetio", + "goeleto", + "gojo", + "golfludejo", + "gombo", + "gondolo", + "gorilo", + "gospelo", + "gotika", + "granda", + "greno", + "griza", + "groto", + "grupo", + "guano", + "gubernatoro", + "gudrotuko", + "gufo", + "gujavo", + "guldeno", + "gumi", + "gupio", + "guruo", + "gusto", + "guto", + "guvernistino", + "gvardio", + "gverilo", + "gvidanto", + "habitato", + "hadito", + "hafnio", + "hagiografio", + "haitiano", + "hajlo", + "hakbloko", + "halti", + "hamstro", + "hangaro", + "hapalo", + "haro", + "hasta", + "hati", + "havebla", + "hazardo", + "hebrea", + "hedero", + "hegemonio", + "hejmo", + "hektaro", + "helpi", + "hemisfero", + "heni", + "hepato", + "herbo", + "hesa", + "heterogena", + "heziti", + "hiacinto", + "hibrida", + "hidrogeno", + "hieroglifo", + "higieno", + "hihii", + "hilumo", + "himno", + "hindino", + "hiperteksto", + "hirundo", + "historio", + "hobio", + "hojli", + "hokeo", + "hologramo", + "homido", + "honesta", + "hopi", + "horizonto", + "hospitalo", + "hotelo", + "huadi", + "hubo", + "hufumo", + "hugenoto", + "hukero", + "huligano", + "humana", + "hundo", + "huoj", + "hupilo", + "hurai", + "husaro", + "hutuo", + "huzo", + "iafoje", + "iagrade", + "iamaniere", + "iarelate", + "iaspeca", + "ibekso", + "ibiso", + "idaro", + "ideala", + "idiomo", + "idolo", + "iele", + "igluo", + "ignori", + "iguamo", + "igvano", + "ikono", + "iksodo", + "ikto", + "iliaflanke", + "ilkomputilo", + "ilobreto", + "ilremedo", + "ilumini", + "imagi", + "imitado", + "imperio", + "imuna", + "incidento", + "industrio", + "inerta", + "infano", + "ingenra", + "inhali", + "iniciati", + "injekti", + "inklino", + "inokuli", + "insekto", + "inteligenta", + "inundi", + "inviti", + "ioma", + "ionosfero", + "iperito", + "ipomeo", + "irana", + "irejo", + "irigacio", + "ironio", + "isato", + "islamo", + "istempo", + "itinero", + "itrio", + "iuloke", + "iumaniere", + "iutempe", + "izolita", + "jado", + "jaguaro", + "jakto", + "jama", + "januaro", + "japano", + "jarringo", + "jazo", + "jenoj", + "jesulo", + "jetavio", + "jezuito", + "jodli", + "joviala", + "juano", + "jubileo", + "judismo", + "jufto", + "juki", + "julio", + "juneca", + "jupo", + "juristo", + "juste", + "juvelo", + "kabineto", + "kadrato", + "kafo", + "kahelo", + "kajako", + "kakao", + "kalkuli", + "kampo", + "kanti", + "kapitalo", + "karaktero", + "kaserolo", + "katapulto", + "kaverna", + "kazino", + "kebabo", + "kefiro", + "keglo", + "kejlo", + "kekso", + "kelka", + "kemio", + "kerno", + "kesto", + "kiamaniere", + "kibuco", + "kidnapi", + "kielo", + "kikero", + "kilogramo", + "kimono", + "kinejo", + "kiosko", + "kirurgo", + "kisi", + "kitelo", + "kivio", + "klavaro", + "klerulo", + "klini", + "klopodi", + "klubo", + "knabo", + "knedi", + "koalo", + "kobalto", + "kodigi", + "kofro", + "kohera", + "koincidi", + "kojoto", + "kokoso", + "koloro", + "komenci", + "kontrakto", + "kopio", + "korekte", + "kosti", + "kotono", + "kovri", + "krajono", + "kredi", + "krii", + "krom", + "kruco", + "ksantino", + "ksenono", + "ksilofono", + "ksosa", + "kubuto", + "kudri", + "kuglo", + "kuiri", + "kuko", + "kulero", + "kumuluso", + "kuneco", + "kupro", + "kuri", + "kuseno", + "kutimo", + "kuvo", + "kuzino", + "kvalito", + "kverko", + "kvin", + "kvoto", + "labori", + "laculo", + "ladbotelo", + "lafo", + "laguno", + "laikino", + "laktobovino", + "lampolumo", + "landkarto", + "laosa", + "lapono", + "larmoguto", + "lastjare", + "latitudo", + "lavejo", + "lazanjo", + "leciono", + "ledosako", + "leganto", + "lekcio", + "lemura", + "lentuga", + "leopardo", + "leporo", + "lerni", + "lesivo", + "letero", + "levilo", + "lezi", + "liano", + "libera", + "liceo", + "lieno", + "lifto", + "ligilo", + "likvoro", + "lila", + "limono", + "lingvo", + "lipo", + "lirika", + "listo", + "literatura", + "liveri", + "lobio", + "logika", + "lojala", + "lokalo", + "longa", + "lordo", + "lotado", + "loza", + "luanto", + "lubriki", + "lucida", + "ludema", + "luigi", + "lukso", + "luli", + "lumbilda", + "lunde", + "lupago", + "lustro", + "lutilo", + "luzerno", + "maato", + "maceri", + "madono", + "mafiano", + "magazeno", + "mahometano", + "maizo", + "majstro", + "maketo", + "malgranda", + "mamo", + "mandareno", + "maorio", + "mapigi", + "marini", + "masko", + "mateno", + "mazuto", + "meandro", + "meblo", + "mecenato", + "medialo", + "mefito", + "megafono", + "mejlo", + "mekanika", + "melodia", + "membro", + "mendi", + "mergi", + "mespilo", + "metoda", + "mevo", + "mezuri", + "miaflanke", + "micelio", + "mielo", + "migdalo", + "mikrofilmo", + "militi", + "mimiko", + "mineralo", + "miopa", + "miri", + "mistera", + "mitralo", + "mizeri", + "mjelo", + "mnemoniko", + "mobilizi", + "mocio", + "moderna", + "mohajro", + "mokadi", + "molaro", + "momento", + "monero", + "mopso", + "mordi", + "moskito", + "motoro", + "movimento", + "mozaiko", + "mueli", + "mukozo", + "muldi", + "mumio", + "munti", + "muro", + "muskolo", + "mutacio", + "muzikisto", + "nabo", + "nacio", + "nadlo", + "nafto", + "naiva", + "najbaro", + "nanometro", + "napo", + "narciso", + "naski", + "naturo", + "navigi", + "naztruo", + "neatendite", + "nebulo", + "necesa", + "nedankinde", + "neebla", + "nefari", + "negoco", + "nehavi", + "neimagebla", + "nektaro", + "nelonga", + "nematura", + "nenia", + "neordinara", + "nepra", + "nervuro", + "nesto", + "nete", + "neulo", + "nevino", + "nifo", + "nigra", + "nihilisto", + "nikotino", + "nilono", + "nimfeo", + "nitrogeno", + "nivelo", + "nobla", + "nocio", + "nodozo", + "nokto", + "nomkarto", + "norda", + "nostalgio", + "notbloko", + "novico", + "nuanco", + "nuboza", + "nuda", + "nugato", + "nuklea", + "nuligi", + "numero", + "nuntempe", + "nupto", + "nura", + "nutri", + "oazo", + "obei", + "objekto", + "oblikva", + "obolo", + "observi", + "obtuza", + "obuso", + "oceano", + "odekolono", + "odori", + "oferti", + "oficiala", + "ofsajdo", + "ofte", + "ogivo", + "ogro", + "ojstredoj", + "okaze", + "okcidenta", + "okro", + "oksido", + "oktobro", + "okulo", + "oldulo", + "oleo", + "olivo", + "omaro", + "ombro", + "omego", + "omikrono", + "omleto", + "omnibuso", + "onagro", + "ondo", + "oneco", + "onidire", + "onklino", + "onlajna", + "onomatopeo", + "ontologio", + "opaka", + "operacii", + "opinii", + "oportuna", + "opresi", + "optimisto", + "oratoro", + "orbito", + "ordinara", + "orelo", + "orfino", + "organizi", + "orienta", + "orkestro", + "orlo", + "orminejo", + "ornami", + "ortangulo", + "orumi", + "oscedi", + "osmozo", + "ostocerbo", + "ovalo", + "ovingo", + "ovoblanko", + "ovri", + "ovulado", + "ozono", + "pacama", + "padeli", + "pafilo", + "pagigi", + "pajlo", + "paketo", + "palaco", + "pampelmo", + "pantalono", + "papero", + "paroli", + "pasejo", + "patro", + "pavimo", + "peco", + "pedalo", + "peklita", + "pelikano", + "pensiono", + "peplomo", + "pesilo", + "petanto", + "pezoforto", + "piano", + "picejo", + "piede", + "pigmento", + "pikema", + "pilkoludo", + "pimento", + "pinglo", + "pioniro", + "pipromento", + "pirato", + "pistolo", + "pitoreska", + "piulo", + "pivoti", + "pizango", + "planko", + "plektita", + "plibonigi", + "ploradi", + "plurlingva", + "pobo", + "podio", + "poeto", + "pogranda", + "pohora", + "pokalo", + "politekniko", + "pomarbo", + "ponevosto", + "populara", + "porcelana", + "postkompreno", + "poteto", + "poviga", + "pozitiva", + "prapatroj", + "precize", + "pridemandi", + "probable", + "pruntanto", + "psalmo", + "psikologio", + "psoriazo", + "pterido", + "publiko", + "pudro", + "pufo", + "pugnobato", + "pulovero", + "pumpi", + "punkto", + "pupo", + "pureo", + "puso", + "putrema", + "puzlo", + "rabate", + "racionala", + "radiko", + "rafinado", + "raguo", + "rajto", + "rakonti", + "ralio", + "rampi", + "rando", + "rapida", + "rastruma", + "ratifiki", + "raviolo", + "razeno", + "reakcio", + "rebildo", + "recepto", + "redakti", + "reenigi", + "reformi", + "regiono", + "rehavi", + "reinspekti", + "rejesi", + "reklamo", + "relativa", + "rememori", + "renkonti", + "reorganizado", + "reprezenti", + "respondi", + "retumilo", + "reuzebla", + "revidi", + "rezulti", + "rialo", + "ribeli", + "ricevi", + "ridiga", + "rifuginto", + "rigardi", + "rikolti", + "rilati", + "rimarki", + "rinocero", + "ripozi", + "riski", + "ritmo", + "rivero", + "rizokampo", + "roboto", + "rododendro", + "rojo", + "rokmuziko", + "rolvorto", + "romantika", + "ronroni", + "rosino", + "rotondo", + "rovero", + "rozeto", + "rubando", + "rudimenta", + "rufa", + "rugbeo", + "ruino", + "ruleto", + "rumoro", + "runo", + "rupio", + "rura", + "rustimuna", + "ruzulo", + "sabato", + "sadismo", + "safario", + "sagaca", + "sakfluto", + "salti", + "samtage", + "sandalo", + "sapejo", + "sarongo", + "satelito", + "savano", + "sbiro", + "sciado", + "seanco", + "sebo", + "sedativo", + "segligno", + "sekretario", + "selektiva", + "semajno", + "senpeza", + "separeo", + "servilo", + "sesangulo", + "setli", + "seurigi", + "severa", + "sezono", + "sfagno", + "sfero", + "sfinkso", + "siatempe", + "siblado", + "sidejo", + "siesto", + "sifono", + "signalo", + "siklo", + "silenti", + "simpla", + "sinjoro", + "siropo", + "sistemo", + "situacio", + "siverto", + "sizifa", + "skatolo", + "skemo", + "skianto", + "sklavo", + "skorpio", + "skribisto", + "skulpti", + "skvamo", + "slango", + "sledeto", + "sliparo", + "smeraldo", + "smirgi", + "smokingo", + "smuto", + "snoba", + "snufegi", + "sobra", + "sociano", + "sodakvo", + "sofo", + "soifi", + "sojlo", + "soklo", + "soldato", + "somero", + "sonilo", + "sopiri", + "sorto", + "soulo", + "soveto", + "sparkado", + "speciala", + "spiri", + "splito", + "sporto", + "sprita", + "spuro", + "stabila", + "stelfiguro", + "stimulo", + "stomako", + "strato", + "studanto", + "subgrupo", + "suden", + "suferanta", + "sugesti", + "suito", + "sukero", + "sulko", + "sume", + "sunlumo", + "super", + "surskribeto", + "suspekti", + "suturo", + "svati", + "svenfali", + "svingi", + "svopo", + "tabako", + "taglumo", + "tajloro", + "taksimetro", + "talento", + "tamen", + "tanko", + "taoismo", + "tapioko", + "tarifo", + "tasko", + "tatui", + "taverno", + "teatro", + "tedlaboro", + "tegmento", + "tehoro", + "teknika", + "telefono", + "tempo", + "tenisejo", + "teorie", + "teraso", + "testudo", + "tetablo", + "teujo", + "tezo", + "tialo", + "tibio", + "tielnomata", + "tifono", + "tigro", + "tikli", + "timida", + "tinkturo", + "tiom", + "tiparo", + "tirkesto", + "titolo", + "tiutempe", + "tizano", + "tobogano", + "tofeo", + "togo", + "toksa", + "tolerema", + "tombolo", + "tondri", + "topografio", + "tordeti", + "tosti", + "totalo", + "traduko", + "tredi", + "triangulo", + "tropika", + "trumpeto", + "tualeto", + "tubisto", + "tufgrebo", + "tuja", + "tukano", + "tulipo", + "tumulto", + "tunelo", + "turisto", + "tusi", + "tutmonda", + "tvisto", + "udono", + "uesto", + "ukazo", + "ukelelo", + "ulcero", + "ulmo", + "ultimato", + "ululi", + "umbiliko", + "unco", + "ungego", + "uniformo", + "unkti", + "unukolora", + "uragano", + "urbano", + "uretro", + "urino", + "ursido", + "uskleco", + "usonigi", + "utero", + "utila", + "utopia", + "uverturo", + "uzadi", + "uzeblo", + "uzino", + "uzkutimo", + "uzofini", + "uzurpi", + "uzvaloro", + "vadejo", + "vafleto", + "vagono", + "vahabismo", + "vajco", + "vakcino", + "valoro", + "vampiro", + "vangharoj", + "vaporo", + "varma", + "vasta", + "vato", + "vazaro", + "veaspekta", + "vedismo", + "vegetalo", + "vehiklo", + "vejno", + "vekita", + "velstango", + "vemieno", + "vendi", + "vepro", + "verando", + "vespero", + "veturi", + "veziko", + "viando", + "vibri", + "vico", + "videbla", + "vifio", + "vigla", + "viktimo", + "vila", + "vimeno", + "vintro", + "violo", + "vippuno", + "virtuala", + "viskoza", + "vitro", + "viveca", + "viziti", + "vobli", + "vodko", + "vojeto", + "vokegi", + "volbo", + "vomema", + "vono", + "vortaro", + "vosto", + "voti", + "vrako", + "vringi", + "vualo", + "vulkano", + "vundo", + "vuvuzelo", + "zamenhofa", + "zapi", + "zebro", + "zefiro", + "zeloto", + "zenismo", + "zeolito", + "zepelino", + "zeto", + "zigzagi", + "zinko", + "zipo", + "zirkonio", + "zodiako", + "zoeto", + "zombio", + "zono", + "zoologio", + "zorgi", + "zukino", + "zumilo" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/es.json b/coins/monero/src/wallet/seed/classic/es.json new file mode 100644 index 00000000..997df613 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/es.json @@ -0,0 +1,1628 @@ +[ + "ábaco", + "abdomen", + "abeja", + "abierto", + "abogado", + "abono", + "aborto", + "abrazo", + "abrir", + "abuelo", + "abuso", + "acabar", + "academia", + "acceso", + "acción", + "aceite", + "acelga", + "acento", + "aceptar", + "ácido", + "aclarar", + "acné", + "acoger", + "acoso", + "activo", + "acto", + "actriz", + "actuar", + "acudir", + "acuerdo", + "acusar", + "adicto", + "admitir", + "adoptar", + "adorno", + "aduana", + "adulto", + "aéreo", + "afectar", + "afición", + "afinar", + "afirmar", + "ágil", + "agitar", + "agonía", + "agosto", + "agotar", + "agregar", + "agrio", + "agua", + "agudo", + "águila", + "aguja", + "ahogo", + "ahorro", + "aire", + "aislar", + "ajedrez", + "ajeno", + "ajuste", + "alacrán", + "alambre", + "alarma", + "alba", + "álbum", + "alcalde", + "aldea", + "alegre", + "alejar", + "alerta", + "aleta", + "alfiler", + "alga", + "algodón", + "aliado", + "aliento", + "alivio", + "alma", + "almeja", + "almíbar", + "altar", + "alteza", + "altivo", + "alto", + "altura", + "alumno", + "alzar", + "amable", + "amante", + "amapola", + "amargo", + "amasar", + "ámbar", + "ámbito", + "ameno", + "amigo", + "amistad", + "amor", + "amparo", + "amplio", + "ancho", + "anciano", + "ancla", + "andar", + "andén", + "anemia", + "ángulo", + "anillo", + "ánimo", + "anís", + "anotar", + "antena", + "antiguo", + "antojo", + "anual", + "anular", + "anuncio", + "añadir", + "añejo", + "año", + "apagar", + "aparato", + "apetito", + "apio", + "aplicar", + "apodo", + "aporte", + "apoyo", + "aprender", + "aprobar", + "apuesta", + "apuro", + "arado", + "araña", + "arar", + "árbitro", + "árbol", + "arbusto", + "archivo", + "arco", + "arder", + "ardilla", + "arduo", + "área", + "árido", + "aries", + "armonía", + "arnés", + "aroma", + "arpa", + "arpón", + "arreglo", + "arroz", + "arruga", + "arte", + "artista", + "asa", + "asado", + "asalto", + "ascenso", + "asegurar", + "aseo", + "asesor", + "asiento", + "asilo", + "asistir", + "asno", + "asombro", + "áspero", + "astilla", + "astro", + "astuto", + "asumir", + "asunto", + "atajo", + "ataque", + "atar", + "atento", + "ateo", + "ático", + "atleta", + "átomo", + "atraer", + "atroz", + "atún", + "audaz", + "audio", + "auge", + "aula", + "aumento", + "ausente", + "autor", + "aval", + "avance", + "avaro", + "ave", + "avellana", + "avena", + "avestruz", + "avión", + "aviso", + "ayer", + "ayuda", + "ayuno", + "azafrán", + "azar", + "azote", + "azúcar", + "azufre", + "azul", + "baba", + "babor", + "bache", + "bahía", + "baile", + "bajar", + "balanza", + "balcón", + "balde", + "bambú", + "banco", + "banda", + "baño", + "barba", + "barco", + "barniz", + "barro", + "báscula", + "bastón", + "basura", + "batalla", + "batería", + "batir", + "batuta", + "baúl", + "bazar", + "bebé", + "bebida", + "bello", + "besar", + "beso", + "bestia", + "bicho", + "bien", + "bingo", + "blanco", + "bloque", + "blusa", + "boa", + "bobina", + "bobo", + "boca", + "bocina", + "boda", + "bodega", + "boina", + "bola", + "bolero", + "bolsa", + "bomba", + "bondad", + "bonito", + "bono", + "bonsái", + "borde", + "borrar", + "bosque", + "bote", + "botín", + "bóveda", + "bozal", + "bravo", + "brazo", + "brecha", + "breve", + "brillo", + "brinco", + "brisa", + "broca", + "broma", + "bronce", + "brote", + "bruja", + "brusco", + "bruto", + "buceo", + "bucle", + "bueno", + "buey", + "bufanda", + "bufón", + "búho", + "buitre", + "bulto", + "burbuja", + "burla", + "burro", + "buscar", + "butaca", + "buzón", + "caballo", + "cabeza", + "cabina", + "cabra", + "cacao", + "cadáver", + "cadena", + "caer", + "café", + "caída", + "caimán", + "caja", + "cajón", + "cal", + "calamar", + "calcio", + "caldo", + "calidad", + "calle", + "calma", + "calor", + "calvo", + "cama", + "cambio", + "camello", + "camino", + "campo", + "cáncer", + "candil", + "canela", + "canguro", + "canica", + "canto", + "caña", + "cañón", + "caoba", + "caos", + "capaz", + "capitán", + "capote", + "captar", + "capucha", + "cara", + "carbón", + "cárcel", + "careta", + "carga", + "cariño", + "carne", + "carpeta", + "carro", + "carta", + "casa", + "casco", + "casero", + "caspa", + "castor", + "catorce", + "catre", + "caudal", + "causa", + "cazo", + "cebolla", + "ceder", + "cedro", + "celda", + "célebre", + "celoso", + "célula", + "cemento", + "ceniza", + "centro", + "cerca", + "cerdo", + "cereza", + "cero", + "cerrar", + "certeza", + "césped", + "cetro", + "chacal", + "chaleco", + "champú", + "chancla", + "chapa", + "charla", + "chico", + "chiste", + "chivo", + "choque", + "choza", + "chuleta", + "chupar", + "ciclón", + "ciego", + "cielo", + "cien", + "cierto", + "cifra", + "cigarro", + "cima", + "cinco", + "cine", + "cinta", + "ciprés", + "circo", + "ciruela", + "cisne", + "cita", + "ciudad", + "clamor", + "clan", + "claro", + "clase", + "clave", + "cliente", + "clima", + "clínica", + "cobre", + "cocción", + "cochino", + "cocina", + "coco", + "código", + "codo", + "cofre", + "coger", + "cohete", + "cojín", + "cojo", + "cola", + "colcha", + "colegio", + "colgar", + "colina", + "collar", + "colmo", + "columna", + "combate", + "comer", + "comida", + "cómodo", + "compra", + "conde", + "conejo", + "conga", + "conocer", + "consejo", + "contar", + "copa", + "copia", + "corazón", + "corbata", + "corcho", + "cordón", + "corona", + "correr", + "coser", + "cosmos", + "costa", + "cráneo", + "cráter", + "crear", + "crecer", + "creído", + "crema", + "cría", + "crimen", + "cripta", + "crisis", + "cromo", + "crónica", + "croqueta", + "crudo", + "cruz", + "cuadro", + "cuarto", + "cuatro", + "cubo", + "cubrir", + "cuchara", + "cuello", + "cuento", + "cuerda", + "cuesta", + "cueva", + "cuidar", + "culebra", + "culpa", + "culto", + "cumbre", + "cumplir", + "cuna", + "cuneta", + "cuota", + "cupón", + "cúpula", + "curar", + "curioso", + "curso", + "curva", + "cutis", + "dama", + "danza", + "dar", + "dardo", + "dátil", + "deber", + "débil", + "década", + "decir", + "dedo", + "defensa", + "definir", + "dejar", + "delfín", + "delgado", + "delito", + "demora", + "denso", + "dental", + "deporte", + "derecho", + "derrota", + "desayuno", + "deseo", + "desfile", + "desnudo", + "destino", + "desvío", + "detalle", + "detener", + "deuda", + "día", + "diablo", + "diadema", + "diamante", + "diana", + "diario", + "dibujo", + "dictar", + "diente", + "dieta", + "diez", + "difícil", + "digno", + "dilema", + "diluir", + "dinero", + "directo", + "dirigir", + "disco", + "diseño", + "disfraz", + "diva", + "divino", + "doble", + "doce", + "dolor", + "domingo", + "don", + "donar", + "dorado", + "dormir", + "dorso", + "dos", + "dosis", + "dragón", + "droga", + "ducha", + "duda", + "duelo", + "dueño", + "dulce", + "dúo", + "duque", + "durar", + "dureza", + "duro", + "ébano", + "ebrio", + "echar", + "eco", + "ecuador", + "edad", + "edición", + "edificio", + "editor", + "educar", + "efecto", + "eficaz", + "eje", + "ejemplo", + "elefante", + "elegir", + "elemento", + "elevar", + "elipse", + "élite", + "elixir", + "elogio", + "eludir", + "embudo", + "emitir", + "emoción", + "empate", + "empeño", + "empleo", + "empresa", + "enano", + "encargo", + "enchufe", + "encía", + "enemigo", + "enero", + "enfado", + "enfermo", + "engaño", + "enigma", + "enlace", + "enorme", + "enredo", + "ensayo", + "enseñar", + "entero", + "entrar", + "envase", + "envío", + "época", + "equipo", + "erizo", + "escala", + "escena", + "escolar", + "escribir", + "escudo", + "esencia", + "esfera", + "esfuerzo", + "espada", + "espejo", + "espía", + "esposa", + "espuma", + "esquí", + "estar", + "este", + "estilo", + "estufa", + "etapa", + "eterno", + "ética", + "etnia", + "evadir", + "evaluar", + "evento", + "evitar", + "exacto", + "examen", + "exceso", + "excusa", + "exento", + "exigir", + "exilio", + "existir", + "éxito", + "experto", + "explicar", + "exponer", + "extremo", + "fábrica", + "fábula", + "fachada", + "fácil", + "factor", + "faena", + "faja", + "falda", + "fallo", + "falso", + "faltar", + "fama", + "familia", + "famoso", + "faraón", + "farmacia", + "farol", + "farsa", + "fase", + "fatiga", + "fauna", + "favor", + "fax", + "febrero", + "fecha", + "feliz", + "feo", + "feria", + "feroz", + "fértil", + "fervor", + "festín", + "fiable", + "fianza", + "fiar", + "fibra", + "ficción", + "ficha", + "fideo", + "fiebre", + "fiel", + "fiera", + "fiesta", + "figura", + "fijar", + "fijo", + "fila", + "filete", + "filial", + "filtro", + "fin", + "finca", + "fingir", + "finito", + "firma", + "flaco", + "flauta", + "flecha", + "flor", + "flota", + "fluir", + "flujo", + "flúor", + "fobia", + "foca", + "fogata", + "fogón", + "folio", + "folleto", + "fondo", + "forma", + "forro", + "fortuna", + "forzar", + "fosa", + "foto", + "fracaso", + "frágil", + "franja", + "frase", + "fraude", + "freír", + "freno", + "fresa", + "frío", + "frito", + "fruta", + "fuego", + "fuente", + "fuerza", + "fuga", + "fumar", + "función", + "funda", + "furgón", + "furia", + "fusil", + "fútbol", + "futuro", + "gacela", + "gafas", + "gaita", + "gajo", + "gala", + "galería", + "gallo", + "gamba", + "ganar", + "gancho", + "ganga", + "ganso", + "garaje", + "garza", + "gasolina", + "gastar", + "gato", + "gavilán", + "gemelo", + "gemir", + "gen", + "género", + "genio", + "gente", + "geranio", + "gerente", + "germen", + "gesto", + "gigante", + "gimnasio", + "girar", + "giro", + "glaciar", + "globo", + "gloria", + "gol", + "golfo", + "goloso", + "golpe", + "goma", + "gordo", + "gorila", + "gorra", + "gota", + "goteo", + "gozar", + "grada", + "gráfico", + "grano", + "grasa", + "gratis", + "grave", + "grieta", + "grillo", + "gripe", + "gris", + "grito", + "grosor", + "grúa", + "grueso", + "grumo", + "grupo", + "guante", + "guapo", + "guardia", + "guerra", + "guía", + "guiño", + "guion", + "guiso", + "guitarra", + "gusano", + "gustar", + "haber", + "hábil", + "hablar", + "hacer", + "hacha", + "hada", + "hallar", + "hamaca", + "harina", + "haz", + "hazaña", + "hebilla", + "hebra", + "hecho", + "helado", + "helio", + "hembra", + "herir", + "hermano", + "héroe", + "hervir", + "hielo", + "hierro", + "hígado", + "higiene", + "hijo", + "himno", + "historia", + "hocico", + "hogar", + "hoguera", + "hoja", + "hombre", + "hongo", + "honor", + "honra", + "hora", + "hormiga", + "horno", + "hostil", + "hoyo", + "hueco", + "huelga", + "huerta", + "hueso", + "huevo", + "huida", + "huir", + "humano", + "húmedo", + "humilde", + "humo", + "hundir", + "huracán", + "hurto", + "icono", + "ideal", + "idioma", + "ídolo", + "iglesia", + "iglú", + "igual", + "ilegal", + "ilusión", + "imagen", + "imán", + "imitar", + "impar", + "imperio", + "imponer", + "impulso", + "incapaz", + "índice", + "inerte", + "infiel", + "informe", + "ingenio", + "inicio", + "inmenso", + "inmune", + "innato", + "insecto", + "instante", + "interés", + "íntimo", + "intuir", + "inútil", + "invierno", + "ira", + "iris", + "ironía", + "isla", + "islote", + "jabalí", + "jabón", + "jamón", + "jarabe", + "jardín", + "jarra", + "jaula", + "jazmín", + "jefe", + "jeringa", + "jinete", + "jornada", + "joroba", + "joven", + "joya", + "juerga", + "jueves", + "juez", + "jugador", + "jugo", + "juguete", + "juicio", + "junco", + "jungla", + "junio", + "juntar", + "júpiter", + "jurar", + "justo", + "juvenil", + "juzgar", + "kilo", + "koala", + "labio", + "lacio", + "lacra", + "lado", + "ladrón", + "lagarto", + "lágrima", + "laguna", + "laico", + "lamer", + "lámina", + "lámpara", + "lana", + "lancha", + "langosta", + "lanza", + "lápiz", + "largo", + "larva", + "lástima", + "lata", + "látex", + "latir", + "laurel", + "lavar", + "lazo", + "leal", + "lección", + "leche", + "lector", + "leer", + "legión", + "legumbre", + "lejano", + "lengua", + "lento", + "leña", + "león", + "leopardo", + "lesión", + "letal", + "letra", + "leve", + "leyenda", + "libertad", + "libro", + "licor", + "líder", + "lidiar", + "lienzo", + "liga", + "ligero", + "lima", + "límite", + "limón", + "limpio", + "lince", + "lindo", + "línea", + "lingote", + "lino", + "linterna", + "líquido", + "liso", + "lista", + "litera", + "litio", + "litro", + "llaga", + "llama", + "llanto", + "llave", + "llegar", + "llenar", + "llevar", + "llorar", + "llover", + "lluvia", + "lobo", + "loción", + "loco", + "locura", + "lógica", + "logro", + "lombriz", + "lomo", + "lonja", + "lote", + "lucha", + "lucir", + "lugar", + "lujo", + "luna", + "lunes", + "lupa", + "lustro", + "luto", + "luz", + "maceta", + "macho", + "madera", + "madre", + "maduro", + "maestro", + "mafia", + "magia", + "mago", + "maíz", + "maldad", + "maleta", + "malla", + "malo", + "mamá", + "mambo", + "mamut", + "manco", + "mando", + "manejar", + "manga", + "maniquí", + "manjar", + "mano", + "manso", + "manta", + "mañana", + "mapa", + "máquina", + "mar", + "marco", + "marea", + "marfil", + "margen", + "marido", + "mármol", + "marrón", + "martes", + "marzo", + "masa", + "máscara", + "masivo", + "matar", + "materia", + "matiz", + "matriz", + "máximo", + "mayor", + "mazorca", + "mecha", + "medalla", + "medio", + "médula", + "mejilla", + "mejor", + "melena", + "melón", + "memoria", + "menor", + "mensaje", + "mente", + "menú", + "mercado", + "merengue", + "mérito", + "mes", + "mesón", + "meta", + "meter", + "método", + "metro", + "mezcla", + "miedo", + "miel", + "miembro", + "miga", + "mil", + "milagro", + "militar", + "millón", + "mimo", + "mina", + "minero", + "mínimo", + "minuto", + "miope", + "mirar", + "misa", + "miseria", + "misil", + "mismo", + "mitad", + "mito", + "mochila", + "moción", + "moda", + "modelo", + "moho", + "mojar", + "molde", + "moler", + "molino", + "momento", + "momia", + "monarca", + "moneda", + "monja", + "monto", + "moño", + "morada", + "morder", + "moreno", + "morir", + "morro", + "morsa", + "mortal", + "mosca", + "mostrar", + "motivo", + "mover", + "móvil", + "mozo", + "mucho", + "mudar", + "mueble", + "muela", + "muerte", + "muestra", + "mugre", + "mujer", + "mula", + "muleta", + "multa", + "mundo", + "muñeca", + "mural", + "muro", + "músculo", + "museo", + "musgo", + "música", + "muslo", + "nácar", + "nación", + "nadar", + "naipe", + "naranja", + "nariz", + "narrar", + "nasal", + "natal", + "nativo", + "natural", + "náusea", + "naval", + "nave", + "navidad", + "necio", + "néctar", + "negar", + "negocio", + "negro", + "neón", + "nervio", + "neto", + "neutro", + "nevar", + "nevera", + "nicho", + "nido", + "niebla", + "nieto", + "niñez", + "niño", + "nítido", + "nivel", + "nobleza", + "noche", + "nómina", + "noria", + "norma", + "norte", + "nota", + "noticia", + "novato", + "novela", + "novio", + "nube", + "nuca", + "núcleo", + "nudillo", + "nudo", + "nuera", + "nueve", + "nuez", + "nulo", + "número", + "nutria", + "oasis", + "obeso", + "obispo", + "objeto", + "obra", + "obrero", + "observar", + "obtener", + "obvio", + "oca", + "ocaso", + "océano", + "ochenta", + "ocho", + "ocio", + "ocre", + "octavo", + "octubre", + "oculto", + "ocupar", + "ocurrir", + "odiar", + "odio", + "odisea", + "oeste", + "ofensa", + "oferta", + "oficio", + "ofrecer", + "ogro", + "oído", + "oír", + "ojo", + "ola", + "oleada", + "olfato", + "olivo", + "olla", + "olmo", + "olor", + "olvido", + "ombligo", + "onda", + "onza", + "opaco", + "opción", + "ópera", + "opinar", + "oponer", + "optar", + "óptica", + "opuesto", + "oración", + "orador", + "oral", + "órbita", + "orca", + "orden", + "oreja", + "órgano", + "orgía", + "orgullo", + "oriente", + "origen", + "orilla", + "oro", + "orquesta", + "oruga", + "osadía", + "oscuro", + "osezno", + "oso", + "ostra", + "otoño", + "otro", + "oveja", + "óvulo", + "óxido", + "oxígeno", + "oyente", + "ozono", + "pacto", + "padre", + "paella", + "página", + "pago", + "país", + "pájaro", + "palabra", + "palco", + "paleta", + "pálido", + "palma", + "paloma", + "palpar", + "pan", + "panal", + "pánico", + "pantera", + "pañuelo", + "papá", + "papel", + "papilla", + "paquete", + "parar", + "parcela", + "pared", + "parir", + "paro", + "párpado", + "parque", + "párrafo", + "parte", + "pasar", + "paseo", + "pasión", + "paso", + "pasta", + "pata", + "patio", + "patria", + "pausa", + "pauta", + "pavo", + "payaso", + "peatón", + "pecado", + "pecera", + "pecho", + "pedal", + "pedir", + "pegar", + "peine", + "pelar", + "peldaño", + "pelea", + "peligro", + "pellejo", + "pelo", + "peluca", + "pena", + "pensar", + "peñón", + "peón", + "peor", + "pepino", + "pequeño", + "pera", + "percha", + "perder", + "pereza", + "perfil", + "perico", + "perla", + "permiso", + "perro", + "persona", + "pesa", + "pesca", + "pésimo", + "pestaña", + "pétalo", + "petróleo", + "pez", + "pezuña", + "picar", + "pichón", + "pie", + "piedra", + "pierna", + "pieza", + "pijama", + "pilar", + "piloto", + "pimienta", + "pino", + "pintor", + "pinza", + "piña", + "piojo", + "pipa", + "pirata", + "pisar", + "piscina", + "piso", + "pista", + "pitón", + "pizca", + "placa", + "plan", + "plata", + "playa", + "plaza", + "pleito", + "pleno", + "plomo", + "pluma", + "plural", + "pobre", + "poco", + "poder", + "podio", + "poema", + "poesía", + "poeta", + "polen", + "policía", + "pollo", + "polvo", + "pomada", + "pomelo", + "pomo", + "pompa", + "poner", + "porción", + "portal", + "posada", + "poseer", + "posible", + "poste", + "potencia", + "potro", + "pozo", + "prado", + "precoz", + "pregunta", + "premio", + "prensa", + "preso", + "previo", + "primo", + "príncipe", + "prisión", + "privar", + "proa", + "probar", + "proceso", + "producto", + "proeza", + "profesor", + "programa", + "prole", + "promesa", + "pronto", + "propio", + "próximo", + "prueba", + "público", + "puchero", + "pudor", + "pueblo", + "puerta", + "puesto", + "pulga", + "pulir", + "pulmón", + "pulpo", + "pulso", + "puma", + "punto", + "puñal", + "puño", + "pupa", + "pupila", + "puré", + "quedar", + "queja", + "quemar", + "querer", + "queso", + "quieto", + "química", + "quince", + "quitar", + "rábano", + "rabia", + "rabo", + "ración", + "radical", + "raíz", + "rama", + "rampa", + "rancho", + "rango", + "rapaz", + "rápido", + "rapto", + "rasgo", + "raspa", + "rato", + "rayo", + "raza", + "razón", + "reacción", + "realidad", + "rebaño", + "rebote", + "recaer", + "receta", + "rechazo", + "recoger", + "recreo", + "recto", + "recurso", + "red", + "redondo", + "reducir", + "reflejo", + "reforma", + "refrán", + "refugio", + "regalo", + "regir", + "regla", + "regreso", + "rehén", + "reino", + "reír", + "reja", + "relato", + "relevo", + "relieve", + "relleno", + "reloj", + "remar", + "remedio", + "remo", + "rencor", + "rendir", + "renta", + "reparto", + "repetir", + "reposo", + "reptil", + "res", + "rescate", + "resina", + "respeto", + "resto", + "resumen", + "retiro", + "retorno", + "retrato", + "reunir", + "revés", + "revista", + "rey", + "rezar", + "rico", + "riego", + "rienda", + "riesgo", + "rifa", + "rígido", + "rigor", + "rincón", + "riñón", + "río", + "riqueza", + "risa", + "ritmo", + "rito" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/fr.json b/coins/monero/src/wallet/seed/classic/fr.json new file mode 100644 index 00000000..65663afc --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/fr.json @@ -0,0 +1,1628 @@ +[ + "abandon", + "abattre", + "aboi", + "abolir", + "aborder", + "abri", + "absence", + "absolu", + "abuser", + "acacia", + "acajou", + "accent", + "accord", + "accrocher", + "accuser", + "acerbe", + "achat", + "acheter", + "acide", + "acier", + "acquis", + "acte", + "action", + "adage", + "adepte", + "adieu", + "admettre", + "admis", + "adorer", + "adresser", + "aduler", + "affaire", + "affirmer", + "afin", + "agacer", + "agent", + "agir", + "agiter", + "agonie", + "agrafe", + "agrume", + "aider", + "aigle", + "aigre", + "aile", + "ailleurs", + "aimant", + "aimer", + "ainsi", + "aise", + "ajouter", + "alarme", + "album", + "alcool", + "alerte", + "algue", + "alibi", + "aller", + "allumer", + "alors", + "amande", + "amener", + "amie", + "amorcer", + "amour", + "ample", + "amuser", + "ananas", + "ancien", + "anglais", + "angoisse", + "animal", + "anneau", + "annoncer", + "apercevoir", + "apparence", + "appel", + "apporter", + "apprendre", + "appuyer", + "arbre", + "arcade", + "arceau", + "arche", + "ardeur", + "argent", + "argile", + "aride", + "arme", + "armure", + "arracher", + "arriver", + "article", + "asile", + "aspect", + "assaut", + "assez", + "assister", + "assurer", + "astre", + "astuce", + "atlas", + "atroce", + "attacher", + "attente", + "attirer", + "aube", + "aucun", + "audace", + "auparavant", + "auquel", + "aurore", + "aussi", + "autant", + "auteur", + "autoroute", + "autre", + "aval", + "avant", + "avec", + "avenir", + "averse", + "aveu", + "avide", + "avion", + "avis", + "avoir", + "avouer", + "avril", + "azote", + "azur", + "badge", + "bagage", + "bague", + "bain", + "baisser", + "balai", + "balcon", + "balise", + "balle", + "bambou", + "banane", + "banc", + "bandage", + "banjo", + "banlieue", + "bannir", + "banque", + "baobab", + "barbe", + "barque", + "barrer", + "bassine", + "bataille", + "bateau", + "battre", + "baver", + "bavoir", + "bazar", + "beau", + "beige", + "berger", + "besoin", + "beurre", + "biais", + "biceps", + "bidule", + "bien", + "bijou", + "bilan", + "billet", + "blanc", + "blason", + "bleu", + "bloc", + "blond", + "bocal", + "boire", + "boiserie", + "boiter", + "bonbon", + "bondir", + "bonheur", + "bordure", + "borgne", + "borner", + "bosse", + "bouche", + "bouder", + "bouger", + "boule", + "bourse", + "bout", + "boxe", + "brader", + "braise", + "branche", + "braquer", + "bras", + "brave", + "brebis", + "brevet", + "brider", + "briller", + "brin", + "brique", + "briser", + "broche", + "broder", + "bronze", + "brosser", + "brouter", + "bruit", + "brute", + "budget", + "buffet", + "bulle", + "bureau", + "buriner", + "buste", + "buter", + "butiner", + "cabas", + "cabinet", + "cabri", + "cacao", + "cacher", + "cadeau", + "cadre", + "cage", + "caisse", + "caler", + "calme", + "camarade", + "camion", + "campagne", + "canal", + "canif", + "capable", + "capot", + "carat", + "caresser", + "carie", + "carpe", + "cartel", + "casier", + "casque", + "casserole", + "cause", + "cavale", + "cave", + "ceci", + "cela", + "celui", + "cendre", + "cent", + "cependant", + "cercle", + "cerise", + "cerner", + "certes", + "cerveau", + "cesser", + "chacun", + "chair", + "chaleur", + "chamois", + "chanson", + "chaque", + "charge", + "chasse", + "chat", + "chaud", + "chef", + "chemin", + "cheveu", + "chez", + "chicane", + "chien", + "chiffre", + "chiner", + "chiot", + "chlore", + "choc", + "choix", + "chose", + "chou", + "chute", + "cibler", + "cidre", + "ciel", + "cigale", + "cinq", + "cintre", + "cirage", + "cirque", + "ciseau", + "citation", + "citer", + "citron", + "civet", + "clairon", + "clan", + "classe", + "clavier", + "clef", + "climat", + "cloche", + "cloner", + "clore", + "clos", + "clou", + "club", + "cobra", + "cocon", + "coiffer", + "coin", + "colline", + "colon", + "combat", + "comme", + "compte", + "conclure", + "conduire", + "confier", + "connu", + "conseil", + "contre", + "convenir", + "copier", + "cordial", + "cornet", + "corps", + "cosmos", + "coton", + "couche", + "coude", + "couler", + "coupure", + "cour", + "couteau", + "couvrir", + "crabe", + "crainte", + "crampe", + "cran", + "creuser", + "crever", + "crier", + "crime", + "crin", + "crise", + "crochet", + "croix", + "cruel", + "cuisine", + "cuite", + "culot", + "culte", + "cumul", + "cure", + "curieux", + "cuve", + "dame", + "danger", + "dans", + "davantage", + "debout", + "dedans", + "dehors", + "delta", + "demain", + "demeurer", + "demi", + "dense", + "dent", + "depuis", + "dernier", + "descendre", + "dessus", + "destin", + "dette", + "deuil", + "deux", + "devant", + "devenir", + "devin", + "devoir", + "dicton", + "dieu", + "difficile", + "digestion", + "digue", + "diluer", + "dimanche", + "dinde", + "diode", + "dire", + "diriger", + "discours", + "disposer", + "distance", + "divan", + "divers", + "docile", + "docteur", + "dodu", + "dogme", + "doigt", + "dominer", + "donation", + "donjon", + "donner", + "dopage", + "dorer", + "dormir", + "doseur", + "douane", + "double", + "douche", + "douleur", + "doute", + "doux", + "douzaine", + "draguer", + "drame", + "drap", + "dresser", + "droit", + "duel", + "dune", + "duper", + "durant", + "durcir", + "durer", + "eaux", + "effacer", + "effet", + "effort", + "effrayant", + "elle", + "embrasser", + "emmener", + "emparer", + "empire", + "employer", + "emporter", + "enclos", + "encore", + "endive", + "endormir", + "endroit", + "enduit", + "enfant", + "enfermer", + "enfin", + "enfler", + "enfoncer", + "enfuir", + "engager", + "engin", + "enjeu", + "enlever", + "ennemi", + "ennui", + "ensemble", + "ensuite", + "entamer", + "entendre", + "entier", + "entourer", + "entre", + "envelopper", + "envie", + "envoyer", + "erreur", + "escalier", + "espace", + "espoir", + "esprit", + "essai", + "essor", + "essuyer", + "estimer", + "exact", + "examiner", + "excuse", + "exemple", + "exiger", + "exil", + "exister", + "exode", + "expliquer", + "exposer", + "exprimer", + "extase", + "fable", + "facette", + "facile", + "fade", + "faible", + "faim", + "faire", + "fait", + "falloir", + "famille", + "faner", + "farce", + "farine", + "fatigue", + "faucon", + "faune", + "faute", + "faux", + "faveur", + "favori", + "faxer", + "feinter", + "femme", + "fendre", + "fente", + "ferme", + "festin", + "feuille", + "feutre", + "fiable", + "fibre", + "ficher", + "fier", + "figer", + "figure", + "filet", + "fille", + "filmer", + "fils", + "filtre", + "final", + "finesse", + "finir", + "fiole", + "firme", + "fixe", + "flacon", + "flair", + "flamme", + "flan", + "flaque", + "fleur", + "flocon", + "flore", + "flot", + "flou", + "fluide", + "fluor", + "flux", + "focus", + "foin", + "foire", + "foison", + "folie", + "fonction", + "fondre", + "fonte", + "force", + "forer", + "forger", + "forme", + "fort", + "fosse", + "fouet", + "fouine", + "foule", + "four", + "foyer", + "frais", + "franc", + "frapper", + "freiner", + "frimer", + "friser", + "frite", + "froid", + "froncer", + "fruit", + "fugue", + "fuir", + "fuite", + "fumer", + "fureur", + "furieux", + "fuser", + "fusil", + "futile", + "futur", + "gagner", + "gain", + "gala", + "galet", + "galop", + "gamme", + "gant", + "garage", + "garde", + "garer", + "gauche", + "gaufre", + "gaule", + "gaver", + "gazon", + "geler", + "genou", + "genre", + "gens", + "gercer", + "germer", + "geste", + "gibier", + "gicler", + "gilet", + "girafe", + "givre", + "glace", + "glisser", + "globe", + "gloire", + "gluant", + "gober", + "golf", + "gommer", + "gorge", + "gosier", + "goutte", + "grain", + "gramme", + "grand", + "gras", + "grave", + "gredin", + "griffure", + "griller", + "gris", + "gronder", + "gros", + "grotte", + "groupe", + "grue", + "guerrier", + "guetter", + "guider", + "guise", + "habiter", + "hache", + "haie", + "haine", + "halte", + "hamac", + "hanche", + "hangar", + "hanter", + "haras", + "hareng", + "harpe", + "hasard", + "hausse", + "haut", + "havre", + "herbe", + "heure", + "hibou", + "hier", + "histoire", + "hiver", + "hochet", + "homme", + "honneur", + "honte", + "horde", + "horizon", + "hormone", + "houle", + "housse", + "hublot", + "huile", + "huit", + "humain", + "humble", + "humide", + "humour", + "hurler", + "idole", + "igloo", + "ignorer", + "illusion", + "image", + "immense", + "immobile", + "imposer", + "impression", + "incapable", + "inconnu", + "index", + "indiquer", + "infime", + "injure", + "inox", + "inspirer", + "instant", + "intention", + "intime", + "inutile", + "inventer", + "inviter", + "iode", + "iris", + "issue", + "ivre", + "jade", + "jadis", + "jamais", + "jambe", + "janvier", + "jardin", + "jauge", + "jaunisse", + "jeter", + "jeton", + "jeudi", + "jeune", + "joie", + "joindre", + "joli", + "joueur", + "journal", + "judo", + "juge", + "juillet", + "juin", + "jument", + "jungle", + "jupe", + "jupon", + "jurer", + "juron", + "jury", + "jusque", + "juste", + "kayak", + "ketchup", + "kilo", + "kiwi", + "koala", + "label", + "lacet", + "lacune", + "laine", + "laisse", + "lait", + "lame", + "lancer", + "lande", + "laque", + "lard", + "largeur", + "larme", + "larve", + "lasso", + "laver", + "lendemain", + "lentement", + "lequel", + "lettre", + "leur", + "lever", + "levure", + "liane", + "libre", + "lien", + "lier", + "lieutenant", + "ligne", + "ligoter", + "liguer", + "limace", + "limer", + "limite", + "lingot", + "lion", + "lire", + "lisser", + "litre", + "livre", + "lobe", + "local", + "logis", + "loin", + "loisir", + "long", + "loque", + "lors", + "lotus", + "louer", + "loup", + "lourd", + "louve", + "loyer", + "lubie", + "lucide", + "lueur", + "luge", + "luire", + "lundi", + "lune", + "lustre", + "lutin", + "lutte", + "luxe", + "machine", + "madame", + "magie", + "magnifique", + "magot", + "maigre", + "main", + "mairie", + "maison", + "malade", + "malheur", + "malin", + "manche", + "manger", + "manier", + "manoir", + "manquer", + "marche", + "mardi", + "marge", + "mariage", + "marquer", + "mars", + "masque", + "masse", + "matin", + "mauvais", + "meilleur", + "melon", + "membre", + "menacer", + "mener", + "mensonge", + "mentir", + "menu", + "merci", + "merlu", + "mesure", + "mettre", + "meuble", + "meunier", + "meute", + "miche", + "micro", + "midi", + "miel", + "miette", + "mieux", + "milieu", + "mille", + "mimer", + "mince", + "mineur", + "ministre", + "minute", + "mirage", + "miroir", + "miser", + "mite", + "mixte", + "mobile", + "mode", + "module", + "moins", + "mois", + "moment", + "momie", + "monde", + "monsieur", + "monter", + "moquer", + "moral", + "morceau", + "mordre", + "morose", + "morse", + "mortier", + "morue", + "motif", + "motte", + "moudre", + "moule", + "mourir", + "mousse", + "mouton", + "mouvement", + "moyen", + "muer", + "muette", + "mugir", + "muguet", + "mulot", + "multiple", + "munir", + "muret", + "muse", + "musique", + "muter", + "nacre", + "nager", + "nain", + "naissance", + "narine", + "narrer", + "naseau", + "nasse", + "nation", + "nature", + "naval", + "navet", + "naviguer", + "navrer", + "neige", + "nerf", + "nerveux", + "neuf", + "neutre", + "neuve", + "neveu", + "niche", + "nier", + "niveau", + "noble", + "noce", + "nocif", + "noir", + "nomade", + "nombre", + "nommer", + "nord", + "norme", + "notaire", + "notice", + "notre", + "nouer", + "nougat", + "nourrir", + "nous", + "nouveau", + "novice", + "noyade", + "noyer", + "nuage", + "nuance", + "nuire", + "nuit", + "nulle", + "nuque", + "oasis", + "objet", + "obliger", + "obscur", + "observer", + "obtenir", + "obus", + "occasion", + "occuper", + "ocre", + "octet", + "odeur", + "odorat", + "offense", + "officier", + "offrir", + "ogive", + "oiseau", + "olive", + "ombre", + "onctueux", + "onduler", + "ongle", + "onze", + "opter", + "option", + "orageux", + "oral", + "orange", + "orbite", + "ordinaire", + "ordre", + "oreille", + "organe", + "orgie", + "orgueil", + "orient", + "origan", + "orner", + "orteil", + "ortie", + "oser", + "osselet", + "otage", + "otarie", + "ouate", + "oublier", + "ouest", + "ours", + "outil", + "outre", + "ouvert", + "ouvrir", + "ovale", + "ozone", + "pacte", + "page", + "paille", + "pain", + "paire", + "paix", + "palace", + "palissade", + "palmier", + "palpiter", + "panda", + "panneau", + "papa", + "papier", + "paquet", + "parc", + "pardi", + "parfois", + "parler", + "parmi", + "parole", + "partir", + "parvenir", + "passer", + "pastel", + "patin", + "patron", + "paume", + "pause", + "pauvre", + "paver", + "pavot", + "payer", + "pays", + "peau", + "peigne", + "peinture", + "pelage", + "pelote", + "pencher", + "pendre", + "penser", + "pente", + "percer", + "perdu", + "perle", + "permettre", + "personne", + "perte", + "peser", + "pesticide", + "petit", + "peuple", + "peur", + "phase", + "photo", + "phrase", + "piano", + "pied", + "pierre", + "pieu", + "pile", + "pilier", + "pilote", + "pilule", + "piment", + "pincer", + "pinson", + "pinte", + "pion", + "piquer", + "pirate", + "pire", + "piste", + "piton", + "pitre", + "pivot", + "pizza", + "placer", + "plage", + "plaire", + "plan", + "plaque", + "plat", + "plein", + "pleurer", + "pliage", + "plier", + "plonger", + "plot", + "pluie", + "plume", + "plus", + "pneu", + "poche", + "podium", + "poids", + "poil", + "point", + "poire", + "poison", + "poitrine", + "poivre", + "police", + "pollen", + "pomme", + "pompier", + "poncer", + "pondre", + "pont", + "portion", + "poser", + "position", + "possible", + "poste", + "potage", + "potin", + "pouce", + "poudre", + "poulet", + "poumon", + "poupe", + "pour", + "pousser", + "poutre", + "pouvoir", + "prairie", + "premier", + "prendre", + "presque", + "preuve", + "prier", + "primeur", + "prince", + "prison", + "priver", + "prix", + "prochain", + "produire", + "profond", + "proie", + "projet", + "promener", + "prononcer", + "propre", + "prose", + "prouver", + "prune", + "public", + "puce", + "pudeur", + "puiser", + "pull", + "pulpe", + "puma", + "punir", + "purge", + "putois", + "quand", + "quartier", + "quasi", + "quatre", + "quel", + "question", + "queue", + "quiche", + "quille", + "quinze", + "quitter", + "quoi", + "rabais", + "raboter", + "race", + "racheter", + "racine", + "racler", + "raconter", + "radar", + "radio", + "rafale", + "rage", + "ragot", + "raideur", + "raie", + "rail", + "raison", + "ramasser", + "ramener", + "rampe", + "rance", + "rang", + "rapace", + "rapide", + "rapport", + "rarement", + "rasage", + "raser", + "rasoir", + "rassurer", + "rater", + "ratio", + "rature", + "ravage", + "ravir", + "rayer", + "rayon", + "rebond", + "recevoir", + "recherche", + "record", + "reculer", + "redevenir", + "refuser", + "regard", + "regretter", + "rein", + "rejeter", + "rejoindre", + "relation", + "relever", + "religion", + "remarquer", + "remettre", + "remise", + "remonter", + "remplir", + "remuer", + "rencontre", + "rendre", + "renier", + "renoncer", + "rentrer", + "renverser", + "repas", + "repli", + "reposer", + "reproche", + "requin", + "respect", + "ressembler", + "reste", + "retard", + "retenir", + "retirer", + "retour", + "retrouver", + "revenir", + "revoir", + "revue", + "rhume", + "ricaner", + "riche", + "rideau", + "ridicule", + "rien", + "rigide", + "rincer", + "rire", + "risquer", + "rituel", + "rivage", + "rive", + "robe", + "robot", + "robuste", + "rocade", + "roche", + "rodeur", + "rogner", + "roman", + "rompre", + "ronce", + "rondeur", + "ronger", + "roque", + "rose", + "rosir", + "rotation", + "rotule", + "roue", + "rouge", + "rouler", + "route", + "ruban", + "rubis", + "ruche", + "rude", + "ruelle", + "ruer", + "rugby", + "rugir", + "ruine", + "rumeur", + "rural", + "ruse", + "rustre", + "sable", + "sabot", + "sabre", + "sacre", + "sage", + "saint", + "saisir", + "salade", + "salive", + "salle", + "salon", + "salto", + "salut", + "salve", + "samba", + "sandale", + "sanguin", + "sapin", + "sarcasme", + "satisfaire", + "sauce", + "sauf", + "sauge", + "saule", + "sauna", + "sauter", + "sauver", + "savoir", + "science", + "scoop", + "score", + "second", + "secret", + "secte", + "seigneur", + "sein", + "seize", + "selle", + "selon", + "semaine", + "sembler", + "semer", + "semis", + "sensuel", + "sentir", + "sept", + "serpe", + "serrer", + "sertir", + "service", + "seuil", + "seulement", + "short", + "sien", + "sigle", + "signal", + "silence", + "silo", + "simple", + "singe", + "sinon", + "sinus", + "sioux", + "sirop", + "site", + "situation", + "skier", + "snob", + "sobre", + "social", + "socle", + "sodium", + "soigner", + "soir", + "soixante", + "soja", + "solaire", + "soldat", + "soleil", + "solide", + "solo", + "solvant", + "sombre", + "somme", + "somnoler", + "sondage", + "songeur", + "sonner", + "sorte", + "sosie", + "sottise", + "souci", + "soudain", + "souffrir", + "souhaiter", + "soulever", + "soumettre", + "soupe", + "sourd", + "soustraire", + "soutenir", + "souvent", + "soyeux", + "spectacle", + "sport", + "stade", + "stagiaire", + "stand", + "star", + "statue", + "stock", + "stop", + "store", + "style", + "suave", + "subir", + "sucre", + "suer", + "suffire", + "suie", + "suite", + "suivre", + "sujet", + "sulfite", + "supposer", + "surf", + "surprendre", + "surtout", + "surveiller", + "tabac", + "table", + "tabou", + "tache", + "tacler", + "tacot", + "tact", + "taie", + "taille", + "taire", + "talon", + "talus", + "tandis", + "tango", + "tanin", + "tant", + "taper", + "tapis", + "tard", + "tarif", + "tarot", + "tarte", + "tasse", + "taureau", + "taux", + "taverne", + "taxer", + "taxi", + "tellement", + "temple", + "tendre", + "tenir", + "tenter", + "tenu", + "terme", + "ternir", + "terre", + "test", + "texte", + "thym", + "tibia", + "tiers", + "tige", + "tipi", + "tique", + "tirer", + "tissu", + "titre", + "toast", + "toge", + "toile", + "toiser", + "toiture", + "tomber", + "tome", + "tonne", + "tonte", + "toque", + "torse", + "tortue", + "totem", + "toucher", + "toujours", + "tour", + "tousser", + "tout", + "toux", + "trace", + "train", + "trame", + "tranquille", + "travail", + "trembler", + "trente", + "tribu", + "trier", + "trio", + "tripe", + "triste", + "troc", + "trois", + "tromper", + "tronc", + "trop", + "trotter", + "trouer", + "truc", + "truite", + "tuba", + "tuer", + "tuile", + "turbo", + "tutu", + "tuyau", + "type", + "union", + "unique", + "unir", + "unisson", + "untel", + "urne", + "usage", + "user", + "usiner", + "usure", + "utile", + "vache", + "vague", + "vaincre", + "valeur", + "valoir", + "valser", + "valve", + "vampire", + "vaseux", + "vaste", + "veau", + "veille", + "veine", + "velours", + "velu", + "vendre", + "venir", + "vent", + "venue", + "verbe", + "verdict", + "version", + "vertige", + "verve", + "veste", + "veto", + "vexer", + "vice", + "victime", + "vide", + "vieil", + "vieux", + "vigie", + "vigne", + "ville", + "vingt", + "violent", + "virer", + "virus", + "visage", + "viser", + "visite", + "visuel", + "vitamine", + "vitrine", + "vivant", + "vivre", + "vocal", + "vodka", + "vogue", + "voici", + "voile", + "voir", + "voisin", + "voiture", + "volaille", + "volcan", + "voler", + "volt", + "votant", + "votre", + "vouer", + "vouloir", + "vous", + "voyage", + "voyou", + "vrac", + "vrai", + "yacht", + "yeti", + "yeux", + "yoga", + "zeste", + "zinc", + "zone", + "zoom" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/it.json b/coins/monero/src/wallet/seed/classic/it.json new file mode 100644 index 00000000..8c015c31 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/it.json @@ -0,0 +1,1628 @@ +[ + "abbinare", + "abbonato", + "abisso", + "abitare", + "abominio", + "accadere", + "accesso", + "acciaio", + "accordo", + "accumulo", + "acido", + "acqua", + "acrobata", + "acustico", + "adattare", + "addetto", + "addio", + "addome", + "adeguato", + "aderire", + "adorare", + "adottare", + "adozione", + "adulto", + "aereo", + "aerobica", + "affare", + "affetto", + "affidare", + "affogato", + "affronto", + "africano", + "afrodite", + "agenzia", + "aggancio", + "aggeggio", + "aggiunta", + "agio", + "agire", + "agitare", + "aglio", + "agnello", + "agosto", + "aiutare", + "albero", + "albo", + "alce", + "alchimia", + "alcool", + "alfabeto", + "algebra", + "alimento", + "allarme", + "alleanza", + "allievo", + "alloggio", + "alluce", + "alpi", + "alterare", + "altro", + "aluminio", + "amante", + "amarezza", + "ambiente", + "ambrosia", + "america", + "amico", + "ammalare", + "ammirare", + "amnesia", + "amnistia", + "amore", + "ampliare", + "amputare", + "analisi", + "anamnesi", + "ananas", + "anarchia", + "anatra", + "anca", + "ancorato", + "andare", + "androide", + "aneddoto", + "anello", + "angelo", + "angolino", + "anguilla", + "anidride", + "anima", + "annegare", + "anno", + "annuncio", + "anomalia", + "antenna", + "anticipo", + "aperto", + "apostolo", + "appalto", + "appello", + "appiglio", + "applauso", + "appoggio", + "appurare", + "aprile", + "aquila", + "arabo", + "arachidi", + "aragosta", + "arancia", + "arbitrio", + "archivio", + "arco", + "argento", + "argilla", + "aria", + "ariete", + "arma", + "armonia", + "aroma", + "arrivare", + "arrosto", + "arsenale", + "arte", + "artiglio", + "asfalto", + "asfissia", + "asino", + "asparagi", + "aspirina", + "assalire", + "assegno", + "assolto", + "assurdo", + "asta", + "astratto", + "atlante", + "atletica", + "atomo", + "atropina", + "attacco", + "attesa", + "attico", + "atto", + "attrarre", + "auguri", + "aula", + "aumento", + "aurora", + "auspicio", + "autista", + "auto", + "autunno", + "avanzare", + "avarizia", + "avere", + "aviatore", + "avido", + "avorio", + "avvenire", + "avviso", + "avvocato", + "azienda", + "azione", + "azzardo", + "azzurro", + "babbuino", + "bacio", + "badante", + "baffi", + "bagaglio", + "bagliore", + "bagno", + "balcone", + "balena", + "ballare", + "balordo", + "balsamo", + "bambola", + "bancomat", + "banda", + "barato", + "barba", + "barista", + "barriera", + "basette", + "basilico", + "bassista", + "bastare", + "battello", + "bavaglio", + "beccare", + "beduino", + "bellezza", + "bene", + "benzina", + "berretto", + "bestia", + "bevitore", + "bianco", + "bibbia", + "biberon", + "bibita", + "bici", + "bidone", + "bilancia", + "biliardo", + "binario", + "binocolo", + "biologia", + "biondina", + "biopsia", + "biossido", + "birbante", + "birra", + "biscotto", + "bisogno", + "bistecca", + "bivio", + "blindare", + "bloccare", + "bocca", + "bollire", + "bombola", + "bonifico", + "borghese", + "borsa", + "bottino", + "botulino", + "braccio", + "bradipo", + "branco", + "bravo", + "bresaola", + "bretelle", + "brevetto", + "briciola", + "brigante", + "brillare", + "brindare", + "brivido", + "broccoli", + "brontolo", + "bruciare", + "brufolo", + "bucare", + "buddista", + "budino", + "bufera", + "buffo", + "bugiardo", + "buio", + "buono", + "burrone", + "bussola", + "bustina", + "buttare", + "cabernet", + "cabina", + "cacao", + "cacciare", + "cactus", + "cadavere", + "caffe", + "calamari", + "calcio", + "caldaia", + "calmare", + "calunnia", + "calvario", + "calzone", + "cambiare", + "camera", + "camion", + "cammello", + "campana", + "canarino", + "cancello", + "candore", + "cane", + "canguro", + "cannone", + "canoa", + "cantare", + "canzone", + "caos", + "capanna", + "capello", + "capire", + "capo", + "capperi", + "capra", + "capsula", + "caraffa", + "carbone", + "carciofo", + "cardigan", + "carenza", + "caricare", + "carota", + "carrello", + "carta", + "casa", + "cascare", + "caserma", + "cashmere", + "casino", + "cassetta", + "castello", + "catalogo", + "catena", + "catorcio", + "cattivo", + "causa", + "cauzione", + "cavallo", + "caverna", + "caviglia", + "cavo", + "cazzotto", + "celibato", + "cemento", + "cenare", + "centrale", + "ceramica", + "cercare", + "ceretta", + "cerniera", + "certezza", + "cervello", + "cessione", + "cestino", + "cetriolo", + "chiave", + "chiedere", + "chilo", + "chimera", + "chiodo", + "chirurgo", + "chitarra", + "chiudere", + "ciabatta", + "ciao", + "cibo", + "ciccia", + "cicerone", + "ciclone", + "cicogna", + "cielo", + "cifra", + "cigno", + "ciliegia", + "cimitero", + "cinema", + "cinque", + "cintura", + "ciondolo", + "ciotola", + "cipolla", + "cippato", + "circuito", + "cisterna", + "citofono", + "ciuccio", + "civetta", + "civico", + "clausola", + "cliente", + "clima", + "clinica", + "cobra", + "coccole", + "cocktail", + "cocomero", + "codice", + "coesione", + "cogliere", + "cognome", + "colla", + "colomba", + "colpire", + "coltello", + "comando", + "comitato", + "commedia", + "comodino", + "compagna", + "comune", + "concerto", + "condotto", + "conforto", + "congiura", + "coniglio", + "consegna", + "conto", + "convegno", + "coperta", + "copia", + "coprire", + "corazza", + "corda", + "corleone", + "cornice", + "corona", + "corpo", + "corrente", + "corsa", + "cortesia", + "corvo", + "coso", + "costume", + "cotone", + "cottura", + "cozza", + "crampo", + "cratere", + "cravatta", + "creare", + "credere", + "crema", + "crescere", + "crimine", + "criterio", + "croce", + "crollare", + "cronaca", + "crostata", + "croupier", + "cubetto", + "cucciolo", + "cucina", + "cultura", + "cuoco", + "cuore", + "cupido", + "cupola", + "cura", + "curva", + "cuscino", + "custode", + "danzare", + "data", + "decennio", + "decidere", + "decollo", + "dedicare", + "dedurre", + "definire", + "delegare", + "delfino", + "delitto", + "demone", + "dentista", + "denuncia", + "deposito", + "derivare", + "deserto", + "designer", + "destino", + "detonare", + "dettagli", + "diagnosi", + "dialogo", + "diamante", + "diario", + "diavolo", + "dicembre", + "difesa", + "digerire", + "digitare", + "diluvio", + "dinamica", + "dipinto", + "diploma", + "diramare", + "dire", + "dirigere", + "dirupo", + "discesa", + "disdetta", + "disegno", + "disporre", + "dissenso", + "distacco", + "dito", + "ditta", + "diva", + "divenire", + "dividere", + "divorare", + "docente", + "dolcetto", + "dolore", + "domatore", + "domenica", + "dominare", + "donatore", + "donna", + "dorato", + "dormire", + "dorso", + "dosaggio", + "dottore", + "dovere", + "download", + "dragone", + "dramma", + "dubbio", + "dubitare", + "duetto", + "durata", + "ebbrezza", + "eccesso", + "eccitare", + "eclissi", + "economia", + "edera", + "edificio", + "editore", + "edizione", + "educare", + "effetto", + "egitto", + "egiziano", + "elastico", + "elefante", + "eleggere", + "elemento", + "elenco", + "elezione", + "elmetto", + "elogio", + "embrione", + "emergere", + "emettere", + "eminenza", + "emisfero", + "emozione", + "empatia", + "energia", + "enfasi", + "enigma", + "entrare", + "enzima", + "epidemia", + "epilogo", + "episodio", + "epoca", + "equivoco", + "erba", + "erede", + "eroe", + "erotico", + "errore", + "eruzione", + "esaltare", + "esame", + "esaudire", + "eseguire", + "esempio", + "esigere", + "esistere", + "esito", + "esperto", + "espresso", + "essere", + "estasi", + "esterno", + "estrarre", + "eterno", + "etica", + "euforico", + "europa", + "evacuare", + "evasione", + "evento", + "evidenza", + "evitare", + "evolvere", + "fabbrica", + "facciata", + "fagiano", + "fagotto", + "falco", + "fame", + "famiglia", + "fanale", + "fango", + "fantasia", + "farfalla", + "farmacia", + "faro", + "fase", + "fastidio", + "faticare", + "fatto", + "favola", + "febbre", + "femmina", + "femore", + "fenomeno", + "fermata", + "feromoni", + "ferrari", + "fessura", + "festa", + "fiaba", + "fiamma", + "fianco", + "fiat", + "fibbia", + "fidare", + "fieno", + "figa", + "figlio", + "figura", + "filetto", + "filmato", + "filosofo", + "filtrare", + "finanza", + "finestra", + "fingere", + "finire", + "finta", + "finzione", + "fiocco", + "fioraio", + "firewall", + "firmare", + "fisico", + "fissare", + "fittizio", + "fiume", + "flacone", + "flagello", + "flirtare", + "flusso", + "focaccia", + "foglio", + "fognario", + "follia", + "fonderia", + "fontana", + "forbici", + "forcella", + "foresta", + "forgiare", + "formare", + "fornace", + "foro", + "fortuna", + "forzare", + "fosforo", + "fotoni", + "fracasso", + "fragola", + "frantumi", + "fratello", + "frazione", + "freccia", + "freddo", + "frenare", + "fresco", + "friggere", + "frittata", + "frivolo", + "frizione", + "fronte", + "frullato", + "frumento", + "frusta", + "frutto", + "fucile", + "fuggire", + "fulmine", + "fumare", + "funzione", + "fuoco", + "furbizia", + "furgone", + "furia", + "furore", + "fusibile", + "fuso", + "futuro", + "gabbiano", + "galassia", + "gallina", + "gamba", + "gancio", + "garanzia", + "garofano", + "gasolio", + "gatto", + "gazebo", + "gazzetta", + "gelato", + "gemelli", + "generare", + "genitori", + "gennaio", + "geologia", + "germania", + "gestire", + "gettare", + "ghepardo", + "ghiaccio", + "giaccone", + "giaguaro", + "giallo", + "giappone", + "giardino", + "gigante", + "gioco", + "gioiello", + "giorno", + "giovane", + "giraffa", + "giudizio", + "giurare", + "giusto", + "globo", + "gloria", + "glucosio", + "gnocca", + "gocciola", + "godere", + "gomito", + "gomma", + "gonfiare", + "gorilla", + "governo", + "gradire", + "graffiti", + "granchio", + "grappolo", + "grasso", + "grattare", + "gridare", + "grissino", + "grondaia", + "grugnito", + "gruppo", + "guadagno", + "guaio", + "guancia", + "guardare", + "gufo", + "guidare", + "guscio", + "gusto", + "icona", + "idea", + "identico", + "idolo", + "idoneo", + "idrante", + "idrogeno", + "igiene", + "ignoto", + "imbarco", + "immagine", + "immobile", + "imparare", + "impedire", + "impianto", + "importo", + "impresa", + "impulso", + "incanto", + "incendio", + "incidere", + "incontro", + "incrocia", + "incubo", + "indagare", + "indice", + "indotto", + "infanzia", + "inferno", + "infinito", + "infranto", + "ingerire", + "inglese", + "ingoiare", + "ingresso", + "iniziare", + "innesco", + "insalata", + "inserire", + "insicuro", + "insonnia", + "insulto", + "interno", + "introiti", + "invasori", + "inverno", + "invito", + "invocare", + "ipnosi", + "ipocrita", + "ipotesi", + "ironia", + "irrigare", + "iscritto", + "isola", + "ispirare", + "isterico", + "istinto", + "istruire", + "italiano", + "jazz", + "labbra", + "labrador", + "ladro", + "lago", + "lamento", + "lampone", + "lancetta", + "lanterna", + "lapide", + "larva", + "lasagne", + "lasciare", + "lastra", + "latte", + "laurea", + "lavagna", + "lavorare", + "leccare", + "legare", + "leggere", + "lenzuolo", + "leone", + "lepre", + "letargo", + "lettera", + "levare", + "levitare", + "lezione", + "liberare", + "libidine", + "libro", + "licenza", + "lievito", + "limite", + "lince", + "lingua", + "liquore", + "lire", + "listino", + "litigare", + "litro", + "locale", + "lottare", + "lucciola", + "lucidare", + "luglio", + "luna", + "macchina", + "madama", + "madre", + "maestro", + "maggio", + "magico", + "maglione", + "magnolia", + "mago", + "maialino", + "maionese", + "malattia", + "male", + "malloppo", + "mancare", + "mandorla", + "mangiare", + "manico", + "manopola", + "mansarda", + "mantello", + "manubrio", + "manzo", + "mappa", + "mare", + "margine", + "marinaio", + "marmotta", + "marocco", + "martello", + "marzo", + "maschera", + "matrice", + "maturare", + "mazzetta", + "meandri", + "medaglia", + "medico", + "medusa", + "megafono", + "melone", + "membrana", + "menta", + "mercato", + "meritare", + "merluzzo", + "mese", + "mestiere", + "metafora", + "meteo", + "metodo", + "mettere", + "miele", + "miglio", + "miliardo", + "mimetica", + "minatore", + "minuto", + "miracolo", + "mirtillo", + "missile", + "mistero", + "misura", + "mito", + "mobile", + "moda", + "moderare", + "moglie", + "molecola", + "molle", + "momento", + "moneta", + "mongolia", + "monologo", + "montagna", + "morale", + "morbillo", + "mordere", + "mosaico", + "mosca", + "mostro", + "motivare", + "moto", + "mulino", + "mulo", + "muovere", + "muraglia", + "muscolo", + "museo", + "musica", + "mutande", + "nascere", + "nastro", + "natale", + "natura", + "nave", + "navigare", + "negare", + "negozio", + "nemico", + "nero", + "nervo", + "nessuno", + "nettare", + "neutroni", + "neve", + "nevicare", + "nicotina", + "nido", + "nipote", + "nocciola", + "noleggio", + "nome", + "nonno", + "norvegia", + "notare", + "notizia", + "nove", + "nucleo", + "nuda", + "nuotare", + "nutrire", + "obbligo", + "occhio", + "occupare", + "oceano", + "odissea", + "odore", + "offerta", + "officina", + "offrire", + "oggetto", + "oggi", + "olfatto", + "olio", + "oliva", + "ombelico", + "ombrello", + "omuncolo", + "ondata", + "onore", + "opera", + "opinione", + "opuscolo", + "opzione", + "orario", + "orbita", + "orchidea", + "ordine", + "orecchio", + "orgasmo", + "orgoglio", + "origine", + "orologio", + "oroscopo", + "orso", + "oscurare", + "ospedale", + "ospite", + "ossigeno", + "ostacolo", + "ostriche", + "ottenere", + "ottimo", + "ottobre", + "ovest", + "pacco", + "pace", + "pacifico", + "padella", + "pagare", + "pagina", + "pagnotta", + "palazzo", + "palestra", + "palpebre", + "pancetta", + "panfilo", + "panino", + "pannello", + "panorama", + "papa", + "paperino", + "paradiso", + "parcella", + "parente", + "parlare", + "parodia", + "parrucca", + "partire", + "passare", + "pasta", + "patata", + "patente", + "patogeno", + "patriota", + "pausa", + "pazienza", + "peccare", + "pecora", + "pedalare", + "pelare", + "pena", + "pendenza", + "penisola", + "pennello", + "pensare", + "pentirsi", + "percorso", + "perdono", + "perfetto", + "perizoma", + "perla", + "permesso", + "persona", + "pesare", + "pesce", + "peso", + "petardo", + "petrolio", + "pezzo", + "piacere", + "pianeta", + "piastra", + "piatto", + "piazza", + "piccolo", + "piede", + "piegare", + "pietra", + "pigiama", + "pigliare", + "pigrizia", + "pilastro", + "pilota", + "pinguino", + "pioggia", + "piombo", + "pionieri", + "piovra", + "pipa", + "pirata", + "pirolisi", + "piscina", + "pisolino", + "pista", + "pitone", + "piumino", + "pizza", + "plastica", + "platino", + "poesia", + "poiana", + "polaroid", + "polenta", + "polimero", + "pollo", + "polmone", + "polpetta", + "poltrona", + "pomodoro", + "pompa", + "popolo", + "porco", + "porta", + "porzione", + "possesso", + "postino", + "potassio", + "potere", + "poverino", + "pranzo", + "prato", + "prefisso", + "prelievo", + "premio", + "prendere", + "prestare", + "pretesa", + "prezzo", + "primario", + "privacy", + "problema", + "processo", + "prodotto", + "profeta", + "progetto", + "promessa", + "pronto", + "proposta", + "proroga", + "prossimo", + "proteina", + "prova", + "prudenza", + "pubblico", + "pudore", + "pugilato", + "pulire", + "pulsante", + "puntare", + "pupazzo", + "puzzle", + "quaderno", + "qualcuno", + "quarzo", + "quercia", + "quintale", + "rabbia", + "racconto", + "radice", + "raffica", + "ragazza", + "ragione", + "rammento", + "ramo", + "rana", + "randagio", + "rapace", + "rapinare", + "rapporto", + "rasatura", + "ravioli", + "reagire", + "realista", + "reattore", + "reazione", + "recitare", + "recluso", + "record", + "recupero", + "redigere", + "regalare", + "regina", + "regola", + "relatore", + "reliquia", + "remare", + "rendere", + "reparto", + "resina", + "resto", + "rete", + "retorica", + "rettile", + "revocare", + "riaprire", + "ribadire", + "ribelle", + "ricambio", + "ricetta", + "richiamo", + "ricordo", + "ridurre", + "riempire", + "riferire", + "riflesso", + "righello", + "rilancio", + "rilevare", + "rilievo", + "rimanere", + "rimborso", + "rinforzo", + "rinuncia", + "riparo", + "ripetere", + "riposare", + "ripulire", + "risalita", + "riscatto", + "riserva", + "riso", + "rispetto", + "ritaglio", + "ritmo", + "ritorno", + "ritratto", + "rituale", + "riunione", + "riuscire", + "riva", + "robotica", + "rondine", + "rosa", + "rospo", + "rosso", + "rotonda", + "rotta", + "roulotte", + "rubare", + "rubrica", + "ruffiano", + "rumore", + "ruota", + "ruscello", + "sabbia", + "sacco", + "saggio", + "sale", + "salire", + "salmone", + "salto", + "salutare", + "salvia", + "sangue", + "sanzioni", + "sapere", + "sapienza", + "sarcasmo", + "sardine", + "sartoria", + "sbalzo", + "sbarcare", + "sberla", + "sborsare", + "scadenza", + "scafo", + "scala", + "scambio", + "scappare", + "scarpa", + "scatola", + "scelta", + "scena", + "sceriffo", + "scheggia", + "schiuma", + "sciarpa", + "scienza", + "scimmia", + "sciopero", + "scivolo", + "sclerare", + "scolpire", + "sconto", + "scopa", + "scordare", + "scossa", + "scrivere", + "scrupolo", + "scuderia", + "scultore", + "scuola", + "scusare", + "sdraiare", + "secolo", + "sedativo", + "sedere", + "sedia", + "segare", + "segreto", + "seguire", + "semaforo", + "seme", + "senape", + "seno", + "sentiero", + "separare", + "sepolcro", + "sequenza", + "serata", + "serpente", + "servizio", + "sesso", + "seta", + "settore", + "sfamare", + "sfera", + "sfidare", + "sfiorare", + "sfogare", + "sgabello", + "sicuro", + "siepe", + "sigaro", + "silenzio", + "silicone", + "simbiosi", + "simpatia", + "simulare", + "sinapsi", + "sindrome", + "sinergia", + "sinonimo", + "sintonia", + "sirena", + "siringa", + "sistema", + "sito", + "smalto", + "smentire", + "smontare", + "soccorso", + "socio", + "soffitto", + "software", + "soggetto", + "sogliola", + "sognare", + "soldi", + "sole", + "sollievo", + "solo", + "sommario", + "sondare", + "sonno", + "sorpresa", + "sorriso", + "sospiro", + "sostegno", + "sovrano", + "spaccare", + "spada", + "spagnolo", + "spalla", + "sparire", + "spavento", + "spazio", + "specchio", + "spedire", + "spegnere", + "spendere", + "speranza", + "spessore", + "spezzare", + "spiaggia", + "spiccare", + "spiegare", + "spiffero", + "spingere", + "sponda", + "sporcare", + "spostare", + "spremuta", + "spugna", + "spumante", + "spuntare", + "squadra", + "squillo", + "staccare", + "stadio", + "stagione", + "stallone", + "stampa", + "stancare", + "starnuto", + "statura", + "stella", + "stendere", + "sterzo", + "stilista", + "stimolo", + "stinco", + "stiva", + "stoffa", + "storia", + "strada", + "stregone", + "striscia", + "studiare", + "stufa", + "stupendo", + "subire", + "successo", + "sudare", + "suono", + "superare", + "supporto", + "surfista", + "sussurro", + "svelto", + "svenire", + "sviluppo", + "svolta", + "svuotare", + "tabacco", + "tabella", + "tabu", + "tacchino", + "tacere", + "taglio", + "talento", + "tangente", + "tappeto", + "tartufo", + "tassello", + "tastiera", + "tavolo", + "tazza", + "teatro", + "tedesco", + "telaio", + "telefono", + "tema", + "temere", + "tempo", + "tendenza", + "tenebre", + "tensione", + "tentare", + "teologia", + "teorema", + "termica", + "terrazzo", + "teschio", + "tesi", + "tesoro", + "tessera", + "testa", + "thriller", + "tifoso", + "tigre", + "timbrare", + "timido", + "tinta", + "tirare", + "tisana", + "titano", + "titolo", + "toccare", + "togliere", + "topolino", + "torcia", + "torrente", + "tovaglia", + "traffico", + "tragitto", + "training", + "tramonto", + "transito", + "trapezio", + "trasloco", + "trattore", + "trazione", + "treccia", + "tregua", + "treno", + "triciclo", + "tridente", + "trilogia", + "tromba", + "troncare", + "trota", + "trovare", + "trucco", + "tubo", + "tulipano", + "tumulto", + "tunisia", + "tuono", + "turista", + "tuta", + "tutelare", + "tutore", + "ubriaco", + "uccello", + "udienza", + "udito", + "uffa", + "umanoide", + "umore", + "unghia", + "unguento", + "unicorno", + "unione", + "universo", + "uomo", + "uragano", + "uranio", + "urlare", + "uscire", + "utente", + "utilizzo", + "vacanza", + "vacca", + "vaglio", + "vagonata", + "valle", + "valore", + "valutare", + "valvola", + "vampiro", + "vaniglia", + "vanto", + "vapore", + "variante", + "vasca", + "vaselina", + "vassoio", + "vedere", + "vegetale", + "veglia", + "veicolo", + "vela", + "veleno", + "velivolo", + "velluto", + "vendere", + "venerare", + "venire", + "vento", + "veranda", + "verbo", + "verdura", + "vergine", + "verifica", + "vernice", + "vero", + "verruca", + "versare", + "vertebra", + "vescica", + "vespaio", + "vestito", + "vesuvio", + "veterano", + "vetro", + "vetta", + "viadotto", + "viaggio", + "vibrare", + "vicenda", + "vichingo", + "vietare", + "vigilare", + "vigneto", + "villa", + "vincere", + "violino", + "vipera", + "virgola", + "virtuoso", + "visita", + "vita", + "vitello", + "vittima", + "vivavoce", + "vivere", + "viziato", + "voglia", + "volare", + "volpe", + "volto", + "volume", + "vongole", + "voragine", + "vortice", + "votare", + "vulcano", + "vuotare", + "zabaione", + "zaffiro", + "zainetto", + "zampa", + "zanzara", + "zattera", + "zavorra", + "zenzero", + "zero", + "zingaro", + "zittire", + "zoccolo", + "zolfo", + "zombie", + "zucchero" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/ja.json b/coins/monero/src/wallet/seed/classic/ja.json new file mode 100644 index 00000000..439e6f72 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/ja.json @@ -0,0 +1,1628 @@ +[ + "あいこくしん", + "あいさつ", + "あいだ", + "あおぞら", + "あかちゃん", + "あきる", + "あけがた", + "あける", + "あこがれる", + "あさい", + "あさひ", + "あしあと", + "あじわう", + "あずかる", + "あずき", + "あそぶ", + "あたえる", + "あたためる", + "あたりまえ", + "あたる", + "あつい", + "あつかう", + "あっしゅく", + "あつまり", + "あつめる", + "あてな", + "あてはまる", + "あひる", + "あぶら", + "あぶる", + "あふれる", + "あまい", + "あまど", + "あまやかす", + "あまり", + "あみもの", + "あめりか", + "あやまる", + "あゆむ", + "あらいぐま", + "あらし", + "あらすじ", + "あらためる", + "あらゆる", + "あらわす", + "ありがとう", + "あわせる", + "あわてる", + "あんい", + "あんがい", + "あんこ", + "あんぜん", + "あんてい", + "あんない", + "あんまり", + "いいだす", + "いおん", + "いがい", + "いがく", + "いきおい", + "いきなり", + "いきもの", + "いきる", + "いくじ", + "いくぶん", + "いけばな", + "いけん", + "いこう", + "いこく", + "いこつ", + "いさましい", + "いさん", + "いしき", + "いじゅう", + "いじょう", + "いじわる", + "いずみ", + "いずれ", + "いせい", + "いせえび", + "いせかい", + "いせき", + "いぜん", + "いそうろう", + "いそがしい", + "いだい", + "いだく", + "いたずら", + "いたみ", + "いたりあ", + "いちおう", + "いちじ", + "いちど", + "いちば", + "いちぶ", + "いちりゅう", + "いつか", + "いっしゅん", + "いっせい", + "いっそう", + "いったん", + "いっち", + "いってい", + "いっぽう", + "いてざ", + "いてん", + "いどう", + "いとこ", + "いない", + "いなか", + "いねむり", + "いのち", + "いのる", + "いはつ", + "いばる", + "いはん", + "いびき", + "いひん", + "いふく", + "いへん", + "いほう", + "いみん", + "いもうと", + "いもたれ", + "いもり", + "いやがる", + "いやす", + "いよかん", + "いよく", + "いらい", + "いらすと", + "いりぐち", + "いりょう", + "いれい", + "いれもの", + "いれる", + "いろえんぴつ", + "いわい", + "いわう", + "いわかん", + "いわば", + "いわゆる", + "いんげんまめ", + "いんさつ", + "いんしょう", + "いんよう", + "うえき", + "うえる", + "うおざ", + "うがい", + "うかぶ", + "うかべる", + "うきわ", + "うくらいな", + "うくれれ", + "うけたまわる", + "うけつけ", + "うけとる", + "うけもつ", + "うける", + "うごかす", + "うごく", + "うこん", + "うさぎ", + "うしなう", + "うしろがみ", + "うすい", + "うすぎ", + "うすぐらい", + "うすめる", + "うせつ", + "うちあわせ", + "うちがわ", + "うちき", + "うちゅう", + "うっかり", + "うつくしい", + "うったえる", + "うつる", + "うどん", + "うなぎ", + "うなじ", + "うなずく", + "うなる", + "うねる", + "うのう", + "うぶげ", + "うぶごえ", + "うまれる", + "うめる", + "うもう", + "うやまう", + "うよく", + "うらがえす", + "うらぐち", + "うらない", + "うりあげ", + "うりきれ", + "うるさい", + "うれしい", + "うれゆき", + "うれる", + "うろこ", + "うわき", + "うわさ", + "うんこう", + "うんちん", + "うんてん", + "うんどう", + "えいえん", + "えいが", + "えいきょう", + "えいご", + "えいせい", + "えいぶん", + "えいよう", + "えいわ", + "えおり", + "えがお", + "えがく", + "えきたい", + "えくせる", + "えしゃく", + "えすて", + "えつらん", + "えのぐ", + "えほうまき", + "えほん", + "えまき", + "えもじ", + "えもの", + "えらい", + "えらぶ", + "えりあ", + "えんえん", + "えんかい", + "えんぎ", + "えんげき", + "えんしゅう", + "えんぜつ", + "えんそく", + "えんちょう", + "えんとつ", + "おいかける", + "おいこす", + "おいしい", + "おいつく", + "おうえん", + "おうさま", + "おうじ", + "おうせつ", + "おうたい", + "おうふく", + "おうべい", + "おうよう", + "おえる", + "おおい", + "おおう", + "おおどおり", + "おおや", + "おおよそ", + "おかえり", + "おかず", + "おがむ", + "おかわり", + "おぎなう", + "おきる", + "おくさま", + "おくじょう", + "おくりがな", + "おくる", + "おくれる", + "おこす", + "おこなう", + "おこる", + "おさえる", + "おさない", + "おさめる", + "おしいれ", + "おしえる", + "おじぎ", + "おじさん", + "おしゃれ", + "おそらく", + "おそわる", + "おたがい", + "おたく", + "おだやか", + "おちつく", + "おっと", + "おつり", + "おでかけ", + "おとしもの", + "おとなしい", + "おどり", + "おどろかす", + "おばさん", + "おまいり", + "おめでとう", + "おもいで", + "おもう", + "おもたい", + "おもちゃ", + "おやつ", + "おやゆび", + "およぼす", + "おらんだ", + "おろす", + "おんがく", + "おんけい", + "おんしゃ", + "おんせん", + "おんだん", + "おんちゅう", + "おんどけい", + "かあつ", + "かいが", + "がいき", + "がいけん", + "がいこう", + "かいさつ", + "かいしゃ", + "かいすいよく", + "かいぜん", + "かいぞうど", + "かいつう", + "かいてん", + "かいとう", + "かいふく", + "がいへき", + "かいほう", + "かいよう", + "がいらい", + "かいわ", + "かえる", + "かおり", + "かかえる", + "かがく", + "かがし", + "かがみ", + "かくご", + "かくとく", + "かざる", + "がぞう", + "かたい", + "かたち", + "がちょう", + "がっきゅう", + "がっこう", + "がっさん", + "がっしょう", + "かなざわし", + "かのう", + "がはく", + "かぶか", + "かほう", + "かほご", + "かまう", + "かまぼこ", + "かめれおん", + "かゆい", + "かようび", + "からい", + "かるい", + "かろう", + "かわく", + "かわら", + "がんか", + "かんけい", + "かんこう", + "かんしゃ", + "かんそう", + "かんたん", + "かんち", + "がんばる", + "きあい", + "きあつ", + "きいろ", + "ぎいん", + "きうい", + "きうん", + "きえる", + "きおう", + "きおく", + "きおち", + "きおん", + "きかい", + "きかく", + "きかんしゃ", + "ききて", + "きくばり", + "きくらげ", + "きけんせい", + "きこう", + "きこえる", + "きこく", + "きさい", + "きさく", + "きさま", + "きさらぎ", + "ぎじかがく", + "ぎしき", + "ぎじたいけん", + "ぎじにってい", + "ぎじゅつしゃ", + "きすう", + "きせい", + "きせき", + "きせつ", + "きそう", + "きぞく", + "きぞん", + "きたえる", + "きちょう", + "きつえん", + "ぎっちり", + "きつつき", + "きつね", + "きてい", + "きどう", + "きどく", + "きない", + "きなが", + "きなこ", + "きぬごし", + "きねん", + "きのう", + "きのした", + "きはく", + "きびしい", + "きひん", + "きふく", + "きぶん", + "きぼう", + "きほん", + "きまる", + "きみつ", + "きむずかしい", + "きめる", + "きもだめし", + "きもち", + "きもの", + "きゃく", + "きやく", + "ぎゅうにく", + "きよう", + "きょうりゅう", + "きらい", + "きらく", + "きりん", + "きれい", + "きれつ", + "きろく", + "ぎろん", + "きわめる", + "ぎんいろ", + "きんかくじ", + "きんじょ", + "きんようび", + "ぐあい", + "くいず", + "くうかん", + "くうき", + "くうぐん", + "くうこう", + "ぐうせい", + "くうそう", + "ぐうたら", + "くうふく", + "くうぼ", + "くかん", + "くきょう", + "くげん", + "ぐこう", + "くさい", + "くさき", + "くさばな", + "くさる", + "くしゃみ", + "くしょう", + "くすのき", + "くすりゆび", + "くせげ", + "くせん", + "ぐたいてき", + "くださる", + "くたびれる", + "くちこみ", + "くちさき", + "くつした", + "ぐっすり", + "くつろぐ", + "くとうてん", + "くどく", + "くなん", + "くねくね", + "くのう", + "くふう", + "くみあわせ", + "くみたてる", + "くめる", + "くやくしょ", + "くらす", + "くらべる", + "くるま", + "くれる", + "くろう", + "くわしい", + "ぐんかん", + "ぐんしょく", + "ぐんたい", + "ぐんて", + "けあな", + "けいかく", + "けいけん", + "けいこ", + "けいさつ", + "げいじゅつ", + "けいたい", + "げいのうじん", + "けいれき", + "けいろ", + "けおとす", + "けおりもの", + "げきか", + "げきげん", + "げきだん", + "げきちん", + "げきとつ", + "げきは", + "げきやく", + "げこう", + "げこくじょう", + "げざい", + "けさき", + "げざん", + "けしき", + "けしごむ", + "けしょう", + "げすと", + "けたば", + "けちゃっぷ", + "けちらす", + "けつあつ", + "けつい", + "けつえき", + "けっこん", + "けつじょ", + "けっせき", + "けってい", + "けつまつ", + "げつようび", + "げつれい", + "けつろん", + "げどく", + "けとばす", + "けとる", + "けなげ", + "けなす", + "けなみ", + "けぬき", + "げねつ", + "けねん", + "けはい", + "げひん", + "けぶかい", + "げぼく", + "けまり", + "けみかる", + "けむし", + "けむり", + "けもの", + "けらい", + "けろけろ", + "けわしい", + "けんい", + "けんえつ", + "けんお", + "けんか", + "げんき", + "けんげん", + "けんこう", + "けんさく", + "けんしゅう", + "けんすう", + "げんそう", + "けんちく", + "けんてい", + "けんとう", + "けんない", + "けんにん", + "げんぶつ", + "けんま", + "けんみん", + "けんめい", + "けんらん", + "けんり", + "こあくま", + "こいぬ", + "こいびと", + "ごうい", + "こうえん", + "こうおん", + "こうかん", + "ごうきゅう", + "ごうけい", + "こうこう", + "こうさい", + "こうじ", + "こうすい", + "ごうせい", + "こうそく", + "こうたい", + "こうちゃ", + "こうつう", + "こうてい", + "こうどう", + "こうない", + "こうはい", + "ごうほう", + "ごうまん", + "こうもく", + "こうりつ", + "こえる", + "こおり", + "ごかい", + "ごがつ", + "ごかん", + "こくご", + "こくさい", + "こくとう", + "こくない", + "こくはく", + "こぐま", + "こけい", + "こける", + "ここのか", + "こころ", + "こさめ", + "こしつ", + "こすう", + "こせい", + "こせき", + "こぜん", + "こそだて", + "こたい", + "こたえる", + "こたつ", + "こちょう", + "こっか", + "こつこつ", + "こつばん", + "こつぶ", + "こてい", + "こてん", + "ことがら", + "ことし", + "ことば", + "ことり", + "こなごな", + "こねこね", + "このまま", + "このみ", + "このよ", + "ごはん", + "こひつじ", + "こふう", + "こふん", + "こぼれる", + "ごまあぶら", + "こまかい", + "ごますり", + "こまつな", + "こまる", + "こむぎこ", + "こもじ", + "こもち", + "こもの", + "こもん", + "こやく", + "こやま", + "こゆう", + "こゆび", + "こよい", + "こよう", + "こりる", + "これくしょん", + "ころっけ", + "こわもて", + "こわれる", + "こんいん", + "こんかい", + "こんき", + "こんしゅう", + "こんすい", + "こんだて", + "こんとん", + "こんなん", + "こんびに", + "こんぽん", + "こんまけ", + "こんや", + "こんれい", + "こんわく", + "ざいえき", + "さいかい", + "さいきん", + "ざいげん", + "ざいこ", + "さいしょ", + "さいせい", + "ざいたく", + "ざいちゅう", + "さいてき", + "ざいりょう", + "さうな", + "さかいし", + "さがす", + "さかな", + "さかみち", + "さがる", + "さぎょう", + "さくし", + "さくひん", + "さくら", + "さこく", + "さこつ", + "さずかる", + "ざせき", + "さたん", + "さつえい", + "ざつおん", + "ざっか", + "ざつがく", + "さっきょく", + "ざっし", + "さつじん", + "ざっそう", + "さつたば", + "さつまいも", + "さてい", + "さといも", + "さとう", + "さとおや", + "さとし", + "さとる", + "さのう", + "さばく", + "さびしい", + "さべつ", + "さほう", + "さほど", + "さます", + "さみしい", + "さみだれ", + "さむけ", + "さめる", + "さやえんどう", + "さゆう", + "さよう", + "さよく", + "さらだ", + "ざるそば", + "さわやか", + "さわる", + "さんいん", + "さんか", + "さんきゃく", + "さんこう", + "さんさい", + "ざんしょ", + "さんすう", + "さんせい", + "さんそ", + "さんち", + "さんま", + "さんみ", + "さんらん", + "しあい", + "しあげ", + "しあさって", + "しあわせ", + "しいく", + "しいん", + "しうち", + "しえい", + "しおけ", + "しかい", + "しかく", + "じかん", + "しごと", + "しすう", + "じだい", + "したうけ", + "したぎ", + "したて", + "したみ", + "しちょう", + "しちりん", + "しっかり", + "しつじ", + "しつもん", + "してい", + "してき", + "してつ", + "じてん", + "じどう", + "しなぎれ", + "しなもの", + "しなん", + "しねま", + "しねん", + "しのぐ", + "しのぶ", + "しはい", + "しばかり", + "しはつ", + "しはらい", + "しはん", + "しひょう", + "しふく", + "じぶん", + "しへい", + "しほう", + "しほん", + "しまう", + "しまる", + "しみん", + "しむける", + "じむしょ", + "しめい", + "しめる", + "しもん", + "しゃいん", + "しゃうん", + "しゃおん", + "じゃがいも", + "しやくしょ", + "しゃくほう", + "しゃけん", + "しゃこ", + "しゃざい", + "しゃしん", + "しゃせん", + "しゃそう", + "しゃたい", + "しゃちょう", + "しゃっきん", + "じゃま", + "しゃりん", + "しゃれい", + "じゆう", + "じゅうしょ", + "しゅくはく", + "じゅしん", + "しゅっせき", + "しゅみ", + "しゅらば", + "じゅんばん", + "しょうかい", + "しょくたく", + "しょっけん", + "しょどう", + "しょもつ", + "しらせる", + "しらべる", + "しんか", + "しんこう", + "じんじゃ", + "しんせいじ", + "しんちく", + "しんりん", + "すあげ", + "すあし", + "すあな", + "ずあん", + "すいえい", + "すいか", + "すいとう", + "ずいぶん", + "すいようび", + "すうがく", + "すうじつ", + "すうせん", + "すおどり", + "すきま", + "すくう", + "すくない", + "すける", + "すごい", + "すこし", + "ずさん", + "すずしい", + "すすむ", + "すすめる", + "すっかり", + "ずっしり", + "ずっと", + "すてき", + "すてる", + "すねる", + "すのこ", + "すはだ", + "すばらしい", + "ずひょう", + "ずぶぬれ", + "すぶり", + "すふれ", + "すべて", + "すべる", + "ずほう", + "すぼん", + "すまい", + "すめし", + "すもう", + "すやき", + "すらすら", + "するめ", + "すれちがう", + "すろっと", + "すわる", + "すんぜん", + "すんぽう", + "せあぶら", + "せいかつ", + "せいげん", + "せいじ", + "せいよう", + "せおう", + "せかいかん", + "せきにん", + "せきむ", + "せきゆ", + "せきらんうん", + "せけん", + "せこう", + "せすじ", + "せたい", + "せたけ", + "せっかく", + "せっきゃく", + "ぜっく", + "せっけん", + "せっこつ", + "せっさたくま", + "せつぞく", + "せつだん", + "せつでん", + "せっぱん", + "せつび", + "せつぶん", + "せつめい", + "せつりつ", + "せなか", + "せのび", + "せはば", + "せびろ", + "せぼね", + "せまい", + "せまる", + "せめる", + "せもたれ", + "せりふ", + "ぜんあく", + "せんい", + "せんえい", + "せんか", + "せんきょ", + "せんく", + "せんげん", + "ぜんご", + "せんさい", + "せんしゅ", + "せんすい", + "せんせい", + "せんぞ", + "せんたく", + "せんちょう", + "せんてい", + "せんとう", + "せんぬき", + "せんねん", + "せんぱい", + "ぜんぶ", + "ぜんぽう", + "せんむ", + "せんめんじょ", + "せんもん", + "せんやく", + "せんゆう", + "せんよう", + "ぜんら", + "ぜんりゃく", + "せんれい", + "せんろ", + "そあく", + "そいとげる", + "そいね", + "そうがんきょう", + "そうき", + "そうご", + "そうしん", + "そうだん", + "そうなん", + "そうび", + "そうめん", + "そうり", + "そえもの", + "そえん", + "そがい", + "そげき", + "そこう", + "そこそこ", + "そざい", + "そしな", + "そせい", + "そせん", + "そそぐ", + "そだてる", + "そつう", + "そつえん", + "そっかん", + "そつぎょう", + "そっけつ", + "そっこう", + "そっせん", + "そっと", + "そとがわ", + "そとづら", + "そなえる", + "そなた", + "そふぼ", + "そぼく", + "そぼろ", + "そまつ", + "そまる", + "そむく", + "そむりえ", + "そめる", + "そもそも", + "そよかぜ", + "そらまめ", + "そろう", + "そんかい", + "そんけい", + "そんざい", + "そんしつ", + "そんぞく", + "そんちょう", + "ぞんび", + "ぞんぶん", + "そんみん", + "たあい", + "たいいん", + "たいうん", + "たいえき", + "たいおう", + "だいがく", + "たいき", + "たいぐう", + "たいけん", + "たいこ", + "たいざい", + "だいじょうぶ", + "だいすき", + "たいせつ", + "たいそう", + "だいたい", + "たいちょう", + "たいてい", + "だいどころ", + "たいない", + "たいねつ", + "たいのう", + "たいはん", + "だいひょう", + "たいふう", + "たいへん", + "たいほ", + "たいまつばな", + "たいみんぐ", + "たいむ", + "たいめん", + "たいやき", + "たいよう", + "たいら", + "たいりょく", + "たいる", + "たいわん", + "たうえ", + "たえる", + "たおす", + "たおる", + "たおれる", + "たかい", + "たかね", + "たきび", + "たくさん", + "たこく", + "たこやき", + "たさい", + "たしざん", + "だじゃれ", + "たすける", + "たずさわる", + "たそがれ", + "たたかう", + "たたく", + "ただしい", + "たたみ", + "たちばな", + "だっかい", + "だっきゃく", + "だっこ", + "だっしゅつ", + "だったい", + "たてる", + "たとえる", + "たなばた", + "たにん", + "たぬき", + "たのしみ", + "たはつ", + "たぶん", + "たべる", + "たぼう", + "たまご", + "たまる", + "だむる", + "ためいき", + "ためす", + "ためる", + "たもつ", + "たやすい", + "たよる", + "たらす", + "たりきほんがん", + "たりょう", + "たりる", + "たると", + "たれる", + "たれんと", + "たろっと", + "たわむれる", + "だんあつ", + "たんい", + "たんおん", + "たんか", + "たんき", + "たんけん", + "たんご", + "たんさん", + "たんじょうび", + "だんせい", + "たんそく", + "たんたい", + "だんち", + "たんてい", + "たんとう", + "だんな", + "たんにん", + "だんねつ", + "たんのう", + "たんぴん", + "だんぼう", + "たんまつ", + "たんめい", + "だんれつ", + "だんろ", + "だんわ", + "ちあい", + "ちあん", + "ちいき", + "ちいさい", + "ちえん", + "ちかい", + "ちから", + "ちきゅう", + "ちきん", + "ちけいず", + "ちけん", + "ちこく", + "ちさい", + "ちしき", + "ちしりょう", + "ちせい", + "ちそう", + "ちたい", + "ちたん", + "ちちおや", + "ちつじょ", + "ちてき", + "ちてん", + "ちぬき", + "ちぬり", + "ちのう", + "ちひょう", + "ちへいせん", + "ちほう", + "ちまた", + "ちみつ", + "ちみどろ", + "ちめいど", + "ちゃんこなべ", + "ちゅうい", + "ちゆりょく", + "ちょうし", + "ちょさくけん", + "ちらし", + "ちらみ", + "ちりがみ", + "ちりょう", + "ちるど", + "ちわわ", + "ちんたい", + "ちんもく", + "ついか", + "ついたち", + "つうか", + "つうじょう", + "つうはん", + "つうわ", + "つかう", + "つかれる", + "つくね", + "つくる", + "つけね", + "つける", + "つごう", + "つたえる", + "つづく", + "つつじ", + "つつむ", + "つとめる", + "つながる", + "つなみ", + "つねづね", + "つのる", + "つぶす", + "つまらない", + "つまる", + "つみき", + "つめたい", + "つもり", + "つもる", + "つよい", + "つるぼ", + "つるみく", + "つわもの", + "つわり", + "てあし", + "てあて", + "てあみ", + "ていおん", + "ていか", + "ていき", + "ていけい", + "ていこく", + "ていさつ", + "ていし", + "ていせい", + "ていたい", + "ていど", + "ていねい", + "ていひょう", + "ていへん", + "ていぼう", + "てうち", + "ておくれ", + "てきとう", + "てくび", + "でこぼこ", + "てさぎょう", + "てさげ", + "てすり", + "てそう", + "てちがい", + "てちょう", + "てつがく", + "てつづき", + "でっぱ", + "てつぼう", + "てつや", + "でぬかえ", + "てぬき", + "てぬぐい", + "てのひら", + "てはい", + "てぶくろ", + "てふだ", + "てほどき", + "てほん", + "てまえ", + "てまきずし", + "てみじか", + "てみやげ", + "てらす", + "てれび", + "てわけ", + "てわたし", + "でんあつ", + "てんいん", + "てんかい", + "てんき", + "てんぐ", + "てんけん", + "てんごく", + "てんさい", + "てんし", + "てんすう", + "でんち", + "てんてき", + "てんとう", + "てんない", + "てんぷら", + "てんぼうだい", + "てんめつ", + "てんらんかい", + "でんりょく", + "でんわ", + "どあい", + "といれ", + "どうかん", + "とうきゅう", + "どうぐ", + "とうし", + "とうむぎ", + "とおい", + "とおか", + "とおく", + "とおす", + "とおる", + "とかい", + "とかす", + "ときおり", + "ときどき", + "とくい", + "とくしゅう", + "とくてん", + "とくに", + "とくべつ", + "とけい", + "とける", + "とこや", + "とさか", + "としょかん", + "とそう", + "とたん", + "とちゅう", + "とっきゅう", + "とっくん", + "とつぜん", + "とつにゅう", + "とどける", + "ととのえる", + "とない", + "となえる", + "となり", + "とのさま", + "とばす", + "どぶがわ", + "とほう", + "とまる", + "とめる", + "ともだち", + "ともる", + "どようび", + "とらえる", + "とんかつ", + "どんぶり", + "ないかく", + "ないこう", + "ないしょ", + "ないす", + "ないせん", + "ないそう", + "なおす", + "ながい", + "なくす", + "なげる", + "なこうど", + "なさけ", + "なたでここ", + "なっとう", + "なつやすみ", + "ななおし", + "なにごと", + "なにもの", + "なにわ", + "なのか", + "なふだ", + "なまいき", + "なまえ", + "なまみ", + "なみだ", + "なめらか", + "なめる", + "なやむ", + "ならう", + "ならび", + "ならぶ", + "なれる", + "なわとび", + "なわばり", + "にあう", + "にいがた", + "にうけ", + "におい", + "にかい", + "にがて", + "にきび", + "にくしみ", + "にくまん", + "にげる", + "にさんかたんそ", + "にしき", + "にせもの", + "にちじょう", + "にちようび", + "にっか", + "にっき", + "にっけい", + "にっこう", + "にっさん", + "にっしょく", + "にっすう", + "にっせき", + "にってい", + "になう", + "にほん", + "にまめ", + "にもつ", + "にやり", + "にゅういん", + "にりんしゃ", + "にわとり", + "にんい", + "にんか", + "にんき", + "にんげん", + "にんしき", + "にんずう", + "にんそう", + "にんたい", + "にんち", + "にんてい", + "にんにく", + "にんぷ", + "にんまり", + "にんむ", + "にんめい", + "にんよう", + "ぬいくぎ", + "ぬかす", + "ぬぐいとる", + "ぬぐう", + "ぬくもり", + "ぬすむ", + "ぬまえび", + "ぬめり", + "ぬらす", + "ぬんちゃく", + "ねあげ", + "ねいき", + "ねいる", + "ねいろ", + "ねぐせ", + "ねくたい", + "ねくら", + "ねこぜ", + "ねこむ", + "ねさげ", + "ねすごす", + "ねそべる", + "ねだん", + "ねつい", + "ねっしん", + "ねつぞう", + "ねったいぎょ", + "ねぶそく", + "ねふだ", + "ねぼう", + "ねほりはほり", + "ねまき", + "ねまわし", + "ねみみ", + "ねむい", + "ねむたい", + "ねもと", + "ねらう", + "ねわざ", + "ねんいり", + "ねんおし", + "ねんかん", + "ねんきん", + "ねんぐ", + "ねんざ", + "ねんし", + "ねんちゃく", + "ねんど", + "ねんぴ", + "ねんぶつ", + "ねんまつ", + "ねんりょう", + "ねんれい", + "のいず", + "のおづま", + "のがす", + "のきなみ", + "のこぎり", + "のこす", + "のこる", + "のせる", + "のぞく", + "のぞむ", + "のたまう", + "のちほど", + "のっく", + "のばす", + "のはら", + "のべる", + "のぼる", + "のみもの", + "のやま", + "のらいぬ", + "のらねこ", + "のりもの", + "のりゆき", + "のれん", + "のんき", + "ばあい", + "はあく", + "ばあさん", + "ばいか", + "ばいく", + "はいけん", + "はいご", + "はいしん", + "はいすい", + "はいせん", + "はいそう", + "はいち", + "ばいばい", + "はいれつ", + "はえる", + "はおる", + "はかい", + "ばかり", + "はかる", + "はくしゅ", + "はけん", + "はこぶ", + "はさみ", + "はさん", + "はしご", + "ばしょ", + "はしる", + "はせる", + "ぱそこん", + "はそん", + "はたん", + "はちみつ", + "はつおん", + "はっかく", + "はづき", + "はっきり", + "はっくつ", + "はっけん", + "はっこう", + "はっさん", + "はっしん", + "はったつ", + "はっちゅう", + "はってん", + "はっぴょう", + "はっぽう", + "はなす", + "はなび", + "はにかむ", + "はぶらし", + "はみがき", + "はむかう", + "はめつ", + "はやい", + "はやし", + "はらう", + "はろうぃん", + "はわい", + "はんい", + "はんえい", + "はんおん", + "はんかく", + "はんきょう", + "ばんぐみ", + "はんこ", + "はんしゃ", + "はんすう", + "はんだん", + "ぱんち", + "ぱんつ", + "はんてい", + "はんとし", + "はんのう", + "はんぱ", + "はんぶん", + "はんぺん", + "はんぼうき", + "はんめい", + "はんらん", + "はんろん", + "ひいき", + "ひうん", + "ひえる", + "ひかく", + "ひかり", + "ひかる", + "ひかん", + "ひくい", + "ひけつ", + "ひこうき", + "ひこく", + "ひさい", + "ひさしぶり", + "ひさん", + "びじゅつかん", + "ひしょ" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/jbo.json b/coins/monero/src/wallet/seed/classic/jbo.json new file mode 100644 index 00000000..ccd02d02 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/jbo.json @@ -0,0 +1,1628 @@ +[ + "backi", + "bacru", + "badna", + "badri", + "bajra", + "bakfu", + "bakni", + "bakri", + "baktu", + "balji", + "balni", + "balre", + "balvi", + "bambu", + "bancu", + "bandu", + "banfi", + "bangu", + "banli", + "banro", + "banxa", + "banzu", + "bapli", + "barda", + "bargu", + "barja", + "barna", + "bartu", + "basfa", + "basna", + "basti", + "batci", + "batke", + "bavmi", + "baxso", + "bebna", + "bekpi", + "bemro", + "bende", + "bengo", + "benji", + "benre", + "benzo", + "bergu", + "bersa", + "berti", + "besna", + "besto", + "betfu", + "betri", + "bevri", + "bidju", + "bifce", + "bikla", + "bilga", + "bilma", + "bilni", + "bindo", + "binra", + "binxo", + "birje", + "birka", + "birti", + "bisli", + "bitmu", + "bitni", + "blabi", + "blaci", + "blanu", + "bliku", + "bloti", + "bolci", + "bongu", + "boske", + "botpi", + "boxfo", + "boxna", + "bradi", + "brano", + "bratu", + "brazo", + "bredi", + "bridi", + "brife", + "briju", + "brito", + "brivo", + "broda", + "bruna", + "budjo", + "bukpu", + "bumru", + "bunda", + "bunre", + "burcu", + "burna", + "cabna", + "cabra", + "cacra", + "cadga", + "cadzu", + "cafne", + "cagna", + "cakla", + "calku", + "calse", + "canci", + "cando", + "cange", + "canja", + "canko", + "canlu", + "canpa", + "canre", + "canti", + "carce", + "carfu", + "carmi", + "carna", + "cartu", + "carvi", + "casnu", + "catke", + "catlu", + "catni", + "catra", + "caxno", + "cecla", + "cecmu", + "cedra", + "cenba", + "censa", + "centi", + "cerda", + "cerni", + "certu", + "cevni", + "cfale", + "cfari", + "cfika", + "cfila", + "cfine", + "cfipu", + "ciblu", + "cicna", + "cidja", + "cidni", + "cidro", + "cifnu", + "cigla", + "cikna", + "cikre", + "ciksi", + "cilce", + "cilfu", + "cilmo", + "cilre", + "cilta", + "cimde", + "cimni", + "cinba", + "cindu", + "cinfo", + "cinje", + "cinki", + "cinla", + "cinmo", + "cinri", + "cinse", + "cinta", + "cinza", + "cipni", + "cipra", + "cirko", + "cirla", + "ciska", + "cisma", + "cisni", + "ciste", + "citka", + "citno", + "citri", + "citsi", + "civla", + "cizra", + "ckabu", + "ckafi", + "ckaji", + "ckana", + "ckape", + "ckasu", + "ckeji", + "ckiku", + "ckilu", + "ckini", + "ckire", + "ckule", + "ckunu", + "cladu", + "clani", + "claxu", + "cletu", + "clika", + "clinu", + "clira", + "clite", + "cliva", + "clupa", + "cmaci", + "cmalu", + "cmana", + "cmavo", + "cmene", + "cmeta", + "cmevo", + "cmila", + "cmima", + "cmoni", + "cnano", + "cnebo", + "cnemu", + "cnici", + "cnino", + "cnisa", + "cnita", + "cokcu", + "condi", + "conka", + "corci", + "cortu", + "cpacu", + "cpana", + "cpare", + "cpedu", + "cpina", + "cradi", + "crane", + "creka", + "crepu", + "cribe", + "crida", + "crino", + "cripu", + "crisa", + "critu", + "ctaru", + "ctebi", + "cteki", + "ctile", + "ctino", + "ctuca", + "cukla", + "cukre", + "cukta", + "culno", + "cumki", + "cumla", + "cunmi", + "cunso", + "cuntu", + "cupra", + "curmi", + "curnu", + "curve", + "cusku", + "cusna", + "cutci", + "cutne", + "cuxna", + "dacru", + "dacti", + "dadjo", + "dakfu", + "dakli", + "damba", + "damri", + "dandu", + "danfu", + "danlu", + "danmo", + "danre", + "dansu", + "danti", + "daplu", + "dapma", + "darca", + "dargu", + "darlu", + "darno", + "darsi", + "darxi", + "daski", + "dasni", + "daspo", + "dasri", + "datka", + "datni", + "datro", + "decti", + "degji", + "dejni", + "dekpu", + "dekto", + "delno", + "dembi", + "denci", + "denmi", + "denpa", + "dertu", + "derxi", + "desku", + "detri", + "dicma", + "dicra", + "didni", + "digno", + "dikca", + "diklo", + "dikni", + "dilcu", + "dilma", + "dilnu", + "dimna", + "dindi", + "dinju", + "dinko", + "dinso", + "dirba", + "dirce", + "dirgo", + "disko", + "ditcu", + "divzi", + "dizlo", + "djacu", + "djedi", + "djica", + "djine", + "djuno", + "donri", + "dotco", + "draci", + "drani", + "drata", + "drudi", + "dugri", + "dukse", + "dukti", + "dunda", + "dunja", + "dunku", + "dunli", + "dunra", + "dutso", + "dzena", + "dzipo", + "facki", + "fadni", + "fagri", + "falnu", + "famti", + "fancu", + "fange", + "fanmo", + "fanri", + "fanta", + "fanva", + "fanza", + "fapro", + "farka", + "farlu", + "farna", + "farvi", + "fasnu", + "fatci", + "fatne", + "fatri", + "febvi", + "fegli", + "femti", + "fendi", + "fengu", + "fenki", + "fenra", + "fenso", + "fepni", + "fepri", + "ferti", + "festi", + "fetsi", + "figre", + "filso", + "finpe", + "finti", + "firca", + "fisli", + "fizbu", + "flaci", + "flalu", + "flani", + "flecu", + "flese", + "fliba", + "flira", + "foldi", + "fonmo", + "fonxa", + "forca", + "forse", + "fraso", + "frati", + "fraxu", + "frica", + "friko", + "frili", + "frinu", + "friti", + "frumu", + "fukpi", + "fulta", + "funca", + "fusra", + "fuzme", + "gacri", + "gadri", + "galfi", + "galtu", + "galxe", + "ganlo", + "ganra", + "ganse", + "ganti", + "ganxo", + "ganzu", + "gapci", + "gapru", + "garna", + "gasnu", + "gaspo", + "gasta", + "genja", + "gento", + "genxu", + "gerku", + "gerna", + "gidva", + "gigdo", + "ginka", + "girzu", + "gismu", + "glare", + "gleki", + "gletu", + "glico", + "glife", + "glosa", + "gluta", + "gocti", + "gomsi", + "gotro", + "gradu", + "grafu", + "grake", + "grana", + "grasu", + "grava", + "greku", + "grusi", + "grute", + "gubni", + "gugde", + "gugle", + "gumri", + "gundi", + "gunka", + "gunma", + "gunro", + "gunse", + "gunta", + "gurni", + "guska", + "gusni", + "gusta", + "gutci", + "gutra", + "guzme", + "jabre", + "jadni", + "jakne", + "jalge", + "jalna", + "jalra", + "jamfu", + "jamna", + "janbe", + "janco", + "janli", + "jansu", + "janta", + "jarbu", + "jarco", + "jarki", + "jaspu", + "jatna", + "javni", + "jbama", + "jbari", + "jbena", + "jbera", + "jbini", + "jdari", + "jdice", + "jdika", + "jdima", + "jdini", + "jduli", + "jecta", + "jeftu", + "jegvo", + "jelca", + "jemna", + "jenca", + "jendu", + "jenmi", + "jensi", + "jerna", + "jersi", + "jerxo", + "jesni", + "jetce", + "jetnu", + "jgalu", + "jganu", + "jgari", + "jgena", + "jgina", + "jgira", + "jgita", + "jibni", + "jibri", + "jicla", + "jicmu", + "jijnu", + "jikca", + "jikfi", + "jikni", + "jikru", + "jilka", + "jilra", + "jimca", + "jimpe", + "jimte", + "jinci", + "jinda", + "jinga", + "jinku", + "jinme", + "jinru", + "jinsa", + "jinto", + "jinvi", + "jinzi", + "jipci", + "jipno", + "jirna", + "jisra", + "jitfa", + "jitro", + "jivbu", + "jivna", + "jmaji", + "jmifa", + "jmina", + "jmive", + "jonse", + "jordo", + "jorne", + "jubme", + "judri", + "jufra", + "jukni", + "jukpa", + "julne", + "julro", + "jundi", + "jungo", + "junla", + "junri", + "junta", + "jurme", + "jursa", + "jutsi", + "juxre", + "jvinu", + "jviso", + "kabri", + "kacma", + "kadno", + "kafke", + "kagni", + "kajde", + "kajna", + "kakne", + "kakpa", + "kalci", + "kalri", + "kalsa", + "kalte", + "kamju", + "kamni", + "kampu", + "kamre", + "kanba", + "kancu", + "kandi", + "kanji", + "kanla", + "kanpe", + "kanro", + "kansa", + "kantu", + "kanxe", + "karbi", + "karce", + "karda", + "kargu", + "karli", + "karni", + "katci", + "katna", + "kavbu", + "kazra", + "kecti", + "kekli", + "kelci", + "kelvo", + "kenka", + "kenra", + "kensa", + "kerfa", + "kerlo", + "kesri", + "ketco", + "ketsu", + "kevna", + "kibro", + "kicne", + "kijno", + "kilto", + "kinda", + "kinli", + "kisto", + "klaji", + "klaku", + "klama", + "klani", + "klesi", + "kliki", + "klina", + "kliru", + "kliti", + "klupe", + "kluza", + "kobli", + "kogno", + "kojna", + "kokso", + "kolme", + "komcu", + "konju", + "korbi", + "korcu", + "korka", + "korvo", + "kosmu", + "kosta", + "krali", + "kramu", + "krasi", + "krati", + "krefu", + "krici", + "krili", + "krinu", + "krixa", + "kruca", + "kruji", + "kruvi", + "kubli", + "kucli", + "kufra", + "kukte", + "kulnu", + "kumfa", + "kumte", + "kunra", + "kunti", + "kurfa", + "kurji", + "kurki", + "kuspe", + "kusru", + "labno", + "lacni", + "lacpu", + "lacri", + "ladru", + "lafti", + "lakne", + "lakse", + "laldo", + "lalxu", + "lamji", + "lanbi", + "lanci", + "landa", + "lanka", + "lanli", + "lanme", + "lante", + "lanxe", + "lanzu", + "larcu", + "larva", + "lasna", + "lastu", + "latmo", + "latna", + "lazni", + "lebna", + "lelxe", + "lenga", + "lenjo", + "lenku", + "lerci", + "lerfu", + "libjo", + "lidne", + "lifri", + "lijda", + "limfa", + "limna", + "lince", + "lindi", + "linga", + "linji", + "linsi", + "linto", + "lisri", + "liste", + "litce", + "litki", + "litru", + "livga", + "livla", + "logji", + "loglo", + "lojbo", + "loldi", + "lorxu", + "lubno", + "lujvo", + "luksi", + "lumci", + "lunbe", + "lunra", + "lunsa", + "luska", + "lusto", + "mabla", + "mabru", + "macnu", + "majga", + "makcu", + "makfa", + "maksi", + "malsi", + "mamta", + "manci", + "manfo", + "mango", + "manku", + "manri", + "mansa", + "manti", + "mapku", + "mapni", + "mapra", + "mapti", + "marbi", + "marce", + "marde", + "margu", + "marji", + "marna", + "marxa", + "masno", + "masti", + "matci", + "matli", + "matne", + "matra", + "mavji", + "maxri", + "mebri", + "megdo", + "mekso", + "melbi", + "meljo", + "melmi", + "menli", + "menre", + "mensi", + "mentu", + "merko", + "merli", + "metfo", + "mexno", + "midju", + "mifra", + "mikce", + "mikri", + "milti", + "milxe", + "minde", + "minji", + "minli", + "minra", + "mintu", + "mipri", + "mirli", + "misno", + "misro", + "mitre", + "mixre", + "mlana", + "mlatu", + "mleca", + "mledi", + "mluni", + "mogle", + "mokca", + "moklu", + "molki", + "molro", + "morji", + "morko", + "morna", + "morsi", + "mosra", + "mraji", + "mrilu", + "mruli", + "mucti", + "mudri", + "mugle", + "mukti", + "mulno", + "munje", + "mupli", + "murse", + "murta", + "muslo", + "mutce", + "muvdu", + "muzga", + "nabmi", + "nakni", + "nalci", + "namcu", + "nanba", + "nanca", + "nandu", + "nanla", + "nanmu", + "nanvi", + "narge", + "narju", + "natfe", + "natmi", + "natsi", + "navni", + "naxle", + "nazbi", + "nejni", + "nelci", + "nenri", + "nerde", + "nibli", + "nicfa", + "nicte", + "nikle", + "nilce", + "nimre", + "ninja", + "ninmu", + "nirna", + "nitcu", + "nivji", + "nixli", + "nobli", + "norgo", + "notci", + "nudle", + "nukni", + "nunmu", + "nupre", + "nurma", + "nusna", + "nutka", + "nutli", + "nuzba", + "nuzlo", + "pacna", + "pagbu", + "pagre", + "pajni", + "palci", + "palku", + "palma", + "palne", + "palpi", + "palta", + "pambe", + "pamga", + "panci", + "pandi", + "panje", + "panka", + "panlo", + "panpi", + "panra", + "pante", + "panzi", + "papri", + "parbi", + "pardu", + "parji", + "pastu", + "patfu", + "patlu", + "patxu", + "paznu", + "pelji", + "pelxu", + "pemci", + "penbi", + "pencu", + "pendo", + "penmi", + "pensi", + "pentu", + "perli", + "pesxu", + "petso", + "pevna", + "pezli", + "picti", + "pijne", + "pikci", + "pikta", + "pilda", + "pilji", + "pilka", + "pilno", + "pimlu", + "pinca", + "pindi", + "pinfu", + "pinji", + "pinka", + "pinsi", + "pinta", + "pinxe", + "pipno", + "pixra", + "plana", + "platu", + "pleji", + "plibu", + "plini", + "plipe", + "plise", + "plita", + "plixa", + "pluja", + "pluka", + "pluta", + "pocli", + "polje", + "polno", + "ponjo", + "ponse", + "poplu", + "porpi", + "porsi", + "porto", + "prali", + "prami", + "prane", + "preja", + "prenu", + "preri", + "preti", + "prije", + "prina", + "pritu", + "proga", + "prosa", + "pruce", + "pruni", + "pruri", + "pruxi", + "pulce", + "pulji", + "pulni", + "punji", + "punli", + "pupsu", + "purci", + "purdi", + "purmo", + "racli", + "ractu", + "radno", + "rafsi", + "ragbi", + "ragve", + "rakle", + "rakso", + "raktu", + "ralci", + "ralju", + "ralte", + "randa", + "rango", + "ranji", + "ranmi", + "ransu", + "ranti", + "ranxi", + "rapli", + "rarna", + "ratcu", + "ratni", + "rebla", + "rectu", + "rekto", + "remna", + "renro", + "renvi", + "respa", + "rexsa", + "ricfu", + "rigni", + "rijno", + "rilti", + "rimni", + "rinci", + "rindo", + "rinju", + "rinka", + "rinsa", + "rirci", + "rirni", + "rirxe", + "rismi", + "risna", + "ritli", + "rivbi", + "rokci", + "romge", + "romlo", + "ronte", + "ropno", + "rorci", + "rotsu", + "rozgu", + "ruble", + "rufsu", + "runme", + "runta", + "rupnu", + "rusko", + "rutni", + "sabji", + "sabnu", + "sacki", + "saclu", + "sadjo", + "sakci", + "sakli", + "sakta", + "salci", + "salpo", + "salri", + "salta", + "samcu", + "sampu", + "sanbu", + "sance", + "sanga", + "sanji", + "sanli", + "sanmi", + "sanso", + "santa", + "sarcu", + "sarji", + "sarlu", + "sarni", + "sarxe", + "saske", + "satci", + "satre", + "savru", + "sazri", + "sefsi", + "sefta", + "sekre", + "selci", + "selfu", + "semto", + "senci", + "sengi", + "senpi", + "senta", + "senva", + "sepli", + "serti", + "sesre", + "setca", + "sevzi", + "sfani", + "sfasa", + "sfofa", + "sfubu", + "sibli", + "siclu", + "sicni", + "sicpi", + "sidbo", + "sidju", + "sigja", + "sigma", + "sikta", + "silka", + "silna", + "simlu", + "simsa", + "simxu", + "since", + "sinma", + "sinso", + "sinxa", + "sipna", + "sirji", + "sirxo", + "sisku", + "sisti", + "sitna", + "sivni", + "skaci", + "skami", + "skapi", + "skari", + "skicu", + "skiji", + "skina", + "skori", + "skoto", + "skuba", + "skuro", + "slabu", + "slaka", + "slami", + "slanu", + "slari", + "slasi", + "sligu", + "slilu", + "sliri", + "slovo", + "sluji", + "sluni", + "smacu", + "smadi", + "smaji", + "smaka", + "smani", + "smela", + "smoka", + "smuci", + "smuni", + "smusu", + "snada", + "snanu", + "snidu", + "snime", + "snipa", + "snuji", + "snura", + "snuti", + "sobde", + "sodna", + "sodva", + "softo", + "solji", + "solri", + "sombo", + "sonci", + "sorcu", + "sorgu", + "sorni", + "sorta", + "sovda", + "spaji", + "spali", + "spano", + "spati", + "speni", + "spero", + "spisa", + "spita", + "spofu", + "spoja", + "spuda", + "sputu", + "sraji", + "sraku", + "sralo", + "srana", + "srasu", + "srera", + "srito", + "sruma", + "sruri", + "stace", + "stagi", + "staku", + "stali", + "stani", + "stapa", + "stasu", + "stati", + "steba", + "steci", + "stedu", + "stela", + "stero", + "stici", + "stidi", + "stika", + "stizu", + "stodi", + "stuna", + "stura", + "stuzi", + "sucta", + "sudga", + "sufti", + "suksa", + "sumji", + "sumne", + "sumti", + "sunga", + "sunla", + "surla", + "sutra", + "tabno", + "tabra", + "tadji", + "tadni", + "tagji", + "taksi", + "talsa", + "tamca", + "tamji", + "tamne", + "tanbo", + "tance", + "tanjo", + "tanko", + "tanru", + "tansi", + "tanxe", + "tapla", + "tarbi", + "tarci", + "tarla", + "tarmi", + "tarti", + "taske", + "tasmi", + "tasta", + "tatpi", + "tatru", + "tavla", + "taxfu", + "tcaci", + "tcadu", + "tcana", + "tcati", + "tcaxe", + "tcena", + "tcese", + "tcica", + "tcidu", + "tcika", + "tcila", + "tcima", + "tcini", + "tcita", + "temci", + "temse", + "tende", + "tenfa", + "tengu", + "terdi", + "terpa", + "terto", + "tifri", + "tigni", + "tigra", + "tikpa", + "tilju", + "tinbe", + "tinci", + "tinsa", + "tirna", + "tirse", + "tirxu", + "tisna", + "titla", + "tivni", + "tixnu", + "toknu", + "toldi", + "tonga", + "tordu", + "torni", + "torso", + "traji", + "trano", + "trati", + "trene", + "tricu", + "trina", + "trixe", + "troci", + "tsaba", + "tsali", + "tsani", + "tsapi", + "tsiju", + "tsina", + "tsuku", + "tubnu", + "tubra", + "tugni", + "tujli", + "tumla", + "tunba", + "tunka", + "tunlo", + "tunta", + "tuple", + "turko", + "turni", + "tutci", + "tutle", + "tutra", + "vacri", + "vajni", + "valsi", + "vamji", + "vamtu", + "vanbi", + "vanci", + "vanju", + "vasru", + "vasxu", + "vecnu", + "vedli", + "venfu", + "vensa", + "vente", + "vepre", + "verba", + "vibna", + "vidni", + "vidru", + "vifne", + "vikmi", + "viknu", + "vimcu", + "vindu", + "vinji", + "vinta", + "vipsi", + "virnu", + "viska", + "vitci", + "vitke", + "vitno", + "vlagi", + "vlile", + "vlina", + "vlipa", + "vofli", + "voksa", + "volve", + "vorme", + "vraga", + "vreji", + "vreta", + "vrici", + "vrude", + "vrusi", + "vubla", + "vujnu", + "vukna", + "vukro", + "xabju", + "xadba", + "xadji", + "xadni", + "xagji", + "xagri", + "xajmi", + "xaksu", + "xalbo", + "xalka", + "xalni", + "xamgu", + "xampo", + "xamsi", + "xance", + "xango", + "xanka", + "xanri", + "xansa", + "xanto", + "xarci", + "xarju", + "xarnu", + "xasli", + "xasne", + "xatra", + "xatsi", + "xazdo", + "xebni", + "xebro", + "xecto", + "xedja", + "xekri", + "xelso", + "xendo", + "xenru", + "xexso", + "xigzo", + "xindo", + "xinmo", + "xirma", + "xislu", + "xispo", + "xlali", + "xlura", + "xorbo", + "xorlo", + "xotli", + "xrabo", + "xrani", + "xriso", + "xrotu", + "xruba", + "xruki", + "xrula", + "xruti", + "xukmi", + "xulta", + "xunre", + "xurdo", + "xusra", + "xutla", + "zabna", + "zajba", + "zalvi", + "zanru", + "zarci", + "zargu", + "zasni", + "zasti", + "zbabu", + "zbani", + "zbasu", + "zbepi", + "zdani", + "zdile", + "zekri", + "zenba", + "zepti", + "zetro", + "zevla", + "zgadi", + "zgana", + "zgike", + "zifre", + "zinki", + "zirpu", + "zivle", + "zmadu", + "zmiku", + "zucna", + "zukte", + "zumri", + "zungi", + "zunle", + "zunti", + "zutse", + "zvati", + "zviki", + "jbobau", + "jbopre", + "karsna", + "cabdei", + "zunsna", + "gendra", + "glibau", + "nintadni", + "pavyseljirna", + "vlaste", + "selbri", + "latro'a", + "zdakemkulgu'a", + "mriste", + "selsku", + "fu'ivla", + "tolmo'i", + "snavei", + "xagmau", + "retsku", + "ckupau", + "skudji", + "smudra", + "prulamdei", + "vokta'a", + "tinju'i", + "jefyfa'o", + "bavlamdei", + "kinzga", + "jbocre", + "jbovla", + "xauzma", + "selkei", + "xuncku", + "spusku", + "jbogu'e", + "pampe'o", + "bripre", + "jbosnu", + "zi'evla", + "gimste", + "tolzdi", + "velski", + "samselpla", + "cnegau", + "velcki", + "selja'e", + "fasybau", + "zanfri", + "reisku", + "favgau", + "jbota'a", + "rejgau", + "malgli", + "zilkai", + "keidji", + "tersu'i", + "jbofi'e", + "cnima'o", + "mulgau", + "ningau", + "ponbau", + "mrobi'o", + "rarbau", + "zmanei", + "famyma'o", + "vacysai", + "jetmlu", + "jbonunsla", + "nunpe'i", + "fa'orma'o", + "crezenzu'e", + "jbojbe", + "cmicu'a", + "zilcmi", + "tolcando", + "zukcfu", + "depybu'i", + "mencre", + "matmau", + "nunctu", + "selma'o", + "titnanba", + "naldra", + "jvajvo", + "nunsnu", + "nerkla", + "cimjvo", + "muvgau", + "zipcpi", + "runbau", + "faumlu", + "terbri", + "balcu'e", + "dragau", + "smuvelcki", + "piksku", + "selpli", + "bregau", + "zvafa'i", + "ci'izra", + "noltruti'u", + "samtci", + "snaxa'a" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/nl.json b/coins/monero/src/wallet/seed/classic/nl.json new file mode 100644 index 00000000..b6b04567 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/nl.json @@ -0,0 +1,1628 @@ +[ + "aalglad", + "aalscholver", + "aambeeld", + "aangeef", + "aanlandig", + "aanvaard", + "aanwakker", + "aapmens", + "aarten", + "abdicatie", + "abnormaal", + "abrikoos", + "accu", + "acuut", + "adjudant", + "admiraal", + "advies", + "afbidding", + "afdracht", + "affaire", + "affiche", + "afgang", + "afkick", + "afknap", + "aflees", + "afmijner", + "afname", + "afpreekt", + "afrader", + "afspeel", + "aftocht", + "aftrek", + "afzijdig", + "ahornboom", + "aktetas", + "akzo", + "alchemist", + "alcohol", + "aldaar", + "alexander", + "alfabet", + "alfredo", + "alice", + "alikruik", + "allrisk", + "altsax", + "alufolie", + "alziend", + "amai", + "ambacht", + "ambieer", + "amina", + "amnestie", + "amok", + "ampul", + "amuzikaal", + "angela", + "aniek", + "antje", + "antwerpen", + "anya", + "aorta", + "apache", + "apekool", + "appelaar", + "arganolie", + "argeloos", + "armoede", + "arrenslee", + "artritis", + "arubaan", + "asbak", + "ascii", + "asgrauw", + "asjes", + "asml", + "aspunt", + "asurn", + "asveld", + "aterling", + "atomair", + "atrium", + "atsma", + "atypisch", + "auping", + "aura", + "avifauna", + "axiaal", + "azoriaan", + "azteek", + "azuur", + "bachelor", + "badderen", + "badhotel", + "badmantel", + "badsteden", + "balie", + "ballans", + "balvers", + "bamibal", + "banneling", + "barracuda", + "basaal", + "batelaan", + "batje", + "beambte", + "bedlamp", + "bedwelmd", + "befaamd", + "begierd", + "begraaf", + "behield", + "beijaard", + "bejaagd", + "bekaaid", + "beks", + "bektas", + "belaad", + "belboei", + "belderbos", + "beloerd", + "beluchten", + "bemiddeld", + "benadeeld", + "benijd", + "berechten", + "beroemd", + "besef", + "besseling", + "best", + "betichten", + "bevind", + "bevochten", + "bevraagd", + "bewust", + "bidplaats", + "biefstuk", + "biemans", + "biezen", + "bijbaan", + "bijeenkom", + "bijfiguur", + "bijkaart", + "bijlage", + "bijpaard", + "bijtgaar", + "bijweg", + "bimmel", + "binck", + "bint", + "biobak", + "biotisch", + "biseks", + "bistro", + "bitter", + "bitumen", + "bizar", + "blad", + "bleken", + "blender", + "bleu", + "blief", + "blijven", + "blozen", + "bock", + "boef", + "boei", + "boks", + "bolder", + "bolus", + "bolvormig", + "bomaanval", + "bombarde", + "bomma", + "bomtapijt", + "bookmaker", + "boos", + "borg", + "bosbes", + "boshuizen", + "bosloop", + "botanicus", + "bougie", + "bovag", + "boxspring", + "braad", + "brasem", + "brevet", + "brigade", + "brinckman", + "bruid", + "budget", + "buffel", + "buks", + "bulgaar", + "buma", + "butaan", + "butler", + "buuf", + "cactus", + "cafeetje", + "camcorder", + "cannabis", + "canyon", + "capoeira", + "capsule", + "carkit", + "casanova", + "catalaan", + "ceintuur", + "celdeling", + "celplasma", + "cement", + "censeren", + "ceramisch", + "cerberus", + "cerebraal", + "cesium", + "cirkel", + "citeer", + "civiel", + "claxon", + "clenbuterol", + "clicheren", + "clijsen", + "coalitie", + "coassistentschap", + "coaxiaal", + "codetaal", + "cofinanciering", + "cognac", + "coltrui", + "comfort", + "commandant", + "condensaat", + "confectie", + "conifeer", + "convector", + "copier", + "corfu", + "correct", + "coup", + "couvert", + "creatie", + "credit", + "crematie", + "cricket", + "croupier", + "cruciaal", + "cruijff", + "cuisine", + "culemborg", + "culinair", + "curve", + "cyrano", + "dactylus", + "dading", + "dagblind", + "dagje", + "daglicht", + "dagprijs", + "dagranden", + "dakdekker", + "dakpark", + "dakterras", + "dalgrond", + "dambord", + "damkat", + "damlengte", + "damman", + "danenberg", + "debbie", + "decibel", + "defect", + "deformeer", + "degelijk", + "degradant", + "dejonghe", + "dekken", + "deppen", + "derek", + "derf", + "derhalve", + "detineren", + "devalueer", + "diaken", + "dicht", + "dictaat", + "dief", + "digitaal", + "dijbreuk", + "dijkmans", + "dimbaar", + "dinsdag", + "diode", + "dirigeer", + "disbalans", + "dobermann", + "doenbaar", + "doerak", + "dogma", + "dokhaven", + "dokwerker", + "doling", + "dolphijn", + "dolven", + "dombo", + "dooraderd", + "dopeling", + "doping", + "draderig", + "drama", + "drenkbak", + "dreumes", + "drol", + "drug", + "duaal", + "dublin", + "duplicaat", + "durven", + "dusdanig", + "dutchbat", + "dutje", + "dutten", + "duur", + "duwwerk", + "dwaal", + "dweil", + "dwing", + "dyslexie", + "ecostroom", + "ecotaks", + "educatie", + "eeckhout", + "eede", + "eemland", + "eencellig", + "eeneiig", + "eenruiter", + "eenwinter", + "eerenberg", + "eerrover", + "eersel", + "eetmaal", + "efteling", + "egaal", + "egtberts", + "eickhoff", + "eidooier", + "eiland", + "eind", + "eisden", + "ekster", + "elburg", + "elevatie", + "elfkoppig", + "elfrink", + "elftal", + "elimineer", + "elleboog", + "elma", + "elodie", + "elsa", + "embleem", + "embolie", + "emoe", + "emonds", + "emplooi", + "enduro", + "enfin", + "engageer", + "entourage", + "entstof", + "epileer", + "episch", + "eppo", + "erasmus", + "erboven", + "erebaan", + "erelijst", + "ereronden", + "ereteken", + "erfhuis", + "erfwet", + "erger", + "erica", + "ermitage", + "erna", + "ernie", + "erts", + "ertussen", + "eruitzien", + "ervaar", + "erven", + "erwt", + "esbeek", + "escort", + "esdoorn", + "essing", + "etage", + "eter", + "ethanol", + "ethicus", + "etholoog", + "eufonisch", + "eurocent", + "evacuatie", + "exact", + "examen", + "executant", + "exen", + "exit", + "exogeen", + "exotherm", + "expeditie", + "expletief", + "expres", + "extase", + "extinctie", + "faal", + "faam", + "fabel", + "facultair", + "fakir", + "fakkel", + "faliekant", + "fallisch", + "famke", + "fanclub", + "fase", + "fatsoen", + "fauna", + "federaal", + "feedback", + "feest", + "feilbaar", + "feitelijk", + "felblauw", + "figurante", + "fiod", + "fitheid", + "fixeer", + "flap", + "fleece", + "fleur", + "flexibel", + "flits", + "flos", + "flow", + "fluweel", + "foezelen", + "fokkelman", + "fokpaard", + "fokvee", + "folder", + "follikel", + "folmer", + "folteraar", + "fooi", + "foolen", + "forfait", + "forint", + "formule", + "fornuis", + "fosfaat", + "foxtrot", + "foyer", + "fragiel", + "frater", + "freak", + "freddie", + "fregat", + "freon", + "frijnen", + "fructose", + "frunniken", + "fuiven", + "funshop", + "furieus", + "fysica", + "gadget", + "galder", + "galei", + "galg", + "galvlieg", + "galzuur", + "ganesh", + "gaswet", + "gaza", + "gazelle", + "geaaid", + "gebiecht", + "gebufferd", + "gedijd", + "geef", + "geflanst", + "gefreesd", + "gegaan", + "gegijzeld", + "gegniffel", + "gegraaid", + "gehikt", + "gehobbeld", + "gehucht", + "geiser", + "geiten", + "gekaakt", + "gekheid", + "gekijf", + "gekmakend", + "gekocht", + "gekskap", + "gekte", + "gelubberd", + "gemiddeld", + "geordend", + "gepoederd", + "gepuft", + "gerda", + "gerijpt", + "geseald", + "geshockt", + "gesierd", + "geslaagd", + "gesnaaid", + "getracht", + "getwijfel", + "geuit", + "gevecht", + "gevlagd", + "gewicht", + "gezaagd", + "gezocht", + "ghanees", + "giebelen", + "giechel", + "giepmans", + "gips", + "giraal", + "gistachtig", + "gitaar", + "glaasje", + "gletsjer", + "gleuf", + "glibberen", + "glijbaan", + "gloren", + "gluipen", + "gluren", + "gluur", + "gnoe", + "goddelijk", + "godgans", + "godschalk", + "godzalig", + "goeierd", + "gogme", + "goklustig", + "gokwereld", + "gonggrijp", + "gonje", + "goor", + "grabbel", + "graf", + "graveer", + "grif", + "grolleman", + "grom", + "groosman", + "grubben", + "gruijs", + "grut", + "guacamole", + "guido", + "guppy", + "haazen", + "hachelijk", + "haex", + "haiku", + "hakhout", + "hakken", + "hanegem", + "hans", + "hanteer", + "harrie", + "hazebroek", + "hedonist", + "heil", + "heineken", + "hekhuis", + "hekman", + "helbig", + "helga", + "helwegen", + "hengelaar", + "herkansen", + "hermafrodiet", + "hertaald", + "hiaat", + "hikspoors", + "hitachi", + "hitparade", + "hobo", + "hoeve", + "holocaust", + "hond", + "honnepon", + "hoogacht", + "hotelbed", + "hufter", + "hugo", + "huilbier", + "hulk", + "humus", + "huwbaar", + "huwelijk", + "hype", + "iconisch", + "idema", + "ideogram", + "idolaat", + "ietje", + "ijker", + "ijkheid", + "ijklijn", + "ijkmaat", + "ijkwezen", + "ijmuiden", + "ijsbox", + "ijsdag", + "ijselijk", + "ijskoud", + "ilse", + "immuun", + "impliceer", + "impuls", + "inbijten", + "inbuigen", + "indijken", + "induceer", + "indy", + "infecteer", + "inhaak", + "inkijk", + "inluiden", + "inmijnen", + "inoefenen", + "inpolder", + "inrijden", + "inslaan", + "invitatie", + "inwaaien", + "ionisch", + "isaac", + "isolatie", + "isotherm", + "isra", + "italiaan", + "ivoor", + "jacobs", + "jakob", + "jammen", + "jampot", + "jarig", + "jehova", + "jenever", + "jezus", + "joana", + "jobdienst", + "josua", + "joule", + "juich", + "jurk", + "juut", + "kaas", + "kabelaar", + "kabinet", + "kagenaar", + "kajuit", + "kalebas", + "kalm", + "kanjer", + "kapucijn", + "karregat", + "kart", + "katvanger", + "katwijk", + "kegelaar", + "keiachtig", + "keizer", + "kenletter", + "kerdijk", + "keus", + "kevlar", + "kezen", + "kickback", + "kieviet", + "kijken", + "kikvors", + "kilheid", + "kilobit", + "kilsdonk", + "kipschnitzel", + "kissebis", + "klad", + "klagelijk", + "klak", + "klapbaar", + "klaver", + "klene", + "klets", + "klijnhout", + "klit", + "klok", + "klonen", + "klotefilm", + "kluif", + "klumper", + "klus", + "knabbel", + "knagen", + "knaven", + "kneedbaar", + "knmi", + "knul", + "knus", + "kokhals", + "komiek", + "komkommer", + "kompaan", + "komrij", + "komvormig", + "koning", + "kopbal", + "kopklep", + "kopnagel", + "koppejan", + "koptekst", + "kopwand", + "koraal", + "kosmisch", + "kostbaar", + "kram", + "kraneveld", + "kras", + "kreling", + "krengen", + "kribbe", + "krik", + "kruid", + "krulbol", + "kuijper", + "kuipbank", + "kuit", + "kuiven", + "kutsmoes", + "kuub", + "kwak", + "kwatong", + "kwetsbaar", + "kwezelaar", + "kwijnen", + "kwik", + "kwinkslag", + "kwitantie", + "lading", + "lakbeits", + "lakken", + "laklaag", + "lakmoes", + "lakwijk", + "lamheid", + "lamp", + "lamsbout", + "lapmiddel", + "larve", + "laser", + "latijn", + "latuw", + "lawaai", + "laxeerpil", + "lebberen", + "ledeboer", + "leefbaar", + "leeman", + "lefdoekje", + "lefhebber", + "legboor", + "legsel", + "leguaan", + "leiplaat", + "lekdicht", + "lekrijden", + "leksteen", + "lenen", + "leraar", + "lesbienne", + "leugenaar", + "leut", + "lexicaal", + "lezing", + "lieten", + "liggeld", + "lijdzaam", + "lijk", + "lijmstang", + "lijnschip", + "likdoorn", + "likken", + "liksteen", + "limburg", + "link", + "linoleum", + "lipbloem", + "lipman", + "lispelen", + "lissabon", + "litanie", + "liturgie", + "lochem", + "loempia", + "loesje", + "logheid", + "lonen", + "lonneke", + "loom", + "loos", + "losbaar", + "loslaten", + "losplaats", + "loting", + "lotnummer", + "lots", + "louie", + "lourdes", + "louter", + "lowbudget", + "luijten", + "luikenaar", + "luilak", + "luipaard", + "luizenbos", + "lulkoek", + "lumen", + "lunzen", + "lurven", + "lutjeboer", + "luttel", + "lutz", + "luuk", + "luwte", + "luyendijk", + "lyceum", + "lynx", + "maakbaar", + "magdalena", + "malheid", + "manchet", + "manfred", + "manhaftig", + "mank", + "mantel", + "marion", + "marxist", + "masmeijer", + "massaal", + "matsen", + "matverf", + "matze", + "maude", + "mayonaise", + "mechanica", + "meifeest", + "melodie", + "meppelink", + "midvoor", + "midweeks", + "midzomer", + "miezel", + "mijnraad", + "minus", + "mirck", + "mirte", + "mispakken", + "misraden", + "miswassen", + "mitella", + "moker", + "molecule", + "mombakkes", + "moonen", + "mopperaar", + "moraal", + "morgana", + "mormel", + "mosselaar", + "motregen", + "mouw", + "mufheid", + "mutueel", + "muzelman", + "naaidoos", + "naald", + "nadeel", + "nadruk", + "nagy", + "nahon", + "naima", + "nairobi", + "napalm", + "napels", + "napijn", + "napoleon", + "narigheid", + "narratief", + "naseizoen", + "nasibal", + "navigatie", + "nawijn", + "negatief", + "nekletsel", + "nekwervel", + "neolatijn", + "neonataal", + "neptunus", + "nerd", + "nest", + "neuzelaar", + "nihiliste", + "nijenhuis", + "nijging", + "nijhoff", + "nijl", + "nijptang", + "nippel", + "nokkenas", + "noordam", + "noren", + "normaal", + "nottelman", + "notulant", + "nout", + "nuance", + "nuchter", + "nudorp", + "nulde", + "nullijn", + "nulmeting", + "nunspeet", + "nylon", + "obelisk", + "object", + "oblie", + "obsceen", + "occlusie", + "oceaan", + "ochtend", + "ockhuizen", + "oerdom", + "oergezond", + "oerlaag", + "oester", + "okhuijsen", + "olifant", + "olijfboer", + "omaans", + "ombudsman", + "omdat", + "omdijken", + "omdoen", + "omgebouwd", + "omkeer", + "omkomen", + "ommegaand", + "ommuren", + "omroep", + "omruil", + "omslaan", + "omsmeden", + "omvaar", + "onaardig", + "onedel", + "onenig", + "onheilig", + "onrecht", + "onroerend", + "ontcijfer", + "onthaal", + "ontvallen", + "ontzadeld", + "onzacht", + "onzin", + "onzuiver", + "oogappel", + "ooibos", + "ooievaar", + "ooit", + "oorarts", + "oorhanger", + "oorijzer", + "oorklep", + "oorschelp", + "oorworm", + "oorzaak", + "opdagen", + "opdien", + "opdweilen", + "opel", + "opgebaard", + "opinie", + "opjutten", + "opkijken", + "opklaar", + "opkuisen", + "opkwam", + "opnaaien", + "opossum", + "opsieren", + "opsmeer", + "optreden", + "opvijzel", + "opvlammen", + "opwind", + "oraal", + "orchidee", + "orkest", + "ossuarium", + "ostendorf", + "oublie", + "oudachtig", + "oudbakken", + "oudnoors", + "oudshoorn", + "oudtante", + "oven", + "over", + "oxidant", + "pablo", + "pacht", + "paktafel", + "pakzadel", + "paljas", + "panharing", + "papfles", + "paprika", + "parochie", + "paus", + "pauze", + "paviljoen", + "peek", + "pegel", + "peigeren", + "pekela", + "pendant", + "penibel", + "pepmiddel", + "peptalk", + "periferie", + "perron", + "pessarium", + "peter", + "petfles", + "petgat", + "peuk", + "pfeifer", + "picknick", + "pief", + "pieneman", + "pijlkruid", + "pijnacker", + "pijpelink", + "pikdonker", + "pikeer", + "pilaar", + "pionier", + "pipet", + "piscine", + "pissebed", + "pitchen", + "pixel", + "plamuren", + "plan", + "plausibel", + "plegen", + "plempen", + "pleonasme", + "plezant", + "podoloog", + "pofmouw", + "pokdalig", + "ponywagen", + "popachtig", + "popidool", + "porren", + "positie", + "potten", + "pralen", + "prezen", + "prijzen", + "privaat", + "proef", + "prooi", + "prozawerk", + "pruik", + "prul", + "publiceer", + "puck", + "puilen", + "pukkelig", + "pulveren", + "pupil", + "puppy", + "purmerend", + "pustjens", + "putemmer", + "puzzelaar", + "queenie", + "quiche", + "raam", + "raar", + "raat", + "raes", + "ralf", + "rally", + "ramona", + "ramselaar", + "ranonkel", + "rapen", + "rapunzel", + "rarekiek", + "rarigheid", + "rattenhol", + "ravage", + "reactie", + "recreant", + "redacteur", + "redster", + "reewild", + "regie", + "reijnders", + "rein", + "replica", + "revanche", + "rigide", + "rijbaan", + "rijdansen", + "rijgen", + "rijkdom", + "rijles", + "rijnwijn", + "rijpma", + "rijstafel", + "rijtaak", + "rijzwepen", + "rioleer", + "ripdeal", + "riphagen", + "riskant", + "rits", + "rivaal", + "robbedoes", + "robot", + "rockact", + "rodijk", + "rogier", + "rohypnol", + "rollaag", + "rolpaal", + "roltafel", + "roof", + "roon", + "roppen", + "rosbief", + "rosharig", + "rosielle", + "rotan", + "rotleven", + "rotten", + "rotvaart", + "royaal", + "royeer", + "rubato", + "ruby", + "ruche", + "rudge", + "ruggetje", + "rugnummer", + "rugpijn", + "rugtitel", + "rugzak", + "ruilbaar", + "ruis", + "ruit", + "rukwind", + "rulijs", + "rumoeren", + "rumsdorp", + "rumtaart", + "runnen", + "russchen", + "ruwkruid", + "saboteer", + "saksisch", + "salade", + "salpeter", + "sambabal", + "samsam", + "satelliet", + "satineer", + "saus", + "scampi", + "scarabee", + "scenario", + "schobben", + "schubben", + "scout", + "secessie", + "secondair", + "seculair", + "sediment", + "seeland", + "settelen", + "setwinst", + "sheriff", + "shiatsu", + "siciliaan", + "sidderaal", + "sigma", + "sijben", + "silvana", + "simkaart", + "sinds", + "situatie", + "sjaak", + "sjardijn", + "sjezen", + "sjor", + "skinhead", + "skylab", + "slamixen", + "sleijpen", + "slijkerig", + "slordig", + "slowaak", + "sluieren", + "smadelijk", + "smiecht", + "smoel", + "smos", + "smukken", + "snackcar", + "snavel", + "sneaker", + "sneu", + "snijdbaar", + "snit", + "snorder", + "soapbox", + "soetekouw", + "soigneren", + "sojaboon", + "solo", + "solvabel", + "somber", + "sommatie", + "soort", + "soppen", + "sopraan", + "soundbar", + "spanen", + "spawater", + "spijgat", + "spinaal", + "spionage", + "spiraal", + "spleet", + "splijt", + "spoed", + "sporen", + "spul", + "spuug", + "spuw", + "stalen", + "standaard", + "star", + "stefan", + "stencil", + "stijf", + "stil", + "stip", + "stopdas", + "stoten", + "stoven", + "straat", + "strobbe", + "strubbel", + "stucadoor", + "stuif", + "stukadoor", + "subhoofd", + "subregent", + "sudoku", + "sukade", + "sulfaat", + "surinaams", + "suus", + "syfilis", + "symboliek", + "sympathie", + "synagoge", + "synchroon", + "synergie", + "systeem", + "taanderij", + "tabak", + "tachtig", + "tackelen", + "taiwanees", + "talman", + "tamheid", + "tangaslip", + "taps", + "tarkan", + "tarwe", + "tasman", + "tatjana", + "taxameter", + "teil", + "teisman", + "telbaar", + "telco", + "telganger", + "telstar", + "tenant", + "tepel", + "terzet", + "testament", + "ticket", + "tiesinga", + "tijdelijk", + "tika", + "tiksel", + "tilleman", + "timbaal", + "tinsteen", + "tiplijn", + "tippelaar", + "tjirpen", + "toezeggen", + "tolbaas", + "tolgeld", + "tolhek", + "tolo", + "tolpoort", + "toltarief", + "tolvrij", + "tomaat", + "tondeuse", + "toog", + "tooi", + "toonbaar", + "toos", + "topclub", + "toppen", + "toptalent", + "topvrouw", + "toque", + "torment", + "tornado", + "tosti", + "totdat", + "toucheer", + "toulouse", + "tournedos", + "tout", + "trabant", + "tragedie", + "trailer", + "traject", + "traktaat", + "trauma", + "tray", + "trechter", + "tred", + "tref", + "treur", + "troebel", + "tros", + "trucage", + "truffel", + "tsaar", + "tucht", + "tuenter", + "tuitelig", + "tukje", + "tuktuk", + "tulp", + "tuma", + "tureluurs", + "twijfel", + "twitteren", + "tyfoon", + "typograaf", + "ugandees", + "uiachtig", + "uier", + "uisnipper", + "ultiem", + "unitair", + "uranium", + "urbaan", + "urendag", + "ursula", + "uurcirkel", + "uurglas", + "uzelf", + "vaat", + "vakantie", + "vakleraar", + "valbijl", + "valpartij", + "valreep", + "valuatie", + "vanmiddag", + "vanonder", + "varaan", + "varken", + "vaten", + "veenbes", + "veeteler", + "velgrem", + "vellekoop", + "velvet", + "veneberg", + "venlo", + "vent", + "venusberg", + "venw", + "veredeld", + "verf", + "verhaaf", + "vermaak", + "vernaaid", + "verraad", + "vers", + "veruit", + "verzaagd", + "vetachtig", + "vetlok", + "vetmesten", + "veto", + "vetrek", + "vetstaart", + "vetten", + "veurink", + "viaduct", + "vibrafoon", + "vicariaat", + "vieux", + "vieveen", + "vijfvoud", + "villa", + "vilt", + "vimmetje", + "vindbaar", + "vips", + "virtueel", + "visdieven", + "visee", + "visie", + "vlaag", + "vleugel", + "vmbo", + "vocht", + "voesenek", + "voicemail", + "voip", + "volg", + "vork", + "vorselaar", + "voyeur", + "vracht", + "vrekkig", + "vreten", + "vrije", + "vrozen", + "vrucht", + "vucht", + "vugt", + "vulkaan", + "vulmiddel", + "vulva", + "vuren", + "waas", + "wacht", + "wadvogel", + "wafel", + "waffel", + "walhalla", + "walnoot", + "walraven", + "wals", + "walvis", + "wandaad", + "wanen", + "wanmolen", + "want", + "warklomp", + "warm", + "wasachtig", + "wasteil", + "watt", + "webhandel", + "weblog", + "webpagina", + "webzine", + "wedereis", + "wedstrijd", + "weeda", + "weert", + "wegmaaien", + "wegscheer", + "wekelijks", + "wekken", + "wekroep", + "wektoon", + "weldaad", + "welwater", + "wendbaar", + "wenkbrauw", + "wens", + "wentelaar", + "wervel", + "wesseling", + "wetboek", + "wetmatig", + "whirlpool", + "wijbrands", + "wijdbeens", + "wijk", + "wijnbes", + "wijting", + "wild", + "wimpelen", + "wingebied", + "winplaats", + "winter", + "winzucht", + "wipstaart", + "wisgerhof", + "withaar", + "witmaker", + "wokkel", + "wolf", + "wonenden", + "woning", + "worden", + "worp", + "wortel", + "wrat", + "wrijf", + "wringen", + "yoghurt", + "ypsilon", + "zaaijer", + "zaak", + "zacharias", + "zakelijk", + "zakkam", + "zakwater", + "zalf", + "zalig", + "zaniken", + "zebracode", + "zeeblauw", + "zeef", + "zeegaand", + "zeeuw", + "zege", + "zegje", + "zeil", + "zesbaans", + "zesenhalf", + "zeskantig", + "zesmaal", + "zetbaas", + "zetpil", + "zeulen", + "ziezo", + "zigzag", + "zijaltaar", + "zijbeuk", + "zijlijn", + "zijmuur", + "zijn", + "zijwaarts", + "zijzelf", + "zilt", + "zimmerman", + "zinledig", + "zinnelijk", + "zionist", + "zitdag", + "zitruimte", + "zitzak", + "zoal", + "zodoende", + "zoekbots", + "zoem", + "zoiets", + "zojuist", + "zondaar", + "zotskap", + "zottebol", + "zucht", + "zuivel", + "zulk", + "zult", + "zuster", + "zuur", + "zweedijk", + "zwendel", + "zwepen", + "zwiep", + "zwijmel", + "zworen" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/pt.json b/coins/monero/src/wallet/seed/classic/pt.json new file mode 100644 index 00000000..4d1fbac5 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/pt.json @@ -0,0 +1,1628 @@ +[ + "abaular", + "abdominal", + "abeto", + "abissinio", + "abjeto", + "ablucao", + "abnegar", + "abotoar", + "abrutalhar", + "absurdo", + "abutre", + "acautelar", + "accessorios", + "acetona", + "achocolatado", + "acirrar", + "acne", + "acovardar", + "acrostico", + "actinomicete", + "acustico", + "adaptavel", + "adeus", + "adivinho", + "adjunto", + "admoestar", + "adnominal", + "adotivo", + "adquirir", + "adriatico", + "adsorcao", + "adutora", + "advogar", + "aerossol", + "afazeres", + "afetuoso", + "afixo", + "afluir", + "afortunar", + "afrouxar", + "aftosa", + "afunilar", + "agentes", + "agito", + "aglutinar", + "aiatola", + "aimore", + "aino", + "aipo", + "airoso", + "ajeitar", + "ajoelhar", + "ajudante", + "ajuste", + "alazao", + "albumina", + "alcunha", + "alegria", + "alexandre", + "alforriar", + "alguns", + "alhures", + "alivio", + "almoxarife", + "alotropico", + "alpiste", + "alquimista", + "alsaciano", + "altura", + "aluviao", + "alvura", + "amazonico", + "ambulatorio", + "ametodico", + "amizades", + "amniotico", + "amovivel", + "amurada", + "anatomico", + "ancorar", + "anexo", + "anfora", + "aniversario", + "anjo", + "anotar", + "ansioso", + "anturio", + "anuviar", + "anverso", + "anzol", + "aonde", + "apaziguar", + "apito", + "aplicavel", + "apoteotico", + "aprimorar", + "aprumo", + "apto", + "apuros", + "aquoso", + "arauto", + "arbusto", + "arduo", + "aresta", + "arfar", + "arguto", + "aritmetico", + "arlequim", + "armisticio", + "aromatizar", + "arpoar", + "arquivo", + "arrumar", + "arsenio", + "arturiano", + "aruaque", + "arvores", + "asbesto", + "ascorbico", + "aspirina", + "asqueroso", + "assustar", + "astuto", + "atazanar", + "ativo", + "atletismo", + "atmosferico", + "atormentar", + "atroz", + "aturdir", + "audivel", + "auferir", + "augusto", + "aula", + "aumento", + "aurora", + "autuar", + "avatar", + "avexar", + "avizinhar", + "avolumar", + "avulso", + "axiomatico", + "azerbaijano", + "azimute", + "azoto", + "azulejo", + "bacteriologista", + "badulaque", + "baforada", + "baixote", + "bajular", + "balzaquiana", + "bambuzal", + "banzo", + "baoba", + "baqueta", + "barulho", + "bastonete", + "batuta", + "bauxita", + "bavaro", + "bazuca", + "bcrepuscular", + "beato", + "beduino", + "begonia", + "behaviorista", + "beisebol", + "belzebu", + "bemol", + "benzido", + "beocio", + "bequer", + "berro", + "besuntar", + "betume", + "bexiga", + "bezerro", + "biatlon", + "biboca", + "bicuspide", + "bidirecional", + "bienio", + "bifurcar", + "bigorna", + "bijuteria", + "bimotor", + "binormal", + "bioxido", + "bipolarizacao", + "biquini", + "birutice", + "bisturi", + "bituca", + "biunivoco", + "bivalve", + "bizarro", + "blasfemo", + "blenorreia", + "blindar", + "bloqueio", + "blusao", + "boazuda", + "bofete", + "bojudo", + "bolso", + "bombordo", + "bonzo", + "botina", + "boquiaberto", + "bostoniano", + "botulismo", + "bourbon", + "bovino", + "boximane", + "bravura", + "brevidade", + "britar", + "broxar", + "bruno", + "bruxuleio", + "bubonico", + "bucolico", + "buda", + "budista", + "bueiro", + "buffer", + "bugre", + "bujao", + "bumerangue", + "burundines", + "busto", + "butique", + "buzios", + "caatinga", + "cabuqui", + "cacunda", + "cafuzo", + "cajueiro", + "camurca", + "canudo", + "caquizeiro", + "carvoeiro", + "casulo", + "catuaba", + "cauterizar", + "cebolinha", + "cedula", + "ceifeiro", + "celulose", + "cerzir", + "cesto", + "cetro", + "ceus", + "cevar", + "chavena", + "cheroqui", + "chita", + "chovido", + "chuvoso", + "ciatico", + "cibernetico", + "cicuta", + "cidreira", + "cientistas", + "cifrar", + "cigarro", + "cilio", + "cimo", + "cinzento", + "cioso", + "cipriota", + "cirurgico", + "cisto", + "citrico", + "ciumento", + "civismo", + "clavicula", + "clero", + "clitoris", + "cluster", + "coaxial", + "cobrir", + "cocota", + "codorniz", + "coexistir", + "cogumelo", + "coito", + "colusao", + "compaixao", + "comutativo", + "contentamento", + "convulsivo", + "coordenativa", + "coquetel", + "correto", + "corvo", + "costureiro", + "cotovia", + "covil", + "cozinheiro", + "cretino", + "cristo", + "crivo", + "crotalo", + "cruzes", + "cubo", + "cucuia", + "cueiro", + "cuidar", + "cujo", + "cultural", + "cunilingua", + "cupula", + "curvo", + "custoso", + "cutucar", + "czarismo", + "dablio", + "dacota", + "dados", + "daguerreotipo", + "daiquiri", + "daltonismo", + "damista", + "dantesco", + "daquilo", + "darwinista", + "dasein", + "dativo", + "deao", + "debutantes", + "decurso", + "deduzir", + "defunto", + "degustar", + "dejeto", + "deltoide", + "demover", + "denunciar", + "deputado", + "deque", + "dervixe", + "desvirtuar", + "deturpar", + "deuteronomio", + "devoto", + "dextrose", + "dezoito", + "diatribe", + "dicotomico", + "didatico", + "dietista", + "difuso", + "digressao", + "diluvio", + "diminuto", + "dinheiro", + "dinossauro", + "dioxido", + "diplomatico", + "dique", + "dirimivel", + "disturbio", + "diurno", + "divulgar", + "dizivel", + "doar", + "dobro", + "docura", + "dodoi", + "doer", + "dogue", + "doloso", + "domo", + "donzela", + "doping", + "dorsal", + "dossie", + "dote", + "doutro", + "doze", + "dravidico", + "dreno", + "driver", + "dropes", + "druso", + "dubnio", + "ducto", + "dueto", + "dulija", + "dundum", + "duodeno", + "duquesa", + "durou", + "duvidoso", + "duzia", + "ebano", + "ebrio", + "eburneo", + "echarpe", + "eclusa", + "ecossistema", + "ectoplasma", + "ecumenismo", + "eczema", + "eden", + "editorial", + "edredom", + "edulcorar", + "efetuar", + "efigie", + "efluvio", + "egiptologo", + "egresso", + "egua", + "einsteiniano", + "eira", + "eivar", + "eixos", + "ejetar", + "elastomero", + "eldorado", + "elixir", + "elmo", + "eloquente", + "elucidativo", + "emaranhar", + "embutir", + "emerito", + "emfa", + "emitir", + "emotivo", + "empuxo", + "emulsao", + "enamorar", + "encurvar", + "enduro", + "enevoar", + "enfurnar", + "enguico", + "enho", + "enigmista", + "enlutar", + "enormidade", + "enpreendimento", + "enquanto", + "enriquecer", + "enrugar", + "entusiastico", + "enunciar", + "envolvimento", + "enxuto", + "enzimatico", + "eolico", + "epiteto", + "epoxi", + "epura", + "equivoco", + "erario", + "erbio", + "ereto", + "erguido", + "erisipela", + "ermo", + "erotizar", + "erros", + "erupcao", + "ervilha", + "esburacar", + "escutar", + "esfuziante", + "esguio", + "esloveno", + "esmurrar", + "esoterismo", + "esperanca", + "espirito", + "espurio", + "essencialmente", + "esturricar", + "esvoacar", + "etario", + "eterno", + "etiquetar", + "etnologo", + "etos", + "etrusco", + "euclidiano", + "euforico", + "eugenico", + "eunuco", + "europio", + "eustaquio", + "eutanasia", + "evasivo", + "eventualidade", + "evitavel", + "evoluir", + "exaustor", + "excursionista", + "exercito", + "exfoliado", + "exito", + "exotico", + "expurgo", + "exsudar", + "extrusora", + "exumar", + "fabuloso", + "facultativo", + "fado", + "fagulha", + "faixas", + "fajuto", + "faltoso", + "famoso", + "fanzine", + "fapesp", + "faquir", + "fartura", + "fastio", + "faturista", + "fausto", + "favorito", + "faxineira", + "fazer", + "fealdade", + "febril", + "fecundo", + "fedorento", + "feerico", + "feixe", + "felicidade", + "felpudo", + "feltro", + "femur", + "fenotipo", + "fervura", + "festivo", + "feto", + "feudo", + "fevereiro", + "fezinha", + "fiasco", + "fibra", + "ficticio", + "fiduciario", + "fiesp", + "fifa", + "figurino", + "fijiano", + "filtro", + "finura", + "fiorde", + "fiquei", + "firula", + "fissurar", + "fitoteca", + "fivela", + "fixo", + "flavio", + "flexor", + "flibusteiro", + "flotilha", + "fluxograma", + "fobos", + "foco", + "fofura", + "foguista", + "foie", + "foliculo", + "fominha", + "fonte", + "forum", + "fosso", + "fotossintese", + "foxtrote", + "fraudulento", + "frevo", + "frivolo", + "frouxo", + "frutose", + "fuba", + "fucsia", + "fugitivo", + "fuinha", + "fujao", + "fulustreco", + "fumo", + "funileiro", + "furunculo", + "fustigar", + "futurologo", + "fuxico", + "fuzue", + "gabriel", + "gado", + "gaelico", + "gafieira", + "gaguejo", + "gaivota", + "gajo", + "galvanoplastico", + "gamo", + "ganso", + "garrucha", + "gastronomo", + "gatuno", + "gaussiano", + "gaviao", + "gaxeta", + "gazeteiro", + "gear", + "geiser", + "geminiano", + "generoso", + "genuino", + "geossinclinal", + "gerundio", + "gestual", + "getulista", + "gibi", + "gigolo", + "gilete", + "ginseng", + "giroscopio", + "glaucio", + "glacial", + "gleba", + "glifo", + "glote", + "glutonia", + "gnostico", + "goela", + "gogo", + "goitaca", + "golpista", + "gomo", + "gonzo", + "gorro", + "gostou", + "goticula", + "gourmet", + "governo", + "gozo", + "graxo", + "grevista", + "grito", + "grotesco", + "gruta", + "guaxinim", + "gude", + "gueto", + "guizo", + "guloso", + "gume", + "guru", + "gustativo", + "grelhado", + "gutural", + "habitue", + "haitiano", + "halterofilista", + "hamburguer", + "hanseniase", + "happening", + "harpista", + "hastear", + "haveres", + "hebreu", + "hectometro", + "hedonista", + "hegira", + "helena", + "helminto", + "hemorroidas", + "henrique", + "heptassilabo", + "hertziano", + "hesitar", + "heterossexual", + "heuristico", + "hexagono", + "hiato", + "hibrido", + "hidrostatico", + "hieroglifo", + "hifenizar", + "higienizar", + "hilario", + "himen", + "hino", + "hippie", + "hirsuto", + "historiografia", + "hitlerista", + "hodometro", + "hoje", + "holograma", + "homus", + "honroso", + "hoquei", + "horto", + "hostilizar", + "hotentote", + "huguenote", + "humilde", + "huno", + "hurra", + "hutu", + "iaia", + "ialorixa", + "iambico", + "iansa", + "iaque", + "iara", + "iatista", + "iberico", + "ibis", + "icar", + "iceberg", + "icosagono", + "idade", + "ideologo", + "idiotice", + "idoso", + "iemenita", + "iene", + "igarape", + "iglu", + "ignorar", + "igreja", + "iguaria", + "iidiche", + "ilativo", + "iletrado", + "ilharga", + "ilimitado", + "ilogismo", + "ilustrissimo", + "imaturo", + "imbuzeiro", + "imerso", + "imitavel", + "imovel", + "imputar", + "imutavel", + "inaveriguavel", + "incutir", + "induzir", + "inextricavel", + "infusao", + "ingua", + "inhame", + "iniquo", + "injusto", + "inning", + "inoxidavel", + "inquisitorial", + "insustentavel", + "intumescimento", + "inutilizavel", + "invulneravel", + "inzoneiro", + "iodo", + "iogurte", + "ioio", + "ionosfera", + "ioruba", + "iota", + "ipsilon", + "irascivel", + "iris", + "irlandes", + "irmaos", + "iroques", + "irrupcao", + "isca", + "isento", + "islandes", + "isotopo", + "isqueiro", + "israelita", + "isso", + "isto", + "iterbio", + "itinerario", + "itrio", + "iuane", + "iugoslavo", + "jabuticabeira", + "jacutinga", + "jade", + "jagunco", + "jainista", + "jaleco", + "jambo", + "jantarada", + "japones", + "jaqueta", + "jarro", + "jasmim", + "jato", + "jaula", + "javel", + "jazz", + "jegue", + "jeitoso", + "jejum", + "jenipapo", + "jeova", + "jequitiba", + "jersei", + "jesus", + "jetom", + "jiboia", + "jihad", + "jilo", + "jingle", + "jipe", + "jocoso", + "joelho", + "joguete", + "joio", + "jojoba", + "jorro", + "jota", + "joule", + "joviano", + "jubiloso", + "judoca", + "jugular", + "juizo", + "jujuba", + "juliano", + "jumento", + "junto", + "jururu", + "justo", + "juta", + "juventude", + "labutar", + "laguna", + "laico", + "lajota", + "lanterninha", + "lapso", + "laquear", + "lastro", + "lauto", + "lavrar", + "laxativo", + "lazer", + "leasing", + "lebre", + "lecionar", + "ledo", + "leguminoso", + "leitura", + "lele", + "lemure", + "lento", + "leonardo", + "leopardo", + "lepton", + "leque", + "leste", + "letreiro", + "leucocito", + "levitico", + "lexicologo", + "lhama", + "lhufas", + "liame", + "licoroso", + "lidocaina", + "liliputiano", + "limusine", + "linotipo", + "lipoproteina", + "liquidos", + "lirismo", + "lisura", + "liturgico", + "livros", + "lixo", + "lobulo", + "locutor", + "lodo", + "logro", + "lojista", + "lombriga", + "lontra", + "loop", + "loquaz", + "lorota", + "losango", + "lotus", + "louvor", + "luar", + "lubrificavel", + "lucros", + "lugubre", + "luis", + "luminoso", + "luneta", + "lustroso", + "luto", + "luvas", + "luxuriante", + "luzeiro", + "maduro", + "maestro", + "mafioso", + "magro", + "maiuscula", + "majoritario", + "malvisto", + "mamute", + "manutencao", + "mapoteca", + "maquinista", + "marzipa", + "masturbar", + "matuto", + "mausoleu", + "mavioso", + "maxixe", + "mazurca", + "meandro", + "mecha", + "medusa", + "mefistofelico", + "megera", + "meirinho", + "melro", + "memorizar", + "menu", + "mequetrefe", + "mertiolate", + "mestria", + "metroviario", + "mexilhao", + "mezanino", + "miau", + "microssegundo", + "midia", + "migratorio", + "mimosa", + "minuto", + "miosotis", + "mirtilo", + "misturar", + "mitzvah", + "miudos", + "mixuruca", + "mnemonico", + "moagem", + "mobilizar", + "modulo", + "moer", + "mofo", + "mogno", + "moita", + "molusco", + "monumento", + "moqueca", + "morubixaba", + "mostruario", + "motriz", + "mouse", + "movivel", + "mozarela", + "muarra", + "muculmano", + "mudo", + "mugir", + "muitos", + "mumunha", + "munir", + "muon", + "muquira", + "murros", + "musselina", + "nacoes", + "nado", + "naftalina", + "nago", + "naipe", + "naja", + "nalgum", + "namoro", + "nanquim", + "napolitano", + "naquilo", + "nascimento", + "nautilo", + "navios", + "nazista", + "nebuloso", + "nectarina", + "nefrologo", + "negus", + "nelore", + "nenufar", + "nepotismo", + "nervura", + "neste", + "netuno", + "neutron", + "nevoeiro", + "newtoniano", + "nexo", + "nhenhenhem", + "nhoque", + "nigeriano", + "niilista", + "ninho", + "niobio", + "niponico", + "niquelar", + "nirvana", + "nisto", + "nitroglicerina", + "nivoso", + "nobreza", + "nocivo", + "noel", + "nogueira", + "noivo", + "nojo", + "nominativo", + "nonuplo", + "noruegues", + "nostalgico", + "noturno", + "nouveau", + "nuanca", + "nublar", + "nucleotideo", + "nudista", + "nulo", + "numismatico", + "nunquinha", + "nupcias", + "nutritivo", + "nuvens", + "oasis", + "obcecar", + "obeso", + "obituario", + "objetos", + "oblongo", + "obnoxio", + "obrigatorio", + "obstruir", + "obtuso", + "obus", + "obvio", + "ocaso", + "occipital", + "oceanografo", + "ocioso", + "oclusivo", + "ocorrer", + "ocre", + "octogono", + "odalisca", + "odisseia", + "odorifico", + "oersted", + "oeste", + "ofertar", + "ofidio", + "oftalmologo", + "ogiva", + "ogum", + "oigale", + "oitavo", + "oitocentos", + "ojeriza", + "olaria", + "oleoso", + "olfato", + "olhos", + "oliveira", + "olmo", + "olor", + "olvidavel", + "ombudsman", + "omeleteira", + "omitir", + "omoplata", + "onanismo", + "ondular", + "oneroso", + "onomatopeico", + "ontologico", + "onus", + "onze", + "opalescente", + "opcional", + "operistico", + "opio", + "oposto", + "oprobrio", + "optometrista", + "opusculo", + "oratorio", + "orbital", + "orcar", + "orfao", + "orixa", + "orla", + "ornitologo", + "orquidea", + "ortorrombico", + "orvalho", + "osculo", + "osmotico", + "ossudo", + "ostrogodo", + "otario", + "otite", + "ouro", + "ousar", + "outubro", + "ouvir", + "ovario", + "overnight", + "oviparo", + "ovni", + "ovoviviparo", + "ovulo", + "oxala", + "oxente", + "oxiuro", + "oxossi", + "ozonizar", + "paciente", + "pactuar", + "padronizar", + "paete", + "pagodeiro", + "paixao", + "pajem", + "paludismo", + "pampas", + "panturrilha", + "papudo", + "paquistanes", + "pastoso", + "patua", + "paulo", + "pauzinhos", + "pavoroso", + "paxa", + "pazes", + "peao", + "pecuniario", + "pedunculo", + "pegaso", + "peixinho", + "pejorativo", + "pelvis", + "penuria", + "pequno", + "petunia", + "pezada", + "piauiense", + "pictorico", + "pierro", + "pigmeu", + "pijama", + "pilulas", + "pimpolho", + "pintura", + "piorar", + "pipocar", + "piqueteiro", + "pirulito", + "pistoleiro", + "pituitaria", + "pivotar", + "pixote", + "pizzaria", + "plistoceno", + "plotar", + "pluviometrico", + "pneumonico", + "poco", + "podridao", + "poetisa", + "pogrom", + "pois", + "polvorosa", + "pomposo", + "ponderado", + "pontudo", + "populoso", + "poquer", + "porvir", + "posudo", + "potro", + "pouso", + "povoar", + "prazo", + "prezar", + "privilegios", + "proximo", + "prussiano", + "pseudopode", + "psoriase", + "pterossauros", + "ptialina", + "ptolemaico", + "pudor", + "pueril", + "pufe", + "pugilista", + "puir", + "pujante", + "pulverizar", + "pumba", + "punk", + "purulento", + "pustula", + "putsch", + "puxe", + "quatrocentos", + "quetzal", + "quixotesco", + "quotizavel", + "rabujice", + "racista", + "radonio", + "rafia", + "ragu", + "rajado", + "ralo", + "rampeiro", + "ranzinza", + "raptor", + "raquitismo", + "raro", + "rasurar", + "ratoeira", + "ravioli", + "razoavel", + "reavivar", + "rebuscar", + "recusavel", + "reduzivel", + "reexposicao", + "refutavel", + "regurgitar", + "reivindicavel", + "rejuvenescimento", + "relva", + "remuneravel", + "renunciar", + "reorientar", + "repuxo", + "requisito", + "resumo", + "returno", + "reutilizar", + "revolvido", + "rezonear", + "riacho", + "ribossomo", + "ricota", + "ridiculo", + "rifle", + "rigoroso", + "rijo", + "rimel", + "rins", + "rios", + "riqueza", + "respeito", + "rissole", + "ritualistico", + "rivalizar", + "rixa", + "robusto", + "rococo", + "rodoviario", + "roer", + "rogo", + "rojao", + "rolo", + "rompimento", + "ronronar", + "roqueiro", + "rorqual", + "rosto", + "rotundo", + "rouxinol", + "roxo", + "royal", + "ruas", + "rucula", + "rudimentos", + "ruela", + "rufo", + "rugoso", + "ruivo", + "rule", + "rumoroso", + "runico", + "ruptura", + "rural", + "rustico", + "rutilar", + "saariano", + "sabujo", + "sacudir", + "sadomasoquista", + "safra", + "sagui", + "sais", + "samurai", + "santuario", + "sapo", + "saquear", + "sartriano", + "saturno", + "saude", + "sauva", + "saveiro", + "saxofonista", + "sazonal", + "scherzo", + "script", + "seara", + "seborreia", + "secura", + "seduzir", + "sefardim", + "seguro", + "seja", + "selvas", + "sempre", + "senzala", + "sepultura", + "sequoia", + "sestercio", + "setuplo", + "seus", + "seviciar", + "sezonismo", + "shalom", + "siames", + "sibilante", + "sicrano", + "sidra", + "sifilitico", + "signos", + "silvo", + "simultaneo", + "sinusite", + "sionista", + "sirio", + "sisudo", + "situar", + "sivan", + "slide", + "slogan", + "soar", + "sobrio", + "socratico", + "sodomizar", + "soerguer", + "software", + "sogro", + "soja", + "solver", + "somente", + "sonso", + "sopro", + "soquete", + "sorveteiro", + "sossego", + "soturno", + "sousafone", + "sovinice", + "sozinho", + "suavizar", + "subverter", + "sucursal", + "sudoriparo", + "sufragio", + "sugestoes", + "suite", + "sujo", + "sultao", + "sumula", + "suntuoso", + "suor", + "supurar", + "suruba", + "susto", + "suturar", + "suvenir", + "tabuleta", + "taco", + "tadjique", + "tafeta", + "tagarelice", + "taitiano", + "talvez", + "tampouco", + "tanzaniano", + "taoista", + "tapume", + "taquion", + "tarugo", + "tascar", + "tatuar", + "tautologico", + "tavola", + "taxionomista", + "tchecoslovaco", + "teatrologo", + "tectonismo", + "tedioso", + "teflon", + "tegumento", + "teixo", + "telurio", + "temporas", + "tenue", + "teosofico", + "tepido", + "tequila", + "terrorista", + "testosterona", + "tetrico", + "teutonico", + "teve", + "texugo", + "tiara", + "tibia", + "tiete", + "tifoide", + "tigresa", + "tijolo", + "tilintar", + "timpano", + "tintureiro", + "tiquete", + "tiroteio", + "tisico", + "titulos", + "tive", + "toar", + "toboga", + "tofu", + "togoles", + "toicinho", + "tolueno", + "tomografo", + "tontura", + "toponimo", + "toquio", + "torvelinho", + "tostar", + "toto", + "touro", + "toxina", + "trazer", + "trezentos", + "trivialidade", + "trovoar", + "truta", + "tuaregue", + "tubular", + "tucano", + "tudo", + "tufo", + "tuiste", + "tulipa", + "tumultuoso", + "tunisino", + "tupiniquim", + "turvo", + "tutu", + "ucraniano", + "udenista", + "ufanista", + "ufologo", + "ugaritico", + "uiste", + "uivo", + "ulceroso", + "ulema", + "ultravioleta", + "umbilical", + "umero", + "umido", + "umlaut", + "unanimidade", + "unesco", + "ungulado", + "unheiro", + "univoco", + "untuoso", + "urano", + "urbano", + "urdir", + "uretra", + "urgente", + "urinol", + "urna", + "urologo", + "urro", + "ursulina", + "urtiga", + "urupe", + "usavel", + "usbeque", + "usei", + "usineiro", + "usurpar", + "utero", + "utilizar", + "utopico", + "uvular", + "uxoricidio", + "vacuo", + "vadio", + "vaguear", + "vaivem", + "valvula", + "vampiro", + "vantajoso", + "vaporoso", + "vaquinha", + "varziano", + "vasto", + "vaticinio", + "vaudeville", + "vazio", + "veado", + "vedico", + "veemente", + "vegetativo", + "veio", + "veja", + "veludo", + "venusiano", + "verdade", + "verve", + "vestuario", + "vetusto", + "vexatorio", + "vezes", + "viavel", + "vibratorio", + "victor", + "vicunha", + "vidros", + "vietnamita", + "vigoroso", + "vilipendiar", + "vime", + "vintem", + "violoncelo", + "viquingue", + "virus", + "visualizar", + "vituperio", + "viuvo", + "vivo", + "vizir", + "voar", + "vociferar", + "vodu", + "vogar", + "voile", + "volver", + "vomito", + "vontade", + "vortice", + "vosso", + "voto", + "vovozinha", + "voyeuse", + "vozes", + "vulva", + "vupt", + "western", + "xadrez", + "xale", + "xampu", + "xango", + "xarope", + "xaual", + "xavante", + "xaxim", + "xenonio", + "xepa", + "xerox", + "xicara", + "xifopago", + "xiita", + "xilogravura", + "xinxim", + "xistoso", + "xixi", + "xodo", + "xogum", + "xucro", + "zabumba", + "zagueiro", + "zambiano", + "zanzar", + "zarpar", + "zebu", + "zefiro", + "zeloso", + "zenite", + "zumbi" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/ru.json b/coins/monero/src/wallet/seed/classic/ru.json new file mode 100644 index 00000000..579cda33 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/ru.json @@ -0,0 +1,1628 @@ +[ + "абажур", + "абзац", + "абонент", + "абрикос", + "абсурд", + "авангард", + "август", + "авиация", + "авоська", + "автор", + "агат", + "агент", + "агитатор", + "агнец", + "агония", + "агрегат", + "адвокат", + "адмирал", + "адрес", + "ажиотаж", + "азарт", + "азбука", + "азот", + "аист", + "айсберг", + "академия", + "аквариум", + "аккорд", + "акробат", + "аксиома", + "актер", + "акула", + "акция", + "алгоритм", + "алебарда", + "аллея", + "алмаз", + "алтарь", + "алфавит", + "алхимик", + "алый", + "альбом", + "алюминий", + "амбар", + "аметист", + "амнезия", + "ампула", + "амфора", + "анализ", + "ангел", + "анекдот", + "анимация", + "анкета", + "аномалия", + "ансамбль", + "антенна", + "апатия", + "апельсин", + "апофеоз", + "аппарат", + "апрель", + "аптека", + "арабский", + "арбуз", + "аргумент", + "арест", + "ария", + "арка", + "армия", + "аромат", + "арсенал", + "артист", + "архив", + "аршин", + "асбест", + "аскетизм", + "аспект", + "ассорти", + "астроном", + "асфальт", + "атака", + "ателье", + "атлас", + "атом", + "атрибут", + "аудитор", + "аукцион", + "аура", + "афера", + "афиша", + "ахинея", + "ацетон", + "аэропорт", + "бабушка", + "багаж", + "бадья", + "база", + "баклажан", + "балкон", + "бампер", + "банк", + "барон", + "бассейн", + "батарея", + "бахрома", + "башня", + "баян", + "бегство", + "бедро", + "бездна", + "бекон", + "белый", + "бензин", + "берег", + "беседа", + "бетонный", + "биатлон", + "библия", + "бивень", + "бигуди", + "бидон", + "бизнес", + "бикини", + "билет", + "бинокль", + "биология", + "биржа", + "бисер", + "битва", + "бицепс", + "благо", + "бледный", + "близкий", + "блок", + "блуждать", + "блюдо", + "бляха", + "бобер", + "богатый", + "бодрый", + "боевой", + "бокал", + "большой", + "борьба", + "босой", + "ботинок", + "боцман", + "бочка", + "боярин", + "брать", + "бревно", + "бригада", + "бросать", + "брызги", + "брюки", + "бублик", + "бугор", + "будущее", + "буква", + "бульвар", + "бумага", + "бунт", + "бурный", + "бусы", + "бутылка", + "буфет", + "бухта", + "бушлат", + "бывалый", + "быль", + "быстрый", + "быть", + "бюджет", + "бюро", + "бюст", + "вагон", + "важный", + "ваза", + "вакцина", + "валюта", + "вампир", + "ванная", + "вариант", + "вассал", + "вата", + "вафля", + "вахта", + "вдова", + "вдыхать", + "ведущий", + "веер", + "вежливый", + "везти", + "веко", + "великий", + "вена", + "верить", + "веселый", + "ветер", + "вечер", + "вешать", + "вещь", + "веяние", + "взаимный", + "взбучка", + "взвод", + "взгляд", + "вздыхать", + "взлетать", + "взмах", + "взнос", + "взор", + "взрыв", + "взывать", + "взятка", + "вибрация", + "визит", + "вилка", + "вино", + "вирус", + "висеть", + "витрина", + "вихрь", + "вишневый", + "включать", + "вкус", + "власть", + "влечь", + "влияние", + "влюблять", + "внешний", + "внимание", + "внук", + "внятный", + "вода", + "воевать", + "вождь", + "воздух", + "войти", + "вокзал", + "волос", + "вопрос", + "ворота", + "восток", + "впадать", + "впускать", + "врач", + "время", + "вручать", + "всадник", + "всеобщий", + "вспышка", + "встреча", + "вторник", + "вулкан", + "вурдалак", + "входить", + "въезд", + "выбор", + "вывод", + "выгодный", + "выделять", + "выезжать", + "выживать", + "вызывать", + "выигрыш", + "вылезать", + "выносить", + "выпивать", + "высокий", + "выходить", + "вычет", + "вышка", + "выяснять", + "вязать", + "вялый", + "гавань", + "гадать", + "газета", + "гаишник", + "галстук", + "гамма", + "гарантия", + "гастроли", + "гвардия", + "гвоздь", + "гектар", + "гель", + "генерал", + "геолог", + "герой", + "гешефт", + "гибель", + "гигант", + "гильза", + "гимн", + "гипотеза", + "гитара", + "глаз", + "глина", + "глоток", + "глубокий", + "глыба", + "глядеть", + "гнать", + "гнев", + "гнить", + "гном", + "гнуть", + "говорить", + "годовой", + "голова", + "гонка", + "город", + "гость", + "готовый", + "граница", + "грех", + "гриб", + "громкий", + "группа", + "грызть", + "грязный", + "губа", + "гудеть", + "гулять", + "гуманный", + "густой", + "гуща", + "давать", + "далекий", + "дама", + "данные", + "дарить", + "дать", + "дача", + "дверь", + "движение", + "двор", + "дебют", + "девушка", + "дедушка", + "дежурный", + "дезертир", + "действие", + "декабрь", + "дело", + "демократ", + "день", + "депутат", + "держать", + "десяток", + "детский", + "дефицит", + "дешевый", + "деятель", + "джаз", + "джинсы", + "джунгли", + "диалог", + "диван", + "диета", + "дизайн", + "дикий", + "динамика", + "диплом", + "директор", + "диск", + "дитя", + "дичь", + "длинный", + "дневник", + "добрый", + "доверие", + "договор", + "дождь", + "доза", + "документ", + "должен", + "домашний", + "допрос", + "дорога", + "доход", + "доцент", + "дочь", + "дощатый", + "драка", + "древний", + "дрожать", + "друг", + "дрянь", + "дубовый", + "дуга", + "дудка", + "дукат", + "дуло", + "думать", + "дупло", + "дурак", + "дуть", + "духи", + "душа", + "дуэт", + "дымить", + "дыня", + "дыра", + "дыханье", + "дышать", + "дьявол", + "дюжина", + "дюйм", + "дюна", + "дядя", + "дятел", + "егерь", + "единый", + "едкий", + "ежевика", + "ежик", + "езда", + "елка", + "емкость", + "ерунда", + "ехать", + "жадный", + "жажда", + "жалеть", + "жанр", + "жара", + "жать", + "жгучий", + "ждать", + "жевать", + "желание", + "жемчуг", + "женщина", + "жертва", + "жесткий", + "жечь", + "живой", + "жидкость", + "жизнь", + "жилье", + "жирный", + "житель", + "журнал", + "жюри", + "забывать", + "завод", + "загадка", + "задача", + "зажечь", + "зайти", + "закон", + "замечать", + "занимать", + "западный", + "зарплата", + "засыпать", + "затрата", + "захват", + "зацепка", + "зачет", + "защита", + "заявка", + "звать", + "звезда", + "звонить", + "звук", + "здание", + "здешний", + "здоровье", + "зебра", + "зевать", + "зеленый", + "земля", + "зенит", + "зеркало", + "зефир", + "зигзаг", + "зима", + "зиять", + "злак", + "злой", + "змея", + "знать", + "зной", + "зодчий", + "золотой", + "зомби", + "зона", + "зоопарк", + "зоркий", + "зрачок", + "зрение", + "зритель", + "зубной", + "зыбкий", + "зять", + "игла", + "иголка", + "играть", + "идея", + "идиот", + "идол", + "идти", + "иерархия", + "избрать", + "известие", + "изгонять", + "издание", + "излагать", + "изменять", + "износ", + "изоляция", + "изрядный", + "изучать", + "изымать", + "изящный", + "икона", + "икра", + "иллюзия", + "имбирь", + "иметь", + "имидж", + "иммунный", + "империя", + "инвестор", + "индивид", + "инерция", + "инженер", + "иномарка", + "институт", + "интерес", + "инфекция", + "инцидент", + "ипподром", + "ирис", + "ирония", + "искать", + "история", + "исходить", + "исчезать", + "итог", + "июль", + "июнь", + "кабинет", + "кавалер", + "кадр", + "казарма", + "кайф", + "кактус", + "калитка", + "камень", + "канал", + "капитан", + "картина", + "касса", + "катер", + "кафе", + "качество", + "каша", + "каюта", + "квартира", + "квинтет", + "квота", + "кедр", + "кекс", + "кенгуру", + "кепка", + "керосин", + "кетчуп", + "кефир", + "кибитка", + "кивнуть", + "кидать", + "километр", + "кино", + "киоск", + "кипеть", + "кирпич", + "кисть", + "китаец", + "класс", + "клетка", + "клиент", + "клоун", + "клуб", + "клык", + "ключ", + "клятва", + "книга", + "кнопка", + "кнут", + "князь", + "кобура", + "ковер", + "коготь", + "кодекс", + "кожа", + "козел", + "койка", + "коктейль", + "колено", + "компания", + "конец", + "копейка", + "короткий", + "костюм", + "котел", + "кофе", + "кошка", + "красный", + "кресло", + "кричать", + "кровь", + "крупный", + "крыша", + "крючок", + "кубок", + "кувшин", + "кудрявый", + "кузов", + "кукла", + "культура", + "кумир", + "купить", + "курс", + "кусок", + "кухня", + "куча", + "кушать", + "кювет", + "лабиринт", + "лавка", + "лагерь", + "ладонь", + "лазерный", + "лайнер", + "лакей", + "лампа", + "ландшафт", + "лапа", + "ларек", + "ласковый", + "лауреат", + "лачуга", + "лаять", + "лгать", + "лебедь", + "левый", + "легкий", + "ледяной", + "лежать", + "лекция", + "лента", + "лепесток", + "лесной", + "лето", + "лечь", + "леший", + "лживый", + "либерал", + "ливень", + "лига", + "лидер", + "ликовать", + "лиловый", + "лимон", + "линия", + "липа", + "лирика", + "лист", + "литр", + "лифт", + "лихой", + "лицо", + "личный", + "лишний", + "лобовой", + "ловить", + "логика", + "лодка", + "ложка", + "лозунг", + "локоть", + "ломать", + "лоно", + "лопата", + "лорд", + "лось", + "лоток", + "лохматый", + "лошадь", + "лужа", + "лукавый", + "луна", + "лупить", + "лучший", + "лыжный", + "лысый", + "львиный", + "льгота", + "льдина", + "любить", + "людской", + "люстра", + "лютый", + "лягушка", + "магазин", + "мадам", + "мазать", + "майор", + "максимум", + "мальчик", + "манера", + "март", + "масса", + "мать", + "мафия", + "махать", + "мачта", + "машина", + "маэстро", + "маяк", + "мгла", + "мебель", + "медведь", + "мелкий", + "мемуары", + "менять", + "мера", + "место", + "метод", + "механизм", + "мечтать", + "мешать", + "миграция", + "мизинец", + "микрофон", + "миллион", + "минута", + "мировой", + "миссия", + "митинг", + "мишень", + "младший", + "мнение", + "мнимый", + "могила", + "модель", + "мозг", + "мойка", + "мокрый", + "молодой", + "момент", + "монах", + "море", + "мост", + "мотор", + "мохнатый", + "мочь", + "мошенник", + "мощный", + "мрачный", + "мстить", + "мудрый", + "мужчина", + "музыка", + "мука", + "мумия", + "мундир", + "муравей", + "мусор", + "мутный", + "муфта", + "муха", + "мучить", + "мушкетер", + "мыло", + "мысль", + "мыть", + "мычать", + "мышь", + "мэтр", + "мюзикл", + "мягкий", + "мякиш", + "мясо", + "мятый", + "мячик", + "набор", + "навык", + "нагрузка", + "надежда", + "наемный", + "нажать", + "называть", + "наивный", + "накрыть", + "налог", + "намерен", + "наносить", + "написать", + "народ", + "натура", + "наука", + "нация", + "начать", + "небо", + "невеста", + "негодяй", + "неделя", + "нежный", + "незнание", + "нелепый", + "немалый", + "неправда", + "нервный", + "нести", + "нефть", + "нехватка", + "нечистый", + "неясный", + "нива", + "нижний", + "низкий", + "никель", + "нирвана", + "нить", + "ничья", + "ниша", + "нищий", + "новый", + "нога", + "ножницы", + "ноздря", + "ноль", + "номер", + "норма", + "нота", + "ночь", + "ноша", + "ноябрь", + "нрав", + "нужный", + "нутро", + "нынешний", + "нырнуть", + "ныть", + "нюанс", + "нюхать", + "няня", + "оазис", + "обаяние", + "обвинять", + "обгонять", + "обещать", + "обжигать", + "обзор", + "обида", + "область", + "обмен", + "обнимать", + "оборона", + "образ", + "обучение", + "обходить", + "обширный", + "общий", + "объект", + "обычный", + "обязать", + "овальный", + "овес", + "овощи", + "овраг", + "овца", + "овчарка", + "огненный", + "огонь", + "огромный", + "огурец", + "одежда", + "одинокий", + "одобрить", + "ожидать", + "ожог", + "озарение", + "озеро", + "означать", + "оказать", + "океан", + "оклад", + "окно", + "округ", + "октябрь", + "окурок", + "олень", + "опасный", + "операция", + "описать", + "оплата", + "опора", + "оппонент", + "опрос", + "оптимизм", + "опускать", + "опыт", + "орать", + "орбита", + "орган", + "орден", + "орел", + "оригинал", + "оркестр", + "орнамент", + "оружие", + "осадок", + "освещать", + "осень", + "осина", + "осколок", + "осмотр", + "основной", + "особый", + "осуждать", + "отбор", + "отвечать", + "отдать", + "отец", + "отзыв", + "открытие", + "отмечать", + "относить", + "отпуск", + "отрасль", + "отставка", + "оттенок", + "отходить", + "отчет", + "отъезд", + "офицер", + "охапка", + "охота", + "охрана", + "оценка", + "очаг", + "очередь", + "очищать", + "очки", + "ошейник", + "ошибка", + "ощущение", + "павильон", + "падать", + "паек", + "пакет", + "палец", + "память", + "панель", + "папка", + "партия", + "паспорт", + "патрон", + "пауза", + "пафос", + "пахнуть", + "пациент", + "пачка", + "пашня", + "певец", + "педагог", + "пейзаж", + "пельмень", + "пенсия", + "пепел", + "период", + "песня", + "петля", + "пехота", + "печать", + "пешеход", + "пещера", + "пианист", + "пиво", + "пиджак", + "пиковый", + "пилот", + "пионер", + "пирог", + "писать", + "пить", + "пицца", + "пишущий", + "пища", + "план", + "плечо", + "плита", + "плохой", + "плыть", + "плюс", + "пляж", + "победа", + "повод", + "погода", + "подумать", + "поехать", + "пожимать", + "позиция", + "поиск", + "покой", + "получать", + "помнить", + "пони", + "поощрять", + "попадать", + "порядок", + "пост", + "поток", + "похожий", + "поцелуй", + "почва", + "пощечина", + "поэт", + "пояснить", + "право", + "предмет", + "проблема", + "пруд", + "прыгать", + "прямой", + "психолог", + "птица", + "публика", + "пугать", + "пудра", + "пузырь", + "пуля", + "пункт", + "пурга", + "пустой", + "путь", + "пухлый", + "пучок", + "пушистый", + "пчела", + "пшеница", + "пыль", + "пытка", + "пыхтеть", + "пышный", + "пьеса", + "пьяный", + "пятно", + "работа", + "равный", + "радость", + "развитие", + "район", + "ракета", + "рамка", + "ранний", + "рапорт", + "рассказ", + "раунд", + "рация", + "рвать", + "реальный", + "ребенок", + "реветь", + "регион", + "редакция", + "реестр", + "режим", + "резкий", + "рейтинг", + "река", + "религия", + "ремонт", + "рента", + "реплика", + "ресурс", + "реформа", + "рецепт", + "речь", + "решение", + "ржавый", + "рисунок", + "ритм", + "рифма", + "робкий", + "ровный", + "рогатый", + "родитель", + "рождение", + "розовый", + "роковой", + "роль", + "роман", + "ронять", + "рост", + "рота", + "роща", + "рояль", + "рубль", + "ругать", + "руда", + "ружье", + "руины", + "рука", + "руль", + "румяный", + "русский", + "ручка", + "рыба", + "рывок", + "рыдать", + "рыжий", + "рынок", + "рысь", + "рыть", + "рыхлый", + "рыцарь", + "рычаг", + "рюкзак", + "рюмка", + "рябой", + "рядовой", + "сабля", + "садовый", + "сажать", + "салон", + "самолет", + "сани", + "сапог", + "сарай", + "сатира", + "сауна", + "сахар", + "сбегать", + "сбивать", + "сбор", + "сбыт", + "свадьба", + "свет", + "свидание", + "свобода", + "связь", + "сгорать", + "сдвигать", + "сеанс", + "северный", + "сегмент", + "седой", + "сезон", + "сейф", + "секунда", + "сельский", + "семья", + "сентябрь", + "сердце", + "сеть", + "сечение", + "сеять", + "сигнал", + "сидеть", + "сизый", + "сила", + "символ", + "синий", + "сирота", + "система", + "ситуация", + "сиять", + "сказать", + "скважина", + "скелет", + "скидка", + "склад", + "скорый", + "скрывать", + "скучный", + "слава", + "слеза", + "слияние", + "слово", + "случай", + "слышать", + "слюна", + "смех", + "смирение", + "смотреть", + "смутный", + "смысл", + "смятение", + "снаряд", + "снег", + "снижение", + "сносить", + "снять", + "событие", + "совет", + "согласие", + "сожалеть", + "сойти", + "сокол", + "солнце", + "сомнение", + "сонный", + "сообщать", + "соперник", + "сорт", + "состав", + "сотня", + "соус", + "социолог", + "сочинять", + "союз", + "спать", + "спешить", + "спина", + "сплошной", + "способ", + "спутник", + "средство", + "срок", + "срывать", + "стать", + "ствол", + "стена", + "стихи", + "сторона", + "страна", + "студент", + "стыд", + "субъект", + "сувенир", + "сугроб", + "судьба", + "суета", + "суждение", + "сукно", + "сулить", + "сумма", + "сунуть", + "супруг", + "суровый", + "сустав", + "суть", + "сухой", + "суша", + "существо", + "сфера", + "схема", + "сцена", + "счастье", + "счет", + "считать", + "сшивать", + "съезд", + "сынок", + "сыпать", + "сырье", + "сытый", + "сыщик", + "сюжет", + "сюрприз", + "таблица", + "таежный", + "таинство", + "тайна", + "такси", + "талант", + "таможня", + "танец", + "тарелка", + "таскать", + "тахта", + "тачка", + "таять", + "тварь", + "твердый", + "творить", + "театр", + "тезис", + "текст", + "тело", + "тема", + "тень", + "теория", + "теплый", + "терять", + "тесный", + "тетя", + "техника", + "течение", + "тигр", + "типичный", + "тираж", + "титул", + "тихий", + "тишина", + "ткань", + "товарищ", + "толпа", + "тонкий", + "топливо", + "торговля", + "тоска", + "точка", + "тощий", + "традиция", + "тревога", + "трибуна", + "трогать", + "труд", + "трюк", + "тряпка", + "туалет", + "тугой", + "туловище", + "туман", + "тундра", + "тупой", + "турнир", + "тусклый", + "туфля", + "туча", + "туша", + "тыкать", + "тысяча", + "тьма", + "тюльпан", + "тюрьма", + "тяга", + "тяжелый", + "тянуть", + "убеждать", + "убирать", + "убогий", + "убыток", + "уважение", + "уверять", + "увлекать", + "угнать", + "угол", + "угроза", + "удар", + "удивлять", + "удобный", + "уезд", + "ужас", + "ужин", + "узел", + "узкий", + "узнавать", + "узор", + "уйма", + "уклон", + "укол", + "уксус", + "улетать", + "улица", + "улучшать", + "улыбка", + "уметь", + "умиление", + "умный", + "умолять", + "умысел", + "унижать", + "уносить", + "уныние", + "упасть", + "уплата", + "упор", + "упрекать", + "упускать", + "уран", + "урна", + "уровень", + "усадьба", + "усердие", + "усилие", + "ускорять", + "условие", + "усмешка", + "уснуть", + "успеть", + "усыпать", + "утешать", + "утка", + "уточнять", + "утро", + "утюг", + "уходить", + "уцелеть", + "участие", + "ученый", + "учитель", + "ушко", + "ущерб", + "уютный", + "уяснять", + "фабрика", + "фаворит", + "фаза", + "файл", + "факт", + "фамилия", + "фантазия", + "фара", + "фасад", + "февраль", + "фельдшер", + "феномен", + "ферма", + "фигура", + "физика", + "фильм", + "финал", + "фирма", + "фишка", + "флаг", + "флейта", + "флот", + "фокус", + "фольклор", + "фонд", + "форма", + "фото", + "фраза", + "фреска", + "фронт", + "фрукт", + "функция", + "фуражка", + "футбол", + "фыркать", + "халат", + "хамство", + "хаос", + "характер", + "хата", + "хватать", + "хвост", + "хижина", + "хилый", + "химия", + "хирург", + "хитрый", + "хищник", + "хлам", + "хлеб", + "хлопать", + "хмурый", + "ходить", + "хозяин", + "хоккей", + "холодный", + "хороший", + "хотеть", + "хохотать", + "храм", + "хрен", + "хриплый", + "хроника", + "хрупкий", + "художник", + "хулиган", + "хутор", + "царь", + "цвет", + "цель", + "цемент", + "центр", + "цепь", + "церковь", + "цикл", + "цилиндр", + "циничный", + "цирк", + "цистерна", + "цитата", + "цифра", + "цыпленок", + "чадо", + "чайник", + "часть", + "чашка", + "человек", + "чемодан", + "чепуха", + "черный", + "честь", + "четкий", + "чехол", + "чиновник", + "число", + "читать", + "членство", + "чреватый", + "чтение", + "чувство", + "чугунный", + "чудо", + "чужой", + "чукча", + "чулок", + "чума", + "чуткий", + "чучело", + "чушь", + "шаблон", + "шагать", + "шайка", + "шакал", + "шалаш", + "шампунь", + "шанс", + "шапка", + "шарик", + "шасси", + "шатер", + "шахта", + "шашлык", + "швейный", + "швырять", + "шевелить", + "шедевр", + "шейка", + "шелковый", + "шептать", + "шерсть", + "шестерка", + "шикарный", + "шинель", + "шипеть", + "широкий", + "шить", + "шишка", + "шкаф", + "школа", + "шкура", + "шланг", + "шлем", + "шлюпка", + "шляпа", + "шнур", + "шоколад", + "шорох", + "шоссе", + "шофер", + "шпага", + "шпион", + "шприц", + "шрам", + "шрифт", + "штаб", + "штора", + "штраф", + "штука", + "штык", + "шуба", + "шуметь", + "шуршать", + "шутка", + "щадить", + "щедрый", + "щека", + "щель", + "щенок", + "щепка", + "щетка", + "щука", + "эволюция", + "эгоизм", + "экзамен", + "экипаж", + "экономия", + "экран", + "эксперт", + "элемент", + "элита", + "эмблема", + "эмигрант", + "эмоция", + "энергия", + "эпизод", + "эпоха", + "эскиз", + "эссе", + "эстрада", + "этап", + "этика", + "этюд", + "эфир", + "эффект", + "эшелон", + "юбилей", + "юбка", + "южный", + "юмор", + "юноша", + "юрист", + "яблоко", + "явление", + "ягода", + "ядерный", + "ядовитый", + "ядро", + "язва", + "язык", + "яйцо", + "якорь", + "январь", + "японец", + "яркий", + "ярмарка", + "ярость", + "ярус", + "ясный", + "яхта", + "ячейка", + "ящик" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/classic/zh.json b/coins/monero/src/wallet/seed/classic/zh.json new file mode 100644 index 00000000..9d03e9d8 --- /dev/null +++ b/coins/monero/src/wallet/seed/classic/zh.json @@ -0,0 +1,1628 @@ +[ + "的", + "一", + "是", + "在", + "不", + "了", + "有", + "和", + "人", + "这", + "中", + "大", + "为", + "上", + "个", + "国", + "我", + "以", + "要", + "他", + "时", + "来", + "用", + "们", + "生", + "到", + "作", + "地", + "于", + "出", + "就", + "分", + "对", + "成", + "会", + "可", + "主", + "发", + "年", + "动", + "同", + "工", + "也", + "能", + "下", + "过", + "子", + "说", + "产", + "种", + "面", + "而", + "方", + "后", + "多", + "定", + "行", + "学", + "法", + "所", + "民", + "得", + "经", + "十", + "三", + "之", + "进", + "着", + "等", + "部", + "度", + "家", + "电", + "力", + "里", + "如", + "水", + "化", + "高", + "自", + "二", + "理", + "起", + "小", + "物", + "现", + "实", + "加", + "量", + "都", + "两", + "体", + "制", + "机", + "当", + "使", + "点", + "从", + "业", + "本", + "去", + "把", + "性", + "好", + "应", + "开", + "它", + "合", + "还", + "因", + "由", + "其", + "些", + "然", + "前", + "外", + "天", + "政", + "四", + "日", + "那", + "社", + "义", + "事", + "平", + "形", + "相", + "全", + "表", + "间", + "样", + "与", + "关", + "各", + "重", + "新", + "线", + "内", + "数", + "正", + "心", + "反", + "你", + "明", + "看", + "原", + "又", + "么", + "利", + "比", + "或", + "但", + "质", + "气", + "第", + "向", + "道", + "命", + "此", + "变", + "条", + "只", + "没", + "结", + "解", + "问", + "意", + "建", + "月", + "公", + "无", + "系", + "军", + "很", + "情", + "者", + "最", + "立", + "代", + "想", + "已", + "通", + "并", + "提", + "直", + "题", + "党", + "程", + "展", + "五", + "果", + "料", + "象", + "员", + "革", + "位", + "入", + "常", + "文", + "总", + "次", + "品", + "式", + "活", + "设", + "及", + "管", + "特", + "件", + "长", + "求", + "老", + "头", + "基", + "资", + "边", + "流", + "路", + "级", + "少", + "图", + "山", + "统", + "接", + "知", + "较", + "将", + "组", + "见", + "计", + "别", + "她", + "手", + "角", + "期", + "根", + "论", + "运", + "农", + "指", + "几", + "九", + "区", + "强", + "放", + "决", + "西", + "被", + "干", + "做", + "必", + "战", + "先", + "回", + "则", + "任", + "取", + "据", + "处", + "队", + "南", + "给", + "色", + "光", + "门", + "即", + "保", + "治", + "北", + "造", + "百", + "规", + "热", + "领", + "七", + "海", + "口", + "东", + "导", + "器", + "压", + "志", + "世", + "金", + "增", + "争", + "济", + "阶", + "油", + "思", + "术", + "极", + "交", + "受", + "联", + "什", + "认", + "六", + "共", + "权", + "收", + "证", + "改", + "清", + "美", + "再", + "采", + "转", + "更", + "单", + "风", + "切", + "打", + "白", + "教", + "速", + "花", + "带", + "安", + "场", + "身", + "车", + "例", + "真", + "务", + "具", + "万", + "每", + "目", + "至", + "达", + "走", + "积", + "示", + "议", + "声", + "报", + "斗", + "完", + "类", + "八", + "离", + "华", + "名", + "确", + "才", + "科", + "张", + "信", + "马", + "节", + "话", + "米", + "整", + "空", + "元", + "况", + "今", + "集", + "温", + "传", + "土", + "许", + "步", + "群", + "广", + "石", + "记", + "需", + "段", + "研", + "界", + "拉", + "林", + "律", + "叫", + "且", + "究", + "观", + "越", + "织", + "装", + "影", + "算", + "低", + "持", + "音", + "众", + "书", + "布", + "复", + "容", + "儿", + "须", + "际", + "商", + "非", + "验", + "连", + "断", + "深", + "难", + "近", + "矿", + "千", + "周", + "委", + "素", + "技", + "备", + "半", + "办", + "青", + "省", + "列", + "习", + "响", + "约", + "支", + "般", + "史", + "感", + "劳", + "便", + "团", + "往", + "酸", + "历", + "市", + "克", + "何", + "除", + "消", + "构", + "府", + "称", + "太", + "准", + "精", + "值", + "号", + "率", + "族", + "维", + "划", + "选", + "标", + "写", + "存", + "候", + "毛", + "亲", + "快", + "效", + "斯", + "院", + "查", + "江", + "型", + "眼", + "王", + "按", + "格", + "养", + "易", + "置", + "派", + "层", + "片", + "始", + "却", + "专", + "状", + "育", + "厂", + "京", + "识", + "适", + "属", + "圆", + "包", + "火", + "住", + "调", + "满", + "县", + "局", + "照", + "参", + "红", + "细", + "引", + "听", + "该", + "铁", + "价", + "严", + "首", + "底", + "液", + "官", + "德", + "随", + "病", + "苏", + "失", + "尔", + "死", + "讲", + "配", + "女", + "黄", + "推", + "显", + "谈", + "罪", + "神", + "艺", + "呢", + "席", + "含", + "企", + "望", + "密", + "批", + "营", + "项", + "防", + "举", + "球", + "英", + "氧", + "势", + "告", + "李", + "台", + "落", + "木", + "帮", + "轮", + "破", + "亚", + "师", + "围", + "注", + "远", + "字", + "材", + "排", + "供", + "河", + "态", + "封", + "另", + "施", + "减", + "树", + "溶", + "怎", + "止", + "案", + "言", + "士", + "均", + "武", + "固", + "叶", + "鱼", + "波", + "视", + "仅", + "费", + "紧", + "爱", + "左", + "章", + "早", + "朝", + "害", + "续", + "轻", + "服", + "试", + "食", + "充", + "兵", + "源", + "判", + "护", + "司", + "足", + "某", + "练", + "差", + "致", + "板", + "田", + "降", + "黑", + "犯", + "负", + "击", + "范", + "继", + "兴", + "似", + "余", + "坚", + "曲", + "输", + "修", + "故", + "城", + "夫", + "够", + "送", + "笔", + "船", + "占", + "右", + "财", + "吃", + "富", + "春", + "职", + "觉", + "汉", + "画", + "功", + "巴", + "跟", + "虽", + "杂", + "飞", + "检", + "吸", + "助", + "升", + "阳", + "互", + "初", + "创", + "抗", + "考", + "投", + "坏", + "策", + "古", + "径", + "换", + "未", + "跑", + "留", + "钢", + "曾", + "端", + "责", + "站", + "简", + "述", + "钱", + "副", + "尽", + "帝", + "射", + "草", + "冲", + "承", + "独", + "令", + "限", + "阿", + "宣", + "环", + "双", + "请", + "超", + "微", + "让", + "控", + "州", + "良", + "轴", + "找", + "否", + "纪", + "益", + "依", + "优", + "顶", + "础", + "载", + "倒", + "房", + "突", + "坐", + "粉", + "敌", + "略", + "客", + "袁", + "冷", + "胜", + "绝", + "析", + "块", + "剂", + "测", + "丝", + "协", + "诉", + "念", + "陈", + "仍", + "罗", + "盐", + "友", + "洋", + "错", + "苦", + "夜", + "刑", + "移", + "频", + "逐", + "靠", + "混", + "母", + "短", + "皮", + "终", + "聚", + "汽", + "村", + "云", + "哪", + "既", + "距", + "卫", + "停", + "烈", + "央", + "察", + "烧", + "迅", + "境", + "若", + "印", + "洲", + "刻", + "括", + "激", + "孔", + "搞", + "甚", + "室", + "待", + "核", + "校", + "散", + "侵", + "吧", + "甲", + "游", + "久", + "菜", + "味", + "旧", + "模", + "湖", + "货", + "损", + "预", + "阻", + "毫", + "普", + "稳", + "乙", + "妈", + "植", + "息", + "扩", + "银", + "语", + "挥", + "酒", + "守", + "拿", + "序", + "纸", + "医", + "缺", + "雨", + "吗", + "针", + "刘", + "啊", + "急", + "唱", + "误", + "训", + "愿", + "审", + "附", + "获", + "茶", + "鲜", + "粮", + "斤", + "孩", + "脱", + "硫", + "肥", + "善", + "龙", + "演", + "父", + "渐", + "血", + "欢", + "械", + "掌", + "歌", + "沙", + "刚", + "攻", + "谓", + "盾", + "讨", + "晚", + "粒", + "乱", + "燃", + "矛", + "乎", + "杀", + "药", + "宁", + "鲁", + "贵", + "钟", + "煤", + "读", + "班", + "伯", + "香", + "介", + "迫", + "句", + "丰", + "培", + "握", + "兰", + "担", + "弦", + "蛋", + "沉", + "假", + "穿", + "执", + "答", + "乐", + "谁", + "顺", + "烟", + "缩", + "征", + "脸", + "喜", + "松", + "脚", + "困", + "异", + "免", + "背", + "星", + "福", + "买", + "染", + "井", + "概", + "慢", + "怕", + "磁", + "倍", + "祖", + "皇", + "促", + "静", + "补", + "评", + "翻", + "肉", + "践", + "尼", + "衣", + "宽", + "扬", + "棉", + "希", + "伤", + "操", + "垂", + "秋", + "宜", + "氢", + "套", + "督", + "振", + "架", + "亮", + "末", + "宪", + "庆", + "编", + "牛", + "触", + "映", + "雷", + "销", + "诗", + "座", + "居", + "抓", + "裂", + "胞", + "呼", + "娘", + "景", + "威", + "绿", + "晶", + "厚", + "盟", + "衡", + "鸡", + "孙", + "延", + "危", + "胶", + "屋", + "乡", + "临", + "陆", + "顾", + "掉", + "呀", + "灯", + "岁", + "措", + "束", + "耐", + "剧", + "玉", + "赵", + "跳", + "哥", + "季", + "课", + "凯", + "胡", + "额", + "款", + "绍", + "卷", + "齐", + "伟", + "蒸", + "殖", + "永", + "宗", + "苗", + "川", + "炉", + "岩", + "弱", + "零", + "杨", + "奏", + "沿", + "露", + "杆", + "探", + "滑", + "镇", + "饭", + "浓", + "航", + "怀", + "赶", + "库", + "夺", + "伊", + "灵", + "税", + "途", + "灭", + "赛", + "归", + "召", + "鼓", + "播", + "盘", + "裁", + "险", + "康", + "唯", + "录", + "菌", + "纯", + "借", + "糖", + "盖", + "横", + "符", + "私", + "努", + "堂", + "域", + "枪", + "润", + "幅", + "哈", + "竟", + "熟", + "虫", + "泽", + "脑", + "壤", + "碳", + "欧", + "遍", + "侧", + "寨", + "敢", + "彻", + "虑", + "斜", + "薄", + "庭", + "纳", + "弹", + "饲", + "伸", + "折", + "麦", + "湿", + "暗", + "荷", + "瓦", + "塞", + "床", + "筑", + "恶", + "户", + "访", + "塔", + "奇", + "透", + "梁", + "刀", + "旋", + "迹", + "卡", + "氯", + "遇", + "份", + "毒", + "泥", + "退", + "洗", + "摆", + "灰", + "彩", + "卖", + "耗", + "夏", + "择", + "忙", + "铜", + "献", + "硬", + "予", + "繁", + "圈", + "雪", + "函", + "亦", + "抽", + "篇", + "阵", + "阴", + "丁", + "尺", + "追", + "堆", + "雄", + "迎", + "泛", + "爸", + "楼", + "避", + "谋", + "吨", + "野", + "猪", + "旗", + "累", + "偏", + "典", + "馆", + "索", + "秦", + "脂", + "潮", + "爷", + "豆", + "忽", + "托", + "惊", + "塑", + "遗", + "愈", + "朱", + "替", + "纤", + "粗", + "倾", + "尚", + "痛", + "楚", + "谢", + "奋", + "购", + "磨", + "君", + "池", + "旁", + "碎", + "骨", + "监", + "捕", + "弟", + "暴", + "割", + "贯", + "殊", + "释", + "词", + "亡", + "壁", + "顿", + "宝", + "午", + "尘", + "闻", + "揭", + "炮", + "残", + "冬", + "桥", + "妇", + "警", + "综", + "招", + "吴", + "付", + "浮", + "遭", + "徐", + "您", + "摇", + "谷", + "赞", + "箱", + "隔", + "订", + "男", + "吹", + "园", + "纷", + "唐", + "败", + "宋", + "玻", + "巨", + "耕", + "坦", + "荣", + "闭", + "湾", + "键", + "凡", + "驻", + "锅", + "救", + "恩", + "剥", + "凝", + "碱", + "齿", + "截", + "炼", + "麻", + "纺", + "禁", + "废", + "盛", + "版", + "缓", + "净", + "睛", + "昌", + "婚", + "涉", + "筒", + "嘴", + "插", + "岸", + "朗", + "庄", + "街", + "藏", + "姑", + "贸", + "腐", + "奴", + "啦", + "惯", + "乘", + "伙", + "恢", + "匀", + "纱", + "扎", + "辩", + "耳", + "彪", + "臣", + "亿", + "璃", + "抵", + "脉", + "秀", + "萨", + "俄", + "网", + "舞", + "店", + "喷", + "纵", + "寸", + "汗", + "挂", + "洪", + "贺", + "闪", + "柬", + "爆", + "烯", + "津", + "稻", + "墙", + "软", + "勇", + "像", + "滚", + "厘", + "蒙", + "芳", + "肯", + "坡", + "柱", + "荡", + "腿", + "仪", + "旅", + "尾", + "轧", + "冰", + "贡", + "登", + "黎", + "削", + "钻", + "勒", + "逃", + "障", + "氨", + "郭", + "峰", + "币", + "港", + "伏", + "轨", + "亩", + "毕", + "擦", + "莫", + "刺", + "浪", + "秘", + "援", + "株", + "健", + "售", + "股", + "岛", + "甘", + "泡", + "睡", + "童", + "铸", + "汤", + "阀", + "休", + "汇", + "舍", + "牧", + "绕", + "炸", + "哲", + "磷", + "绩", + "朋", + "淡", + "尖", + "启", + "陷", + "柴", + "呈", + "徒", + "颜", + "泪", + "稍", + "忘", + "泵", + "蓝", + "拖", + "洞", + "授", + "镜", + "辛", + "壮", + "锋", + "贫", + "虚", + "弯", + "摩", + "泰", + "幼", + "廷", + "尊", + "窗", + "纲", + "弄", + "隶", + "疑", + "氏", + "宫", + "姐", + "震", + "瑞", + "怪", + "尤", + "琴", + "循", + "描", + "膜", + "违", + "夹", + "腰", + "缘", + "珠", + "穷", + "森", + "枝", + "竹", + "沟", + "催", + "绳", + "忆", + "邦", + "剩", + "幸", + "浆", + "栏", + "拥", + "牙", + "贮", + "礼", + "滤", + "钠", + "纹", + "罢", + "拍", + "咱", + "喊", + "袖", + "埃", + "勤", + "罚", + "焦", + "潜", + "伍", + "墨", + "欲", + "缝", + "姓", + "刊", + "饱", + "仿", + "奖", + "铝", + "鬼", + "丽", + "跨", + "默", + "挖", + "链", + "扫", + "喝", + "袋", + "炭", + "污", + "幕", + "诸", + "弧", + "励", + "梅", + "奶", + "洁", + "灾", + "舟", + "鉴", + "苯", + "讼", + "抱", + "毁", + "懂", + "寒", + "智", + "埔", + "寄", + "届", + "跃", + "渡", + "挑", + "丹", + "艰", + "贝", + "碰", + "拔", + "爹", + "戴", + "码", + "梦", + "芽", + "熔", + "赤", + "渔", + "哭", + "敬", + "颗", + "奔", + "铅", + "仲", + "虎", + "稀", + "妹", + "乏", + "珍", + "申", + "桌", + "遵", + "允", + "隆", + "螺", + "仓", + "魏", + "锐", + "晓", + "氮", + "兼", + "隐", + "碍", + "赫", + "拨", + "忠", + "肃", + "缸", + "牵", + "抢", + "博", + "巧", + "壳", + "兄", + "杜", + "讯", + "诚", + "碧", + "祥", + "柯", + "页", + "巡", + "矩", + "悲", + "灌", + "龄", + "伦", + "票", + "寻", + "桂", + "铺", + "圣", + "恐", + "恰", + "郑", + "趣", + "抬", + "荒", + "腾", + "贴", + "柔", + "滴", + "猛", + "阔", + "辆", + "妻", + "填", + "撤", + "储", + "签", + "闹", + "扰", + "紫", + "砂", + "递", + "戏", + "吊", + "陶", + "伐", + "喂", + "疗", + "瓶", + "婆", + "抚", + "臂", + "摸", + "忍", + "虾", + "蜡", + "邻", + "胸", + "巩", + "挤", + "偶", + "弃", + "槽", + "劲", + "乳", + "邓", + "吉", + "仁", + "烂", + "砖", + "租", + "乌", + "舰", + "伴", + "瓜", + "浅", + "丙", + "暂", + "燥", + "橡", + "柳", + "迷", + "暖", + "牌", + "秧", + "胆", + "详", + "簧", + "踏", + "瓷", + "谱", + "呆", + "宾", + "糊", + "洛", + "辉", + "愤", + "竞", + "隙", + "怒", + "粘", + "乃", + "绪", + "肩", + "籍", + "敏", + "涂", + "熙", + "皆", + "侦", + "悬", + "掘", + "享", + "纠", + "醒", + "狂", + "锁", + "淀", + "恨", + "牲", + "霸", + "爬", + "赏", + "逆", + "玩", + "陵", + "祝", + "秒", + "浙", + "貌" +] \ No newline at end of file diff --git a/coins/monero/src/wallet/seed/mod.rs b/coins/monero/src/wallet/seed/mod.rs new file mode 100644 index 00000000..e34852eb --- /dev/null +++ b/coins/monero/src/wallet/seed/mod.rs @@ -0,0 +1,92 @@ +use core::fmt; + +use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; +use rand_core::{RngCore, CryptoRng}; + +use thiserror::Error; + +pub(crate) mod classic; +use classic::{CLASSIC_SEED_LENGTH, CLASSIC_SEED_LENGTH_WITH_CHECKSUM, ClassicSeed}; + +/// Error when decoding a seed. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)] +pub enum SeedError { + #[error("invalid number of words in seed")] + InvalidSeedLength, + #[error("unknown language")] + UnknownLanguage, + #[error("invalid checksum")] + InvalidChecksum, + #[error("english old seeds don't support checksums")] + EnglishOldWithChecksum, + #[error("invalid seed")] + InvalidSeed, +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub enum Language { + Chinese, + English, + Dutch, + French, + Spanish, + German, + Italian, + Portuguese, + Japanese, + Russian, + Esperanto, + Lojban, + EnglishOld, +} + +/// A Monero seed. +// TODO: Add polyseed to enum +#[derive(Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)] +pub enum Seed { + Classic(ClassicSeed), +} + +impl fmt::Debug for Seed { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Seed::Classic(_) => f.debug_struct("Seed::Classic").finish_non_exhaustive(), + } + } +} + +impl Seed { + /// Create a new seed. + pub fn new(rng: &mut R, lang: Language) -> Seed { + Seed::Classic(ClassicSeed::new(rng, lang)) + } + + /// Parse a seed from a String. + pub fn from_string(words: Zeroizing) -> Result { + match words.split_whitespace().count() { + CLASSIC_SEED_LENGTH | CLASSIC_SEED_LENGTH_WITH_CHECKSUM => { + ClassicSeed::from_string(words).map(Seed::Classic) + } + _ => Err(SeedError::InvalidSeedLength)?, + } + } + + /// Create a Seed from entropy. + pub fn from_entropy(lang: Language, entropy: Zeroizing<[u8; 32]>) -> Option { + ClassicSeed::from_entropy(lang, entropy).map(Seed::Classic) + } + + /// Convert a seed to a String. + pub fn to_string(&self) -> Zeroizing { + match self { + Seed::Classic(seed) => seed.to_string(), + } + } + + /// Return the entropy for this seed. + pub fn entropy(&self) -> Zeroizing<[u8; 32]> { + match self { + Seed::Classic(seed) => seed.entropy(), + } + } +} From 4335baa43f908d0aee849c5f6ceb7b6cf2ccadd7 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 11 Mar 2023 04:49:05 -0500 Subject: [PATCH 64/74] cargo update --- Cargo.lock | 335 +++++++++++++++++++++++------------------------------ 1 file changed, 145 insertions(+), 190 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e088349..10d23ffe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,7 +95,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ "cfg-if", - "cipher 0.4.3", + "cipher 0.4.4", "cpufeatures", ] @@ -121,7 +121,7 @@ checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" dependencies = [ "aead 0.5.1", "aes 0.8.2", - "cipher 0.4.3", + "cipher 0.4.4", "ctr 0.9.2", "ghash 0.5.0", "subtle", @@ -269,9 +269,9 @@ dependencies = [ [[package]] name = "asn1-rs" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf6690c370453db30743b373a60ba498fc0d6d83b11f4abfd87a84a075db5dd4" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ "asn1-rs-derive 0.4.0", "asn1-rs-impl", @@ -405,6 +405,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "auto_impl" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7862e21c893d65a1650125d157eaeec691439379a1cee17ee49031b79236ada4" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "auto_impl" version = "1.0.1" @@ -706,9 +718,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array 0.14.6", ] @@ -837,9 +849,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6031a462f977dd38968b6f23378356512feeace69cef817e1a4475108093cec3" +checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" dependencies = [ "serde", ] @@ -936,7 +948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08" dependencies = [ "cfg-if", - "cipher 0.4.3", + "cipher 0.4.4", "cpufeatures", ] @@ -1002,9 +1014,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", @@ -1305,18 +1317,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b18cf92869a6ae85cde3af4bc4beb6154efa8adef03b18db2ad413d5bce3a2" +checksum = "a7379abaacee0f14abf3204a7606118f0465785252169d186337bcb75030815a" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567d9f6e919bac076f39b902a072686eaf9e6d015baa34d10a61b85105b7af59" +checksum = "9489fa336927df749631f1008007ced2871068544f40a202ce6d93fbf2366a7b" dependencies = [ "arrayvec 0.7.2", "bumpalo", @@ -1335,33 +1347,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e72b2d5ec8917b2971fe83850187373d0a186db4748a7c23a5f48691b8d92bb" +checksum = "05bbb67da91ec721ed57cef2f7c5ef7728e1cd9bde9ffd3ef8601022e73e3239" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3461c0e0c2ebbeb92533aacb27e219289f60dc84134ef34fbf2d77c9eddf07ef" +checksum = "418ecb2f36032f6665dc1a5e2060a143dbab41d83b784882e97710e890a7a16d" [[package]] name = "cranelift-entity" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af684f7f7b01427b1942c7102673322a51b9d6f261e9663dc5e5595786775531" +checksum = "7cf583f7b093f291005f9fb1323e2c37f6ee4c7909e39ce016b2e8360d461705" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d361ed0373cf5f086b49c499aa72227b646a64f899f32e34312f97c0fadff75" +checksum = "0b66bf9e916f57fbbd0f7703ec6286f4624866bf45000111627c70d272c8dda1" dependencies = [ "cranelift-codegen", "log", @@ -1371,15 +1383,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef4f8f3984d772c199a48896d2fb766f96301bf71b371e03a2b99f4f3b7b931" +checksum = "649782a39ce99798dd6b4029e2bb318a2fbeaade1b4fa25330763c10c65bc358" [[package]] name = "cranelift-native" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98e4e99a353703475d5acb402b9c13482d41d8a4008b352559bd560afb90363" +checksum = "937e021e089c51f9749d09e7ad1c4f255c2f8686cb8c3df63a34b3ec9921bc41" dependencies = [ "cranelift-codegen", "libc", @@ -1388,9 +1400,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e3f4f0779a1b0f286a6ef19835d8665f88326e656a6d7d84fa9a39fa38ca32" +checksum = "d850cf6775477747c9dfda9ae23355dd70512ffebc70cf82b85a5b111ae668b5" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1533,7 +1545,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.4.3", + "cipher 0.4.4", ] [[package]] @@ -1638,9 +1650,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" dependencies = [ "darling_core", "darling_macro", @@ -1648,9 +1660,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", @@ -1662,9 +1674,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core", "quote", @@ -1724,11 +1736,11 @@ dependencies = [ [[package]] name = "der-parser" -version = "8.1.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d4bc9b0db0a0df9ae64634ac5bdefb7afcb534e182275ca0beadbe486701c1" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ - "asn1-rs 0.5.1", + "asn1-rs 0.5.2", "displaydoc", "nom", "num-bigint", @@ -1848,7 +1860,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", "subtle", ] @@ -2116,25 +2128,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "enr" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "492a7e5fc2504d5fdce8e124d3e263b244a68b283cac67a69eda0cd43e0aebad" -dependencies = [ - "base64 0.13.1", - "bs58", - "bytes", - "hex", - "k256", - "log", - "rand 0.8.5", - "rlp", - "serde", - "sha3", - "zeroize", -] - [[package]] name = "enum-as-inner" version = "0.5.1" @@ -2293,9 +2286,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6fef0375eef9f126f5c9fa41a4d1f8cc109e41160f2757f74e1d0b485fd069b" +checksum = "fe4be54dd2260945d784e06ccdeb5ad573e8f1541838cee13a1ab885485eaa0b" dependencies = [ "ethers-core", "once_cell", @@ -2305,9 +2298,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fc3d7048cfc56615edf05cdfb38a38c8bc6108e2f51a0f2959a9397bd271b3c" +checksum = "e9c3c3e119a89f0a9a1e539e7faecea815f74ddcf7c90d0b00d1f524db2fdc9c" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", @@ -2324,19 +2317,17 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "651115f37eb5a2c91289c184174f67bb9053c052b2189e3f162044e84ac5e505" +checksum = "3d4e5ad46aede34901f71afdb7bb555710ed9613d88d644245c657dc371aa228" dependencies = [ "Inflector", "cfg-if", "dunce", "ethers-core", - "ethers-etherscan", "eyre", "getrandom 0.2.8", "hex", - "prettyplease", "proc-macro2", "quote", "regex", @@ -2344,7 +2335,6 @@ dependencies = [ "serde", "serde_json", "syn", - "tokio", "toml", "url", "walkdir", @@ -2352,13 +2342,12 @@ dependencies = [ [[package]] name = "ethers-contract-derive" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b3385c9daa450bbcef5da438ed99e9361019f1242f7c3f635f132ecc961cd3" +checksum = "f192e8e4cf2b038318aae01e94e7644e0659a76219e94bcd3203df744341d61f" dependencies = [ "ethers-contract-abigen", "ethers-core", - "eyre", "hex", "proc-macro2", "quote", @@ -2368,9 +2357,9 @@ dependencies = [ [[package]] name = "ethers-core" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94573efbaddb420037ffc2be6540d86ec17efd715ae8c1b4792ac6d6865b157f" +checksum = "ade3e9c97727343984e1ceada4fdab11142d2ee3472d2c67027d56b1251d4f15" dependencies = [ "arrayvec 0.7.2", "bytes", @@ -2380,10 +2369,8 @@ dependencies = [ "elliptic-curve", "ethabi", "generic-array 0.14.6", - "getrandom 0.2.8", "hex", "k256", - "num_enum", "once_cell", "open-fastrlp", "proc-macro2", @@ -2394,7 +2381,6 @@ dependencies = [ "serde_json", "strum", "syn", - "tempfile", "thiserror", "tiny-keccak", "unicode-xid", @@ -2402,9 +2388,9 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb663dde0a44aba855cc9b7d3ec17ea9ffb3659914933a170a46954896edb339" +checksum = "a9713f525348e5dde025d09b0a4217429f8074e8ff22c886263cc191e87d8216" dependencies = [ "ethers-core", "getrandom 0.2.8", @@ -2419,12 +2405,12 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2b2e125feb05c17909919c30385b012ce33330c1522426c116929063b9f924" +checksum = "e71df7391b0a9a51208ffb5c7f2d068900e99d6b3128d3a4849d138f194778b7" dependencies = [ "async-trait", - "auto_impl", + "auto_impl 0.5.0", "ethers-contract", "ethers-core", "ethers-etherscan", @@ -2445,14 +2431,13 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c96fbae569931aa0fab963a010d4c98d2757028ec840809b98032d9543d18" +checksum = "a1a9e0597aa6b2fdc810ff58bc95e4eeaa2c219b3e615ed025106ecb027407d8" dependencies = [ "async-trait", - "auto_impl", - "base64 0.21.0", - "enr", + "auto_impl 1.0.1", + "base64 0.13.1", "ethers-core", "futures-core", "futures-timer", @@ -2481,9 +2466,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52b8308a63f1c00ecf001a75c9b192499d87324c310c6fd9e772d20bdfbf366b" +checksum = "3f41ced186867f64773db2e55ffdd92959e094072a1d09a5e5e831d443204f98" dependencies = [ "async-trait", "coins-bip32", @@ -2495,14 +2480,13 @@ dependencies = [ "rand 0.8.5", "sha2 0.10.6", "thiserror", - "tracing", ] [[package]] name = "ethers-solc" -version = "1.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9482f0e65b8e09e3d3e86a1ea5e558a8b5e7da3597a97fc588ff4a0bdaf0e148" +checksum = "cbe9c0a6d296c57191e5f8a613a3b5e816812c28f4a28d6178a17c21db903d77" dependencies = [ "cfg-if", "dunce", @@ -2607,9 +2591,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b2f3c51e4dd999930845da5d10a48775b8fe4ca9f4f9ec1f9161f334da5dfe" +checksum = "93ace6ec7cc19c8ed33a32eaa9ea692d7faea05006b5356b9e2b668ec4bc3955" [[package]] name = "file-per-thread-logger" @@ -3468,9 +3452,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.24" +version = "0.14.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c" +checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" dependencies = [ "bytes", "futures-channel", @@ -3758,9 +3742,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3" dependencies = [ "libc", "windows-sys 0.45.0", @@ -4083,9 +4067,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "libloading" @@ -5191,9 +5175,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6515c882ebfddccaa73ead7320ca28036c4bc84c9bcca3cc0cbba8efe89223a" +checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511" dependencies = [ "approx", "matrixmultiply", @@ -5435,27 +5419,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "number_prefix" version = "0.4.0" @@ -5498,7 +5461,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ - "asn1-rs 0.5.1", + "asn1-rs 0.5.2", ] [[package]] @@ -5526,7 +5489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" dependencies = [ "arrayvec 0.7.2", - "auto_impl", + "auto_impl 1.0.1", "bytes", "ethereum-types", "open-fastrlp-derive", @@ -6006,32 +5969,34 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ "phf_macros", - "phf_shared 0.11.1", + "phf_shared", + "proc-macro-hack", ] [[package]] name = "phf_generator" -version = "0.11.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "phf_shared 0.11.1", + "phf_shared", "rand 0.8.5", ] [[package]] name = "phf_macros" -version = "0.11.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" dependencies = [ "phf_generator", - "phf_shared 0.11.1", + "phf_shared", + "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -6046,15 +6011,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "phf_shared" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" -dependencies = [ - "siphasher", -] - [[package]] name = "pico-args" version = "0.4.2" @@ -6129,16 +6085,18 @@ checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" [[package]] name = "polling" -version = "2.5.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" +checksum = "7e1f879b2998099c2d69ab9605d145d5b661195627eccc680002c4918a7fb6fa" dependencies = [ "autocfg", + "bitflags", "cfg-if", + "concurrent-queue", "libc", "log", - "wepoll-ffi", - "windows-sys 0.42.0", + "pin-project-lite 0.2.9", + "windows-sys 0.45.0", ] [[package]] @@ -6276,6 +6234,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.51" @@ -7001,7 +6965,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" dependencies = [ - "cipher 0.4.3", + "cipher 0.4.4", ] [[package]] @@ -8294,9 +8258,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.152" +version = "1.0.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "8cdd151213925e7f1ab45a9bbfb129316bd00799784b174b7cc7bcd16961c49e" dependencies = [ "serde_derive", ] @@ -8322,9 +8286,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217" dependencies = [ "proc-macro2", "quote", @@ -8550,9 +8514,9 @@ dependencies = [ [[package]] name = "solang-parser" -version = "0.2.2" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58feb14d4002859db0b744b0915840bae403b8a5675efded3e8adddb6beb85b2" +checksum = "ac8ac4bfef383f368bd9bb045107a501cd9cd0b64ad1983e1b7e839d6a44ecad" dependencies = [ "itertools", "lalrpop", @@ -9219,14 +9183,14 @@ dependencies = [ [[package]] name = "string_cache" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d69e88b23f23030bf4d0e9ca7b07434f70e1c1f4d3ca7e93ce958b373654d9f" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot 0.12.1", - "phf_shared 0.10.0", + "phf_shared", "precomputed-hash", ] @@ -10125,9 +10089,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" +checksum = "524b68aca1d05e03fdf03fcdce2c6c94b6daf6d16861ddaa7e4f2b6638a9052c" [[package]] name = "unicode-ident" @@ -10506,9 +10470,9 @@ dependencies = [ [[package]] name = "wasmtime" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9010891d0b8e367c3be94ca35d7bc25c1de3240463bb1d61bcfc8c2233c4e0d0" +checksum = "f6e89f9819523447330ffd70367ef4a18d8c832e24e8150fe054d1d912841632" dependencies = [ "anyhow", "bincode", @@ -10534,18 +10498,18 @@ dependencies = [ [[package]] name = "wasmtime-asm-macros" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65805c663eaa8257b910666f6d4b056b5c7329750da754ba5df54f3af7dbf35c" +checksum = "9bd3a5e46c198032da934469f3a6e48649d1f9142438e4fd4617b68a35644b8a" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-cache" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2049ddfc1b10efc3c5591d0e84b9570ca50478f8818f3bfabb1a467918f53fb4" +checksum = "b389ae9b678b9c3851091a4804f4182d688d27aff7abc9aa37fa7be37d8ecffa" dependencies = [ "anyhow", "base64 0.13.1", @@ -10563,9 +10527,9 @@ dependencies = [ [[package]] name = "wasmtime-cranelift" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9065cad6a724fa838ec8497567e0b23acc26417bb2449f8d9d2021925c72f2" +checksum = "59b2c92a08c0db6efffd88fdc97d7aa9c7c63b03edb0971dbca745469f820e8c" dependencies = [ "anyhow", "cranelift-codegen", @@ -10584,9 +10548,9 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f964bb0b91fa021b8d1b488c62cc77b346c1dae6e3ebd010050b57c1f2ca657" +checksum = "9a6db9fc52985ba06ca601f2ff0ff1f526c5d724c7ac267b47326304b0c97883" dependencies = [ "anyhow", "cranelift-entity", @@ -10603,9 +10567,9 @@ dependencies = [ [[package]] name = "wasmtime-jit" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a1d06f5d109539e0168fc74fa65e3948ac8dac3bb8cdbd08b62b36a0ae27b8" +checksum = "b77e3a52cd84d0f7f18554afa8060cfe564ccac61e3b0802d3fd4084772fa5f6" dependencies = [ "addr2line 0.17.0", "anyhow", @@ -10627,9 +10591,9 @@ dependencies = [ [[package]] name = "wasmtime-jit-debug" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f76ef2e410329aaf8555ac6571d6fe07711be0646dcdf7ff3ab750a42ed2e583" +checksum = "d0245e8a9347017c7185a72e215218a802ff561545c242953c11ba00fccc930f" dependencies = [ "object 0.29.0", "once_cell", @@ -10638,9 +10602,9 @@ dependencies = [ [[package]] name = "wasmtime-jit-icache-coherence" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1fd0f0dd79e7cc0f55b102e320d7c77ab76cd272008a8fd98e25b5777e2636" +checksum = "67d412e9340ab1c83867051d8d1d7c90aa8c9afc91da086088068e2734e25064" dependencies = [ "cfg-if", "libc", @@ -10649,9 +10613,9 @@ dependencies = [ [[package]] name = "wasmtime-runtime" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271aef9b4ca2e953a866293683f2db33cda46f6933c5e431e68d8373723d4ab6" +checksum = "d594e791b5fdd4dbaf8cf7ae62f2e4ff85018ce90f483ca6f42947688e48827d" dependencies = [ "anyhow", "cc", @@ -10673,9 +10637,9 @@ dependencies = [ [[package]] name = "wasmtime-types" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18144b0e45479a830ac9fcebfc71a16d90dc72d8ebd5679700eb3bfe974d7df" +checksum = "a6688d6f96d4dbc1f89fab626c56c1778936d122b5f4ae7a57c2eb42b8d982e2" dependencies = [ "cranelift-entity", "serde", @@ -10792,7 +10756,7 @@ dependencies = [ "byteorder", "ccm", "curve25519-dalek 3.2.0", - "der-parser 8.1.0", + "der-parser 8.2.0", "elliptic-curve", "hkdf", "hmac 0.12.1", @@ -10934,15 +10898,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "wepoll-ffi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] - [[package]] name = "which" version = "4.4.0" @@ -11209,10 +11164,10 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" dependencies = [ - "asn1-rs 0.5.1", + "asn1-rs 0.5.2", "base64 0.13.1", "data-encoding", - "der-parser 8.1.0", + "der-parser 8.2.0", "lazy_static", "nom", "oid-registry 0.6.1", From 71dbc798b504d7ec7ae809c02a857c7ea30277e5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 11 Mar 2023 05:23:38 -0500 Subject: [PATCH 65/74] Fix #251 --- coins/monero/src/wallet/send/mod.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index bf169299..3090af8a 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -308,13 +308,13 @@ impl SignableTransaction { // Include a random payment ID if we don't actually have one // It prevents transactions from leaking if they're sending to integrated addresses or not - let id = if let Some(id) = id { - id - } else { - let mut id = [0; 8]; - rng.fill_bytes(&mut id); - id - }; + // Only do this if we only have two outputs though, as Monero won't add a dummy if there's + // more than two outputs + if outputs.len() <= 2 { + let mut rand = [0; 8]; + rng.fill_bytes(&mut rand); + id = id.or(Some(rand)); + } let commitments = outputs.iter().map(|output| output.commitment.clone()).collect::>(); let sum = commitments.iter().map(|commitment| commitment.mask).sum(); @@ -329,9 +329,11 @@ impl SignableTransaction { if additional { outputs.iter().map(|output| output.R).collect() } else { vec![] }, ); - let mut id_vec = Vec::with_capacity(1 + 8); - PaymentId::Encrypted(id).write(&mut id_vec).unwrap(); - extra.push(ExtraField::Nonce(id_vec)); + if let Some(id) = id { + let mut id_vec = Vec::with_capacity(1 + 8); + PaymentId::Encrypted(id).write(&mut id_vec).unwrap(); + extra.push(ExtraField::Nonce(id_vec)); + } // Include data if present for part in self.data.drain(..) { From e56495d624d445177e32540aefc9302fb0e602b5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 11 Mar 2023 05:47:25 -0500 Subject: [PATCH 66/74] Prefix arbitrary data with 127 Since we cannot expect/guarantee a payment ID will be included, the previous position-based code for determining arbitrary data wasn't sufficient. --- coins/monero/src/wallet/extra.rs | 24 ++++++++++++--------- coins/monero/src/wallet/send/builder.rs | 4 ++-- coins/monero/src/wallet/send/mod.rs | 24 ++++++++++++++------- coins/monero/tests/add_data.rs | 13 +++++------ coins/monero/tests/wallet2_compatibility.rs | 5 +++-- 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/coins/monero/src/wallet/extra.rs b/coins/monero/src/wallet/extra.rs index 867c5189..b8b5f3c1 100644 --- a/coins/monero/src/wallet/extra.rs +++ b/coins/monero/src/wallet/extra.rs @@ -12,6 +12,14 @@ use crate::serialize::{ pub const MAX_TX_EXTRA_NONCE_SIZE: usize = 255; +pub const PAYMENT_ID_MARKER: u8 = 0; +pub const ENCRYPTED_PAYMENT_ID_MARKER: u8 = 1; +// Used as it's the highest value not interpretable as a continued VarInt +pub const ARBITRARY_DATA_MARKER: u8 = 127; + +// 1 byte is used for the marker +pub const MAX_ARBITRARY_DATA_SIZE: usize = MAX_TX_EXTRA_NONCE_SIZE - 1; + #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] pub(crate) enum PaymentId { Unencrypted([u8; 32]), @@ -35,11 +43,11 @@ impl PaymentId { pub(crate) fn write(&self, w: &mut W) -> io::Result<()> { match self { PaymentId::Unencrypted(id) => { - w.write_all(&[0])?; + w.write_all(&[PAYMENT_ID_MARKER])?; w.write_all(id)?; } PaymentId::Encrypted(id) => { - w.write_all(&[1])?; + w.write_all(&[ENCRYPTED_PAYMENT_ID_MARKER])?; w.write_all(id)?; } } @@ -138,16 +146,12 @@ impl Extra { } pub(crate) fn data(&self) -> Vec> { - let mut first = true; let mut res = vec![]; for field in &self.0 { if let ExtraField::Nonce(data) = field { - // Skip the first Nonce, which should be the payment ID - if first { - first = false; - continue; + if data[0] == ARBITRARY_DATA_MARKER { + res.push(data[1 ..].to_vec()); } - res.push(data.clone()); } } res @@ -167,13 +171,13 @@ impl Extra { } #[rustfmt::skip] - pub(crate) fn fee_weight(outputs: usize, data: &[Vec]) -> usize { + pub(crate) fn fee_weight(outputs: usize, payment_id: bool, data: &[Vec]) -> usize { // PublicKey, key (1 + 32) + // PublicKeys, length, additional keys (1 + 1 + (outputs.saturating_sub(1) * 32)) + // PaymentId (Nonce), length, encrypted, ID - (1 + 1 + 1 + 8) + + (if payment_id { 1 + 1 + 1 + 8 } else { 0 }) + // Nonce, length, data (if existent) data.iter().map(|v| 1 + varint_len(v.len()) + v.len()).sum::() } diff --git a/coins/monero/src/wallet/send/builder.rs b/coins/monero/src/wallet/send/builder.rs index b137dcbf..ef70900a 100644 --- a/coins/monero/src/wallet/send/builder.rs +++ b/coins/monero/src/wallet/send/builder.rs @@ -6,7 +6,7 @@ use crate::{ Protocol, wallet::{ address::MoneroAddress, Fee, SpendableOutput, SignableTransaction, TransactionError, - extra::MAX_TX_EXTRA_NONCE_SIZE, + extra::MAX_ARBITRARY_DATA_SIZE, }, }; @@ -104,7 +104,7 @@ impl SignableTransactionBuilder { } pub fn add_data(&mut self, data: Vec) -> Result { - if data.len() > MAX_TX_EXTRA_NONCE_SIZE { + if data.len() > MAX_ARBITRARY_DATA_SIZE { Err(TransactionError::TooMuchData)?; } self.0.write().unwrap().add_data(data); diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index 3090af8a..aac69ee9 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -25,8 +25,10 @@ use crate::{ transaction::{Input, Output, Timelock, TransactionPrefix, Transaction}, rpc::{Rpc, RpcError}, wallet::{ - address::MoneroAddress, SpendableOutput, Decoys, PaymentId, ExtraField, Extra, key_image_sort, - uniqueness, shared_key, commitment_mask, amount_encryption, extra::MAX_TX_EXTRA_NONCE_SIZE, + address::MoneroAddress, + SpendableOutput, Decoys, PaymentId, ExtraField, Extra, key_image_sort, uniqueness, shared_key, + commitment_mask, amount_encryption, + extra::{ARBITRARY_DATA_MARKER, MAX_ARBITRARY_DATA_SIZE}, }, }; @@ -196,7 +198,7 @@ impl SignableTransaction { fee_rate: Fee, ) -> Result { // Make sure there's only one payment ID - { + let mut has_payment_id = { let mut payment_ids = 0; let mut count = |addr: MoneroAddress| { if addr.payment_id().is_some() { @@ -212,7 +214,8 @@ impl SignableTransaction { if payment_ids > 1 { Err(TransactionError::MultiplePaymentIds)?; } - } + payment_ids == 1 + }; if inputs.is_empty() { Err(TransactionError::NoInputs)?; @@ -222,7 +225,7 @@ impl SignableTransaction { } for part in &data { - if part.len() > MAX_TX_EXTRA_NONCE_SIZE { + if part.len() > MAX_ARBITRARY_DATA_SIZE { Err(TransactionError::TooMuchData)?; } } @@ -235,9 +238,11 @@ impl SignableTransaction { Err(TransactionError::NoChange)?; } let outputs = payments.len() + usize::from(change); + // Add a dummy payment ID if there's only 2 payments + has_payment_id |= outputs == 2; // Calculate the extra length - let extra = Extra::fee_weight(outputs, data.as_ref()); + let extra = Extra::fee_weight(outputs, has_payment_id, data.as_ref()); // Calculate the fee. let mut fee = @@ -337,10 +342,13 @@ impl SignableTransaction { // Include data if present for part in self.data.drain(..) { - extra.push(ExtraField::Nonce(part)); + let mut arb = vec![ARBITRARY_DATA_MARKER]; + arb.extend(part); + extra.push(ExtraField::Nonce(arb)); } - let mut serialized = Vec::with_capacity(Extra::fee_weight(outputs.len(), self.data.as_ref())); + let mut serialized = + Vec::with_capacity(Extra::fee_weight(outputs.len(), id.is_some(), self.data.as_ref())); extra.write(&mut serialized).unwrap(); serialized }; diff --git a/coins/monero/tests/add_data.rs b/coins/monero/tests/add_data.rs index 918a51af..edb550ab 100644 --- a/coins/monero/tests/add_data.rs +++ b/coins/monero/tests/add_data.rs @@ -1,5 +1,5 @@ use monero_serai::{ - wallet::{TransactionError, extra::MAX_TX_EXTRA_NONCE_SIZE}, + wallet::{TransactionError, extra::MAX_ARBITRARY_DATA_SIZE}, transaction::Transaction, }; @@ -9,7 +9,7 @@ test!( add_single_data_less_than_max, ( |_, mut builder: Builder, addr| async move { - let arbitrary_data = vec![b'\0', (MAX_TX_EXTRA_NONCE_SIZE as u8) - 1]; + let arbitrary_data = vec![b'\0'; MAX_ARBITRARY_DATA_SIZE - 1]; // make sure we can add to tx let result = builder.add_data(arbitrary_data.clone()); @@ -30,7 +30,7 @@ test!( add_multiple_data_less_than_max, ( |_, mut builder: Builder, addr| async move { - let data = vec![b'\0', (MAX_TX_EXTRA_NONCE_SIZE as u8) - 1]; + let data = vec![b'\0'; MAX_ARBITRARY_DATA_SIZE - 1]; // Add tx multiple times for _ in 0 .. 5 { @@ -53,13 +53,14 @@ test!( add_single_data_more_than_max, ( |_, mut builder: Builder, addr| async move { - // Make a data that is bigger than 255 bytes - let mut data = vec![b'a'; MAX_TX_EXTRA_NONCE_SIZE + 1]; + // Make a data that is bigger than the maximum + let mut data = vec![b'a'; MAX_ARBITRARY_DATA_SIZE + 1]; // Make sure we get an error if we try to add it to the TX assert_eq!(builder.add_data(data.clone()), Err(TransactionError::TooMuchData)); - // Reduce data size and retry. The data will now be 255 bytes long, exactly + // Reduce data size and retry. The data will now be 255 bytes long (including the added + // marker), exactly data.pop(); assert!(builder.add_data(data.clone()).is_ok()); diff --git a/coins/monero/tests/wallet2_compatibility.rs b/coins/monero/tests/wallet2_compatibility.rs index 4e6586aa..1b028435 100644 --- a/coins/monero/tests/wallet2_compatibility.rs +++ b/coins/monero/tests/wallet2_compatibility.rs @@ -217,9 +217,10 @@ test!( 1000000, ); - // Make 2 data that is full 255 bytes + // Make 2 data that is the full 255 bytes for _ in 0 .. 2 { - let data = vec![b'a'; MAX_TX_EXTRA_NONCE_SIZE]; + // Subtract 1 since we prefix data with 127 + let data = vec![b'a'; MAX_TX_EXTRA_NONCE_SIZE - 1]; assert!(builder.add_data(data).is_ok()); } From 5e62072a0f06fdc8790f9f3cb7690c5f249c02f8 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 11 Mar 2023 10:31:58 -0500 Subject: [PATCH 67/74] Fix #237 --- coins/monero/src/wallet/extra.rs | 31 ++- coins/monero/src/wallet/mod.rs | 4 +- coins/monero/src/wallet/send/builder.rs | 10 +- coins/monero/src/wallet/send/mod.rs | 255 +++++++++++++++----- coins/monero/src/wallet/send/multisig.rs | 21 +- coins/monero/tests/runner.rs | 10 +- coins/monero/tests/send.rs | 69 +++++- coins/monero/tests/wallet2_compatibility.rs | 35 +-- processor/src/coin/monero.rs | 7 +- 9 files changed, 342 insertions(+), 100 deletions(-) diff --git a/coins/monero/src/wallet/extra.rs b/coins/monero/src/wallet/extra.rs index b8b5f3c1..1b902109 100644 --- a/coins/monero/src/wallet/extra.rs +++ b/coins/monero/src/wallet/extra.rs @@ -21,7 +21,7 @@ pub const ARBITRARY_DATA_MARKER: u8 = 127; pub const MAX_ARBITRARY_DATA_SIZE: usize = MAX_TX_EXTRA_NONCE_SIZE - 1; #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] -pub(crate) enum PaymentId { +pub enum PaymentId { Unencrypted([u8; 32]), Encrypted([u8; 8]), } @@ -31,6 +31,7 @@ impl BitXor<[u8; 8]> for PaymentId { fn bitxor(self, bytes: [u8; 8]) -> PaymentId { match self { + // Don't perform the xor since this isn't intended to be encrypted with xor PaymentId::Unencrypted(_) => self, PaymentId::Encrypted(id) => { PaymentId::Encrypted((u64::from_le_bytes(id) ^ u64::from_le_bytes(bytes)).to_le_bytes()) @@ -40,7 +41,7 @@ impl BitXor<[u8; 8]> for PaymentId { } impl PaymentId { - pub(crate) fn write(&self, w: &mut W) -> io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { match self { PaymentId::Unencrypted(id) => { w.write_all(&[PAYMENT_ID_MARKER])?; @@ -54,7 +55,7 @@ impl PaymentId { Ok(()) } - fn read(r: &mut R) -> io::Result { + pub fn read(r: &mut R) -> io::Result { Ok(match read_byte(r)? { 0 => PaymentId::Unencrypted(read_bytes(r)?), 1 => PaymentId::Encrypted(read_bytes(r)?), @@ -65,7 +66,7 @@ impl PaymentId { // Doesn't bother with padding nor MinerGate #[derive(Clone, PartialEq, Eq, Debug, Zeroize)] -pub(crate) enum ExtraField { +pub enum ExtraField { PublicKey(EdwardsPoint), Nonce(Vec), MergeMining(usize, [u8; 32]), @@ -73,7 +74,7 @@ pub(crate) enum ExtraField { } impl ExtraField { - fn write(&self, w: &mut W) -> io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { match self { ExtraField::PublicKey(key) => { w.write_all(&[1])?; @@ -96,7 +97,7 @@ impl ExtraField { Ok(()) } - fn read(r: &mut R) -> io::Result { + pub fn read(r: &mut R) -> io::Result { Ok(match read_byte(r)? { 1 => ExtraField::PublicKey(read_point(r)?), 2 => ExtraField::Nonce({ @@ -118,9 +119,9 @@ impl ExtraField { } #[derive(Clone, PartialEq, Eq, Debug, Zeroize)] -pub(crate) struct Extra(Vec); +pub struct Extra(Vec); impl Extra { - pub(crate) fn keys(&self) -> Option<(EdwardsPoint, Option>)> { + pub fn keys(&self) -> Option<(EdwardsPoint, Option>)> { let mut key = None; let mut additional = None; for field in &self.0 { @@ -136,7 +137,7 @@ impl Extra { key.map(|key| (key, additional)) } - pub(crate) fn payment_id(&self) -> Option { + pub fn payment_id(&self) -> Option { for field in &self.0 { if let ExtraField::Nonce(data) = field { return PaymentId::read::<&[u8]>(&mut data.as_ref()).ok(); @@ -145,7 +146,7 @@ impl Extra { None } - pub(crate) fn data(&self) -> Vec> { + pub fn data(&self) -> Vec> { let mut res = vec![]; for field in &self.0 { if let ExtraField::Nonce(data) = field { @@ -182,14 +183,20 @@ impl Extra { data.iter().map(|v| 1 + varint_len(v.len()) + v.len()).sum::() } - pub(crate) fn write(&self, w: &mut W) -> io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { for field in &self.0 { field.write(w)?; } Ok(()) } - pub(crate) fn read(r: &mut R) -> io::Result { + pub fn serialize(&self) -> Vec { + let mut buf = vec![]; + self.write(&mut buf).unwrap(); + buf + } + + pub fn read(r: &mut R) -> io::Result { let mut res = Extra(vec![]); let mut field; while { diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index f0fd398e..1f23406b 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -28,7 +28,9 @@ pub(crate) mod decoys; pub(crate) use decoys::Decoys; mod send; -pub use send::{Fee, TransactionError, SignableTransaction, SignableTransactionBuilder}; +pub use send::{Fee, TransactionError, Change, SignableTransaction, SignableTransactionBuilder}; +#[cfg(feature = "multisig")] +pub(crate) use send::InternalPayment; #[cfg(feature = "multisig")] pub use send::TransactionMachine; diff --git a/coins/monero/src/wallet/send/builder.rs b/coins/monero/src/wallet/send/builder.rs index ef70900a..d1e632cf 100644 --- a/coins/monero/src/wallet/send/builder.rs +++ b/coins/monero/src/wallet/send/builder.rs @@ -5,7 +5,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; use crate::{ Protocol, wallet::{ - address::MoneroAddress, Fee, SpendableOutput, SignableTransaction, TransactionError, + address::MoneroAddress, Fee, SpendableOutput, Change, SignableTransaction, TransactionError, extra::MAX_ARBITRARY_DATA_SIZE, }, }; @@ -17,14 +17,14 @@ struct SignableTransactionBuilderInternal { inputs: Vec, payments: Vec<(MoneroAddress, u64)>, - change_address: Option, + change_address: Option, data: Vec>, } impl SignableTransactionBuilderInternal { // Takes in the change address so users don't miss that they have to manually set one // If they don't, all leftover funds will become part of the fee - fn new(protocol: Protocol, fee: Fee, change_address: Option) -> Self { + fn new(protocol: Protocol, fee: Fee, change_address: Option) -> Self { Self { protocol, fee, inputs: vec![], payments: vec![], change_address, data: vec![] } } @@ -77,7 +77,7 @@ impl SignableTransactionBuilder { Self(self.0.clone()) } - pub fn new(protocol: Protocol, fee: Fee, change_address: Option) -> Self { + pub fn new(protocol: Protocol, fee: Fee, change_address: Option) -> Self { Self(Arc::new(RwLock::new(SignableTransactionBuilderInternal::new( protocol, fee, @@ -117,7 +117,7 @@ impl SignableTransactionBuilder { read.protocol, read.inputs.clone(), read.payments.clone(), - read.change_address, + read.change_address.clone(), read.data.clone(), read.fee, ) diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index aac69ee9..f8eec1e6 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -1,4 +1,4 @@ -use core::ops::Deref; +use core::{ops::Deref, fmt}; use thiserror::Error; @@ -8,7 +8,11 @@ use rand::seq::SliceRandom; use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; use group::Group; -use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint}; +use curve25519_dalek::{ + constants::{ED25519_BASEPOINT_POINT, ED25519_BASEPOINT_TABLE}, + scalar::Scalar, + edwards::EdwardsPoint, +}; use dalek_ff_group as dfg; #[cfg(feature = "multisig")] @@ -25,9 +29,9 @@ use crate::{ transaction::{Input, Output, Timelock, TransactionPrefix, Transaction}, rpc::{Rpc, RpcError}, wallet::{ - address::MoneroAddress, - SpendableOutput, Decoys, PaymentId, ExtraField, Extra, key_image_sort, uniqueness, shared_key, - commitment_mask, amount_encryption, + address::{Network, AddressSpec, MoneroAddress}, + ViewPair, SpendableOutput, Decoys, PaymentId, ExtraField, Extra, key_image_sort, uniqueness, + shared_key, commitment_mask, amount_encryption, extra::{ARBITRARY_DATA_MARKER, MAX_ARBITRARY_DATA_SIZE}, }, }; @@ -51,24 +55,23 @@ struct SendOutput { } impl SendOutput { - fn new( - r: &Zeroizing, + #[allow(non_snake_case)] + fn internal( unique: [u8; 32], output: (usize, (MoneroAddress, u64)), + ecdh_left: &Zeroizing, + ecdh_right: &EdwardsPoint, + R: EdwardsPoint, ) -> (SendOutput, Option<[u8; 8]>) { let o = output.0; let output = output.1; let (view_tag, shared_key, payment_id_xor) = - shared_key(Some(unique).filter(|_| output.0.is_guaranteed()), r, &output.0.view, o); + shared_key(Some(unique).filter(|_| output.0.is_guaranteed()), ecdh_left, ecdh_right, o); ( SendOutput { - R: if !output.0.is_subaddress() { - r.deref() * &ED25519_BASEPOINT_TABLE - } else { - r.deref() * output.0.spend - }, + R, view_tag, dest: ((&shared_key * &ED25519_BASEPOINT_TABLE) + output.0.spend), commitment: Commitment::new(commitment_mask(shared_key), output.1), @@ -80,6 +83,39 @@ impl SendOutput { .map(|id| (u64::from_le_bytes(id) ^ u64::from_le_bytes(payment_id_xor)).to_le_bytes()), ) } + + fn new( + r: &Zeroizing, + unique: [u8; 32], + output: (usize, (MoneroAddress, u64)), + ) -> (SendOutput, Option<[u8; 8]>) { + let address = output.1 .0; + SendOutput::internal( + unique, + output, + r, + &address.view, + if !address.is_subaddress() { + r.deref() * &ED25519_BASEPOINT_TABLE + } else { + r.deref() * address.spend + }, + ) + } + + fn change( + ecdh: &EdwardsPoint, + unique: [u8; 32], + output: (usize, (MoneroAddress, u64)), + ) -> (SendOutput, Option<[u8; 8]>) { + SendOutput::internal( + unique, + output, + &Zeroizing::new(Scalar::one()), + ecdh, + ED25519_BASEPOINT_POINT, + ) + } } #[derive(Clone, PartialEq, Eq, Debug, Error)] @@ -179,21 +215,66 @@ impl Fee { pub struct SignableTransaction { protocol: Protocol, inputs: Vec, - payments: Vec<(MoneroAddress, u64)>, + payments: Vec, data: Vec>, fee: u64, } +/// Specification for a change output. +#[derive(Clone, PartialEq, Eq, Zeroize)] +pub struct Change { + address: MoneroAddress, + view: Option>, +} + +impl fmt::Debug for Change { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Change").field("address", &self.address).finish_non_exhaustive() + } +} + +impl Change { + /// Create a change output specification from a ViewPair, as needed to maintain privacy. + pub fn new(view: &ViewPair, guaranteed: bool) -> Change { + Change { + address: view.address( + Network::Mainnet, + if !guaranteed { + AddressSpec::Standard + } else { + AddressSpec::Featured { subaddress: None, payment_id: None, guaranteed: true } + }, + ), + view: Some(view.view.clone()), + } + } + + /// Create a fingerprintable change output specification which will harm privacy. Only use this + /// if you know what you're doing. + pub fn fingerprintable(address: MoneroAddress) -> Change { + Change { address, view: None } + } +} + +#[derive(Clone, PartialEq, Eq, Debug, Zeroize)] +pub(crate) enum InternalPayment { + Payment((MoneroAddress, u64)), + Change(Change, u64), +} + impl SignableTransaction { - /// Create a signable transaction. If the change address is specified, leftover funds will be - /// sent to it. If the change address isn't specified, up to 16 outputs may be specified, using - /// any leftover funds as a bonus to the fee. The optional data field will be embedded in TX - /// extra. + /// Create a signable transaction. + /// + /// Up to 16 outputs may be present, including the change output. + /// + /// If the change address is specified, leftover funds will be sent to it. + /// + /// Each chunk of data must not exceed MAX_ARBITRARY_DATA_SIZE. pub fn new( protocol: Protocol, inputs: Vec, mut payments: Vec<(MoneroAddress, u64)>, - change_address: Option, + change_address: Option, data: Vec>, fee_rate: Fee, ) -> Result { @@ -208,8 +289,8 @@ impl SignableTransaction { for payment in &payments { count(payment.0); } - if let Some(change) = change_address { - count(change); + if let Some(change) = change_address.as_ref() { + count(change.address); } if payment_ids > 1 { Err(TransactionError::MultiplePaymentIds)?; @@ -232,12 +313,11 @@ impl SignableTransaction { // TODO TX MAX SIZE - // If we don't have two outputs, as required by Monero, add a second - let mut change = payments.len() == 1; - if change && change_address.is_none() { + // If we don't have two outputs, as required by Monero, error + if (payments.len() == 1) && change_address.is_none() { Err(TransactionError::NoChange)?; } - let outputs = payments.len() + usize::from(change); + let outputs = payments.len() + usize::from(change_address.is_some()); // Add a dummy payment ID if there's only 2 payments has_payment_id |= outputs == 2; @@ -245,37 +325,24 @@ impl SignableTransaction { let extra = Extra::fee_weight(outputs, has_payment_id, data.as_ref()); // Calculate the fee. - let mut fee = - fee_rate.calculate(Transaction::fee_weight(protocol, inputs.len(), outputs, extra)); + let fee = fee_rate.calculate(Transaction::fee_weight(protocol, inputs.len(), outputs, extra)); // Make sure we have enough funds let in_amount = inputs.iter().map(|input| input.commitment().amount).sum::(); - let mut out_amount = payments.iter().map(|payment| payment.1).sum::() + fee; + let out_amount = payments.iter().map(|payment| payment.1).sum::() + fee; if in_amount < out_amount { Err(TransactionError::NotEnoughFunds(in_amount, out_amount))?; } - // If we have yet to add a change output, do so if it's economically viable - if (!change) && change_address.is_some() && (in_amount != out_amount) { - // Check even with the new fee, there's remaining funds - let change_fee = - fee_rate.calculate(Transaction::fee_weight(protocol, inputs.len(), outputs + 1, extra)) - - fee; - if (out_amount + change_fee) < in_amount { - change = true; - out_amount += change_fee; - fee += change_fee; - } - } - - if change { - payments.push((change_address.unwrap(), in_amount - out_amount)); - } - - if payments.len() > MAX_OUTPUTS { + if outputs > MAX_OUTPUTS { Err(TransactionError::TooManyOutputs)?; } + let mut payments = payments.drain(..).map(InternalPayment::Payment).collect::>(); + if let Some(change) = change_address { + payments.push(InternalPayment::Change(change, in_amount - out_amount)); + } + Ok(SignableTransaction { protocol, inputs, payments, data, fee }) } @@ -289,23 +356,93 @@ impl SignableTransaction { // Used for all non-subaddress outputs, or if there's only one subaddress output and a change let tx_key = Zeroizing::new(random_scalar(rng)); - // TODO: Support not needing additional when one subaddress and non-subaddress change - let additional = self.payments.iter().filter(|payment| payment.0.is_subaddress()).count() != 0; + let mut tx_public_key = tx_key.deref() * &ED25519_BASEPOINT_TABLE; + + // If any of these outputs are to a subaddress, we need keys distinct to them + // The only time this *does not* force having additional keys is when the only other output + // is a change output we have the view key for, enabling rewriting rA to aR + let mut has_change_view = false; + let subaddresses = self + .payments + .iter() + .filter(|payment| match *payment { + InternalPayment::Payment(payment) => payment.0.is_subaddress(), + InternalPayment::Change(change, _) => { + if change.view.is_some() { + has_change_view = true; + // It should not be possible to construct a change specification to a subaddress with a + // view key + debug_assert!(!change.address.is_subaddress()); + } + change.address.is_subaddress() + } + }) + .count() != + 0; + + // We need additional keys if we have any subaddresses + let mut additional = subaddresses; + // Unless the above change view key path is taken + if (self.payments.len() == 2) && has_change_view { + additional = false; + } + let modified_change_ecdh = subaddresses && (!additional); + + // If we're using the aR rewrite, update tx_public_key from rG to rB + if modified_change_ecdh { + for payment in &self.payments { + match payment { + InternalPayment::Payment(payment) => { + // This should be the only payment and it should be a subaddress + debug_assert!(payment.0.is_subaddress()); + tx_public_key = tx_key.deref() * payment.0.spend; + } + InternalPayment::Change(_, _) => {} + } + } + debug_assert!(tx_public_key != (tx_key.deref() * &ED25519_BASEPOINT_TABLE)); + } // Actually create the outputs let mut outputs = Vec::with_capacity(self.payments.len()); let mut id = None; - for payment in self.payments.drain(..).enumerate() { - // If this is a subaddress, generate a dedicated r. Else, reuse the TX key - let dedicated = Zeroizing::new(random_scalar(&mut *rng)); - let use_dedicated = additional && payment.1 .0.is_subaddress(); - let r = if use_dedicated { &dedicated } else { &tx_key }; + for (o, mut payment) in self.payments.drain(..).enumerate() { + // Downcast the change output to a payment output if it doesn't require special handling + // regarding it's view key + payment = if !modified_change_ecdh { + if let InternalPayment::Change(change, amount) = &payment { + InternalPayment::Payment((change.address, *amount)) + } else { + payment + } + } else { + payment + }; - let (mut output, payment_id) = SendOutput::new(r, uniqueness, payment); - // If this used the tx_key, randomize its R - if !use_dedicated { - output.R = dfg::EdwardsPoint::random(&mut *rng).0; - } + let (output, payment_id) = match payment { + InternalPayment::Payment(payment) => { + // If this is a subaddress, generate a dedicated r. Else, reuse the TX key + let dedicated = Zeroizing::new(random_scalar(&mut *rng)); + let use_dedicated = additional && payment.0.is_subaddress(); + let r = if use_dedicated { &dedicated } else { &tx_key }; + + let (mut output, payment_id) = SendOutput::new(r, uniqueness, (o, payment)); + if modified_change_ecdh { + debug_assert_eq!(tx_public_key, output.R); + } + // If this used tx_key, randomize its R + if !use_dedicated { + output.R = dfg::EdwardsPoint::random(&mut *rng).0; + } + (output, payment_id) + } + InternalPayment::Change(change, amount) => { + // Instead of rA, use Ra, where R is r * subaddress_spend_key + // change.view must be Some as if it's None, this payment would've been downcast + let ecdh = tx_public_key * change.view.unwrap().deref(); + SendOutput::change(&ecdh, uniqueness, (o, (change.address, amount))) + } + }; outputs.push(output); id = id.or(payment_id); @@ -330,7 +467,7 @@ impl SignableTransaction { // Create the TX extra let extra = { let mut extra = Extra::new( - tx_key.deref() * &ED25519_BASEPOINT_TABLE, + tx_public_key, if additional { outputs.iter().map(|output| output.R).collect() } else { vec![] }, ); diff --git a/coins/monero/src/wallet/send/multisig.rs b/coins/monero/src/wallet/send/multisig.rs index d665928e..8a1327e9 100644 --- a/coins/monero/src/wallet/send/multisig.rs +++ b/coins/monero/src/wallet/send/multisig.rs @@ -4,6 +4,8 @@ use std::{ collections::HashMap, }; +use zeroize::Zeroizing; + use rand_core::{RngCore, CryptoRng, SeedableRng}; use rand_chacha::ChaCha20Rng; @@ -29,7 +31,9 @@ use crate::{ }, transaction::{Input, Transaction}, rpc::Rpc, - wallet::{TransactionError, SignableTransaction, Decoys, key_image_sort, uniqueness}, + wallet::{ + TransactionError, InternalPayment, SignableTransaction, Decoys, key_image_sort, uniqueness, + }, }; /// FROST signing machine to produce a signed transaction. @@ -108,8 +112,19 @@ impl SignableTransaction { transcript.append_message(b"input_shared_key", input.key_offset().to_bytes()); } for payment in &self.payments { - transcript.append_message(b"payment_address", payment.0.to_string().as_bytes()); - transcript.append_message(b"payment_amount", payment.1.to_le_bytes()); + match payment { + InternalPayment::Payment(payment) => { + transcript.append_message(b"payment_address", payment.0.to_string().as_bytes()); + transcript.append_message(b"payment_amount", payment.1.to_le_bytes()); + } + InternalPayment::Change(change, amount) => { + transcript.append_message(b"change_address", change.address.to_string().as_bytes()); + if let Some(view) = change.view.as_ref() { + transcript.append_message(b"change_view_key", Zeroizing::new(view.to_bytes())); + } + transcript.append_message(b"change_amount", amount.to_le_bytes()); + } + } } let mut key_images = vec![]; diff --git a/coins/monero/tests/runner.rs b/coins/monero/tests/runner.rs index 5eac16b5..5c3bb64f 100644 --- a/coins/monero/tests/runner.rs +++ b/coins/monero/tests/runner.rs @@ -155,7 +155,7 @@ macro_rules! test { use monero_serai::{ random_scalar, wallet::{ - address::{Network, AddressSpec}, ViewPair, Scanner, SignableTransaction, + address::{Network, AddressSpec}, ViewPair, Scanner, Change, SignableTransaction, SignableTransactionBuilder, }, }; @@ -196,7 +196,13 @@ macro_rules! test { let builder = SignableTransactionBuilder::new( rpc.get_protocol().await.unwrap(), rpc.get_fee().await.unwrap(), - Some(random_address().2), + Some(Change::new( + &ViewPair::new( + &random_scalar(&mut OsRng) * &ED25519_BASEPOINT_TABLE, + Zeroizing::new(random_scalar(&mut OsRng)) + ), + false + )), ); let sign = |tx: SignableTransaction| { diff --git a/coins/monero/tests/send.rs b/coins/monero/tests/send.rs index 84eb2bb0..66f8e593 100644 --- a/coins/monero/tests/send.rs +++ b/coins/monero/tests/send.rs @@ -1,6 +1,7 @@ use monero_serai::{ - wallet::{ReceivedOutput, SpendableOutput}, + wallet::{extra::Extra, address::SubaddressIndex, ReceivedOutput, SpendableOutput}, transaction::Transaction, + rpc::Rpc, }; mod runner; @@ -49,3 +50,69 @@ test!( }, ), ); + +test!( + // Ideally, this would be single_R, yet it isn't feasible to apply allow(non_snake_case) here + single_r_subaddress_send, + ( + // Consume this builder for an output we can use in the future + // This is needed because we can't get the input from the passed in builder + |_, mut builder: Builder, addr| async move { + builder.add_payment(addr, 1000000000000); + (builder.build().unwrap(), ()) + }, + |_, tx: Transaction, mut scanner: Scanner, _| async move { + let mut outputs = scanner.scan_transaction(&tx).not_locked(); + outputs.sort_by(|x, y| x.commitment().amount.cmp(&y.commitment().amount)); + assert_eq!(outputs[0].commitment().amount, 1000000000000); + outputs + }, + ), + ( + |rpc: Rpc, _, _, mut outputs: Vec| async move { + let change_view = ViewPair::new( + &random_scalar(&mut OsRng) * &ED25519_BASEPOINT_TABLE, + Zeroizing::new(random_scalar(&mut OsRng)), + ); + + let mut builder = SignableTransactionBuilder::new( + rpc.get_protocol().await.unwrap(), + rpc.get_fee().await.unwrap(), + Some(Change::new(&change_view, false)), + ); + builder.add_input(SpendableOutput::from(&rpc, outputs.swap_remove(0)).await.unwrap()); + + // Send to a subaddress + let sub_view = ViewPair::new( + &random_scalar(&mut OsRng) * &ED25519_BASEPOINT_TABLE, + Zeroizing::new(random_scalar(&mut OsRng)), + ); + builder.add_payment( + sub_view + .address(Network::Mainnet, AddressSpec::Subaddress(SubaddressIndex::new(0, 1).unwrap())), + 1, + ); + (builder.build().unwrap(), (change_view, sub_view)) + }, + |_, tx: Transaction, _, views: (ViewPair, ViewPair)| async move { + // Make sure the change can pick up its output + let mut change_scanner = Scanner::from_view(views.0, Some(HashSet::new())); + assert!(change_scanner.scan_transaction(&tx).not_locked().len() == 1); + + // Make sure the subaddress can pick up its output + let mut sub_scanner = Scanner::from_view(views.1, Some(HashSet::new())); + sub_scanner.register_subaddress(SubaddressIndex::new(0, 1).unwrap()); + let sub_outputs = sub_scanner.scan_transaction(&tx).not_locked(); + assert!(sub_outputs.len() == 1); + assert_eq!(sub_outputs[0].commitment().amount, 1); + + // Make sure only one R was included in TX extra + assert!(Extra::read::<&[u8]>(&mut tx.prefix.extra.as_ref()) + .unwrap() + .keys() + .unwrap() + .1 + .is_none()); + }, + ), +); diff --git a/coins/monero/tests/wallet2_compatibility.rs b/coins/monero/tests/wallet2_compatibility.rs index 1b028435..113249c0 100644 --- a/coins/monero/tests/wallet2_compatibility.rs +++ b/coins/monero/tests/wallet2_compatibility.rs @@ -21,7 +21,7 @@ use monero_serai::{ transaction::Transaction, wallet::{ address::{Network, AddressSpec, SubaddressIndex, MoneroAddress}, - extra::MAX_TX_EXTRA_NONCE_SIZE, + extra::{MAX_TX_EXTRA_NONCE_SIZE, Extra}, Scanner, }, rpc::Rpc, @@ -56,7 +56,7 @@ async fn initialize_rpcs() -> (WalletClient, Rpc, monero_rpc::monero::Address) { let wallet_rpc_addr = if address_resp.is_ok() { address_resp.unwrap().address } else { - wallet_rpc.create_wallet("test_wallet".to_string(), None, "English".to_string()).await.unwrap(); + wallet_rpc.create_wallet("wallet".to_string(), None, "English".to_string()).await.unwrap(); let addr = wallet_rpc.get_address(0, None).await.unwrap().address; daemon_rpc.generate_blocks(&addr.to_string(), 70).await.unwrap(); addr @@ -64,7 +64,7 @@ async fn initialize_rpcs() -> (WalletClient, Rpc, monero_rpc::monero::Address) { (wallet_rpc, daemon_rpc, wallet_rpc_addr) } -async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { +async fn from_wallet_rpc_to_self(spec: AddressSpec) { // initialize rpc let (wallet_rpc, daemon_rpc, wallet_rpc_addr) = initialize_rpcs().await; @@ -109,24 +109,23 @@ async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { } async_sequential!( - async fn test_receipt_of_wallet_rpc_tx_standard() { - test_from_wallet_rpc_to_self(AddressSpec::Standard).await; + async fn receipt_of_wallet_rpc_tx_standard() { + from_wallet_rpc_to_self(AddressSpec::Standard).await; } - async fn test_receipt_of_wallet_rpc_tx_subaddress() { - test_from_wallet_rpc_to_self(AddressSpec::Subaddress(SubaddressIndex::new(0, 1).unwrap())) - .await; + async fn receipt_of_wallet_rpc_tx_subaddress() { + from_wallet_rpc_to_self(AddressSpec::Subaddress(SubaddressIndex::new(0, 1).unwrap())).await; } - async fn test_receipt_of_wallet_rpc_tx_integrated() { + async fn receipt_of_wallet_rpc_tx_integrated() { let mut payment_id = [0u8; 8]; OsRng.fill_bytes(&mut payment_id); - test_from_wallet_rpc_to_self(AddressSpec::Integrated(payment_id)).await; + from_wallet_rpc_to_self(AddressSpec::Integrated(payment_id)).await; } ); test!( - test_send_to_wallet_rpc_standard, + send_to_wallet_rpc_standard, ( |_, mut builder: Builder, _| async move { // initialize rpc @@ -151,7 +150,7 @@ test!( ); test!( - test_send_to_wallet_rpc_subaddress, + send_to_wallet_rpc_subaddress, ( |_, mut builder: Builder, _| async move { // initialize rpc @@ -173,12 +172,20 @@ test!( data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); assert_eq!(transfer.amount.as_pico(), 1000000); assert_eq!(transfer.subaddr_index, Index { major: 0, minor: data.1 }); + + // Make sure only one R was included in TX extra + assert!(Extra::read::<&[u8]>(&mut tx.prefix.extra.as_ref()) + .unwrap() + .keys() + .unwrap() + .1 + .is_none()); }, ), ); test!( - test_send_to_wallet_rpc_integrated, + send_to_wallet_rpc_integrated, ( |_, mut builder: Builder, _| async move { // initialize rpc @@ -205,7 +212,7 @@ test!( ); test!( - test_send_to_wallet_rpc_with_arb_data, + send_to_wallet_rpc_with_arb_data, ( |_, mut builder: Builder, _| async move { // initialize rpc diff --git a/processor/src/coin/monero.rs b/processor/src/coin/monero.rs index 67329a74..9103c3b0 100644 --- a/processor/src/coin/monero.rs +++ b/processor/src/coin/monero.rs @@ -15,7 +15,7 @@ use monero_serai::{ wallet::{ ViewPair, Scanner, address::{Network, SubaddressIndex, AddressSpec, MoneroAddress}, - Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine, + Fee, SpendableOutput, Change, SignableTransaction as MSignableTransaction, TransactionMachine, }, }; @@ -236,7 +236,8 @@ impl Coin for Monero { self.rpc.get_protocol().await.unwrap(), // TODO: Make this deterministic inputs.drain(..).map(|input| input.0).collect(), payments.to_vec(), - change.map(|change| self.address_internal(change, CHANGE_SUBADDRESS)), + change + .map(|change| Change::fingerprintable(self.address_internal(change, CHANGE_SUBADDRESS))), vec![], fee, ) @@ -316,7 +317,7 @@ impl Coin for Monero { self.rpc.get_protocol().await.unwrap(), outputs, vec![(address, amount - fee)], - Some(Self::test_address()), + Some(Change::new(&Self::test_view_pair(), true)), vec![], self.rpc.get_fee().await.unwrap(), ) From 36034c2f72e595c14a6103dfcdb9d80c34451a9a Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 11 Mar 2023 10:51:40 -0500 Subject: [PATCH 68/74] Move ecdh derivation up to prevent Scalar::one() * ecdh --- coins/monero/src/wallet/mod.rs | 5 ++--- coins/monero/src/wallet/scan.rs | 4 ++-- coins/monero/src/wallet/send/mod.rs | 20 ++++++-------------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index 1f23406b..72f098ba 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -59,12 +59,11 @@ pub(crate) fn uniqueness(inputs: &[Input]) -> [u8; 32] { #[allow(non_snake_case)] pub(crate) fn shared_key( uniqueness: Option<[u8; 32]>, - s: &Zeroizing, - P: &EdwardsPoint, + ecdh: EdwardsPoint, o: usize, ) -> (u8, Scalar, [u8; 8]) { // 8Ra - let mut output_derivation = (s.deref() * P).mul_by_cofactor().compress().to_bytes().to_vec(); + let mut output_derivation = ecdh.mul_by_cofactor().compress().to_bytes().to_vec(); let mut payment_id_xor = [0; 8]; payment_id_xor diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index f4a1f580..3deb080f 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -1,3 +1,4 @@ +use core::ops::Deref; use std::io::{self, Read, Write}; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -316,8 +317,7 @@ impl Scanner { }; let (view_tag, shared_key, payment_id_xor) = shared_key( if self.burning_bug.is_none() { Some(uniqueness(&tx.prefix.inputs)) } else { None }, - &self.pair.view, - key, + self.pair.view.deref() * key, o, ); diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index f8eec1e6..10704ec6 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -59,15 +59,14 @@ impl SendOutput { fn internal( unique: [u8; 32], output: (usize, (MoneroAddress, u64)), - ecdh_left: &Zeroizing, - ecdh_right: &EdwardsPoint, + ecdh: EdwardsPoint, R: EdwardsPoint, ) -> (SendOutput, Option<[u8; 8]>) { let o = output.0; let output = output.1; let (view_tag, shared_key, payment_id_xor) = - shared_key(Some(unique).filter(|_| output.0.is_guaranteed()), ecdh_left, ecdh_right, o); + shared_key(Some(unique).filter(|_| output.0.is_guaranteed()), ecdh, o); ( SendOutput { @@ -93,8 +92,7 @@ impl SendOutput { SendOutput::internal( unique, output, - r, - &address.view, + r.deref() * address.view, if !address.is_subaddress() { r.deref() * &ED25519_BASEPOINT_TABLE } else { @@ -104,17 +102,11 @@ impl SendOutput { } fn change( - ecdh: &EdwardsPoint, + ecdh: EdwardsPoint, unique: [u8; 32], output: (usize, (MoneroAddress, u64)), ) -> (SendOutput, Option<[u8; 8]>) { - SendOutput::internal( - unique, - output, - &Zeroizing::new(Scalar::one()), - ecdh, - ED25519_BASEPOINT_POINT, - ) + SendOutput::internal(unique, output, ecdh, ED25519_BASEPOINT_POINT) } } @@ -440,7 +432,7 @@ impl SignableTransaction { // Instead of rA, use Ra, where R is r * subaddress_spend_key // change.view must be Some as if it's None, this payment would've been downcast let ecdh = tx_public_key * change.view.unwrap().deref(); - SendOutput::change(&ecdh, uniqueness, (o, (change.address, amount))) + SendOutput::change(ecdh, uniqueness, (o, (change.address, amount))) } }; From 41a285ddfab39e0571d52fdcdbf18dc20e650c84 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 12 Mar 2023 03:54:30 -0400 Subject: [PATCH 69/74] Add a TX size check to Monero This isn't perfect yet should ensure the eventual TX is less than 100k bytes. --- coins/monero/src/ringct/bulletproofs/mod.rs | 1 + coins/monero/src/wallet/send/mod.rs | 22 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/coins/monero/src/ringct/bulletproofs/mod.rs b/coins/monero/src/ringct/bulletproofs/mod.rs index 866f9018..fdddca2a 100644 --- a/coins/monero/src/ringct/bulletproofs/mod.rs +++ b/coins/monero/src/ringct/bulletproofs/mod.rs @@ -37,6 +37,7 @@ impl Bulletproofs { pub(crate) fn fee_weight(plus: bool, outputs: usize) -> usize { let fields = if plus { 6 } else { 9 }; + // TODO: Shouldn't this use u32/u64? #[allow(non_snake_case)] let mut LR_len = usize::try_from(usize::BITS - (outputs - 1).leading_zeros()).unwrap(); let padded_outputs = 1 << LR_len; diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index 10704ec6..0a58cf94 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -124,6 +124,8 @@ pub enum TransactionError { TooManyOutputs, #[error("too much data")] TooMuchData, + #[error("too many inputs/too much arbitrary data")] + TooLargeTransaction, #[error("not enough funds (in {0}, out {1})")] NotEnoughFunds(u64, u64), #[error("wrong spend private key")] @@ -303,8 +305,6 @@ impl SignableTransaction { } } - // TODO TX MAX SIZE - // If we don't have two outputs, as required by Monero, error if (payments.len() == 1) && change_address.is_none() { Err(TransactionError::NoChange)?; @@ -316,8 +316,24 @@ impl SignableTransaction { // Calculate the extra length let extra = Extra::fee_weight(outputs, has_payment_id, data.as_ref()); + // This is a extremely heavy fee weight estimation which can only be trusted for two things + // 1) Ensuring we have enough for whatever fee we end up using + // 2) Ensuring we aren't over the max size + let estimated_tx_size = Transaction::fee_weight(protocol, inputs.len(), outputs, extra); + + // The actual limit is half the block size, and for the minimum block size of 300k, that'd be + // 150k + // wallet2 will only create transactions up to 100k bytes however + const MAX_TX_SIZE: usize = 100_000; + + // This uses the weight (estimated_tx_size) despite the BP clawback + // The clawback *increases* the weight, so this will over-estimate, yet it's still safe + if estimated_tx_size >= MAX_TX_SIZE { + Err(TransactionError::TooLargeTransaction)?; + } + // Calculate the fee. - let fee = fee_rate.calculate(Transaction::fee_weight(protocol, inputs.len(), outputs, extra)); + let fee = fee_rate.calculate(estimated_tx_size); // Make sure we have enough funds let in_amount = inputs.iter().map(|input| input.commitment().amount).sum::(); From f5fa6f020d771018e1327eaec93ab67ee9fb0be6 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 12 Mar 2023 03:55:17 -0400 Subject: [PATCH 70/74] Remove note about adding in a DB handle It'd arguably be safer yet it isn't worth the API complexity. --- coins/monero/src/wallet/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index 72f098ba..d7dff8ff 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -213,7 +213,6 @@ impl Scanner { /// When a new scanner is created, ALL saved output keys must be passed in to be secure. /// If None is passed, a modified shared key derivation is used which is immune to the burning /// bug (specifically the Guaranteed feature from Featured Addresses). - // TODO: Should this take in a DB access handle to ensure output keys are saved? pub fn from_view(pair: ViewPair, burning_bug: Option>) -> Scanner { let mut subaddresses = HashMap::new(); subaddresses.insert(pair.spend.compress(), None); From 14203bbb466cff25ad356c9bdbcfd04a29aff0e8 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 12 Mar 2023 04:13:43 -0400 Subject: [PATCH 71/74] Use an async Mutex for the Monero distribution Enables safe async/thread-safe usage. --- Cargo.lock | 1 + coins/monero/Cargo.toml | 2 + coins/monero/src/wallet/decoys.rs | 75 ++++++++++++++++++------------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10d23ffe..4985fa39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5027,6 +5027,7 @@ dependencies = [ "digest_auth", "dleq", "flexible-transcript", + "futures", "group", "hex", "hex-literal", diff --git a/coins/monero/Cargo.toml b/coins/monero/Cargo.toml index fb480b9f..f3ddfdcb 100644 --- a/coins/monero/Cargo.toml +++ b/coins/monero/Cargo.toml @@ -12,6 +12,8 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] +futures = "0.3" + hex-literal = "0.3" lazy_static = "1" thiserror = "1" diff --git a/coins/monero/src/wallet/decoys.rs b/coins/monero/src/wallet/decoys.rs index e9ab7280..4b67955a 100644 --- a/coins/monero/src/wallet/decoys.rs +++ b/coins/monero/src/wallet/decoys.rs @@ -1,4 +1,6 @@ -use std::{sync::Mutex, collections::HashSet}; +use std::collections::HashSet; + +use futures::lock::{Mutex, MutexGuard}; use lazy_static::lazy_static; @@ -24,16 +26,15 @@ const TIP_APPLICATION: f64 = (LOCK_WINDOW * BLOCK_TIME) as f64; lazy_static! { static ref GAMMA: Gamma = Gamma::new(19.28, 1.0 / 1.61).unwrap(); // TODO: Expose an API to reset this in case a reorg occurs/the RPC fails/returns garbage - // TODO: This is not currently thread-safe. This needs to be a tokio Mutex held by select until - // it returns - // TODO: Update this when scanning a block, as possible. + // TODO: Update this when scanning a block, as possible static ref DISTRIBUTION: Mutex> = Mutex::new(Vec::with_capacity(3000000)); } #[allow(clippy::too_many_arguments)] -async fn select_n( +async fn select_n<'a, R: RngCore + CryptoRng>( rng: &mut R, rpc: &Rpc, + distribution: &MutexGuard<'a, Vec>, height: usize, high: u64, per_second: f64, @@ -65,7 +66,6 @@ async fn select_n( let o = (age * per_second) as u64; if o < high { - let distribution = DISTRIBUTION.lock().unwrap(); let i = distribution.partition_point(|s| *s < (high - 1 - o)); let prev = i.saturating_sub(1); let n = distribution[i] - distribution[prev]; @@ -140,6 +140,8 @@ impl Decoys { height: usize, inputs: &[SpendableOutput], ) -> Result, RpcError> { + let mut distribution = DISTRIBUTION.lock().await; + let decoy_count = ring_len - 1; // Convert the inputs in question to the raw output data @@ -150,29 +152,19 @@ impl Decoys { outputs.push((real[real.len() - 1], [input.key(), input.commitment().calculate()])); } - let distribution_len = { - let distribution = DISTRIBUTION.lock().unwrap(); - distribution.len() - }; - if distribution_len <= height { - let extension = rpc.get_output_distribution(distribution_len, height).await?; - DISTRIBUTION.lock().unwrap().extend(extension); + if distribution.len() <= height { + let extension = rpc.get_output_distribution(distribution.len(), height).await?; + distribution.extend(extension); } + // If asked to use an older height than previously asked, truncate to ensure accuracy + // Should never happen, yet risks desyncing if it did + distribution.truncate(height + 1); // height is inclusive, and 0 is a valid height - let high; - let per_second; - { - let mut distribution = DISTRIBUTION.lock().unwrap(); - // If asked to use an older height than previously asked, truncate to ensure accuracy - // Should never happen, yet risks desyncing if it did - distribution.truncate(height + 1); // height is inclusive, and 0 is a valid height - - high = distribution[distribution.len() - 1]; - per_second = { - let blocks = distribution.len().min(BLOCKS_PER_YEAR); - let outputs = high - distribution[distribution.len().saturating_sub(blocks + 1)]; - (outputs as f64) / ((blocks * BLOCK_TIME) as f64) - }; + let high = distribution[distribution.len() - 1]; + let per_second = { + let blocks = distribution.len().min(BLOCKS_PER_YEAR); + let outputs = high - distribution[distribution.len().saturating_sub(blocks + 1)]; + (outputs as f64) / ((blocks * BLOCK_TIME) as f64) }; let mut used = HashSet::::new(); @@ -188,9 +180,18 @@ impl Decoys { // Select all decoys for this transaction, assuming we generate a sane transaction // We should almost never naturally generate an insane transaction, hence why this doesn't // bother with an overage - let mut decoys = - select_n(rng, rpc, height, high, per_second, &real, &mut used, inputs.len() * decoy_count) - .await?; + let mut decoys = select_n( + rng, + rpc, + &distribution, + height, + high, + per_second, + &real, + &mut used, + inputs.len() * decoy_count, + ) + .await?; real.zeroize(); let mut res = Vec::with_capacity(inputs.len()); @@ -228,8 +229,18 @@ impl Decoys { // Select new outputs until we have a full sized ring again ring.extend( - select_n(rng, rpc, height, high, per_second, &[], &mut used, ring_len - ring.len()) - .await?, + select_n( + rng, + rpc, + &distribution, + height, + high, + per_second, + &[], + &mut used, + ring_len - ring.len(), + ) + .await?, ); ring.sort_by(|a, b| a.0.cmp(&b.0)); } From 0e0243639e273968e3dc7ef9342eecbdf7321cf5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 13 Mar 2023 07:57:45 -0400 Subject: [PATCH 72/74] Resolve clippy error This was resolved on the processor branch yet not on develop. --- substrate/node/src/cli.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/substrate/node/src/cli.rs b/substrate/node/src/cli.rs index b5869e30..e8bf2d34 100644 --- a/substrate/node/src/cli.rs +++ b/substrate/node/src/cli.rs @@ -9,6 +9,7 @@ pub struct Cli { pub run: RunCmd, } +#[allow(clippy::large_enum_variant)] #[derive(Debug, clap::Subcommand)] pub enum Subcommand { // Key management CLI utilities From 48078d0b4bb6d3dc9dcc2eadacb3bf510d9aa0b5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 13 Mar 2023 08:03:13 -0400 Subject: [PATCH 73/74] Remove Protocol::Unsupported --- coins/monero/src/lib.rs | 3 --- coins/monero/src/rpc.rs | 4 +++- coins/monero/tests/runner.rs | 5 +++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/coins/monero/src/lib.rs b/coins/monero/src/lib.rs index e1574cf7..cc6b325e 100644 --- a/coins/monero/src/lib.rs +++ b/coins/monero/src/lib.rs @@ -56,7 +56,6 @@ mod tests; #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] #[allow(non_camel_case_types)] pub enum Protocol { - Unsupported(usize), v14, v16, Custom { ring_len: usize, bp_plus: bool }, @@ -66,7 +65,6 @@ impl Protocol { /// Amount of ring members under this protocol version. pub fn ring_len(&self) -> usize { match self { - Protocol::Unsupported(_) => panic!("Unsupported protocol version"), Protocol::v14 => 11, Protocol::v16 => 16, Protocol::Custom { ring_len, .. } => *ring_len, @@ -77,7 +75,6 @@ impl Protocol { /// This method will likely be reworked when versions not using Bulletproofs at all are added. pub fn bp_plus(&self) -> bool { match self { - Protocol::Unsupported(_) => panic!("Unsupported protocol version"), Protocol::v14 => false, Protocol::v16 => true, Protocol::Custom { bp_plus, .. } => *bp_plus, diff --git a/coins/monero/src/rpc.rs b/coins/monero/src/rpc.rs index 73386829..f53bfc72 100644 --- a/coins/monero/src/rpc.rs +++ b/coins/monero/src/rpc.rs @@ -45,6 +45,8 @@ pub enum RpcError { ConnectionError, #[error("invalid node")] InvalidNode, + #[error("unsupported protocol version ({0})")] + UnsupportedProtocol(usize), #[error("transactions not found")] TransactionsNotFound(Vec<[u8; 32]>), #[error("invalid point ({0})")] @@ -211,7 +213,7 @@ impl Rpc { { 13 | 14 => Protocol::v14, 15 | 16 => Protocol::v16, - version => Protocol::Unsupported(version), + protocol => Err(RpcError::UnsupportedProtocol(protocol))?, }, ) } diff --git a/coins/monero/tests/runner.rs b/coins/monero/tests/runner.rs index 5c3bb64f..3d061348 100644 --- a/coins/monero/tests/runner.rs +++ b/coins/monero/tests/runner.rs @@ -11,7 +11,7 @@ use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar}; use tokio::sync::Mutex; use monero_serai::{ - Protocol, random_scalar, + random_scalar, wallet::{ ViewPair, Scanner, address::{Network, AddressType, AddressSpec, AddressMeta, MoneroAddress}, @@ -76,6 +76,8 @@ pub async fn get_miner_tx_output(rpc: &Rpc, view: &ViewPair) -> SpendableOutput pub async fn rpc() -> Rpc { let rpc = Rpc::new("http://127.0.0.1:18081".to_string()).unwrap(); + // Make sure we recognize the protocol + rpc.get_protocol().await.unwrap(); // Only run once if rpc.get_height().await.unwrap() != 1 { @@ -91,7 +93,6 @@ pub async fn rpc() -> Rpc { // Mine 40 blocks to ensure decoy availability rpc.generate_blocks(&addr, 40).await.unwrap(); - assert!(!matches!(rpc.get_protocol().await.unwrap(), Protocol::Unsupported(_))); rpc } From f4e2da2767ee674e0d81cea829f2869bac2bf75a Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Tue, 14 Mar 2023 01:54:08 -0400 Subject: [PATCH 74/74] Move where we check the Monero node's protocol The genesis block has a version of 1, so immediately checking (before new blocks are added) will cause failures. --- coins/monero/tests/runner.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coins/monero/tests/runner.rs b/coins/monero/tests/runner.rs index 3d061348..0f28cb30 100644 --- a/coins/monero/tests/runner.rs +++ b/coins/monero/tests/runner.rs @@ -76,8 +76,6 @@ pub async fn get_miner_tx_output(rpc: &Rpc, view: &ViewPair) -> SpendableOutput pub async fn rpc() -> Rpc { let rpc = Rpc::new("http://127.0.0.1:18081".to_string()).unwrap(); - // Make sure we recognize the protocol - rpc.get_protocol().await.unwrap(); // Only run once if rpc.get_height().await.unwrap() != 1 { @@ -94,6 +92,9 @@ pub async fn rpc() -> Rpc { // Mine 40 blocks to ensure decoy availability rpc.generate_blocks(&addr, 40).await.unwrap(); + // Make sure we recognize the protocol + rpc.get_protocol().await.unwrap(); + rpc }