From 069840665732894a103806aa76067e8da9ae6f41 Mon Sep 17 00:00:00 2001 From: godmodegalactus Date: Tue, 14 Nov 2023 17:21:05 +0100 Subject: [PATCH] Making the geyser plugin work --- Cargo.lock | 203 +++++++++++++------------ Cargo.toml | 6 +- README.md | 9 +- client/Cargo.toml | 8 +- client/src/cli.rs | 2 +- client/src/main.rs | 70 +++------ client/src/skip_server_verification.rs | 9 -- config.json | 2 +- plugin/Cargo.toml | 11 +- plugin/src/lib.rs | 114 ++++++++------ plugin/src/skip_client_verification.rs | 6 +- plugin/src/tls_certificate.rs | 53 +++++++ rust-toolchain.toml | 2 +- 13 files changed, 274 insertions(+), 221 deletions(-) create mode 100644 plugin/src/tls_certificate.rs diff --git a/Cargo.lock b/Cargo.lock index 092001d..fa2734b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,29 +128,30 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" dependencies = [ "utf8parse", ] @@ -166,9 +167,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -676,9 +677,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bstr" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" +checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" dependencies = [ "memchr", "serde", @@ -812,31 +813,33 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "fb690e81c7840c0d7aade59f242ea3b41b9bc27bcd5997890e7702ae4b32e487" dependencies = [ "clap_builder", "clap_derive", + "once_cell", ] [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "5ed2e96bc16d8d740f6f48d663eddf4b8a0983e79210fd55479b7bcd0a69860e" dependencies = [ "anstream", "anstyle", - "clap_lex 0.6.0", + "clap_lex 0.5.0", + "once_cell", "strsim", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2 1.0.69", @@ -855,14 +858,16 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "client" version = "0.1.0" dependencies = [ + "anstyle", + "anstyle-parse", "anyhow", "async-channel", "base64 0.21.5", @@ -870,7 +875,8 @@ dependencies = [ "bs58", "bytes", "chrono", - "clap 4.4.7", + "clap 4.3.24", + "clap_lex 0.5.0", "const_env", "dashmap", "dotenv", @@ -1596,6 +1602,8 @@ dependencies = [ name = "geyser-quic-plugin" version = "0.1.0" dependencies = [ + "anstyle", + "anstyle-parse", "anyhow", "async-channel", "base64 0.21.5", @@ -1604,7 +1612,8 @@ dependencies = [ "bytes", "cargo-lock", "chrono", - "clap 4.4.7", + "clap 4.3.24", + "clap_lex 0.5.0", "const_env", "dashmap", "dotenv", @@ -1619,19 +1628,19 @@ dependencies = [ "pkcs8", "postgres-native-tls", "prometheus", - "quinn 0.9.4", + "quinn 0.10.2", "rcgen", - "rustls 0.20.8", + "rustls 0.21.8", "serde", "serde_json", "solana-geyser-plugin-interface", "solana-sdk 1.16.18", - "solana-streamer", "thiserror", "tokio", "tracing", "tracing-subscriber", "vergen", + "x509-parser", ] [[package]] @@ -1848,9 +1857,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -2007,6 +2016,17 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi 0.3.3", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "itertools" version = "0.10.5" @@ -3022,7 +3042,7 @@ dependencies = [ "quinn-proto 0.9.6", "quinn-udp 0.3.2", "rustc-hash", - "rustls 0.20.8", + "rustls 0.20.9", "thiserror", "tokio", "tracing", @@ -3056,7 +3076,7 @@ dependencies = [ "rand 0.8.5", "ring 0.16.20", "rustc-hash", - "rustls 0.20.8", + "rustls 0.20.9", "rustls-native-certs", "slab", "thiserror", @@ -3380,9 +3400,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "80109a168d9bc0c7f483083244543a6eb0dba02295d33ca268145e6190d6df0c" dependencies = [ "bitflags 2.4.1", "errno", @@ -3393,9 +3413,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "ring 0.16.20", "sct", @@ -3428,9 +3448,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64 0.21.5", ] @@ -3743,9 +3763,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "socket2" @@ -3894,9 +3914,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.17.4" +version = "1.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80447a64ba88aff4ab1fe70c646b9a0ee65f190aa2977b1e7360066445f8ed34" +checksum = "358b2e42869ebb34c6cafc89ca7cda381817b5bd781fa33302d335c6feaa04b6" dependencies = [ "ahash 0.8.6", "blake3", @@ -3917,7 +3937,7 @@ dependencies = [ "serde_derive", "serde_json", "sha2 0.10.8", - "solana-frozen-abi-macro 1.17.4", + "solana-frozen-abi-macro 1.17.5", "subtle", "thiserror", ] @@ -3935,9 +3955,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.17.4" +version = "1.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28b7325d40b3b3fef0db6917972e8121bec05fa2b59904212b25478c85924cd" +checksum = "ea690497947bc9cc8bcf7985b3c4c539b199e56c28f250746026797b681ea291" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", @@ -3968,9 +3988,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.17.4" +version = "1.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a224a0a87196c940472515838630e0ed6a49f97ea0d01d9dbeed0bb57390447" +checksum = "e679b49d07fa6a140e194cb453322b265fb48993e4ae6225a9524a7a6e28f27b" dependencies = [ "env_logger", "lazy_static", @@ -4102,9 +4122,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.17.4" +version = "1.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fe4a811ec2c4b0c3773e5661ecfaff81f822c9e18866097caeba6be9338dab" +checksum = "926ca88c8b0d0815ce4336092379eb0b61aebaab8ba984784c029a559200527f" dependencies = [ "ark-bn254", "ark-ec", @@ -4145,9 +4165,9 @@ dependencies = [ "serde_json", "sha2 0.10.8", "sha3 0.10.8", - "solana-frozen-abi 1.17.4", - "solana-frozen-abi-macro 1.17.4", - "solana-sdk-macro 1.17.4", + "solana-frozen-abi 1.17.5", + "solana-frozen-abi-macro 1.17.5", + "solana-sdk-macro 1.17.5", "thiserror", "tiny-bip39", "wasm-bindgen", @@ -4196,7 +4216,7 @@ dependencies = [ "quinn-proto 0.9.6", "quinn-udp 0.3.2", "rcgen", - "rustls 0.20.8", + "rustls 0.20.9", "solana-connection-cache", "solana-measure", "solana-metrics", @@ -4292,9 +4312,9 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.17.4" +version = "1.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c79894240bad61135a9ec86cd7709dcbc9e69eec8ebcc0b4066bccde6615600" +checksum = "d55719c5a4fdcf7651120ba6650cf4eba5f2b1eb30b06d2d53aec7237146d1f9" dependencies = [ "assert_matches", "base64 0.21.5", @@ -4334,11 +4354,11 @@ dependencies = [ "serde_with", "sha2 0.10.8", "sha3 0.10.8", - "solana-frozen-abi 1.17.4", - "solana-frozen-abi-macro 1.17.4", - "solana-logger 1.17.4", - "solana-program 1.17.4", - "solana-sdk-macro 1.17.4", + "solana-frozen-abi 1.17.5", + "solana-frozen-abi-macro 1.17.5", + "solana-logger 1.17.5", + "solana-program 1.17.5", + "solana-sdk-macro 1.17.5", "thiserror", "uriparse", "wasm-bindgen", @@ -4358,9 +4378,9 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.17.4" +version = "1.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dce8e347d73bcd9a6fe0b37bf830a20d0a4913ac58046c79959d5e15bbbed3" +checksum = "b7985176f781b66c625070b413f48740fab2ec2dd330f7afd04563799dffec44" dependencies = [ "bs58", "proc-macro2 1.0.69", @@ -4392,7 +4412,7 @@ dependencies = [ "quinn-udp 0.3.2", "rand 0.7.3", "rcgen", - "rustls 0.20.8", + "rustls 0.20.9", "solana-metrics", "solana-perf", "solana-sdk 1.16.18", @@ -4464,9 +4484,9 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.17.4" +version = "1.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48f33d2ce508c9e70aa7d2f1948f3a9df56ee66423252785c608b4023e0c01a" +checksum = "a1d5f912154350af6318043ff857198914fbaaa88338f57bfff5f0ba5cf0da62" dependencies = [ "aes-gcm-siv", "base64 0.21.5", @@ -4484,8 +4504,8 @@ dependencies = [ "serde", "serde_json", "sha3 0.9.1", - "solana-program 1.17.4", - "solana-sdk 1.17.4", + "solana-program 1.17.5", + "solana-sdk 1.17.5", "subtle", "thiserror", "zeroize", @@ -4542,7 +4562,7 @@ dependencies = [ "borsh 0.10.3", "num-derive 0.4.1", "num-traits", - "solana-program 1.17.4", + "solana-program 1.17.5", "spl-token", "spl-token-2022", "thiserror", @@ -4555,7 +4575,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" dependencies = [ "bytemuck", - "solana-program 1.17.4", + "solana-program 1.17.5", "spl-discriminator-derive", ] @@ -4589,7 +4609,7 @@ version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" dependencies = [ - "solana-program 1.17.4", + "solana-program 1.17.5", ] [[package]] @@ -4600,7 +4620,7 @@ checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" dependencies = [ "borsh 0.10.3", "bytemuck", - "solana-program 1.17.4", + "solana-program 1.17.5", "solana-zk-token-sdk", "spl-program-error", ] @@ -4613,7 +4633,7 @@ checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" dependencies = [ "num-derive 0.4.1", "num-traits", - "solana-program 1.17.4", + "solana-program 1.17.5", "spl-program-error-derive", "thiserror", ] @@ -4637,7 +4657,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" dependencies = [ "bytemuck", - "solana-program 1.17.4", + "solana-program 1.17.5", "spl-discriminator", "spl-pod", "spl-program-error", @@ -4655,7 +4675,7 @@ dependencies = [ "num-derive 0.3.3", "num-traits", "num_enum 0.6.1", - "solana-program 1.17.4", + "solana-program 1.17.5", "thiserror", ] @@ -4670,7 +4690,7 @@ dependencies = [ "num-derive 0.4.1", "num-traits", "num_enum 0.7.1", - "solana-program 1.17.4", + "solana-program 1.17.5", "solana-zk-token-sdk", "spl-memo", "spl-pod", @@ -4688,7 +4708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" dependencies = [ "borsh 0.10.3", - "solana-program 1.17.4", + "solana-program 1.17.5", "spl-discriminator", "spl-pod", "spl-program-error", @@ -4703,7 +4723,7 @@ checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" dependencies = [ "arrayref", "bytemuck", - "solana-program 1.17.4", + "solana-program 1.17.5", "spl-discriminator", "spl-pod", "spl-program-error", @@ -4718,7 +4738,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" dependencies = [ "bytemuck", - "solana-program 1.17.4", + "solana-program 1.17.5", "spl-discriminator", "spl-pod", "spl-program-error", @@ -4828,9 +4848,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -4938,9 +4958,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ "backtrace", "bytes", @@ -4957,9 +4977,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", @@ -5154,9 +5174,9 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ "log", "once_cell", @@ -5165,9 +5185,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -5725,18 +5745,3 @@ dependencies = [ "cc", "pkg-config", ] - -[[patch.unused]] -name = "solana-geyser-plugin-interface" -version = "1.16.17" -source = "git+https://github.com/blockworks-foundation/solana.git?branch=geyser_send_transaction_results_v1.16.17#445f8e7c5185e1c610a98267604a19679d0bade0" - -[[patch.unused]] -name = "solana-sdk" -version = "1.16.17" -source = "git+https://github.com/blockworks-foundation/solana.git?branch=geyser_send_transaction_results_v1.16.17#445f8e7c5185e1c610a98267604a19679d0bade0" - -[[patch.unused]] -name = "solana-streamer" -version = "1.16.17" -source = "git+https://github.com/blockworks-foundation/solana.git?branch=geyser_send_transaction_results_v1.16.17#445f8e7c5185e1c610a98267604a19679d0bade0" diff --git a/Cargo.toml b/Cargo.toml index f2d3bdc..c484f19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,6 @@ lto = true codegen-units = 1 [patch.crates-io] -solana-geyser-plugin-interface = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.17" } -solana-sdk = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.17" } -solana-streamer = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.17" } +solana-geyser-plugin-interface = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.18" } +solana-sdk = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.18" } +solana-streamer = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.18" } diff --git a/README.md b/README.md index d7ef279..a8d1541 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,11 @@ This project aims to get banking stage transaction data over geyser from the leader. There is a plugin which needs to be installed on leader. It will create a QUIC port and only accept connections from a known identity. -Once connection is accepted it will start sending the banking stage data over geyser to its suibscriber. \ No newline at end of file +Once connection is accepted it will start sending the banking stage data over geyser to its suibscriber. + +## Run solana validator with plugin + +```bash +$ solana-validator --geyser-plugin-config config.json +``` + diff --git a/client/Cargo.toml b/client/Cargo.toml index 62b79d6..a5bd628 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -27,7 +27,6 @@ futures = "0.3.28" bytes = "1.4.0" anyhow = "1.0.70" log = "0.4.17" -clap = { version = "4.2.4", features = ["derive", "env"] } dashmap = "5.4.0" const_env = "0.1.2" jsonrpsee = { version = "0.17.0", features = ["macros", "full"] } @@ -44,4 +43,9 @@ quinn = "0.10.2" rustls = { version = "0.21.8", default-features = false, features = ["quic"] } rcgen = "0.10.0" pkcs8 = "0.8.0" -pem = "1.1.1" \ No newline at end of file +pem = "1.1.1" + +clap = { version = "=4.3.24", features = ["cargo", "derive"] } +anstyle = "=1.0.0" +anstyle-parse = "=0.2.0" +clap_lex = "=0.5.0" \ No newline at end of file diff --git a/client/src/cli.rs b/client/src/cli.rs index 756234a..df5f22d 100644 --- a/client/src/cli.rs +++ b/client/src/cli.rs @@ -3,7 +3,7 @@ use clap::Parser; #[derive(Parser, Debug, Clone)] #[command(author, version, about, long_about = None)] pub struct Args { - #[arg(short, long, default_value_t = String::from("http://127.0.0.1:11000"))] + #[arg(short, long, default_value_t = String::from("127.0.0.1:11000"))] pub geyser_quic_address: String, #[arg(short, long, default_value_t = String::from("connection_identity.json"))] diff --git a/client/src/main.rs b/client/src/main.rs index 46e04d6..8d07efb 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -1,10 +1,8 @@ use std::{time::Duration, net::{IpAddr, Ipv4Addr, SocketAddr}, sync::Arc}; use cli::Args; -use geyser_quic_plugin::{TransactionResults, ALPN_GEYSER_PROTOCOL_ID}; -use pkcs8::{AlgorithmIdentifier, ObjectIdentifier, der::Document}; +use geyser_quic_plugin::{TransactionResults, ALPN_GEYSER_PROTOCOL_ID, tls_certificate::new_self_signed_tls_certificate}; use quinn::{TokioRuntime, EndpointConfig, Endpoint, ClientConfig, TransportConfig, IdleTimeout}; -use rcgen::{RcgenError, CertificateParams, SanType, DistinguishedName, DnType}; use skip_server_verification::SkipServerVerification; use solana_sdk::signature::Keypair; use clap::Parser; @@ -14,45 +12,6 @@ mod skip_server_verification; pub const PACKET_DATA_SIZE: usize = 1280 - 40 - 8; -pub fn new_self_signed_tls_certificate( - keypair: &Keypair, - san: IpAddr, -) -> Result<(rustls::Certificate, rustls::PrivateKey), RcgenError> { - const ED25519_IDENTIFIER: [u32; 4] = [1, 3, 101, 112]; - let mut private_key = Vec::::with_capacity(34); - private_key.extend_from_slice(&[0x04, 0x20]); // ASN.1 OCTET STRING - private_key.extend_from_slice(keypair.secret().as_bytes()); - let key_pkcs8 = pkcs8::PrivateKeyInfo { - algorithm: AlgorithmIdentifier { - oid: ObjectIdentifier::from_arcs(&ED25519_IDENTIFIER).expect("Failed to convert OID"), - parameters: None, - }, - private_key: &private_key, - public_key: None, - }; - let key_pkcs8_der = key_pkcs8 - .to_der() - .expect("Failed to convert keypair to DER") - .to_der(); - - let rcgen_keypair = rcgen::KeyPair::from_der(&key_pkcs8_der)?; - - let mut cert_params = CertificateParams::default(); - cert_params.subject_alt_names = vec![SanType::IpAddress(san)]; - cert_params.alg = &rcgen::PKCS_ED25519; - cert_params.key_pair = Some(rcgen_keypair); - cert_params.distinguished_name = DistinguishedName::new(); - cert_params - .distinguished_name - .push(DnType::CommonName, "Solana node"); - - let cert = rcgen::Certificate::from_params(cert_params)?; - let cert_der = cert.serialize_der().unwrap(); - let priv_key = cert.serialize_private_key_der(); - let priv_key = rustls::PrivateKey(priv_key); - Ok((rustls::Certificate(cert_der), priv_key)) -} - pub async fn load_identity_keypair(identity_file: &String) -> Option { let identity_file = tokio::fs::read_to_string(identity_file.as_str()) .await @@ -109,21 +68,32 @@ pub async fn main() -> anyhow::Result<()> { let endpoint = create_endpoint(certificate, key); let connection = endpoint.connect(address, "quic_geyser_plugin").expect("Should be connecting").await.expect("Should be able to connect to the plugin"); - let (_send_stream, recv_stream) = connection.open_bi().await.expect("Should be able to create a bi directional connection"); - - tokio::spawn(async move { + let (mut send_stream, recv_stream) = connection.open_bi().await.expect("Should be able to create a bi directional connection"); + send_stream.write_all(b"connect").await.unwrap(); + // let jh = tokio::spawn(async move { // wait for 10 s max let mut buffer: [u8; PACKET_DATA_SIZE] = [0; PACKET_DATA_SIZE]; let mut recv_stream = recv_stream; loop { - if let Ok(Some(size)) = recv_stream.read(&mut buffer ).await + let res = recv_stream.read(&mut buffer ).await; + match res { - let data = &buffer[0..size]; - if let Ok(result) = bincode::deserialize::(&data) { - println!("Transaction Result \n s:{} e:{} slt:{}", result.signature, result.error.map(|x| x.to_string()).unwrap_or_default(), result.slot); + Ok(Some(size)) => { + let data = &buffer[0..size]; + if let Ok(result) = bincode::deserialize::(&data) { + println!("Transaction Result \n s:{} e:{} slt:{}", result.signature, result.error.map(|x| x.to_string()).unwrap_or_default(), result.slot); + } + }, + Ok(None) => { + log::warn!("got ok none"); + }, + Err(e) => { + log::error!("got error {e:?}"); + break; } } } - }); + // }); + // jh.await.unwrap(); Ok(()) } diff --git a/client/src/skip_server_verification.rs b/client/src/skip_server_verification.rs index b16bf5f..496aa7c 100644 --- a/client/src/skip_server_verification.rs +++ b/client/src/skip_server_verification.rs @@ -1,14 +1,5 @@ -use std::sync::Arc; - - pub struct SkipServerVerification; -impl SkipServerVerification { - pub fn new() -> Arc { - Arc::new(Self) - } -} - impl rustls::client::ServerCertVerifier for SkipServerVerification { fn verify_server_cert( &self, diff --git a/config.json b/config.json index a27e48d..8cfa129 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,5 @@ { - "libpath": "../target/debug/libgeyser_quic_plugin.so", + "libpath": "target/debug/libgeyser_quic_plugin.so", "quic_plugin": { "address": "0.0.0.0:11000" } diff --git a/plugin/Cargo.toml b/plugin/Cargo.toml index f6d77a8..5d8cfc4 100644 --- a/plugin/Cargo.toml +++ b/plugin/Cargo.toml @@ -16,7 +16,6 @@ name = "config-check" tokio = { version = "1.21.2", features = ["rt-multi-thread", "macros", "time", "fs"] } solana-sdk = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.18" } solana-geyser-plugin-interface = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.18" } -solana-streamer = { git = "https://github.com/blockworks-foundation/solana.git", branch = "geyser_send_transaction_results_v1.16.18" } itertools = "0.10.5" serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0.96" @@ -28,7 +27,6 @@ futures = "0.3.28" bytes = "1.4.0" anyhow = "1.0.70" log = "0.4.17" -clap = { version = "4.2.4", features = ["derive", "env"] } dashmap = "5.4.0" const_env = "0.1.2" jsonrpsee = { version = "0.17.0", features = ["macros", "full"] } @@ -41,11 +39,16 @@ prometheus = "0.13.3" lazy_static = "1.4.0" dotenv = "0.15.0" async-channel = "1.8.0" -quinn = "0.9.3" -rustls = { version = "=0.20.8", default-features = false } +quinn = "0.10.2" +rustls = { version = "0.21.8", default-features = false, features = ["quic", "dangerous_configuration"] } rcgen = "0.10.0" pkcs8 = "0.8.0" pem = "1.1.1" +x509-parser = "0.14.0" +clap = { version = "=4.3.24", features = ["cargo", "derive"] } +anstyle = "=1.0.0" +anstyle-parse = "=0.2.0" +clap_lex = "=0.5.0" [build-dependencies] anyhow = "1.0.62" diff --git a/plugin/src/lib.rs b/plugin/src/lib.rs index 6c272b3..84ae3e4 100644 --- a/plugin/src/lib.rs +++ b/plugin/src/lib.rs @@ -1,10 +1,10 @@ use std::{ net::{IpAddr, Ipv4Addr, UdpSocket}, str::FromStr, - sync::Arc, + sync::{Arc, atomic::AtomicBool}, }; -use crate::config::Config; +use crate::{config::Config, tls_certificate::new_self_signed_tls_certificate}; use itertools::Itertools; use pem::Pem; use quinn::{Endpoint, EndpointConfig, IdleTimeout, ServerConfig, TokioRuntime}; @@ -20,16 +20,14 @@ use solana_sdk::{ slot_history::Slot, transaction::{SanitizedTransaction, TransactionError}, compute_budget::{self, ComputeBudgetInstruction}, borsh0_10::try_from_slice_unchecked, }; -use solana_streamer::{ - quic::QuicServerError, - tls_certificates::{get_pubkey_from_tls_certificate, new_self_signed_tls_certificate}, -}; +use tls_certificate::get_pubkey_from_tls_certificate; use tokio::{runtime::Runtime, sync::mpsc::UnboundedSender, task::JoinHandle}; use crate::skip_client_verification::SkipClientVerification; pub mod skip_client_verification; pub mod config; +pub mod tls_certificate; pub const ALPN_GEYSER_PROTOCOL_ID: &[u8] = b"solana-geyser"; @@ -78,9 +76,10 @@ pub struct PluginInner { pub runtime: Runtime, pub handle: JoinHandle<()>, pub sender: Arc>, + pub start_sending: Arc, } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct Plugin { inner: Option, } @@ -102,6 +101,12 @@ impl GeyserPlugin for Plugin { slot: Slot, ) -> PluginResult<()> { if let Some(inner) = &self.inner { + if !inner.start_sending.load(std::sync::atomic::Ordering::Relaxed) { + return Ok(()) + } + if transaction.is_simple_vote_transaction() { + return Ok(()) + } let message = transaction.message(); let accounts = message.account_keys(); @@ -124,7 +129,7 @@ impl GeyserPlugin for Plugin { cu_requested, prioritization_fees, }) { - log::error!("error sending on the channel {}", e); + log::error!("error sending on the channel {e:?}"); } Ok(()) } else { @@ -140,61 +145,68 @@ impl GeyserPlugin for Plugin { let runtime = Runtime::new().map_err(|error| GeyserPluginError::Custom(Box::new(error)))?; let res = configure_server(&Keypair::new(), IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))); - let (config, _) = res.map_err(|error| GeyserPluginError::Custom(Box::new(error)))?; + let (config, _) = res.map_err(|_| GeyserPluginError::TransactionUpdateError { msg: "error configuring server".to_string() })?; let sock = UdpSocket::bind(plugin_config.quic_plugin.address).expect("couldn't bind to address"); - let endpoint = Endpoint::new(EndpointConfig::default(), Some(config), sock, TokioRuntime) - .map_err(|error| GeyserPluginError::Custom(Box::new(error)))?; + let (sender, reciever) = tokio::sync::mpsc::unbounded_channel::(); let allowed_connection = Pubkey::from_str("G8pLuvzarejjLuuPNVNR1gk9xiFKmAcs9J5LL3GZGM6F").unwrap(); + let start_sending = Arc::new(AtomicBool::new(false)); + let start_sending_cp = start_sending.clone(); - let handle = tokio::spawn(async move { + let handle = runtime.block_on(async move { let mut reciever = reciever; - loop { - let connecting = endpoint.accept().await; - if let Some(connecting) = connecting { - let connected = connecting.await; - let connection = match connected { - Ok(connection) => connection, - Err(e) => { - log::error!("geyser plugin connecting {} error", e); + let endpoint = Endpoint::new(EndpointConfig::default(), Some(config), sock, Arc::new(TokioRuntime)).expect("Should be able to create endpoint"); + tokio::spawn(async move { + loop { + let connecting = endpoint.accept().await; + if let Some(connecting) = connecting { + let connected = connecting.await; + let connection = match connected { + Ok(connection) => connection, + Err(e) => { + log::error!("geyser plugin connecting {} error", e); + continue; + } + }; + let connection_identity = get_remote_pubkey(&connection); + if let Some(connection_identity) = connection_identity { + if !allowed_connection.eq(&connection_identity) { + // not an authorized connection + continue; + } + } else { continue; } - }; - let connection_identity = get_remote_pubkey(&connection); - if let Some(connection_identity) = connection_identity { - if !allowed_connection.eq(&connection_identity) { - // not an authorized connection - continue; - } - } else { - continue; - } - let (mut send_stream, _) = match connection.accept_bi().await { - Ok(res) => res, - Err(e) => { - log::error!("geyser plugin accepting bi-channel {} error", e); - continue; - } - }; + let (mut send_stream, _) = match connection.accept_bi().await { + Ok(res) => res, + Err(e) => { + log::error!("geyser plugin accepting bi-channel {} error", e); + continue; + } + }; - while let Some(msg) = reciever.recv().await { - let bytes = bincode::serialize(&msg).unwrap_or(vec![]); - if !bytes.is_empty() { - if let Err(e) = send_stream.write_all(&bytes).await { - log::error!("error writing on stream channel {}", e); + start_sending_cp.store(true, std::sync::atomic::Ordering::Relaxed); + while let Some(msg) = reciever.recv().await { + let bytes = bincode::serialize(&msg).unwrap_or(vec![]); + if !bytes.is_empty() { + if let Err(e) = send_stream.write_all(&bytes).await { + log::error!("error writing on stream channel {}", e); + } } } + start_sending_cp.store(false, std::sync::atomic::Ordering::Relaxed); } } - } + }) }); self.inner = Some(PluginInner { runtime, handle, sender: Arc::new(sender), + start_sending, }); Ok(()) } @@ -205,7 +217,7 @@ impl GeyserPlugin for Plugin { pub(crate) fn configure_server( identity_keypair: &Keypair, host: IpAddr, -) -> Result<(ServerConfig, String), QuicServerError> { +) -> anyhow::Result<(ServerConfig, String)> { let (cert, priv_key) = new_self_signed_tls_certificate(identity_keypair, host)?; let cert_chain_pem_parts = vec![Pem { tag: "CERTIFICATE".to_string(), @@ -223,15 +235,15 @@ pub(crate) fn configure_server( server_config.use_retry(true); let config = Arc::get_mut(&mut server_config.transport).unwrap(); - config.max_concurrent_uni_streams((0 as u32).into()); - let recv_size = (PACKET_DATA_SIZE as u32).into(); + config.max_concurrent_uni_streams((1 as u32).into()); + let recv_size = (PACKET_DATA_SIZE as u32 * 100).into(); config.stream_receive_window(recv_size); config.receive_window(recv_size); let timeout = IdleTimeout::try_from(QUIC_MAX_TIMEOUT).unwrap(); config.max_idle_timeout(Some(timeout)); // disable bidi & datagrams - const MAX_CONCURRENT_BIDI_STREAMS: u32 = 1; + const MAX_CONCURRENT_BIDI_STREAMS: u32 = 10; config.max_concurrent_bidi_streams(MAX_CONCURRENT_BIDI_STREAMS.into()); config.datagram_receive_buffer_size(None); @@ -248,3 +260,11 @@ pub fn get_remote_pubkey(connection: &quinn::Connection) -> Option { .first() .and_then(get_pubkey_from_tls_certificate) } + +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub unsafe extern "C" fn _create_plugin() -> *mut dyn GeyserPlugin { + let plugin = Plugin::default(); + let plugin: Box = Box::new(plugin); + Box::into_raw(plugin) +} diff --git a/plugin/src/skip_client_verification.rs b/plugin/src/skip_client_verification.rs index 878c0b9..03ce778 100644 --- a/plugin/src/skip_client_verification.rs +++ b/plugin/src/skip_client_verification.rs @@ -1,6 +1,6 @@ use std::{sync::Arc, time::SystemTime}; -use rustls::{server::ClientCertVerified, Certificate, DistinguishedNames}; +use rustls::{server::ClientCertVerified, Certificate, DistinguishedName}; pub struct SkipClientVerification; @@ -11,8 +11,8 @@ impl SkipClientVerification { } impl rustls::server::ClientCertVerifier for SkipClientVerification { - fn client_auth_root_subjects(&self) -> Option { - Some(DistinguishedNames::new()) + fn client_auth_root_subjects(&self) -> &[DistinguishedName] { + &[] } fn verify_client_cert( diff --git a/plugin/src/tls_certificate.rs b/plugin/src/tls_certificate.rs new file mode 100644 index 0000000..67fecef --- /dev/null +++ b/plugin/src/tls_certificate.rs @@ -0,0 +1,53 @@ +use std::net::IpAddr; + +use pkcs8::{AlgorithmIdentifier, ObjectIdentifier, der::Document}; +use rcgen::{RcgenError, CertificateParams, SanType, DistinguishedName, DnType}; +use solana_sdk::{signature::Keypair, pubkey::Pubkey}; +use x509_parser::{prelude::{X509Certificate, FromDer}, public_key::PublicKey}; + +pub fn new_self_signed_tls_certificate( + keypair: &Keypair, + san: IpAddr, +) -> Result<(rustls::Certificate, rustls::PrivateKey), RcgenError> { + const ED25519_IDENTIFIER: [u32; 4] = [1, 3, 101, 112]; + let mut private_key = Vec::::with_capacity(34); + private_key.extend_from_slice(&[0x04, 0x20]); // ASN.1 OCTET STRING + private_key.extend_from_slice(keypair.secret().as_bytes()); + let key_pkcs8 = pkcs8::PrivateKeyInfo { + algorithm: AlgorithmIdentifier { + oid: ObjectIdentifier::from_arcs(&ED25519_IDENTIFIER).expect("Failed to convert OID"), + parameters: None, + }, + private_key: &private_key, + public_key: None, + }; + let key_pkcs8_der = key_pkcs8 + .to_der() + .expect("Failed to convert keypair to DER") + .to_der(); + + let rcgen_keypair = rcgen::KeyPair::from_der(&key_pkcs8_der)?; + + let mut cert_params = CertificateParams::default(); + cert_params.subject_alt_names = vec![SanType::IpAddress(san)]; + cert_params.alg = &rcgen::PKCS_ED25519; + cert_params.key_pair = Some(rcgen_keypair); + cert_params.distinguished_name = DistinguishedName::new(); + cert_params + .distinguished_name + .push(DnType::CommonName, "Solana node"); + + let cert = rcgen::Certificate::from_params(cert_params)?; + let cert_der = cert.serialize_der().unwrap(); + let priv_key = cert.serialize_private_key_der(); + let priv_key = rustls::PrivateKey(priv_key); + Ok((rustls::Certificate(cert_der), priv_key)) +} + +pub fn get_pubkey_from_tls_certificate(der_cert: &rustls::Certificate) -> Option { + let (_, cert) = X509Certificate::from_der(der_cert.as_ref()).ok()?; + match cert.public_key().parsed().ok()? { + PublicKey::Unknown(key) => Pubkey::try_from(key).ok(), + _ => None, + } +} \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml index e3f5a5f..4de7796 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.73.0" +channel = "1.69.0" components = ["clippy", "rustfmt"] targets = [] profile = "minimal" \ No newline at end of file