From b2ec40c275145efb82a41a005abbfc93c9bbfcb0 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 27 Mar 2025 20:21:50 -0400 Subject: [PATCH 1/2] `binaries/rpc-compat/` --- Cargo.lock | 527 +++++++++++++++++++++++++++-- Cargo.toml | 1 + binaries/rpc-compat/Cargo.toml | 35 ++ binaries/rpc-compat/README.md | 108 ++++++ binaries/rpc-compat/src/cli.rs | 50 +++ binaries/rpc-compat/src/harness.rs | 1 + binaries/rpc-compat/src/main.rs | 78 +++++ binaries/rpc-compat/src/rpc.rs | 207 +++++++++++ binaries/rpc-compat/src/traits.rs | 0 9 files changed, 986 insertions(+), 21 deletions(-) create mode 100644 binaries/rpc-compat/Cargo.toml create mode 100644 binaries/rpc-compat/README.md create mode 100644 binaries/rpc-compat/src/cli.rs create mode 100644 binaries/rpc-compat/src/harness.rs create mode 100644 binaries/rpc-compat/src/main.rs create mode 100644 binaries/rpc-compat/src/rpc.rs create mode 100644 binaries/rpc-compat/src/traits.rs diff --git a/Cargo.lock b/Cargo.lock index 59a3526dd..207e779d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,12 +44,56 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + [[package]] name = "anstyle" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "anyhow" version = "1.0.94" @@ -401,6 +445,7 @@ version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ + "anstream", "anstyle", "clap_lex", "strsim", @@ -425,6 +470,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "const_format" version = "0.2.34" @@ -453,6 +504,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation" version = "0.10.0" @@ -920,6 +981,27 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cuprate-rpc-compat" +version = "0.0.0" +dependencies = [ + "clap", + "crossbeam", + "cuprate-consensus-rules", + "cuprate-constants", + "cuprate-cryptonight", + "futures", + "hex", + "hex-literal", + "monero-serai", + "randomx-rs", + "rayon", + "reqwest", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "cuprate-rpc-interface" version = "0.0.0" @@ -1267,6 +1349,15 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1335,6 +1426,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1552,6 +1658,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hex" version = "0.4.3" @@ -1652,6 +1764,22 @@ dependencies = [ "tower-service 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hyper-util" version = "0.1.10" @@ -1844,6 +1972,44 @@ dependencies = [ "rayon", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix 0.37.28", + "windows-sys 0.48.0", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2736dd548daf35f50d261bbad35a83890bb9b461797f15de528485fbf206ab15" +dependencies = [ + "is-terminal", +] + [[package]] name = "itoa" version = "1.0.14" @@ -1863,9 +2029,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -1923,6 +2089,12 @@ dependencies = [ "libc", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -2179,6 +2351,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "native-tls" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2220,12 +2409,50 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "openssl" +version = "0.10.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -2357,6 +2584,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2586,6 +2819,50 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "reqwest" +version = "0.12.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower 0.5.2", + "tower-service 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + [[package]] name = "ring" version = "0.17.14" @@ -2615,6 +2892,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + [[package]] name = "rustix" version = "0.38.42" @@ -2624,7 +2915,7 @@ dependencies = [ "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.14", "windows-sys 0.59.0", ] @@ -2652,7 +2943,16 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.1.0", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", ] [[package]] @@ -2711,6 +3011,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework" version = "3.1.0" @@ -2718,7 +3031,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81d3f8c9bfcc3cbb6b0179eb57042d75b1582bdc65c3cb95f3fa999509c03cbc" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.10.0", "core-foundation-sys", "libc", "security-framework-sys", @@ -3005,6 +3318,9 @@ name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] [[package]] name = "synchronoise" @@ -3026,6 +3342,27 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "system-configuration" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -3041,7 +3378,7 @@ dependencies = [ "cfg-if", "fastrand", "once_cell", - "rustix", + "rustix 0.38.42", "windows-sys 0.59.0", ] @@ -3051,7 +3388,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ - "rustix", + "rustix 0.38.42", "windows-sys 0.59.0", ] @@ -3161,6 +3498,16 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.1" @@ -3448,12 +3795,24 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "valuable" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -3486,20 +3845,21 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", @@ -3509,11 +3869,24 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3521,9 +3894,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -3534,9 +3907,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "webpki-roots" @@ -3596,8 +3982,8 @@ checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ "windows-implement", "windows-interface", - "windows-result", - "windows-strings", + "windows-result 0.2.0", + "windows-strings 0.1.0", "windows-targets 0.52.6", ] @@ -3623,6 +4009,23 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +dependencies = [ + "windows-result 0.3.2", + "windows-strings 0.3.1", + "windows-targets 0.53.0", +] + [[package]] name = "windows-result" version = "0.2.0" @@ -3632,16 +4035,34 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-strings" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -3693,13 +4114,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -3712,6 +4149,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3724,6 +4167,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3736,12 +4185,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3754,6 +4215,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3766,6 +4233,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3778,6 +4251,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3790,6 +4269,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.6.20" diff --git a/Cargo.toml b/Cargo.toml index 1192a6b18..82a7b0154 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "3" members = [ # Binaries "binaries/cuprated", + "binaries/rpc-compat", # Consensus "consensus", diff --git a/binaries/rpc-compat/Cargo.toml b/binaries/rpc-compat/Cargo.toml new file mode 100644 index 000000000..909b3dcf5 --- /dev/null +++ b/binaries/rpc-compat/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "cuprate-rpc-compat" +version = "0.0.0" +edition = "2024" +description = "Cuprate RPC compatability testing harness" +license = "MIT" +authors = ["hinto-janai"] +repository = "https://github.com/Cuprate/cuprate/tree/main/rpc/cuprate-rpc-compat" +keywords = ["cuprate", "rpc", "compat"] + +[features] +default = [] + +[dependencies] +cuprate-constants = { workspace = true, features = ["build"] } +cuprate-consensus-rules = { workspace = true } +cuprate-cryptonight = { workspace = true } + +clap = { workspace = true, features = ["cargo", "derive", "default", "string"] } +crossbeam = { workspace = true, features = ["std"] } +futures = { workspace = true, features = ["std"] } +monero-serai = { workspace = true } +rayon = { workspace = true } +hex = { workspace = true, features = ["serde", "std"] } +hex-literal = { workspace = true } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true, features = ["std"] } +tokio = { workspace = true, features = ["full"] } +reqwest = { version = "0.12", features = ["json"] } +randomx-rs = { workspace = true } + +[dev-dependencies] + +[lints] +workspace = true diff --git a/binaries/rpc-compat/README.md b/binaries/rpc-compat/README.md new file mode 100644 index 000000000..1cfeb5f82 --- /dev/null +++ b/binaries/rpc-compat/README.md @@ -0,0 +1,108 @@ +# `cuprate-rpc-compat` +This crate provides tools for testing compatability between `monerod` and `cuprated`'s daemon RPC API, specifically: +- Request/response type correctness (both have same schema) +- Value correctness (both output the same values) + +There are cases where type/value correctness cannot be upheld by `cuprated`, +this crate provides tools for these cases as well. + +# Harness +TODO + +# Input permutations +TODO + +# Leniency on correctness +TODO + +# Configuring the RPC servers +TODO + +# Example +TODO + +```rust +// use std::sync::Arc; + +// use tokio::{net::TcpListener, sync::Barrier}; + +// use cuprate_json_rpc::{Request, Response, Id}; +// use cuprate_rpc_types::{ +// json::{JsonRpcRequest, JsonRpcResponse, GetBlockCountResponse}, +// other::{OtherRequest, OtherResponse}, +// }; +// use cuprate_rpc_interface::{RouterBuilder, RpcHandlerDummy}; + +// // Send a `/get_height` request. This endpoint has no inputs. +// async fn get_height(port: u16) -> OtherResponse { +// let url = format!("http://127.0.0.1:{port}/get_height"); +// ureq::get(&url) +// .set("Content-Type", "application/json") +// .call() +// .unwrap() +// .into_json() +// .unwrap() +// } + +// // Send a JSON-RPC request with the `get_block_count` method. +// // +// // The returned [`String`] is JSON. +// async fn get_block_count(port: u16) -> String { +// let url = format!("http://127.0.0.1:{port}/json_rpc"); +// let method = JsonRpcRequest::GetBlockCount(Default::default()); +// let request = Request::new(method); +// ureq::get(&url) +// .set("Content-Type", "application/json") +// .send_json(request) +// .unwrap() +// .into_string() +// .unwrap() +// } + +// #[tokio::main] +// async fn main() { +// // Start a local RPC server. +// let port = { +// // Create the router. +// let state = RpcHandlerDummy { restricted: false }; +// let router = RouterBuilder::new().all().build().with_state(state); + +// // Start a server. +// let listener = TcpListener::bind("127.0.0.1:0") +// .await +// .unwrap(); +// let port = listener.local_addr().unwrap().port(); + +// // Run the server with `axum`. +// tokio::task::spawn(async move { +// axum::serve(listener, router).await.unwrap(); +// }); + +// port +// }; + +// // Assert the response is the default. +// let response = get_height(port).await; +// let expected = OtherResponse::GetHeight(Default::default()); +// assert_eq!(response, expected); + +// // Assert the response JSON is correct. +// let response = get_block_count(port).await; +// let expected = r#"{"jsonrpc":"2.0","id":null,"result":{"status":"OK","untrusted":false,"count":0}}"#; +// assert_eq!(response, expected); + +// // Assert that (de)serialization works. +// let expected = Response::ok(Id::Null, Default::default()); +// let response: Response = serde_json::from_str(&response).unwrap(); +// assert_eq!(response, expected); +// } +``` + +# Feature flags +List of feature flags for `cuprate-rpc-compat`. + +All are enabled by default. + +| Feature flag | Does what | +|--------------|-----------| +| TODO | TODO \ No newline at end of file diff --git a/binaries/rpc-compat/src/cli.rs b/binaries/rpc-compat/src/cli.rs new file mode 100644 index 000000000..1ddaaaec6 --- /dev/null +++ b/binaries/rpc-compat/src/cli.rs @@ -0,0 +1,50 @@ +use std::num::{NonZeroU64, NonZeroUsize}; + +use clap::Parser; + +/// `cuprate` <-> `monerod` compatibility tester. +#[derive(Parser, Debug)] +#[command( + about, + long_about = None, + long_version = format!( + "{} {}", + clap::crate_version!(), + cuprate_constants::build::COMMIT + ), +)] +pub struct Args { + /// Base URL to use for `monerod` RPC. + /// + /// This must be a non-restricted RPC. + #[arg(long, default_value_t = String::from("http://127.0.0.1:18081"))] + pub rpc_url: String, + + /// Amount of async RPC tasks to spawn. + #[arg(long, default_value_t = NonZeroUsize::new(4).unwrap())] + pub rpc_tasks: NonZeroUsize, + + /// The maximum capacity of the block buffer in-between the RPC and verifier. + /// + /// `0` will cause the buffer to be unbounded. + #[arg(long, default_value_t = 1000)] + pub buffer_limit: usize, + + /// Amount of verifying threads to spawn. + #[arg(long, default_value_t = std::thread::available_parallelism().unwrap())] + pub threads: NonZeroUsize, + + /// Print an update every `update` amount of blocks. + #[arg(long, default_value_t = NonZeroU64::new(500).unwrap())] + pub update: NonZeroU64, +} + +impl Args { + pub fn get() -> Self { + let this = Self::parse(); + + println!("{this:#?}"); + + this + } +} diff --git a/binaries/rpc-compat/src/harness.rs b/binaries/rpc-compat/src/harness.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/binaries/rpc-compat/src/harness.rs @@ -0,0 +1 @@ + diff --git a/binaries/rpc-compat/src/main.rs b/binaries/rpc-compat/src/main.rs new file mode 100644 index 000000000..8c4931c89 --- /dev/null +++ b/binaries/rpc-compat/src/main.rs @@ -0,0 +1,78 @@ +#![doc = include_str!("../README.md")] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![allow(unreachable_pub, reason = "This is a binary, everything `pub` is ok")] + +mod cli; +mod rpc; + +use std::{ + sync::atomic::Ordering, + time::{Duration, Instant}, +}; + +#[tokio::main] +async fn main() { + let now = Instant::now(); + + // Parse CLI args. + let cli::Args { + rpc_url, + update, + rpc_tasks, + buffer_limit, + threads, + } = cli::Args::get(); + + // Set-up RPC client. + let client = rpc::RpcClient::new(rpc_url, rpc_tasks).await; + let top_height = client.top_height; + println!("top_height: {top_height}"); + println!(); + + todo!() +} + +// some draft code for `monerod` <-> `cuprated` RPC compat testing + +// /// represents a `monerod/cuprated` RPC request type. +// trait RpcRequest { +// /// the expected response type, potentially only being a subset of the fields. +// type SubsetOfResponse: PartialEq; + +// /// create a 'base' request. +// fn base() -> Self; + +// /// permutate the base request into all (or practically) possible requests. +// // e.g. `{"height":0}`, `{"height":1}`, etc +// fn all_possible_inputs_for_rpc_request(self) -> Vec; + +// /// send the request, get the response. +// /// +// /// `monerod` and `cuprated` are both expected to be fully synced. +// fn get(self, node: Node) -> Self::SubsetOfResponse; +// } + +// enum Node { +// Monerod, +// Cuprated, +// } + +// // all RPC requests. +// let all_rpc_requests: Vec = todo!(); + +// // for each request... +// for base in all_rpc_requests { +// // create all possible inputs... +// let requests = all_possible_inputs_for_rpc_request(base); + +// // for each input permutation... +// for r in requests { +// // assert (a potential subset of) `monerod` and `cuprated`'s response fields match in value. +// let monerod_response = r.get(Node::Monerod); +// let cuprated_response = r.get(Node::Cuprated); +// assert_eq!( +// monerod_response.subset_of_response(), +// cuprated_response.subset_of_response(), +// ); +// } +// } diff --git a/binaries/rpc-compat/src/rpc.rs b/binaries/rpc-compat/src/rpc.rs new file mode 100644 index 000000000..5ada0be75 --- /dev/null +++ b/binaries/rpc-compat/src/rpc.rs @@ -0,0 +1,207 @@ +use std::num::NonZeroUsize; + +use reqwest::{ + Client, ClientBuilder, + header::{HeaderMap, HeaderValue}, +}; +use serde_json::{Value, json}; + +#[derive(Debug, Clone)] +pub struct RpcClient { + client: Client, + json_rpc_url: String, + get_transactions_url: String, + rpc_tasks: NonZeroUsize, + pub top_height: u64, +} + +impl RpcClient { + pub async fn new(rpc_url: String, rpc_tasks: NonZeroUsize) -> Self { + let headers = { + let mut h = HeaderMap::new(); + h.insert("Content-Type", HeaderValue::from_static("application/json")); + h + }; + + let client = ClientBuilder::new() + .default_headers(headers) + .build() + .unwrap(); + + let request = json!({ + "jsonrpc": "2.0", + "id": 0, + "method": "get_last_block_header", + "params": {} + }); + + let json_rpc_url = format!("{rpc_url}/json_rpc"); + let get_transactions_url = format!("{rpc_url}/get_transactions"); + + let top_height = client + .get(&json_rpc_url) + .json(&request) + .send() + .await + .unwrap() + .json::() + .await + .unwrap() + .get("result") + .unwrap() + .get("block_header") + .unwrap() + .get("height") + .unwrap() + .as_u64() + .unwrap(); + + assert!(top_height > 3301441, "node is behind"); + + Self { + client, + json_rpc_url, + get_transactions_url, + rpc_tasks, + top_height, + } + } + + // async fn get_block(&self, height: u64) -> GetBlockResponse { + // let request = json!({ + // "jsonrpc": "2.0", + // "id": 0, + // "method": "get_block", + // "params": {"height": height, "fill_pow_hash": true} + // }); + + // self.client + // .get(&self.json_rpc_url) + // .json(&request) + // .send() + // .await + // .unwrap() + // .json::() + // .await + // .unwrap() + // .result + // } + + // async fn get_transactions(&self, tx_hashes: Vec<[u8; 32]>) -> Vec { + // assert!(!tx_hashes.is_empty()); + + // #[derive(Debug, Clone, Deserialize)] + // struct GetTransactionsResponse { + // txs: Vec, + // } + + // #[derive(Debug, Clone, Deserialize)] + // struct Tx { + // as_hex: String, + // pruned_as_hex: String, + // } + + // let txs_hashes = tx_hashes.iter().map(hex::encode).collect::>(); + // let request = json!({"txs_hashes":txs_hashes}); + + // let txs = self + // .client + // .get(&self.get_transactions_url) + // .json(&request) + // .send() + // .await + // .unwrap() + // .json::() + // .await + // .unwrap() + // .txs; + + // assert_eq!(txs.len(), tx_hashes.len()); + + // txs.into_par_iter() + // .zip(tx_hashes) + // .map(|(r, tx_hash)| { + // let tx_blob = hex::decode(if r.as_hex.is_empty() { + // r.pruned_as_hex + // } else { + // r.as_hex + // }) + // .unwrap(); + + // let tx = Transaction::read(&mut tx_blob.as_slice()).unwrap(); + + // RpcTxData { + // tx, + // tx_blob, + // tx_hash, + // } + // }) + // .collect() + // } + + // #[expect(clippy::cast_precision_loss)] + // pub async fn test(self, top_height: u64, tx: Sender) { + // use futures::StreamExt; + + // let now = Instant::now(); + + // let iter = (0..top_height).map(|height| { + // let this = self.clone(); + // let tx = tx.clone(); + + // async move { + // let get_block_response = this.get_block(height).await; + + // let (this, get_block_response, block, txs) = + // tokio::task::spawn_blocking(move || async move { + // // Deserialize the block. + // let block = Block::read(&mut get_block_response.blob.as_slice()).unwrap(); + + // // Fetch and deserialize all transactions. + // let mut tx_hashes = Vec::with_capacity(block.transactions.len() + 1); + // tx_hashes.push(block.miner_transaction.hash()); + // tx_hashes.extend(block.transactions.iter()); + // let txs = this.get_transactions(tx_hashes).await; + + // (this, get_block_response, block, txs) + // }) + // .await + // .unwrap() + // .await; + + // let (seed_height, seed_hash) = if height < RANDOMX_START_HEIGHT { + // (0, [0; 32]) + // } else { + // let seed_height = cuprate_consensus_rules::blocks::randomx_seed_height( + // height.try_into().unwrap(), + // ) + // .try_into() + // .unwrap(); + + // let seed_hash = this.get_block(seed_height).await.block_header.hash; + + // (seed_height, seed_hash) + // }; + + // let elapsed = now.elapsed().as_secs_f64(); + // let blocks_per_sec = height as f64 / elapsed; + + // let data = RpcBlockData { + // get_block_response, + // block, + // seed_height, + // seed_hash, + // txs, + // blocks_per_sec, + // }; + + // tx.send(data).unwrap(); + // } + // }); + + // futures::stream::iter(iter) + // .buffer_unordered(self.rpc_tasks.get()) // This can't be too high or else we get bottlenecked by `monerod` + // .for_each(|()| async {}) + // .await; + // } +} diff --git a/binaries/rpc-compat/src/traits.rs b/binaries/rpc-compat/src/traits.rs new file mode 100644 index 000000000..e69de29bb From f9b49a8ad470815e2a1e9fb57f59f49734098ee3 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 28 Mar 2025 16:34:46 -0400 Subject: [PATCH 2/2] typos --- binaries/rpc-compat/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binaries/rpc-compat/README.md b/binaries/rpc-compat/README.md index 1cfeb5f82..e0b3a0d80 100644 --- a/binaries/rpc-compat/README.md +++ b/binaries/rpc-compat/README.md @@ -1,5 +1,5 @@ # `cuprate-rpc-compat` -This crate provides tools for testing compatability between `monerod` and `cuprated`'s daemon RPC API, specifically: +This crate provides tools for testing compatibility between `monerod` and `cuprated`'s daemon RPC API, specifically: - Request/response type correctness (both have same schema) - Value correctness (both output the same values)