From 88f7d8b42d21425dfa675c6fbe8493f87dc6b3b6 Mon Sep 17 00:00:00 2001 From: Jesse Schulman Date: Wed, 7 Aug 2024 16:45:00 -0700 Subject: [PATCH] Creating telos-reth binary which uses TelosNode from the telos crate --- Cargo.lock | 452 +++++++++++++++++++++++++++++---- Cargo.toml | 7 + bin/reth/Cargo.toml | 19 ++ bin/reth/src/main.rs | 2 +- bin/reth/src/telos.rs | 50 ++++ crates/telos/node/Cargo.toml | 36 +++ crates/telos/node/src/args.rs | 47 ++++ crates/telos/node/src/lib.rs | 166 ++++++++++++ crates/telos/node/src/node.rs | 75 ++++++ crates/telos/rpc/Cargo.toml | 21 ++ crates/telos/rpc/src/client.rs | 102 ++++++++ crates/telos/rpc/src/lib.rs | 3 + 12 files changed, 928 insertions(+), 52 deletions(-) create mode 100644 bin/reth/src/telos.rs create mode 100644 crates/telos/node/Cargo.toml create mode 100644 crates/telos/node/src/args.rs create mode 100644 crates/telos/node/src/lib.rs create mode 100644 crates/telos/node/src/node.rs create mode 100644 crates/telos/rpc/Cargo.toml create mode 100644 crates/telos/rpc/src/client.rs create mode 100644 crates/telos/rpc/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d3447ba7f5531..eba828cc3bc3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,7 +314,7 @@ dependencies = [ "futures-utils-wasm", "lru", "pin-project", - "reqwest", + "reqwest 0.12.5", "serde", "serde_json", "tokio", @@ -377,7 +377,7 @@ dependencies = [ "alloy-transport-ws", "futures", "pin-project", - "reqwest", + "reqwest 0.12.5", "serde", "serde_json", "tokio", @@ -656,7 +656,7 @@ checksum = "2437d145d80ea1aecde8574d2058cceb8b3c9cba05f6aea8e67907c660d46698" dependencies = [ "alloy-json-rpc", "alloy-transport", - "reqwest", + "reqwest 0.12.5", "serde_json", "tower", "tracing", @@ -691,7 +691,7 @@ dependencies = [ "alloy-pubsub", "alloy-transport", "futures", - "http", + "http 1.1.0", "rustls", "serde_json", "tokio", @@ -790,6 +790,48 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "antelope-client" +version = "0.2.1" +source = "git+https://github.com/telosnetwork/antelope-rs?branch=finish_table_rows_params#c8d60b2f465f53c0245b615e6f76070755a8a587" +dependencies = [ + "antelope-client-macros", + "async-trait", + "base64 0.21.7", + "bs58", + "chrono", + "digest 0.10.7", + "ecdsa", + "flate2", + "hex", + "hmac 0.12.1", + "k256", + "log", + "once_cell", + "p256", + "rand 0.8.5", + "rand_core 0.6.4", + "reqwest 0.11.27", + "ripemd", + "serde", + "serde-big-array", + "serde_json", + "sha2 0.10.8", + "signature", + "thiserror", + "tokio", +] + +[[package]] +name = "antelope-client-macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe146e985f20989c1c9e9aca87f854ba430b5a5fadaac3f115bc9f81619634" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "anyhow" version = "1.0.86" @@ -2346,6 +2388,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] @@ -2614,6 +2657,8 @@ dependencies = [ "ff", "generic-array", "group", + "hkdf", + "pem-rfc7468", "pkcs8", "rand_core 0.6.4", "sec1", @@ -2627,6 +2672,15 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + [[package]] name = "endian-type" version = "0.1.2" @@ -2744,7 +2798,7 @@ dependencies = [ "clap", "eyre", "futures-util", - "reqwest", + "reqwest 0.12.5", "reth", "reth-node-ethereum", "serde", @@ -3138,6 +3192,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" @@ -3347,7 +3416,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http", + "http 1.1.0", "js-sys", "pin-project", "serde", @@ -3394,6 +3463,25 @@ dependencies = [ "subtle", ] +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.3.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.5" @@ -3405,7 +3493,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.1.0", "indexmap 2.3.0", "slab", "tokio", @@ -3554,6 +3642,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -3565,6 +3664,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.1" @@ -3572,7 +3682,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -3583,8 +3693,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -3648,6 +3758,30 @@ dependencies = [ "serde", ] +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.4.1" @@ -3657,9 +3791,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -3676,8 +3810,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", - "http", - "hyper", + "http 1.1.0", + "hyper 1.4.1", "hyper-util", "log", "rustls", @@ -3689,6 +3823,19 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.30", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "hyper-util" version = "0.1.6" @@ -3698,9 +3845,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", "pin-project-lite", "socket2 0.5.7", "tokio", @@ -4204,7 +4351,7 @@ dependencies = [ "futures-channel", "futures-util", "gloo-net", - "http", + "http 1.1.0", "jsonrpsee-core", "pin-project", "rustls", @@ -4229,8 +4376,8 @@ dependencies = [ "bytes", "futures-timer", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", "jsonrpsee-types", "parking_lot 0.12.3", @@ -4254,8 +4401,8 @@ checksum = "4d5f8f6ddb09312a9592ec9e21a3ccd6f61e51730d9d56321351eff971b0fe55" dependencies = [ "async-trait", "base64 0.22.1", - "http-body", - "hyper", + "http-body 1.0.1", + "hyper 1.4.1", "hyper-rustls", "hyper-util", "jsonrpsee-core", @@ -4291,10 +4438,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85bf179199ad809157ceaab653f71cdb67f55d9e0093a6907c5765414a6b3bbb" dependencies = [ "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.4.1", "hyper-util", "jsonrpsee-core", "jsonrpsee-types", @@ -4317,7 +4464,7 @@ version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98deeee954567f75632fa40666ac93a66d4f9f4ed4ca15bd6b7ed0720b53e761" dependencies = [ - "http", + "http 1.1.0", "serde", "serde_json", "thiserror", @@ -4340,7 +4487,7 @@ version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385cf0a6103a9f64987cdf0f7c9d0b08e1d7183dd952820beffb3676e7df7787" dependencies = [ - "http", + "http 1.1.0", "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", @@ -4833,7 +4980,7 @@ dependencies = [ "futures-util", "http-types", "pin-project-lite", - "reqwest", + "reqwest 0.12.5", "serde", "serde_json", "thiserror", @@ -5004,6 +5151,23 @@ dependencies = [ "unsigned-varint 0.7.2", ] +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nibble_vec" version = "0.1.0" @@ -5254,12 +5418,50 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +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.72", +] + [[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.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -5419,6 +5621,15 @@ dependencies = [ "serde", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -6156,6 +6367,46 @@ dependencies = [ "memchr", ] +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.50.0", +] + [[package]] name = "reqwest" version = "0.12.5" @@ -6166,10 +6417,10 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.4.1", "hyper-rustls", "hyper-util", "ipnet", @@ -6182,12 +6433,12 @@ dependencies = [ "quinn", "rustls", "rustls-native-certs", - "rustls-pemfile", + "rustls-pemfile 2.1.3", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tokio-rustls", "tokio-util", @@ -6216,6 +6467,7 @@ name = "reth" version = "1.0.4" dependencies = [ "alloy-rlp", + "antelope-client", "aquamarine", "backon", "clap", @@ -6259,6 +6511,7 @@ dependencies = [ "reth-node-events", "reth-node-metrics", "reth-node-optimism", + "reth-node-telos", "reth-optimism-cli", "reth-optimism-primitives", "reth-payload-builder", @@ -6280,6 +6533,7 @@ dependencies = [ "reth-static-file", "reth-static-file-types", "reth-tasks", + "reth-telos-rpc", "reth-tracing", "reth-transaction-pool", "reth-trie", @@ -6412,7 +6666,7 @@ dependencies = [ "eyre", "futures", "libc", - "reqwest", + "reqwest 0.12.5", "reth-cli-runner", "reth-db", "reth-node-api", @@ -6690,7 +6944,7 @@ dependencies = [ "auto_impl", "eyre", "futures", - "reqwest", + "reqwest 0.12.5", "reth-node-api", "reth-node-core", "reth-rpc-api", @@ -7483,7 +7737,7 @@ name = "reth-net-nat" version = "1.0.4" dependencies = [ "futures-util", - "reqwest", + "reqwest 0.12.5", "reth-tracing", "serde_with", "thiserror", @@ -7828,7 +8082,7 @@ name = "reth-node-metrics" version = "1.0.4" dependencies = [ "eyre", - "http", + "http 1.1.0", "jsonrpsee", "metrics", "metrics-exporter-prometheus", @@ -7836,7 +8090,7 @@ dependencies = [ "metrics-util", "once_cell", "procfs", - "reqwest", + "reqwest 0.12.5", "reth-chainspec", "reth-db", "reth-db-api", @@ -7863,7 +8117,7 @@ dependencies = [ "jsonrpsee", "jsonrpsee-types", "parking_lot 0.12.3", - "reqwest", + "reqwest 0.12.5", "reth", "reth-auto-seal-consensus", "reth-basic-payload-builder", @@ -7901,6 +8155,30 @@ dependencies = [ "tracing", ] +[[package]] +name = "reth-node-telos" +version = "1.0.4" +dependencies = [ + "antelope-client", + "clap", + "reth-auto-seal-consensus", + "reth-basic-payload-builder", + "reth-beacon-consensus", + "reth-ethereum-engine-primitives", + "reth-evm-ethereum", + "reth-network", + "reth-node-api", + "reth-node-builder", + "reth-node-ethereum", + "reth-payload-builder", + "reth-primitives", + "reth-provider", + "reth-rpc", + "reth-tracing", + "reth-transaction-pool", + "serde", +] + [[package]] name = "reth-optimism-cli" version = "1.0.4" @@ -8241,9 +8519,9 @@ dependencies = [ "async-trait", "derive_more", "futures", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", "jsonrpsee", "jsonrpsee-types", "jsonwebtoken", @@ -8321,7 +8599,7 @@ name = "reth-rpc-builder" version = "1.0.4" dependencies = [ "clap", - "http", + "http 1.1.0", "jsonrpsee", "metrics", "pin-project", @@ -8470,11 +8748,11 @@ name = "reth-rpc-layer" version = "1.0.4" dependencies = [ "alloy-rpc-types-engine", - "http", + "http 1.1.0", "jsonrpsee", "jsonrpsee-http-client", "pin-project", - "reqwest", + "reqwest 0.12.5", "tokio", "tower", "tracing", @@ -8700,6 +8978,17 @@ dependencies = [ "tracing-futures", ] +[[package]] +name = "reth-telos-rpc" +version = "1.0.4" +dependencies = [ + "antelope-client", + "async-trait", + "reth-node-telos", + "reth-rpc-eth-api", + "reth-rpc-eth-types", +] + [[package]] name = "reth-testing-utils" version = "1.0.4" @@ -9180,12 +9469,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 2.1.3", "rustls-pki-types", "schannel", "security-framework", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + [[package]] name = "rustls-pemfile" version = "2.1.3" @@ -9437,6 +9735,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.15" @@ -9787,7 +10094,7 @@ dependencies = [ "base64 0.22.1", "bytes", "futures", - "http", + "http 1.1.0", "httparse", "log", "rand 0.8.5", @@ -9958,6 +10265,12 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "sync_wrapper" version = "1.0.1" @@ -9989,6 +10302,27 @@ dependencies = [ "windows 0.52.0", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -10277,6 +10611,16 @@ dependencies = [ "syn 2.0.72", ] +[[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.0" @@ -10409,8 +10753,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", "http-range-header", "httpdate", @@ -10645,7 +10989,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 1.1.0", "httparse", "log", "rand 0.8.5", @@ -10831,6 +11175,12 @@ 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 = "vergen" version = "8.3.2" diff --git a/Cargo.toml b/Cargo.toml index 0eeb57e5dd987..f6f104d52bb99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,6 +112,8 @@ members = [ "crates/storage/provider/", "crates/storage/storage-api/", "crates/tasks/", + "crates/telos/node", + "crates/telos/rpc", "crates/tokio-util/", "crates/tracing/", "crates/transaction-pool/", @@ -540,3 +542,8 @@ serial_test = "3" similar-asserts = "1.5.0" tempfile = "3.8" test-fuzz = "5" + +# telos +reth-node-telos = { path = "crates/telos/node" } +reth-telos-rpc = { path = "crates/telos/rpc" } +antelope-client = { git = "https://github.com/telosnetwork/antelope-rs", branch = "finish_table_rows_params" } diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index 3623f31dbcaff..e0af1f5633fe7 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -110,6 +110,11 @@ itertools.workspace = true # p2p discv5.workspace = true +# telos +reth-node-telos = { workspace = true, optional = true } +reth-telos-rpc = { workspace = true, optional = true } +antelope-client = { workspace = true, optional = true } + [target.'cfg(unix)'.dependencies] tikv-jemallocator = { version = "0.5.0", optional = true } libc = "0.2" @@ -148,6 +153,15 @@ optimism = [ # no-op feature flag for switching between the `optimism` and default functionality in CI matrices ethereum = [] +telos = [ + "dep:antelope-client", + "dep:reth-node-telos", + "dep:reth-telos-rpc", +# "reth-rpc/telos", +# "reth-network/telos", +# "reth-node-core/telos", +] + [[bin]] name = "reth" path = "src/main.rs" @@ -160,3 +174,8 @@ path = "src/engine2.rs" name = "op-reth" path = "src/optimism.rs" required-features = ["optimism"] + +[[bin]] +name = "telos-reth" +path = "src/telos.rs" +required-features = ["telos"] diff --git a/bin/reth/src/main.rs b/bin/reth/src/main.rs index 4eacb9df3f2d5..34f7615c743f6 100644 --- a/bin/reth/src/main.rs +++ b/bin/reth/src/main.rs @@ -8,7 +8,7 @@ static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; #[cfg(all(feature = "optimism", not(test)))] compile_error!("Cannot build the `reth` binary with the `optimism` feature flag enabled. Did you mean to build `op-reth`?"); -#[cfg(not(feature = "optimism"))] +#[cfg(all(not(feature = "optimism"), not(feature = "telos")))] fn main() { use reth::cli::Cli; use reth_node_ethereum::EthereumNode; diff --git a/bin/reth/src/telos.rs b/bin/reth/src/telos.rs new file mode 100644 index 0000000000000..6e8e89b0ee151 --- /dev/null +++ b/bin/reth/src/telos.rs @@ -0,0 +1,50 @@ +#![allow(missing_docs)] + +use std::sync::Arc; +use clap::Parser; +use reth::cli::Cli; +use reth_node_telos::TelosArgs; +use reth_node_telos::TelosNode; +use reth_telos_rpc::TelosClient; + +// We use jemalloc for performance reasons. +#[cfg(all(feature = "jemalloc", unix))] +#[global_allocator] +static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; + +#[cfg(all(feature = "optimism", not(test)))] +compile_error!("Cannot build the `telos-reth` binary with the `optimism` feature flag enabled. Did you mean to build `op-reth`?"); + +#[cfg(feature = "telos")] +fn main() { + use reth::cli::Cli; + + reth_cli_util::sigsegv_handler::install(); + + // Enable backtraces unless a RUST_BACKTRACE value has already been explicitly provided. + if std::env::var_os("RUST_BACKTRACE").is_none() { + std::env::set_var("RUST_BACKTRACE", "1"); + } + + if let Err(err) = Cli::::parse().run(|builder, telos_args| async move { + let handle = builder + .node(TelosNode::new(telos_args.clone())) + .extend_rpc_modules(move |ctx| { + // register sequencer tx forwarder + if telos_args.telos_endpoint.is_some() { + ctx.registry.set_eth_raw_transaction_forwarder(Arc::new(TelosClient::new( + telos_args, + ))); + } + + Ok(()) + }) + .launch() + .await?; + + handle.node_exit_future.await + }) { + eprintln!("Error: {err:?}"); + std::process::exit(1); + } +} diff --git a/crates/telos/node/Cargo.toml b/crates/telos/node/Cargo.toml new file mode 100644 index 0000000000000..8f6467f470a3e --- /dev/null +++ b/crates/telos/node/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "reth-node-telos" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +antelope-client.workspace = true +reth-primitives.workspace = true + +reth-auto-seal-consensus.workspace = true +reth-basic-payload-builder.workspace = true +reth-beacon-consensus.workspace = true +reth-ethereum-engine-primitives.workspace = true +reth-evm-ethereum.workspace = true +reth-network.workspace = true +reth-node-api.workspace = true +reth-node-builder.workspace = true +reth-node-ethereum.workspace = true +reth-payload-builder.workspace = true +reth-provider.workspace = true +reth-rpc.workspace = true +reth-tracing.workspace = true +reth-transaction-pool.workspace = true + +clap.workspace = true +serde = { workspace = true, features = ["derive"] } + +[features] +telos = [] \ No newline at end of file diff --git a/crates/telos/node/src/args.rs b/crates/telos/node/src/args.rs new file mode 100644 index 0000000000000..514effae1d114 --- /dev/null +++ b/crates/telos/node/src/args.rs @@ -0,0 +1,47 @@ +//! clap [Args](clap::Args) for telos configuration + +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Default, PartialEq, Eq, clap::Args)] +#[clap(next_help_heading = "Telos")] +pub struct TelosArgs { + /// TelosZero endpoint to use for API calls (send_transaction, get gas price from table) + #[arg(long = "telos.telos_endpoint", value_name = "HTTP_URL")] + pub telos_endpoint: Option, + + /// Signer account name + #[arg(long = "telos.signer_account")] + pub signer_account: Option, + + /// Signer permission name + #[arg(long = "telos.signer_permission")] + pub signer_permission: Option, + + /// Signer private key + #[arg(long = "telos.signer_key")] + pub signer_key: Option, + + /// Seconds to cache gas price + #[arg(long = "telos.gas_cache_seconds")] + pub gas_cache_seconds: Option, +} + +#[cfg(test)] +mod tests { + use super::*; + use clap::{Args, Parser}; + + /// A helper type to parse Args more easily + #[derive(Parser)] + struct CommandParser { + #[clap(flatten)] + args: T, + } + + #[test] + fn test_parse_database_args() { + let default_args = TelosArgs::default(); + let args = CommandParser::::parse_from(["reth"]).args; + assert_eq!(args, default_args); + } +} \ No newline at end of file diff --git a/crates/telos/node/src/lib.rs b/crates/telos/node/src/lib.rs new file mode 100644 index 0000000000000..00b08bc9ed0b1 --- /dev/null +++ b/crates/telos/node/src/lib.rs @@ -0,0 +1,166 @@ +//! Standalone crate for Telos-specific Reth configuration and builder types. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/telosnetwork/telos-reth/issues/" +)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +#![cfg(feature = "telos")] + +use std::fmt::{Debug, Formatter}; +use antelope::api::client::{APIClient, DefaultProvider}; +use antelope::api::v1::structs::GetTableRowsParams; +use antelope::chain::action::{Action, PermissionLevel}; +use antelope::chain::checksum::{Checksum160, Checksum256}; +use antelope::chain::name::Name; +use antelope::chain::private_key::PrivateKey; +use antelope::chain::transaction::{SignedTransaction, Transaction}; +use antelope::serializer::{Decoder, Encoder, Packer}; +use antelope::{name, StructPacker}; +use reth_primitives::{TransactionSigned, U256}; +use std::time::{Duration, Instant}; + +pub mod args; +pub mod node; + +pub use crate::args::TelosArgs; +pub use crate::node::TelosNode; + + +/// Telos Network Config +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone, Default)] +pub struct TelosNetworkConfig { + pub api_client: APIClient, + pub signer_account: Name, + pub signer_permission: Name, + pub signer_key: PrivateKey, + pub gas_cache: GasPriceCache, +} + +#[derive(StructPacker)] +pub struct RawActionData { + pub ram_payer: Name, + pub tx: Vec, + pub estimate_gas: bool, + pub sender: Option, +} + +#[derive(Clone)] +pub struct GasPriceCache { + api_client: Box>, + gas_cache_duration: Duration, + value: Option<(U256, Instant)>, +} + +impl Debug for GasPriceCache { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "GasPriceCache duration: ") + } +} + +impl Default for GasPriceCache { + fn default() -> Self { + GasPriceCache { + api_client: Box::new(APIClient::::default_provider("https://example.com".into()).unwrap()), + gas_cache_duration: Duration::default(), + value: None + } + } +} + +#[derive(StructPacker, Default)] +struct TelosEVMConfig { + trx_index: u32, + last_block: u32, + gas_used_block: Checksum256, + gas_price: Checksum256, + revision: Option, +} + +impl GasPriceCache { + pub fn new(api_client: Box>, gas_cache_duration: Duration) -> Self { + GasPriceCache { api_client, gas_cache_duration, value: None } + } + + async fn load_value(&self) -> U256 { + let table_rows_params = GetTableRowsParams { + code: name!("eosio.evm"), + table: name!("config"), + scope: Some(name!("eosio.evm")), + lower_bound: None, + upper_bound: None, + limit: Some(1), + reverse: None, + index_position: None, + show_payer: None, + }; + let config_result = + self.api_client.v1_chain.get_table_rows::(table_rows_params).await.unwrap(); + + return U256::from_be_slice(&config_result.rows[0].gas_price.data); + } + + pub async fn get(&mut self) -> &U256 { + let now = Instant::now(); + if self.value.as_ref().map_or(true, |&(_, ref expiry)| *expiry <= now) { + let new_val = self.load_value(); // Call the hardcoded loader function + self.value = Some((new_val.await, now + self.gas_cache_duration)); + } + &self.value.as_ref().unwrap().0 + } +} + +pub async fn send_to_telos( + network_config: &TelosNetworkConfig, + trxs: &Vec, +) -> Result { + let get_info = network_config.api_client.v1_chain.get_info().await.unwrap(); + let trx_header = get_info.get_transaction_header(90); + let _trxs_results = trxs.iter().map(|trx| { + let trx_header = trx_header.clone(); + async move { + let mut trx_bytes = Vec::new(); + trx.encode_enveloped(&mut trx_bytes); + + let raw_action_data = RawActionData { + ram_payer: name!("eosio.evm"), + tx: trx_bytes, + estimate_gas: false, + sender: None, + }; + + let action = Action::new_ex( + name!("eosio.evm"), + name!("raw"), + vec![PermissionLevel::new( + network_config.signer_account, + network_config.signer_permission, + )], + raw_action_data, + ); + + let transaction = Transaction { + header: trx_header, + context_free_actions: vec![], + actions: vec![action], + extension: vec![], + }; + + let signed_telos_transaction = SignedTransaction { + transaction: transaction.clone(), + signatures: vec![network_config + .signer_key + .sign_message(&transaction.signing_data(&get_info.chain_id.data.to_vec()))], + context_free_data: vec![], + }; + + let result = network_config.api_client.v1_chain.send_transaction(signed_telos_transaction); + + result.await.unwrap().transaction_id + } + }); + Ok("Good".into()) +} \ No newline at end of file diff --git a/crates/telos/node/src/node.rs b/crates/telos/node/src/node.rs new file mode 100644 index 0000000000000..a3b7a6cfe1c88 --- /dev/null +++ b/crates/telos/node/src/node.rs @@ -0,0 +1,75 @@ +use reth_ethereum_engine_primitives::{EthBuiltPayload, EthEngineTypes, EthPayloadAttributes, EthPayloadBuilderAttributes}; +use reth_evm_ethereum::EthEvmConfig; +use reth_node_api::{FullNodeTypes, NodeTypes}; +use reth_node_builder::components::ComponentsBuilder; +use reth_node_builder::{Node, PayloadTypes}; +use reth_node_ethereum::EthereumNode; +use reth_node_ethereum::node::{EthereumAddOns, EthereumConsensusBuilder, EthereumExecutorBuilder, EthereumNetworkBuilder, EthereumPayloadBuilder, EthereumPoolBuilder}; +use crate::args::TelosArgs; + +/// Type configuration for a regular Telos node. +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +pub struct TelosNode { + /// Additional Telos args + pub args: TelosArgs, +} + +impl TelosNode { + /// Creates a new instance of the Telos node type. + pub const fn new(args: TelosArgs) -> Self { + Self { args } + } + + /// Returns a [`ComponentsBuilder`] configured for a regular Ethereum node. + pub fn components() -> ComponentsBuilder< + Node, + EthereumPoolBuilder, + EthereumPayloadBuilder, + EthereumNetworkBuilder, + EthereumExecutorBuilder, + EthereumConsensusBuilder, + > + where + Node: FullNodeTypes, + ::Engine: PayloadTypes< + BuiltPayload = EthBuiltPayload, + PayloadAttributes = EthPayloadAttributes, + PayloadBuilderAttributes = EthPayloadBuilderAttributes, + >, + { + ComponentsBuilder::default() + .node_types::() + .pool(EthereumPoolBuilder::default()) + .payload(EthereumPayloadBuilder::new(EthEvmConfig::default())) + .network(EthereumNetworkBuilder::default()) + .executor(EthereumExecutorBuilder::default()) + .consensus(EthereumConsensusBuilder::default()) + } +} + +impl NodeTypes for TelosNode { + type Primitives = (); + type Engine = EthEngineTypes; +} + +impl Node for TelosNode +where + N: FullNodeTypes, +{ + type ComponentsBuilder = ComponentsBuilder< + N, + EthereumPoolBuilder, + EthereumPayloadBuilder, + EthereumNetworkBuilder, + EthereumExecutorBuilder, + EthereumConsensusBuilder, + >; + + type AddOns = EthereumAddOns; + + fn components_builder(&self) -> Self::ComponentsBuilder { + Self::components() + } +} + diff --git a/crates/telos/rpc/Cargo.toml b/crates/telos/rpc/Cargo.toml new file mode 100644 index 0000000000000..c838f9998781a --- /dev/null +++ b/crates/telos/rpc/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "reth-telos-rpc" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +exclude.workspace = true + +[dependencies] +async-trait.workspace = true + +reth-rpc-eth-api.workspace = true +reth-rpc-eth-types.workspace = true + +antelope-client.workspace = true +reth-node-telos = { workspace = true, features = ["telos"] } + +[lints] +workspace = true diff --git a/crates/telos/rpc/src/client.rs b/crates/telos/rpc/src/client.rs new file mode 100644 index 0000000000000..522458b750419 --- /dev/null +++ b/crates/telos/rpc/src/client.rs @@ -0,0 +1,102 @@ +use std::sync::Arc; +use reth_rpc_eth_api::RawTransactionForwarder; +use reth_rpc_eth_types::error::{EthResult}; +use antelope::api::client::{APIClient, DefaultProvider}; +use antelope::chain::name::Name; +use antelope::chain::private_key::PrivateKey; +use antelope::{chain::{Packer, Encoder, Decoder}, name, StructPacker}; +use antelope::chain::action::{Action, PermissionLevel}; +use antelope::chain::checksum::Checksum160; +use antelope::chain::transaction::{SignedTransaction, Transaction}; +use reth_node_telos::TelosArgs; + +/// A client to interact with a Sequencer +#[derive(Debug, Clone)] +pub struct TelosClient { + inner: Arc, +} + +#[derive(Debug, Clone)] +struct TelosClientInner { + pub api_client: APIClient, + pub signer_account: Name, + pub signer_permission: Name, + pub signer_key: PrivateKey, +} + +#[derive(StructPacker)] +pub struct RawActionData { + pub ram_payer: Name, + pub tx: Vec, + pub estimate_gas: bool, + pub sender: Option, +} + +impl TelosClient { + /// Creates a new [`TelosClient`]. + pub fn new(telos_args: TelosArgs) -> Self { + if telos_args.telos_endpoint.is_none() || telos_args.signer_account.is_none() || telos_args.signer_permission.is_none() || telos_args.signer_key.is_none() { + panic!("Should not construct TelosClient without proper TelosArgs with telos_endpoint and signer args"); + } + let api_client = APIClient::::default_provider(telos_args.telos_endpoint.unwrap().into()).unwrap(); + let inner = TelosClientInner { + api_client, + signer_account: name!(&telos_args.signer_account.unwrap()), + signer_permission: name!(&telos_args.signer_permission.unwrap()), + signer_key: PrivateKey::from_str(&telos_args.signer_key.unwrap(), false).unwrap(), + }; + Self { inner: Arc::new(inner) } + } + + async fn send_to_telos(&self, tx: &[u8]) -> EthResult<()> { + let get_info = self.inner.api_client.v1_chain.get_info().await.unwrap(); + let trx_header = get_info.get_transaction_header(90); + let trx_header = trx_header.clone(); + let trx_bytes = tx.to_vec(); + + let raw_action_data = RawActionData { + ram_payer: name!("eosio.evm"), + tx: trx_bytes, + estimate_gas: false, + sender: None, + }; + + let action = Action::new_ex( + name!("eosio.evm"), + name!("raw"), + vec![PermissionLevel::new( + self.inner.signer_account, + self.inner.signer_permission, + )], + raw_action_data, + ); + + let transaction = Transaction { + header: trx_header, + context_free_actions: vec![], + actions: vec![action], + extension: vec![], + }; + + let signed_telos_transaction = SignedTransaction { + transaction: transaction.clone(), + signatures: vec![self.inner + .signer_key + .sign_message(&transaction.signing_data(&get_info.chain_id.data.to_vec()))], + context_free_data: vec![], + }; + + let result = self.inner.api_client.v1_chain.send_transaction(signed_telos_transaction); + + let _trx_id = result.await.unwrap().transaction_id; + Ok(()) + } +} + +#[async_trait::async_trait] +impl RawTransactionForwarder for TelosClient { + async fn forward_raw_transaction(&self, tx: &[u8]) -> EthResult<()> { + Self::send_to_telos(self, tx).await?; + Ok(()) + } +} \ No newline at end of file diff --git a/crates/telos/rpc/src/lib.rs b/crates/telos/rpc/src/lib.rs new file mode 100644 index 0000000000000..f8cdbc292a4f5 --- /dev/null +++ b/crates/telos/rpc/src/lib.rs @@ -0,0 +1,3 @@ +mod client; + +pub use crate::client::TelosClient; \ No newline at end of file