diff --git a/.github/workflows/bolt_cli_ci.yml b/.github/workflows/bolt_cli_ci.yml new file mode 100644 index 000000000..6ea7c18c7 --- /dev/null +++ b/.github/workflows/bolt_cli_ci.yml @@ -0,0 +1,46 @@ +name: Bolt CLI CI + +on: + push: + paths: + - "bolt-cli/**" + pull_request: + paths: + - "bolt-cli/**" + +env: + CARGO_TERM_COLOR: always + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + cargo-tests: + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + RUST_BACKTRACE: 1 + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Install Protoc + uses: arduino/setup-protoc@v3 + + - name: Cache cargo registry + uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + + - name: Install cargo-nextest + uses: baptiste0928/cargo-install@v3 + with: + crate: cargo-nextest + + - name: Run bolt-cli tests + run: cd bolt-cli && cargo nextest run --workspace --retries 3 diff --git a/README.md b/README.md index 990e02fa9..445271c7c 100644 --- a/README.md +++ b/README.md @@ -111,9 +111,8 @@ In particular, the core components are: such as proposer registration and permissionless dispute resolution for attributable faults. - [**Bolt Boost**](./bolt-boost/): A [Commit-Boost][commit-boost] module that implements the Constraints-API and is compatible with the Bolt Sidecar. -- [**Bolt client**](./bolt-client/): A CLI tool to send preconfirmations on enabled test networks. -- [**Bolt Kurtosis client**](./bolt-kurtosis-client/): A CLI tool to send preconfirmations on our Kurtosis devnet. -- [**Bolt delegations CLI**](./bolt-delegations-cli/): A CLI tool to generate signed delegation and revocation messages for ETH validators. +- [**Bolt CLI**](./bolt-cli/): A CLI tool to interact with Bolt contracts, register proposers, + and submit transactions to the Bolt Sidecar. - [**Testnets**](./testnets/): A set of guides and scripts to deploy the Bolt contracts on testnets. Additionally, this repository contains the necessary scripts to spin up a [Kurtosis][kurtosis] diff --git a/bolt-cli/.gitignore b/bolt-cli/.gitignore new file mode 100644 index 000000000..12571ac34 --- /dev/null +++ b/bolt-cli/.gitignore @@ -0,0 +1,7 @@ +/target + +.env +.env.* + +delegations.json +pubkeys.json diff --git a/bolt-delegations-cli/Cargo.lock b/bolt-cli/Cargo.lock similarity index 54% rename from bolt-delegations-cli/Cargo.lock rename to bolt-cli/Cargo.lock index 31990b74e..6fd80d826 100644 --- a/bolt-delegations-cli/Cargo.lock +++ b/bolt-cli/Cargo.lock @@ -2,26 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "account_utils" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "directory", - "eth2_keystore", - "eth2_wallet", - "filesystem", - "rand", - "regex", - "rpassword", - "serde", - "serde_yaml 0.9.34+deprecated", - "slog", - "types", - "validator_dir", - "zeroize", -] - [[package]] name = "addr2line" version = "0.24.2" @@ -37,21 +17,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array", -] - [[package]] name = "aes" version = "0.7.5" @@ -59,49 +24,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ "cfg-if", - "cipher 0.3.0", + "cipher", "cpufeatures", - "ctr 0.8.0", + "ctr", "opaque-debug", ] -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc3be92e19a7ef47457b8e6f90707e12b6ac5d20c6f3866584fa3be0787d839f" -dependencies = [ - "aead", - "aes 0.7.5", - "cipher 0.3.0", - "ctr 0.7.0", - "ghash", - "subtle", -] - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -111,198 +39,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "alloy" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f4a4aaae80afd4be443a6aecd92a6b255dcdd000f97996928efb33d8a71e100" -dependencies = [ - "alloy-consensus", - "alloy-contract", - "alloy-core", - "alloy-eips", - "alloy-genesis", - "alloy-network", - "alloy-provider", - "alloy-pubsub", - "alloy-rpc-client", - "alloy-rpc-types", - "alloy-serde", - "alloy-signer", - "alloy-signer-local", - "alloy-transport", - "alloy-transport-http", - "alloy-transport-ipc", - "alloy-transport-ws", -] - -[[package]] -name = "alloy-chains" -version = "0.1.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "156bfc5dcd52ef9a5f33381701fa03310317e14c65093a9430d3e3557b08dcd3" -dependencies = [ - "alloy-primitives 0.8.7", - "num_enum", - "strum", -] - -[[package]] -name = "alloy-consensus" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c309895995eaa4bfcc345f5515a39c7df9447798645cc8bf462b6c5bf1dc96" -dependencies = [ - "alloy-eips", - "alloy-primitives 0.7.7", - "alloy-rlp", - "alloy-serde", - "c-kzg", - "serde", -] - -[[package]] -name = "alloy-contract" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f4e0ef72b0876ae3068b2ed7dfae9ae1779ce13cfaec2ee1f08f5bd0348dc57" -dependencies = [ - "alloy-dyn-abi", - "alloy-json-abi", - "alloy-network", - "alloy-network-primitives", - "alloy-primitives 0.7.7", - "alloy-provider", - "alloy-pubsub", - "alloy-rpc-types-eth", - "alloy-sol-types", - "alloy-transport", - "futures", - "futures-util", - "thiserror", -] - -[[package]] -name = "alloy-core" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529fc6310dc1126c8de51c376cbc59c79c7f662bd742be7dc67055d5421a81b4" -dependencies = [ - "alloy-dyn-abi", - "alloy-json-abi", - "alloy-primitives 0.7.7", - "alloy-sol-types", -] - -[[package]] -name = "alloy-dyn-abi" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413902aa18a97569e60f679c23f46a18db1656d87ab4d4e49d0e1e52042f66df" -dependencies = [ - "alloy-json-abi", - "alloy-primitives 0.7.7", - "alloy-sol-type-parser", - "alloy-sol-types", - "const-hex", - "itoa", - "serde", - "serde_json", - "winnow", -] - -[[package]] -name = "alloy-eips" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9431c99a3b3fe606ede4b3d4043bdfbcb780c45b8d8d226c3804e2b75cfbe68" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-rlp", - "alloy-serde", - "c-kzg", - "derive_more 0.99.18", - "k256 0.13.4", - "once_cell", - "serde", - "sha2 0.10.8", -] - -[[package]] -name = "alloy-genesis" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79614dfe86144328da11098edcc7bc1a3f25ad8d3134a9eb9e857e06f0d9840d" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-serde", - "serde", -] - -[[package]] -name = "alloy-json-abi" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc05b04ac331a9f07e3a4036ef7926e49a8bf84a99a1ccfc7e2ab55a5fcbb372" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-sol-type-parser", - "serde", - "serde_json", -] - -[[package]] -name = "alloy-json-rpc" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e2865c4c3bb4cdad3f0d9ec1ab5c0c657ba69a375651bd35e32fb6c180ccc2" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-sol-types", - "serde", - "serde_json", - "thiserror", - "tracing", -] - -[[package]] -name = "alloy-network" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e701fc87ef9a3139154b0b4ccb935b565d27ffd9de020fe541bf2dec5ae4ede" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-json-rpc", - "alloy-network-primitives", - "alloy-primitives 0.7.7", - "alloy-rpc-types-eth", - "alloy-serde", - "alloy-signer", - "alloy-sol-types", - "async-trait", - "auto_impl", - "futures-utils-wasm", - "thiserror", -] - -[[package]] -name = "alloy-network-primitives" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec9d5a0f9170b10988b6774498a022845e13eda94318440d17709d50687f67f9" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-serde", - "serde", -] - [[package]] name = "alloy-primitives" version = "0.7.7" @@ -327,76 +63,30 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb848c43f6b06ae3de2e4a67496cbbabd78ae87db0f1248934f15d76192c6a" +checksum = "c71738eb20c42c5fb149571e76536a0f309d142f3957c28791662b96baf77a3d" dependencies = [ + "alloy-rlp", "bytes", "cfg-if", "const-hex", "derive_more 1.0.0", + "foldhash", + "hashbrown 0.15.0", "hex-literal", + "indexmap 2.6.0", "itoa", + "k256 0.13.4", + "keccak-asm", "paste", + "proptest", + "rand", "ruint", - "tiny-keccak", -] - -[[package]] -name = "alloy-provider" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9c0ab10b93de601a6396fc7ff2ea10d3b28c46f079338fa562107ebf9857c8" -dependencies = [ - "alloy-chains", - "alloy-consensus", - "alloy-eips", - "alloy-json-rpc", - "alloy-network", - "alloy-network-primitives", - "alloy-primitives 0.7.7", - "alloy-pubsub", - "alloy-rpc-client", - "alloy-rpc-types-engine", - "alloy-rpc-types-eth", - "alloy-rpc-types-trace", - "alloy-transport", - "alloy-transport-http", - "alloy-transport-ipc", - "alloy-transport-ws", - "async-stream", - "async-trait", - "auto_impl", - "dashmap", - "futures", - "futures-utils-wasm", - "lru", - "pin-project", - "reqwest 0.12.8", - "serde", - "serde_json", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "alloy-pubsub" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f5da2c55cbaf229bad3c5f8b00b5ab66c74ef093e5f3a753d874cfecf7d2281" -dependencies = [ - "alloy-json-rpc", - "alloy-primitives 0.7.7", - "alloy-transport", - "bimap", - "futures", + "rustc-hash 2.0.0", "serde", - "serde_json", - "tokio", - "tokio-stream", - "tower", - "tracing", + "sha3", + "tiny-keccak", ] [[package]] @@ -405,144 +95,17 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" dependencies = [ - "alloy-rlp-derive", "arrayvec", "bytes", ] -[[package]] -name = "alloy-rlp-derive" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "alloy-rpc-client" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b38e3ffdb285df5d9f60cb988d336d9b8e3505acb78750c3bc60336a7af41d3" -dependencies = [ - "alloy-json-rpc", - "alloy-primitives 0.7.7", - "alloy-pubsub", - "alloy-transport", - "alloy-transport-http", - "alloy-transport-ipc", - "alloy-transport-ws", - "futures", - "pin-project", - "reqwest 0.12.8", - "serde", - "serde_json", - "tokio", - "tokio-stream", - "tower", - "tracing", - "url", -] - -[[package]] -name = "alloy-rpc-types" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c31a3750b8f5a350d17354e46a52b0f2f19ec5f2006d816935af599dedc521" -dependencies = [ - "alloy-rpc-types-beacon", - "alloy-rpc-types-engine", - "alloy-rpc-types-eth", - "alloy-rpc-types-trace", - "alloy-serde", - "serde", -] - -[[package]] -name = "alloy-rpc-types-beacon" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8a24bcff4f9691d7a4971b43e5da46aa7b4ce22ed7789796612dc1eed220983" -dependencies = [ - "alloy-eips", - "alloy-primitives 0.7.7", - "alloy-rpc-types-engine", - "serde", - "serde_with", - "thiserror", -] - -[[package]] -name = "alloy-rpc-types-engine" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff63f51b2fb2f547df5218527fd0653afb1947bf7fead5b3ce58c75d170b30f7" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives 0.7.7", - "alloy-rlp", - "alloy-rpc-types-eth", - "alloy-serde", - "jsonwebtoken", - "rand", - "serde", - "thiserror", -] - -[[package]] -name = "alloy-rpc-types-eth" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81e18424d962d7700a882fe423714bd5b9dde74c7a7589d4255ea64068773aef" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-network-primitives", - "alloy-primitives 0.7.7", - "alloy-rlp", - "alloy-serde", - "alloy-sol-types", - "itertools 0.13.0", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "alloy-rpc-types-trace" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a86eeb49ea0cc79f249faa1d35c20541bb1c317a59b5962cb07b1890355b0064" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-rpc-types-eth", - "alloy-serde", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "alloy-serde" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33feda6a53e6079895aed1d08dcb98a1377b000d80d16370fbbdb8155d547ef" -dependencies = [ - "alloy-primitives 0.7.7", - "serde", - "serde_json", -] - [[package]] name = "alloy-signer" -version = "0.2.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740a25b92e849ed7b0fa013951fe2f64be9af1ad5abe805037b44fb7770c5c47" +checksum = "67eca011160d18a7dc6d8cdc1e8dc13e2e86c908f8e41b02aa76e429d6fe7085" dependencies = [ - "alloy-primitives 0.7.7", + "alloy-primitives 0.8.9", "async-trait", "auto_impl", "elliptic-curve 0.13.8", @@ -550,181 +113,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "alloy-signer-local" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b0707d4f63e4356a110b30ef3add8732ab6d181dd7be4607bf79b8777105cee" -dependencies = [ - "alloy-consensus", - "alloy-network", - "alloy-primitives 0.7.7", - "alloy-signer", - "async-trait", - "k256 0.13.4", - "rand", - "thiserror", -] - -[[package]] -name = "alloy-sol-macro" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" -dependencies = [ - "alloy-sol-macro-expander", - "alloy-sol-macro-input", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "alloy-sol-macro-expander" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" -dependencies = [ - "alloy-json-abi", - "alloy-sol-macro-input", - "const-hex", - "heck", - "indexmap 2.6.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.79", - "syn-solidity", - "tiny-keccak", -] - -[[package]] -name = "alloy-sol-macro-input" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" -dependencies = [ - "alloy-json-abi", - "const-hex", - "dunce", - "heck", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.79", - "syn-solidity", -] - -[[package]] -name = "alloy-sol-type-parser" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" -dependencies = [ - "serde", - "winnow", -] - -[[package]] -name = "alloy-sol-types" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" -dependencies = [ - "alloy-json-abi", - "alloy-primitives 0.7.7", - "alloy-sol-macro", - "const-hex", - "serde", -] - -[[package]] -name = "alloy-transport" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0590afbdacf2f8cca49d025a2466f3b6584a016a8b28f532f29f8da1007bae" -dependencies = [ - "alloy-json-rpc", - "base64 0.22.1", - "futures-util", - "futures-utils-wasm", - "serde", - "serde_json", - "thiserror", - "tokio", - "tower", - "tracing", - "url", -] - -[[package]] -name = "alloy-transport-http" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2437d145d80ea1aecde8574d2058cceb8b3c9cba05f6aea8e67907c660d46698" -dependencies = [ - "alloy-json-rpc", - "alloy-transport", - "reqwest 0.12.8", - "serde_json", - "tower", - "tracing", - "url", -] - -[[package]] -name = "alloy-transport-ipc" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804494366e20468776db4e18f9eb5db7db0fe14f1271eb6dbf155d867233405c" -dependencies = [ - "alloy-json-rpc", - "alloy-pubsub", - "alloy-transport", - "bytes", - "futures", - "interprocess", - "pin-project", - "serde_json", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "alloy-transport-ws" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af855163e7df008799941aa6dd324a43ef2bf264b08ba4b22d44aad6ced65300" -dependencies = [ - "alloy-pubsub", - "alloy-transport", - "futures", - "http 1.1.0", - "rustls 0.23.14", - "serde_json", - "tokio", - "tokio-tungstenite", - "tracing", - "ws_stream_wasm", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anstream" version = "0.6.15" @@ -789,21 +177,6 @@ dependencies = [ "derive_arbitrary", ] -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - -[[package]] -name = "archery" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a8da9bc4c4053ee067669762bcaeea6e241841295a2b6c948312dad6ef4cc02" -dependencies = [ - "static_assertions", -] - [[package]] name = "ark-ff" version = "0.3.0" @@ -940,12 +313,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "asn1_der" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" - [[package]] name = "async-stream" version = "0.3.6" @@ -965,7 +332,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -976,19 +343,14 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] -name = "async_io_stream" -version = "0.3.3" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" -dependencies = [ - "futures", - "pharos", - "rustc_version 0.4.1", -] +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "auto_impl" @@ -998,7 +360,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1007,6 +369,80 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "aws-lc-rs" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd82dba44d209fddb11c190e0a94b78651f95299598e472215667417a03ff1d" +dependencies = [ + "aws-lc-sys", + "mirai-annotations", + "paste", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7a4168111d7eb622a31b214057b8509c0a7e1794f44c546d742330dc793972" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", + "libc", + "paste", +] + +[[package]] +name = "axum" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 1.0.1", + "tower 0.5.1", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.1", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -1019,15 +455,9 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - [[package]] name = "base16ct" version = "0.1.1" @@ -1046,12 +476,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -1065,10 +489,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] -name = "bimap" -version = "0.6.3" +name = "bindgen" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools 0.10.5", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.82", + "which", +] [[package]] name = "bit-set" @@ -1087,27 +528,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "bitvec" -version = "0.20.4" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" -dependencies = [ - "funty 1.1.0", - "radium 0.6.2", - "tap", - "wyz 0.2.0", -] +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -1115,10 +538,10 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "funty 2.0.0", - "radium 0.7.0", + "funty", + "radium", "tap", - "wyz 0.5.1", + "wyz", ] [[package]] @@ -1127,7 +550,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array", ] @@ -1140,12 +562,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls" version = "0.2.0" @@ -1153,7 +569,7 @@ source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff dependencies = [ "arbitrary", "blst", - "ethereum-types 0.14.1", + "ethereum-types", "ethereum_hashing", "ethereum_serde_utils", "ethereum_ssz", @@ -1177,11 +593,11 @@ dependencies = [ ] [[package]] -name = "bolt-delegations-cli" +name = "bolt" version = "0.1.0" dependencies = [ - "account_utils", - "alloy", + "alloy-primitives 0.8.9", + "alloy-signer", "blst", "clap", "dotenvy", @@ -1189,10 +605,18 @@ dependencies = [ "ethereum-consensus", "eyre", "hex", + "prost", + "reqwest", + "rustls", "serde", "serde_json", "tempfile", "thiserror", + "tokio", + "tonic", + "tonic-build", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1201,15 +625,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -1237,27 +652,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bzip2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "c-kzg" version = "1.0.3" @@ -1273,20 +667,6 @@ dependencies = [ "serde", ] -[[package]] -name = "cached_tree_hash" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "ethereum-types 0.14.1", - "ethereum_hashing", - "ethereum_ssz", - "ethereum_ssz_derive", - "smallvec", - "ssz_types", - "tree_hash", -] - [[package]] name = "cc" version = "1.1.30" @@ -1299,23 +679,19 @@ dependencies = [ ] [[package]] -name = "cfg-if" -version = "1.0.0" +name = "cexpr" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] [[package]] -name = "chrono" -version = "0.4.38" +name = "cfg-if" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "windows-targets 0.52.6", -] +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" @@ -1327,13 +703,14 @@ dependencies = [ ] [[package]] -name = "cipher" -version = "0.4.4" +name = "clang-sys" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ - "crypto-common", - "inout", + "glob", + "libc", + "libloading", ] [[package]] @@ -1355,8 +732,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", - "terminal_size", + "strsim", ] [[package]] @@ -1368,7 +744,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1378,20 +754,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] -name = "clap_utils" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" +name = "cmake" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" dependencies = [ - "clap", - "dirs", - "eth2_network_config", - "ethereum-types 0.14.1", - "ethereum_ssz", - "hex", - "serde", - "serde_json", - "serde_yaml 0.9.34+deprecated", - "types", + "cc", ] [[package]] @@ -1400,23 +768,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" -[[package]] -name = "compare_fields" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "itertools 0.10.5", -] - -[[package]] -name = "compare_fields_derive" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "const-hex" version = "1.13.1" @@ -1436,12 +787,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "convert_case" version = "0.4.0" @@ -1474,301 +819,78 @@ dependencies = [ ] [[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[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", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "crypto-mac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" -dependencies = [ - "cipher 0.3.0", -] - -[[package]] -name = "ctr" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" -dependencies = [ - "cipher 0.3.0", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version 0.4.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core 0.13.4", - "darling_macro 0.13.4", -] - -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core 0.20.10", - "darling_macro 0.20.10", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.11.1", - "syn 2.0.79", -] - -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core 0.13.4", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" +name = "cpufeatures" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ - "darling_core 0.20.10", - "quote", - "syn 2.0.79", + "libc", ] [[package]] -name = "dary_heap" -version = "0.3.6" +name = "crunchy" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] -name = "dashmap" -version = "5.5.3" +name = "crypto-bigint" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "cfg-if", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core 0.9.10", + "generic-array", + "rand_core", + "subtle", + "zeroize", ] [[package]] -name = "data-encoding" -version = "2.6.0" +name = "crypto-bigint" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] [[package]] -name = "data-encoding-macro" -version = "0.1.15" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "data-encoding", - "data-encoding-macro-internal", + "generic-array", + "typenum", ] [[package]] -name = "data-encoding-macro-internal" -version = "0.1.13" +name = "crypto-mac" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ - "data-encoding", - "syn 1.0.109", + "generic-array", + "subtle", ] [[package]] -name = "delay_map" -version = "0.3.0" +name = "ctr" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4355c25cbf99edcb6b4a0e906f6bdc6956eda149e84455bea49696429b2f8e8" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" dependencies = [ - "futures", - "tokio-util", + "cipher", ] [[package]] -name = "deposit_contract" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "ethabi", - "ethereum_ssz", - "hex", - "reqwest 0.11.27", - "serde_json", - "sha2 0.9.9", - "tree_hash", - "types", -] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "der" @@ -1790,16 +912,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", - "serde", -] - [[package]] name = "derivative" version = "2.2.0" @@ -1819,7 +931,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1832,7 +944,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1852,7 +964,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "unicode-xid", ] @@ -1877,94 +989,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "directory" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "clap", - "clap_utils", - "eth2_network_config", -] - -[[package]] -name = "dirs" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "discv5" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac33cb3f99889a57e56a8c6ccb77aaf0cfc7787602b7af09783f736d77314e1" -dependencies = [ - "aes 0.7.5", - "aes-gcm", - "arrayvec", - "delay_map", - "enr 0.10.0", - "fnv", - "futures", - "hashlink", - "hex", - "hkdf", - "lazy_static", - "libp2p", - "lru", - "more-asserts", - "parking_lot 0.11.2", - "rand", - "rlp", - "smallvec", - "socket2 0.4.10", - "tokio", - "tracing", - "uint", - "zeroize", -] - -[[package]] -name = "doctest-file" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aac81fa3e28d21450aa4d2ac065992ba96a1d7303efbce51a95f4fd175b67562" - [[package]] name = "dotenvy" version = "0.15.7" @@ -2003,31 +1027,6 @@ dependencies = [ "spki 0.7.3", ] -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek", - "ed25519", - "rand_core", - "serde", - "sha2 0.10.8", - "subtle", - "zeroize", -] - [[package]] name = "either" version = "1.13.0" @@ -2089,7 +1088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26fa0a0be8915790626d5759eb51fe47435a8eac92c2f212bd2da9aa7f30ea56" dependencies = [ "base64 0.13.1", - "bs58 0.4.0", + "bs58", "bytes", "hex", "k256 0.11.6", @@ -2097,26 +1096,7 @@ dependencies = [ "rand", "rlp", "serde", - "sha3 0.10.8", - "zeroize", -] - -[[package]] -name = "enr" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" -dependencies = [ - "base64 0.21.7", - "bytes", - "ed25519-dalek", - "hex", - "k256 0.13.4", - "log", - "rand", - "rlp", - "serde", - "sha3 0.10.8", + "sha3", "zeroize", ] @@ -2126,15 +1106,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "erased-serde" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" -dependencies = [ - "serde", -] - [[package]] name = "errno" version = "0.3.9" @@ -2145,29 +1116,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "eth2_config" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "paste", - "types", -] - -[[package]] -name = "eth2_interop_keypairs" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "bls", - "ethereum_hashing", - "hex", - "lazy_static", - "num-bigint", - "serde", - "serde_yaml 0.9.34+deprecated", -] - [[package]] name = "eth2_key_derivation" version = "0.1.0" @@ -2185,12 +1133,12 @@ name = "eth2_keystore" version = "0.1.0" source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" dependencies = [ - "aes 0.7.5", + "aes", "bls", "eth2_key_derivation", "hex", "hmac 0.11.0", - "pbkdf2 0.8.0", + "pbkdf2", "rand", "scrypt", "serde", @@ -2202,69 +1150,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "eth2_network_config" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "bytes", - "discv5", - "eth2_config", - "logging", - "pretty_reqwest_error", - "reqwest 0.11.27", - "sensitive_url", - "serde_yaml 0.9.34+deprecated", - "sha2 0.9.9", - "slog", - "types", - "url", - "zip", -] - -[[package]] -name = "eth2_wallet" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "eth2_key_derivation", - "eth2_keystore", - "rand", - "serde", - "serde_json", - "serde_repr", - "tiny-bip39", - "uuid", -] - -[[package]] -name = "ethabi" -version = "16.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c98847055d934070b90e806e12d3936b787d0a115068981c1d8dfd5dfef5a5" -dependencies = [ - "ethereum-types 0.12.1", - "hex", - "serde", - "serde_json", - "sha3 0.9.1", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb684ac8fa8f6c5759f788862bb22ec6fe3cb392f6bfd08e3c64b603661e3f8" -dependencies = [ - "crunchy", - "fixed-hash 0.7.0", - "impl-rlp", - "impl-serde 0.3.2", - "tiny-keccak", -] - [[package]] name = "ethbloom" version = "0.13.0" @@ -2272,9 +1157,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" dependencies = [ "crunchy", - "fixed-hash 0.8.0", + "fixed-hash", "impl-rlp", - "impl-serde 0.4.0", + "impl-serde", "tiny-keccak", ] @@ -2284,17 +1169,17 @@ version = "0.1.1" source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=cf3c404#cf3c404043230559660810bc0c9d6d5a8498d819" dependencies = [ "blst", - "bs58 0.4.0", + "bs58", "c-kzg", - "enr 0.6.2", + "enr", "hex", "integer-sqrt", - "multiaddr 0.14.0", - "multihash 0.16.3", + "multiaddr", + "multihash", "rand", "serde", "serde_json", - "serde_yaml 0.8.26", + "serde_yaml", "sha2 0.10.8", "ssz_rs", "thiserror", @@ -2302,31 +1187,17 @@ dependencies = [ "tokio-stream", ] -[[package]] -name = "ethereum-types" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05136f7057fe789f06e6d41d07b34e6f70d8c86e5693b60f97aaa6553553bdaf" -dependencies = [ - "ethbloom 0.11.1", - "fixed-hash 0.7.0", - "impl-rlp", - "impl-serde 0.3.2", - "primitive-types 0.10.1", - "uint", -] - [[package]] name = "ethereum-types" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ - "ethbloom 0.13.0", - "fixed-hash 0.8.0", + "ethbloom", + "fixed-hash", "impl-rlp", - "impl-serde 0.4.0", - "primitive-types 0.12.2", + "impl-serde", + "primitive-types", "uint", ] @@ -2348,7 +1219,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de4d5951468846963c24e8744c133d44f39dff2cd3a233f6be22b370d08a524f" dependencies = [ - "ethereum-types 0.14.1", + "ethereum-types", "hex", "serde", "serde_derive", @@ -2361,44 +1232,20 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d3627f83d8b87b432a5fad9934b4565260722a141a2c40f371f8080adec9425" dependencies = [ - "ethereum-types 0.14.1", + "ethereum-types", "itertools 0.10.5", "smallvec", ] -[[package]] -name = "ethereum_ssz_derive" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eccd5378ec34a07edd3d9b48088cbc63309d0367d14ba10b0cdb1d1791080ea" -dependencies = [ - "darling 0.13.4", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] [[package]] name = "fastrand" @@ -2437,50 +1284,12 @@ dependencies = [ "subtle", ] -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "field-offset" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" -dependencies = [ - "memoffset", - "rustc_version 0.4.1", -] - -[[package]] -name = "filesystem" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "winapi", - "windows-acl", -] - -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - [[package]] name = "fixed-hash" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ - "arbitrary", "byteorder", "rand", "rustc-hex", @@ -2488,14 +1297,10 @@ dependencies = [ ] [[package]] -name = "flate2" -version = "1.0.34" +name = "fixedbitset" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" -dependencies = [ - "crc32fast", - "miniz_oxide", -] +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "fnv" @@ -2534,20 +1339,10 @@ dependencies = [ ] [[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "funty" -version = "1.1.0" +name = "fs_extra" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "funty" @@ -2555,21 +1350,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" version = "0.3.31" @@ -2577,7 +1357,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -2586,35 +1365,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "futures-sink" version = "0.3.31" @@ -2627,36 +1377,18 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" - [[package]] name = "futures-util" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "futures-channel", "futures-core", - "futures-io", - "futures-macro", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", - "slab", ] -[[package]] -name = "futures-utils-wasm" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" - [[package]] name = "generic-array" version = "0.14.7" @@ -2675,20 +1407,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", -] - -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug", - "polyval", ] [[package]] @@ -2727,16 +1447,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.26" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", - "http 0.2.12", + "http", "indexmap 2.6.0", "slab", "tokio", @@ -2750,36 +1470,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] - [[package]] name = "hashbrown" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" dependencies = [ - "allocator-api2", - "equivalent", "foldhash", ] -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.5", -] - [[package]] name = "heck" version = "0.5.0" @@ -2792,12 +1491,6 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - [[package]] name = "hex" version = "0.4.3" @@ -2813,32 +1506,13 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac 0.12.1", -] - -[[package]] -name = "hmac" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ - "crypto-mac 0.11.0", + "crypto-mac", "digest 0.9.0", ] @@ -2852,25 +1526,12 @@ dependencies = [ ] [[package]] -name = "hmac-drbg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" -dependencies = [ - "digest 0.9.0", - "generic-array", - "hmac 0.8.1", -] - -[[package]] -name = "http" -version = "0.2.12" +name = "home" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "bytes", - "fnv", - "itoa", + "windows-sys 0.52.0", ] [[package]] @@ -2884,17 +1545,6 @@ 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" @@ -2902,7 +1552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http", ] [[package]] @@ -2913,8 +1563,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "pin-project-lite", ] @@ -2932,42 +1582,20 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.30" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", - "http 0.2.12", - "http-body 0.4.6", + "http", + "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "httparse", - "itoa", - "pin-project-lite", "smallvec", "tokio", "want", @@ -2975,29 +1603,32 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http 0.2.12", - "hyper 0.14.30", - "rustls 0.21.12", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", + "tower-service", ] [[package]] -name = "hyper-tls" -version = "0.5.0" +name = "hyper-timeout" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "bytes", - "hyper 0.14.30", - "native-tls", + "hyper", + "hyper-util", + "pin-project-lite", "tokio", - "tokio-native-tls", + "tower-service", ] [[package]] @@ -3008,7 +1639,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.4.1", + "hyper", "hyper-util", "native-tls", "tokio", @@ -3025,45 +1656,16 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "hyper 1.4.1", + "http", + "http-body", + "hyper", "pin-project-lite", - "socket2 0.5.7", + "socket2", "tokio", "tower-service", "tracing", ] -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.5.0" @@ -3074,22 +1676,13 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "impl-codec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" -dependencies = [ - "parity-scale-codec 2.3.1", -] - [[package]] name = "impl-codec" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.12", + "parity-scale-codec", ] [[package]] @@ -3101,15 +1694,6 @@ dependencies = [ "rlp", ] -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - [[package]] name = "impl-serde" version = "0.4.0" @@ -3144,7 +1728,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -3155,57 +1738,15 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown 0.15.0", - "serde", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "int_to_bytes" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "bytes", -] - -[[package]] -name = "integer-sqrt" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" -dependencies = [ - "num-traits", ] [[package]] -name = "interprocess" -version = "2.2.1" +name = "integer-sqrt" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f4e4a06d42fab3e85ab1b419ad32b09eab58b901d40c57935ff92db3287a13" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" dependencies = [ - "doctest-file", - "futures-core", - "libc", - "recvmsg", - "tokio", - "widestring 1.1.0", - "windows-sys 0.52.0", + "num-traits", ] [[package]] @@ -3214,17 +1755,6 @@ version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" -[[package]] -name = "is-terminal" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -3273,21 +1803,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonwebtoken" -version = "9.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" -dependencies = [ - "base64 0.21.7", - "js-sys", - "pem", - "ring 0.17.8", - "serde", - "serde_json", - "simple_asn1", -] - [[package]] name = "k256" version = "0.11.6" @@ -3311,7 +1826,6 @@ dependencies = [ "elliptic-curve 0.13.8", "once_cell", "sha2 0.10.8", - "signature 2.2.0", ] [[package]] @@ -3333,23 +1847,6 @@ dependencies = [ "sha3-asm", ] -[[package]] -name = "kzg" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "arbitrary", - "c-kzg", - "derivative", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", - "hex", - "serde", - "tree_hash", -] - [[package]] name = "lazy_static" version = "1.5.0" @@ -3360,33 +1857,25 @@ dependencies = [ ] [[package]] -name = "libc" -version = "0.2.159" +name = "lazycell" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] -name = "libflate" -version = "2.1.0" +name = "libc" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d9dfdc14ea4ef0900c1cddbc8dcd553fbaacd8a4a282cf4018ae9dd04fb21e" -dependencies = [ - "adler32", - "core2", - "crc32fast", - "dary_heap", - "libflate_lz77", -] +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] -name = "libflate_lz77" -version = "2.1.0" +name = "libloading" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ - "core2", - "hashbrown 0.14.5", - "rle-decode-fast", + "cfg-if", + "windows-targets", ] [[package]] @@ -3395,200 +1884,6 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" -[[package]] -name = "libp2p" -version = "0.53.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681fb3f183edfbedd7a57d32ebe5dcdc0b9f94061185acf3c30249349cc6fc99" -dependencies = [ - "bytes", - "either", - "futures", - "futures-timer", - "getrandom", - "instant", - "libp2p-allow-block-list", - "libp2p-connection-limits", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "multiaddr 0.18.2", - "pin-project", - "rw-stream-sink", - "thiserror", -] - -[[package]] -name = "libp2p-allow-block-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107b238b794cb83ab53b74ad5dcf7cca3200899b72fe662840cfb52f5b0a32e6" -dependencies = [ - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "void", -] - -[[package]] -name = "libp2p-connection-limits" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7cd50a78ccfada14de94cbacd3ce4b0138157f376870f13d3a8422cd075b4fd" -dependencies = [ - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "void", -] - -[[package]] -name = "libp2p-core" -version = "0.41.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5a8920cbd8540059a01950c1e5c96ea8d89eb50c51cd366fc18bdf540a6e48f" -dependencies = [ - "either", - "fnv", - "futures", - "futures-timer", - "libp2p-identity", - "multiaddr 0.18.2", - "multihash 0.19.1", - "multistream-select", - "once_cell", - "parking_lot 0.12.3", - "pin-project", - "quick-protobuf", - "rand", - "rw-stream-sink", - "smallvec", - "thiserror", - "tracing", - "unsigned-varint 0.8.0", - "void", - "web-time", -] - -[[package]] -name = "libp2p-identity" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" -dependencies = [ - "asn1_der", - "bs58 0.5.1", - "ed25519-dalek", - "hkdf", - "libsecp256k1", - "multihash 0.19.1", - "quick-protobuf", - "rand", - "sha2 0.10.8", - "thiserror", - "tracing", - "zeroize", -] - -[[package]] -name = "libp2p-swarm" -version = "0.44.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80cae6cb75f89dbca53862f9ebe0b9f463aa7b302762fcfaafb9e51dcc9b0f7e" -dependencies = [ - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-core", - "libp2p-identity", - "lru", - "multistream-select", - "once_cell", - "rand", - "smallvec", - "tracing", - "void", -] - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.6.0", - "libc", -] - -[[package]] -name = "libsecp256k1" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" -dependencies = [ - "arrayref", - "base64 0.13.1", - "digest 0.9.0", - "hmac-drbg", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", - "rand", - "serde", - "sha2 0.9.9", - "typenum", -] - -[[package]] -name = "libsecp256k1-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" -dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle", -] - -[[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsecp256k1-gen-genmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsqlite3-sys" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "lighthouse_metrics" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "prometheus", -] - [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3611,138 +1906,23 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "lockfile" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "fs2", -] - [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "logging" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "chrono", - "lazy_static", - "lighthouse_metrics", - "parking_lot 0.12.3", - "serde", - "serde_json", - "slog", - "slog-term", - "sloggers", - "take_mut", - "tokio", - "tracing", - "tracing-appender", - "tracing-core", - "tracing-log", - "tracing-subscriber", -] - -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown 0.15.0", -] - -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "merkle_proof" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "ethereum-types 0.14.1", - "ethereum_hashing", - "lazy_static", - "safe_arith", -] - -[[package]] -name = "metastruct" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00a5ba4a0f3453c31c397b214e1675d95b697c33763aa58add57ea833424384" -dependencies = [ - "metastruct_macro", -] - -[[package]] -name = "metastruct_macro" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a991d4536c933306e52f0e8ab303757185ec13a09d1f3e1cbde5a0d8410bf" -dependencies = [ - "darling 0.13.4", - "itertools 0.10.5", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", -] - -[[package]] -name = "milhouse" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3826d3602a3674b07e080ce1982350e454ec253d73f156bd927ac1b652293f4d" -dependencies = [ - "arbitrary", - "derivative", - "ethereum-types 0.14.1", - "ethereum_hashing", - "ethereum_ssz", - "ethereum_ssz_derive", - "itertools 0.10.5", - "parking_lot 0.12.3", - "rayon", - "serde", - "smallvec", - "tree_hash", - "triomphe", - "typenum", - "vec_map", -] +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -3750,6 +1930,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -3765,17 +1951,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", ] [[package]] -name = "more-asserts" -version = "0.3.1" +name = "mirai-annotations" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" +checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" [[package]] name = "multiaddr" @@ -3784,47 +1970,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c580bfdd8803cce319b047d239559a22f809094aaea4ac13902a1fdcfcd4261" dependencies = [ "arrayref", - "bs58 0.4.0", + "bs58", "byteorder", "data-encoding", - "multihash 0.16.3", + "multihash", "percent-encoding", "serde", "static_assertions", - "unsigned-varint 0.7.2", + "unsigned-varint", "url", ] -[[package]] -name = "multiaddr" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" -dependencies = [ - "arrayref", - "byteorder", - "data-encoding", - "libp2p-identity", - "multibase", - "multihash 0.19.1", - "percent-encoding", - "serde", - "static_assertions", - "unsigned-varint 0.8.0", - "url", -] - -[[package]] -name = "multibase" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" -dependencies = [ - "base-x", - "data-encoding", - "data-encoding-macro", -] - [[package]] name = "multihash" version = "0.16.3" @@ -3835,17 +1991,7 @@ dependencies = [ "digest 0.10.7", "multihash-derive", "sha2 0.10.8", - "unsigned-varint 0.7.2", -] - -[[package]] -name = "multihash" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" -dependencies = [ - "core2", - "unsigned-varint 0.7.2", + "unsigned-varint", ] [[package]] @@ -3863,18 +2009,10 @@ dependencies = [ ] [[package]] -name = "multistream-select" -version = "0.13.0" +name = "multimap" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19" -dependencies = [ - "bytes", - "futures", - "log", - "pin-project", - "smallvec", - "unsigned-varint 0.7.2", -] +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "native-tls" @@ -3893,6 +2031,16 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -3931,12 +2079,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - [[package]] name = "num-integer" version = "0.1.46" @@ -3973,30 +2115,10 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] -[[package]] -name = "num_enum" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "object" version = "0.36.5" @@ -4020,11 +2142,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -4041,7 +2163,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -4050,24 +2172,14 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "300.3.2+3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -4078,20 +2190,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parity-scale-codec" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" -dependencies = [ - "arrayvec", - "bitvec 0.20.4", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive 2.3.1", - "serde", -] - [[package]] name = "parity-scale-codec" version = "3.6.12" @@ -4099,25 +2197,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", - "bitvec 1.0.1", + "bitvec", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.12", + "parity-scale-codec-derive", "serde", ] -[[package]] -name = "parity-scale-codec-derive" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" -dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "parity-scale-codec-derive" version = "3.6.12" @@ -4130,17 +2216,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.3" @@ -4148,21 +2223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -4173,20 +2234,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall", "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core", - "subtle", + "windows-targets", ] [[package]] @@ -4201,29 +2251,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" dependencies = [ - "crypto-mac 0.11.0", -] - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", - "hmac 0.12.1", - "password-hash", - "sha2 0.10.8", -] - -[[package]] -name = "pem" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" -dependencies = [ - "base64 0.22.1", - "serde", + "crypto-mac", ] [[package]] @@ -4244,13 +2272,13 @@ dependencies = [ ] [[package]] -name = "pharos" -version = "0.5.3" +name = "petgraph" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ - "futures", - "rustc_version 0.4.1", + "fixedbitset", + "indexmap 2.6.0", ] [[package]] @@ -4270,7 +2298,7 @@ checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -4311,24 +2339,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" -[[package]] -name = "polyval" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.20" @@ -4339,25 +2349,13 @@ dependencies = [ ] [[package]] -name = "pretty_reqwest_error" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "reqwest 0.11.27", - "sensitive_url", -] - -[[package]] -name = "primitive-types" -version = "0.10.1" +name = "prettyplease" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +checksum = "910d41a655dac3b764f1ade94821093d3610248694320cd072303a8eedcf221d" dependencies = [ - "fixed-hash 0.7.0", - "impl-codec 0.5.1", - "impl-rlp", - "impl-serde 0.3.2", - "uint", + "proc-macro2", + "syn 2.0.82", ] [[package]] @@ -4366,10 +2364,10 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ - "fixed-hash 0.8.0", - "impl-codec 0.6.0", + "fixed-hash", + "impl-codec", "impl-rlp", - "impl-serde 0.4.0", + "impl-serde", "uint", ] @@ -4425,21 +2423,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prometheus" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" -dependencies = [ - "cfg-if", - "fnv", - "lazy_static", - "memchr", - "parking_lot 0.12.3", - "protobuf", - "thiserror", -] - [[package]] name = "proptest" version = "1.5.0" @@ -4448,39 +2431,77 @@ checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.6.0", + "bitflags", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.5", + "regex-syntax", "rusty-fork", "tempfile", "unarray", ] [[package]] -name = "protobuf" -version = "2.28.0" +name = "prost" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +dependencies = [ + "bytes", + "prost-derive", +] [[package]] -name = "quick-error" -version = "1.2.3" +name = "prost-build" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" +dependencies = [ + "bytes", + "heck", + "itertools 0.13.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.82", + "tempfile", +] [[package]] -name = "quick-protobuf" -version = "0.8.1" +name = "prost-derive" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" dependencies = [ - "byteorder", + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "prost-types" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" +dependencies = [ + "prost", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.37" @@ -4490,12 +2511,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" - [[package]] name = "radium" version = "0.7.0" @@ -4541,59 +2556,13 @@ dependencies = [ "rand_core", ] -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "recvmsg" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175" - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", + "bitflags", ] [[package]] @@ -4604,17 +2573,8 @@ checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -4625,67 +2585,15 @@ checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[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", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.30", - "hyper-rustls", - "hyper-tls 0.5.0", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", - "tokio", - "tokio-native-tls", - "tokio-rustls 0.24.1", - "tokio-util", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots 0.25.4", - "winreg", -] - [[package]] name = "reqwest" version = "0.12.8" @@ -4694,13 +2602,16 @@ checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" dependencies = [ "base64 0.22.1", "bytes", + "encoding_rs", "futures-core", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "h2", + "http", + "http-body", "http-body-util", - "hyper 1.4.1", - "hyper-tls 0.6.0", + "hyper", + "hyper-rustls", + "hyper-tls", "hyper-util", "ipnet", "js-sys", @@ -4710,11 +2621,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -4776,12 +2688,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rle-decode-fast" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" - [[package]] name = "rlp" version = "0.5.2" @@ -4792,25 +2698,6 @@ dependencies = [ "rustc-hex", ] -[[package]] -name = "rpassword" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "rpds" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ef5140bcb576bfd6d56cd2de709a7d17851ac1f3805e67fe9d99e42a11821f" -dependencies = [ - "archery", -] - [[package]] name = "ruint" version = "1.12.3" @@ -4824,8 +2711,8 @@ dependencies = [ "fastrlp", "num-bigint", "num-traits", - "parity-scale-codec 3.6.12", - "primitive-types 0.12.2", + "parity-scale-codec", + "primitive-types", "proptest", "rand", "rlp", @@ -4841,20 +2728,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" -[[package]] -name = "rusqlite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" -dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -4867,6 +2740,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -4897,7 +2776,7 @@ version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -4906,39 +2785,20 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.12" +version = "0.23.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" dependencies = [ + "aws-lc-rs", "log", - "ring 0.17.8", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" -version = "0.23.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" -dependencies = [ "once_cell", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.8", + "rustls-webpki", "subtle", "zeroize", ] -[[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.2.0" @@ -4950,19 +2810,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" - -[[package]] -name = "rustls-webpki" -version = "0.101.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -4970,6 +2820,7 @@ version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ + "aws-lc-rs", "ring 0.17.8", "rustls-pki-types", "untrusted 0.9.0", @@ -4977,9 +2828,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rusty-fork" @@ -4993,35 +2844,19 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "rw-stream-sink" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c9026ff5d2f23da5e45bbc283f156383001bfb09c4e44256d02c1a685fe9a1" -dependencies = [ - "futures", - "pin-project", - "static_assertions", -] - [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "safe_arith" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" - [[package]] name = "salsa20" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecbd2eb639fd7cab5804a0837fe373cc2172d15437e804c054a9fb885cb923b0" dependencies = [ - "cipher 0.3.0", + "cipher", ] [[package]] @@ -5046,21 +2881,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879588d8f90906e73302547e20fffefdd240eb3e0e744e142321f5d49dea0518" dependencies = [ "hmac 0.11.0", - "pbkdf2 0.8.0", + "pbkdf2", "salsa20", "sha2 0.9.9", ] -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - [[package]] name = "sec1" version = "0.3.0" @@ -5095,7 +2920,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -5136,21 +2961,6 @@ dependencies = [ "pest", ] -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - -[[package]] -name = "sensitive_url" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "serde", - "url", -] - [[package]] name = "serde" version = "1.0.210" @@ -5168,7 +2978,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5191,7 +3001,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5206,36 +3016,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.6.0", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" -dependencies = [ - "darling 0.20.10", - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "serde_yaml" version = "0.8.26" @@ -5248,30 +3028,6 @@ dependencies = [ "yaml-rust", ] -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.6.0", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - [[package]] name = "sha2" version = "0.9.9" @@ -5292,207 +3048,81 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "sha3-asm" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" -dependencies = [ - "cc", - "cfg-if", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -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", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core", -] - -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror", - "time", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", + "cpufeatures", + "digest 0.10.7", ] [[package]] -name = "slog" -version = "2.7.0" +name = "sha3" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "erased-serde", + "digest 0.10.7", + "keccak", ] [[package]] -name = "slog-async" -version = "2.8.0" +name = "sha3-asm" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c8038f898a2c79507940990f05386455b3a317d8f18d4caea7cbc3d5096b84" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" dependencies = [ - "crossbeam-channel", - "slog", - "take_mut", - "thread_local", + "cc", + "cfg-if", ] [[package]] -name = "slog-json" -version = "2.6.1" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e1e53f61af1e3c8b852eef0a9dee29008f55d6dd63794f3f12cef786cf0f219" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "serde", - "serde_json", - "slog", - "time", + "lazy_static", ] [[package]] -name = "slog-kvfilter" -version = "0.7.0" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae939ed7d169eed9699f4f5cd440f046f5dc5dfc27c19e3cd311619594c175e0" -dependencies = [ - "regex", - "slog", -] +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "slog-scope" -version = "4.4.0" +name = "signal-hook-registry" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f95a4b4c3274cd2869549da82b57ccc930859bdbf5bcea0424bc5f140b3c786" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ - "arc-swap", - "lazy_static", - "slog", + "libc", ] [[package]] -name = "slog-stdlog" -version = "4.1.1" +name = "signature" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6706b2ace5bbae7291d3f8d2473e2bfab073ccd7d03670946197aec98471fa3e" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "log", - "slog", - "slog-scope", + "digest 0.10.7", + "rand_core", ] [[package]] -name = "slog-term" -version = "2.9.1" +name = "signature" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6e022d0b998abfe5c3782c1f03551a596269450ccd677ea51c56f8b214610e8" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "is-terminal", - "slog", - "term", - "thread_local", - "time", + "digest 0.10.7", + "rand_core", ] [[package]] -name = "sloggers" -version = "2.2.0" +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75062c2738b82cd45ae633623caae3393f43eb00aada1dc2d3ebe88db6b0db9b" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "chrono", - "libc", - "libflate", - "once_cell", - "regex", - "serde", - "slog", - "slog-async", - "slog-json", - "slog-kvfilter", - "slog-scope", - "slog-stdlog", - "slog-term", - "trackable", - "winapi", - "windows-acl", + "autocfg", ] [[package]] @@ -5501,16 +3131,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.7" @@ -5559,7 +3179,7 @@ version = "0.9.0" source = "git+https://github.com/ralexstokes/ssz-rs?rev=84ef2b71aa004f6767420badb42c902ad56b8b72#84ef2b71aa004f6767420badb42c902ad56b8b72" dependencies = [ "alloy-primitives 0.7.7", - "bitvec 1.0.1", + "bitvec", "serde", "sha2 0.9.9", "ssz_rs_derive", @@ -5575,99 +3195,24 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "ssz_types" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625b20de2d4b3891e6972f4ce5061cb11bd52b3479270c4b177c134b571194a9" -dependencies = [ - "arbitrary", - "derivative", - "ethereum_serde_utils", - "ethereum_ssz", - "itertools 0.10.5", - "serde", - "serde_derive", - "smallvec", - "tree_hash", - "typenum", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.79", -] - [[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "superstruct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4e1f478a7728f8855d7e620e9a152cf8932c6614f86564c886f9b8141f3201" -dependencies = [ - "darling 0.13.4", - "itertools 0.10.5", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", -] - -[[package]] -name = "swap_or_not_shuffle" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "ethereum-types 0.14.1", - "ethereum_hashing", -] - [[package]] name = "syn" version = "1.0.109" @@ -5681,27 +3226,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn-solidity" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" -dependencies = [ - "paste", - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "sync_wrapper" version = "0.1.2" @@ -5731,31 +3264,25 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ "core-foundation-sys", "libc", ] -[[package]] -name = "take_mut" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" - [[package]] name = "tap" version = "1.0.1" @@ -5775,36 +3302,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "term" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" -dependencies = [ - "dirs-next", - "rustversion", - "winapi", -] - -[[package]] -name = "terminal_size" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" -dependencies = [ - "rustix", - "windows-sys 0.59.0", -] - -[[package]] -name = "test_random_derive" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "thiserror" version = "1.0.64" @@ -5822,7 +3319,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5844,56 +3341,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "time" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tiny-bip39" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" -dependencies = [ - "anyhow", - "hmac 0.12.1", - "once_cell", - "pbkdf2 0.11.0", - "rand", - "rustc-hash", - "sha2 0.10.8", - "thiserror", - "unicode-normalization", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "tiny-keccak" version = "2.0.2" @@ -5920,18 +3367,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", "libc", "mio", - "parking_lot 0.12.3", + "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2", "tokio-macros", "windows-sys 0.52.0", ] @@ -5944,7 +3391,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -5957,23 +3404,13 @@ 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.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.14", + "rustls", "rustls-pki-types", "tokio", ] @@ -5987,23 +3424,6 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6989540ced10490aaf14e6bad2e3d33728a2813310a0c71d1574304c49631cd" -dependencies = [ - "futures-util", - "log", - "rustls 0.23.14", - "rustls-pki-types", - "tokio", - "tokio-rustls 0.26.0", - "tungstenite", - "webpki-roots 0.26.6", ] [[package]] @@ -6016,7 +3436,6 @@ dependencies = [ "futures-core", "futures-sink", "pin-project-lite", - "slab", "tokio", ] @@ -6046,6 +3465,52 @@ dependencies = [ "winnow", ] +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "rustls-pemfile", + "socket2", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn 2.0.82", +] + [[package]] name = "tower" version = "0.4.13" @@ -6054,11 +3519,30 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", - "pin-project", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", "pin-project-lite", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -6079,24 +3563,11 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-appender" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" -dependencies = [ - "crossbeam-channel", - "thiserror", - "time", - "tracing-subscriber", -] - [[package]] name = "tracing-attributes" version = "0.1.27" @@ -6105,7 +3576,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -6135,150 +3606,37 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ - "matchers", "nu-ansi-term", - "once_cell", - "regex", "sharded-slab", "smallvec", "thread_local", - "tracing", "tracing-core", "tracing-log", ] -[[package]] -name = "trackable" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15bd114abb99ef8cee977e517c8f37aee63f184f2d08e3e6ceca092373369ae" -dependencies = [ - "trackable_derive", -] - -[[package]] -name = "trackable_derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebeb235c5847e2f82cfe0f07eb971d1e5f6804b18dac2ae16349cc604380f82f" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "tree_hash" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "134d6b24a5b829f30b5ee7de05ba7384557f5f6b00e29409cdf2392f93201bfa" dependencies = [ - "ethereum-types 0.14.1", + "ethereum-types", "ethereum_hashing", "smallvec", ] -[[package]] -name = "tree_hash_derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce7bccc538359a213436af7bc95804bdbf1c2a21d80e22953cbe9e096837ff1" -dependencies = [ - "darling 0.13.4", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "triomphe" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" -dependencies = [ - "serde", - "stable_deref_trait", -] - [[package]] name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tungstenite" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 1.1.0", - "httparse", - "log", - "rand", - "rustls 0.23.14", - "rustls-pki-types", - "sha1", - "thiserror", - "utf-8", -] - [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "types" -version = "0.2.1" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "arbitrary", - "bls", - "cached_tree_hash", - "compare_fields", - "compare_fields_derive", - "derivative", - "eth2_interop_keypairs", - "ethereum-types 0.14.1", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", - "hex", - "int_to_bytes", - "itertools 0.10.5", - "kzg", - "lazy_static", - "log", - "maplit", - "merkle_proof", - "metastruct", - "milhouse", - "parking_lot 0.12.3", - "rand", - "rand_xorshift", - "rayon", - "regex", - "rpds", - "rusqlite", - "safe_arith", - "serde", - "serde_json", - "serde_yaml 0.9.34+deprecated", - "slog", - "smallvec", - "ssz_types", - "superstruct", - "swap_or_not_shuffle", - "tempfile", - "test_random_derive", - "tree_hash", - "tree_hash_derive", -] - [[package]] name = "ucd-trie" version = "0.1.7" @@ -6291,7 +3649,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ - "arbitrary", "byteorder", "crunchy", "hex", @@ -6331,34 +3688,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "universal-hash" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - [[package]] name = "unsigned-varint" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" -[[package]] -name = "unsigned-varint" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" - [[package]] name = "untrusted" version = "0.7.1" @@ -6382,12 +3717,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "utf8parse" version = "0.2.2" @@ -6404,24 +3733,6 @@ dependencies = [ "serde", ] -[[package]] -name = "validator_dir" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?rev=a87f19d#a87f19d801a57b1d6ff101750840294c210ff956" -dependencies = [ - "bls", - "deposit_contract", - "derivative", - "directory", - "eth2_keystore", - "filesystem", - "hex", - "lockfile", - "rand", - "tree_hash", - "types", -] - [[package]] name = "valuable" version = "0.1.0" @@ -6434,24 +3745,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "wait-timeout" version = "0.2.0" @@ -6498,7 +3797,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "wasm-bindgen-shared", ] @@ -6532,7 +3831,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6543,19 +3842,6 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" -[[package]] -name = "wasm-streams" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "web-sys" version = "0.3.72" @@ -6567,42 +3853,17 @@ dependencies = [ ] [[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[package]] -name = "webpki-roots" -version = "0.26.6" +name = "which" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ - "rustls-pki-types", + "either", + "home", + "once_cell", + "rustix", ] -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - -[[package]] -name = "widestring" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" - [[package]] name = "winapi" version = "0.3.9" @@ -6625,27 +3886,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-acl" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177b1723986bcb4c606058e77f6e8614b51c7f9ad2face6f6fd63dd5c8b3cec3" -dependencies = [ - "field-offset", - "libc", - "widestring 0.4.3", - "winapi", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-registry" version = "0.2.0" @@ -6654,7 +3894,7 @@ checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ "windows-result", "windows-strings", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -6663,7 +3903,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -6673,16 +3913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ "windows-result", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", + "windows-targets", ] [[package]] @@ -6691,7 +3922,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -6700,22 +3931,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -6724,46 +3940,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -6776,48 +3974,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -6833,41 +4007,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "ws_stream_wasm" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" -dependencies = [ - "async_io_stream", - "futures", - "js-sys", - "log", - "pharos", - "rustc_version 0.4.1", - "send_wrapper", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "wyz" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" - [[package]] name = "wyz" version = "0.5.1" @@ -6904,7 +4043,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -6924,54 +4063,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", -] - -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "aes 0.8.4", - "byteorder", - "bzip2", - "constant_time_eq", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac 0.12.1", - "pbkdf2 0.11.0", - "sha1", - "time", - "zstd", -] - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" -dependencies = [ - "cc", - "pkg-config", + "syn 2.0.82", ] diff --git a/bolt-delegations-cli/Cargo.toml b/bolt-cli/Cargo.toml similarity index 56% rename from bolt-delegations-cli/Cargo.toml rename to bolt-cli/Cargo.toml index 9fb05a9f3..526ffeec9 100644 --- a/bolt-delegations-cli/Cargo.toml +++ b/bolt-cli/Cargo.toml @@ -1,30 +1,42 @@ [package] -name = "bolt-delegations-cli" +name = "bolt" version = "0.1.0" edition = "2021" [dependencies] +# async +tokio = { version = "1.41.0", features = ["full"] } + +# cli clap = { version = "4.5.4", features = ["derive", "env"] } serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.115" -ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "cf3c404" } -alloy = { version = "0.2.0", features = [ - "full", - "provider-trace-api", - "rpc-types-beacon", - "rpc-types-engine", -] } + +# grpc +rustls = { version = "0.23.15", features = ["ring"] } +tonic = { version = "0.12.3", features = ["tls"] } +prost = "0.13.3" + +# crypto blst = "0.3.12" +# ethereum +ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "cf3c404" } +lighthouse_eth2_keystore = { package = "eth2_keystore", git = "https://github.com/sigp/lighthouse", rev = "a87f19d" } +alloy-primitives = "0.8.9" +alloy-signer = "0.5.2" + # utils dotenvy = "0.15.7" eyre = "0.6.12" thiserror = "1.0" hex = "0.4.3" - -# lighthouse -lighthouse_eth2_keystore = { package = "eth2_keystore", git = "https://github.com/sigp/lighthouse", rev = "a87f19d" } -lighthouse_account_utils = { package = "account_utils", git = "https://github.com/sigp/lighthouse", rev = "a87f19d" } +tracing = "0.1.40" +tracing-subscriber = "0.3.18" [dev-dependencies] -tempfile = "3.13.0" \ No newline at end of file +tempfile = "3.13.0" +reqwest = "0.12.8" + +[build-dependencies] +tonic-build = "0.12.3" diff --git a/bolt-cli/README.md b/bolt-cli/README.md new file mode 100644 index 000000000..6f40376d0 --- /dev/null +++ b/bolt-cli/README.md @@ -0,0 +1,214 @@ +# Bolt CLI + +The Bolt CLI is a collection of command-line tools for interacting with Bolt protocol. + +## Installation + +Prerequisites: + +- [Rust toolchain][rust] +- [Protoc][protoc] + +Once you have the necessary prerequisites, you can build the binary in the following way: + +```shell +# clone the Bolt repository if you haven't already +git clone git@github.com:chainbound/bolt.git + +# navigate to the Bolt CLI package directory +cd bolt-cli + +# build and install the binary on your machine +cargo install --path . --force + +# test the installation +bolt --version +``` + +## Usage + +Available commands: + +- [`delegate`](#delegate) - Generate BLS delegation messages for the Constraints API. +- [`pubkeys`](#pubkeys) - List available BLS public keys from various key sources. + +All above commands support three key sources: + +- Local BLS secret keys (as hex-encoded strings) via `secret-keys` +- Local EIP-2335 filesystem keystore directories via `local-keystore` +- Remote Dirk keystore via `dirk` (requires TLS credentials) + +--- + +### `Delegate` + +The `delegate` command generates signed delegation messages for the Constraints API. +To learn more about the Constraints API, please refer to the [Bolt documentation][bolt-docs]. + +
+Usage + +```text +❯ bolt delegate --help + +Generate BLS delegation or revocation messages + +Usage: bolt delegate [OPTIONS] --delegatee-pubkey + +Commands: +secret-keys Use local secret keys to generate the signed messages +local-keystore Use an EIP-2335 filesystem keystore directory to generate the signed messages +dirk Use a remote DIRK keystore to generate the signed messages +help Print this message or the help of the given subcommand(s) + +Options: + --delegatee-pubkey + The BLS public key to which the delegation message should be signed + + [env: DELEGATEE_PUBKEY=] + + --out + The output file for the delegations + + [env: OUTPUT_FILE_PATH=] + [default: delegations.json] + + --chain + The chain for which the delegation message is intended + + [env: CHAIN=] + [default: mainnet] + [possible values: mainnet, holesky, helder, kurtosis] + + --action + The action to perform. The tool can be used to generate delegation or revocation messages (default: delegate) + + [env: ACTION=] + [default: delegate] + + Possible values: + - delegate: Create a delegation message + - revoke: Create a revocation message + +-h, --help + Print help (see a summary with '-h') +``` + +
+ +
+Examples + +1. Generating a delegation using a local BLS secret key + +```text +bolt delegate \ + --delegatee-pubkey 0x8d0edf4fe9c80cd640220ca7a68a48efcbc56a13536d6b274bf3719befaffa13688ebee9f37414b3dddc8c7e77233ce8 \ + --chain holesky \ + secret-keys --secret-keys 642e0d33fde8968a48b5f560c1b20143eb82036c1aa6c7f4adc4beed919a22e3 +``` + +2. Generating a delegation using an ERC-2335 keystore directory + +```text +bolt delegate \ + --delegatee-pubkey 0x8d0edf4fe9c80cd640220ca7a68a48efcbc56a13536d6b274bf3719befaffa13688ebee9f37414b3dddc8c7e77233ce8 \ + --chain holesky \ + local-keystore --path test_data/lighthouse/validators --password-path test_data/lighthouse/secrets +``` + +3. Generating a delegation using a remote DIRK keystore + +```text +bolt delegate \ + --delegatee-pubkey 0x83eeddfac5e60f8fe607ee8713efb8877c295ad9f8ca075f4d8f6f2ae241a30dd57f78f6f3863a9fe0d5b5db9d550b93 \ + --chain holesky \ + dirk --url https://localhost:9091 \ + --client-cert-path ./test_data/dirk/client1.crt \ + --client-key-path ./test_data/dirk/client1.key \ + --ca-cert-path ./test_data/dirk/security/ca.crt \ + --wallet-path wallet1 --passphrases secret +``` + +
+ +--- + +### `Pubkeys` + +The `pubkeys` command lists available BLS public keys from different key sources. + +
+Usage + +```text +❯ bolt pubkeys --help + +Output a list of pubkeys in JSON format + +Usage: bolt pubkeys [OPTIONS] + +Commands: + secret-keys Use local secret keys to generate the signed messages + local-keystore Use an EIP-2335 filesystem keystore directory to generate the signed messages + dirk Use a remote DIRK keystore to generate the signed messages + help Print this message or the help of the given subcommand(s) + +Options: + --out The output file for the pubkeys [env: OUTPUT_FILE_PATH=] [default: pubkeys.json] + -h, --help Print help +``` + +
+ +
+Examples + +1. Listing BLS public keys from a local secret key + +```text +bolt pubkeys secret-keys --secret-keys 642e0d33fde8968a48b5f560c1b20143eb82036c1aa6c7f4adc4beed919a22e3 +``` + +2. Listing BLS public keys from an ERC-2335 keystore directory + +```text +bolt pubkeys local-keystore \ + --path test_data/lighthouse/validators \ + --password-path test_data/lighthouse/secrets +``` + +3. Listing BLS public keys from a remote DIRK keystore + +```text +bolt pubkeys dirk --url https://localhost:9091 \ + --client-cert-path ./test_data/dirk/client1.crt \ + --client-key-path ./test_data/dirk/client1.key \ + --ca-cert-path ./test_data/dirk/security/ca.crt \ + --wallet-path wallet1 --passphrases secret +``` + +
+ +--- + +## Security + +The Bolt CLI is designed to be used offline. It does not require any network connections +unless you are using the remote `dirk` key source. In that case, the tool will connect to +the Dirk server with the provided TLS credentials. + +The tool does not store any sensitive information beyond the duration of the execution. +It is recommended to use the tool in a secure environment and to avoid storing any sensitive +information in the shell history. + +If you have any security concerns or have found a security issue/bug, please contact Chainbound +on our official [Discord][discord] or [Twitter][twitter] channels. + + + +[rust]: https://www.rust-lang.org/tools/install +[protoc]: https://grpc.io/docs/protoc-installation/ +[bolt-docs]: https://docs.boltprotocol.xyz/ +[discord]: https://discord.gg/G5BJjCD9ss +[twitter]: https://twitter.com/chainbound_ diff --git a/bolt-cli/build.rs b/bolt-cli/build.rs new file mode 100644 index 000000000..9342cfe4c --- /dev/null +++ b/bolt-cli/build.rs @@ -0,0 +1,21 @@ +use std::{fs, io, path::Path}; + +const PB_OUT_DIR: &str = "src/pb"; + +// Perform the code generation for the protobuf files. +fn main() -> io::Result<()> { + // create the /src/pb directory if it doesn't exist + if !Path::new(PB_OUT_DIR).exists() { + fs::create_dir(PB_OUT_DIR)?; + } + + tonic_build::configure().build_client(true).out_dir(PB_OUT_DIR).compile_protos( + &[ + "proto/eth2-signer-api/v1/lister.proto", + "proto/eth2-signer-api/v1/signer.proto", + "proto/eth2-signer-api/v1/accountmanager.proto", + "proto/eth2-signer-api/v1/walletmanager.proto", + ], + &["proto/eth2-signer-api/v1/", "proto/eth2-signer-api/"], + ) +} diff --git a/bolt-cli/proto/README.md b/bolt-cli/proto/README.md new file mode 100644 index 000000000..450eae729 --- /dev/null +++ b/bolt-cli/proto/README.md @@ -0,0 +1,7 @@ +# Protobuf definitions + +## Eth2 signer API + +The definitions in this folder are taken from the [eth2-signer-api][eth2-signer-api] package. + +[eth2-signer-api]: https://github.com/wealdtech/eth2-signer-api/tree/4aaf36e54f4e62d0cf4edc1b794e9a6354cf4f95/pb/v1 diff --git a/bolt-cli/proto/eth2-signer-api/google/api/annotations.proto b/bolt-cli/proto/eth2-signer-api/google/api/annotations.proto new file mode 100644 index 000000000..85c361b47 --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright (c) 2015, Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/bolt-cli/proto/eth2-signer-api/google/api/http.proto b/bolt-cli/proto/eth2-signer-api/google/api/http.proto new file mode 100644 index 000000000..2bd3a19bf --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/google/api/http.proto @@ -0,0 +1,318 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parmeters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// `HttpRule` defines the mapping of an RPC method to one or more HTTP +// REST API methods. The mapping specifies how different portions of the RPC +// request message are mapped to URL path, URL query parameters, and +// HTTP request body. The mapping is typically specified as an +// `google.api.http` annotation on the RPC method, +// see "google/api/annotations.proto" for details. +// +// The mapping consists of a field specifying the path template and +// method kind. The path template can refer to fields in the request +// message, as in the example below which describes a REST GET +// operation on a resource collection of messages: +// +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // mapped to the URL +// SubMessage sub = 2; // `sub.subfield` is url-mapped +// } +// message Message { +// string text = 1; // content of the resource +// } +// +// The same http annotation can alternatively be expressed inside the +// `GRPC API Configuration` YAML file. +// +// http: +// rules: +// - selector: .Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// This definition enables an automatic, bidrectional mapping of HTTP +// JSON to RPC. Example: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` +// +// In general, not only fields but also field paths can be referenced +// from a path pattern. Fields mapped to the path pattern cannot be +// repeated and must have a primitive (non-message) type. +// +// Any fields in the request message which are not bound by the path +// pattern automatically become (optional) HTTP query +// parameters. Assume the following definition of the request message: +// +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http).get = "/v1/messages/{message_id}"; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // mapped to the URL +// int64 revision = 2; // becomes a parameter +// SubMessage sub = 3; // `sub.subfield` becomes a parameter +// } +// +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` +// +// Note that fields which are mapped to HTTP parameters must have a +// primitive type or a repeated primitive type. Message types are not +// allowed. In the case of a repeated type, the parameter can be +// repeated in the URL, as in `...?param=A¶m=B`. +// +// For HTTP method kinds which allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// put: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | RPC +// -----|----- +// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// put: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | RPC +// -----|----- +// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice of +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// +// This enables the following two alternative HTTP JSON to RPC +// mappings: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` +// +// # Rules for HTTP mapping +// +// The rules for mapping HTTP path, query parameters, and body fields +// to the request message are as follows: +// +// 1. The `body` field specifies either `*` or a field path, or is +// omitted. If omitted, it indicates there is no HTTP request body. +// 2. Leaf fields (recursive expansion of nested messages in the +// request) can be classified into three types: +// (a) Matched in the URL template. +// (b) Covered by body (if body is `*`, everything except (a) fields; +// else everything under the body field) +// (c) All other fields. +// 3. URL query parameters found in the HTTP request are mapped to (c) fields. +// 4. Any body sent with an HTTP request can contain only (b) fields. +// +// The syntax of the path template is as follows: +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single path segment. The syntax `**` matches zero +// or more path segments, which must be the last part of the path except the +// `Verb`. The syntax `LITERAL` matches literal text in the path. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path, all characters +// except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the +// Discovery Document as `{var}`. +// +// If a variable contains one or more path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path, all +// characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables +// show up in the Discovery Document as `{+var}`. +// +// NOTE: While the single segment variable matches the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 +// Simple String Expansion, the multi segment variable **does not** match +// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. +// +// NOTE: the field paths in variables and in the `body` must not refer to +// repeated fields or map fields. +message HttpRule { + // Selects methods to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Used for listing and getting information about resources. + string get = 2; + + // Used for updating a resource. + string put = 3; + + // Used for creating a resource. + string post = 4; + + // Used for deleting a resource. + string delete = 5; + + // Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP body, or + // `*` for mapping all fields not captured by the path pattern to the HTTP + // body. NOTE: the referred field must not be a repeated field and must be + // present at the top-level of request message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // body of response. Other response fields are ignored. When + // not set, the response message will be used as HTTP body of response. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/bolt-cli/proto/eth2-signer-api/v1/accountmanager.proto b/bolt-cli/proto/eth2-signer-api/v1/accountmanager.proto new file mode 100644 index 000000000..6ca3abb8e --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/v1/accountmanager.proto @@ -0,0 +1,65 @@ +syntax = "proto3"; + +package v1; + +import "google/api/annotations.proto"; +import "responsestate.proto"; +import "endpoint.proto"; + +option csharp_namespace = "Eth2Signer.v1"; +option php_namespace = "Eth2Signer\\v1"; +option go_package = "github.com/wealdtech/eth2-signer-api/pb/v1"; +option java_package = "com.wealdtech.eth2signerapi.v1"; +option java_multiple_files = true; +option java_outer_classname = "AccountManagerProto"; + +service AccountManager { + rpc Unlock(UnlockAccountRequest) returns (UnlockAccountResponse) { + option (google.api.http) = { + get: "/v1/accountmanager/unlock" + }; + } + + rpc Lock(LockAccountRequest) returns (LockAccountResponse) { + option (google.api.http) = { + get: "/v1/accountmanager/lock" + }; + } + + rpc Generate(GenerateRequest) returns (GenerateResponse) { + option (google.api.http) = { + post: "/v1/accountmanager/generate" + }; + } +} + +message UnlockAccountRequest { + string account = 1; + bytes passphrase = 2; +} + +message LockAccountRequest { + string account = 1; +} + +message UnlockAccountResponse { + ResponseState state = 1; +} + +message LockAccountResponse { + ResponseState state = 1; +} + +message GenerateRequest { + string account = 1; + bytes passphrase = 2; + uint32 participants = 3; + uint32 signing_threshold = 4; +} + +message GenerateResponse { + ResponseState state = 1; + string message = 2; + bytes public_key = 3; + repeated Endpoint participants = 4; +} diff --git a/bolt-cli/proto/eth2-signer-api/v1/dkg.proto b/bolt-cli/proto/eth2-signer-api/v1/dkg.proto new file mode 100644 index 000000000..e335a4b78 --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/v1/dkg.proto @@ -0,0 +1,70 @@ +syntax = "proto3"; + +package v1; + +import "google/protobuf/empty.proto"; +import "endpoint.proto"; + +option csharp_namespace = "Eth2Signer.v1"; +option php_namespace = "Eth2Signer\\v1"; +option go_package = "github.com/wealdtech/eth2-signer-api/pb/v1"; +option java_package = "com.wealdtech.eth2signerapi.v1"; +option java_multiple_files = true; +option java_outer_classname = "DKGProto"; + +// DKG is the internal protocol that runs between distributed key generators. +service DKG { + rpc Prepare(PrepareRequest) returns (google.protobuf.Empty) { } + rpc Execute(ExecuteRequest) returns (google.protobuf.Empty) { } + rpc Commit(CommitRequest) returns (CommitResponse) { } + rpc Abort(AbortRequest) returns (google.protobuf.Empty) { } + rpc Contribute(ContributeRequest) returns (ContributeResponse) { } +} + +message PrepareRequest { + // account is the name of the account. + string account = 1; + // threshold is the number of participants required to generate a valid signature. + uint32 threshold = 2; + // participants contains the endpoints of all participants. + repeated Endpoint participants = 3; + // passphrase is the passphrase of the account. + bytes passphrase = 4; +} + +message ExecuteRequest { + // account is the name of the account. + string account = 1; +} + +message CommitRequest { + // account is the name of the account. + string account = 1; + // confirmation data is data used to generate the confirmation signature. + bytes confirmation_data = 2; +} + +message CommitResponse { + // public_key is the key generated by the process. + bytes public_key = 1; + // confirmation_signature is the signature generated by the individual secret key. + bytes confirmation_signature = 2; +} + +message AbortRequest { + // account is the name of the account. + string account = 1; +} + +// ContributeRequest is sent by each part to all other parties with a contribution. +message ContributeRequest { + string account = 1; + bytes secret = 2; + repeated bytes verification_vector = 3; +} + +// ContributeResponse receives the contribution from a participant. +message ContributeResponse { + bytes secret = 1; + repeated bytes verification_vector = 2; +} diff --git a/bolt-cli/proto/eth2-signer-api/v1/endpoint.proto b/bolt-cli/proto/eth2-signer-api/v1/endpoint.proto new file mode 100644 index 000000000..e61f84aea --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/v1/endpoint.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package v1; + +option csharp_namespace = "Eth2Signer.v1"; +option php_namespace = "Eth2Signer\\v1"; +option go_package = "github.com/wealdtech/eth2-signer-api/pb/v1"; +option java_package = "com.wealdtech.eth2signerapi.v1"; +option java_multiple_files = true; +option java_outer_classname = "EndpointProto"; + +message Endpoint { + uint64 id = 1; + string name = 2; + uint32 port = 3; +} diff --git a/bolt-cli/proto/eth2-signer-api/v1/eth2.proto b/bolt-cli/proto/eth2-signer-api/v1/eth2.proto new file mode 100644 index 000000000..615ba814d --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/v1/eth2.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package v1; + +option csharp_namespace = "Eth2Signer.v1"; +option php_namespace = "Eth2Signer\\v1"; +option go_package = "github.com/wealdtech/eth2-signer-api/pb/v1"; +option java_package = "com.wealdtech.eth2signerapi.v1"; +option java_multiple_files = true; +option java_outer_classname = "Eth2Proto"; + +// AttestationData is defined at https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#attestationdata +message AttestationData { + uint64 slot = 1; + uint64 committee_index = 2; + bytes beacon_block_root = 3; + Checkpoint source = 4; + Checkpoint target = 5; +} + +// Checkpoint is defined at https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#checkpoint +message Checkpoint { + uint64 epoch = 1; + bytes root = 2; +} + +// BeaconBlockheader is defined at https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblockheader +message BeaconBlockHeader { + uint64 slot = 1; + uint64 proposer_index = 2; + bytes parent_root = 3; + bytes state_root = 4; + bytes body_root = 5; +} diff --git a/bolt-cli/proto/eth2-signer-api/v1/lister.proto b/bolt-cli/proto/eth2-signer-api/v1/lister.proto new file mode 100644 index 000000000..46640d5cb --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/v1/lister.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +package v1; + +import "google/api/annotations.proto"; +import "endpoint.proto"; +import "responsestate.proto"; + +option csharp_namespace = "Eth2Signer.v1"; +option php_namespace = "Eth2Signer\\v1"; +option go_package = "github.com/wealdtech/eth2-signer-api/pb/v1"; +option java_package = "com.wealdtech.eth2signerapi.v1"; +option java_multiple_files = true; +option java_outer_classname = "ListerProto"; + +service Lister { + rpc ListAccounts(ListAccountsRequest) returns (ListAccountsResponse) { + option (google.api.http) = { + get: "/v1/lister/listaccounts" + }; + } +} + +message ListAccountsRequest { + repeated string paths = 1; +} + +message ListAccountsResponse { + ResponseState state = 1; + repeated Account Accounts = 2; + repeated DistributedAccount DistributedAccounts = 3; +} + +message Account { + string name = 1; + bytes public_key = 2; + bytes uuid = 3; +} + +message DistributedAccount { + string name = 1; + bytes public_key = 2; + repeated Endpoint participants = 3; + uint32 signing_threshold = 4; + bytes uuid = 5; + bytes composite_public_key = 6; +} diff --git a/bolt-cli/proto/eth2-signer-api/v1/responsestate.proto b/bolt-cli/proto/eth2-signer-api/v1/responsestate.proto new file mode 100644 index 000000000..8eb57d9ea --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/v1/responsestate.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package v1; + +option csharp_namespace = "Eth2Signer.v1"; +option php_namespace = "Eth2Signer\\v1"; +option go_package = "github.com/wealdtech/eth2-signer-api/pb/v1"; +option java_package = "com.wealdtech.eth2signerapi.v1"; +option java_multiple_files = true; +option java_outer_classname = "ResponseStateProto"; + +enum ResponseState { + // UNKNOWN occurs when no information about the response is available. + UNKNOWN = 0; + // SUCCEEDED occurs when a request was successful. + SUCCEEDED = 1; + // DENIED occurs when a request was denied. + DENIED = 2; + // FAILED occurs when a request failed to complete. + FAILED = 3; +} diff --git a/bolt-cli/proto/eth2-signer-api/v1/signer.proto b/bolt-cli/proto/eth2-signer-api/v1/signer.proto new file mode 100644 index 000000000..02612063c --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/v1/signer.proto @@ -0,0 +1,86 @@ +syntax = "proto3"; + +package v1; + +import "google/api/annotations.proto"; +import "eth2.proto"; +import "responsestate.proto"; + +option csharp_namespace = "Eth2Signer.v1"; +option php_namespace = "Eth2Signer\\v1"; +option go_package = "github.com/wealdtech/eth2-signer-api/pb/v1"; +option java_package = "com.wealdtech.eth2signerapi.v1"; +option java_multiple_files = true; +option java_outer_classname = "SignerProto"; + +service Signer { + rpc Sign(SignRequest) returns (SignResponse) { + option (google.api.http) = { + get: "/v1/signer/sign" + }; + } + rpc Multisign(MultisignRequest) returns (MultisignResponse) { + option (google.api.http) = { + get: "/v1/signer/multisign" + }; + } + rpc SignBeaconAttestation(SignBeaconAttestationRequest) returns (SignResponse) { + option (google.api.http) = { + get: "/v1/signer/signbeaconattestation" + }; + } + rpc SignBeaconAttestations(SignBeaconAttestationsRequest) returns (MultisignResponse) { + option (google.api.http) = { + get: "/v1/signer/signbeaconattestations" + }; + } + rpc SignBeaconProposal(SignBeaconProposalRequest) returns (SignResponse) { + option (google.api.http) = { + get: "/v1/signer/signbeaconproposal" + }; + } +} + +message SignRequest { + oneof id { + bytes public_key = 1; + string account = 2; + } + bytes data = 3; + bytes domain = 4; +} + +message MultisignRequest { + repeated SignRequest requests = 1; +} + +message SignBeaconAttestationRequest { + oneof id { + bytes public_key = 1; + string account = 2; + } + bytes domain = 3; + AttestationData data = 4; +} + +message SignBeaconAttestationsRequest { + repeated SignBeaconAttestationRequest requests = 1; +} + +message SignBeaconProposalRequest { + oneof id { + bytes public_key = 1; + string account = 2; + } + bytes domain = 3; + BeaconBlockHeader data = 4; +} + +message SignResponse { + ResponseState state = 1; + bytes signature = 2; +} + +message MultisignResponse { + repeated SignResponse responses = 1; +} diff --git a/bolt-cli/proto/eth2-signer-api/v1/walletmanager.proto b/bolt-cli/proto/eth2-signer-api/v1/walletmanager.proto new file mode 100644 index 000000000..98a5d8a03 --- /dev/null +++ b/bolt-cli/proto/eth2-signer-api/v1/walletmanager.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package v1; + +import "google/api/annotations.proto"; +import "responsestate.proto"; + +option csharp_namespace = "Eth2Signer.v1"; +option php_namespace = "Eth2Signer\\v1"; +option java_package = "com.wealdtech.eth2signerapi.v1"; +option go_package = "github.com/wealdtech/eth2-signer-api/pb/v1"; +option java_multiple_files = true; +option java_outer_classname = "WalletManagerProto"; + +service WalletManager { + rpc Unlock(UnlockWalletRequest) returns (UnlockWalletResponse) { + option (google.api.http) = { + get: "/v1/walletmanager/unlock" + }; + } + rpc Lock(LockWalletRequest) returns (LockWalletResponse) { + option (google.api.http) = { + get: "/v1/walletmanager/lock" + }; + } +} + +message UnlockWalletRequest { + string wallet = 1; + bytes passphrase = 2; +} + +message LockWalletRequest { + string wallet = 1; +} + +message UnlockWalletResponse { + ResponseState state = 1; +} + +message LockWalletResponse { + ResponseState state = 1; +} diff --git a/bolt-delegations-cli/rustfmt.toml b/bolt-cli/rustfmt.toml similarity index 100% rename from bolt-delegations-cli/rustfmt.toml rename to bolt-cli/rustfmt.toml diff --git a/bolt-cli/src/cli.rs b/bolt-cli/src/cli.rs new file mode 100644 index 000000000..1f387988c --- /dev/null +++ b/bolt-cli/src/cli.rs @@ -0,0 +1,181 @@ +use clap::{Parser, Subcommand, ValueEnum}; +use serde::Deserialize; + +use crate::utils::keystore::DEFAULT_KEYSTORE_PASSWORD; + +/// A CLI tool to interact with Bolt Protocol ✨ +#[derive(Parser, Debug, Clone, Deserialize)] +#[command(author, version, about, long_about = None)] +pub struct Opts { + /// The subcommand to run. + #[clap(subcommand)] + pub command: Commands, +} + +#[derive(Subcommand, Debug, Clone, Deserialize)] +pub enum Commands { + /// Generate BLS delegation or revocation messages. + Delegate { + /// The BLS public key to which the delegation message should be signed. + #[clap(long, env = "DELEGATEE_PUBKEY")] + delegatee_pubkey: String, + + /// The output file for the delegations. + #[clap(long, env = "OUTPUT_FILE_PATH", default_value = "delegations.json")] + out: String, + + /// The chain for which the delegation message is intended. + #[clap(long, env = "CHAIN", default_value = "mainnet")] + chain: Chain, + + /// The action to perform. The tool can be used to generate + /// delegation or revocation messages (default: delegate). + #[clap(long, env = "ACTION", default_value = "delegate")] + action: Action, + + /// The source of the private key. + #[clap(subcommand)] + source: KeySource, + }, + + /// Output a list of pubkeys in JSON format. + Pubkeys { + /// The output file for the pubkeys. + #[clap(long, env = "OUTPUT_FILE_PATH", default_value = "pubkeys.json")] + out: String, + + /// The source of the private keys from which to extract the pubkeys. + #[clap(subcommand)] + source: KeySource, + }, +} + +/// The action to perform. +#[derive(Debug, Clone, ValueEnum, Deserialize)] +#[clap(rename_all = "kebab_case")] +pub enum Action { + /// Create a delegation message. + Delegate, + /// Create a revocation message. + Revoke, +} + +#[derive(Debug, Clone, Parser, Deserialize)] +pub enum KeySource { + /// Use local secret keys to generate the signed messages. + SecretKeys { + /// The private key in hex format. + /// Multiple secret keys must be seperated by commas. + #[clap(long, env = "SECRET_KEYS", value_delimiter = ',', hide_env_values = true)] + secret_keys: Vec, + }, + + /// Use an EIP-2335 filesystem keystore directory to generate the signed messages. + LocalKeystore { + /// The options for reading the keystore directory. + #[clap(flatten)] + opts: LocalKeystoreOpts, + }, + + /// Use a remote DIRK keystore to generate the signed messages. + Dirk { + /// The options for connecting to the DIRK keystore. + #[clap(flatten)] + opts: DirkOpts, + }, +} + +/// Options for reading a keystore folder. +#[derive(Debug, Clone, Deserialize, Parser)] +pub struct LocalKeystoreOpts { + /// The path to the keystore file. + #[clap(long, env = "KEYSTORE_PATH", default_value = "validators")] + pub path: String, + + /// The password for the keystore files in the path. + /// Assumes all keystore files have the same password. + #[clap( + long, + env = "KEYSTORE_PASSWORD", + hide_env_values = true, + default_value = DEFAULT_KEYSTORE_PASSWORD, + conflicts_with = "password_path" + )] + pub password: Option, + + #[clap( + long, + env = "KEYSTORE_PASSWORD_PATH", + default_value = "secrets", + conflicts_with = "password" + )] + pub password_path: Option, +} + +/// Options for connecting to a DIRK keystore. +#[derive(Debug, Clone, Deserialize, Parser)] +pub struct DirkOpts { + /// The URL of the DIRK keystore. + #[clap(long, env = "DIRK_URL")] + pub url: String, + + /// The path of the wallets in the DIRK keystore. + #[clap(long, env = "DIRK_WALLET_PATH")] + pub wallet_path: String, + + /// The passphrases to unlock the wallet in the DIRK keystore. + /// If multiple are provided, they are tried in order until one works. + #[clap(long, env = "DIRK_PASSPHRASES", value_delimiter = ',', hide_env_values = true)] + pub passphrases: Option>, + + /// The TLS credentials for connecting to the DIRK keystore. + #[clap(flatten)] + pub tls_credentials: TlsCredentials, +} + +/// TLS credentials for connecting to a remote server. +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Parser)] +pub struct TlsCredentials { + /// Path to the client certificate file. (.crt) + #[clap(long, env = "CLIENT_CERT_PATH")] + pub client_cert_path: String, + /// Path to the client key file. (.key) + #[clap(long, env = "CLIENT_KEY_PATH")] + pub client_key_path: String, + /// Path to the CA certificate file. (.crt) + #[clap(long, env = "CA_CERT_PATH")] + pub ca_cert_path: Option, +} + +/// Supported chains for the CLI +#[derive(Debug, Clone, Copy, ValueEnum, Deserialize)] +#[clap(rename_all = "kebab_case")] +pub enum Chain { + Mainnet, + Holesky, + Helder, + Kurtosis, +} + +impl Chain { + /// Get the fork version for the given chain. + pub fn fork_version(&self) -> [u8; 4] { + match self { + Chain::Mainnet => [0, 0, 0, 0], + Chain::Holesky => [1, 1, 112, 0], + Chain::Helder => [16, 0, 0, 0], + Chain::Kurtosis => [16, 0, 0, 56], + } + } +} + +#[cfg(test)] +mod tests { + use super::Opts; + + #[test] + pub fn verify_cli() { + use clap::CommandFactory; + Opts::command().debug_assert() + } +} diff --git a/bolt-cli/src/delegation.rs b/bolt-cli/src/delegation.rs new file mode 100644 index 000000000..239c6871c --- /dev/null +++ b/bolt-cli/src/delegation.rs @@ -0,0 +1,322 @@ +use alloy_primitives::B256; +use alloy_signer::k256::sha2::{Digest, Sha256}; +use ethereum_consensus::crypto::{ + PublicKey as BlsPublicKey, SecretKey as BlsSecretKey, Signature as BlsSignature, +}; +use eyre::{bail, Result}; +use lighthouse_eth2_keystore::Keystore; +use serde::Serialize; +use tracing::{debug, warn}; + +use crate::{ + cli::{Action, Chain}, + utils::{ + dirk::Dirk, + keystore::{keystore_paths, KeystoreError, KeystoreSecret}, + signing::{ + compute_commit_boost_signing_root, compute_domain_from_mask, verify_commit_boost_root, + }, + }, +}; + +/// Generate signed delegations/revocations using local BLS private keys +/// +/// - Use the provided private keys from either CLI or env variable +/// - Create message +/// - Compute the signing roots and sign the messages +/// - Return the signed messages +pub fn generate_from_local_keys( + secret_keys: &[String], + delegatee_pubkey: BlsPublicKey, + chain: &Chain, + action: Action, +) -> Result> { + let mut signed_messages = Vec::with_capacity(secret_keys.len()); + + for sk in secret_keys { + let sk = BlsSecretKey::try_from(sk.trim().to_string())?; + + match action { + Action::Delegate => { + let message = DelegationMessage::new(sk.public_key(), delegatee_pubkey.clone()); + let signing_root = compute_commit_boost_signing_root(message.digest(), chain)?; + let signature = sk.sign(signing_root.0.as_ref()); + let signed = SignedDelegation { message, signature }; + signed_messages.push(SignedMessage::Delegation(signed)) + } + Action::Revoke => { + let message = RevocationMessage::new(sk.public_key(), delegatee_pubkey.clone()); + let signing_root = compute_commit_boost_signing_root(message.digest(), chain)?; + let signature = sk.sign(signing_root.0.as_ref()); + let signed = SignedRevocation { message, signature }; + signed_messages.push(SignedMessage::Revocation(signed)); + } + } + } + + Ok(signed_messages) +} + +/// Generate signed delegations/revocations using a keystore file +/// +/// - Read the keystore file +/// - Decrypt the keypairs using the password +/// - Create messages +/// - Compute the signing roots and sign the message +/// - Return the signed message +pub fn generate_from_keystore( + keys_path: &str, + keystore_secret: KeystoreSecret, + delegatee_pubkey: BlsPublicKey, + chain: Chain, + action: Action, +) -> Result> { + let keystores_paths = keystore_paths(keys_path)?; + let mut signed_messages = Vec::with_capacity(keystores_paths.len()); + debug!("Found {} keys in the keystore", keystores_paths.len()); + + for path in keystores_paths { + let ks = Keystore::from_json_file(path).map_err(KeystoreError::Eth2Keystore)?; + let password = keystore_secret.get(ks.pubkey()).ok_or(KeystoreError::MissingPassword)?; + let kp = ks.decrypt_keypair(password.as_bytes()).map_err(KeystoreError::Eth2Keystore)?; + let validator_pubkey = BlsPublicKey::try_from(kp.pk.serialize().to_vec().as_ref())?; + let validator_private_key = kp.sk; + + match action { + Action::Delegate => { + let message = DelegationMessage::new(validator_pubkey, delegatee_pubkey.clone()); + let signing_root = compute_commit_boost_signing_root(message.digest(), &chain)?; + let signature = validator_private_key.sign(signing_root.0.into()); + let signature = BlsSignature::try_from(signature.serialize().as_ref())?; + let signed = SignedDelegation { message, signature }; + signed_messages.push(SignedMessage::Delegation(signed)); + } + Action::Revoke => { + let message = RevocationMessage::new(validator_pubkey, delegatee_pubkey.clone()); + let signing_root = compute_commit_boost_signing_root(message.digest(), &chain)?; + let signature = validator_private_key.sign(signing_root.0.into()); + let signature = BlsSignature::try_from(signature.serialize().as_ref())?; + let signed = SignedRevocation { message, signature }; + signed_messages.push(SignedMessage::Revocation(signed)); + } + } + } + + Ok(signed_messages) +} + +/// Generate signed delegations/revocations using a remote Dirk signer +pub async fn generate_from_dirk( + dirk: &mut Dirk, + delegatee_pubkey: BlsPublicKey, + account_path: String, + passphrases: Option>, + chain: Chain, + action: Action, +) -> Result> { + // first read the accounts from the remote keystore + let accounts = dirk.list_accounts(account_path).await?; + debug!("Found {} remote accounts to sign with", accounts.len()); + + let mut signed_messages = Vec::with_capacity(accounts.len()); + + // specify the signing domain (needs to be included in the signing request) + let domain = B256::from(compute_domain_from_mask(chain.fork_version())); + + for account in accounts { + // for each available pubkey we control, sign a delegation message + let pubkey = BlsPublicKey::try_from(account.public_key.as_slice())?; + + // Note: before signing, we must unlock the account + if let Some(ref passphrases) = passphrases { + for passphrase in passphrases { + if dirk.unlock_account(account.name.clone(), passphrase.clone()).await? { + break; + } + } + } else { + bail!("A passphrase is required in order to sign messages remotely with Dirk"); + } + + match action { + Action::Delegate => { + let message = DelegationMessage::new(pubkey.clone(), delegatee_pubkey.clone()); + let signing_root = message.digest().into(); // Dirk does the hash tree root internally + let signature = dirk.request_signature(&account, signing_root, domain).await?; + let signed = SignedDelegation { message, signature }; + signed_messages.push(SignedMessage::Delegation(signed)); + } + Action::Revoke => { + let message = RevocationMessage::new(pubkey.clone(), delegatee_pubkey.clone()); + let signing_root = message.digest().into(); // Dirk does the hash tree root internally + let signature = dirk.request_signature(&account, signing_root, domain).await?; + let signed = SignedRevocation { message, signature }; + signed_messages.push(SignedMessage::Revocation(signed)); + } + } + + // Try to lock the account back after signing + if let Err(err) = dirk.lock_account(account.name.clone()).await { + warn!("Failed to lock account after signing {}: {:?}", account.name, err); + } + } + + Ok(signed_messages) +} + +/// Event types that can be emitted by the validator pubkey to +/// signal some action on the Bolt protocol. +#[derive(Debug, Clone, Copy)] +#[repr(u8)] +enum SignedMessageAction { + /// Signal delegation of a validator pubkey to a delegatee pubkey. + Delegation, + /// Signal revocation of a previously delegated pubkey. + Revocation, +} + +/// Transparent serialization of signed messages. +/// This is used to serialize and deserialize signed messages +/// +/// e.g. serde_json::to_string(&signed_message): +/// ``` +/// { +/// "message": { +/// "action": 0, +/// "validator_pubkey": "0x...", +/// "delegatee_pubkey": "0x..." +/// }, +/// "signature": "0x..." +/// }, +/// ``` +#[derive(Debug, Clone, Serialize, PartialEq, Eq)] +#[serde(untagged)] +pub enum SignedMessage { + Delegation(SignedDelegation), + Revocation(SignedRevocation), +} + +#[derive(Debug, Clone, Serialize, PartialEq, Eq)] +pub struct SignedDelegation { + pub message: DelegationMessage, + pub signature: BlsSignature, +} + +#[derive(Debug, Clone, Serialize, PartialEq, Eq)] +pub struct DelegationMessage { + action: u8, + pub validator_pubkey: BlsPublicKey, + pub delegatee_pubkey: BlsPublicKey, +} + +impl DelegationMessage { + /// Create a new delegation message. + pub fn new(validator_pubkey: BlsPublicKey, delegatee_pubkey: BlsPublicKey) -> Self { + Self { action: SignedMessageAction::Delegation as u8, validator_pubkey, delegatee_pubkey } + } + + /// Compute the digest of the delegation message. + pub fn digest(&self) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.update([self.action]); + hasher.update(self.validator_pubkey.to_vec()); + hasher.update(self.delegatee_pubkey.to_vec()); + + hasher.finalize().into() + } +} + +#[derive(Debug, Clone, Serialize, PartialEq, Eq)] +pub struct SignedRevocation { + pub message: RevocationMessage, + pub signature: BlsSignature, +} + +#[derive(Debug, Clone, Serialize, PartialEq, Eq)] +pub struct RevocationMessage { + action: u8, + pub validator_pubkey: BlsPublicKey, + pub delegatee_pubkey: BlsPublicKey, +} + +impl RevocationMessage { + /// Create a new revocation message. + pub fn new(validator_pubkey: BlsPublicKey, delegatee_pubkey: BlsPublicKey) -> Self { + Self { action: SignedMessageAction::Revocation as u8, validator_pubkey, delegatee_pubkey } + } + + /// Compute the digest of the revocation message. + pub fn digest(&self) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.update([self.action]); + hasher.update(self.validator_pubkey.to_vec()); + hasher.update(self.delegatee_pubkey.to_vec()); + + hasher.finalize().into() + } +} + +/// Verify the signature of a signed message +pub fn verify_message_signature(message: &SignedMessage, chain: Chain) -> Result<()> { + match message { + SignedMessage::Delegation(signed_delegation) => { + let signer_pubkey = signed_delegation.message.validator_pubkey.clone(); + let digest = signed_delegation.message.digest(); + + let blst_sig = + blst::min_pk::Signature::from_bytes(signed_delegation.signature.as_ref()) + .map_err(|e| eyre::eyre!("Failed to parse signature: {:?}", e))?; + + // Verify the signature + verify_commit_boost_root(signer_pubkey, digest, &blst_sig, &chain) + } + SignedMessage::Revocation(signed_revocation) => { + let signer_pubkey = signed_revocation.message.validator_pubkey.clone(); + let digest = signed_revocation.message.digest(); + + let blst_sig = + blst::min_pk::Signature::from_bytes(signed_revocation.signature.as_ref()) + .map_err(|e| eyre::eyre!("Failed to parse signature: {:?}", e))?; + + // Verify the signature + verify_commit_boost_root(signer_pubkey, digest, &blst_sig, &chain) + } + } +} + +#[cfg(test)] +mod tests { + use crate::{ + cli::{Action, Chain}, + utils::{keystore::KeystoreSecret, parse_bls_public_key}, + }; + + use super::{generate_from_keystore, verify_message_signature}; + + #[test] + fn test_delegation_keystore_signer_lighthouse() -> eyre::Result<()> { + // Read the keystore from test_data + let keys_path = env!("CARGO_MANIFEST_DIR").to_string() + "/test_data/lighthouse/validators"; + let secrets_path = env!("CARGO_MANIFEST_DIR").to_string() + "/test_data/lighthouse/secrets"; + + let keystore_secret = KeystoreSecret::from_directory(&secrets_path)?; + + let delegatee_pubkey = "0x83eeddfac5e60f8fe607ee8713efb8877c295ad9f8ca075f4d8f6f2ae241a30dd57f78f6f3863a9fe0d5b5db9d550b93"; + let delegatee_pubkey = parse_bls_public_key(delegatee_pubkey)?; + let chain = Chain::Mainnet; + + let signed_delegations = generate_from_keystore( + &keys_path, + keystore_secret, + delegatee_pubkey.clone(), + chain, + Action::Delegate, + )?; + + let signed_message = signed_delegations.first().expect("to get signed delegation"); + + verify_message_signature(signed_message, chain)?; + + Ok(()) + } +} diff --git a/bolt-cli/src/main.rs b/bolt-cli/src/main.rs new file mode 100644 index 000000000..6bdfecfc7 --- /dev/null +++ b/bolt-cli/src/main.rs @@ -0,0 +1,122 @@ +use clap::Parser; +use eyre::Result; + +/// CLI commands and options. +mod cli; +use cli::{Commands, KeySource, Opts}; + +/// Module for generating delegation/revocation messages for BLS keys. +mod delegation; + +/// Module for listing BLS pubkeys from various sources. +mod pubkeys; + +/// Utility functions and helpers for the CLI. +mod utils; +use tracing::debug; +use utils::{dirk::Dirk, keystore::KeystoreSecret, parse_bls_public_key, write_to_file}; + +/// Protocol Buffers definitions generated by `prost`. +mod pb; + +#[tokio::main] +async fn main() -> Result<()> { + let _ = dotenvy::dotenv(); + let _ = tracing_subscriber::fmt::try_init(); + + let cli = Opts::parse(); + + // Init the default rustls provider for Dirk + let _ = rustls::crypto::ring::default_provider().install_default(); + + match cli.command { + Commands::Delegate { delegatee_pubkey, out, chain, source, action } => match source { + KeySource::SecretKeys { secret_keys } => { + let delegatee_pubkey = parse_bls_public_key(&delegatee_pubkey)?; + let signed_messages = delegation::generate_from_local_keys( + &secret_keys, + delegatee_pubkey, + &chain, + action, + )?; + + // Verify signatures + for message in &signed_messages { + delegation::verify_message_signature(message, chain)?; + } + + write_to_file(&out, &signed_messages)?; + println!("Signed delegation messages generated and saved to {}", out); + } + KeySource::LocalKeystore { opts } => { + let keystore_secret = KeystoreSecret::from_keystore_options(&opts)?; + let delegatee_pubkey = parse_bls_public_key(&delegatee_pubkey)?; + let signed_messages = delegation::generate_from_keystore( + &opts.path, + keystore_secret, + delegatee_pubkey, + chain, + action, + )?; + + // Verify signatures + for message in &signed_messages { + delegation::verify_message_signature(message, chain)?; + } + + write_to_file(&out, &signed_messages)?; + println!("Signed delegation messages generated and saved to {}", out); + } + KeySource::Dirk { opts } => { + let mut dirk = Dirk::connect(opts.url, opts.tls_credentials).await?; + let delegatee_pubkey = parse_bls_public_key(&delegatee_pubkey)?; + + let signed_messages = delegation::generate_from_dirk( + &mut dirk, + delegatee_pubkey, + opts.wallet_path, + opts.passphrases, + chain, + action, + ) + .await?; + debug!("Signed {} messages with Dirk", signed_messages.len()); + + // Verify signatures + for message in &signed_messages { + delegation::verify_message_signature(message, chain)?; + } + + write_to_file(&out, &signed_messages)?; + println!("Signed delegation messages generated and saved to {}", out); + } + }, + + Commands::Pubkeys { source, out } => match source { + KeySource::SecretKeys { secret_keys } => { + let pubkeys = pubkeys::list_from_local_keys(&secret_keys)?; + + write_to_file(&out, &pubkeys)?; + println!("Pubkeys generated and saved to {}", out); + } + KeySource::LocalKeystore { opts } => { + let keystore_secret = KeystoreSecret::from_keystore_options(&opts)?; + let pubkeys = pubkeys::list_from_keystore(&opts.path, keystore_secret)?; + + write_to_file(&out, &pubkeys)?; + println!("Pubkeys generated and saved to {}", out); + } + KeySource::Dirk { opts } => { + // Note: we don't need to unlock wallets to list pubkeys + let mut dirk = Dirk::connect(opts.url, opts.tls_credentials).await?; + let accounts = dirk.list_accounts(opts.wallet_path).await?; + let pubkeys = pubkeys::list_from_dirk_accounts(&accounts)?; + + write_to_file(&out, &pubkeys)?; + println!("Pubkeys generated and saved to {}", out); + } + }, + } + + Ok(()) +} diff --git a/bolt-cli/src/pb/google.api.rs b/bolt-cli/src/pb/google.api.rs new file mode 100644 index 000000000..243114a3a --- /dev/null +++ b/bolt-cli/src/pb/google.api.rs @@ -0,0 +1,306 @@ +// This file is @generated by prost-build. +/// Defines the HTTP configuration for an API service. It contains a list of +/// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +/// to one or more HTTP REST API methods. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Http { + /// A list of HTTP configuration rules that apply to individual API methods. + /// + /// **NOTE:** All service configuration rules follow "last one wins" order. + #[prost(message, repeated, tag = "1")] + pub rules: ::prost::alloc::vec::Vec, + /// When set to true, URL path parmeters will be fully URI-decoded except in + /// cases of single segment matches in reserved expansion, where "%2F" will be + /// left encoded. + /// + /// The default behavior is to not decode RFC 6570 reserved characters in multi + /// segment matches. + #[prost(bool, tag = "2")] + pub fully_decode_reserved_expansion: bool, +} +/// `HttpRule` defines the mapping of an RPC method to one or more HTTP +/// REST API methods. The mapping specifies how different portions of the RPC +/// request message are mapped to URL path, URL query parameters, and +/// HTTP request body. The mapping is typically specified as an +/// `google.api.http` annotation on the RPC method, +/// see "google/api/annotations.proto" for details. +/// +/// The mapping consists of a field specifying the path template and +/// method kind. The path template can refer to fields in the request +/// message, as in the example below which describes a REST GET +/// operation on a resource collection of messages: +/// +/// +/// service Messaging { +/// rpc GetMessage(GetMessageRequest) returns (Message) { +/// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; +/// } +/// } +/// message GetMessageRequest { +/// message SubMessage { +/// string subfield = 1; +/// } +/// string message_id = 1; // mapped to the URL +/// SubMessage sub = 2; // `sub.subfield` is url-mapped +/// } +/// message Message { +/// string text = 1; // content of the resource +/// } +/// +/// The same http annotation can alternatively be expressed inside the +/// `GRPC API Configuration` YAML file. +/// +/// http: +/// rules: +/// - selector: .Messaging.GetMessage +/// get: /v1/messages/{message_id}/{sub.subfield} +/// +/// This definition enables an automatic, bidrectional mapping of HTTP +/// JSON to RPC. Example: +/// +/// HTTP | RPC +/// -----|----- +/// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` +/// +/// In general, not only fields but also field paths can be referenced +/// from a path pattern. Fields mapped to the path pattern cannot be +/// repeated and must have a primitive (non-message) type. +/// +/// Any fields in the request message which are not bound by the path +/// pattern automatically become (optional) HTTP query +/// parameters. Assume the following definition of the request message: +/// +/// +/// service Messaging { +/// rpc GetMessage(GetMessageRequest) returns (Message) { +/// option (google.api.http).get = "/v1/messages/{message_id}"; +/// } +/// } +/// message GetMessageRequest { +/// message SubMessage { +/// string subfield = 1; +/// } +/// string message_id = 1; // mapped to the URL +/// int64 revision = 2; // becomes a parameter +/// SubMessage sub = 3; // `sub.subfield` becomes a parameter +/// } +/// +/// +/// This enables a HTTP JSON to RPC mapping as below: +/// +/// HTTP | RPC +/// -----|----- +/// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` +/// +/// Note that fields which are mapped to HTTP parameters must have a +/// primitive type or a repeated primitive type. Message types are not +/// allowed. In the case of a repeated type, the parameter can be +/// repeated in the URL, as in `...?param=A¶m=B`. +/// +/// For HTTP method kinds which allow a request body, the `body` field +/// specifies the mapping. Consider a REST update method on the +/// message resource collection: +/// +/// +/// service Messaging { +/// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +/// option (google.api.http) = { +/// put: "/v1/messages/{message_id}" +/// body: "message" +/// }; +/// } +/// } +/// message UpdateMessageRequest { +/// string message_id = 1; // mapped to the URL +/// Message message = 2; // mapped to the body +/// } +/// +/// +/// The following HTTP JSON to RPC mapping is enabled, where the +/// representation of the JSON in the request body is determined by +/// protos JSON encoding: +/// +/// HTTP | RPC +/// -----|----- +/// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` +/// +/// The special name `*` can be used in the body mapping to define that +/// every field not bound by the path template should be mapped to the +/// request body. This enables the following alternative definition of +/// the update method: +/// +/// service Messaging { +/// rpc UpdateMessage(Message) returns (Message) { +/// option (google.api.http) = { +/// put: "/v1/messages/{message_id}" +/// body: "*" +/// }; +/// } +/// } +/// message Message { +/// string message_id = 1; +/// string text = 2; +/// } +/// +/// +/// The following HTTP JSON to RPC mapping is enabled: +/// +/// HTTP | RPC +/// -----|----- +/// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` +/// +/// Note that when using `*` in the body mapping, it is not possible to +/// have HTTP parameters, as all fields not bound by the path end in +/// the body. This makes this option more rarely used in practice of +/// defining REST APIs. The common usage of `*` is in custom methods +/// which don't use the URL at all for transferring data. +/// +/// It is possible to define multiple HTTP methods for one RPC by using +/// the `additional_bindings` option. Example: +/// +/// service Messaging { +/// rpc GetMessage(GetMessageRequest) returns (Message) { +/// option (google.api.http) = { +/// get: "/v1/messages/{message_id}" +/// additional_bindings { +/// get: "/v1/users/{user_id}/messages/{message_id}" +/// } +/// }; +/// } +/// } +/// message GetMessageRequest { +/// string message_id = 1; +/// string user_id = 2; +/// } +/// +/// +/// This enables the following two alternative HTTP JSON to RPC +/// mappings: +/// +/// HTTP | RPC +/// -----|----- +/// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +/// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` +/// +/// # Rules for HTTP mapping +/// +/// The rules for mapping HTTP path, query parameters, and body fields +/// to the request message are as follows: +/// +/// 1. The `body` field specifies either `*` or a field path, or is +/// omitted. If omitted, it indicates there is no HTTP request body. +/// 2. Leaf fields (recursive expansion of nested messages in the +/// request) can be classified into three types: +/// (a) Matched in the URL template. +/// (b) Covered by body (if body is `*`, everything except (a) fields; +/// else everything under the body field) +/// (c) All other fields. +/// 3. URL query parameters found in the HTTP request are mapped to (c) fields. +/// 4. Any body sent with an HTTP request can contain only (b) fields. +/// +/// The syntax of the path template is as follows: +/// +/// Template = "/" Segments \[ Verb \] ; +/// Segments = Segment { "/" Segment } ; +/// Segment = "*" | "**" | LITERAL | Variable ; +/// Variable = "{" FieldPath \[ "=" Segments \] "}" ; +/// FieldPath = IDENT { "." IDENT } ; +/// Verb = ":" LITERAL ; +/// +/// The syntax `*` matches a single path segment. The syntax `**` matches zero +/// or more path segments, which must be the last part of the path except the +/// `Verb`. The syntax `LITERAL` matches literal text in the path. +/// +/// The syntax `Variable` matches part of the URL path as specified by its +/// template. A variable template must not contain other variables. If a variable +/// matches a single path segment, its template may be omitted, e.g. `{var}` +/// is equivalent to `{var=*}`. +/// +/// If a variable contains exactly one path segment, such as `"{var}"` or +/// `"{var=*}"`, when such a variable is expanded into a URL path, all characters +/// except `\[-_.~0-9a-zA-Z\]` are percent-encoded. Such variables show up in the +/// Discovery Document as `{var}`. +/// +/// If a variable contains one or more path segments, such as `"{var=foo/*}"` +/// or `"{var=**}"`, when such a variable is expanded into a URL path, all +/// characters except `\[-_.~/0-9a-zA-Z\]` are percent-encoded. Such variables +/// show up in the Discovery Document as `{+var}`. +/// +/// NOTE: While the single segment variable matches the semantics of +/// [RFC 6570]() Section 3.2.2 +/// Simple String Expansion, the multi segment variable **does not** match +/// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion +/// does not expand special characters like `?` and `#`, which would lead +/// to invalid URLs. +/// +/// NOTE: the field paths in variables and in the `body` must not refer to +/// repeated fields or map fields. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HttpRule { + /// Selects methods to which this rule applies. + /// + /// Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + #[prost(string, tag = "1")] + pub selector: ::prost::alloc::string::String, + /// The name of the request field whose value is mapped to the HTTP body, or + /// `*` for mapping all fields not captured by the path pattern to the HTTP + /// body. NOTE: the referred field must not be a repeated field and must be + /// present at the top-level of request message type. + #[prost(string, tag = "7")] + pub body: ::prost::alloc::string::String, + /// Optional. The name of the response field whose value is mapped to the HTTP + /// body of response. Other response fields are ignored. When + /// not set, the response message will be used as HTTP body of response. + #[prost(string, tag = "12")] + pub response_body: ::prost::alloc::string::String, + /// Additional HTTP bindings for the selector. Nested bindings must + /// not contain an `additional_bindings` field themselves (that is, + /// the nesting may only be one level deep). + #[prost(message, repeated, tag = "11")] + pub additional_bindings: ::prost::alloc::vec::Vec, + /// Determines the URL pattern is matched by this rules. This pattern can be + /// used with any of the {get|put|post|delete|patch} methods. A custom method + /// can be defined using the 'custom' field. + #[prost(oneof = "http_rule::Pattern", tags = "2, 3, 4, 5, 6, 8")] + pub pattern: ::core::option::Option, +} +/// Nested message and enum types in `HttpRule`. +pub mod http_rule { + /// Determines the URL pattern is matched by this rules. This pattern can be + /// used with any of the {get|put|post|delete|patch} methods. A custom method + /// can be defined using the 'custom' field. + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Pattern { + /// Used for listing and getting information about resources. + #[prost(string, tag = "2")] + Get(::prost::alloc::string::String), + /// Used for updating a resource. + #[prost(string, tag = "3")] + Put(::prost::alloc::string::String), + /// Used for creating a resource. + #[prost(string, tag = "4")] + Post(::prost::alloc::string::String), + /// Used for deleting a resource. + #[prost(string, tag = "5")] + Delete(::prost::alloc::string::String), + /// Used for updating a resource. + #[prost(string, tag = "6")] + Patch(::prost::alloc::string::String), + /// The custom pattern is used for specifying an HTTP method that is not + /// included in the `pattern` field, such as HEAD, or "*" to leave the + /// HTTP method unspecified for this rule. The wild-card rule is useful + /// for services that provide content to Web (HTML) clients. + #[prost(message, tag = "8")] + Custom(super::CustomHttpPattern), + } +} +/// A custom pattern is used for defining custom HTTP verb. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CustomHttpPattern { + /// The name of this custom HTTP verb. + #[prost(string, tag = "1")] + pub kind: ::prost::alloc::string::String, + /// The path matched by this custom verb. + #[prost(string, tag = "2")] + pub path: ::prost::alloc::string::String, +} diff --git a/bolt-cli/src/pb/mod.rs b/bolt-cli/src/pb/mod.rs new file mode 100644 index 000000000..5a22114fc --- /dev/null +++ b/bolt-cli/src/pb/mod.rs @@ -0,0 +1,16 @@ +mod v1; + +/// Re-exported protobuf API for the ETH2 remote signer service. +pub mod eth2_signer_api { + + #[allow(unused_imports)] + pub use super::v1::{ + account_manager_client::AccountManagerClient, lister_client::ListerClient, + sign_request::Id as SignRequestId, signer_client::SignerClient, + wallet_manager_client::WalletManagerClient, Account, DistributedAccount, + ListAccountsRequest, ListAccountsResponse, LockAccountRequest, LockAccountResponse, + LockWalletRequest, LockWalletResponse, MultisignRequest, MultisignResponse, ResponseState, + SignRequest, SignResponse, UnlockAccountRequest, UnlockAccountResponse, + UnlockWalletRequest, UnlockWalletResponse, + }; +} diff --git a/bolt-cli/src/pb/v1.rs b/bolt-cli/src/pb/v1.rs new file mode 100644 index 000000000..dbef7a820 --- /dev/null +++ b/bolt-cli/src/pb/v1.rs @@ -0,0 +1,1944 @@ +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Endpoint { + #[prost(uint64, tag = "1")] + pub id: u64, + #[prost(string, tag = "2")] + pub name: ::prost::alloc::string::String, + #[prost(uint32, tag = "3")] + pub port: u32, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ResponseState { + /// UNKNOWN occurs when no information about the response is available. + Unknown = 0, + /// SUCCEEDED occurs when a request was successful. + Succeeded = 1, + /// DENIED occurs when a request was denied. + Denied = 2, + /// FAILED occurs when a request failed to complete. + Failed = 3, +} +impl ResponseState { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unknown => "UNKNOWN", + Self::Succeeded => "SUCCEEDED", + Self::Denied => "DENIED", + Self::Failed => "FAILED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNKNOWN" => Some(Self::Unknown), + "SUCCEEDED" => Some(Self::Succeeded), + "DENIED" => Some(Self::Denied), + "FAILED" => Some(Self::Failed), + _ => None, + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListAccountsRequest { + #[prost(string, repeated, tag = "1")] + pub paths: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListAccountsResponse { + #[prost(enumeration = "ResponseState", tag = "1")] + pub state: i32, + #[prost(message, repeated, tag = "2")] + pub accounts: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub distributed_accounts: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Account { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "2")] + pub public_key: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub uuid: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DistributedAccount { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "2")] + pub public_key: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub participants: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "4")] + pub signing_threshold: u32, + #[prost(bytes = "vec", tag = "5")] + pub uuid: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "6")] + pub composite_public_key: ::prost::alloc::vec::Vec, +} +/// Generated client implementations. +pub mod lister_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct ListerClient { + inner: tonic::client::Grpc, + } + impl ListerClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl ListerClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> ListerClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + std::marker::Send + std::marker::Sync, + { + ListerClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + pub async fn list_accounts( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/v1.Lister/ListAccounts"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("v1.Lister", "ListAccounts")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated server implementations. +pub mod lister_server { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with ListerServer. + #[async_trait] + pub trait Lister: std::marker::Send + std::marker::Sync + 'static { + async fn list_accounts( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + } + #[derive(Debug)] + pub struct ListerServer { + inner: Arc, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + impl ListerServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for ListerServer + where + T: Lister, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + match req.uri().path() { + "/v1.Lister/ListAccounts" => { + #[allow(non_camel_case_types)] + struct ListAccountsSvc(pub Arc); + impl< + T: Lister, + > tonic::server::UnaryService + for ListAccountsSvc { + type Response = super::ListAccountsResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::list_accounts(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = ListAccountsSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + let mut response = http::Response::new(empty_body()); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) + }) + } + } + } + } + impl Clone for ListerServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "v1.Lister"; + impl tonic::server::NamedService for ListerServer { + const NAME: &'static str = SERVICE_NAME; + } +} +/// AttestationData is defined at +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AttestationData { + #[prost(uint64, tag = "1")] + pub slot: u64, + #[prost(uint64, tag = "2")] + pub committee_index: u64, + #[prost(bytes = "vec", tag = "3")] + pub beacon_block_root: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "4")] + pub source: ::core::option::Option, + #[prost(message, optional, tag = "5")] + pub target: ::core::option::Option, +} +/// Checkpoint is defined at +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Checkpoint { + #[prost(uint64, tag = "1")] + pub epoch: u64, + #[prost(bytes = "vec", tag = "2")] + pub root: ::prost::alloc::vec::Vec, +} +/// BeaconBlockheader is defined at +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BeaconBlockHeader { + #[prost(uint64, tag = "1")] + pub slot: u64, + #[prost(uint64, tag = "2")] + pub proposer_index: u64, + #[prost(bytes = "vec", tag = "3")] + pub parent_root: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "4")] + pub state_root: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "5")] + pub body_root: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignRequest { + #[prost(bytes = "vec", tag = "3")] + pub data: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "4")] + pub domain: ::prost::alloc::vec::Vec, + #[prost(oneof = "sign_request::Id", tags = "1, 2")] + pub id: ::core::option::Option, +} +/// Nested message and enum types in `SignRequest`. +pub mod sign_request { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Id { + #[prost(bytes, tag = "1")] + PublicKey(::prost::alloc::vec::Vec), + #[prost(string, tag = "2")] + Account(::prost::alloc::string::String), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MultisignRequest { + #[prost(message, repeated, tag = "1")] + pub requests: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignBeaconAttestationRequest { + #[prost(bytes = "vec", tag = "3")] + pub domain: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "4")] + pub data: ::core::option::Option, + #[prost(oneof = "sign_beacon_attestation_request::Id", tags = "1, 2")] + pub id: ::core::option::Option, +} +/// Nested message and enum types in `SignBeaconAttestationRequest`. +pub mod sign_beacon_attestation_request { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Id { + #[prost(bytes, tag = "1")] + PublicKey(::prost::alloc::vec::Vec), + #[prost(string, tag = "2")] + Account(::prost::alloc::string::String), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignBeaconAttestationsRequest { + #[prost(message, repeated, tag = "1")] + pub requests: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignBeaconProposalRequest { + #[prost(bytes = "vec", tag = "3")] + pub domain: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "4")] + pub data: ::core::option::Option, + #[prost(oneof = "sign_beacon_proposal_request::Id", tags = "1, 2")] + pub id: ::core::option::Option, +} +/// Nested message and enum types in `SignBeaconProposalRequest`. +pub mod sign_beacon_proposal_request { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Id { + #[prost(bytes, tag = "1")] + PublicKey(::prost::alloc::vec::Vec), + #[prost(string, tag = "2")] + Account(::prost::alloc::string::String), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignResponse { + #[prost(enumeration = "ResponseState", tag = "1")] + pub state: i32, + #[prost(bytes = "vec", tag = "2")] + pub signature: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MultisignResponse { + #[prost(message, repeated, tag = "1")] + pub responses: ::prost::alloc::vec::Vec, +} +/// Generated client implementations. +pub mod signer_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct SignerClient { + inner: tonic::client::Grpc, + } + impl SignerClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl SignerClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> SignerClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + std::marker::Send + std::marker::Sync, + { + SignerClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + pub async fn sign( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/v1.Signer/Sign"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("v1.Signer", "Sign")); + self.inner.unary(req, path, codec).await + } + pub async fn multisign( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/v1.Signer/Multisign"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("v1.Signer", "Multisign")); + self.inner.unary(req, path, codec).await + } + pub async fn sign_beacon_attestation( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/v1.Signer/SignBeaconAttestation", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("v1.Signer", "SignBeaconAttestation")); + self.inner.unary(req, path, codec).await + } + pub async fn sign_beacon_attestations( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/v1.Signer/SignBeaconAttestations", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("v1.Signer", "SignBeaconAttestations")); + self.inner.unary(req, path, codec).await + } + pub async fn sign_beacon_proposal( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/v1.Signer/SignBeaconProposal", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("v1.Signer", "SignBeaconProposal")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated server implementations. +pub mod signer_server { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with SignerServer. + #[async_trait] + pub trait Signer: std::marker::Send + std::marker::Sync + 'static { + async fn sign( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn multisign( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn sign_beacon_attestation( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn sign_beacon_attestations( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn sign_beacon_proposal( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + } + #[derive(Debug)] + pub struct SignerServer { + inner: Arc, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + impl SignerServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for SignerServer + where + T: Signer, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + match req.uri().path() { + "/v1.Signer/Sign" => { + #[allow(non_camel_case_types)] + struct SignSvc(pub Arc); + impl tonic::server::UnaryService + for SignSvc { + type Response = super::SignResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::sign(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = SignSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/v1.Signer/Multisign" => { + #[allow(non_camel_case_types)] + struct MultisignSvc(pub Arc); + impl tonic::server::UnaryService + for MultisignSvc { + type Response = super::MultisignResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::multisign(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = MultisignSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/v1.Signer/SignBeaconAttestation" => { + #[allow(non_camel_case_types)] + struct SignBeaconAttestationSvc(pub Arc); + impl< + T: Signer, + > tonic::server::UnaryService + for SignBeaconAttestationSvc { + type Response = super::SignResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::sign_beacon_attestation(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = SignBeaconAttestationSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/v1.Signer/SignBeaconAttestations" => { + #[allow(non_camel_case_types)] + struct SignBeaconAttestationsSvc(pub Arc); + impl< + T: Signer, + > tonic::server::UnaryService + for SignBeaconAttestationsSvc { + type Response = super::MultisignResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::sign_beacon_attestations(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = SignBeaconAttestationsSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/v1.Signer/SignBeaconProposal" => { + #[allow(non_camel_case_types)] + struct SignBeaconProposalSvc(pub Arc); + impl< + T: Signer, + > tonic::server::UnaryService + for SignBeaconProposalSvc { + type Response = super::SignResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::sign_beacon_proposal(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = SignBeaconProposalSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + let mut response = http::Response::new(empty_body()); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) + }) + } + } + } + } + impl Clone for SignerServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "v1.Signer"; + impl tonic::server::NamedService for SignerServer { + const NAME: &'static str = SERVICE_NAME; + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnlockAccountRequest { + #[prost(string, tag = "1")] + pub account: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "2")] + pub passphrase: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LockAccountRequest { + #[prost(string, tag = "1")] + pub account: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct UnlockAccountResponse { + #[prost(enumeration = "ResponseState", tag = "1")] + pub state: i32, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct LockAccountResponse { + #[prost(enumeration = "ResponseState", tag = "1")] + pub state: i32, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenerateRequest { + #[prost(string, tag = "1")] + pub account: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "2")] + pub passphrase: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "3")] + pub participants: u32, + #[prost(uint32, tag = "4")] + pub signing_threshold: u32, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenerateResponse { + #[prost(enumeration = "ResponseState", tag = "1")] + pub state: i32, + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "3")] + pub public_key: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "4")] + pub participants: ::prost::alloc::vec::Vec, +} +/// Generated client implementations. +pub mod account_manager_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct AccountManagerClient { + inner: tonic::client::Grpc, + } + impl AccountManagerClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl AccountManagerClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> AccountManagerClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + std::marker::Send + std::marker::Sync, + { + AccountManagerClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + pub async fn unlock( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/v1.AccountManager/Unlock"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("v1.AccountManager", "Unlock")); + self.inner.unary(req, path, codec).await + } + pub async fn lock( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/v1.AccountManager/Lock"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("v1.AccountManager", "Lock")); + self.inner.unary(req, path, codec).await + } + pub async fn generate( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/v1.AccountManager/Generate", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("v1.AccountManager", "Generate")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated server implementations. +pub mod account_manager_server { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with AccountManagerServer. + #[async_trait] + pub trait AccountManager: std::marker::Send + std::marker::Sync + 'static { + async fn unlock( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn lock( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn generate( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + } + #[derive(Debug)] + pub struct AccountManagerServer { + inner: Arc, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + impl AccountManagerServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for AccountManagerServer + where + T: AccountManager, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + match req.uri().path() { + "/v1.AccountManager/Unlock" => { + #[allow(non_camel_case_types)] + struct UnlockSvc(pub Arc); + impl< + T: AccountManager, + > tonic::server::UnaryService + for UnlockSvc { + type Response = super::UnlockAccountResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::unlock(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = UnlockSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/v1.AccountManager/Lock" => { + #[allow(non_camel_case_types)] + struct LockSvc(pub Arc); + impl< + T: AccountManager, + > tonic::server::UnaryService + for LockSvc { + type Response = super::LockAccountResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::lock(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = LockSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/v1.AccountManager/Generate" => { + #[allow(non_camel_case_types)] + struct GenerateSvc(pub Arc); + impl< + T: AccountManager, + > tonic::server::UnaryService + for GenerateSvc { + type Response = super::GenerateResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::generate(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GenerateSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + let mut response = http::Response::new(empty_body()); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) + }) + } + } + } + } + impl Clone for AccountManagerServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "v1.AccountManager"; + impl tonic::server::NamedService for AccountManagerServer { + const NAME: &'static str = SERVICE_NAME; + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnlockWalletRequest { + #[prost(string, tag = "1")] + pub wallet: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "2")] + pub passphrase: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LockWalletRequest { + #[prost(string, tag = "1")] + pub wallet: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct UnlockWalletResponse { + #[prost(enumeration = "ResponseState", tag = "1")] + pub state: i32, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct LockWalletResponse { + #[prost(enumeration = "ResponseState", tag = "1")] + pub state: i32, +} +/// Generated client implementations. +pub mod wallet_manager_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct WalletManagerClient { + inner: tonic::client::Grpc, + } + impl WalletManagerClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl WalletManagerClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> WalletManagerClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + std::marker::Send + std::marker::Sync, + { + WalletManagerClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + pub async fn unlock( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/v1.WalletManager/Unlock"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("v1.WalletManager", "Unlock")); + self.inner.unary(req, path, codec).await + } + pub async fn lock( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/v1.WalletManager/Lock"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("v1.WalletManager", "Lock")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated server implementations. +pub mod wallet_manager_server { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with WalletManagerServer. + #[async_trait] + pub trait WalletManager: std::marker::Send + std::marker::Sync + 'static { + async fn unlock( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn lock( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + } + #[derive(Debug)] + pub struct WalletManagerServer { + inner: Arc, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + impl WalletManagerServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for WalletManagerServer + where + T: WalletManager, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + match req.uri().path() { + "/v1.WalletManager/Unlock" => { + #[allow(non_camel_case_types)] + struct UnlockSvc(pub Arc); + impl< + T: WalletManager, + > tonic::server::UnaryService + for UnlockSvc { + type Response = super::UnlockWalletResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::unlock(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = UnlockSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/v1.WalletManager/Lock" => { + #[allow(non_camel_case_types)] + struct LockSvc(pub Arc); + impl< + T: WalletManager, + > tonic::server::UnaryService + for LockSvc { + type Response = super::LockWalletResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::lock(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = LockSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + let mut response = http::Response::new(empty_body()); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) + }) + } + } + } + } + impl Clone for WalletManagerServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "v1.WalletManager"; + impl tonic::server::NamedService for WalletManagerServer { + const NAME: &'static str = SERVICE_NAME; + } +} diff --git a/bolt-cli/src/pubkeys.rs b/bolt-cli/src/pubkeys.rs new file mode 100644 index 000000000..c06eef8de --- /dev/null +++ b/bolt-cli/src/pubkeys.rs @@ -0,0 +1,51 @@ +use ethereum_consensus::crypto::bls::{PublicKey as BlsPublicKey, SecretKey as BlsSecretKey}; +use eyre::Result; +use lighthouse_eth2_keystore::Keystore; + +use crate::{ + pb::eth2_signer_api::Account, + utils::keystore::{keystore_paths, KeystoreError, KeystoreSecret}, +}; + +/// Derive public keys from the provided secret keys. +pub fn list_from_local_keys(secret_keys: &[String]) -> Result> { + let mut pubkeys = Vec::with_capacity(secret_keys.len()); + + for sk in secret_keys { + let sk = BlsSecretKey::try_from(sk.trim().to_string())?; + pubkeys.push(sk.public_key()); + } + + Ok(pubkeys) +} + +/// Derive public keys from the keystore files in the provided directory. +pub fn list_from_keystore( + keys_path: &str, + keystore_secret: KeystoreSecret, +) -> Result> { + let keystores_paths = keystore_paths(keys_path)?; + let mut pubkeys = Vec::with_capacity(keystores_paths.len()); + + for path in keystores_paths { + let ks = Keystore::from_json_file(path).map_err(KeystoreError::Eth2Keystore)?; + let password = keystore_secret.get(ks.pubkey()).ok_or(KeystoreError::MissingPassword)?; + let kp = ks.decrypt_keypair(password.as_bytes()).map_err(KeystoreError::Eth2Keystore)?; + let pubkey = BlsPublicKey::try_from(kp.pk.serialize().to_vec().as_ref())?; + pubkeys.push(pubkey); + } + + Ok(pubkeys) +} + +/// Derive public keys from the provided dirk accounts. +pub fn list_from_dirk_accounts(accounts: &[Account]) -> Result> { + let mut pubkeys = Vec::with_capacity(accounts.len()); + + for acc in accounts { + let pubkey = BlsPublicKey::try_from(acc.public_key.as_slice())?; + pubkeys.push(pubkey); + } + + Ok(pubkeys) +} diff --git a/bolt-cli/src/utils/dirk.rs b/bolt-cli/src/utils/dirk.rs new file mode 100644 index 000000000..dc5e594eb --- /dev/null +++ b/bolt-cli/src/utils/dirk.rs @@ -0,0 +1,226 @@ +use std::fs; + +use alloy_primitives::B256; +use ethereum_consensus::crypto::bls::Signature as BlsSignature; +use eyre::{bail, Context, Result}; +use tonic::transport::{Certificate, Channel, ClientTlsConfig, Identity}; +use tracing::debug; + +use crate::{ + cli::TlsCredentials, + pb::eth2_signer_api::{ + Account, AccountManagerClient, ListAccountsRequest, ListerClient, LockAccountRequest, + ResponseState, SignRequest, SignRequestId, SignerClient, UnlockAccountRequest, + }, +}; + +/// A Dirk remote signer. +/// +/// Available services: +/// - `Lister`: List accounts in the keystore. +/// - `Signer`: Request a signature from the remote signer. +/// - `AccountManager`: Manage accounts in the keystore (lock and unlock accounts). +/// +/// Reference: https://github.com/attestantio/dirk +#[derive(Clone)] +pub struct Dirk { + lister: ListerClient, + signer: SignerClient, + account_mng: AccountManagerClient, +} + +impl Dirk { + /// Connect to the DIRK server with the given address and TLS credentials. + pub async fn connect(addr: String, credentials: TlsCredentials) -> Result { + let addr = addr.parse()?; + let tls_config = compose_credentials(credentials)?; + let conn = Channel::builder(addr).tls_config(tls_config)?.connect().await?; + + let lister = ListerClient::new(conn.clone()); + let signer = SignerClient::new(conn.clone()); + let account_mng = AccountManagerClient::new(conn); + + Ok(Self { lister, signer, account_mng }) + } + + /// List all accounts in the keystore. + pub async fn list_accounts(&mut self, wallet_path: String) -> Result> { + // Request all accounts in the given path. Only one path at a time + // as done in https://github.com/wealdtech/go-eth2-wallet-dirk/blob/182f99b22b64d01e0d4ae67bf47bb055763465d7/grpc.go#L121 + let req = ListAccountsRequest { paths: vec![wallet_path] }; + let res = self.lister.list_accounts(req).await?.into_inner(); + + if !matches!(res.state(), ResponseState::Succeeded) { + bail!("Failed to list accounts: {:?}", res); + } + + debug!("{} Accounts listed successfully", res.accounts.len()); + Ok(res.accounts) + } + + /// Unlock an account in the keystore with the given passphrase. + pub async fn unlock_account( + &mut self, + account_name: String, + passphrase: String, + ) -> Result { + let pf_bytes = passphrase.as_bytes().to_vec(); + let req = UnlockAccountRequest { account: account_name.clone(), passphrase: pf_bytes }; + let res = self.account_mng.unlock(req).await?.into_inner(); + + match res.state() { + ResponseState::Succeeded => { + debug!("Unlock request succeeded for account {}", account_name); + Ok(true) + } + ResponseState::Denied => { + debug!("Unlock request denied for account {}", account_name); + Ok(false) + } + ResponseState::Unknown => bail!("Unknown response from unlock account: {:?}", res), + ResponseState::Failed => bail!("Failed to unlock account: {:?}", res), + } + } + + /// Lock an account in the keystore. + pub async fn lock_account(&mut self, account_name: String) -> Result { + let req = LockAccountRequest { account: account_name.clone() }; + let res = self.account_mng.lock(req).await?.into_inner(); + + match res.state() { + ResponseState::Succeeded => { + debug!("Lock request succeeded for account {}", account_name); + Ok(true) + } + ResponseState::Denied => { + debug!("Lock request denied for account {}", account_name); + Ok(false) + } + ResponseState::Unknown => bail!("Unknown response from lock account: {:?}", res), + ResponseState::Failed => bail!("Failed to lock account: {:?}", res), + } + } + + /// Request a signature from the remote signer. + pub async fn request_signature( + &mut self, + account: &Account, + hash: B256, + domain: B256, + ) -> Result { + let req = SignRequest { + data: hash.to_vec(), + domain: domain.to_vec(), + id: Some(SignRequestId::Account(account.name.clone())), + }; + + let res = self.signer.sign(req).await?.into_inner(); + + if !matches!(res.state(), ResponseState::Succeeded) { + bail!("Failed to sign data: {:?}", res); + } + if res.signature.is_empty() { + bail!("Empty signature returned"); + } + + let sig = BlsSignature::try_from(res.signature.as_slice()) + .wrap_err("Failed to parse signature")?; + + debug!("Signature request succeeded for account {}", account.name); + Ok(sig) + } +} + +/// Compose the TLS credentials from the given paths. +fn compose_credentials(creds: TlsCredentials) -> Result { + let client_cert = fs::read(creds.client_cert_path).wrap_err("Failed to read client cert")?; + let client_key = fs::read(creds.client_key_path).wrap_err("Failed to read client key")?; + + // Create client identity (certificate + key) + let identity = Identity::from_pem(&client_cert, &client_key); + + // Configure the TLS client + let mut tls_config = ClientTlsConfig::new().identity(identity); + + // Add CA certificate if provided + if let Some(ca_path) = creds.ca_cert_path { + let ca_cert = fs::read(ca_path).wrap_err("Failed to read CA certificate")?; + tls_config = tls_config.ca_certificate(Certificate::from_pem(&ca_cert)); + } + + Ok(tls_config) +} + +#[cfg(test)] +mod tests { + use std::{process::Command, time::Duration}; + + use super::*; + + /// Test connecting to a DIRK server and listing available accounts. + /// + /// ```shell + /// cargo test --package bolt -- utils::dirk::tests::test_dirk_connection_e2e + /// --exact --show-output --ignored + /// ``` + #[tokio::test] + #[ignore] + async fn test_dirk_connection_e2e() -> eyre::Result<()> { + // Init the default rustls provider + let _ = rustls::crypto::ring::default_provider().install_default(); + + let test_data_dir = env!("CARGO_MANIFEST_DIR").to_string() + "/test_data/dirk"; + + // Init the DIRK config file + init_dirk_config(test_data_dir.clone())?; + + // Check if dirk is installed (in $PATH) + if Command::new("dirk") + .arg("--base-dir") + .arg(&test_data_dir) + .arg("--help") + .status() + .is_err() + { + eprintln!("DIRK is not installed in $PATH"); + return Ok(()); + } + + // Start the DIRK server in the background + let mut dirk_proc = Command::new("dirk").arg("--base-dir").arg(&test_data_dir).spawn()?; + + // Wait for some time for the server to start up + tokio::time::sleep(Duration::from_secs(3)).await; + + let url = "https://localhost:9091".to_string(); + + let cred = TlsCredentials { + client_cert_path: test_data_dir.clone() + "/client1.crt", + client_key_path: test_data_dir.clone() + "/client1.key", + ca_cert_path: Some(test_data_dir.clone() + "/security/ca.crt"), + }; + + let mut dirk = Dirk::connect(url, cred).await?; + + let accounts = dirk.list_accounts("wallet1".to_string()).await?; + println!("Dirk Accounts: {:?}", accounts); + + // make sure to stop the dirk server + dirk_proc.kill()?; + + Ok(()) + } + + fn init_dirk_config(test_data_dir: String) -> eyre::Result<()> { + // read the template json file from test_data + let template_path = test_data_dir.clone() + "/dirk.template.json"; + let template = fs::read_to_string(template_path).wrap_err("Failed to read template")?; + + // change the occurrence of $PWD to the current working directory in the template + let new_file = test_data_dir.clone() + "/dirk.json"; + let new_content = template.replace("$PWD", &test_data_dir); + fs::write(new_file, new_content).wrap_err("Failed to write dirk config file")?; + + Ok(()) + } +} diff --git a/bolt-delegations-cli/src/utils.rs b/bolt-cli/src/utils/keystore.rs similarity index 52% rename from bolt-delegations-cli/src/utils.rs rename to bolt-cli/src/utils/keystore.rs index d38c18bf9..26810e11b 100644 --- a/bolt-delegations-cli/src/utils.rs +++ b/bolt-cli/src/utils/keystore.rs @@ -1,29 +1,31 @@ use std::{ collections::HashMap, ffi::OsString, - fs::{self, read_dir, DirEntry}, + fs::{self, DirEntry}, io, path::{Path, PathBuf}, }; -use alloy::primitives::FixedBytes; -use blst::{min_pk::Signature, BLST_ERROR}; -use ethereum_consensus::{ - crypto::PublicKey as BlsPublicKey, - deneb::{compute_fork_data_root, compute_signing_root, Root}, -}; -use eyre::{Context, Result}; - -use crate::{config::Chain, types::KeystoreError}; - -// Reference: https://eips.ethereum.org/EIPS/eip-2335#test-cases -pub const KEYSTORE_PASSWORD: &str = r#"π”±π”’π”°π”±π”­π”žπ”°π”°π”΄π”¬π”―π”‘πŸ”‘"#; +use eyre::{bail, Context, ContextCompat, Result}; -pub const COMMIT_BOOST_DOMAIN_MASK: [u8; 4] = [109, 109, 111, 67]; +use crate::cli::LocalKeystoreOpts; -/// The BLS Domain Separator used in Ethereum 2.0. -pub const BLS_DST_PREFIX: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; +/// Default password used for keystores in the test vectors. +/// +/// Reference: https://eips.ethereum.org/EIPS/eip-2335#test-cases +pub const DEFAULT_KEYSTORE_PASSWORD: &str = r#"π”±π”’π”°π”±π”­π”žπ”°π”°π”΄π”¬π”―π”‘πŸ”‘"#; + +#[derive(Debug, thiserror::Error)] +pub enum KeystoreError { + #[error("failed to read keystore directory: {0}")] + ReadFromDirectory(#[from] std::io::Error), + #[error("Failed to read or decrypt keystore: {0:?}")] + Eth2Keystore(lighthouse_eth2_keystore::Error), + #[error("Missing password for keypair")] + MissingPassword, +} +/// EIP-2335 keystore secret kind. pub enum KeystoreSecret { /// When using a unique password for all validators in the keystore /// (e.g. for Prysm keystore) @@ -34,14 +36,26 @@ pub enum KeystoreSecret { } impl KeystoreSecret { + /// Create a new [`KeystoreSecret`] from the provided [`LocalKeystoreOpts`]. + pub fn from_keystore_options(opts: &LocalKeystoreOpts) -> Result { + if let Some(password_path) = &opts.password_path { + Ok(KeystoreSecret::from_directory(password_path)?) + } else if let Some(password) = &opts.password { + Ok(KeystoreSecret::from_unique_password(password.clone())) + } else { + // This case is prevented upstream by clap's validation. + bail!("Either `password_path` or `password` must be provided") + } + } + /// Load the keystore passwords from a directory containing individual password files. - pub fn from_directory(root_dir: String) -> Result { + pub fn from_directory(root_dir: &str) -> Result { let mut secrets = HashMap::new(); for entry in fs::read_dir(root_dir)? { let entry = entry.wrap_err("Failed to read secrets directory entry")?; let path = entry.path(); - let filename = path.file_name().expect("secret file name").to_string_lossy(); + let filename = path.file_name().wrap_err("Secret file name")?.to_string_lossy(); let secret = fs::read_to_string(&path).wrap_err("Failed to read secret file")?; secrets.insert(filename.trim_start_matches("0x").to_string(), secret); } @@ -85,13 +99,6 @@ impl Drop for KeystoreSecret { } } -/// Parse the delegated public key from a string -pub fn parse_public_key(delegatee_pubkey: &str) -> Result { - let hex_pk = delegatee_pubkey.strip_prefix("0x").unwrap_or(delegatee_pubkey); - BlsPublicKey::try_from(hex::decode(hex_pk).expect("Failed to decode pubkey").as_slice()) - .map_err(|e| eyre::eyre!("Failed to parse public key '{}': {}", hex_pk, e)) -} - /// Returns the paths of all the keystore files provided in `keys_path`. /// /// We're expecting a directory structure like: @@ -125,54 +132,6 @@ fn read_path(entry: io::Result) -> Result { Ok(entry.map_err(KeystoreError::ReadFromDirectory)?.path()) } -/// Helper function to compute the signing root for a message -pub fn compute_commit_boost_signing_root( - message: [u8; 32], - chain: &Chain, -) -> Result> { - compute_signing_root(&message, compute_domain_from_mask(chain.fork_version())) - .map_err(|e| eyre::eyre!("Failed to compute signing root: {}", e)) -} - -/// Compute the commit boost domain from the fork version -pub fn compute_domain_from_mask(fork_version: [u8; 4]) -> [u8; 32] { - let mut domain = [0; 32]; - - // Note: the application builder domain specs require the genesis_validators_root - // to be 0x00 for any out-of-protocol message. The commit-boost domain follows the - // same rule. - let root = Root::default(); - let fork_data_root = compute_fork_data_root(fork_version, root).expect("valid fork data"); - - domain[..4].copy_from_slice(&COMMIT_BOOST_DOMAIN_MASK); - domain[4..].copy_from_slice(&fork_data_root[..28]); - domain -} - -/// Verify the signature with the public key of the signer using the Commit Boost domain. -pub fn verify_commit_boost_root( - pubkey: BlsPublicKey, - root: [u8; 32], - signature: &Signature, - chain: &Chain, -) -> Result<()> { - verify_root(pubkey, root, signature, compute_domain_from_mask(chain.fork_version())) -} - -/// Verify the signature of the object with the given public key. -pub fn verify_root( - pubkey: BlsPublicKey, - root: [u8; 32], - signature: &Signature, - domain: [u8; 32], -) -> Result<()> { - let signing_root = compute_signing_root(&root, domain)?; - let pk = blst::min_pk::PublicKey::from_bytes(pubkey.as_ref()).unwrap(); - - let res = signature.verify(true, signing_root.as_ref(), BLS_DST_PREFIX, &[], &pk, true); - if res == BLST_ERROR::BLST_SUCCESS { - Ok(()) - } else { - Err(eyre::eyre!("bls verification failed")) - } +fn read_dir(path: PathBuf) -> Result { + fs::read_dir(path).wrap_err("Failed to read directory") } diff --git a/bolt-cli/src/utils/mod.rs b/bolt-cli/src/utils/mod.rs new file mode 100644 index 000000000..efee3e63e --- /dev/null +++ b/bolt-cli/src/utils/mod.rs @@ -0,0 +1,29 @@ +use std::{fs, path::PathBuf}; + +use ethereum_consensus::crypto::PublicKey as BlsPublicKey; +use eyre::{Context, Result}; +use serde::Serialize; + +/// Utilities for working with DIRK remote keystores. +pub mod dirk; + +/// Utilities and types for EIP-2335 keystore files. +pub mod keystore; + +/// Utilities for signing and verifying messages. +pub mod signing; + +/// Parse a BLS public key from a string +pub fn parse_bls_public_key(delegatee_pubkey: &str) -> Result { + let hex_pk = delegatee_pubkey.strip_prefix("0x").unwrap_or(delegatee_pubkey); + BlsPublicKey::try_from(hex::decode(hex_pk).wrap_err("Failed to hex-decode pubkey")?.as_slice()) + .map_err(|e| eyre::eyre!("Failed to parse public key '{}': {}", hex_pk, e)) +} + +/// Write some serializable data to an output json file +pub fn write_to_file(out: &str, data: &T) -> Result<()> { + let out_path = PathBuf::from(out); + let out_file = fs::File::create(out_path)?; + serde_json::to_writer_pretty(out_file, data)?; + Ok(()) +} diff --git a/bolt-cli/src/utils/signing.rs b/bolt-cli/src/utils/signing.rs new file mode 100644 index 000000000..daee353e1 --- /dev/null +++ b/bolt-cli/src/utils/signing.rs @@ -0,0 +1,67 @@ +use alloy_primitives::B256; +use blst::{min_pk::Signature, BLST_ERROR}; +use ethereum_consensus::{ + crypto::PublicKey as BlsPublicKey, + deneb::{compute_fork_data_root, compute_signing_root, Root}, +}; +use eyre::Result; + +use crate::cli::Chain; + +/// The domain mask for the Commit Boost domain. +pub const COMMIT_BOOST_DOMAIN_MASK: [u8; 4] = [109, 109, 111, 67]; + +/// The BLS Domain Separator used in Ethereum 2.0. +pub const BLS_DST_PREFIX: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; + +/// Helper function to compute the signing root for a message +pub fn compute_commit_boost_signing_root(message: [u8; 32], chain: &Chain) -> Result { + compute_signing_root(&message, compute_domain_from_mask(chain.fork_version())) + // Ethereum-consensus uses a different version of alloy so we need to do this cast + .map(|r| B256::from_slice(r.to_vec().as_slice())) + .map_err(|e| eyre::eyre!("Failed to compute signing root: {}", e)) +} + +/// Compute the commit boost domain from the fork version +pub fn compute_domain_from_mask(fork_version: [u8; 4]) -> [u8; 32] { + let mut domain = [0; 32]; + + // Note: the application builder domain specs require the genesis_validators_root + // to be 0x00 for any out-of-protocol message. The commit-boost domain follows the + // same rule. + let root = Root::default(); + let fork_data_root = compute_fork_data_root(fork_version, root).expect("valid fork data"); + + domain[..4].copy_from_slice(&COMMIT_BOOST_DOMAIN_MASK); + domain[4..].copy_from_slice(&fork_data_root[..28]); + domain +} + +/// Verify the signature with the public key of the signer using the Commit Boost domain. +#[allow(dead_code)] +pub fn verify_commit_boost_root( + pubkey: BlsPublicKey, + root: [u8; 32], + signature: &Signature, + chain: &Chain, +) -> Result<()> { + verify_root(pubkey, root, signature, compute_domain_from_mask(chain.fork_version())) +} + +/// Verify the signature of the object with the given public key. +pub fn verify_root( + pubkey: BlsPublicKey, + root: [u8; 32], + signature: &Signature, + domain: [u8; 32], +) -> Result<()> { + let signing_root = compute_signing_root(&root, domain)?; + let pk = blst::min_pk::PublicKey::from_bytes(pubkey.as_ref()).unwrap(); + + let res = signature.verify(true, signing_root.as_ref(), BLS_DST_PREFIX, &[], &pk, true); + if res == BLST_ERROR::BLST_SUCCESS { + Ok(()) + } else { + Err(eyre::eyre!("bls verification failed")) + } +} diff --git a/bolt-cli/test_data/README.md b/bolt-cli/test_data/README.md new file mode 100644 index 000000000..e1e4fd7ff --- /dev/null +++ b/bolt-cli/test_data/README.md @@ -0,0 +1,11 @@ +# test data for the bolt cli tool + +- [`lighthouse`](./lighthouse/): A lighthouse-format keystore according to the [specs][lh-specs]. + It contains two directories: `validators` for the voting-keystores, and `secrets` for the passwords + needed to decrypt the keypairs. + +- [`dirk`](./dirk/): A directory containing test TLS certificates and keys for authenticating a test [Dirk][dirk] + server on localhost. The certificates are self-signed for test purposes and are not to be used in production. + +[lh-specs]: https://lighthouse-book.sigmaprime.io/validator-management.html#automatic-validator-discovery +[dirk]: https://github.com/attestantio/dirk diff --git a/bolt-cli/test_data/dirk/.gitignore b/bolt-cli/test_data/dirk/.gitignore new file mode 100644 index 000000000..98368746f --- /dev/null +++ b/bolt-cli/test_data/dirk/.gitignore @@ -0,0 +1 @@ +dirk.json \ No newline at end of file diff --git a/bolt-cli/test_data/dirk/client1.crt b/bolt-cli/test_data/dirk/client1.crt new file mode 100644 index 000000000..2af82337f --- /dev/null +++ b/bolt-cli/test_data/dirk/client1.crt @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgIUS6WAuJjrNKU6qzOR3/cxTooU9/IwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEwMjIwOTA2MjFaFw0yOTEw +MjEwOTA2MjFaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANyTDRfa37FhTG2qEPckYPR6vP1tFcUqatK1V5mhKk7p +U38dF5YtCwuNX0FH/iG4fe7w3Xavt86aVVOpUF/Vxy3becv+RThpmUbRzCN/FlfT +ZzxsEMN/VFABRarxQK24UCbjnQ7p/yHiXOeRE5pAgBanp5uKKkSq+qEo9sb7s0w9 +c6ifgXQR/GuX68yui1XiJgE3WlkTk/hvKbbOAAhuzE0x9atndbFfBRMO1Sz7zScH +HF0cp/YI2SRx5cx7ovj9biOR0hi0Af+DuHT15vznDkfMo4sAT28CeBjtXBM1eYY9 +cm6gD7zm35+kcD2xulVkw4a/AueBLOwiszclnIKULC1t4ubuwYx6Be2uGrwBy2x3 +sJh8NoMVqGqZLfVmZ7qpah1iBMsuGhH+NjZtdiKeFtU2KhOkbpUlSVHCoL3Qn8xY +eytg7IqyfXZ0YSVnE3YsAJDCOjh1vQXTK0FMkt4z4uaM8UepG5ucurhQpGcEbcSj +DLxLbHMlR4dMFNlR825OPBBVpNLxXyfsHNuftJmX0OziSS2glVjYERqRWpkglgh2 +EHL2P2R63LRMNr9qKJBdZbHzschURvcZLuNr8dqkCS83vtOhHhCH9Hyl+QZC9w+F +MgIgdbxyE0iSUwVu2gwWqoPLC9gf0rssLxySkaKXUEizpbcuyb9qnT/JlNxahaDd +AgMBAAGjcDBuMB8GA1UdIwQYMBaAFO3Lnl1Id4OcqYwhtgbFXrx6min4MAkGA1Ud +EwQCMAAwCwYDVR0PBAQDAgTwMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAdBgNVHQ4E +FgQUWlWshAUj6JXYhYHPlSKkBCx2A9swDQYJKoZIhvcNAQELBQADggIBACuvuqA1 +aL+iiyZw8DUnPgBFHoFRbViLKLxg6Qiqv/ldvoLYKYzE5rlCuSoSRoh2cd7Du3i8 +66cRrp8eh70XiHM5P7034BdYzIo7oCHfEmVPJpo1+G85+WbNzTf2ZLNFGoeudOGw +Kvwkxb4gr2xX03EOms/w2EyVycdQ0u7Y0yaDluDhXQF2ynJYnXDGx5oIrwp9YQWF +neGSyCTP4A67QybKYaA1p1Jibhv3i4QPcFHFOSOFOidqWn01zY/TS0kxQvFpX9cB +7LjMTujHiTdZGZVHFAf9gAlMXQ1jvYdUf9r1qOXvnBOLI/aqV5fLKqgXXmqt5WFZ +bhtbUVhEu4OEavgboPOt3WUpbXSnHyVR7t/f/wtycOnfTcYcQb2dZAGRyLP/cVQt +nDBElrpUHizysNuNMa1rfd/3WC0FvC0/M2OwNK1ad9itctGKel0UrTvCU59/GO3C +P6Q2EFxyQc1wAgekkBZQX5se9RcTo8VJlV16ZMlo4tm3l57YtHwipKCVVf7EUgxu +Bsj21nBY5nOIHzaYAqF5Bz7/Lg/9IFuVx/sPatcMYmUcYkPSvm/1uRB17lr30sQp +bOKGbxzv00JFBwF0t6ZO/XnpLQiHLBtbwgGKMUak0/wZiFiZPmcdaljHLqq08fPV +S3zuTPjwU2aaQsAqAu9F/B1Cn2/gFiJEL/Mg +-----END CERTIFICATE----- diff --git a/bolt-cli/test_data/dirk/client1.key b/bolt-cli/test_data/dirk/client1.key new file mode 100644 index 000000000..7d7601a25 --- /dev/null +++ b/bolt-cli/test_data/dirk/client1.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQDckw0X2t+xYUxt +qhD3JGD0erz9bRXFKmrStVeZoSpO6VN/HReWLQsLjV9BR/4huH3u8N12r7fOmlVT +qVBf1cct23nL/kU4aZlG0cwjfxZX02c8bBDDf1RQAUWq8UCtuFAm450O6f8h4lzn +kROaQIAWp6ebiipEqvqhKPbG+7NMPXOon4F0Efxrl+vMrotV4iYBN1pZE5P4bym2 +zgAIbsxNMfWrZ3WxXwUTDtUs+80nBxxdHKf2CNkkceXMe6L4/W4jkdIYtAH/g7h0 +9eb85w5HzKOLAE9vAngY7VwTNXmGPXJuoA+85t+fpHA9sbpVZMOGvwLngSzsIrM3 +JZyClCwtbeLm7sGMegXtrhq8Actsd7CYfDaDFahqmS31Zme6qWodYgTLLhoR/jY2 +bXYinhbVNioTpG6VJUlRwqC90J/MWHsrYOyKsn12dGElZxN2LACQwjo4db0F0ytB +TJLeM+LmjPFHqRubnLq4UKRnBG3Eowy8S2xzJUeHTBTZUfNuTjwQVaTS8V8n7Bzb +n7SZl9Ds4kktoJVY2BEakVqZIJYIdhBy9j9kety0TDa/aiiQXWWx87HIVEb3GS7j +a/HapAkvN77ToR4Qh/R8pfkGQvcPhTICIHW8chNIklMFbtoMFqqDywvYH9K7LC8c +kpGil1BIs6W3Lsm/ap0/yZTcWoWg3QIDAQABAoICACF+sx5MPmvROqnsiWb+Pzrg +6JITXpryNgaJQyQxNRuGkwdag5pqfKLkdPKU3CKCwZznNrovNNpK1Wo+69WhwP1V +tskjc599aak3cqhxRBNSJvsl7eXCECuWBd5PhGLc+k7tgYwiPHwIw9LmVPO3l7vY ++brE4GZNEIIollDhJ/kL2+RfVGkr0gkEqOoMF1yTWvIUVcPxFSdEujDoV1jwelW+ +oG/G5jhpFXwvZG/QTPcAPW5mS5sw/MhsA1lp7PWihncgTacyrpr+haQ9MzZ0X9bH +XI5fHbDdzx757GF+XVXlPttNsxYceRjk/6Zets0A4DA2EVrWYtv46P4W2A18Mrjr +BtEWBy/ggTrGoEc/r4WdVYz7V1vLaYOk8bDkhpsCv5WznCzg8DrzY+CFjk+BEV/S +Ib1e8iNai5JYv9Ng0X9mPkop2FHXwJnj7jt/+Hdyf4TCoOYtM0AfZDPpS2fglXi/ +9Pp9wusY01khm339yPEdPJOYjKuYa4NuQlwy4iOo+KEJIRCXvLwSxV6Eb2AZZaU1 +/1ddKU2u/wi1EdyeiNbZASOjiIC6gMhRgPX0DVCn3cPTSekV3Y82vyM8kNKyDMIc +j8qIPPFxRnqUs+/0cI64M+EPiybdtqVSCb7Qp4raMMLeFtntdqlNEkBmKZ6PRDbY +8+eMLEXcD3Kp7UQtRuCBAoIBAQD9C+WIlW7pxx88oGl0xX+BhUwO1T2Ul8zF7dfp +B0QqN62B9AIgELYJ8rcdprBDtVcFehSOgWGYMYA0tVSauqnIip0x9bsMhiO2NtX6 ++7ci9jEQw/UGfXg6EUBioG9PpgGovDo2vGMEGK1KrIEfvilhqOP04oqD8OltQQ4p +FDIC2+FFsV0mshDcuGSbWMbV/ogyg+t1NdKZT6AT7q89PHY3oMAVPRemtoLc+bfY +LPIfooDqAPTUJ/6w/hcUoGJNF1YwYXewNzNPwlqNqssfBsOIgDwCQnL+v8vo/6hj +VSHKZSFgTRj25Eo5sy4M8DFji2qlv4OZs1Hv9/lBtIdjCZA3AoIBAQDfJiDCkGNV +XI+uhKqhBCSa7HlEHFrVtoF3VPSVd4XlaCLUFON4TCPjAfTHm96dCJHbCiTu1urJ +n06P6+wTMoFv5W6xyACfuseDgzmnq0+gu5N/GqrJ9sXqe3ZG+wvOFLsuwsb/MosF +VDR3CF8Rx+rxMTMqFOolRW/vJDGB0Kl83DjlF9cb00TB+qgnZZWeR1ELBfGXMFNo +aMqkP9TjNaAwphzx+5rzY9tbPnvqzJPRjwhDx/e5khSx57FJob8OhX8QyC+yJmjK +GfTyETKxgenOh/drQyxpgybUkKqQtMYI4q6WiJ/E50U5Y7a+K5wwZ7GtUGAH0aRq +dSdr5BW5dsWLAoH/B+hXQ+1nieavEzXwFbYWRfXkapI/WmVkAMtt89pGRwt2YJk/ +d8EN70Gmd0a+O19vWLx35/wjEJ57YypHeo5av+mU//qt3bZTZ15PUYiMMIuA/QUi +oxFIsIfZezuIPvTxGFTJfOxmK7qZr7u0TUmkAWlFtmFd8sGUidV+m8oFxhEY+RSR +1KO74ynf+vrLO+S4XNvCf+curZvPZNAQqdk52IMtfXxrQMpzTHSBSkAdUN/DJ4zg +GcEmNGG8VuisKbyQ9PIWy2ruL4/jRIoRzuZnNdzMA0YQUeWseZuDp5cBd1GxuVCv +dwerSiJPThgzcujobEWP1z3DUbxuDZ+Wm4GxAoIBAQDa6ce3t/iLFIwsVCAkaDEU +/yoUJJEEGdA25lQvkZr8rEWGs5tYN7H5EME3VXV1rqOQNAp5eMPK2osy6+qkBqcu +w/DtXd0m1hDGtuTH1Wr/ryUKy3mDOqF84HPvPHefS306aYDZeJcjujDiGYdSpUKa +LX8ZKH1v5QfjniknRjIPuOfj75hqxr8sYZ+3TpQSO7qIyuLwREt/IVay/Z/26nPl +ZgD9b6zaWzsl702X0eyt59jezfz7wxCkWzz0lEYfk91M9Ga+KaohoodHNpH5zA44 +O/EA/FxEgpKEdAuwfHfO3bsTGKNMgunJXEY5mATZA9Etyqz63rKicZ4j3RVm5drz +AoIBAQCzvTWkOKNhp3MIrAp/uTbsmx76rrac1z1x6vjYteZgEtQAqlajy0AEIToi +/5Ds2psTumJ4DsHole1gi6wvYbsTOutHeSKl5pTw96+6JJfifWENZDsNvNoEk8kp +99X9cn8BBY/wrKE5hHDmfwyV7ZurZqxLsaRVBpOYoZsBxK8QzCu/7OnENI62RBaJ +ICPhHA0XnJ/tK06WhTlG4nYdLA50Q0sUqEAB/RD/kCAxIsFnHjP9ooT7STSGgmo+ +M/olWJN3eUkBLSD9uD++n7xj2gcONro6N+7dKpENzslzWNPsXEczF4R9lG+75ea4 +nJqYM6m13Q+F0Wu8krDMA65Wi5nA +-----END PRIVATE KEY----- diff --git a/bolt-cli/test_data/dirk/dirk.template.json b/bolt-cli/test_data/dirk/dirk.template.json new file mode 100644 index 000000000..e51b81701 --- /dev/null +++ b/bolt-cli/test_data/dirk/dirk.template.json @@ -0,0 +1,26 @@ +{ + "server": { + "id": 212483780, + "name": "localhost", + "listen-address": "localhost:9091" + }, + "certificates": { + "ca-cert": "file://$PWD/security/ca.crt", + "server-cert": "file://$PWD/security/localhost.crt", + "server-key": "file://$PWD/security/localhost.key" + }, + "peers": { + "212483780": "localhost:9091" + }, + "permissions": { + "client1": { + "wallet1": "All" + }, + "localhost": { + "wallet1": "All" + } + }, + "unlocker": { + "wallet-passphrases": ["file://$PWD/wallet1-pf.txt"] + } +} diff --git a/bolt-cli/test_data/dirk/security/ca.crt b/bolt-cli/test_data/dirk/security/ca.crt new file mode 100644 index 000000000..b5e0e8589 --- /dev/null +++ b/bolt-cli/test_data/dirk/security/ca.crt @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIUajRZTClnGXJo8F4++mVh3BuvA0wwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEwMjIwOTA0MjNaFw0yOTEw +MjEwOTA0MjNaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC4Svtmk0sKkTk4hlrnWEVgJ14vVeUbb9vA0mpGDUaX +SeZiMiYGJjug6mSt1AiVSzbOWXH1Dit37q7KP44USgCg42kLKqEAgud+bg2SNAw8 +Doat+yA6xyZMl1T63oZHZN3qy5SY/m6BJECYAjij9Uw0wNpX86tBTPyNCWdDGOR7 +XN44QhDqgaRWT1j6zZJ1ilDM/v0c116JZybK74YSDI7kBw9ZRJBdpNi7aEs5oI8a +IU2KAGQxp+GE96M68m9ny+VqMR9Ihm8OuHwtHa4TxxGmVVS9K0WlQH+UbOeVON+k +yIbJRLzED1o91Qp2JzmIDE0bh3/DewYgMvKIDaGoB5v/6+TuXPD4HOBVWOeIqaq1 +myUJb73KvQG6o4FrwcdN10/3595/7tf/R/YKIEQ5HJVlFfRSIf2svqz0op0kHkaP +TVhg1IoXPm6vIs1YElVLyXwMnGrjp2HX6BHXMpoUTyTXvZ2l7keki953LdfuJ6he +NGZvkrQVlXxJf50J6XVqfdG7wpjAKxK5QMCEtveeEcrr36i3uLxEsnOstU13WMmL +xoFSIaQfwML1uZifN+PcN4jVxSPvtSXrrJdtBgojPcr5CHjnY6iyrqgi1mndXi3y +fO7dtW/gJ552uyCdWlVV/dTNTej9uhDIRJl5QMl7olODZ6O/iYkRbaOnQMP4ZACF +AwIDAQABo1MwUTAdBgNVHQ4EFgQU7cueXUh3g5ypjCG2BsVevHqaKfgwHwYDVR0j +BBgwFoAU7cueXUh3g5ypjCG2BsVevHqaKfgwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEAiZeQIdvj9jWbYRBfKADAKMIQDKGhZ+fnEh+WT4EpLUyo +MrCFx1tS12iACwjo/8QoDlljriQvWeEVNxICuE8L3mwuwKc1KuzxcRV7O6tvP6Ox +vDRoy0+uPBn5Cg9Cae0SOEDN0kYqQ2YGO9cioLFfkxquzAiuh70xsJ/j523QedXw +Y234FC/EDk3dd9BvTefqxfrzwl5UIcn7uXjhorB6bw3u4eraRKlUSyICCNs6LO+X +I9xiOdjrDrwJQtjVRvpGIOOVoyGEfoj+P0hVcsuRc0AGDaFaHn1/Jpylxcrhduuw +hFXOIvx9vAGQpzSPOvUO/rFu4ofAj7mEwiHX1RN87WdhEkKVD3nddfJyeLfUObuR +kKsPucU0I0uEVJ7ymL3R7ClAFZ89sH1yStiocsxAYlhOchxbcgLvmczbvkLtQpHE +vvynNohxJThSWRhM36i5BSi8nOtVqPeXWO45eE3jEg4j/BbYZwmwDxpJjBViHS2S +XhBpJlhEMZ9jBbdq0LivGfoR5AP7HcFwm1pxR7DcJbIOBAbdHNaZF+wqSxJyMpoH ++1QJUW1ArseG45zfKNRzNO1AxDqEnRD6hurYVhOuyoh4nsTUmTa+aCRbCgtLLzwf +7z1tWIPMeUYlwLyVcDBOt1m8NLbIYfkP9tcjDJGufQ02Y3l+0/5Tv5xUXW6zuAI= +-----END CERTIFICATE----- diff --git a/bolt-cli/test_data/dirk/security/localhost.crt b/bolt-cli/test_data/dirk/security/localhost.crt new file mode 100644 index 000000000..2847974ab --- /dev/null +++ b/bolt-cli/test_data/dirk/security/localhost.crt @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgIUS6WAuJjrNKU6qzOR3/cxTooU9/EwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEwMjIwOTA1MjlaFw0yOTEw +MjEwOTA1MjlaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBALrlmq0IifUnHe8mv1uGDHkudYfZhv2ttsfGVTU3CQNN +WHsVu0Tm2JS7ressCyB9wDa0HsUKEE/b0Lfsdwk/v4A00khStTNYuCdY7cfIoloz +LzF2THDAAEGHJ3oFLy4XyxvtClIj8fZqt2ygSqiUCQh8FoJntdE46G3z7Yf/PMWF +5zpeasUbThvl4Ljwys2jj8L6e7fiWa4ir+gv5OIqkpwvdwM2CWudeF3TXC5V1c3Z +QxxPqD9ESyltfCLjy0G/Y+2326hrI7YU/44IBZ2CEbCEfcOitBjCY2jOifEorv2T +XOGH7wvt17pSRKnnvRjLWlLdONKWNJCDaMgzwEtm7N8BZXITojHWM7f5N3c386fD +e+LP9riD5W0Y84VLy/nUD0214IRcmcekVzi24RJ9vlmtMgPYCsULDXO/ZLQ9VVxq +Di3NfuEJEWtVOH5Izch0/Koq702r9/PTrAqQv3i/ph5FGizJacX8FsgzHtlPJPix +5MRTppdin/IcYkI41gBaxGvzMKAMfzALsiac7FLUbzP7HY+GbLN+GluheDBEn0CB +DRE9U1rbku9N/Rkf/I3a8UnfHGtW/JSF15o28z5+W7dehguVSOmbP4KaWgNm2cTX +QSEdvJKr23w8r+aW1gCGKlXwkxZS6GHvgmjWHhB5mJBsYujjxmg2cEPl2CjqGLTF +AgMBAAGjcDBuMB8GA1UdIwQYMBaAFO3Lnl1Id4OcqYwhtgbFXrx6min4MAkGA1Ud +EwQCMAAwCwYDVR0PBAQDAgTwMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAdBgNVHQ4E +FgQUkjkxOfOFwdfEqOs8Sokmno68mD8wDQYJKoZIhvcNAQELBQADggIBAKo2RgA3 +2hb1ejZqbizUW8no4rX4Ok9ZYRcw/iviawWP24PzVuJIQSsHPsLOah+QWvGW/p0C +ZxsnUPhbjawF7f27BKSCrynhjsl9FwfEva3RY71iNvYO6I2JIUndcSTqA0QCLkIt +s/p7Bj+eWJ3PdoKh6kUerAZIjlmNA0XX1BFFf5QEcsESHq4JSv9KLgwPHQRbdYAa +A99oB9p/Rxeum39Bx6A+FQH5M0uhd+EMmMfa5ZsVNgLQAUcnt88q0D5o+vQVWcp4 +/6I3SmExTCCBmGmSJ4d0uzec02Pm5HjBeKo89tdVZZRtpMJe3bkVD+03jbdcXBSv +KeFqyeyCS5xXzpXZwD+5kommsOe27WgDj9XHAYMQvKoqWnM3NfS5Qsbop4KAfECZ +cmqn70p/3eT8o22G1U9uw0LMB97W660bW6bJN7K7Q1K288NABu6yqGlI32iTiJRd +6PeOhJsERik38SmgfoPNlZmi0VXuDycl/lI4MuUw+8tJ4Wggc2KA00y4J05jWf5Z +ag/dRcq6knqVykHJ9P8zVZnaHyLBT4jZItiem9iaogO5RzoGr9o1Yj+20MVUglcJ +b2i4z0BynVF+0RI38jL6reJ+UnREAEUz9yOEkHkg9ocoTKCYOY/mj1X+t7TyuQz5 +dT/migcmX+PolDOKVvY7Mn3bH1Lb+IbtydDx +-----END CERTIFICATE----- diff --git a/bolt-cli/test_data/dirk/security/localhost.key b/bolt-cli/test_data/dirk/security/localhost.key new file mode 100644 index 000000000..90413bf83 --- /dev/null +++ b/bolt-cli/test_data/dirk/security/localhost.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQC65ZqtCIn1Jx3v +Jr9bhgx5LnWH2Yb9rbbHxlU1NwkDTVh7FbtE5tiUu63rLAsgfcA2tB7FChBP29C3 +7HcJP7+ANNJIUrUzWLgnWO3HyKJaMy8xdkxwwABBhyd6BS8uF8sb7QpSI/H2ards +oEqolAkIfBaCZ7XROOht8+2H/zzFhec6XmrFG04b5eC48MrNo4/C+nu34lmuIq/o +L+TiKpKcL3cDNglrnXhd01wuVdXN2UMcT6g/REspbXwi48tBv2Ptt9uoayO2FP+O +CAWdghGwhH3DorQYwmNozonxKK79k1zhh+8L7de6UkSp570Yy1pS3TjSljSQg2jI +M8BLZuzfAWVyE6Ix1jO3+Td3N/Onw3viz/a4g+VtGPOFS8v51A9NteCEXJnHpFc4 +tuESfb5ZrTID2ArFCw1zv2S0PVVcag4tzX7hCRFrVTh+SM3IdPyqKu9Nq/fz06wK +kL94v6YeRRosyWnF/BbIMx7ZTyT4seTEU6aXYp/yHGJCONYAWsRr8zCgDH8wC7Im +nOxS1G8z+x2PhmyzfhpboXgwRJ9AgQ0RPVNa25LvTf0ZH/yN2vFJ3xxrVvyUhdea +NvM+flu3XoYLlUjpmz+CmloDZtnE10EhHbySq9t8PK/mltYAhipV8JMWUuhh74Jo +1h4QeZiQbGLo48ZoNnBD5dgo6hi0xQIDAQABAoICAC5v2RgwHHMElpvysS4Q5u1/ +HSW1ZySFsnn9rfMsavlekOL4OdD7WInP/f0GMveONyGAbHrBrt7gu4HPZ54tMCwv +M6ZTooERBKSGJIJ0t94YhJvSDFkhY47kgWsAecIGmGkmYt+Y3cg/qLZ9Nz+elIX+ +qusY0KSc8qdLKdQWF2fuhs7KYdX6nFQzMDxTW9hvUMt9yBqey3CIXtOefsyxDj9v +Ta9HEF0kQaFyYB+FJTvhxRp2MlQR6GjxMpxKpBiAcNhCS/oTMMrPedW06YxCopmM +ueDPftb+CYwjcUOxu5T2tee1ijAZFvZM9ZGPqjzMXfNj0vgD6SiU9gZ0UU2K08SC +VUg9DdBlFE+FR4/L9jzu8UCZTG995b2FkADVy0Y7nHkDMqmrfj5Z0aLTYhcuBk1R +uzxxNNa1rngG4j/YldiR0dtvYdSgc52jFptpkE0cxIjMF3T33WurSsd0xzUoNiIZ +J75e3QK098ksv0wyAnkzPwnj+64encb6o91U5vT2tWM5WSPKhWa9rlybGfL6BPLG +C9lMXcaqiOwxP6UBs9SxR/jVUDPP97n2ALf10S76CdAsZN9HD14beX/7pnQc/6Y+ +q/tY0Q+cXFGHTj1I+sPmruFOG55DQc7aTSjezv1GH4NhZwUk78BKrCJ3UTDBb38S +4XTD01gJVYEAU53aO9HbAoIBAQDcmwwVmgA9FUEQBth8r/lziIuZEWKeNT86KYyp +ayGvcbxKzHVVzRvnzSz151MnrbDVT4N4InyOBTcrlCj/IiASmYnKXj/nC3su9eK8 +VhGHXbnmg34YWjggFPvAGDjGHWADz1DarI08H5KRCAtdrJLTE6sZZRpHpj0poA+k +DRmcp8t0jLhivAwVNFKIiH8Fh3bZClf08YU+Vni3JOTtUrh9p2tGBeb1HTz+BKcc +jtMsx0HNhfzQipF7k+Rjtte8uDZHiqJxToosFrim+2F07B4Hbbmv5xtYBDicHLSi +XYt0QEyH0N4mEwGBx4/IxPMR2teyhyy/erILV/+qLfbBOvmTAoIBAQDY4gjSYW/x +clg6pjUTQbel44w/+XRUJLMq5WIWyTPpLWjMnIPVmcJp5lQWfFwv6NDmp3j8iR1h +QehOEer7M0HBSyHPttT2SEf5Wx4Ir+x9dDbq3CfAyx7WafL8uc1d4ysC64wpC0EB +A2It6Hlrg15B+93W6TQPFXIgKBy7aGW830ZsQZS02ch4fY6BSJq/bbxg6WaGW2o8 +uMCFodOj8YmLWnv6OeayCztqWSYD8fcoPpN7rtovx1ZbuzWlWpsiE+SZ9i7bQo0R +IWrRfFpAeMnG8FLjoL8O+tkQzWCh5Vm8itPjDKbe1U9pUDUJ/TbNHee6KBVzaYOE +2Qudb0Dilq9HAoIBAFzTAKq2OhN5tf7AYqdUhGoQsmyd3Bkl3ozinsVKxsnD2a6/ +iT+pJmzK8Hgn9d1kQFwBMRiDqlU37JbxqK5x9XzeDhSQw+K7+gEwhU8qCAYlceuE +uLIWhDc7nRKfHoR+J8Byo1rf8C20Oz+7Wsz3qHAYfo4Y9I3hbSrupqYovPYlxH4u +GAeziIIDmhbJGGmDLob0yz3NwnsQd4rYg1s4y1hT8dds9Fl/DAL2gjqJ/mGBFjcc +gdxd8glFmXw7m1tVR8Gim+eBXLJgfSIF9GP2VkxZ5yAU5nSKkideDMOlCODJjWo4 +gMEUjjXFesLH3F9O7iO4rSOExRXw2SsKXCHCZvECggEBANVSdlTfq+izjF6bjobT +U9xiFVfzd90vf98IYdOBsYJ/vJ3MsMtPAm+BMmIvjck92QOV5CWYhAJefi0T6KmN +v/ZsfOQ+s/dOHyT/32myCA1ZWo7lXmB+KWXCLlMwOfRH9c1Ye7L/M7/YYSBAkfUS +8Io8PvYcyKyxbmB8s84NoEwG3NCsLKU5tLn23U0CadsyB2DXEZXDopn5KrwF8RJH +B/++T0VO4D9tVtKCvyaQP4chDZVQ5aCrE6EEYX6zwPTi1i4te+cD7ZbU5KkKBAd4 +Bxea2By2xlXom8qwB4UV/o65ijHABv4Ul5hBYPnjSpyz9nIe7QJo3Qi1J3yBqjN0 +/Q8CggEAFTiOan7pnfp4LVQHKQp9xFubsOikVHGpcaE2CbQ5Pr9qdAbJ1NcdsYwI +5Dk8j495cB8lWnRhX5hzP2Z/KxBSJk4VZgF0ugHpTI59XEoz4B1CuI6CpgDZhaSA +i5Kz8ol2tTWB5bEVlbz8EIqBZAtmBy2bPmvNKNohwI3NyPkFx2eWb4n/JFJKkrb2 +MVGVY+MOO1WX+crOYSEVpB9ue9gfRURooi5SApcKnZHDKLBYPGEAO6Jj/p2QaltK +OO1sn3SAkYS38CZex2SreNRxOvaNDONP8QyqSvn30r5Oz3zmxGa6aGXilmc785P3 +kkYwJXvS1QdFkYaVFutGpEVVGf6uCw== +-----END PRIVATE KEY----- diff --git a/bolt-cli/test_data/dirk/storage/000000.vlog b/bolt-cli/test_data/dirk/storage/000000.vlog new file mode 100644 index 000000000..ff7a6f8f9 Binary files /dev/null and b/bolt-cli/test_data/dirk/storage/000000.vlog differ diff --git a/bolt-cli/test_data/dirk/storage/KEYREGISTRY b/bolt-cli/test_data/dirk/storage/KEYREGISTRY new file mode 100644 index 000000000..cd3e15ea5 --- /dev/null +++ b/bolt-cli/test_data/dirk/storage/KEYREGISTRY @@ -0,0 +1 @@ +ΰέυφƒAχΈcΎΘΑW•Hello Badger \ No newline at end of file diff --git a/bolt-cli/test_data/dirk/storage/LOCK b/bolt-cli/test_data/dirk/storage/LOCK new file mode 100644 index 000000000..31ab16834 --- /dev/null +++ b/bolt-cli/test_data/dirk/storage/LOCK @@ -0,0 +1 @@ +33375 diff --git a/bolt-cli/test_data/dirk/storage/MANIFEST b/bolt-cli/test_data/dirk/storage/MANIFEST new file mode 100644 index 000000000..0b5596943 Binary files /dev/null and b/bolt-cli/test_data/dirk/storage/MANIFEST differ diff --git a/bolt-cli/test_data/dirk/wallet1-pf.txt b/bolt-cli/test_data/dirk/wallet1-pf.txt new file mode 100644 index 000000000..536aca34d --- /dev/null +++ b/bolt-cli/test_data/dirk/wallet1-pf.txt @@ -0,0 +1 @@ +secret \ No newline at end of file diff --git a/bolt-delegations-cli/test_data/lighthouse/secrets/0x8a37d5942b2919e4e77f7784805146da013bd4cd0c77eee5f689873980a23c70570dfd08abc3b267003b32d2e1c015eb b/bolt-cli/test_data/lighthouse/secrets/0x8a37d5942b2919e4e77f7784805146da013bd4cd0c77eee5f689873980a23c70570dfd08abc3b267003b32d2e1c015eb similarity index 100% rename from bolt-delegations-cli/test_data/lighthouse/secrets/0x8a37d5942b2919e4e77f7784805146da013bd4cd0c77eee5f689873980a23c70570dfd08abc3b267003b32d2e1c015eb rename to bolt-cli/test_data/lighthouse/secrets/0x8a37d5942b2919e4e77f7784805146da013bd4cd0c77eee5f689873980a23c70570dfd08abc3b267003b32d2e1c015eb diff --git a/bolt-delegations-cli/test_data/lighthouse/secrets/0x8a5985a8000d845913dad7651ea42f30b71b561cf759189f3390ddfa726d1112b182af8547a8393af24116173832442f b/bolt-cli/test_data/lighthouse/secrets/0x8a5985a8000d845913dad7651ea42f30b71b561cf759189f3390ddfa726d1112b182af8547a8393af24116173832442f similarity index 100% rename from bolt-delegations-cli/test_data/lighthouse/secrets/0x8a5985a8000d845913dad7651ea42f30b71b561cf759189f3390ddfa726d1112b182af8547a8393af24116173832442f rename to bolt-cli/test_data/lighthouse/secrets/0x8a5985a8000d845913dad7651ea42f30b71b561cf759189f3390ddfa726d1112b182af8547a8393af24116173832442f diff --git a/bolt-delegations-cli/test_data/lighthouse/validators/0x8a37d5942b2919e4e77f7784805146da013bd4cd0c77eee5f689873980a23c70570dfd08abc3b267003b32d2e1c015eb/voting-keystore.json b/bolt-cli/test_data/lighthouse/validators/0x8a37d5942b2919e4e77f7784805146da013bd4cd0c77eee5f689873980a23c70570dfd08abc3b267003b32d2e1c015eb/voting-keystore.json similarity index 100% rename from bolt-delegations-cli/test_data/lighthouse/validators/0x8a37d5942b2919e4e77f7784805146da013bd4cd0c77eee5f689873980a23c70570dfd08abc3b267003b32d2e1c015eb/voting-keystore.json rename to bolt-cli/test_data/lighthouse/validators/0x8a37d5942b2919e4e77f7784805146da013bd4cd0c77eee5f689873980a23c70570dfd08abc3b267003b32d2e1c015eb/voting-keystore.json diff --git a/bolt-delegations-cli/test_data/lighthouse/validators/0x8a5985a8000d845913dad7651ea42f30b71b561cf759189f3390ddfa726d1112b182af8547a8393af24116173832442f/voting-keystore.json b/bolt-cli/test_data/lighthouse/validators/0x8a5985a8000d845913dad7651ea42f30b71b561cf759189f3390ddfa726d1112b182af8547a8393af24116173832442f/voting-keystore.json similarity index 100% rename from bolt-delegations-cli/test_data/lighthouse/validators/0x8a5985a8000d845913dad7651ea42f30b71b561cf759189f3390ddfa726d1112b182af8547a8393af24116173832442f/voting-keystore.json rename to bolt-cli/test_data/lighthouse/validators/0x8a5985a8000d845913dad7651ea42f30b71b561cf759189f3390ddfa726d1112b182af8547a8393af24116173832442f/voting-keystore.json diff --git a/bolt-delegations-cli/.env.keystore.example b/bolt-delegations-cli/.env.keystore.example deleted file mode 100644 index 1e1938fd8..000000000 --- a/bolt-delegations-cli/.env.keystore.example +++ /dev/null @@ -1,7 +0,0 @@ -# generate keystore - -PATH=keys -PASSWORD=password -DELEGATEE_PUBKEY=0x83eeddfac5e60f8fe607ee8713efb8877c295ad9f8ca075f4d8f6f2ae241a30dd57f78f6f3863a9fe0d5b5db9d550b93 -OUTPUT_FILE_PATH=delegations.json -CHAIN=kurtosis \ No newline at end of file diff --git a/bolt-delegations-cli/.env.local.example b/bolt-delegations-cli/.env.local.example deleted file mode 100644 index 1d5225855..000000000 --- a/bolt-delegations-cli/.env.local.example +++ /dev/null @@ -1,6 +0,0 @@ -# generate local - -SECRET_KEYS=0f40d627fa199720b79db91ce3f57034680f3ee6eef161abfb8275e676a7fd15,0f40d627fa199720b79db91ce3f57034680f3ee6eef161abfb8275e676a7fd15 -DELEGATEE_PUBKEY=0x83eeddfac5e60f8fe607ee8713efb8877c295ad9f8ca075f4d8f6f2ae241a30dd57f78f6f3863a9fe0d5b5db9d550b93 -OUTPUT_FILE_PATH=delegations.json -CHAIN=kurtosis \ No newline at end of file diff --git a/bolt-delegations-cli/.gitignore b/bolt-delegations-cli/.gitignore deleted file mode 100644 index 31190eaba..000000000 --- a/bolt-delegations-cli/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/target -.env -.env.* -delegations.json -!.env.local.example -!.env.keystore.example \ No newline at end of file diff --git a/bolt-delegations-cli/README.md b/bolt-delegations-cli/README.md deleted file mode 100644 index db5889076..000000000 --- a/bolt-delegations-cli/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# Bolt Delegations CLI - -`bolt-delegations-cli` is an offline command-line tool for safely generating delegation messages -signed with a BLS12-381 key for the [Constraints API](https://docs.boltprotocol.xyz/api/builder) -in [Bolt](https://docs.boltprotocol.xyz/). - -The tool supports two key sources: - -- Local: A BLS private key provided directly from a file. -- Keystore: A keystore file that contains an encrypted BLS private key. - -Features: - -- Offline usage: Safely generate delegation messages in an offline environment. -- Flexible key source: Support for both direct local BLS private keys and Ethereum keystore files (ERC-2335 format). -- BLS delegation signing: Sign delegation messages using a BLS secret key and output the signed delegation in JSON format. - -## Usage - -```text -A CLI tool to generate signed delegation messages for BLS keys - -Usage: bolt-delegations-cli - -Commands: - generate Generate delegation messages - help Print this message or the help of the given subcommand(s) - -Options: - -h, --help Print help - -V, --version Print version -``` - -### Example - -1. Using a local BLS private key: - - ```text - bolt-delegations-cli generate \ - --delegatee-pubkey 0x7890ab... \ - --out my_delegations.json \ - --chain kurtosis \ - local \ - --secret-keys 0xabc123...,0xdef456.. - ``` - -2. Using an Ethereum keystore file: - - ```text - bolt-delegations-cli generate \ - --delegatee-pubkey 0x7890ab... \ - --out my_delegations.json \ - --chain kurtosis \ - keystore \ - --path /keys \ - --password myS3cr3tP@ssw0rd - ``` - -When using the `keystore` key source, the `--path` flag should point to the directory -containing the encrypted keypair directories. - -In case of validator-specific passwords (e.g. Lighthouse format) the `--password-path` -flag must be used instead of `--password`, pointing to the directory containing the password files. - -You can find a reference Lighthouse keystore [here](./test_data/lighthouse/). - -### Supported Chains - -The tool supports the following chains: - -- `mainnet` -- `holesky` -- `helder` -- `kurtosis` - -Each chain has its specific fork version used in computing the signing root. diff --git a/bolt-delegations-cli/delegations.json b/bolt-delegations-cli/delegations.json deleted file mode 100644 index 0637a088a..000000000 --- a/bolt-delegations-cli/delegations.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/bolt-delegations-cli/src/config.rs b/bolt-delegations-cli/src/config.rs deleted file mode 100644 index 5b2294fa1..000000000 --- a/bolt-delegations-cli/src/config.rs +++ /dev/null @@ -1,119 +0,0 @@ -use clap::{Parser, Subcommand, ValueEnum}; -use serde::Deserialize; - -use crate::utils::KEYSTORE_PASSWORD; - -/// A CLI tool to generate signed delegation messages for BLS keys. -#[derive(Parser, Debug, Clone, Deserialize)] -#[command(author, version, about, long_about = None)] -pub struct Opts { - /// The subcommand to run. - #[clap(subcommand)] - pub command: Commands, -} - -#[derive(Subcommand, Debug, Clone, Deserialize)] -pub enum Commands { - /// Generate delegation messages. - Generate { - /// The BLS public key to which the delegation message should be signed. - #[clap(long, env = "DELEGATEE_PUBKEY")] - delegatee_pubkey: String, - - /// The output file for the delegations. - #[clap(long, env = "OUTPUT_FILE_PATH", default_value = "delegations.json")] - out: String, - - /// The chain for which the delegation message is intended. - #[clap(long, env = "CHAIN", default_value = "mainnet")] - chain: Chain, - - /// The action to perform. The tool can be used to generate - /// delegation or revocation messages (default: delegate). - #[clap(long, env = "ACTION", default_value = "delegate")] - action: Action, - - /// The source of the private key. - #[clap(subcommand)] - source: KeySource, - }, -} - -/// The action to perform. -#[derive(Debug, Clone, ValueEnum, Deserialize)] -pub enum Action { - /// Create a delegation message. - Delegate, - /// Create a revocation message. - Revoke, -} - -#[derive(Debug, Clone, Parser, Deserialize)] -pub enum KeySource { - /// Use local private keys to generate the signed messages. - Local { - /// The private key in hex format (required if source is local). - /// Multiple secret keys must be seperated by commas. - #[clap(long, env = "SECRET_KEYS", value_delimiter = ',', hide_env_values = true)] - secret_keys: Vec, - }, - - /// Use an EIP-2335 keystore folder to generate the signed messages. - Keystore { - /// Path to the keystore file. - #[clap(long, env = "KEYSTORE_PATH", default_value = "validators")] - path: String, - - /// The password for the keystore files in the path. - /// Assumes all keystore files have the same password. - #[clap( - long, - env = "KEYSTORE_PASSWORD", - hide_env_values = true, - default_value = KEYSTORE_PASSWORD, - conflicts_with = "password_path" - )] - password: Option, - - #[clap( - long, - env = "KEYSTORE_PASSWORD_PATH", - default_value = "secrets", - conflicts_with = "password" - )] - password_path: Option, - }, -} - -/// Supported chains for the CLI -#[derive(Debug, Clone, Copy, ValueEnum, Deserialize)] -#[clap(rename_all = "kebab_case")] -pub enum Chain { - Mainnet, - Holesky, - Helder, - Kurtosis, -} - -impl Chain { - /// Get the fork version for the given chain. - pub fn fork_version(&self) -> [u8; 4] { - match self { - Chain::Mainnet => [0, 0, 0, 0], - Chain::Holesky => [1, 1, 112, 0], - Chain::Helder => [16, 0, 0, 0], - Chain::Kurtosis => [16, 0, 0, 56], - } - } -} - -#[cfg(test)] -mod tests { - use super::Opts; - - #[test] - pub fn verify_cli() { - use clap::CommandFactory; - Opts::command().debug_assert() - } -} diff --git a/bolt-delegations-cli/src/main.rs b/bolt-delegations-cli/src/main.rs deleted file mode 100644 index 572462201..000000000 --- a/bolt-delegations-cli/src/main.rs +++ /dev/null @@ -1,210 +0,0 @@ -use std::{fs, path::PathBuf}; - -use clap::Parser; -use ethereum_consensus::crypto::{ - PublicKey as BlsPublicKey, SecretKey as BlsSecretKey, Signature as BlsSignature, -}; -use eyre::{bail, Result}; -use lighthouse_eth2_keystore::Keystore; -use serde::Serialize; - -pub mod config; -use config::{Action, Chain, Commands, KeySource, Opts}; - -pub mod types; -use types::{ - DelegationMessage, KeystoreError, RevocationMessage, SignedDelegation, SignedMessage, - SignedRevocation, -}; - -pub mod utils; -use utils::{compute_commit_boost_signing_root, keystore_paths, parse_public_key, KeystoreSecret}; - -fn main() -> Result<()> { - let _ = dotenvy::dotenv(); - - let cli = Opts::parse(); - - match cli.command { - Commands::Generate { delegatee_pubkey, out, chain, source, action } => match source { - KeySource::Local { secret_keys } => { - let delegatee = parse_public_key(&delegatee_pubkey)?; - let messages = generate_from_local_keys(&secret_keys, delegatee, &chain, action)?; - - write_to_file(&out, &messages)?; - println!("Signed delegation messages generated and saved to {}", out); - } - KeySource::Keystore { path, password, password_path } => { - let passwords = if let Some(password_path) = password_path { - KeystoreSecret::from_directory(password_path)? - } else if let Some(password) = password { - KeystoreSecret::from_unique_password(password) - } else { - bail!("Either `password_path` or `password` must be provided") - }; - - let delegatee = parse_public_key(&delegatee_pubkey)?; - let messages = generate_from_keystore(&path, passwords, delegatee, chain, action)?; - - write_to_file(&out, &messages)?; - println!("Signed delegation messages generated and saved to {}", out); - } - }, - } - Ok(()) -} - -/// Generate signed delegations/revocations using local BLS private keys -/// -/// - Use the provided private keys from either CLI or env variable -/// - Create message -/// - Compute the signing roots and sign the messages -/// - Return the signed messages -fn generate_from_local_keys( - secret_keys: &Vec, - delegatee_pubkey: BlsPublicKey, - chain: &Chain, - action: Action, -) -> Result> { - let mut signed_messages = Vec::with_capacity(secret_keys.len()); - - for sk in secret_keys { - let sk = BlsSecretKey::try_from(sk.trim().to_string())?; - - match action { - Action::Delegate => { - let message = DelegationMessage::new(sk.public_key(), delegatee_pubkey.clone()); - let signing_root = compute_commit_boost_signing_root(message.digest(), chain)?; - let signature = sk.sign(signing_root.0.as_ref()); - let signed = SignedDelegation { message, signature }; - signed_messages.push(SignedMessage::Delegation(signed)) - } - Action::Revoke => { - let message = RevocationMessage::new(sk.public_key(), delegatee_pubkey.clone()); - let signing_root = compute_commit_boost_signing_root(message.digest(), chain)?; - let signature = sk.sign(signing_root.0.as_ref()); - let signed = SignedRevocation { message, signature }; - signed_messages.push(SignedMessage::Revocation(signed)); - } - } - } - - Ok(signed_messages) -} - -/// Generate signed delegations/revocations using a keystore file -/// -/// - Read the keystore file -/// - Decrypt the keypairs using the password -/// - Create messages -/// - Compute the signing roots and sign the message -/// - Return the signed message -fn generate_from_keystore( - keys_path: &str, - keystore_secret: KeystoreSecret, - delegatee_pubkey: BlsPublicKey, - chain: Chain, - action: Action, -) -> Result> { - let keystores_paths = keystore_paths(keys_path)?; - let mut signed_messages = Vec::with_capacity(keystores_paths.len()); - - for path in keystores_paths { - let ks = Keystore::from_json_file(path).map_err(KeystoreError::Eth2Keystore)?; - let password = keystore_secret.get(ks.pubkey()).ok_or(KeystoreError::MissingPassword)?; - let kp = ks.decrypt_keypair(password.as_bytes()).map_err(KeystoreError::Eth2Keystore)?; - let validator_pubkey = BlsPublicKey::try_from(kp.pk.serialize().to_vec().as_ref())?; - let validator_private_key = kp.sk; - - match action { - Action::Delegate => { - let message = DelegationMessage::new(validator_pubkey, delegatee_pubkey.clone()); - let signing_root = compute_commit_boost_signing_root(message.digest(), &chain)?; - let signature = validator_private_key.sign(signing_root.0.into()); - let signature = BlsSignature::try_from(signature.serialize().as_ref())?; - let signed = SignedDelegation { message, signature }; - signed_messages.push(SignedMessage::Delegation(signed)); - } - Action::Revoke => { - let message = RevocationMessage::new(validator_pubkey, delegatee_pubkey.clone()); - let signing_root = compute_commit_boost_signing_root(message.digest(), &chain)?; - let signature = validator_private_key.sign(signing_root.0.into()); - let signature = BlsSignature::try_from(signature.serialize().as_ref())?; - let signed = SignedRevocation { message, signature }; - signed_messages.push(SignedMessage::Revocation(signed)); - } - } - } - - Ok(signed_messages) -} - -/// Write the signed delegation to an output json file -fn write_to_file(out: &str, messages: &Vec) -> Result<()> { - let out_path = PathBuf::from(out); - let out_file = fs::File::create(out_path)?; - serde_json::to_writer_pretty(out_file, &messages)?; - Ok(()) -} - -#[cfg(test)] -mod tests { - use ethereum_consensus::crypto::PublicKey as BlsPublicKey; - - use crate::{ - config::{Action, Chain}, - generate_from_keystore, - types::SignedMessage, - utils::{parse_public_key, verify_commit_boost_root, KeystoreSecret}, - }; - - #[test] - fn test_delegation_keystore_signer_lighthouse() -> eyre::Result<()> { - // Read the keystore from test_data - let keys_path = env!("CARGO_MANIFEST_DIR").to_string() + "/test_data/lighthouse/validators"; - let secrets_path = env!("CARGO_MANIFEST_DIR").to_string() + "/test_data/lighthouse/secrets"; - - let keystore_secret = KeystoreSecret::from_directory(secrets_path)?; - - let delegatee_pubkey = "0x83eeddfac5e60f8fe607ee8713efb8877c295ad9f8ca075f4d8f6f2ae241a30dd57f78f6f3863a9fe0d5b5db9d550b93"; - let delegatee_pubkey = parse_public_key(delegatee_pubkey)?; - let chain = Chain::Mainnet; - - let signed_delegations = generate_from_keystore( - &keys_path, - keystore_secret, - delegatee_pubkey.clone(), - chain, - Action::Delegate, - )?; - - let signed_message = signed_delegations.first().expect("to get signed delegation"); - - verify_delegation_signature(signed_message, delegatee_pubkey, chain); - - Ok(()) - } - - fn verify_delegation_signature( - message: &SignedMessage, - delegatee_pubkey: BlsPublicKey, - chain: Chain, - ) { - match message { - SignedMessage::Delegation(signed_delegation) => { - let output_delegatee_pubkey = signed_delegation.message.delegatee_pubkey.clone(); - let signer_pubkey = signed_delegation.message.validator_pubkey.clone(); - let digest = signed_delegation.message.digest(); - assert_eq!(output_delegatee_pubkey, delegatee_pubkey); - - let blst_sig = - blst::min_pk::Signature::from_bytes(signed_delegation.signature.as_ref()) - .expect("Failed to convert delegation signature"); - - // Verify the signature - assert!(verify_commit_boost_root(signer_pubkey, digest, &blst_sig, &chain).is_ok()); - } - _ => panic!("Expected a delegation message"), - } - } -} diff --git a/bolt-delegations-cli/src/types.rs b/bolt-delegations-cli/src/types.rs deleted file mode 100644 index 9fa5b917e..000000000 --- a/bolt-delegations-cli/src/types.rs +++ /dev/null @@ -1,108 +0,0 @@ -use alloy::signers::k256::sha2::{Digest, Sha256}; -use ethereum_consensus::crypto::{PublicKey as BlsPublicKey, Signature as BlsSignature}; -use serde::Serialize; - -#[derive(Debug, thiserror::Error)] -pub enum KeystoreError { - #[error("failed to read keystore directory: {0}")] - ReadFromDirectory(#[from] std::io::Error), - #[error("Failed to read or decrypt keystore: {0:?}")] - Eth2Keystore(lighthouse_eth2_keystore::Error), - #[error("Failed to get public key from keypair: {0}")] - UnknownPublicKey(String), - #[error("Missing password for keypair")] - MissingPassword, -} - -/// Event types that can be emitted by the validator pubkey to -/// signal some action on the Bolt protocol. -#[derive(Debug, Clone, Copy)] -#[repr(u8)] -#[allow(dead_code)] -enum SignedMessageAction { - /// Signal delegation of a validator pubkey to a delegatee pubkey. - Delegation, - /// Signal revocation of a previously delegated pubkey. - Revocation, -} - -/// Transparent serialization of signed messages. -/// This is used to serialize and deserialize signed messages -/// -/// e.g. serde_json::to_string(&signed_message): -/// ``` -/// { -/// "message": { -/// "action": 0, -/// "validator_pubkey": "0x...", -/// "delegatee_pubkey": "0x..." -/// }, -/// "signature": "0x..." -/// }, -/// ``` -#[derive(Debug, Clone, Serialize, PartialEq, Eq)] -#[serde(untagged)] -pub enum SignedMessage { - Delegation(SignedDelegation), - Revocation(SignedRevocation), -} - -#[derive(Debug, Clone, Serialize, PartialEq, Eq)] -pub struct SignedDelegation { - pub message: DelegationMessage, - pub signature: BlsSignature, -} - -#[derive(Debug, Clone, Serialize, PartialEq, Eq)] -pub struct DelegationMessage { - action: u8, - pub validator_pubkey: BlsPublicKey, - pub delegatee_pubkey: BlsPublicKey, -} - -impl DelegationMessage { - /// Create a new delegation message. - pub fn new(validator_pubkey: BlsPublicKey, delegatee_pubkey: BlsPublicKey) -> Self { - Self { action: SignedMessageAction::Delegation as u8, validator_pubkey, delegatee_pubkey } - } - - /// Compute the digest of the delegation message. - pub fn digest(&self) -> [u8; 32] { - let mut hasher = Sha256::new(); - hasher.update([self.action]); - hasher.update(self.validator_pubkey.to_vec()); - hasher.update(self.delegatee_pubkey.to_vec()); - - hasher.finalize().into() - } -} - -#[derive(Debug, Clone, Serialize, PartialEq, Eq)] -pub struct SignedRevocation { - pub message: RevocationMessage, - pub signature: BlsSignature, -} - -#[derive(Debug, Clone, Serialize, PartialEq, Eq)] -pub struct RevocationMessage { - action: u8, - pub validator_pubkey: BlsPublicKey, - pub delegatee_pubkey: BlsPublicKey, -} - -impl RevocationMessage { - /// Create a new revocation message. - pub fn new(validator_pubkey: BlsPublicKey, delegatee_pubkey: BlsPublicKey) -> Self { - Self { action: SignedMessageAction::Revocation as u8, validator_pubkey, delegatee_pubkey } - } - - /// Compute the digest of the revocation message. - pub fn digest(&self) -> [u8; 32] { - let mut hasher = Sha256::new(); - hasher.update([self.action]); - hasher.update(self.validator_pubkey.to_vec()); - hasher.update(self.delegatee_pubkey.to_vec()); - - hasher.finalize().into() - } -} diff --git a/bolt-delegations-cli/test_data/README.md b/bolt-delegations-cli/test_data/README.md deleted file mode 100644 index 7aa1be7fe..000000000 --- a/bolt-delegations-cli/test_data/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# test data for the delegation cli tool - -- `lighthouse`: A lighthouse-format keystore according to the [specs][lh-specs]. - It contains two directories: `validators` for the voting-keystores, and `secrets` for the passwords - needed to decrypt the keypairs. - -[lh-specs]: https://lighthouse-book.sigmaprime.io/validator-management.html#automatic-validator-discovery