diff --git a/Cargo.lock b/Cargo.lock index 804f7400..af6e49e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -382,7 +382,7 @@ checksum = "003f46c54f22854a32b9cc7972660a476968008ad505427eabab49225309ec40" dependencies = [ "alloy-primitives 1.4.1", "alloy-sol-types 1.4.1", - "http", + "http 1.4.0", "serde", "serde_json", "thiserror 2.0.17", @@ -814,7 +814,7 @@ dependencies = [ "async-trait", "auto_impl", "either", - "elliptic-curve", + "elliptic-curve 0.13.8", "k256", "thiserror 2.0.17", ] @@ -1049,8 +1049,8 @@ dependencies = [ "alloy-pubsub", "alloy-transport", "futures", - "http", - "rustls", + "http 1.4.0", + "rustls 0.23.31", "serde_json", "tokio", "tokio-tungstenite", @@ -1679,7 +1679,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e2cdb6d5ed835199484bb92bb8b3edd526effe995c61732580439c1a67e2e9" dependencies = [ "base64 0.22.1", - "http", + "http 1.4.0", "log", "url", ] @@ -1711,6 +1711,48 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-config" +version = "1.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0149602eeaf915158e14029ba0c78dedb8c08d554b024d54c8f239aab46511d" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "hex", + "http 1.4.0", + "ring", + "time", + "tokio", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "aws-credential-types" +version = "1.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01c9521fa01558f750d183c8c68c81b0155b9d193a4ba7f84c36bd1b6d04a06" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + [[package]] name = "aws-lc-rs" version = "1.13.3" @@ -1734,6 +1776,372 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "aws-runtime" +version = "1.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce527fb7e53ba9626fc47824f25e256250556c40d8f81d27dd92aa38239d632" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http-body 0.4.6", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid", +] + +[[package]] +name = "aws-sdk-s3" +version = "1.116.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd4c10050aa905b50dc2a1165a9848d598a80c3a724d6f93b5881aa62235e4a5" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-checksums", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "bytes", + "fastrand", + "hex", + "hmac", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "lru 0.12.5", + "percent-encoding", + "regex-lite", + "sha2", + "tracing", + "url", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.90.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f18e53542c522459e757f81e274783a78f8c81acdfc8d1522ee8a18b5fb1c66" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.92.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532f4d866012ffa724a4385c82e8dd0e59f0ca0e600f3f22d4c03b6824b34e4a" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.94.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be6fbbfa1a57724788853a623378223fe828fc4c09b146c992f0c95b6256174" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c35452ec3f001e1f2f6db107b6373f1f48f05ec63ba2c5c9fa91f07dad32af11" +dependencies = [ + "aws-credential-types", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "crypto-bigint 0.5.5", + "form_urlencoded", + "hex", + "hmac", + "http 0.2.12", + "http 1.4.0", + "p256 0.11.1", + "percent-encoding", + "ring", + "sha2", + "subtle", + "time", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-async" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee19095c7c4dda59f1697d028ce704c24b2d33c6718790c7f1d5a3015b4107c" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-checksums" +version = "0.63.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87294a084b43d649d967efe58aa1f9e0adc260e13a6938eb904c0ae9b45824ae" +dependencies = [ + "aws-smithy-http", + "aws-smithy-types", + "bytes", + "crc-fast", + "hex", + "http 0.2.12", + "http-body 0.4.6", + "md-5", + "pin-project-lite", + "sha1", + "sha2", + "tracing", +] + +[[package]] +name = "aws-smithy-eventstream" +version = "0.60.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc12f8b310e38cad85cf3bef45ad236f470717393c613266ce0a89512286b650" +dependencies = [ + "aws-smithy-types", + "bytes", + "crc32fast", +] + +[[package]] +name = "aws-smithy-http" +version = "0.62.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826141069295752372f8203c17f28e30c464d22899a43a0c9fd9c458d469c88b" +dependencies = [ + "aws-smithy-eventstream", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "futures-util", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-http-client" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e62db736db19c488966c8d787f52e6270be565727236fd5579eaa301e7bc4a" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "h2 0.3.27", + "h2 0.4.12", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper 1.8.1", + "hyper-rustls 0.24.2", + "hyper-rustls 0.27.7", + "hyper-util", + "pin-project-lite", + "rustls 0.21.12", + "rustls 0.23.31", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.4", + "tower 0.5.2", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.61.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6864c190cbb8e30cf4b77b2c8f3b6dfffa697a09b7218d2f7cd3d4c4065a9f7" +dependencies = [ + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-observability" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f616c3f2260612fe44cede278bafa18e73e6479c4e393e2c4518cf2a9a228a" +dependencies = [ + "aws-smithy-runtime-api", +] + +[[package]] +name = "aws-smithy-query" +version = "0.60.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae5d689cf437eae90460e944a58b5668530d433b4ff85789e69d2f2a556e057d" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a392db6c583ea4a912538afb86b7be7c5d8887d91604f50eb55c262ee1b4a5f5" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-http-client", + "aws-smithy-observability", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "http-body 1.0.1", + "pin-project-lite", + "pin-utils", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab0d43d899f9e508300e587bf582ba54c27a452dd0a9ea294690669138ae14a2" +dependencies = [ + "aws-smithy-async", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.4.0", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-types" +version = "1.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905cb13a9895626d49cf2ced759b062d913834c7482c38e49557eac4e6193f01" +dependencies = [ + "base64-simd", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time", + "tokio", + "tokio-util", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.60.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11b2f670422ff42bf7065031e72b45bc52a3508bd089f743ea90731ca2b6ea57" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d79fb68e3d7fe5d4833ea34dc87d2e97d26d3086cb3da660bb6b1f76d98680b6" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "rustc_version 0.4.1", + "tracing", +] + [[package]] name = "axum" version = "0.7.9" @@ -1744,8 +2152,8 @@ dependencies = [ "axum-core 0.4.5", "bytes", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "itoa", "matchit 0.7.3", @@ -1771,10 +2179,10 @@ dependencies = [ "bytes", "form_urlencoded", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-util", "itoa", "matchit 0.8.4", @@ -1803,8 +2211,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", @@ -1822,8 +2230,8 @@ checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" dependencies = [ "bytes", "futures-core", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", @@ -1866,6 +2274,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base16ct" version = "0.2.0" @@ -1894,6 +2308,16 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + [[package]] name = "base64-url" version = "3.0.2" @@ -2267,16 +2691,16 @@ dependencies = [ "futures-util", "hex", "home", - "http", + "http 1.4.0", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-named-pipe", - "hyper-rustls", + "hyper-rustls 0.27.7", "hyper-util", "hyperlocal", "log", "pin-project-lite", - "rustls", + "rustls 0.23.31", "rustls-native-certs", "rustls-pemfile", "rustls-pki-types", @@ -2420,6 +2844,16 @@ dependencies = [ "serde", ] +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] + [[package]] name = "c-kzg" version = "2.1.5" @@ -2948,6 +3382,19 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc-fast" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ddc2d09feefeee8bd78101665bd8645637828fa9317f9f292496dbbd8c65ff3" +dependencies = [ + "crc", + "digest 0.10.7", + "rand 0.9.2", + "regex", + "rustversion", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -3042,6 +3489,18 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -3249,7 +3708,7 @@ dependencies = [ "alloy-sol-types 0.8.26", "chrono", "hex", - "p256", + "p256 0.13.2", "serde", "serde_json", "sha2", @@ -3275,6 +3734,16 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "der" version = "0.7.10" @@ -3614,19 +4083,31 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", + "der 0.7.10", "digest 0.10.7", - "elliptic-curve", - "rfc6979", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", "serdect", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -3635,8 +4116,8 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", - "signature", + "pkcs8 0.10.2", + "signature 2.2.0", ] [[package]] @@ -3675,22 +4156,42 @@ dependencies = [ "serde", ] +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct", - "crypto-bigint", + "base16ct 0.2.0", + "crypto-bigint 0.5.5", "digest 0.10.7", - "ff", + "ff 0.13.1", "generic-array", - "group", + "group 0.13.0", "pem-rfc7468", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1", + "sec1 0.7.3", "serdect", "subtle", "zeroize", @@ -3965,6 +4466,16 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "ff" version = "0.13.1" @@ -4212,7 +4723,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls", + "rustls 0.23.31", "rustls-pki-types", ] @@ -4353,7 +4864,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http", + "http 1.4.0", "js-sys", "pin-project", "serde", @@ -4399,17 +4910,47 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.1", "rand_core 0.6.4", "subtle", ] +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.12.1", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.12" @@ -4421,7 +4962,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.4.0", "indexmap 2.12.1", "slab", "tokio", @@ -4609,6 +5150,17 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f558a64ac9af88b5ba400d99b579451af0d39c6d360980045b91aac966d705e2" +[[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.4.0" @@ -4619,6 +5171,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" @@ -4626,7 +5189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.4.0", ] [[package]] @@ -4637,8 +5200,8 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -4682,6 +5245,30 @@ dependencies = [ "serde", ] +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.8.1" @@ -4692,9 +5279,9 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "h2", - "http", - "http-body", + "h2 0.4.12", + "http 1.4.0", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -4712,7 +5299,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" dependencies = [ "hex", - "hyper", + "hyper 1.8.1", "hyper-util", "pin-project-lite", "tokio", @@ -4720,21 +5307,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.32", + "log", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + [[package]] name = "hyper-rustls" version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http", - "hyper", + "http 1.4.0", + "hyper 1.8.1", "hyper-util", "log", - "rustls", + "rustls 0.23.31", "rustls-native-certs", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.4", "tower-service", "webpki-roots 1.0.4", ] @@ -4745,7 +5347,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper", + "hyper 1.8.1", "hyper-util", "pin-project-lite", "tokio", @@ -4760,7 +5362,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-util", "native-tls", "tokio", @@ -4779,14 +5381,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "http", - "http-body", - "hyper", + "http 1.4.0", + "http-body 1.0.1", + "hyper 1.8.1", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", @@ -4802,7 +5404,7 @@ checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" dependencies = [ "hex", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-util", "pin-project-lite", "tokio", @@ -4821,7 +5423,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.57.0", ] [[package]] @@ -5002,9 +5604,9 @@ dependencies = [ "attohttpc", "bytes", "futures", - "http", + "http 1.4.0", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-util", "log", "rand 0.9.2", @@ -5333,16 +5935,16 @@ dependencies = [ "futures-channel", "futures-util", "gloo-net", - "http", + "http 1.4.0", "jsonrpsee-core 0.26.0", "pin-project", - "rustls", + "rustls 0.23.31", "rustls-pki-types", "rustls-platform-verifier", "soketto", "thiserror 2.0.17", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.4", "tokio-util", "tracing", "url", @@ -5356,8 +5958,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "jsonrpsee-types 0.25.1", "parking_lot", @@ -5382,8 +5984,8 @@ dependencies = [ "bytes", "futures-timer", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "jsonrpsee-types 0.26.0", "parking_lot", @@ -5406,13 +6008,13 @@ version = "0.25.1" source = "git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff#f04afa740e55db60dce20d9839758792f035ffff" dependencies = [ "base64 0.22.1", - "http-body", - "hyper", - "hyper-rustls", + "http-body 1.0.1", + "hyper 1.8.1", + "hyper-rustls 0.27.7", "hyper-util", "jsonrpsee-core 0.25.1", "jsonrpsee-types 0.25.1", - "rustls", + "rustls 0.23.31", "rustls-platform-verifier", "serde", "serde_json", @@ -5429,13 +6031,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790bedefcec85321e007ff3af84b4e417540d5c87b3c9779b9e247d1bcc3dab8" dependencies = [ "base64 0.22.1", - "http-body", - "hyper", - "hyper-rustls", + "http-body 1.0.1", + "hyper 1.8.1", + "hyper-rustls 0.27.7", "hyper-util", "jsonrpsee-core 0.26.0", "jsonrpsee-types 0.26.0", - "rustls", + "rustls 0.23.31", "rustls-platform-verifier", "serde", "serde_json", @@ -5476,10 +6078,10 @@ version = "0.25.1" source = "git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff#f04afa740e55db60dce20d9839758792f035ffff" dependencies = [ "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-util", "jsonrpsee-core 0.25.1", "jsonrpsee-types 0.25.1", @@ -5503,10 +6105,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c51b7c290bb68ce3af2d029648148403863b982f138484a73f02a9dd52dbd7f" dependencies = [ "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-util", "jsonrpsee-core 0.26.0", "jsonrpsee-types 0.26.0", @@ -5528,7 +6130,7 @@ name = "jsonrpsee-types" version = "0.25.1" source = "git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff#f04afa740e55db60dce20d9839758792f035ffff" dependencies = [ - "http", + "http 1.4.0", "serde", "serde_json", "thiserror 2.0.17", @@ -5540,7 +6142,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc88ff4688e43cc3fa9883a8a95c6fa27aa2e76c96e610b737b6554d650d7fd5" dependencies = [ - "http", + "http 1.4.0", "serde", "serde_json", "thiserror 2.0.17", @@ -5564,7 +6166,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6fceceeb05301cc4c065ab3bd2fa990d41ff4eb44e4ca1b30fa99c057c3e79" dependencies = [ - "http", + "http 1.4.0", "jsonrpsee-client-transport", "jsonrpsee-core 0.26.0", "jsonrpsee-types 0.26.0", @@ -5594,12 +6196,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", "serdect", "sha2", - "signature", + "signature 2.2.0", ] [[package]] @@ -5940,7 +6542,7 @@ dependencies = [ "quinn", "rand 0.8.5", "ring", - "rustls", + "rustls 0.23.31", "socket2 0.5.10", "thiserror 2.0.17", "tokio", @@ -6041,8 +6643,8 @@ dependencies = [ "libp2p-identity", "rcgen", "ring", - "rustls", - "rustls-webpki", + "rustls 0.23.31", + "rustls-webpki 0.103.4", "thiserror 2.0.17", "x509-parser 0.17.0", "yasna", @@ -6311,6 +6913,16 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + [[package]] name = "memchr" version = "2.7.6" @@ -6365,8 +6977,8 @@ checksum = "dd7399781913e5393588a8d8c6a2867bf85fb38eaf2502fdce465aad2dc6f034" dependencies = [ "base64 0.22.1", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.8.1", + "hyper-rustls 0.27.7", "hyper-util", "indexmap 2.12.1", "ipnet", @@ -6386,8 +6998,8 @@ checksum = "2b166dea96003ee2531cf14833efedced545751d800f03535801d833313f8c15" dependencies = [ "base64 0.22.1", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.8.1", + "hyper-rustls 0.27.7", "hyper-util", "indexmap 2.12.1", "ipnet", @@ -7120,9 +7732,9 @@ dependencies = [ "futures", "futures-util", "hex", - "http", + "http 1.4.0", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-util", "jsonrpsee 0.26.0", "jsonrpsee-core 0.26.0", @@ -7142,6 +7754,7 @@ dependencies = [ "p2p", "parking_lot", "rand 0.9.2", + "rdkafka", "reqwest", "reth", "reth-basic-payload-builder", @@ -7205,6 +7818,7 @@ dependencies = [ "thiserror 1.0.69", "tikv-jemallocator", "time", + "tips-audit", "tips-core", "tokio", "tokio-tungstenite", @@ -7267,6 +7881,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-src" +version = "300.5.4+3.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" +dependencies = [ + "cc", +] + [[package]] name = "openssl-sys" version = "0.9.111" @@ -7275,6 +7898,7 @@ checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] @@ -7315,7 +7939,7 @@ checksum = "a8863faf2910030d139fb48715ad5ff2f35029fc5f244f6d5f689ddcf4d26253" dependencies = [ "async-trait", "bytes", - "http", + "http 1.4.0", "opentelemetry 0.28.0", "reqwest", "tracing", @@ -7329,7 +7953,7 @@ checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" dependencies = [ "async-trait", "bytes", - "http", + "http 1.4.0", "opentelemetry 0.31.0", "reqwest", ] @@ -7342,7 +7966,7 @@ checksum = "5bef114c6d41bea83d6dc60eb41720eedd0261a67af57b66dd2b84ac46c01d91" dependencies = [ "async-trait", "futures-core", - "http", + "http 1.4.0", "opentelemetry 0.28.0", "opentelemetry-http 0.28.0", "opentelemetry-proto 0.28.0", @@ -7362,7 +7986,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" dependencies = [ - "http", + "http 1.4.0", "opentelemetry 0.31.0", "opentelemetry-http 0.31.0", "opentelemetry-proto 0.31.0", @@ -7460,14 +8084,31 @@ dependencies = [ "num-traits", ] +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2", +] + [[package]] name = "p256" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "primeorder", "sha2", ] @@ -7756,14 +8397,24 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.10", + "spki 0.7.3", ] [[package]] @@ -7874,7 +8525,7 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.8", ] [[package]] @@ -8161,8 +8812,8 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", - "rustls", - "socket2 0.6.1", + "rustls 0.23.31", + "socket2 0.5.10", "thiserror 2.0.17", "tokio", "tracing", @@ -8181,7 +8832,7 @@ dependencies = [ "rand 0.9.2", "ring", "rustc-hash 2.1.1", - "rustls", + "rustls 0.23.31", "rustls-pki-types", "slab", "thiserror 2.0.17", @@ -8199,7 +8850,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.1", + "socket2 0.5.10", "tracing", "windows-sys 0.60.2", ] @@ -8378,6 +9029,38 @@ dependencies = [ "yasna", ] +[[package]] +name = "rdkafka" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b52c81ac3cac39c9639b95c20452076e74b8d9a71bc6fc4d83407af2ea6fff" +dependencies = [ + "futures-channel", + "futures-util", + "libc", + "log", + "rdkafka-sys", + "serde", + "serde_derive", + "serde_json", + "slab", + "tokio", +] + +[[package]] +name = "rdkafka-sys" +version = "4.9.0+2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5230dca48bc354d718269f3e4353280e188b610f7af7e2fcf54b7a79d5802872" +dependencies = [ + "libc", + "libz-sys", + "num_enum", + "openssl-sys", + "pkg-config", + "zstd-sys", +] + [[package]] name = "recvmsg" version = "1.0.0" @@ -8467,6 +9150,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d942b98df5e658f56f20d592c7f868833fe38115e65c33003d8cd224b0155da" + [[package]] name = "regex-syntax" version = "0.8.8" @@ -8495,12 +9184,12 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.12", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.8.1", + "hyper-rustls 0.27.7", "hyper-tls", "hyper-util", "js-sys", @@ -8510,7 +9199,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls", + "rustls 0.23.31", "rustls-native-certs", "rustls-pki-types", "serde", @@ -8519,7 +9208,7 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.26.4", "tokio-util", "tower 0.5.2", "tower-http", @@ -10136,7 +10825,7 @@ version = "1.9.3" source = "git+https://github.com/paradigmxyz/reth?tag=v1.9.3#27a8c0f5a6dfb27dea84c5751776ecabdd069646" dependencies = [ "eyre", - "http", + "http 1.4.0", "jsonrpsee-server 0.26.0", "metrics", "metrics-exporter-prometheus 0.16.2", @@ -10853,9 +11542,9 @@ dependencies = [ "derive_more", "dyn-clone", "futures", - "http", - "http-body", - "hyper", + "http 1.4.0", + "http-body 1.0.1", + "hyper 1.8.1", "itertools 0.14.0", "jsonrpsee 0.26.0", "jsonrpsee-types 0.26.0", @@ -10938,7 +11627,7 @@ dependencies = [ "alloy-network", "alloy-provider", "dyn-clone", - "http", + "http 1.4.0", "jsonrpsee 0.26.0", "metrics", "pin-project", @@ -11123,7 +11812,7 @@ version = "1.9.3" source = "git+https://github.com/paradigmxyz/reth?tag=v1.9.3#27a8c0f5a6dfb27dea84c5751776ecabdd069646" dependencies = [ "alloy-rpc-types-engine", - "http", + "http 1.4.0", "jsonrpsee-http-client 0.26.0", "pin-project", "tower 0.5.2", @@ -11739,7 +12428,7 @@ dependencies = [ "c-kzg", "cfg-if", "k256", - "p256", + "p256 0.13.2", "revm-primitives", "ripemd", "rug", @@ -11771,6 +12460,17 @@ dependencies = [ "serde", ] +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -11886,10 +12586,10 @@ dependencies = [ "dotenvy", "eyre", "futures", - "http", + "http 1.4.0", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.8.1", + "hyper-rustls 0.27.7", "hyper-util", "jsonrpsee 0.25.1", "lru 0.16.2", @@ -11905,7 +12605,7 @@ dependencies = [ "parking_lot", "paste", "reth-optimism-payload-builder", - "rustls", + "rustls 0.23.31", "serde", "serde_json", "sha2", @@ -12078,6 +12778,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + [[package]] name = "rustls" version = "0.23.31" @@ -12089,7 +12801,7 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.4", "subtle", "zeroize", ] @@ -12136,10 +12848,10 @@ dependencies = [ "jni", "log", "once_cell", - "rustls", + "rustls 0.23.31", "rustls-native-certs", "rustls-platform-verifier-android", - "rustls-webpki", + "rustls-webpki 0.103.4", "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs 0.26.11", @@ -12152,6 +12864,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.4" @@ -12270,16 +12992,40 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct", - "der", + "base16ct 0.2.0", + "der 0.7.10", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "serdect", "subtle", "zeroize", @@ -12582,7 +13328,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "base16ct", + "base16ct 0.2.0", "serde", ] @@ -12688,6 +13434,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "signature" version = "2.2.0" @@ -12820,7 +13576,7 @@ dependencies = [ "base64 0.22.1", "bytes", "futures", - "http", + "http 1.4.0", "httparse", "log", "rand 0.8.5", @@ -12833,6 +13589,16 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + [[package]] name = "spki" version = "0.7.3" @@ -12840,7 +13606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.10", ] [[package]] @@ -13354,17 +14120,47 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tips-audit" +version = "0.1.0" +source = "git+https://github.com/base/tips?rev=d571797179fd0cc9e932373ba9a4eb5c2be0c0c9#d571797179fd0cc9e932373ba9a4eb5c2be0c0c9" +dependencies = [ + "alloy-consensus", + "alloy-primitives 1.4.1", + "alloy-provider", + "anyhow", + "async-trait", + "aws-config", + "aws-credential-types", + "aws-sdk-s3", + "bytes", + "clap", + "dotenvy", + "op-alloy-consensus", + "rdkafka", + "serde", + "serde_json", + "tips-core", + "tokio", + "tracing", + "tracing-subscriber 0.3.20", + "uuid", +] + [[package]] name = "tips-core" version = "0.1.0" -source = "git+https://github.com/base/tips?rev=c08eaa4fe10c26de8911609b41ddab4918698325#c08eaa4fe10c26de8911609b41ddab4918698325" +source = "git+https://github.com/base/tips?rev=d571797179fd0cc9e932373ba9a4eb5c2be0c0c9#d571797179fd0cc9e932373ba9a4eb5c2be0c0c9" dependencies = [ "alloy-consensus", "alloy-primitives 1.4.1", "alloy-provider", + "alloy-rpc-types", "alloy-serde", + "alloy-signer-local", "op-alloy-consensus", "op-alloy-flz", + "op-alloy-rpc-types", "serde", "tracing", "tracing-subscriber 0.3.20", @@ -13409,13 +14205,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls", + "rustls 0.23.31", "tokio", ] @@ -13455,12 +14261,12 @@ dependencies = [ "futures-util", "log", "native-tls", - "rustls", + "rustls 0.23.31", "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.26.4", "tungstenite", "webpki-roots 0.26.11", ] @@ -13583,11 +14389,11 @@ dependencies = [ "axum 0.7.9", "base64 0.22.1", "bytes", - "h2", - "http", - "http-body", + "h2 0.4.12", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-timeout", "hyper-util", "percent-encoding", @@ -13611,10 +14417,10 @@ dependencies = [ "async-trait", "base64 0.22.1", "bytes", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-timeout", "hyper-util", "percent-encoding", @@ -13691,8 +14497,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "http-range-header", "httpdate", @@ -13976,12 +14782,12 @@ checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ "bytes", "data-encoding", - "http", + "http 1.4.0", "httparse", "log", "native-tls", "rand 0.9.2", - "rustls", + "rustls 0.23.31", "rustls-pki-types", "sha1", "thiserror 2.0.17", @@ -14121,7 +14927,7 @@ dependencies = [ "flate2", "log", "once_cell", - "rustls", + "rustls 0.23.31", "rustls-pki-types", "serde", "serde_json", @@ -14141,6 +14947,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" @@ -14248,6 +15060,12 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "wait-timeout" version = "0.2.1" @@ -14472,7 +15290,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -15188,6 +16006,12 @@ version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "xmltree" version = "0.10.3" @@ -15391,6 +16215,7 @@ version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ + "bindgen 0.72.1", "cc", "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index a338c9b0..2b1519be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -216,4 +216,6 @@ opentelemetry = { version = "0.31", features = ["trace"] } # Base Path concurrent-queue = "2.5.0" -tips-core = { git = "https://github.com/base/tips", rev = "c08eaa4fe10c26de8911609b41ddab4918698325", default-features = false } \ No newline at end of file +tips-core = { git = "https://github.com/base/tips", rev = "d571797179fd0cc9e932373ba9a4eb5c2be0c0c9", default-features = false } +tips-audit = { git = "https://github.com/base/tips", rev = "d571797179fd0cc9e932373ba9a4eb5c2be0c0c9" } +rdkafka = { version = "0.37" } \ No newline at end of file diff --git a/crates/op-rbuilder/Cargo.toml b/crates/op-rbuilder/Cargo.toml index a0f5c8d2..28619df2 100644 --- a/crates/op-rbuilder/Cargo.toml +++ b/crates/op-rbuilder/Cargo.toml @@ -135,6 +135,8 @@ reqwest = "0.12.23" k256 = "0.13.4" rollup-boost.workspace = true +tips-audit.workspace = true +rdkafka.workspace = true nanoid = { version = "0.4", optional = true } reth-ipc = { workspace = true, optional = true } diff --git a/crates/op-rbuilder/src/args/op.rs b/crates/op-rbuilder/src/args/op.rs index 4dc0663c..46a70d2b 100644 --- a/crates/op-rbuilder/src/args/op.rs +++ b/crates/op-rbuilder/src/args/op.rs @@ -58,6 +58,25 @@ pub struct OpRbuilderArgs { )] pub resource_metering_buffer_size: usize, + /// Buffer size for backrun bundles (LRU eviction when full) + #[arg(long = "builder.backrun-bundle-buffer-size", default_value = "10000")] + pub backrun_bundle_buffer_size: usize, + + /// Path to Kafka properties file for audit events (enables Kafka audit if set) + #[arg( + long = "builder.audit-kafka-properties", + env = "AUDIT_KAFKA_PROPERTIES_FILE" + )] + pub audit_kafka_properties: Option, + + /// Kafka topic for audit events + #[arg( + long = "builder.audit-kafka-topic", + env = "AUDIT_KAFKA_TOPIC", + default_value = "tips-audit" + )] + pub audit_kafka_topic: String, + /// Path to builder playgorund to automatically start up the node connected to it #[arg( long = "builder.playground", diff --git a/crates/op-rbuilder/src/builders/context.rs b/crates/op-rbuilder/src/builders/context.rs index 1e0f22da..6cb71443 100644 --- a/crates/op-rbuilder/src/builders/context.rs +++ b/crates/op-rbuilder/src/builders/context.rs @@ -36,10 +36,12 @@ use reth_revm::{State, context::Block}; use reth_transaction_pool::{BestTransactionsAttributes, PoolTransaction}; use revm::{DatabaseCommit, context::result::ResultAndState, interpreter::as_u64_saturated}; use std::{sync::Arc, time::Instant}; +use tips_audit::BundleEvent; use tokio_util::sync::CancellationToken; -use tracing::{debug, info, trace}; +use tracing::{debug, info, trace, warn}; use crate::{ + bundles::AuditSender, gas_limiter::AddressGasLimiter, metrics::OpRBuilderMetrics, primitives::reth::{ExecutionInfo, TxnExecutionResult}, @@ -80,6 +82,10 @@ pub struct OpPayloadBuilderCtx { pub address_gas_limiter: AddressGasLimiter, /// Per transaction resource metering information pub resource_metering: ResourceMetering, + /// Backrun bundle store for storing backrun transactions + pub backrun_bundle_store: crate::bundles::BackrunBundleStore, + /// Audit event channel for backrun bundle lifecycle tracking + pub audit_tx: Option, } impl OpPayloadBuilderCtx { @@ -91,6 +97,19 @@ impl OpPayloadBuilderCtx { Self { extra_ctx, ..self } } + /// Send an audit event if the audit channel is configured + fn send_audit_event(&self, event: BundleEvent) { + if let Some(ref audit_tx) = self.audit_tx { + if let Err(e) = audit_tx.send(event) { + warn!( + target: "payload_builder", + error = %e, + "Failed to send audit event" + ); + } + } + } + /// Returns the parent block the payload will be build on. pub fn parent(&self) -> &SealedHeader { &self.config.parent_header @@ -433,7 +452,7 @@ impl OpPayloadBuilderCtx { is_bundle_tx && !reverted_hashes.unwrap().contains(&tx_hash); let log_txn = |result: TxnExecutionResult| { - debug!( + info!( target: "payload_builder", message = "Considering transaction", tx_hash = ?tx_hash, @@ -445,6 +464,17 @@ impl OpPayloadBuilderCtx { num_txs_considered += 1; + // Look up bundle_id for this tx (registered via base_txBundleId RPC) + let bundle_id = self.backrun_bundle_store.get_tx_bundle_id(&tx_hash); + + // Emit StartExecuting audit event - tx is about to be executed + self.send_audit_event(BundleEvent::StartExecuting { + bundle_id, + tx_hash, + block_number: self.block_number(), + timestamp_ms: chrono::Utc::now().timestamp_millis(), + }); + let _resource_usage = self.resource_metering.get(&tx_hash); // TODO: ideally we should get this from the txpool stream @@ -543,7 +573,9 @@ impl OpPayloadBuilderCtx { continue; } - if result.is_success() { + let is_success = result.is_success(); + + if is_success { log_txn(TxnExecutionResult::Success); num_txs_simulated_success += 1; self.metrics.successful_tx_gas_used.record(gas_used as f64); @@ -600,6 +632,90 @@ impl OpPayloadBuilderCtx { // append sender and transaction to the respective lists info.executed_senders.push(tx.signer()); info.executed_transactions.push(tx.into_inner()); + + // Emit Executed audit event - tx successfully executed and committed + self.send_audit_event(BundleEvent::Executed { + bundle_id, + tx_hash, + block_number: self.block_number(), + gas_used, + timestamp_ms: chrono::Utc::now().timestamp_millis(), + }); + + // Execute backrun bundles for this transaction if it succeeded + if is_success && let Some(backrun_bundles) = self.backrun_bundle_store.get(&tx_hash) { + self.metrics.backrun_target_txs_found_total.increment(1); + + for stored_bundle in backrun_bundles { + let bundle_id = stored_bundle.bundle_id; + for backrun_tx in stored_bundle.backrun_txs { + let ResultAndState { result, state } = match evm.transact(&backrun_tx) { + Ok(res) => res, + Err(err) => { + return Err(PayloadBuilderError::evm(err)); + } + }; + + let backrun_gas_used = result.gas_used(); + let is_backrun_success = result.is_success(); + + if !is_backrun_success { + info!(message = "Backrun transaction reverted", tx_hash = ?backrun_tx.tx_hash(), bundle_id = %bundle_id); + + // Emit BackrunBundleExecuted audit event for reverted tx + self.send_audit_event(BundleEvent::BackrunBundleExecuted { + bundle_id, + target_tx_hash: tx_hash, + backrun_tx_hash: backrun_tx.tx_hash(), + block_number: self.block_number(), + gas_used: backrun_gas_used, + success: false, + timestamp_ms: chrono::Utc::now().timestamp_millis(), + }); + + continue; + } + + info!(message = "Backrun transaction succeeded", tx_hash = ?backrun_tx.tx_hash(), bundle_id = %bundle_id); + + info.cumulative_gas_used += backrun_gas_used; + info.cumulative_da_bytes_used += backrun_tx.encoded_2718().len() as u64; + + let ctx = ReceiptBuilderCtx { + tx: backrun_tx.inner(), + evm: &evm, + result, + state: &state, + cumulative_gas_used: info.cumulative_gas_used, + }; + info.receipts.push(self.build_receipt(ctx, None)); + + // commit changes + evm.db_mut().commit(state); + + // Emit BackrunBundleExecuted audit event for successful tx + self.send_audit_event(BundleEvent::BackrunBundleExecuted { + bundle_id, + target_tx_hash: tx_hash, + backrun_tx_hash: backrun_tx.tx_hash(), + block_number: self.block_number(), + gas_used: backrun_gas_used, + success: true, + timestamp_ms: chrono::Utc::now().timestamp_millis(), + }); + + // update add to total fees + let miner_fee = backrun_tx + .effective_tip_per_gas(base_fee) + .expect("fee is always valid; execution succeeded"); + info.total_fees += U256::from(miner_fee) * U256::from(backrun_gas_used); + + // append sender and transaction to the respective lists + info.executed_senders.push(backrun_tx.signer()); + info.executed_transactions.push(backrun_tx.into_inner()); + } + } + } } let payload_transaction_simulation_time = execute_txs_start_time.elapsed(); diff --git a/crates/op-rbuilder/src/builders/flashblocks/ctx.rs b/crates/op-rbuilder/src/builders/flashblocks/ctx.rs index 28cbae76..7da627a7 100644 --- a/crates/op-rbuilder/src/builders/flashblocks/ctx.rs +++ b/crates/op-rbuilder/src/builders/flashblocks/ctx.rs @@ -1,5 +1,6 @@ use crate::{ builders::{BuilderConfig, OpPayloadBuilderCtx, flashblocks::FlashblocksConfig}, + bundles::{AuditSender, BackrunBundleStore}, gas_limiter::{AddressGasLimiter, args::GasLimiterArgs}, metrics::OpRBuilderMetrics, resource_metering::ResourceMetering, @@ -32,6 +33,10 @@ pub(super) struct OpPayloadSyncerCtx { metrics: Arc, /// Resource metering tracking resource_metering: ResourceMetering, + /// Backrun bundle store + backrun_bundle_store: BackrunBundleStore, + /// Audit event channel + audit_tx: Option, } impl OpPayloadSyncerCtx { @@ -45,6 +50,7 @@ impl OpPayloadSyncerCtx { Client: ClientBounds, { let chain_spec = client.chain_spec(); + let audit_tx = builder_config.backrun_bundle_store.audit_tx(); Ok(Self { evm_config, da_config: builder_config.da_config.clone(), @@ -52,6 +58,8 @@ impl OpPayloadSyncerCtx { max_gas_per_txn: builder_config.max_gas_per_txn, metrics, resource_metering: builder_config.resource_metering, + backrun_bundle_store: builder_config.backrun_bundle_store, + audit_tx, }) } @@ -85,6 +93,8 @@ impl OpPayloadSyncerCtx { max_gas_per_txn: self.max_gas_per_txn, address_gas_limiter: AddressGasLimiter::new(GasLimiterArgs::default()), resource_metering: self.resource_metering.clone(), + backrun_bundle_store: self.backrun_bundle_store.clone(), + audit_tx: self.audit_tx, } } } diff --git a/crates/op-rbuilder/src/builders/flashblocks/payload.rs b/crates/op-rbuilder/src/builders/flashblocks/payload.rs index 35e16834..b6a16a68 100644 --- a/crates/op-rbuilder/src/builders/flashblocks/payload.rs +++ b/crates/op-rbuilder/src/builders/flashblocks/payload.rs @@ -283,6 +283,8 @@ where max_gas_per_txn: self.config.max_gas_per_txn, address_gas_limiter: self.address_gas_limiter.clone(), resource_metering: self.config.resource_metering.clone(), + backrun_bundle_store: self.config.backrun_bundle_store.clone(), + audit_tx: self.config.backrun_bundle_store.audit_tx(), }) } diff --git a/crates/op-rbuilder/src/builders/mod.rs b/crates/op-rbuilder/src/builders/mod.rs index 48ce625b..4da8be12 100644 --- a/crates/op-rbuilder/src/builders/mod.rs +++ b/crates/op-rbuilder/src/builders/mod.rs @@ -21,7 +21,7 @@ mod flashblocks; mod generator; mod standard; -use crate::resource_metering::ResourceMetering; +use crate::{bundles::BackrunBundleStore, resource_metering::ResourceMetering}; pub use builder_tx::{ BuilderTransactionCtx, BuilderTransactionError, BuilderTransactions, InvalidContractDataError, SimulationSuccessResult, get_balance, get_nonce, @@ -130,6 +130,9 @@ pub struct BuilderConfig { /// Resource metering context pub resource_metering: ResourceMetering, + + /// Backrun bundle store for storing backrun transactions + pub backrun_bundle_store: BackrunBundleStore, } impl core::fmt::Debug for BuilderConfig { @@ -152,6 +155,7 @@ impl core::fmt::Debug for BuilderConfig { .field("specific", &self.specific) .field("max_gas_per_txn", &self.max_gas_per_txn) .field("gas_limiter_config", &self.gas_limiter_config) + .field("backrun_bundle_store", &self.backrun_bundle_store) .finish() } } @@ -171,6 +175,7 @@ impl Default for BuilderConfig { max_gas_per_txn: None, gas_limiter_config: GasLimiterArgs::default(), resource_metering: ResourceMetering::default(), + backrun_bundle_store: BackrunBundleStore::default(), } } } @@ -197,6 +202,7 @@ where args.enable_resource_metering, args.resource_metering_buffer_size, ), + backrun_bundle_store: BackrunBundleStore::new(args.backrun_bundle_buffer_size), specific: S::try_from(args)?, }) } diff --git a/crates/op-rbuilder/src/builders/standard/payload.rs b/crates/op-rbuilder/src/builders/standard/payload.rs index d9a74add..7cfdc4d9 100644 --- a/crates/op-rbuilder/src/builders/standard/payload.rs +++ b/crates/op-rbuilder/src/builders/standard/payload.rs @@ -252,6 +252,8 @@ where max_gas_per_txn: self.config.max_gas_per_txn, address_gas_limiter: self.address_gas_limiter.clone(), resource_metering: self.config.resource_metering.clone(), + backrun_bundle_store: self.config.backrun_bundle_store.clone(), + audit_tx: self.config.backrun_bundle_store.audit_tx(), }; let builder = OpBuilder::new(best); diff --git a/crates/op-rbuilder/src/bundles.rs b/crates/op-rbuilder/src/bundles.rs new file mode 100644 index 00000000..3871ec62 --- /dev/null +++ b/crates/op-rbuilder/src/bundles.rs @@ -0,0 +1,373 @@ +use alloy_consensus::transaction::Recovered; +use alloy_primitives::TxHash; +use concurrent_queue::ConcurrentQueue; +use jsonrpsee::{ + core::{RpcResult, async_trait}, + proc_macros::rpc, +}; +use op_alloy_consensus::OpTxEnvelope; +use std::{fmt::Debug, sync::Arc}; +use tips_audit::BundleEvent; +use tips_core::{Bundle, types::ParsedBundle}; +use tokio::sync::mpsc; +use tracing::{debug, info, warn}; +use uuid::Uuid; + +use crate::metrics::OpRBuilderMetrics; + +/// Type alias for the audit event sender +pub(crate) type AuditSender = mpsc::UnboundedSender; + +/// Stored backrun bundle with its bundle_id and transactions +#[derive(Clone)] +pub struct StoredBackrunBundle { + pub bundle_id: Uuid, + pub backrun_txs: Vec>, +} + +struct BackrunData { + /// Key is the hash of the target tx, value is list of backrun bundles with their IDs + by_target_tx: dashmap::DashMap>, + lru: ConcurrentQueue, + /// Map tx hash to bundle ID for audit tracking + tx_bundle_ids: dashmap::DashMap, +} + +#[derive(Clone)] +pub struct BackrunBundleStore { + data: Arc, + metrics: OpRBuilderMetrics, + audit_tx: Option, +} + +impl Debug for BackrunBundleStore { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("BackrunBundleStore") + .field("by_target_tx_count", &self.data.by_target_tx.len()) + .finish() + } +} + +impl BackrunBundleStore { + pub fn new(buffer_size: usize) -> Self { + Self { + data: Arc::new(BackrunData { + by_target_tx: dashmap::DashMap::new(), + lru: ConcurrentQueue::bounded(buffer_size), + tx_bundle_ids: dashmap::DashMap::new(), + }), + metrics: OpRBuilderMetrics::default(), + audit_tx: None, + } + } + + /// Create a new BackrunBundleStore with an audit channel + pub fn with_audit(buffer_size: usize, audit_tx: AuditSender) -> Self { + Self { + data: Arc::new(BackrunData { + by_target_tx: dashmap::DashMap::new(), + lru: ConcurrentQueue::bounded(buffer_size), + tx_bundle_ids: dashmap::DashMap::new(), + }), + metrics: OpRBuilderMetrics::default(), + audit_tx: Some(audit_tx), + } + } + + /// Get the audit sender (for passing to context) + pub fn audit_tx(&self) -> Option { + self.audit_tx.clone() + } + + /// Register a tx hash to bundle ID mapping for audit tracking + pub fn set_tx_bundle_id(&self, tx_hash: TxHash, bundle_id: Uuid) { + self.data.tx_bundle_ids.insert(tx_hash, bundle_id); + } + + /// Look up the bundle ID for a tx hash + pub fn get_tx_bundle_id(&self, tx_hash: &TxHash) -> Option { + self.data.tx_bundle_ids.get(tx_hash).map(|entry| *entry) + } + + pub fn insert(&self, bundle: ParsedBundle, bundle_id: Uuid) -> Result<(), String> { + if bundle.txs.len() < 2 { + return Err("Bundle must have at least 2 transactions (target + backrun)".to_string()); + } + + // Target tx is txs[0], backrun txs are txs[1..] + let target_tx_hash = bundle.txs[0].tx_hash(); + let backrun_txs: Vec> = bundle.txs[1..].to_vec(); + + // Handle LRU eviction + if self.data.lru.is_full() + && let Ok(evicted_hash) = self.data.lru.pop() + { + self.data.by_target_tx.remove(&evicted_hash); + warn!( + target: "backrun_bundles", + evicted_target = ?evicted_hash, + "Evicted old backrun bundle" + ); + } + + let _ = self.data.lru.push(target_tx_hash); + + let stored_bundle = StoredBackrunBundle { + bundle_id, + backrun_txs: backrun_txs.clone(), + }; + + self.data + .by_target_tx + .entry(target_tx_hash) + .or_insert_with(Vec::new) + .push(stored_bundle); + + info!( + target: "backrun_bundles", + target_tx = ?target_tx_hash, + bundle_id = %bundle_id, + backrun_tx_count = backrun_txs.len(), + "Stored backrun bundle" + ); + + self.metrics + .backrun_bundles_in_store + .set(self.data.by_target_tx.len() as f64); + + // Emit audit event for backrun bundle inserted into store + if let Some(ref audit_tx) = self.audit_tx { + let event = BundleEvent::BackrunInserted { + bundle_id, + target_tx_hash, + backrun_tx_hashes: backrun_txs.iter().map(|tx| tx.tx_hash()).collect(), + timestamp_ms: chrono::Utc::now().timestamp_millis(), + }; + if let Err(e) = audit_tx.send(event) { + warn!( + target: "backrun_bundles", + error = %e, + "Failed to send BackrunInserted audit event" + ); + } + } + + Ok(()) + } + + pub fn get(&self, target_tx_hash: &TxHash) -> Option> { + self.data + .by_target_tx + .get(target_tx_hash) + .map(|entry| entry.clone()) + } + + pub fn remove(&self, target_tx_hash: &TxHash) { + if let Some((_, bundles)) = self.data.by_target_tx.remove(target_tx_hash) { + debug!( + target: "backrun_bundles", + target_tx = ?target_tx_hash, + bundle_count = bundles.len(), + "Removed backrun bundles" + ); + + self.metrics + .backrun_bundles_in_store + .set(self.data.by_target_tx.len() as f64); + } + } + + pub fn len(&self) -> usize { + self.data.by_target_tx.len() + } +} + +impl Default for BackrunBundleStore { + fn default() -> Self { + Self::new(10_000) + } +} + +#[cfg_attr(not(test), rpc(server, namespace = "base"))] +#[cfg_attr(test, rpc(server, client, namespace = "base"))] +pub trait BaseBundlesApiExt { + #[method(name = "sendBackrunBundle")] + async fn send_backrun_bundle(&self, bundle: Bundle, bundle_id: Uuid) -> RpcResult<()>; + + /// Register a tx hash to bundle ID mapping for audit tracking + #[method(name = "txBundleId")] + async fn tx_bundle_id(&self, tx_hash: TxHash, bundle_id: Uuid) -> RpcResult<()>; +} + +pub(crate) struct BundlesApiExt { + bundle_store: BackrunBundleStore, + metrics: OpRBuilderMetrics, +} + +impl BundlesApiExt { + pub(crate) fn new(bundle_store: BackrunBundleStore) -> Self { + Self { + bundle_store, + metrics: OpRBuilderMetrics::default(), + } + } +} + +#[async_trait] +impl BaseBundlesApiExtServer for BundlesApiExt { + async fn send_backrun_bundle(&self, bundle: Bundle, bundle_id: Uuid) -> RpcResult<()> { + self.metrics.backrun_bundles_received_total.increment(1); + + info!( + message = "Received backrun bundle", + bundle_id = %bundle_id, + tx_hashes = ?bundle.reverting_tx_hashes + ); + + let parsed_bundle = ParsedBundle::try_from(bundle).map_err(|e| { + warn!(target: "backrun_bundles", error = %e, "Failed to parse bundle"); + jsonrpsee::types::ErrorObject::owned( + jsonrpsee::types::error::INVALID_PARAMS_CODE, + format!("Failed to parse bundle: {}", e), + None::<()>, + ) + })?; + + self.bundle_store + .insert(parsed_bundle, bundle_id) + .map_err(|e| { + warn!(target: "backrun_bundles", error = %e, "Failed to store bundle"); + jsonrpsee::types::ErrorObject::owned( + jsonrpsee::types::error::INTERNAL_ERROR_CODE, + format!("Failed to store bundle: {}", e), + None::<()>, + ) + })?; + + Ok(()) + } + + async fn tx_bundle_id(&self, tx_hash: TxHash, bundle_id: Uuid) -> RpcResult<()> { + info!( + target: "backrun_bundles", + tx_hash = ?tx_hash, + bundle_id = %bundle_id, + "Registered tx bundle ID" + ); + self.bundle_store.set_tx_bundle_id(tx_hash, bundle_id); + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloy_consensus::SignableTransaction; + use alloy_primitives::{Address, Bytes, TxHash, U256}; + use alloy_provider::network::{TxSignerSync, eip2718::Encodable2718}; + use alloy_signer_local::PrivateKeySigner; + use op_alloy_consensus::OpTxEnvelope; + use op_alloy_rpc_types::OpTransactionRequest; + + fn create_transaction(from: PrivateKeySigner, nonce: u64, to: Address) -> OpTxEnvelope { + let mut txn = OpTransactionRequest::default() + .value(U256::from(10_000)) + .gas_limit(21_000) + .max_fee_per_gas(200) + .max_priority_fee_per_gas(100) + .from(from.address()) + .to(to) + .nonce(nonce) + .build_typed_tx() + .unwrap(); + + let sig = from.sign_transaction_sync(&mut txn).unwrap(); + OpTxEnvelope::Eip1559(txn.eip1559().cloned().unwrap().into_signed(sig).clone()) + } + + fn create_test_parsed_bundle(txs: Vec) -> ParsedBundle { + tips_core::Bundle { + txs, + block_number: 1, + ..Default::default() + } + .try_into() + .unwrap() + } + + #[test] + fn test_backrun_bundle_store() { + let alice = PrivateKeySigner::random(); + let bob = PrivateKeySigner::random(); + + // Create test transactions + let target_tx = create_transaction(alice.clone(), 0, bob.address()); + let backrun_tx1 = create_transaction(alice.clone(), 1, bob.address()); + let backrun_tx2 = create_transaction(alice.clone(), 2, bob.address()); + + let target_tx_hash = target_tx.tx_hash(); + + let store = BackrunBundleStore::new(100); + + // Test insert fails with only 1 tx (need target + at least 1 backrun) + let single_tx_bundle = create_test_parsed_bundle(vec![target_tx.encoded_2718().into()]); + assert!(store.insert(single_tx_bundle, Uuid::new_v4()).is_err()); + assert_eq!(store.len(), 0); + + // Test insert succeeds with 2+ txs + let valid_bundle = create_test_parsed_bundle(vec![ + target_tx.encoded_2718().into(), + backrun_tx1.encoded_2718().into(), + ]); + assert!(store.insert(valid_bundle, Uuid::new_v4()).is_ok()); + assert_eq!(store.len(), 1); + + // Test get returns the backrun txs (not the target) + let retrieved = store.get(&target_tx_hash).unwrap(); + assert_eq!(retrieved.len(), 1); // 1 bundle + assert_eq!(retrieved[0].backrun_txs.len(), 1); // 1 backrun tx in that bundle + assert_eq!(retrieved[0].backrun_txs[0].tx_hash(), backrun_tx1.tx_hash()); + + // Test multiple backrun bundles for same target + let second_bundle = create_test_parsed_bundle(vec![ + target_tx.encoded_2718().into(), + backrun_tx2.encoded_2718().into(), + ]); + assert!(store.insert(second_bundle, Uuid::new_v4()).is_ok()); + assert_eq!(store.len(), 1); // Still 1 target, but 2 backrun bundles + + let retrieved = store.get(&target_tx_hash).unwrap(); + assert_eq!(retrieved.len(), 2); // Now 2 bundles for same target + + // Test remove + store.remove(&target_tx_hash); + assert_eq!(store.len(), 0); + assert!(store.get(&target_tx_hash).is_none()); + + // Test remove on non-existent key doesn't panic + store.remove(&TxHash::ZERO); + } + + #[test] + fn test_backrun_bundle_store_lru_eviction() { + let alice = PrivateKeySigner::random(); + let bob = PrivateKeySigner::random(); + + // Small buffer to test eviction + let store = BackrunBundleStore::new(2); + + // Insert 3 bundles, first should be evicted + for nonce in 0..3u64 { + let target = create_transaction(alice.clone(), nonce * 2, bob.address()); + let backrun = create_transaction(alice.clone(), nonce * 2 + 1, bob.address()); + let bundle = create_test_parsed_bundle(vec![ + target.encoded_2718().into(), + backrun.encoded_2718().into(), + ]); + let _ = store.insert(bundle, Uuid::new_v4()); + } + + // Only 2 should remain due to LRU eviction + assert_eq!(store.len(), 2); + } +} diff --git a/crates/op-rbuilder/src/launcher.rs b/crates/op-rbuilder/src/launcher.rs index 5d7c6f84..648f837c 100644 --- a/crates/op-rbuilder/src/launcher.rs +++ b/crates/op-rbuilder/src/launcher.rs @@ -1,9 +1,17 @@ use eyre::Result; +use rdkafka::ClientConfig; +use rdkafka::producer::FutureProducer; use reth_optimism_rpc::OpEthApiBuilder; +use tips_audit::{ + BundleEvent, KafkaBundleEventPublisher, LoggingBundleEventPublisher, connect_audit_to_publisher, +}; +use tips_core::kafka::load_kafka_config_from_file; +use tokio::sync::mpsc; use crate::{ args::*, builders::{BuilderConfig, BuilderMode, FlashblocksBuilder, PayloadBuilder, StandardBuilder}, + bundles::{BackrunBundleStore, BaseBundlesApiExtServer, BundlesApiExt}, metrics::{VERSION, record_flag_gauge_metrics}, monitor_tx_pool::monitor_tx_pool, primitives::reth::engine_api_builder::OpEngineApiBuilder, @@ -57,7 +65,8 @@ pub fn launch() -> Result<()> { } BuilderMode::Flashblocks => { tracing::info!("Starting OP builder in flashblocks mode"); - let launcher = BuilderLauncher::::new(); + let launcher: BuilderLauncher = + BuilderLauncher::::new(); cli_app.run(launcher)?; } } @@ -99,9 +108,41 @@ where builder: WithLaunchContext, OpChainSpec>>, builder_args: OpRbuilderArgs, ) -> Result<()> { - let builder_config = BuilderConfig::::try_from(builder_args.clone()) + // Set up audit event channel + let (audit_tx, audit_rx) = mpsc::unbounded_channel::(); + + // Use Kafka publisher if config provided, otherwise use logging publisher + if let Some(ref kafka_properties_file) = builder_args.audit_kafka_properties { + let kafka_config = load_kafka_config_from_file(kafka_properties_file) + .expect("Failed to load Kafka config from properties file"); + let audit_client_config = ClientConfig::from_iter(kafka_config); + let audit_producer: FutureProducer = audit_client_config + .create() + .expect("Failed to create Kafka producer"); + let audit_publisher = KafkaBundleEventPublisher::new( + audit_producer, + builder_args.audit_kafka_topic.clone(), + ); + connect_audit_to_publisher(audit_rx, audit_publisher); + tracing::info!( + topic = %builder_args.audit_kafka_topic, + "Backrun bundle audit events enabled (Kafka)" + ); + } else { + connect_audit_to_publisher(audit_rx, LoggingBundleEventPublisher::new()); + tracing::warn!("Backrun bundle audit events enabled (logging only)"); + } + + // Create backrun bundle store with audit channel + let backrun_bundle_store = + BackrunBundleStore::with_audit(builder_args.backrun_bundle_buffer_size, audit_tx); + + let mut builder_config = BuilderConfig::::try_from(builder_args.clone()) .expect("Failed to convert rollup args to builder config"); + // Replace the default backrun bundle store with the one that has audit + builder_config.backrun_bundle_store = backrun_bundle_store.clone(); + record_flag_gauge_metrics(&builder_args); let da_config = builder_config.da_config.clone(); @@ -167,8 +208,12 @@ where } let resource_metering_ext = ResourceMeteringExt::new(resource_metering); + let bundles_ext = BundlesApiExt::new(backrun_bundle_store); + ctx.modules .add_or_replace_configured(resource_metering_ext.into_rpc())?; + ctx.modules + .add_or_replace_configured(bundles_ext.into_rpc())?; Ok(()) }) diff --git a/crates/op-rbuilder/src/lib.rs b/crates/op-rbuilder/src/lib.rs index f61c39b0..32676307 100644 --- a/crates/op-rbuilder/src/lib.rs +++ b/crates/op-rbuilder/src/lib.rs @@ -11,6 +11,7 @@ pub mod traits; pub mod tx; pub mod tx_signer; +mod bundles; #[cfg(test)] pub mod mock_tx; mod resource_metering; diff --git a/crates/op-rbuilder/src/metrics.rs b/crates/op-rbuilder/src/metrics.rs index 75ebb874..f2c9f5f0 100644 --- a/crates/op-rbuilder/src/metrics.rs +++ b/crates/op-rbuilder/src/metrics.rs @@ -167,6 +167,12 @@ pub struct OpRBuilderMetrics { pub metering_unknown_transaction: Counter, /// Count of the number of times we were unable to resolve metering information due to locking pub metering_locked_transaction: Counter, + /// Current number of backrun bundles in store + pub backrun_bundles_in_store: Gauge, + /// Number of target transactions found with backrun bundles + pub backrun_target_txs_found_total: Counter, + /// Number of backrun bundles received via RPC + pub backrun_bundles_received_total: Counter, } impl OpRBuilderMetrics { diff --git a/docker/audit-kafka-properties b/docker/audit-kafka-properties new file mode 100644 index 00000000..03c434cb --- /dev/null +++ b/docker/audit-kafka-properties @@ -0,0 +1,7 @@ +# Kafka configuration properties for backrun bundle audit events +# Use localhost when running op-rbuilder on host (not in Docker) +# Use host.docker.internal when running op-rbuilder inside Docker + +bootstrap.servers=localhost:9092 +message.timeout.ms=5000 + diff --git a/justfile b/justfile index d3ab4caf..facfe326 100644 --- a/justfile +++ b/justfile @@ -11,7 +11,9 @@ run-playground: --port 30333 --disable-discovery \ --metrics 127.0.0.1:9011 \ --rollup.builder-secret-key ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ - --trusted-peers enode://79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8@127.0.0.1:30304 + --trusted-peers enode://79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8@127.0.0.1:30304 \ + --builder.audit-kafka-properties=./docker/audit-kafka-properties \ + --builder.audit-kafka-topic=tips-audit # Run the complete test suite (genesis generation, build, and tests) run-tests: