diff --git a/Cargo.lock b/Cargo.lock index b6d66d41..8ec885c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,18 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -234,7 +246,7 @@ dependencies = [ "c-kzg", "derive_more 2.0.1", "either", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "ethereum_ssz_derive", "once_cell", "serde", @@ -326,9 +338,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eacedba97e65cdc7ab592f2b22ef5d3ab8d60b2056bc3a6e6363577e8270ec6f" dependencies = [ "alloy-rlp", + "arbitrary", "bytes", "cfg-if", "const-hex", + "derive_arbitrary", "derive_more 2.0.1", "foldhash", "getrandom 0.2.15", @@ -339,6 +353,7 @@ dependencies = [ "keccak-asm", "paste", "proptest", + "proptest-derive", "rand 0.8.5", "ruint", "rustc-hash", @@ -507,12 +522,12 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "ethereum_ssz_derive", "serde", "serde_with", "thiserror 2.0.12", - "tree_hash 0.9.1", + "tree_hash", "tree_hash_derive", ] @@ -538,7 +553,7 @@ dependencies = [ "alloy-rlp", "alloy-serde", "derive_more 2.0.1", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "ethereum_ssz_derive", "rand 0.8.5", "serde", @@ -875,6 +890,15 @@ dependencies = [ "derive_arbitrary", ] +[[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" @@ -1279,6 +1303,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.9.0" @@ -1318,20 +1348,20 @@ dependencies = [ [[package]] name = "bls" version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" dependencies = [ "alloy-primitives", "arbitrary", "blst", "ethereum_hashing", "ethereum_serde_utils", - "ethereum_ssz 0.7.1", + "ethereum_ssz", "fixed_bytes", "hex", "rand 0.8.5", "safe_arith", "serde", - "tree_hash 0.8.0", + "tree_hash", "zeroize", ] @@ -1374,6 +1404,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "blstrs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" +dependencies = [ + "blst", + "byte-slice-cast", + "ff", + "group", + "pairing", + "rand_core 0.6.4", + "serde", + "subtle", +] + [[package]] name = "blstrs_plus" version = "0.8.18" @@ -1484,7 +1530,6 @@ dependencies = [ "axum 0.8.1", "base64 0.22.1", "bimap", - "blst", "bytes", "cipher 0.4.4", "ctr 0.9.2", @@ -1492,7 +1537,7 @@ dependencies = [ "docker-image", "eth2_keystore", "ethereum_serde_utils", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "ethereum_ssz_derive", "eyre", "futures", @@ -1513,8 +1558,9 @@ dependencies = [ "tracing", "tracing-appender", "tracing-subscriber", - "tree_hash 0.9.1", + "tree_hash", "tree_hash_derive", + "types", "unicode-normalization", "url", ] @@ -1540,7 +1586,6 @@ dependencies = [ "async-trait", "axum 0.8.1", "axum-extra", - "blst", "cb-common", "cb-metrics", "eyre", @@ -1552,7 +1597,7 @@ dependencies = [ "serde_json", "tokio", "tracing", - "tree_hash 0.9.1", + "tree_hash", "url", "uuid 1.16.0", ] @@ -1582,7 +1627,7 @@ dependencies = [ "tonic", "tonic-build", "tracing", - "tree_hash 0.9.1", + "tree_hash", "uuid 1.16.0", ] @@ -1602,7 +1647,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", - "tree_hash 0.9.1", + "tree_hash", "url", ] @@ -1672,7 +1717,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -1751,10 +1796,27 @@ dependencies = [ "eyre", "tokio", "tracing", - "tree_hash 0.9.1", + "tree_hash", "tree_hash_derive", ] +[[package]] +name = "compare_fields" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "itertools 0.10.5", +] + +[[package]] +name = "compare_fields_derive" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "const-hex" version = "1.14.0" @@ -1794,6 +1856,25 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "context_deserialize" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "milhouse", + "serde", + "ssz_types", +] + +[[package]] +name = "context_deserialize_derive" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1828,6 +1909,58 @@ dependencies = [ "libc", ] +[[package]] +name = "crate_crypto_internal_eth_kzg_bls12_381" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f9cdad245e39a3659bc4c8958e93de34bd31ba3131ead14ccfb4b2cd60e52d" +dependencies = [ + "blst", + "blstrs", + "ff", + "group", + "pairing", + "subtle", +] + +[[package]] +name = "crate_crypto_internal_eth_kzg_erasure_codes" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581d28bcc93eecd97a04cebc5293271e0f41650f03c102f24d6cd784cbedb9f2" +dependencies = [ + "crate_crypto_internal_eth_kzg_bls12_381", + "crate_crypto_internal_eth_kzg_polynomial", +] + +[[package]] +name = "crate_crypto_internal_eth_kzg_maybe_rayon" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06fc0f984e585ea984a766c5b58d6bf6c51e463b0a0835b0dd4652d358b506b3" + +[[package]] +name = "crate_crypto_internal_eth_kzg_polynomial" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dff7a45e2d80308b21abdbc5520ec23c3ebfb3a94fafc02edfa7f356af6d7f" +dependencies = [ + "crate_crypto_internal_eth_kzg_bls12_381", +] + +[[package]] +name = "crate_crypto_kzg_multi_open_fk20" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a0c2f82695a88809e713e1ff9534cb90ceffab0a08f4bd33245db711f9d356f" +dependencies = [ + "crate_crypto_internal_eth_kzg_bls12_381", + "crate_crypto_internal_eth_kzg_maybe_rayon", + "crate_crypto_internal_eth_kzg_polynomial", + "hex", + "sha2 0.10.8", +] + [[package]] name = "crc" version = "3.2.1" @@ -1883,7 +2016,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags", + "bitflags 2.9.0", "crossterm_winapi", "parking_lot", "rustix 0.38.44", @@ -1971,14 +2104,38 @@ dependencies = [ "tracing", ] +[[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", - "darling_macro", + "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]] @@ -1991,17 +2148,28 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.11.1", "syn 2.0.100", ] +[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core", + "darling_core 0.20.10", "quote", "syn 2.0.100", ] @@ -2083,7 +2251,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.100", @@ -2221,6 +2389,18 @@ dependencies = [ "spki", ] +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "either" version = "1.15.0" @@ -2260,6 +2440,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -2276,10 +2476,23 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "eth2_interop_keypairs" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "bls", + "ethereum_hashing", + "hex", + "num-bigint", + "serde", + "serde_yaml", +] + [[package]] name = "eth2_key_derivation" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" dependencies = [ "bls", "num-bigint-dig", @@ -2291,7 +2504,7 @@ dependencies = [ [[package]] name = "eth2_keystore" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" dependencies = [ "aes 0.7.5", "bls", @@ -2334,17 +2547,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "ethereum_ssz" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e999563461faea0ab9bc0024e5e66adcee35881f3d5062f52f31a4070fe1522" -dependencies = [ - "alloy-primitives", - "itertools 0.13.0", - "smallvec", -] - [[package]] name = "ethereum_ssz" version = "0.8.3" @@ -2352,6 +2554,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86da3096d1304f5f28476ce383005385459afeaf0eea08592b65ddbc9b258d16" dependencies = [ "alloy-primitives", + "arbitrary", "ethereum_serde_utils", "itertools 0.13.0", "serde", @@ -2366,7 +2569,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d832a5c38eba0e7ad92592f7a22d693954637fbb332b4f669590d66a5c3183e5" dependencies = [ - "darling", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.100", @@ -2382,6 +2585,18 @@ dependencies = [ "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.3.0" @@ -2436,7 +2651,7 @@ dependencies = [ [[package]] name = "fixed_bytes" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" dependencies = [ "alloy-primitives", "safe_arith", @@ -2685,6 +2900,10 @@ 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" @@ -2698,6 +2917,15 @@ dependencies = [ "serde", ] +[[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 = "headers" version = "0.4.0" @@ -3123,6 +3351,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ + "arbitrary", "equivalent", "hashbrown 0.15.2", "serde", @@ -3137,6 +3366,14 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "int_to_bytes" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "bytes", +] + [[package]] name = "interprocess" version = "2.2.3" @@ -3253,6 +3490,25 @@ dependencies = [ "sha3-asm", ] +[[package]] +name = "kzg" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "arbitrary", + "c-kzg", + "derivative", + "ethereum_hashing", + "ethereum_serde_utils", + "ethereum_ssz", + "ethereum_ssz_derive", + "hex", + "rust_eth_kzg", + "serde", + "serde_json", + "tree_hash", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -3274,6 +3530,17 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +[[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 = "linux-raw-sys" version = "0.4.15" @@ -3328,6 +3595,12 @@ dependencies = [ "syn 2.0.100", ] +[[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" @@ -3355,6 +3628,17 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "merkle_proof" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "alloy-primitives", + "ethereum_hashing", + "fixed_bytes", + "safe_arith", +] + [[package]] name = "merlin" version = "3.0.0" @@ -3367,6 +3651,52 @@ dependencies = [ "zeroize", ] +[[package]] +name = "metastruct" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d74f54f231f9a18d77393ecc5cc7ab96709b2a61ee326c2b2b291009b0cc5a07" +dependencies = [ + "metastruct_macro", +] + +[[package]] +name = "metastruct_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7225f3a4dfbec47a0c6a730a874185fda840d365d7bbd6ba199dd81796d5" +dependencies = [ + "darling 0.13.4", + "itertools 0.10.5", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "milhouse" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1ada1f56cc1c79f40517fdcbf57e19f60424a3a1ce372c3fe9b22e4fdd83eb" +dependencies = [ + "alloy-primitives", + "arbitrary", + "educe", + "ethereum_hashing", + "ethereum_ssz", + "ethereum_ssz_derive", + "itertools 0.13.0", + "parking_lot", + "rayon", + "serde", + "smallvec", + "tree_hash", + "triomphe", + "typenum", + "vec_map", +] + [[package]] name = "mime" version = "0.3.17" @@ -3560,7 +3890,7 @@ version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -3879,7 +4209,7 @@ checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set", "bit-vec", - "bitflags", + "bitflags 2.9.0", "lazy_static", "num-traits", "rand 0.8.5", @@ -3891,6 +4221,17 @@ dependencies = [ "unarray", ] +[[package]] +name = "proptest-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "prost" version = "0.13.5" @@ -4072,7 +4413,7 @@ version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags", + "bitflags 2.9.0", ] [[package]] @@ -4199,6 +4540,15 @@ dependencies = [ "rustc-hex", ] +[[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.13.1" @@ -4206,6 +4556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "825df406ec217a8116bd7b06897c6cc8f65ffefc15d030ae2c9540acc9ed50b6" dependencies = [ "alloy-rlp", + "arbitrary", "ark-ff 0.3.0", "ark-ff 0.4.2", "bytes", @@ -4231,6 +4582,34 @@ 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 = "rust_eth_kzg" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f83b5559e1dcd3f7721838909288faf4500fb466eff98eac99b67ac04335b93" +dependencies = [ + "crate_crypto_internal_eth_kzg_bls12_381", + "crate_crypto_internal_eth_kzg_erasure_codes", + "crate_crypto_kzg_multi_open_fk20", + "hex", + "serde", + "serde_json", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -4273,7 +4652,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -4286,7 +4665,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" dependencies = [ - "bitflags", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.9.3", @@ -4361,7 +4740,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "safe_arith" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" [[package]] name = "salsa20" @@ -4420,7 +4799,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags", + "bitflags 2.9.0", "core-foundation", "core-foundation-sys", "libc", @@ -4574,7 +4953,7 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ - "darling", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.100", @@ -4707,6 +5086,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" dependencies = [ + "arbitrary", "serde", ] @@ -4742,13 +5122,14 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dad0fa7e9a85c06d0a6ba5100d733fff72e231eb6db2d86078225cf716fd2d95" dependencies = [ + "arbitrary", "ethereum_serde_utils", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "itertools 0.13.0", "serde", "serde_derive", "smallvec", - "tree_hash 0.9.1", + "tree_hash", "typenum", ] @@ -4781,6 +5162,12 @@ dependencies = [ "tracing", ] +[[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" @@ -4815,6 +5202,30 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "superstruct" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf0f31f730ad9e579364950e10d6172b4a9bd04b447edf5988b066a860cc340e" +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?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "alloy-primitives", + "ethereum_hashing", + "fixed_bytes", +] + [[package]] name = "syn" version = "1.0.109" @@ -4875,7 +5286,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags", + "bitflags 2.9.0", "core-foundation", "system-configuration-sys", ] @@ -4909,6 +5320,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "test_random_derive" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -5368,17 +5788,6 @@ dependencies = [ "tracing-serde", ] -[[package]] -name = "tree_hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373495c23db675a5192de8b610395e1bec324d596f9e6111192ce903dc11403a" -dependencies = [ - "alloy-primitives", - "ethereum_hashing", - "smallvec", -] - [[package]] name = "tree_hash" version = "0.9.1" @@ -5387,7 +5796,7 @@ checksum = "6c58eb0f518840670270d90d97ffee702d8662d9c5494870c9e1e9e0fa00f668" dependencies = [ "alloy-primitives", "ethereum_hashing", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "smallvec", "typenum", ] @@ -5398,12 +5807,22 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "699e7fb6b3fdfe0c809916f251cf5132d64966858601695c3736630a87e7166a" dependencies = [ - "darling", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.100", ] +[[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" @@ -5435,6 +5854,56 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "types" +version = "0.2.1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "arbitrary", + "bls", + "compare_fields", + "compare_fields_derive", + "context_deserialize", + "context_deserialize_derive", + "derivative", + "eth2_interop_keypairs", + "ethereum_hashing", + "ethereum_serde_utils", + "ethereum_ssz", + "ethereum_ssz_derive", + "fixed_bytes", + "hex", + "int_to_bytes", + "itertools 0.10.5", + "kzg", + "maplit", + "merkle_proof", + "metastruct", + "milhouse", + "parking_lot", + "rand 0.8.5", + "rand_xorshift", + "rayon", + "regex", + "rpds", + "rusqlite", + "safe_arith", + "serde", + "serde_json", + "serde_yaml", + "smallvec", + "ssz_types", + "superstruct", + "swap_or_not_shuffle", + "tempfile", + "test_random_derive", + "tracing", + "tree_hash", + "tree_hash_derive", +] + [[package]] name = "ucd-trie" version = "0.1.7" @@ -5582,6 +6051,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" @@ -5987,7 +6462,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags", + "bitflags 2.9.0", ] [[package]] @@ -6056,18 +6531,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 3955e9cc..c39ad54b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ axum-extra = { version = "0.10.0", features = ["typed-header"] } base64 = "0.22.1" bimap = { version = "0.6.3", features = ["serde"] } blsful = "2.5" -blst = "0.3.11" bytes = "1.10.1" cb-cli = { path = "crates/cli" } cb-common = { path = "crates/common" } @@ -38,7 +37,6 @@ ctr = "0.9.2" derive_more = { version = "2.0.1", features = ["deref", "display", "from", "into"] } docker-compose-types = "0.16.0" docker-image = "0.2.1" -eth2_keystore = { git = "https://github.com/sigp/lighthouse", tag = "v7.0.1" } ethereum_serde_utils = "0.7.0" ethereum_ssz = "0.8" ethereum_ssz_derive = "0.8" @@ -48,6 +46,8 @@ headers = "0.4.0" indexmap = "2.2.6" jsonwebtoken = { version = "9.3.1", default-features = false } lazy_static = "1.5.0" +lh_eth2_keystore = { package = "eth2_keystore", git = "https://github.com/sigp/lighthouse", tag = "v7.1.0" } +lh_types = { package = "types", git = "https://github.com/sigp/lighthouse", tag = "v7.1.0" } parking_lot = "0.12.3" pbkdf2 = "0.12.2" prometheus = "0.13.4" diff --git a/benches/pbs/src/main.rs b/benches/pbs/src/main.rs index c013fd61..7b852a43 100644 --- a/benches/pbs/src/main.rs +++ b/benches/pbs/src/main.rs @@ -1,12 +1,11 @@ use std::time::{Duration, Instant}; -use alloy::{primitives::B256, rpc::types::beacon::BlsPublicKey}; +use alloy::primitives::B256; use cb_common::{ config::RelayConfig, pbs::{GetHeaderResponse, RelayClient, RelayEntry}, - signer::BlsSecretKey, - types::Chain, - utils::blst_pubkey_to_alloy, + types::{BlsPublicKey, BlsSecretKey, Chain}, + utils::TestRandomSeed, }; use cb_tests::mock_relay::{start_mock_relay_service, MockRelayState}; use comfy_table::Table; @@ -18,9 +17,6 @@ mod config; fn get_random_hash() -> B256 { B256::from(rand::random::<[u8; 32]>()) } -fn get_random_pubkey() -> BlsPublicKey { - BlsPublicKey::ZERO -} #[tokio::main] async fn main() { @@ -46,8 +42,8 @@ async fn main() { // bench for slot in 0..config.benchmark.n_slots { let parent_hash = get_random_hash(); - let validator_pubkey = get_random_pubkey(); - let url = mock_validator.get_header_url(slot, parent_hash, validator_pubkey).unwrap(); + let validator_pubkey = BlsPublicKey::test_random(); + let url = mock_validator.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap(); for _ in 0..config.benchmark.headers_per_slot { let url = url.clone(); @@ -138,8 +134,8 @@ const MOCK_RELAY_SECRET: [u8; 32] = [ 152, 98, 59, 240, 181, 131, 47, 1, 180, 255, 245, ]; async fn start_mock_relay(chain: Chain, relay_config: RelayConfig) { - let signer = BlsSecretKey::key_gen(&MOCK_RELAY_SECRET, &[]).unwrap(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let signer = BlsSecretKey::deserialize(&MOCK_RELAY_SECRET).unwrap(); + let pubkey: BlsPublicKey = signer.public_key(); assert_eq!(relay_config.entry.pubkey, pubkey, "Expected relay pubkey to be 0xb060572f535ba5615b874ebfef757fbe6825352ad257e31d724e57fe25a067a13cfddd0f00cb17bf3a3d2e901a380c17"); @@ -152,7 +148,7 @@ async fn start_mock_relay(chain: Chain, relay_config: RelayConfig) { } fn get_mock_validator(bench: BenchConfig) -> RelayClient { - let entry = RelayEntry { id: bench.id, pubkey: BlsPublicKey::default(), url: bench.url }; + let entry = RelayEntry { id: bench.id, pubkey: BlsPublicKey::test_random(), url: bench.url }; let config = RelayConfig { entry, id: None, diff --git a/bin/src/lib.rs b/bin/src/lib.rs index 126847b6..e0747d2c 100644 --- a/bin/src/lib.rs +++ b/bin/src/lib.rs @@ -10,8 +10,8 @@ pub mod prelude { load_pbs_custom_config, LogsSettings, StartCommitModuleConfig, PBS_MODULE_NAME, }, pbs::{BuilderEvent, BuilderEventClient, OnBuilderApiEvent}, - signer::{BlsPublicKey, BlsSignature, EcdsaSignature}, - types::Chain, + signer::EcdsaSignature, + types::{BlsPublicKey, BlsSignature, Chain}, utils::{initialize_tracing_log, utcnow_ms, utcnow_ns, utcnow_sec, utcnow_us}, }; pub use cb_metrics::provider::MetricsProvider; diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index fe2f9aec..e46e1982 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -12,19 +12,19 @@ async-trait.workspace = true axum.workspace = true base64.workspace = true bimap.workspace = true -blst.workspace = true bytes.workspace = true cipher.workspace = true ctr.workspace = true derive_more.workspace = true docker-image.workspace = true -eth2_keystore.workspace = true ethereum_serde_utils.workspace = true ethereum_ssz.workspace = true ethereum_ssz_derive.workspace = true eyre.workspace = true futures.workspace = true jsonwebtoken.workspace = true +lh_eth2_keystore.workspace = true +lh_types.workspace = true pbkdf2.workspace = true rand.workspace = true rayon.workspace = true diff --git a/crates/common/src/commit/client.rs b/crates/common/src/commit/client.rs index 34413b65..3fe0ab9c 100644 --- a/crates/common/src/commit/client.rs +++ b/crates/common/src/commit/client.rs @@ -1,6 +1,6 @@ use std::time::{Duration, Instant}; -use alloy::{primitives::Address, rpc::types::beacon::BlsSignature}; +use alloy::primitives::Address; use eyre::WrapErr; use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION}; use serde::Deserialize; @@ -16,8 +16,8 @@ use super::{ }; use crate::{ constants::SIGNER_JWT_EXPIRATION, - signer::{BlsPublicKey, EcdsaSignature}, - types::{Jwt, ModuleId}, + signer::EcdsaSignature, + types::{BlsPublicKey, BlsSignature, Jwt, ModuleId}, utils::create_jwt, DEFAULT_REQUEST_TIMEOUT, }; diff --git a/crates/common/src/commit/request.rs b/crates/common/src/commit/request.rs index b8843234..afa01807 100644 --- a/crates/common/src/commit/request.rs +++ b/crates/common/src/commit/request.rs @@ -6,7 +6,6 @@ use std::{ use alloy::{ hex, primitives::{Address, B256}, - rpc::types::beacon::BlsSignature, }; use derive_more::derive::From; use serde::{Deserialize, Serialize}; @@ -14,18 +13,29 @@ use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use crate::{ - constants::COMMIT_BOOST_DOMAIN, error::BlstErrorWrapper, signature::verify_signed_message, - signer::BlsPublicKey, types::Chain, + constants::COMMIT_BOOST_DOMAIN, + signature::verify_signed_message, + types::{BlsPublicKey, BlsSignature, Chain}, }; -pub trait ProxyId: AsRef<[u8]> + Debug + Clone + Copy + TreeHash + Display {} +pub trait ProxyId: Debug + Clone + TreeHash + Display { + fn to_bytes(&self) -> Vec; +} -impl ProxyId for Address {} +impl ProxyId for Address { + fn to_bytes(&self) -> Vec { + self.0.as_slice().to_vec() + } +} -impl ProxyId for BlsPublicKey {} +impl ProxyId for BlsPublicKey { + fn to_bytes(&self) -> Vec { + self.serialize().to_vec() + } +} // GENERIC PROXY DELEGATION -#[derive(Debug, Clone, Copy, Serialize, Deserialize, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, TreeHash)] pub struct ProxyDelegation { pub delegator: BlsPublicKey, pub proxy: T, @@ -40,7 +50,7 @@ impl fmt::Display for ProxyDelegation { } } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct SignedProxyDelegation { pub message: ProxyDelegation, /// Signature of message with the delegator keypair @@ -51,7 +61,7 @@ pub type SignedProxyDelegationBls = SignedProxyDelegation; pub type SignedProxyDelegationEcdsa = SignedProxyDelegation
; impl SignedProxyDelegation { - pub fn validate(&self, chain: Chain) -> Result<(), BlstErrorWrapper> { + pub fn validate(&self, chain: Chain) -> bool { verify_signed_message( chain, &self.message.delegator, @@ -250,7 +260,7 @@ mod tests { #[test] fn test_decode_response_signature() { - let data = r#""0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989""#; + let data = r#""0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000""#; let _: BlsSignature = serde_json::from_str(data).unwrap(); let data = r#""0x985b495f49d1b96db3bba3f6c5dd1810950317c10d4c2042bd316f338cdbe74359072e209b85e56ac492092d7860063dd096ca31b4e164ef27e3f8d508e656801c""#; @@ -283,7 +293,7 @@ mod tests { "delegator": "0xa3366b54f28e4bf1461926a3c70cdb0ec432b5c92554ecaae3742d33fb33873990cbed1761c68020e6d3c14d30a22050", "proxy": "0xa3366b54f28e4bf1461926a3c70cdb0ec432b5c92554ecaae3742d33fb33873990cbed1761c68020e6d3c14d30a22050" }, - "signature": "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989" + "signature": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }"#; let _: SignedProxyDelegationBls = serde_json::from_str(data).unwrap(); @@ -293,7 +303,7 @@ mod tests { "delegator": "0xa3366b54f28e4bf1461926a3c70cdb0ec432b5c92554ecaae3742d33fb33873990cbed1761c68020e6d3c14d30a22050", "proxy": "0x4ca9939a8311a7cab3dde201b70157285fa81a9d" }, - "signature": "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989" + "signature": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }"#; let _: SignedProxyDelegationEcdsa = serde_json::from_str(data).unwrap(); diff --git a/crates/common/src/config/mux.rs b/crates/common/src/config/mux.rs index 65be45fb..0c8f7011 100644 --- a/crates/common/src/config/mux.rs +++ b/crates/common/src/config/mux.rs @@ -8,13 +8,13 @@ use std::{ use alloy::{ primitives::{address, Address, U256}, providers::ProviderBuilder, - rpc::{client::RpcClient, types::beacon::BlsPublicKey}, + rpc::{client::RpcClient, types::beacon::constants::BLS_PUBLIC_KEY_BYTES_LEN}, sol, transports::http::Http, }; use eyre::{bail, ensure, Context}; use reqwest::Client; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use tracing::{debug, info, warn}; use url::Url; @@ -22,7 +22,7 @@ use super::{load_optional_env_var, PbsConfig, RelayConfig, MUX_PATH_ENV}; use crate::{ config::{remove_duplicate_keys, safe_read_http_response}, pbs::RelayClient, - types::Chain, + types::{BlsPublicKey, Chain}, }; #[derive(Debug, Deserialize, Serialize)] @@ -103,8 +103,8 @@ impl PbsMuxes { let config = Arc::new(config); let runtime_config = RuntimeMuxConfig { id: mux.id, config, relays: relay_clients }; - for pubkey in mux.validator_pubkeys.iter() { - configs.insert(*pubkey, runtime_config.clone()); + for pubkey in mux.validator_pubkeys.into_iter() { + configs.insert(pubkey, runtime_config.clone()); } } @@ -296,7 +296,6 @@ async fn fetch_lido_registry_keys( debug!("fetching {total_keys} total keys"); const CALL_BATCH_SIZE: u64 = 250u64; - const BLS_PK_LEN: usize = BlsPublicKey::len_bytes(); let mut keys = vec![]; let mut offset = 0; @@ -311,13 +310,16 @@ async fn fetch_lido_registry_keys( .pubkeys; ensure!( - pubkeys.len() % BLS_PK_LEN == 0, - "unexpected number of keys in batch, expected multiple of {BLS_PK_LEN}, got {}", + pubkeys.len() % BLS_PUBLIC_KEY_BYTES_LEN == 0, + "unexpected number of keys in batch, expected multiple of {BLS_PUBLIC_KEY_BYTES_LEN}, got {}", pubkeys.len() ); - for chunk in pubkeys.chunks(BLS_PK_LEN) { - keys.push(BlsPublicKey::try_from(chunk)?); + for chunk in pubkeys.chunks(BLS_PUBLIC_KEY_BYTES_LEN) { + keys.push( + BlsPublicKey::deserialize(chunk) + .map_err(|_| eyre::eyre!("invalid BLS public key"))?, + ); } offset += limit; @@ -356,10 +358,13 @@ async fn fetch_ssv_pubkeys( ); let response = fetch_ssv_pubkeys_from_url(&url, http_timeout).await?; - pubkeys.extend(response.validators.iter().map(|v| v.pubkey).collect::>()); + let fetched = response.validators.len(); + pubkeys.extend( + response.validators.into_iter().map(|v| v.pubkey).collect::>(), + ); page += 1; - if response.validators.len() < MAX_PER_PAGE { + if fetched < MAX_PER_PAGE { ensure!( pubkeys.len() == response.pagination.total, "expected {} keys, got {}", @@ -397,12 +402,29 @@ struct SSVResponse { pagination: SSVPagination, } -#[derive(Deserialize)] struct SSVValidator { - #[serde(rename = "public_key")] pubkey: BlsPublicKey, } +impl<'de> Deserialize<'de> for SSVValidator { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct SSVValidator { + public_key: String, + } + + let s = SSVValidator::deserialize(deserializer)?; + let bytes = alloy::hex::decode(&s.public_key).map_err(serde::de::Error::custom)?; + let pubkey = BlsPublicKey::deserialize(&bytes) + .map_err(|e| serde::de::Error::custom(format!("invalid BLS public key: {e:?}")))?; + + Ok(Self { pubkey }) + } +} + #[derive(Deserialize)] struct SSVPagination { total: usize, @@ -412,7 +434,7 @@ struct SSVPagination { mod tests { use std::net::SocketAddr; - use alloy::{hex::FromHex, primitives::U256, providers::ProviderBuilder}; + use alloy::{primitives::U256, providers::ProviderBuilder}; use axum::{response::Response, routing::get}; use tokio::{net::TcpListener, task::JoinHandle}; use url::Url; @@ -420,7 +442,7 @@ mod tests { use super::*; use crate::{ config::{HTTP_TIMEOUT_SECONDS_DEFAULT, MUXER_HTTP_MAX_LENGTH}, - utils::{set_ignore_content_length, ResponseReadError}, + utils::{bls_pubkey_from_hex_unchecked, set_ignore_content_length, ResponseReadError}, }; const TEST_HTTP_TIMEOUT: u64 = 2; @@ -448,8 +470,11 @@ mod tests { .pubkeys; let mut vec = vec![]; - for chunk in pubkeys.chunks(BlsPublicKey::len_bytes()) { - vec.push(BlsPublicKey::try_from(chunk)?); + for chunk in pubkeys.chunks(BLS_PUBLIC_KEY_BYTES_LEN) { + vec.push( + BlsPublicKey::deserialize(chunk) + .map_err(|_| eyre::eyre!("invalid BLS public key"))?, + ); } assert_eq!(vec.len(), LIMIT); @@ -472,15 +497,9 @@ mod tests { // NOTE: requires that ssv_data.json dpesn't change assert_eq!(response.validators.len(), 3); let expected_pubkeys = [ - BlsPublicKey::from_hex( - "0x967ba17a3e7f82a25aa5350ec34d6923e28ad8237b5a41efe2c5e325240d74d87a015bf04634f21900963539c8229b2a", - )?, - BlsPublicKey::from_hex( - "0xac769e8cec802e8ffee34de3253be8f438a0c17ee84bdff0b6730280d24b5ecb77ebc9c985281b41ee3bda8663b6658c", - )?, - BlsPublicKey::from_hex( - "0x8c866a5a05f3d45c49b457e29365259021a509c5daa82e124f9701a960ee87b8902e87175315ab638a3d8b1115b23639", - )?, + bls_pubkey_from_hex_unchecked("967ba17a3e7f82a25aa5350ec34d6923e28ad8237b5a41efe2c5e325240d74d87a015bf04634f21900963539c8229b2a"), + bls_pubkey_from_hex_unchecked("ac769e8cec802e8ffee34de3253be8f438a0c17ee84bdff0b6730280d24b5ecb77ebc9c985281b41ee3bda8663b6658c"), + bls_pubkey_from_hex_unchecked("8c866a5a05f3d45c49b457e29365259021a509c5daa82e124f9701a960ee87b8902e87175315ab638a3d8b1115b23639"), ]; for (i, validator) in response.validators.iter().enumerate() { assert_eq!(validator.pubkey, expected_pubkeys[i]); diff --git a/crates/common/src/config/pbs.rs b/crates/common/src/config/pbs.rs index d04b3394..184f0082 100644 --- a/crates/common/src/config/pbs.rs +++ b/crates/common/src/config/pbs.rs @@ -9,7 +9,6 @@ use std::{ use alloy::{ primitives::{utils::format_ether, U256}, providers::{Provider, ProviderBuilder}, - rpc::types::beacon::BlsPublicKey, }; use eyre::{ensure, Result}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -29,7 +28,7 @@ use crate::{ BuilderEventPublisher, DefaultTimeout, RelayClient, RelayEntry, DEFAULT_PBS_PORT, LATE_IN_SLOT_TIME_MS, REGISTER_VALIDATOR_RETRY_LIMIT, }, - types::{Chain, Jwt, ModuleId}, + types::{BlsPublicKey, Chain, Jwt, ModuleId}, utils::{ as_eth_str, default_bool, default_host, default_u16, default_u256, default_u32, default_u64, WEI_PER_ETH, diff --git a/crates/common/src/config/utils.rs b/crates/common/src/config/utils.rs index 13784316..906c45e2 100644 --- a/crates/common/src/config/utils.rs +++ b/crates/common/src/config/utils.rs @@ -1,11 +1,14 @@ use std::{collections::HashMap, path::Path}; -use alloy::rpc::types::beacon::BlsPublicKey; use eyre::{bail, Context, Result}; use serde::de::DeserializeOwned; use super::JWTS_ENV; -use crate::{config::MUXER_HTTP_MAX_LENGTH, types::ModuleId, utils::read_chunked_body_with_max}; +use crate::{ + config::MUXER_HTTP_MAX_LENGTH, + types::{BlsPublicKey, ModuleId}, + utils::read_chunked_body_with_max, +}; pub fn load_env_var(env: &str) -> Result { std::env::var(env).wrap_err(format!("{env} is not set")) @@ -63,7 +66,7 @@ pub fn remove_duplicate_keys(keys: Vec) -> Vec { let mut key_set = std::collections::HashSet::new(); for key in keys { - if key_set.insert(key) { + if key_set.insert(key.clone()) { unique_keys.push(key); } } @@ -88,6 +91,7 @@ fn decode_string_to_map(raw: &str) -> Result> { #[cfg(test)] mod tests { use super::*; + use crate::utils::TestRandomSeed; #[test] fn test_decode_string_to_map() { @@ -101,9 +105,9 @@ mod tests { #[test] fn test_remove_duplicate_keys() { - let key1 = BlsPublicKey::from([1; 48]); - let key2 = BlsPublicKey::from([2; 48]); - let keys = vec![key1, key2, key1]; + let key1 = BlsPublicKey::test_random(); + let key2 = BlsPublicKey::test_random(); + let keys = vec![key1.clone(), key2.clone(), key1.clone()]; let unique_keys = remove_duplicate_keys(keys); assert_eq!(unique_keys.len(), 2); diff --git a/crates/common/src/error.rs b/crates/common/src/error.rs deleted file mode 100644 index d34949ca..00000000 --- a/crates/common/src/error.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::fmt::{Display, Formatter}; - -use blst::BLST_ERROR; -use thiserror::Error; -#[derive(Debug, Error, PartialEq, Eq)] -pub enum BlstErrorWrapper { - BlstSuccess(BLST_ERROR), - BlstBadEncoding(BLST_ERROR), - BlstPointNotOnCurve(BLST_ERROR), - BlstPointNotInGroup(BLST_ERROR), - BlstAggrTypeMismatch(BLST_ERROR), - BlstVerifyFail(BLST_ERROR), - BlstPkIsInfinity(BLST_ERROR), - BlstBadScalar(BLST_ERROR), -} - -impl Display for BlstErrorWrapper { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - BlstErrorWrapper::BlstSuccess(_) => write!(f, "BLST_SUCCESS"), - BlstErrorWrapper::BlstBadEncoding(_) => write!(f, "BLST_BAD_ENCODING"), - BlstErrorWrapper::BlstPointNotOnCurve(_) => write!(f, "BLST_POINT_NOT_ON_CURVE"), - BlstErrorWrapper::BlstPointNotInGroup(_) => write!(f, "BLST_POINT_NOT_IN_GROUP"), - BlstErrorWrapper::BlstAggrTypeMismatch(_) => write!(f, "BLST_AGGR_TYPE_MISMATCH"), - BlstErrorWrapper::BlstVerifyFail(_) => write!(f, "BLST_VERIFY_FAIL"), - BlstErrorWrapper::BlstPkIsInfinity(_) => write!(f, "BLST_PK_IS_INFINITY"), - BlstErrorWrapper::BlstBadScalar(_) => write!(f, "BLST_BAD_SCALAR"), - } - } -} -impl From for BlstErrorWrapper { - fn from(value: BLST_ERROR) -> Self { - match value { - BLST_ERROR::BLST_SUCCESS => BlstErrorWrapper::BlstSuccess(BLST_ERROR::BLST_SUCCESS), - BLST_ERROR::BLST_BAD_ENCODING => { - BlstErrorWrapper::BlstBadEncoding(BLST_ERROR::BLST_BAD_ENCODING) - } - BLST_ERROR::BLST_POINT_NOT_ON_CURVE => { - BlstErrorWrapper::BlstPointNotOnCurve(BLST_ERROR::BLST_POINT_NOT_ON_CURVE) - } - BLST_ERROR::BLST_POINT_NOT_IN_GROUP => { - BlstErrorWrapper::BlstPointNotInGroup(BLST_ERROR::BLST_POINT_NOT_IN_GROUP) - } - BLST_ERROR::BLST_AGGR_TYPE_MISMATCH => { - BlstErrorWrapper::BlstAggrTypeMismatch(BLST_ERROR::BLST_AGGR_TYPE_MISMATCH) - } - BLST_ERROR::BLST_VERIFY_FAIL => { - BlstErrorWrapper::BlstVerifyFail(BLST_ERROR::BLST_VERIFY_FAIL) - } - BLST_ERROR::BLST_PK_IS_INFINITY => { - BlstErrorWrapper::BlstPkIsInfinity(BLST_ERROR::BLST_PK_IS_INFINITY) - } - BLST_ERROR::BLST_BAD_SCALAR => { - BlstErrorWrapper::BlstBadScalar(BLST_ERROR::BLST_BAD_SCALAR) - } - } - } -} diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 5042061b..1fe1f26a 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -3,7 +3,6 @@ use std::time::Duration; pub mod commit; pub mod config; pub mod constants; -pub mod error; pub mod pbs; pub mod signature; pub mod signer; diff --git a/crates/common/src/pbs/error.rs b/crates/common/src/pbs/error.rs index 9b42a626..dd91ec45 100644 --- a/crates/common/src/pbs/error.rs +++ b/crates/common/src/pbs/error.rs @@ -1,10 +1,7 @@ -use alloy::{ - primitives::{B256, U256}, - rpc::types::beacon::BlsPublicKey, -}; +use alloy::primitives::{B256, U256}; use thiserror::Error; -use crate::{error::BlstErrorWrapper, utils::ResponseReadError}; +use crate::{types::BlsPublicKey, utils::ResponseReadError}; #[derive(Debug, Error)] pub enum PbsError { @@ -58,7 +55,7 @@ pub enum ValidationError { EmptyBlockhash, #[error("pubkey mismatch: expected {expected} got {got}")] - PubkeyMismatch { expected: BlsPublicKey, got: BlsPublicKey }, + PubkeyMismatch { expected: Box, got: Box }, #[error("parent hash mismatch: expected {expected} got {got}")] ParentHashMismatch { expected: B256, got: B256 }, @@ -66,7 +63,7 @@ pub enum ValidationError { #[error("block hash mismatch: expected {expected} got {got}")] BlockHashMismatch { expected: B256, got: B256 }, - #[error("mismatch in KZG commitments: exepcted_blobs: {expected_blobs} got_blobs: {got_blobs} got_commitments: {got_commitments} got_proofs: {got_proofs}")] + #[error("mismatch in KZG commitments: expected_blobs: {expected_blobs} got_blobs: {got_blobs} got_commitments: {got_commitments} got_proofs: {got_proofs}")] KzgCommitments { expected_blobs: usize, got_blobs: usize, @@ -83,8 +80,8 @@ pub enum ValidationError { #[error("empty tx root")] EmptyTxRoot, - #[error("failed signature verification: {0:?}")] - Sigverify(#[from] BlstErrorWrapper), + #[error("failed signature verification")] + Sigverify, #[error("wrong timestamp: expected {expected} got {got}")] TimestampMismatch { expected: u64, got: u64 }, diff --git a/crates/common/src/pbs/relay.rs b/crates/common/src/pbs/relay.rs index 6f582a13..4d8296c2 100644 --- a/crates/common/src/pbs/relay.rs +++ b/crates/common/src/pbs/relay.rs @@ -1,9 +1,6 @@ use std::{str::FromStr, sync::Arc}; -use alloy::{ - primitives::{hex::FromHex, B256}, - rpc::types::beacon::BlsPublicKey, -}; +use alloy::primitives::B256; use eyre::WrapErr; use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; use serde::{Deserialize, Serialize}; @@ -14,7 +11,9 @@ use super::{ error::PbsError, HEADER_VERSION_KEY, HEADER_VERSION_VALUE, }; -use crate::{config::RelayConfig, pbs::BuilderApiVersion, DEFAULT_REQUEST_TIMEOUT}; +use crate::{ + config::RelayConfig, pbs::BuilderApiVersion, types::BlsPublicKey, DEFAULT_REQUEST_TIMEOUT, +}; /// A parsed entry of the relay url in the format: scheme://pubkey@host #[derive(Debug, Clone)] @@ -43,7 +42,7 @@ impl<'de> Deserialize<'de> for RelayEntry { { let url = Url::deserialize(deserializer)?; let id = url.host().ok_or(serde::de::Error::custom("missing host"))?.to_string(); - let pubkey = BlsPublicKey::from_hex(url.username()) + let pubkey = BlsPublicKey::from_str(url.username()) .map_err(|_| serde::de::Error::custom("invalid BLS pubkey"))?; Ok(RelayEntry { pubkey, url, id }) @@ -84,8 +83,8 @@ impl RelayClient { Ok(Self { id: Arc::new(config.id().to_owned()), client, config: Arc::new(config) }) } - pub fn pubkey(&self) -> BlsPublicKey { - self.config.entry.pubkey + pub fn pubkey(&self) -> &BlsPublicKey { + &self.config.entry.pubkey } // URL builders @@ -112,8 +111,8 @@ impl RelayClient { pub fn get_header_url( &self, slot: u64, - parent_hash: B256, - validator_pubkey: BlsPublicKey, + parent_hash: &B256, + validator_pubkey: &BlsPublicKey, ) -> Result { self.builder_api_url( &format!("/header/{slot}/{parent_hash}/{validator_pubkey}"), @@ -138,21 +137,19 @@ impl RelayClient { mod tests { use std::collections::HashMap; - use alloy::{ - primitives::{hex::FromHex, B256}, - rpc::types::beacon::BlsPublicKey, - }; + use alloy::primitives::B256; use super::{RelayClient, RelayEntry}; - use crate::config::RelayConfig; + use crate::{config::RelayConfig, utils::bls_pubkey_from_hex_unchecked}; #[test] fn test_relay_entry() { - let s = "http://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@abc.xyz/"; + let pubkey = bls_pubkey_from_hex_unchecked("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae"); + let s = format!("http://{pubkey}@abc.xyz/"); let parsed = serde_json::from_str::(&format!("\"{s}\"")).unwrap(); - assert_eq!(parsed.pubkey, BlsPublicKey::from_hex("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae").unwrap()); + assert_eq!(parsed.pubkey, pubkey); assert_eq!(parsed.url.as_str(), s); assert_eq!(parsed.id, "abc.xyz"); } @@ -161,7 +158,7 @@ mod tests { fn test_relay_url() { let slot = 0; let parent_hash = B256::ZERO; - let validator_pubkey = BlsPublicKey::ZERO; + let validator_pubkey = bls_pubkey_from_hex_unchecked("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae"); let expected = format!("http://0xa1cec75a3f0661e99299274182938151e8433c61a19222347ea1313d839229cb4ce4e3e5aa2bdeb71c8fcf1b084963c2@abc.xyz/eth/v1/builder/header/{slot}/{parent_hash}/{validator_pubkey}"); let relay_config = r#" @@ -173,7 +170,7 @@ mod tests { let relay = RelayClient::new(config).unwrap(); assert_eq!( - relay.get_header_url(slot, parent_hash, validator_pubkey).unwrap().to_string(), + relay.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap().to_string(), expected ); @@ -186,7 +183,7 @@ mod tests { let relay = RelayClient::new(config).unwrap(); assert_eq!( - relay.get_header_url(slot, parent_hash, validator_pubkey).unwrap().to_string(), + relay.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap().to_string(), expected ); } @@ -195,7 +192,7 @@ mod tests { fn test_relay_url_with_get_params() { let slot = 0; let parent_hash = B256::ZERO; - let validator_pubkey = BlsPublicKey::ZERO; + let validator_pubkey = bls_pubkey_from_hex_unchecked("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae"); // Note: HashMap iteration order is not guaranteed, so we can't predict the // exact order of parameters Instead of hard-coding the order, we'll // check that both parameters are present in the URL @@ -214,7 +211,7 @@ mod tests { config.get_params = Some(get_params); let relay = RelayClient::new(config).unwrap(); - let url = relay.get_header_url(slot, parent_hash, validator_pubkey).unwrap().to_string(); + let url = relay.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap().to_string(); assert!(url.starts_with(&url_prefix)); assert!(url.contains("param1=value1")); assert!(url.contains("param2=value2")); diff --git a/crates/common/src/pbs/types/beacon_block.rs b/crates/common/src/pbs/types/beacon_block.rs index 485876e9..5d3b139c 100644 --- a/crates/common/src/pbs/types/beacon_block.rs +++ b/crates/common/src/pbs/types/beacon_block.rs @@ -1,4 +1,4 @@ -use alloy::{primitives::B256, rpc::types::beacon::BlsSignature}; +use alloy::primitives::B256; use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; @@ -6,8 +6,9 @@ use super::{ blinded_block_body::BlindedBeaconBlockBodyElectra, blobs_bundle::BlobsBundle, execution_payload::ExecutionPayload, spec::ElectraSpec, utils::VersionedResponse, }; +use crate::types::BlsSignature; -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] /// Sent to relays in submit_block pub struct SignedBlindedBeaconBlock { pub message: BlindedBeaconBlock, @@ -47,13 +48,7 @@ pub enum BlindedBeaconBlock { Electra(BlindedBeaconBlockElectra), } -impl Default for BlindedBeaconBlock { - fn default() -> Self { - Self::Electra(BlindedBeaconBlockElectra::default()) - } -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct BlindedBeaconBlockElectra { #[serde(with = "serde_utils::quoted_u64")] pub slot: u64, @@ -170,8 +165,7 @@ mod tests { assert!(matches!(block_json.message, BlindedBeaconBlock::Electra(_))); let data_ssz = include_bytes!("testdata/signed-blinded-beacon-block-electra-2.ssz"); - let data_ssz = alloy::primitives::hex::decode(data_ssz).unwrap(); - let block_ssz = test_encode_decode_ssz::(&data_ssz); + let block_ssz = test_encode_decode_ssz::(data_ssz); assert!(matches!(block_ssz.message, BlindedBeaconBlock::Electra(_))); assert_eq!(block_json.as_ssz_bytes(), data_ssz); diff --git a/crates/common/src/pbs/types/blinded_block_body.rs b/crates/common/src/pbs/types/blinded_block_body.rs index 966aa1e5..4acd3dd1 100644 --- a/crates/common/src/pbs/types/blinded_block_body.rs +++ b/crates/common/src/pbs/types/blinded_block_body.rs @@ -1,7 +1,4 @@ -use alloy::{ - primitives::{Address, B256}, - rpc::types::beacon::{BlsPublicKey, BlsSignature}, -}; +use alloy::primitives::{Address, B256}; use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use ssz_types::{typenum, BitList, BitVector, FixedVector, VariableList}; @@ -10,8 +7,9 @@ use super::{ execution_payload::ExecutionPayloadHeader, execution_requests::ExecutionRequests, kzg::KzgCommitments, spec::EthSpec, utils::*, }; +use crate::types::{BlsPublicKey, BlsSignature}; -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(deny_unknown_fields)] pub struct BlindedBeaconBlockBodyElectra { pub randao_reveal: BlsSignature, @@ -49,13 +47,13 @@ pub struct BeaconBlockHeader { pub body_root: B256, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct SignedBeaconBlockHeader { pub message: BeaconBlockHeader, pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct BlsToExecutionChange { #[serde(with = "serde_utils::quoted_u64")] pub validator_index: u64, @@ -63,25 +61,25 @@ pub struct BlsToExecutionChange { pub to_execution_address: Address, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct SignedBlsToExecutionChange { pub message: BlsToExecutionChange, pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct ProposerSlashing { pub signed_header_1: SignedBeaconBlockHeader, pub signed_header_2: SignedBeaconBlockHeader, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct AttesterSlashingElectra { pub attestation_1: IndexedAttestationElectra, pub attestation_2: IndexedAttestationElectra, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(bound = "T: EthSpec")] pub struct IndexedAttestationElectra { /// Lists validator registry indices, not committee indices. @@ -120,13 +118,13 @@ pub struct AttestationElectra { pub committee_bits: BitVector, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct Deposit { pub proof: FixedVector, // put this in EthSpec? pub data: DepositData, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct DepositData { pub pubkey: BlsPublicKey, pub withdrawal_credentials: B256, @@ -135,7 +133,7 @@ pub struct DepositData { pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct SignedVoluntaryExit { pub message: VoluntaryExit, pub signature: BlsSignature, @@ -150,7 +148,7 @@ pub struct VoluntaryExit { pub validator_index: u64, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(bound = "T: EthSpec")] pub struct SyncAggregate { pub sync_committee_bits: BitVector, diff --git a/crates/common/src/pbs/types/execution_requests.rs b/crates/common/src/pbs/types/execution_requests.rs index b84430bb..2c48f24a 100644 --- a/crates/common/src/pbs/types/execution_requests.rs +++ b/crates/common/src/pbs/types/execution_requests.rs @@ -1,13 +1,11 @@ -use alloy::{ - primitives::{Address, B256}, - rpc::types::beacon::{BlsPublicKey, BlsSignature}, -}; +use alloy::primitives::{Address, B256}; use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use ssz_types::VariableList; use tree_hash_derive::TreeHash; use super::spec::EthSpec; +use crate::types::{BlsPublicKey, BlsSignature}; #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct ExecutionRequests { @@ -16,7 +14,7 @@ pub struct ExecutionRequests { pub consolidations: VariableList, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct DepositRequest { pub pubkey: BlsPublicKey, pub withdrawal_credentials: B256, @@ -27,7 +25,7 @@ pub struct DepositRequest { pub index: u64, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct WithdrawalRequest { pub source_address: Address, pub validator_pubkey: BlsPublicKey, @@ -35,7 +33,7 @@ pub struct WithdrawalRequest { pub amount: u64, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct ConsolidationRequest { pub source_address: Address, pub source_pubkey: BlsPublicKey, diff --git a/crates/common/src/pbs/types/get_header.rs b/crates/common/src/pbs/types/get_header.rs index 18d5361f..c243f21d 100644 --- a/crates/common/src/pbs/types/get_header.rs +++ b/crates/common/src/pbs/types/get_header.rs @@ -1,7 +1,4 @@ -use alloy::{ - primitives::{B256, U256}, - rpc::types::beacon::{BlsPublicKey, BlsSignature}, -}; +use alloy::primitives::{B256, U256}; use serde::{Deserialize, Serialize}; use ssz::{Decode, Encode}; use ssz_derive::{Decode, Encode}; @@ -11,8 +8,9 @@ use super::{ execution_payload::ExecutionPayloadHeader, execution_requests::ExecutionRequests, kzg::KzgCommitments, spec::ElectraSpec, utils::VersionedResponse, }; +use crate::types::{BlsPublicKey, BlsSignature}; -#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct GetHeaderParams { /// The slot to request the header for pub slot: u64, @@ -45,9 +43,9 @@ impl GetHeaderResponse { } } - pub fn pubkey(&self) -> BlsPublicKey { + pub fn pubkey(&self) -> &BlsPublicKey { match self { - VersionedResponse::Electra(data) => data.message.pubkey, + VersionedResponse::Electra(data) => &data.message.pubkey, } } @@ -69,20 +67,20 @@ impl GetHeaderResponse { } } - pub fn signautre(&self) -> BlsSignature { + pub fn signautre(&self) -> &BlsSignature { match self { - GetHeaderResponse::Electra(data) => data.signature, + GetHeaderResponse::Electra(data) => &data.signature, } } } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct SignedExecutionPayloadHeader { pub message: T, pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct ExecutionPayloadHeaderMessageElectra { pub header: ExecutionPayloadHeader, pub blob_kzg_commitments: KzgCommitments, @@ -106,7 +104,7 @@ mod tests { }; #[test] - // from the builder api spec, the signature is a dummy so it's not checked + // from the builder api spec, with signature fixed to the correct pubkey fn test_get_header_electra() { let data = r#"{ "version": "electra", @@ -137,32 +135,32 @@ mod tests { "execution_requests": { "deposits": [ { - "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "pubkey": "0x911f24ad11078aad2b28ff9dcb4651a0b686e3972b2b4190273f35d416bf057dbd95553d7a0edb107b1a5e1b211da8c4", "withdrawal_credentials": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "amount": "1", - "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "signature": "0xb4f92cd90de8e4b67debeb0379f08d0e6d3046e67e824e6ed63cd841abc9999c8b123a780e34a480d4ef13466b6241e30000b047d27de43fcf475fc4e69da2d26929cec97742892346f53e78f973bbe8095285f05a8ea60b118cdd1e6a704c94", "index": "1" } ], "withdrawals": [ { "source_address": "0xabcf8e0d4e9587369b2301d0790347320302cc09", - "validator_pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "validator_pubkey": "0x911f24ad11078aad2b28ff9dcb4651a0b686e3972b2b4190273f35d416bf057dbd95553d7a0edb107b1a5e1b211da8c4", "amount": "1" } ], "consolidations": [ { "source_address": "0xabcf8e0d4e9587369b2301d0790347320302cc09", - "source_pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", - "target_pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" + "source_pubkey": "0x911f24ad11078aad2b28ff9dcb4651a0b686e3972b2b4190273f35d416bf057dbd95553d7a0edb107b1a5e1b211da8c4", + "target_pubkey": "0x911f24ad11078aad2b28ff9dcb4651a0b686e3972b2b4190273f35d416bf057dbd95553d7a0edb107b1a5e1b211da8c4" } ] }, "value": "1", - "pubkey": "0x86b1cea87eed94cad99244356abcd83995947670f0553a1d3fe83c4a9e8116f4891fb1c51db232e736be1cb3327164bc" + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" }, - "signature": "0x8addecd35e0ffe27b74e41aff2836527e6fea0efdb46dbb0f7436f5087d0cd5665bd16d924f640fc928cdba0173971e400dc603dbd6310bfb6f249c1554b044fe06ae4cf5d5f452f3ff19d9d130809b34d3d3abdca3d192c839ba2ac91129c15" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } }"#; @@ -177,8 +175,7 @@ mod tests { &parsed.message, &parsed.signature, APPLICATION_BUILDER_DOMAIN - ) - .is_ok()) + )) } #[test] @@ -190,9 +187,8 @@ mod tests { >(data_json); let data_ssz = include_bytes!("testdata/get-header-response.ssz"); - let data_ssz = alloy::primitives::hex::decode(data_ssz).unwrap(); test_encode_decode_ssz::>( - &data_ssz, + data_ssz, ); assert_eq!(block_json.as_ssz_bytes(), data_ssz); diff --git a/crates/common/src/pbs/types/testdata/get-header-response.json b/crates/common/src/pbs/types/testdata/get-header-response.json index 0198af6a..96ee57af 100644 --- a/crates/common/src/pbs/types/testdata/get-header-response.json +++ b/crates/common/src/pbs/types/testdata/get-header-response.json @@ -25,30 +25,30 @@ "execution_requests": { "deposits": [ { - "pubkey": "0x0e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "withdrawal_credentials": "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", "amount": "100", - "signature": "0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f", "index": "1" } ], "withdrawals": [ { "source_address": "0x1100000000000000000000000000000000000000", - "validator_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "validator_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "amount": "1" } ], "consolidations": [ { "source_address": "0x1200000000000000000000000000000000000000", - "source_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "target_pubkey": "0x110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "source_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", + "target_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" } ] }, "value": "11", - "pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" }, - "signature": "0x010203040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } \ No newline at end of file diff --git a/crates/common/src/pbs/types/testdata/get-header-response.ssz b/crates/common/src/pbs/types/testdata/get-header-response.ssz index 59133c48..7d9c12c5 100644 Binary files a/crates/common/src/pbs/types/testdata/get-header-response.ssz and b/crates/common/src/pbs/types/testdata/get-header-response.ssz differ diff --git a/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.json b/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.json index 81c8743b..f25a3bbd 100644 --- a/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.json +++ b/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.json @@ -18,7 +18,7 @@ "root": "0x0200000000000000000000000000000000000000000000000000000000000000" } }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } ], "attester_slashings": [ @@ -42,7 +42,7 @@ "root": "0x0100000000000000000000000000000000000000000000000000000000000000" } }, - "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" }, "attestation_2": { "attesting_indices": [ @@ -63,7 +63,7 @@ "root": "0x0200000000000000000000000000000000000000000000000000000000000000" } }, - "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } } ], @@ -73,19 +73,19 @@ "bls_to_execution_changes": [ { "message": { - "from_bls_pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "from_bls_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "to_execution_address": "0x0000000000000000000000000000000000000000", "validator_index": "1" }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } ], "deposits": [ { "data": { "amount": "1", - "pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000", - "signature": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f", "withdrawal_credentials": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" }, "proof": [ @@ -153,16 +153,16 @@ "consolidations": [ { "source_address": "0x0100000000000000000000000000000000000000", - "source_pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000", - "target_pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000" + "source_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", + "target_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" } ], "deposits": [ { "amount": "32000000000", "index": "0", - "pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f", "withdrawal_credentials": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" } ], @@ -170,7 +170,7 @@ { "amount": "0", "source_address": "0x0100000000000000000000000000000000000000", - "validator_pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "validator_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" } ] }, @@ -185,7 +185,7 @@ "slot": "123", "state_root": "0x0000000000000000000000000000000000000000000000000000000000000000" }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" }, "signed_header_2": { "message": { @@ -195,11 +195,11 @@ "slot": "123", "state_root": "0x0000000000000000000000000000000000000000000000000000000000000000" }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } } ], - "randao_reveal": "0xa7a74e03d8ef909abc75b9452d167e150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "randao_reveal": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f", "sync_aggregate": { "sync_committee_bits": "0xff98b62322edaa4d9198b62322edaa4d9198b62322edaa4d91ff98b62322edaa4d9198b62322edaa4d9198b62322edaa4d912322edaa4d9198b62322edaa4d91", "sync_committee_signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" @@ -210,7 +210,7 @@ "epoch": "123", "validator_index": "0" }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } ] }, @@ -219,5 +219,5 @@ "slot": "252288", "state_root": "0x4c033e0b4a34c0eb8e0caba126fae3ed303a83254fe39f8daaa673125f4042cc" }, - "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } \ No newline at end of file diff --git a/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.ssz b/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.ssz index db36f0b5..7067c41b 100644 Binary files a/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.ssz and b/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.ssz differ diff --git a/crates/common/src/signature.rs b/crates/common/src/signature.rs index e51e2291..9753a9a1 100644 --- a/crates/common/src/signature.rs +++ b/crates/common/src/signature.rs @@ -1,50 +1,48 @@ -use alloy::rpc::types::beacon::{constants::BLS_DST_SIG, BlsPublicKey, BlsSignature}; +use alloy::primitives::B256; use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use crate::{ constants::{COMMIT_BOOST_DOMAIN, GENESIS_VALIDATORS_ROOT}, - error::BlstErrorWrapper, - signer::{verify_bls_signature, BlsSecretKey}, - types::Chain, + signer::verify_bls_signature, + types::{BlsPublicKey, BlsSecretKey, BlsSignature, Chain}, }; -pub fn sign_message(secret_key: &BlsSecretKey, msg: &[u8]) -> BlsSignature { - let signature = secret_key.sign(msg, BLS_DST_SIG, &[]).to_bytes(); - BlsSignature::from_slice(&signature) +pub fn sign_message(secret_key: &BlsSecretKey, msg: B256) -> BlsSignature { + secret_key.sign(msg) } -pub fn compute_signing_root(object_root: [u8; 32], signing_domain: [u8; 32]) -> [u8; 32] { +pub fn compute_signing_root(object_root: B256, signing_domain: B256) -> B256 { #[derive(Default, Debug, TreeHash)] struct SigningData { - object_root: [u8; 32], - signing_domain: [u8; 32], + object_root: B256, + signing_domain: B256, } let signing_data = SigningData { object_root, signing_domain }; - signing_data.tree_hash_root().0 + signing_data.tree_hash_root() } // NOTE: this currently works only for builder domain signatures and // verifications // ref: https://github.com/ralexstokes/ethereum-consensus/blob/cf3c404043230559660810bc0c9d6d5a8498d819/ethereum-consensus/src/builder/mod.rs#L26-L29 -pub fn compute_domain(chain: Chain, domain_mask: [u8; 4]) -> [u8; 32] { +pub fn compute_domain(chain: Chain, domain_mask: [u8; 4]) -> B256 { #[derive(Debug, TreeHash)] struct ForkData { fork_version: [u8; 4], - genesis_validators_root: [u8; 32], + genesis_validators_root: B256, } let mut domain = [0u8; 32]; domain[..4].copy_from_slice(&domain_mask); let fork_version = chain.genesis_fork_version(); - let fd = ForkData { fork_version, genesis_validators_root: GENESIS_VALIDATORS_ROOT }; + let fd = ForkData { fork_version, genesis_validators_root: GENESIS_VALIDATORS_ROOT.into() }; let fork_data_root = fd.tree_hash_root(); domain[4..].copy_from_slice(&fork_data_root[..28]); - domain + domain.into() } pub fn verify_signed_message( @@ -53,11 +51,11 @@ pub fn verify_signed_message( msg: &T, signature: &BlsSignature, domain_mask: [u8; 4], -) -> Result<(), BlstErrorWrapper> { +) -> bool { let domain = compute_domain(chain, domain_mask); - let signing_root = compute_signing_root(msg.tree_hash_root().0, domain); + let signing_root = compute_signing_root(msg.tree_hash_root(), domain); - verify_bls_signature(pubkey, &signing_root, signature) + verify_bls_signature(pubkey, signing_root, signature) } pub fn sign_builder_message( @@ -65,27 +63,27 @@ pub fn sign_builder_message( secret_key: &BlsSecretKey, msg: &impl TreeHash, ) -> BlsSignature { - sign_builder_root(chain, secret_key, msg.tree_hash_root().0) + sign_builder_root(chain, secret_key, msg.tree_hash_root()) } pub fn sign_builder_root( chain: Chain, secret_key: &BlsSecretKey, - object_root: [u8; 32], + object_root: B256, ) -> BlsSignature { let domain = chain.builder_domain(); let signing_root = compute_signing_root(object_root, domain); - sign_message(secret_key, &signing_root) + sign_message(secret_key, signing_root) } pub fn sign_commit_boost_root( chain: Chain, secret_key: &BlsSecretKey, - object_root: [u8; 32], + object_root: B256, ) -> BlsSignature { let domain = compute_domain(chain, COMMIT_BOOST_DOMAIN); let signing_root = compute_signing_root(object_root, domain); - sign_message(secret_key, &signing_root) + sign_message(secret_key, signing_root) } #[cfg(test)] diff --git a/crates/common/src/signer/loader.rs b/crates/common/src/signer/loader.rs index 4fb9adb1..853eba5c 100644 --- a/crates/common/src/signer/loader.rs +++ b/crates/common/src/signer/loader.rs @@ -8,9 +8,8 @@ use aes::{ cipher::{KeyIvInit, StreamCipher}, Aes128, }; -use alloy::{primitives::hex::FromHex, rpc::types::beacon::BlsPublicKey}; -use eth2_keystore::{json_keystore::JsonKeystore, Keystore}; use eyre::{eyre, Context}; +use lh_eth2_keystore::{json_keystore::JsonKeystore, Keystore}; use pbkdf2::{hmac, pbkdf2}; use rayon::prelude::*; use serde::{de, Deserialize, Deserializer, Serialize}; @@ -21,6 +20,7 @@ use super::{BlsSigner, EcdsaSigner, PrysmDecryptedKeystore, PrysmKeystore}; use crate::{ config::{load_env_var, SIGNER_DIR_KEYS_ENV, SIGNER_DIR_SECRETS_ENV, SIGNER_KEYS_ENV}, signer::ConsensusSigner, + utils::bls_pubkey_from_hex, }; #[derive(Debug, Serialize, Deserialize, Clone)] @@ -127,9 +127,12 @@ fn load_from_lighthouse_format( } let maybe_pubkey = path.file_name().and_then(|d| d.to_str())?; - let Ok(pubkey) = BlsPublicKey::from_hex(maybe_pubkey) else { - warn!("Invalid pubkey: {}", maybe_pubkey); - return None + let pubkey = match bls_pubkey_from_hex(maybe_pubkey) { + Ok(pubkey) => pubkey, + Err(e) => { + warn!("Invalid pubkey: {}: {}", maybe_pubkey, e); + return None + } }; let ks_path = keys_path.join(maybe_pubkey).join("voting-keystore.json"); @@ -290,7 +293,7 @@ fn load_from_nimbus_format( } let maybe_pubkey = path.file_name().and_then(|d| d.to_str())?; - let Ok(pubkey) = BlsPublicKey::from_hex(maybe_pubkey) else { + let Ok(pubkey) = bls_pubkey_from_hex(maybe_pubkey) else { warn!("Invalid pubkey: {}", maybe_pubkey); return None }; @@ -329,7 +332,7 @@ pub fn load_ecdsa_signer(keys_path: PathBuf, secrets_path: PathBuf) -> eyre::Res let key_reader = std::io::BufReader::new(key_file); let keystore: JsonKeystore = serde_json::from_reader(key_reader)?; let password = std::fs::read(secrets_path)?; - let decrypted_password = eth2_keystore::decrypt(&password, &keystore.crypto) + let decrypted_password = lh_eth2_keystore::decrypt(&password, &keystore.crypto) .map_err(|_| eyre::eyre!("Error decrypting ECDSA keystore"))?; EcdsaSigner::new_from_bytes(decrypted_password.as_bytes()) @@ -338,12 +341,13 @@ pub fn load_ecdsa_signer(keys_path: PathBuf, secrets_path: PathBuf) -> eyre::Res #[cfg(test)] mod tests { - use alloy::{hex, primitives::FixedBytes}; - use super::{load_from_lighthouse_format, load_from_lodestar_format, FileKey}; - use crate::signer::{ - loader::{load_from_nimbus_format, load_from_prysm_format, load_from_teku_format}, - BlsPublicKey, BlsSigner, + use crate::{ + signer::{ + loader::{load_from_nimbus_format, load_from_prysm_format, load_from_teku_format}, + BlsSigner, + }, + utils::bls_pubkey_from_hex_unchecked, }; #[test] @@ -364,12 +368,10 @@ mod tests { fn test_correct_load(signers: Vec) { assert_eq!(signers.len(), 2); - assert!(signers.iter().any(|s| s.pubkey() == BlsPublicKey::from(FixedBytes::new( - hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4") - )))); - assert!(signers.iter().any(|s| s.pubkey() == BlsPublicKey::from(FixedBytes::new( - hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9") - )))); + assert!(signers.iter().any(|s| s.pubkey() == bls_pubkey_from_hex_unchecked("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4") + )); + assert!(signers.iter().any(|s| s.pubkey() == bls_pubkey_from_hex_unchecked("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9") + )); } #[test] @@ -420,9 +422,9 @@ mod tests { let signers = result.unwrap(); assert_eq!(signers.len(), 1); - assert!(signers[0].pubkey() == BlsPublicKey::from(FixedBytes::new( - hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4") - ))); + assert!(signers[0].pubkey() == bls_pubkey_from_hex_unchecked( + "883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4" + )); let result = load_from_lodestar_format( "../../tests/data/keystores/teku-keys/".into(), @@ -434,9 +436,9 @@ mod tests { let signers = result.unwrap(); assert_eq!(signers.len(), 1); - assert!(signers[0].pubkey() == BlsPublicKey::from(FixedBytes::new( - hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9") - ))); + assert!(signers[0].pubkey() == bls_pubkey_from_hex_unchecked( + "b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9" + )); } #[test] diff --git a/crates/common/src/signer/schemes/bls.rs b/crates/common/src/signer/schemes/bls.rs index f133b2bc..8525f015 100644 --- a/crates/common/src/signer/schemes/bls.rs +++ b/crates/common/src/signer/schemes/bls.rs @@ -1,16 +1,11 @@ -use alloy::rpc::types::beacon::constants::BLS_DST_SIG; -pub use alloy::rpc::types::beacon::BlsSignature; -use blst::BLST_ERROR; +use alloy::primitives::B256; use tree_hash::TreeHash; use crate::{ - error::BlstErrorWrapper, signature::sign_commit_boost_root, types::Chain, - utils::blst_pubkey_to_alloy, + signature::sign_commit_boost_root, + types::{BlsPublicKey, BlsSecretKey, BlsSignature, Chain}, }; -pub type BlsSecretKey = blst::min_pk::SecretKey; -pub type BlsPublicKey = alloy::rpc::types::beacon::BlsPublicKey; - #[derive(Clone)] pub enum BlsSigner { Local(BlsSecretKey), @@ -22,61 +17,38 @@ impl BlsSigner { } pub fn new_from_bytes(bytes: &[u8]) -> eyre::Result { - let secret = BlsSecretKey::from_bytes(bytes).map_err(BlstErrorWrapper::from)?; + let secret = + BlsSecretKey::deserialize(bytes).map_err(|_| eyre::eyre!("invalid secret key"))?; Ok(Self::Local(secret)) } pub fn pubkey(&self) -> BlsPublicKey { match self { - BlsSigner::Local(secret) => blst_pubkey_to_alloy(&secret.sk_to_pk()), + BlsSigner::Local(secret) => secret.public_key(), } } pub fn secret(&self) -> [u8; 32] { match self { - BlsSigner::Local(secret) => secret.clone().to_bytes(), + BlsSigner::Local(secret) => secret.serialize().as_bytes().try_into().unwrap(), } } - pub async fn sign(&self, chain: Chain, object_root: [u8; 32]) -> BlsSignature { + pub async fn sign(&self, chain: Chain, object_root: B256) -> BlsSignature { match self { BlsSigner::Local(sk) => sign_commit_boost_root(chain, sk, object_root), } } pub async fn sign_msg(&self, chain: Chain, msg: &impl TreeHash) -> BlsSignature { - self.sign(chain, msg.tree_hash_root().0).await + self.sign(chain, msg.tree_hash_root()).await } } pub fn random_secret() -> BlsSecretKey { - use rand::RngCore; - - let mut rng = rand::rng(); - let mut ikm = [0u8; 32]; - rng.fill_bytes(&mut ikm); - - match BlsSecretKey::key_gen(&ikm, &[]) { - Ok(key) => key, - // Key material is always valid (32 `u8`s), so `key_gen` can't return Err. - Err(_) => unreachable!(), - } + BlsSecretKey::random() } -pub fn verify_bls_signature( - pubkey: &BlsPublicKey, - msg: &[u8], - signature: &BlsSignature, -) -> Result<(), BlstErrorWrapper> { - use crate::utils::{alloy_pubkey_to_blst, alloy_sig_to_blst}; - - let pubkey = alloy_pubkey_to_blst(pubkey)?; - let signature = alloy_sig_to_blst(signature)?; - - let res = signature.verify(true, msg, BLS_DST_SIG, &[], &pubkey, true); - if res == BLST_ERROR::BLST_SUCCESS { - Ok(()) - } else { - Err(res.into()) - } +pub fn verify_bls_signature(pubkey: &BlsPublicKey, msg: B256, signature: &BlsSignature) -> bool { + signature.verify(pubkey, msg) } diff --git a/crates/common/src/signer/schemes/ecdsa.rs b/crates/common/src/signer/schemes/ecdsa.rs index 612df5e3..f845e2f4 100644 --- a/crates/common/src/signer/schemes/ecdsa.rs +++ b/crates/common/src/signer/schemes/ecdsa.rs @@ -1,7 +1,7 @@ use std::{ops::Deref, str::FromStr}; use alloy::{ - primitives::{Address, PrimitiveSignature}, + primitives::{Address, PrimitiveSignature, B256}, signers::{local::PrivateKeySigner, SignerSync}, }; use eyre::ensure; @@ -86,12 +86,12 @@ impl EcdsaSigner { pub async fn sign( &self, chain: Chain, - object_root: [u8; 32], + object_root: B256, ) -> Result { match self { EcdsaSigner::Local(sk) => { let domain = compute_domain(chain, COMMIT_BOOST_DOMAIN); - let signing_root = compute_signing_root(object_root, domain).into(); + let signing_root = compute_signing_root(object_root, domain); sk.sign_hash_sync(&signing_root).map(EcdsaSignature::from) } } @@ -102,7 +102,7 @@ impl EcdsaSigner { chain: Chain, msg: &impl TreeHash, ) -> Result { - self.sign(chain, msg.tree_hash_root().0).await + self.sign(chain, msg.tree_hash_root()).await } } @@ -128,7 +128,7 @@ mod test { let pk = bytes!("88bcd6672d95bcba0d52a3146494ed4d37675af4ed2206905eb161aa99a6c0d1"); let signer = EcdsaSigner::new_from_bytes(&pk).unwrap(); - let object_root = [1; 32]; + let object_root = B256::from([1; 32]); let signature = signer.sign(Chain::Holesky, object_root).await.unwrap(); let domain = compute_domain(Chain::Holesky, COMMIT_BOOST_DOMAIN); diff --git a/crates/common/src/signer/store.rs b/crates/common/src/signer/store.rs index 479a4016..12659686 100644 --- a/crates/common/src/signer/store.rs +++ b/crates/common/src/signer/store.rs @@ -8,10 +8,10 @@ use std::{ use alloy::{ hex, - primitives::{Address, Bytes, FixedBytes}, - rpc::types::beacon::constants::BLS_SIGNATURE_BYTES_LEN, + primitives::{Address, Bytes}, }; -use eth2_keystore::{ +use eyre::{Context, OptionExt}; +use lh_eth2_keystore::{ default_kdf, json_keystore::{ Aes128Ctr, ChecksumModule, Cipher, CipherModule, Crypto, JsonKeystore, KdfModule, @@ -19,7 +19,6 @@ use eth2_keystore::{ }, Uuid, IV_SIZE, SALT_SIZE, }; -use eyre::{Context, OptionExt}; use rand::Rng; use serde::{Deserialize, Serialize}; use tracing::{trace, warn}; @@ -28,10 +27,8 @@ use super::{load_bls_signer, load_ecdsa_signer}; use crate::{ commit::request::{EncryptionScheme, ProxyDelegation, ProxyId, SignedProxyDelegation}, config::{load_env_var, PROXY_DIR_ENV, PROXY_DIR_KEYS_ENV, PROXY_DIR_SECRETS_ENV}, - signer::{ - BlsProxySigner, BlsPublicKey, BlsSigner, EcdsaProxySigner, EcdsaSigner, ProxySigners, - }, - types::ModuleId, + signer::{BlsProxySigner, BlsSigner, EcdsaProxySigner, EcdsaSigner, ProxySigners}, + types::{BlsPublicKey, BlsSignature, ModuleId}, }; #[derive(Debug, Serialize, Deserialize)] @@ -90,7 +87,7 @@ impl ProxyStore { .join("bls") .join(proxy.signer.pubkey().to_string()); let secret = Bytes::from(proxy.signer.secret()); - let to_store = KeyAndDelegation { secret, delegation: proxy.delegation }; + let to_store = KeyAndDelegation { secret, delegation: proxy.delegation.clone() }; let content = serde_json::to_vec(&to_store)?; if let Some(parent) = file_path.parent() { @@ -103,7 +100,7 @@ impl ProxyStore { ProxyStore::ERC2335 { keys_path, secrets_path } => { store_erc2335_key( module_id, - proxy.delegation, + proxy.delegation.clone(), proxy.secret().to_vec(), keys_path, secrets_path, @@ -127,7 +124,7 @@ impl ProxyStore { .join("ecdsa") .join(proxy.signer.address().to_string()); let secret = Bytes::from(proxy.signer.secret()); - let to_store = KeyAndDelegation { secret, delegation: proxy.delegation }; + let to_store = KeyAndDelegation { secret, delegation: proxy.delegation.clone() }; let content = serde_json::to_vec(&to_store)?; if let Some(parent) = file_path.parent() { @@ -140,7 +137,7 @@ impl ProxyStore { ProxyStore::ERC2335 { keys_path, secrets_path } => { store_erc2335_key( module_id, - proxy.delegation, + proxy.delegation.clone(), proxy.secret(), keys_path, secrets_path, @@ -230,7 +227,9 @@ impl ProxyStore { delegation: key_and_delegation.delegation, }; - proxy_signers.bls_signers.insert(pubkey, proxy_signer); + proxy_signers + .bls_signers + .insert(pubkey.clone(), proxy_signer); bls_map.entry(module_id.clone()).or_default().push(pubkey); } } @@ -277,20 +276,24 @@ impl ProxyStore { for entry in std::fs::read_dir(keys_path)? { let entry = entry?; let consensus_key_path = entry.path(); - let consensus_pubkey = - match FixedBytes::from_str(&entry.file_name().to_string_lossy()) { - Ok(bytes) => BlsPublicKey::from(bytes), - Err(e) => { - warn!("Failed to parse consensus pubkey: {e}"); - continue; - } - }; + let Ok(consensus_key_str) = + hex::decode(entry.file_name().to_string_lossy().as_ref()) + else { + warn!("Failed to parse consensus pubkey: {consensus_key_path:?}"); + continue; + }; + + let Ok(consensus_pubkey) = BlsPublicKey::deserialize(&consensus_key_str) else { + warn!("Failed to parse consensus pubkey: {consensus_key_path:?}"); + continue; + }; if !consensus_key_path.is_dir() { warn!("{consensus_key_path:?} is not a directory"); continue; } + let consensus_pubkey_str = consensus_pubkey.to_string(); for entry in std::fs::read_dir(&consensus_key_path)? { let entry = entry?; let module_path = entry.path(); @@ -319,30 +322,42 @@ impl ProxyStore { let signer = load_bls_signer( path, secrets_path - .join(consensus_pubkey.to_string()) + .join(consensus_pubkey_str.clone()) .join(&module_id) .join("bls") .join(name), ) .map_err(|e| eyre::eyre!("Error loading BLS signer: {e}"))?; - let delegation_signature = match std::fs::read_to_string( - bls_path.join(format!("{name}.sig")), - ) { - Ok(sig) => { - FixedBytes::::from_str(&sig)? - } - Err(e) => { - warn!("Failed to read delegation signature: {e}"); - continue; - } + let delegation_signature_path = + bls_path.join(format!("{name}.sig")); + + let Ok(delegation_signature) = + std::fs::read_to_string(&delegation_signature_path) + else { + warn!("Failed to read delegation signature: {delegation_signature_path:?}"); + continue; + }; + + let Ok(delegation_signature) = + alloy::primitives::hex::decode(delegation_signature) + else { + warn!("Failed to parse delegation signature: {delegation_signature_path:?}"); + continue; + }; + + let Ok(delegation_signature) = + BlsSignature::deserialize(&delegation_signature) + else { + warn!("Failed to parse delegation signature: {delegation_signature_path:?}"); + continue; }; let proxy_signer = BlsProxySigner { signer: signer.clone(), delegation: SignedProxyDelegation { message: ProxyDelegation { - delegator: consensus_pubkey, + delegator: consensus_pubkey.clone(), proxy: signer.pubkey(), }, signature: delegation_signature, @@ -375,28 +390,41 @@ impl ProxyStore { let signer = load_ecdsa_signer( path, secrets_path - .join(consensus_pubkey.to_string()) + .join(consensus_pubkey_str.clone()) .join(&module_id) .join("ecdsa") .join(name), )?; - let delegation_signature = match std::fs::read_to_string( - ecdsa_path.join(format!("{name}.sig")), - ) { - Ok(sig) => { - FixedBytes::::from_str(&sig)? - } - Err(e) => { - warn!("Failed to read delegation signature: {e}",); - continue; - } + + let delegation_signature_path = + ecdsa_path.join(format!("{name}.sig")); + + let Ok(delegation_signature) = + std::fs::read_to_string(&delegation_signature_path) + else { + warn!("Failed to read delegation signature: {delegation_signature_path:?}"); + continue; + }; + + let Ok(delegation_signature) = + alloy::primitives::hex::decode(delegation_signature) + else { + warn!("Failed to parse delegation signature: {delegation_signature_path:?}"); + continue; + }; + + let Ok(delegation_signature) = + BlsSignature::deserialize(&delegation_signature) + else { + warn!("Failed to parse delegation signature: {delegation_signature_path:?}"); + continue; }; let proxy_signer = EcdsaProxySigner { signer: signer.clone(), delegation: SignedProxyDelegation { message: ProxyDelegation { - delegator: consensus_pubkey, + delegator: consensus_pubkey.clone(), proxy: signer.address(), }, signature: delegation_signature, @@ -426,7 +454,7 @@ fn store_erc2335_key( secrets_path: &Path, scheme: EncryptionScheme, ) -> eyre::Result<()> { - let proxy_delegation = delegation.message.proxy; + let proxy_delegation = delegation.message.proxy.clone(); let password_bytes: [u8; 32] = rand::rng().random(); let password = hex::encode(password_bytes); @@ -455,7 +483,7 @@ fn store_erc2335_key( let kdf = default_kdf(salt.to_vec()); let cipher = Cipher::Aes128Ctr(Aes128Ctr { iv: iv.to_vec().into() }); let (cipher_text, checksum) = - eth2_keystore::encrypt(&secret, password.as_bytes(), &kdf, &cipher) + lh_eth2_keystore::encrypt(&secret, password.as_bytes(), &kdf, &cipher) .map_err(|_| eyre::eyre!("Error encrypting key"))?; let keystore = JsonKeystore { @@ -463,11 +491,11 @@ fn store_erc2335_key( kdf: KdfModule { function: kdf.function(), params: kdf, - message: eth2_keystore::json_keystore::EmptyString, + message: lh_eth2_keystore::json_keystore::EmptyString, }, checksum: ChecksumModule { function: Sha256Checksum::function(), - params: eth2_keystore::json_keystore::EmptyMap, + params: lh_eth2_keystore::json_keystore::EmptyMap, message: checksum.to_vec().into(), }, cipher: CipherModule { @@ -478,8 +506,8 @@ fn store_erc2335_key( }, uuid: Uuid::new_v4(), path: None, - pubkey: alloy::hex::encode(delegation.message.proxy), - version: eth2_keystore::json_keystore::Version::V4, + pubkey: alloy::hex::encode(delegation.message.proxy.to_bytes()), + version: lh_eth2_keystore::json_keystore::Version::V4, description: Some(delegation.message.proxy.to_string()), name: None, }; @@ -498,7 +526,6 @@ fn store_erc2335_key( #[cfg(test)] mod test { - use hex::FromHex; use tree_hash::TreeHash; use super::*; @@ -506,6 +533,7 @@ mod test { commit::request::{ProxyDelegationBls, SignedProxyDelegationBls}, signer::ConsensusSigner, types::Chain, + utils::bls_pubkey_from_hex_unchecked, }; #[tokio::test] @@ -532,8 +560,8 @@ mod test { delegator: consensus_signer.pubkey(), proxy: proxy_signer.pubkey(), }; - let signature = consensus_signer.sign(Chain::Mainnet, message.tree_hash_root().0).await; - let delegation = SignedProxyDelegationBls { signature, message }; + let signature = consensus_signer.sign(Chain::Mainnet, message.tree_hash_root()).await; + let delegation = SignedProxyDelegationBls { signature: signature.clone(), message }; let proxy_signer = BlsProxySigner { signer: proxy_signer, delegation }; store.store_proxy_bls(&module_id, &proxy_signer).unwrap(); @@ -563,9 +591,10 @@ mod test { assert_eq!(keystore.pubkey, proxy_signer.pubkey().to_string().trim_start_matches("0x")); - let sig = FixedBytes::from_hex(std::fs::read_to_string(sig_path).unwrap()); - assert!(sig.is_ok()); - assert_eq!(sig.unwrap(), signature); + let sig = hex::decode(std::fs::read_to_string(sig_path).unwrap()).unwrap(); + let sig = BlsSignature::deserialize(&sig).unwrap(); + + assert_eq!(sig, signature); } #[test] @@ -583,16 +612,8 @@ mod test { assert_eq!(proxy_signers.bls_signers.len(), 1); assert_eq!(proxy_signers.ecdsa_signers.len(), 0); - let proxy_key = BlsPublicKey::from( - FixedBytes::from_hex( - "a77084280678d9f1efe4ef47a3d62af27872ce82db19a35ee012c4fd5478e6b1123b8869032ba18b2383e8873294f0ba" - ).unwrap() - ); - let consensus_key = BlsPublicKey::from( - FixedBytes::from_hex( - "ac5e059177afc33263e95d0be0690138b9a1d79a6e19018086a0362e0c30a50bf9e05a08cb44785724d0b2718c5c7118" - ).unwrap() - ); + let proxy_key = bls_pubkey_from_hex_unchecked("a77084280678d9f1efe4ef47a3d62af27872ce82db19a35ee012c4fd5478e6b1123b8869032ba18b2383e8873294f0ba"); + let consensus_key = bls_pubkey_from_hex_unchecked("ac5e059177afc33263e95d0be0690138b9a1d79a6e19018086a0362e0c30a50bf9e05a08cb44785724d0b2718c5c7118"); let proxy_signer = proxy_signers.bls_signers.get(&proxy_key); @@ -601,13 +622,16 @@ mod test { assert_eq!( proxy_signer.delegation.signature, - FixedBytes::from_hex( - std::fs::read_to_string( - keys_path - .join(consensus_key.to_string()) - .join("TEST_MODULE") - .join("bls") - .join(format!("{proxy_key}.sig")) + BlsSignature::deserialize( + &hex::decode( + std::fs::read_to_string( + keys_path + .join(consensus_key.clone().to_string()) + .join("TEST_MODULE") + .join("bls") + .join(format!("{proxy_key}.sig")) + ) + .unwrap() ) .unwrap() ) @@ -645,7 +669,7 @@ mod test { delegator: consensus_signer.pubkey(), proxy: proxy_signer.pubkey(), }; - let signature = consensus_signer.sign(Chain::Mainnet, message.tree_hash_root().0).await; + let signature = consensus_signer.sign(Chain::Mainnet, message.tree_hash_root()).await; let delegation = SignedProxyDelegationBls { signature, message }; let proxy_signer = BlsProxySigner { signer: proxy_signer, delegation }; @@ -668,13 +692,16 @@ mod test { assert_eq!( loaded_proxy_signer.delegation.signature, - FixedBytes::from_hex( - std::fs::read_to_string( - keys_path - .join(consensus_signer.pubkey().to_string()) - .join("TEST_MODULE") - .join("bls") - .join(format!("{}.sig", proxy_signer.pubkey())) + BlsSignature::deserialize( + &hex::decode( + std::fs::read_to_string( + keys_path + .join(consensus_signer.pubkey().to_string()) + .join("TEST_MODULE") + .join("bls") + .join(format!("{}.sig", proxy_signer.pubkey().to_string())) + ) + .unwrap() ) .unwrap() ) diff --git a/crates/common/src/signer/types.rs b/crates/common/src/signer/types.rs index da36af5d..60878c84 100644 --- a/crates/common/src/signer/types.rs +++ b/crates/common/src/signer/types.rs @@ -8,10 +8,11 @@ use serde::{ Deserialize, Deserializer, }; -use super::{BlsPublicKey, EcdsaSigner}; +use super::EcdsaSigner; use crate::{ commit::request::{SignedProxyDelegationBls, SignedProxyDelegationEcdsa}, signer::BlsSigner, + types::BlsPublicKey, }; // For extra safety and to avoid risking signing malicious messages, use a proxy diff --git a/crates/common/src/types.rs b/crates/common/src/types.rs index 5293a789..40c3a990 100644 --- a/crates/common/src/types.rs +++ b/crates/common/src/types.rs @@ -1,12 +1,16 @@ use std::path::PathBuf; -use alloy::primitives::{hex, Bytes}; +use alloy::primitives::{b256, hex, Bytes, B256}; use derive_more::{Deref, Display, From, Into}; use eyre::{bail, Context}; use serde::{Deserialize, Serialize}; use crate::{constants::APPLICATION_BUILDER_DOMAIN, signature::compute_domain}; +pub type BlsPublicKey = lh_types::PublicKey; +pub type BlsSignature = lh_types::Signature; +pub type BlsSecretKey = lh_types::SecretKey; + #[derive(Clone, Debug, Display, PartialEq, Eq, Hash, Deref, From, Into, Serialize, Deserialize)] #[into(owned, ref, ref_mut)] #[serde(transparent)] @@ -78,7 +82,7 @@ impl Chain { } } - pub fn builder_domain(&self) -> [u8; 32] { + pub fn builder_domain(&self) -> B256 { match self { Chain::Mainnet => KnownChain::Mainnet.builder_domain(), Chain::Holesky => KnownChain::Holesky.builder_domain(), @@ -149,28 +153,23 @@ impl KnownChain { } } - pub fn builder_domain(&self) -> [u8; 32] { + pub fn builder_domain(&self) -> B256 { match self { - KnownChain::Mainnet => [ - 0, 0, 0, 1, 245, 165, 253, 66, 209, 106, 32, 48, 39, 152, 239, 110, 211, 9, 151, - 155, 67, 0, 61, 35, 32, 217, 240, 232, 234, 152, 49, 169, - ], - KnownChain::Holesky => [ - 0, 0, 0, 1, 91, 131, 162, 55, 89, 197, 96, 178, 208, 198, 69, 118, 225, 220, 252, - 52, 234, 148, 196, 152, 143, 62, 13, 159, 119, 240, 83, 135, - ], - KnownChain::Sepolia => [ - 0, 0, 0, 1, 211, 1, 7, 120, 205, 8, 238, 81, 75, 8, 254, 103, 182, 197, 3, 181, 16, - 152, 122, 76, 228, 63, 66, 48, 109, 151, 198, 124, - ], - KnownChain::Helder => [ - 0, 0, 0, 1, 148, 196, 26, 244, 132, 255, 247, 150, 73, 105, 224, 189, 217, 34, 248, - 45, 255, 15, 75, 232, 122, 96, 208, 102, 76, 201, 209, 255, - ], - KnownChain::Hoodi => [ - 0, 0, 0, 1, 113, 145, 3, 81, 30, 250, 79, 19, 98, 255, 42, 80, 153, 108, 204, 243, - 41, 204, 132, 203, 65, 12, 94, 92, 125, 53, 29, 3, - ], + KnownChain::Mainnet => { + b256!("0x00000001f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a9") + } + KnownChain::Holesky => { + b256!("0x000000015b83a23759c560b2d0c64576e1dcfc34ea94c4988f3e0d9f77f05387") + } + KnownChain::Sepolia => { + b256!("0x00000001d3010778cd08ee514b08fe67b6c503b510987a4ce43f42306d97c67c") + } + KnownChain::Helder => { + b256!("0x0000000194c41af484fff7964969e0bdd922f82dff0f4be87a60d0664cc9d1ff") + } + KnownChain::Hoodi => { + b256!("0x00000001719103511efa4f1362ff2a50996cccf329cc84cb410c5e5c7d351d03") + } } } diff --git a/crates/common/src/utils.rs b/crates/common/src/utils.rs index 6d39465c..db972c84 100644 --- a/crates/common/src/utils.rs +++ b/crates/common/src/utils.rs @@ -5,13 +5,10 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; -use alloy::{ - primitives::U256, - rpc::types::beacon::{BlsPublicKey, BlsSignature}, -}; +use alloy::{hex, primitives::U256}; use axum::http::HeaderValue; -use blst::min_pk::{PublicKey, Signature}; use futures::StreamExt; +use lh_types::test_utils::{SeedableRng, TestRandom, XorShiftRng}; use rand::{distr::Alphanumeric, Rng}; use reqwest::{header::HeaderMap, Response}; use serde::{de::DeserializeOwned, Serialize}; @@ -30,7 +27,7 @@ use crate::{ config::LogsSettings, constants::SIGNER_JWT_EXPIRATION, pbs::HEADER_VERSION_VALUE, - types::{Chain, Jwt, JwtClaims, ModuleId}, + types::{BlsPublicKey, Chain, Jwt, JwtClaims, ModuleId}, }; const MILLIS_PER_SECOND: u64 = 1_000; @@ -345,20 +342,6 @@ pub fn print_logo() { ) } -// Crypto conversions - -pub fn alloy_pubkey_to_blst(pubkey: &BlsPublicKey) -> Result { - PublicKey::key_validate(&pubkey.0) -} - -pub fn alloy_sig_to_blst(signature: &BlsSignature) -> Result { - Signature::from_bytes(&signature.0) -} - -pub fn blst_pubkey_to_alloy(pubkey: &PublicKey) -> BlsPublicKey { - BlsPublicKey::from_slice(&pubkey.to_bytes()) -} - /// Create a JWT for the given module id with expiration pub fn create_jwt(module_id: &ModuleId, secret: &str) -> eyre::Result { jsonwebtoken::encode( @@ -446,6 +429,34 @@ pub async fn wait_for_signal() -> eyre::Result<()> { Ok(()) } +pub trait TestRandomSeed: TestRandom { + fn test_random() -> Self + where + Self: Sized, + { + let mut rng = XorShiftRng::from_entropy(); + Self::random_for_test(&mut rng) + } +} + +impl TestRandomSeed for T {} + +pub fn bls_pubkey_from_hex(hex: &str) -> eyre::Result { + let Ok(bytes) = hex::decode(hex) else { + eyre::bail!("invalid hex pubkey: {hex}"); + }; + + let pubkey = BlsPublicKey::deserialize(&bytes) + .map_err(|e| eyre::eyre!("invalid hex pubkey: {hex}: {e:?}"))?; + + Ok(pubkey) +} + +#[cfg(test)] +pub fn bls_pubkey_from_hex_unchecked(hex: &str) -> BlsPublicKey { + bls_pubkey_from_hex(hex).unwrap() +} + #[cfg(test)] mod test { use super::{create_jwt, decode_jwt, validate_jwt}; diff --git a/crates/pbs/Cargo.toml b/crates/pbs/Cargo.toml index ad747f9d..4cc3d2b2 100644 --- a/crates/pbs/Cargo.toml +++ b/crates/pbs/Cargo.toml @@ -10,7 +10,6 @@ alloy.workspace = true async-trait.workspace = true axum.workspace = true axum-extra.workspace = true -blst.workspace = true cb-common.workspace = true cb-metrics.workspace = true eyre.workspace = true diff --git a/crates/pbs/src/mev_boost/get_header.rs b/crates/pbs/src/mev_boost/get_header.rs index 613815ce..6014b513 100644 --- a/crates/pbs/src/mev_boost/get_header.rs +++ b/crates/pbs/src/mev_boost/get_header.rs @@ -6,7 +6,7 @@ use std::{ use alloy::{ primitives::{utils::format_ether, B256, U256}, providers::Provider, - rpc::types::{beacon::BlsPublicKey, Block}, + rpc::types::Block, }; use axum::http::{HeaderMap, HeaderValue}; use cb_common::{ @@ -17,8 +17,7 @@ use cb_common::{ HEADER_START_TIME_UNIX_MS, }, signature::verify_signed_message, - signer::BlsSignature, - types::Chain, + types::{BlsPublicKey, BlsSignature, Chain}, utils::{ get_user_agent_with_version, ms_into_slot, read_chunked_body_with_max, timestamp_of_slot_start_sec, utcnow_ms, @@ -90,7 +89,7 @@ pub async fn get_header( for relay in relays.iter() { handles.push( send_timed_get_header( - params, + params.clone(), relay.clone(), state.config.chain, send_headers.clone(), @@ -166,7 +165,7 @@ async fn send_timed_get_header( mut timeout_left_ms: u64, validation: ValidationContext, ) -> Result, PbsError> { - let url = relay.get_header_url(params.slot, params.parent_hash, params.pubkey)?; + let url = relay.get_header_url(params.slot, ¶ms.parent_hash, ¶ms.pubkey)?; if relay.config.enable_timing_games { if let Some(target_ms) = relay.config.target_first_request_ms { @@ -197,6 +196,7 @@ async fn send_timed_get_header( ); loop { + let params = params.clone(); handles.push(tokio::spawn( send_one_get_header( params, @@ -388,7 +388,7 @@ async fn send_one_get_header( validate_signature( chain, relay.pubkey(), - res.message.pubkey, + &res.message.pubkey, &res.message, &res.signature, )?; @@ -458,26 +458,27 @@ fn validate_header_data( fn validate_signature( chain: Chain, - expected_relay_pubkey: BlsPublicKey, - received_relay_pubkey: BlsPublicKey, + expected_relay_pubkey: &BlsPublicKey, + received_relay_pubkey: &BlsPublicKey, message: &T, signature: &BlsSignature, ) -> Result<(), ValidationError> { if expected_relay_pubkey != received_relay_pubkey { return Err(ValidationError::PubkeyMismatch { - expected: expected_relay_pubkey, - got: received_relay_pubkey, + expected: Box::new(expected_relay_pubkey.clone()), + got: Box::new(received_relay_pubkey.clone()), }); } - verify_signed_message( + if !verify_signed_message( chain, - &received_relay_pubkey, + received_relay_pubkey, &message, signature, APPLICATION_BUILDER_DOMAIN, - ) - .map_err(ValidationError::Sigverify)?; + ) { + return Err(ValidationError::Sigverify); + } Ok(()) } @@ -505,16 +506,12 @@ fn extra_validation( #[cfg(test)] mod tests { - use alloy::{ - primitives::{B256, U256}, - rpc::types::beacon::BlsPublicKey, - }; - use blst::min_pk; + use alloy::primitives::{B256, U256}; use cb_common::{ - pbs::{error::ValidationError, ExecutionPayloadHeaderMessageElectra, EMPTY_TX_ROOT_HASH}, + pbs::{error::ValidationError, EMPTY_TX_ROOT_HASH}, signature::sign_builder_message, - types::Chain, - utils::timestamp_of_slot_start_sec, + types::{BlsSecretKey, Chain}, + utils::{timestamp_of_slot_start_sec, TestRandomSeed}, }; use super::{validate_header_data, *}; @@ -578,33 +575,28 @@ mod tests { #[test] fn test_validate_signature() { - let secret_key = min_pk::SecretKey::from_bytes(&[ - 0, 136, 227, 100, 165, 57, 106, 129, 181, 15, 235, 189, 200, 120, 70, 99, 251, 144, - 137, 181, 230, 124, 189, 193, 115, 153, 26, 0, 197, 135, 103, 63, - ]) - .unwrap(); - let pubkey = BlsPublicKey::from_slice(&secret_key.sk_to_pk().to_bytes()); + let secret_key = BlsSecretKey::test_random(); + let pubkey = secret_key.public_key(); + let wrong_pubkey = BlsPublicKey::test_random(); + let wrong_signature = BlsSignature::test_random(); - let message = ExecutionPayloadHeaderMessageElectra::default(); + let message = B256::random(); let signature = sign_builder_message(Chain::Holesky, &secret_key, &message); assert_eq!( - validate_signature( - Chain::Holesky, - BlsPublicKey::default(), - pubkey, - &message, - &BlsSignature::default() - ), - Err(ValidationError::PubkeyMismatch { expected: BlsPublicKey::default(), got: pubkey }) + validate_signature(Chain::Holesky, &wrong_pubkey, &pubkey, &message, &wrong_signature), + Err(ValidationError::PubkeyMismatch { + expected: Box::new(wrong_pubkey), + got: Box::new(pubkey.clone()) + }) ); assert!(matches!( - validate_signature(Chain::Holesky, pubkey, pubkey, &message, &BlsSignature::default()), - Err(ValidationError::Sigverify(_)) + validate_signature(Chain::Holesky, &pubkey, &pubkey, &message, &wrong_signature), + Err(ValidationError::Sigverify) )); - assert!(validate_signature(Chain::Holesky, pubkey, pubkey, &message, &signature).is_ok()); + assert!(validate_signature(Chain::Holesky, &pubkey, &pubkey, &message, &signature).is_ok()); } } diff --git a/crates/pbs/src/routes/get_header.rs b/crates/pbs/src/routes/get_header.rs index b6f55fa0..53aa194d 100644 --- a/crates/pbs/src/routes/get_header.rs +++ b/crates/pbs/src/routes/get_header.rs @@ -26,11 +26,11 @@ pub async fn handle_get_header>( ) -> Result { tracing::Span::current().record("slot", params.slot); tracing::Span::current().record("parent_hash", tracing::field::debug(params.parent_hash)); - tracing::Span::current().record("validator", tracing::field::debug(params.pubkey)); + tracing::Span::current().record("validator", tracing::field::debug(¶ms.pubkey)); let state = state.read().clone(); - state.publish_event(BuilderEvent::GetHeaderRequest(params)); + state.publish_event(BuilderEvent::GetHeaderRequest(params.clone())); let ua = get_user_agent(&req_headers); let ms_into_slot = ms_into_slot(params.slot, state.config.chain); diff --git a/crates/pbs/src/state.rs b/crates/pbs/src/state.rs index fbf211d3..f641c069 100644 --- a/crates/pbs/src/state.rs +++ b/crates/pbs/src/state.rs @@ -1,9 +1,9 @@ use std::sync::Arc; -use alloy::rpc::types::beacon::BlsPublicKey; use cb_common::{ config::{PbsConfig, PbsModuleConfig}, pbs::{BuilderEvent, RelayClient}, + types::BlsPublicKey, }; use parking_lot::RwLock; diff --git a/crates/signer/src/manager/dirk.rs b/crates/signer/src/manager/dirk.rs index 4c2d909f..7e98324f 100644 --- a/crates/signer/src/manager/dirk.rs +++ b/crates/signer/src/manager/dirk.rs @@ -1,14 +1,14 @@ use std::{collections::HashMap, io::Write, path::PathBuf}; -use alloy::{hex, rpc::types::beacon::constants::BLS_SIGNATURE_BYTES_LEN}; +use alloy::{hex, primitives::B256}; use blsful::inner_types::{Field, G2Affine, G2Projective, Group, Scalar}; use cb_common::{ commit::request::{ConsensusProxyMap, ProxyDelegation, SignedProxyDelegation}, config::{DirkConfig, DirkHostConfig}, constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, - signer::{BlsPublicKey, BlsSignature, ProxyStore}, - types::{Chain, ModuleId}, + signer::ProxyStore, + types::{BlsPublicKey, BlsSignature, Chain, ModuleId}, }; use eyre::{bail, OptionExt}; use futures::{future::join_all, stream::FuturesUnordered, FutureExt, StreamExt}; @@ -57,10 +57,10 @@ struct DistributedAccount { } impl Account { - pub fn public_key(&self) -> BlsPublicKey { + pub fn public_key(&self) -> &BlsPublicKey { match self { - Account::Simple(account) => account.public_key, - Account::Distributed(account) => account.composite_public_key, + Account::Simple(account) => &account.public_key, + Account::Distributed(account) => &account.composite_public_key, } } } @@ -168,7 +168,7 @@ impl DirkManager { self.consensus_accounts .values() .map(|account| ConsensusProxyMap { - consensus: account.public_key(), + consensus: account.public_key().clone(), proxy_bls: self .proxy_accounts .values() @@ -176,7 +176,7 @@ impl DirkManager { if proxy.module == *module && proxy.consensus.public_key() == account.public_key() { - Some(proxy.inner.public_key()) + Some(proxy.inner.public_key().clone()) } else { None } @@ -192,7 +192,7 @@ impl DirkManager { pub async fn request_consensus_signature( &self, pubkey: &BlsPublicKey, - object_root: [u8; 32], + object_root: B256, ) -> Result { match self.consensus_accounts.get(pubkey) { Some(Account::Simple(account)) => { @@ -201,7 +201,7 @@ impl DirkManager { Some(Account::Distributed(account)) => { self.request_distributed_signature(account, object_root).await } - None => Err(SignerModuleError::UnknownConsensusSigner(pubkey.to_vec())), + None => Err(SignerModuleError::UnknownConsensusSigner(pubkey.serialize().to_vec())), } } @@ -209,7 +209,7 @@ impl DirkManager { pub async fn request_proxy_signature( &self, pubkey: &BlsPublicKey, - object_root: [u8; 32], + object_root: B256, ) -> Result { match self.proxy_accounts.get(pubkey) { Some(ProxyAccount { inner: Account::Simple(account), .. }) => { @@ -218,7 +218,7 @@ impl DirkManager { Some(ProxyAccount { inner: Account::Distributed(account), .. }) => { self.request_distributed_signature(account, object_root).await } - None => Err(SignerModuleError::UnknownProxySigner(pubkey.to_vec())), + None => Err(SignerModuleError::UnknownProxySigner(pubkey.serialize().to_vec())), } } @@ -226,7 +226,7 @@ impl DirkManager { async fn request_simple_signature( &self, account: &SimpleAccount, - object_root: [u8; 32], + object_root: B256, ) -> Result { let domain = compute_domain(self.chain, COMMIT_BOOST_DOMAIN); @@ -234,7 +234,7 @@ impl DirkManager { .sign(SignRequest { data: object_root.to_vec(), domain: domain.to_vec(), - id: Some(sign_request::Id::PublicKey(account.public_key.to_vec())), + id: Some(sign_request::Id::PublicKey(account.public_key.serialize().to_vec())), }) .await .map_err(|e| { @@ -247,7 +247,7 @@ impl DirkManager { )); } - BlsSignature::try_from(response.into_inner().signature.as_slice()).map_err(|_| { + BlsSignature::deserialize(response.into_inner().signature.as_slice()).map_err(|_| { SignerModuleError::DirkCommunicationError("Failed to parse signature".to_string()) }) } @@ -256,7 +256,7 @@ impl DirkManager { async fn request_distributed_signature( &self, account: &DistributedAccount, - object_root: [u8; 32], + object_root: B256, ) -> Result { let mut partials = Vec::with_capacity(account.participants.len()); let mut requests = Vec::with_capacity(account.participants.len()); @@ -291,14 +291,14 @@ impl DirkManager { continue; } - let signature = match BlsSignature::try_from(response.into_inner().signature.as_slice()) - { - Ok(sig) => sig, - Err(e) => { - warn!("Failed to parse signature from participant {participant_id}: {e}"); - continue; - } - }; + let signature = + match BlsSignature::deserialize(response.into_inner().signature.as_slice()) { + Ok(sig) => sig, + Err(e) => { + warn!("Failed to parse signature from participant {participant_id}: {e:?}"); + continue; + } + }; partials.push((signature, participant_id)); @@ -330,13 +330,19 @@ impl DirkManager { Some(Account::Distributed(account)) => { self.generate_distributed_proxy_key(account, module).await? } - None => return Err(SignerModuleError::UnknownConsensusSigner(consensus.to_vec())), + None => { + return Err(SignerModuleError::UnknownConsensusSigner( + consensus.serialize().to_vec(), + )) + } }; - let message = - ProxyDelegation { delegator: consensus, proxy: proxy_account.inner.public_key() }; + let message = ProxyDelegation { + delegator: consensus.clone(), + proxy: proxy_account.inner.public_key().clone(), + }; let delegation_signature = - self.request_consensus_signature(&consensus, message.tree_hash_root().0).await?; + self.request_consensus_signature(&consensus, message.tree_hash_root()).await?; let delegation = SignedProxyDelegation { message, signature: delegation_signature }; @@ -347,7 +353,7 @@ impl DirkManager { })?; } - self.proxy_accounts.insert(proxy_account.inner.public_key(), proxy_account.clone()); + self.proxy_accounts.insert(proxy_account.inner.public_key().clone(), proxy_account.clone()); Ok(delegation) } @@ -378,7 +384,7 @@ impl DirkManager { ))); } - let proxy_key = BlsPublicKey::try_from(response.into_inner().public_key.as_slice()) + let proxy_key = BlsPublicKey::deserialize(response.into_inner().public_key.as_slice()) .map_err(|_| { SignerModuleError::DirkCommunicationError("Failed to parse proxy key".to_string()) })?; @@ -436,7 +442,8 @@ impl DirkManager { continue; } - let Ok(proxy_key) = BlsPublicKey::try_from(response.into_inner().public_key.as_slice()) + let Ok(proxy_key) = + BlsPublicKey::deserialize(response.into_inner().public_key.as_slice()) else { warn!("Failed to parse proxy key with participant {id}"); continue; @@ -565,10 +572,10 @@ fn load_simple_accounts( continue; } - match BlsPublicKey::try_from(account.public_key.as_slice()) { + match BlsPublicKey::deserialize(account.public_key.as_slice()) { Ok(public_key) => { consensus_accounts.insert( - public_key, + public_key.clone(), Account::Simple(SimpleAccount { public_key, connection: channel.clone(), @@ -603,7 +610,8 @@ fn load_distributed_accounts( continue; } - let Ok(public_key) = BlsPublicKey::try_from(account.composite_public_key.as_slice()) else { + let Ok(public_key) = BlsPublicKey::deserialize(account.composite_public_key.as_slice()) + else { warn!("Failed to parse composite public key for account {}", account.name); continue; }; @@ -637,7 +645,7 @@ fn load_distributed_accounts( participants.insert(participant_id as u32, channel.clone()); consensus_accounts.insert( - public_key, + public_key.clone(), Account::Distributed(DistributedAccount { composite_public_key: public_key, participants, @@ -660,10 +668,7 @@ fn aggregate_partial_signatures(partials: &[(BlsSignature, u32)]) -> eyre::Resul // Deserialize partial signatures into G2 points let mut shares: HashMap = HashMap::new(); for (signature, id) in partials { - if signature.len() != BLS_SIGNATURE_BYTES_LEN { - bail!("Invalid signature length") - } - let affine = G2Affine::from_compressed(signature) + let affine = G2Affine::from_compressed(&signature.serialize()) .into_option() .ok_or_eyre("Failed to deserialize signature")?; shares.insert(*id, G2Projective::from(&affine)); @@ -693,7 +698,10 @@ fn aggregate_partial_signatures(partials: &[(BlsSignature, u32)]) -> eyre::Resul // Serialize the recovered point back into a BlsSignature let bytes = recovered.to_compressed(); - Ok(bytes.into()) + let sig = BlsSignature::deserialize(&bytes) + .map_err(|_| eyre::eyre!("Failed to deserialize aggregated signature"))?; + + Ok(sig) } /// Generate a random password of 64 hex-characters @@ -710,21 +718,22 @@ fn name_matches_proxy(name: &str) -> bool { name.rsplit_once("/").is_some_and(|(_, name)| uuid::Uuid::parse_str(name).is_ok()) } -mod test { +#[cfg(test)] +mod tests { + use super::*; #[test] fn test_signature_aggregation() { use alloy::hex; - use cb_common::signer::BlsSignature; use super::aggregate_partial_signatures; let partials = vec![ - (BlsSignature::from_slice(&hex::decode("aa16233b9e65b596caf070122d564ad7a021dad4fc2ed8508fccecfab010da80892fad7336e9fbada607c50e2d0d78e00c9961f26618334ec9f0e7ea225212f3c0c7d66f73ff1c2e555712a3e31f517b8329bd0ad9e15a9aeaa91521ba83502c").unwrap()), 1), - (BlsSignature::from_slice(&hex::decode("b27dd4c088e386edc4d07b6b23c72ba87a34e04cffd4975e8cb679aa4640cec1d34ace3e2bf33ac0dffca023c82422840012bb6c92eab36ca7908a9f9519fa18b1ed2bdbc624a98e01ca217c318a021495cc6cc9c8b982d0afed2cd83dc8fe65").unwrap()), 2), - (BlsSignature::from_slice(&hex::decode("aca4a71373df2f76369e8b242b0e2b1f41fc384feee3abe605ee8d6723f5fb11de1c9bd2408f4a09be981342352c523801e3beea73893a329204dd67fe84cb520220af33f7fa027b6bcc3b7c8e78647f2aa372145e4d3aec7682d2605040a64a").unwrap()), 3) + (BlsSignature::deserialize(&hex::decode("aa16233b9e65b596caf070122d564ad7a021dad4fc2ed8508fccecfab010da80892fad7336e9fbada607c50e2d0d78e00c9961f26618334ec9f0e7ea225212f3c0c7d66f73ff1c2e555712a3e31f517b8329bd0ad9e15a9aeaa91521ba83502c").unwrap()).unwrap(), 1), + (BlsSignature::deserialize(&hex::decode("b27dd4c088e386edc4d07b6b23c72ba87a34e04cffd4975e8cb679aa4640cec1d34ace3e2bf33ac0dffca023c82422840012bb6c92eab36ca7908a9f9519fa18b1ed2bdbc624a98e01ca217c318a021495cc6cc9c8b982d0afed2cd83dc8fe65").unwrap()).unwrap(), 2), + (BlsSignature::deserialize(&hex::decode("aca4a71373df2f76369e8b242b0e2b1f41fc384feee3abe605ee8d6723f5fb11de1c9bd2408f4a09be981342352c523801e3beea73893a329204dd67fe84cb520220af33f7fa027b6bcc3b7c8e78647f2aa372145e4d3aec7682d2605040a64a").unwrap()).unwrap(), 3) ]; - let expected = BlsSignature::from_slice(&hex::decode("0x8e343f074f91d19fd5118d9301768e30cecb21fb96a1ad9539cbdeae8907e2e12a88c91fe1d7e1f6995dcde18fb0272b1512cd68800e14ebd1c7f189e7221ba238a0f196226385737157f4b72d348c1886ce18d0a9609ba0cd5503e41546286f").unwrap()); + let expected = BlsSignature::deserialize(&hex::decode("0x8e343f074f91d19fd5118d9301768e30cecb21fb96a1ad9539cbdeae8907e2e12a88c91fe1d7e1f6995dcde18fb0272b1512cd68800e14ebd1c7f189e7221ba238a0f196226385737157f4b72d348c1886ce18d0a9609ba0cd5503e41546286f").unwrap()).unwrap(); // With all signers let signature = aggregate_partial_signatures(&partials).unwrap(); diff --git a/crates/signer/src/manager/local.rs b/crates/signer/src/manager/local.rs index a613df0a..17832fdf 100644 --- a/crates/signer/src/manager/local.rs +++ b/crates/signer/src/manager/local.rs @@ -1,16 +1,16 @@ use std::collections::HashMap; -use alloy::{primitives::Address, rpc::types::beacon::BlsSignature}; +use alloy::primitives::{Address, B256}; use cb_common::{ commit::request::{ - ConsensusProxyMap, ProxyDelegationBls, ProxyDelegationEcdsa, SignedProxyDelegationBls, - SignedProxyDelegationEcdsa, + ConsensusProxyMap, ProxyDelegationBls, ProxyDelegationEcdsa, ProxyId, + SignedProxyDelegationBls, SignedProxyDelegationEcdsa, }, signer::{ - BlsProxySigner, BlsPublicKey, BlsSigner, ConsensusSigner, EcdsaProxySigner, EcdsaSignature, - EcdsaSigner, ProxySigners, ProxyStore, + BlsProxySigner, BlsSigner, ConsensusSigner, EcdsaProxySigner, EcdsaSignature, EcdsaSigner, + ProxySigners, ProxyStore, }, - types::{Chain, ModuleId}, + types::{BlsPublicKey, BlsSignature, Chain, ModuleId}, }; use tree_hash::TreeHash; @@ -94,10 +94,10 @@ impl LocalSigningManager { let signer = BlsSigner::new_random(); let proxy_pubkey = signer.pubkey(); - let message = ProxyDelegationBls { delegator, proxy: proxy_pubkey }; - let signature = self.sign_consensus(&delegator, &message.tree_hash_root().0).await?; + let message = ProxyDelegationBls { delegator: delegator.clone(), proxy: proxy_pubkey }; + let signature = self.sign_consensus(&delegator, message.tree_hash_root()).await?; let delegation = SignedProxyDelegationBls { signature, message }; - let proxy_signer = BlsProxySigner { signer, delegation }; + let proxy_signer = BlsProxySigner { signer, delegation: delegation.clone() }; self.add_proxy_signer_bls(proxy_signer, module_id) .map_err(|err| SignerModuleError::Internal(err.to_string()))?; @@ -113,10 +113,10 @@ impl LocalSigningManager { let signer = EcdsaSigner::new_random(); let proxy_address = signer.address(); - let message = ProxyDelegationEcdsa { delegator, proxy: proxy_address }; - let signature = self.sign_consensus(&delegator, &message.tree_hash_root().0).await?; + let message = ProxyDelegationEcdsa { delegator: delegator.clone(), proxy: proxy_address }; + let signature = self.sign_consensus(&delegator, message.tree_hash_root()).await?; let delegation = SignedProxyDelegationEcdsa { signature, message }; - let proxy_signer = EcdsaProxySigner { signer, delegation }; + let proxy_signer = EcdsaProxySigner { signer, delegation: delegation.clone() }; self.add_proxy_signer_ecdsa(proxy_signer, module_id) .map_err(|err| SignerModuleError::Internal(err.to_string()))?; @@ -129,13 +129,13 @@ impl LocalSigningManager { pub async fn sign_consensus( &self, pubkey: &BlsPublicKey, - object_root: &[u8; 32], + object_root: B256, ) -> Result { let signer = self .consensus_signers .get(pubkey) - .ok_or(SignerModuleError::UnknownConsensusSigner(pubkey.to_vec()))?; - let signature = signer.sign(self.chain, *object_root).await; + .ok_or(SignerModuleError::UnknownConsensusSigner(pubkey.to_bytes()))?; + let signature = signer.sign(self.chain, object_root).await; Ok(signature) } @@ -143,28 +143,28 @@ impl LocalSigningManager { pub async fn sign_proxy_bls( &self, pubkey: &BlsPublicKey, - object_root: &[u8; 32], + object_root: B256, ) -> Result { let bls_proxy = self .proxy_signers .bls_signers .get(pubkey) - .ok_or(SignerModuleError::UnknownProxySigner(pubkey.to_vec()))?; - let signature = bls_proxy.sign(self.chain, *object_root).await; + .ok_or(SignerModuleError::UnknownProxySigner(pubkey.serialize().to_vec()))?; + let signature = bls_proxy.sign(self.chain, object_root).await; Ok(signature) } pub async fn sign_proxy_ecdsa( &self, address: &Address, - object_root: &[u8; 32], + object_root: B256, ) -> Result { let ecdsa_proxy = self .proxy_signers .ecdsa_signers .get(address) .ok_or(SignerModuleError::UnknownProxySigner(address.to_vec()))?; - let signature = ecdsa_proxy.sign(self.chain, *object_root).await?; + let signature = ecdsa_proxy.sign(self.chain, object_root).await?; Ok(signature) } @@ -205,22 +205,22 @@ impl LocalSigningManager { pub fn get_delegation_bls( &self, pubkey: &BlsPublicKey, - ) -> Result { + ) -> Result<&SignedProxyDelegationBls, SignerModuleError> { self.proxy_signers .bls_signers .get(pubkey) - .map(|x| x.delegation) - .ok_or(SignerModuleError::UnknownProxySigner(pubkey.to_vec())) + .map(|x| &x.delegation) + .ok_or(SignerModuleError::UnknownProxySigner(pubkey.serialize().to_vec())) } pub fn get_delegation_ecdsa( &self, address: &Address, - ) -> Result { + ) -> Result<&SignedProxyDelegationEcdsa, SignerModuleError> { self.proxy_signers .ecdsa_signers .get(address) - .map(|x| x.delegation) + .map(|x| &x.delegation) .ok_or(SignerModuleError::UnknownProxySigner(address.to_vec())) } @@ -235,21 +235,21 @@ impl LocalSigningManager { let mut keys: Vec<_> = consensus.into_iter().map(ConsensusProxyMap::new).collect(); for bls in proxy_bls { - let delegator = self.get_delegation_bls(&bls)?.message.delegator; + let delegator = &self.get_delegation_bls(&bls)?.message.delegator; let entry = keys .iter_mut() - .find(|x| x.consensus == delegator) - .ok_or(SignerModuleError::UnknownConsensusSigner(delegator.0.to_vec()))?; + .find(|x| &x.consensus == delegator) + .ok_or(SignerModuleError::UnknownConsensusSigner(delegator.serialize().to_vec()))?; entry.proxy_bls.push(bls); } for ecdsa in proxy_ecdsa { - let delegator = self.get_delegation_ecdsa(&ecdsa)?.message.delegator; + let delegator = &self.get_delegation_ecdsa(&ecdsa)?.message.delegator; let entry = keys .iter_mut() - .find(|x| x.consensus == delegator) - .ok_or(SignerModuleError::UnknownConsensusSigner(delegator.0.to_vec()))?; + .find(|x| &x.consensus == delegator) + .ok_or(SignerModuleError::UnknownConsensusSigner(delegator.serialize().to_vec()))?; entry.proxy_ecdsa.push(ecdsa); } @@ -289,7 +289,8 @@ mod tests { mod test_proxy_bls { use cb_common::{ - constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, signer::verify_bls_signature, + constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, + signer::verify_bls_signature, utils::TestRandomSeed, }; use super::*; @@ -304,7 +305,7 @@ mod tests { let validation_result = signed_delegation.validate(CHAIN); assert!( - validation_result.is_ok(), + validation_result, "Proxy delegation signature must be valid for consensus key." ); @@ -322,12 +323,11 @@ mod tests { let mut signed_delegation = signing_manager.create_proxy_bls(MODULE_ID.clone(), consensus_pk).await.unwrap(); - let m = &mut signed_delegation.signature.0[0]; - (*m, _) = m.overflowing_add(1); + signed_delegation.signature = BlsSignature::test_random(); let validation_result = signed_delegation.validate(CHAIN); - assert!(validation_result.is_err(), "Tampered proxy key must be invalid."); + assert!(!validation_result, "Tampered proxy key must be invalid."); } #[tokio::test] @@ -340,25 +340,22 @@ mod tests { let data_root = B256::random(); - let sig = signing_manager.sign_proxy_bls(&proxy_pk, &data_root).await.unwrap(); + let sig = signing_manager.sign_proxy_bls(&proxy_pk, data_root).await.unwrap(); // Verify signature let domain = compute_domain(CHAIN, COMMIT_BOOST_DOMAIN); - let signing_root = compute_signing_root(data_root.tree_hash_root().0, domain); + let signing_root = compute_signing_root(data_root.tree_hash_root(), domain); - let validation_result = verify_bls_signature(&proxy_pk, &signing_root, &sig); + let validation_result = verify_bls_signature(&proxy_pk, signing_root, &sig); - assert!( - validation_result.is_ok(), - "Proxy keypair must produce valid signatures of messages." - ) + assert!(validation_result, "Proxy keypair must produce valid signatures of messages.") } } mod test_proxy_ecdsa { use cb_common::{ constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, - signer::verify_ecdsa_signature, + signer::verify_ecdsa_signature, utils::TestRandomSeed, }; use super::*; @@ -373,7 +370,7 @@ mod tests { let validation_result = signed_delegation.validate(CHAIN); assert!( - validation_result.is_ok(), + validation_result, "Proxy delegation signature must be valid for consensus key." ); @@ -391,12 +388,11 @@ mod tests { let mut signed_delegation = signing_manager.create_proxy_ecdsa(MODULE_ID.clone(), consensus_pk).await.unwrap(); - let m = &mut signed_delegation.signature.0[0]; - (*m, _) = m.overflowing_add(1); + signed_delegation.signature = BlsSignature::test_random(); let validation_result = signed_delegation.validate(CHAIN); - assert!(validation_result.is_err(), "Tampered proxy key must be invalid."); + assert!(!validation_result, "Tampered proxy key must be invalid."); } #[tokio::test] @@ -409,11 +405,11 @@ mod tests { let data_root = B256::random(); - let sig = signing_manager.sign_proxy_ecdsa(&proxy_pk, &data_root).await.unwrap(); + let sig = signing_manager.sign_proxy_ecdsa(&proxy_pk, data_root).await.unwrap(); // Verify signature let domain = compute_domain(CHAIN, COMMIT_BOOST_DOMAIN); - let signing_root = compute_signing_root(data_root.tree_hash_root().0, domain); + let signing_root = compute_signing_root(data_root.tree_hash_root(), domain); let validation_result = verify_ecdsa_signature(&proxy_pk, &signing_root, &sig); diff --git a/crates/signer/src/service.rs b/crates/signer/src/service.rs index 1a41a008..ab223829 100644 --- a/crates/signer/src/service.rs +++ b/crates/signer/src/service.rs @@ -274,29 +274,29 @@ async fn handle_request_signature( let res = match &*manager { SigningManager::Local(local_manager) => match request { SignRequest::Consensus(SignConsensusRequest { object_root, pubkey }) => local_manager - .sign_consensus(&pubkey, &object_root) + .sign_consensus(&pubkey, object_root) .await .map(|sig| Json(sig).into_response()), SignRequest::ProxyBls(SignProxyRequest { object_root, proxy: bls_key }) => { local_manager - .sign_proxy_bls(&bls_key, &object_root) + .sign_proxy_bls(&bls_key, object_root) .await .map(|sig| Json(sig).into_response()) } SignRequest::ProxyEcdsa(SignProxyRequest { object_root, proxy: ecdsa_key }) => { local_manager - .sign_proxy_ecdsa(&ecdsa_key, &object_root) + .sign_proxy_ecdsa(&ecdsa_key, object_root) .await .map(|sig| Json(sig).into_response()) } }, SigningManager::Dirk(dirk_manager) => match request { SignRequest::Consensus(SignConsensusRequest { object_root, pubkey }) => dirk_manager - .request_consensus_signature(&pubkey, *object_root) + .request_consensus_signature(&pubkey, object_root) .await .map(|sig| Json(sig).into_response()), SignRequest::ProxyBls(SignProxyRequest { object_root, proxy: bls_key }) => dirk_manager - .request_proxy_signature(&bls_key, *object_root) + .request_proxy_signature(&bls_key, object_root) .await .map(|sig| Json(sig).into_response()), SignRequest::ProxyEcdsa(_) => { diff --git a/examples/da_commit/src/main.rs b/examples/da_commit/src/main.rs index 71b61c53..27b5ce86 100644 --- a/examples/da_commit/src/main.rs +++ b/examples/da_commit/src/main.rs @@ -49,16 +49,17 @@ impl DaCommitService { let pubkeys = self.config.signer_client.get_pubkeys().await?.keys; info!(pubkeys = %serde_json::to_string_pretty(&pubkeys).unwrap(), "Received pubkeys"); - let pubkey = pubkeys.first().ok_or_eyre("no key available")?.consensus; + let pubkey = pubkeys.first().ok_or_eyre("no key available")?.consensus.clone(); info!("Registered validator {pubkey}"); - let proxy_delegation_bls = self.config.signer_client.generate_proxy_key_bls(pubkey).await?; + let proxy_delegation_bls = + self.config.signer_client.generate_proxy_key_bls(pubkey.clone()).await?; info!("Obtained a BLS proxy delegation:\n{proxy_delegation_bls}"); let proxy_bls = proxy_delegation_bls.message.proxy; let proxy_ecdsa = if self.config.extra.use_ecdsa_keys { let proxy_delegation_ecdsa = - self.config.signer_client.generate_proxy_key_ecdsa(pubkey).await?; + self.config.signer_client.generate_proxy_key_ecdsa(pubkey.clone()).await?; info!("Obtained an ECDSA proxy delegation:\n{proxy_delegation_ecdsa}"); Some(proxy_delegation_ecdsa.message.proxy) } else { @@ -68,7 +69,7 @@ impl DaCommitService { let mut data = 0; loop { - self.send_request(data, pubkey, proxy_bls, proxy_ecdsa).await?; + self.send_request(data, pubkey.clone(), proxy_bls.clone(), proxy_ecdsa).await?; sleep(Duration::from_secs(self.config.extra.sleep_secs)).await; data += 1; } diff --git a/tests/data/signed_blinded_block_holesky.json b/tests/data/signed_blinded_block_holesky.json index f70a69ad..14aeb814 100644 --- a/tests/data/signed_blinded_block_holesky.json +++ b/tests/data/signed_blinded_block_holesky.json @@ -197,25 +197,25 @@ "execution_requests": { "deposits": [ { - "pubkey": "0x0e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "withdrawal_credentials": "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", "amount": "100", - "signature": "0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f", "index": "1" } ], "withdrawals": [ { "source_address": "0x1100000000000000000000000000000000000000", - "validator_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "validator_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "amount": "1" } ], "consolidations": [ { "source_address": "0x1200000000000000000000000000000000000000", - "source_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "target_pubkey": "0x110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "source_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", + "target_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" } ] } diff --git a/tests/data/ssv_valid.json b/tests/data/ssv_valid.json index e19b13e6..20fa9baa 100644 --- a/tests/data/ssv_valid.json +++ b/tests/data/ssv_valid.json @@ -2,7 +2,7 @@ "validators": [ { "id": 554991, - "public_key": "967ba17a3e7f82a25aa5350ec34d6923e28ad8237b5a41efe2c5e325240d74d87a015bf04634f21900963539c8229b2a", + "public_key": "0x967ba17a3e7f82a25aa5350ec34d6923e28ad8237b5a41efe2c5e325240d74d87a015bf04634f21900963539c8229b2a", "cluster": "0xf7c1283eb0c0f76b5fa84c7541d8d4d27751b4083a5e8dcb8ac9e72bb7f559b8", "owner_address": "0xB2EE025B1d129c61E77223bAb42fc65b29B16243", "status": "Inactive", @@ -31,7 +31,7 @@ }, { "id": 554992, - "public_key": "ac769e8cec802e8ffee34de3253be8f438a0c17ee84bdff0b6730280d24b5ecb77ebc9c985281b41ee3bda8663b6658c", + "public_key": "0xac769e8cec802e8ffee34de3253be8f438a0c17ee84bdff0b6730280d24b5ecb77ebc9c985281b41ee3bda8663b6658c", "cluster": "0xf7c1283eb0c0f76b5fa84c7541d8d4d27751b4083a5e8dcb8ac9e72bb7f559b8", "owner_address": "0xB2EE025B1d129c61E77223bAb42fc65b29B16243", "status": "Inactive", @@ -60,7 +60,7 @@ }, { "id": 554994, - "public_key": "8c866a5a05f3d45c49b457e29365259021a509c5daa82e124f9701a960ee87b8902e87175315ab638a3d8b1115b23639", + "public_key": "0x8c866a5a05f3d45c49b457e29365259021a509c5daa82e124f9701a960ee87b8902e87175315ab638a3d8b1115b23639", "cluster": "0xf7c1283eb0c0f76b5fa84c7541d8d4d27751b4083a5e8dcb8ac9e72bb7f559b8", "owner_address": "0xB2EE025B1d129c61E77223bAb42fc65b29B16243", "status": "Inactive", diff --git a/tests/src/mock_relay.rs b/tests/src/mock_relay.rs index 04ebfc24..4b0b6364 100644 --- a/tests/src/mock_relay.rs +++ b/tests/src/mock_relay.rs @@ -16,15 +16,15 @@ use axum::{ }; use cb_common::{ pbs::{ - ExecutionPayloadHeaderMessageElectra, GetHeaderParams, GetHeaderResponse, - SignedExecutionPayloadHeader, SubmitBlindedBlockResponse, BUILDER_V1_API_PATH, - BUILDER_V2_API_PATH, GET_HEADER_PATH, GET_STATUS_PATH, REGISTER_VALIDATOR_PATH, - SUBMIT_BLOCK_PATH, + BlindedBeaconBlock, ExecutionPayloadHeaderMessageElectra, ExecutionRequests, + GetHeaderParams, GetHeaderResponse, KzgProof, SignedBlindedBeaconBlock, + SignedExecutionPayloadHeader, SubmitBlindedBlockResponse, VersionedResponse, + BUILDER_V1_API_PATH, BUILDER_V2_API_PATH, GET_HEADER_PATH, GET_STATUS_PATH, + REGISTER_VALIDATOR_PATH, SUBMIT_BLOCK_PATH, }, signature::sign_builder_root, - signer::BlsSecretKey, - types::Chain, - utils::{blst_pubkey_to_alloy, timestamp_of_slot_start_sec}, + types::{BlsSecretKey, Chain}, + utils::timestamp_of_slot_start_sec, }; use cb_pbs::MAX_SIZE_SUBMIT_BLOCK_RESPONSE; use tokio::net::TcpListener; @@ -112,17 +112,23 @@ async fn handle_get_header( ) -> Response { state.received_get_header.fetch_add(1, Ordering::Relaxed); - let mut response: SignedExecutionPayloadHeader = - SignedExecutionPayloadHeader::default(); + let mut message = ExecutionPayloadHeaderMessageElectra { + header: Default::default(), + blob_kzg_commitments: Default::default(), + execution_requests: ExecutionRequests::default(), + value: Default::default(), + pubkey: state.signer.public_key(), + }; - response.message.header.parent_hash = parent_hash; - response.message.header.block_hash.0[0] = 1; - response.message.value = U256::from(10); - response.message.pubkey = blst_pubkey_to_alloy(&state.signer.sk_to_pk()); - response.message.header.timestamp = timestamp_of_slot_start_sec(0, state.chain); + message.header.parent_hash = parent_hash; + message.header.block_hash.0[0] = 1; + message.value = U256::from(10); + message.pubkey = state.signer.public_key(); + message.header.timestamp = timestamp_of_slot_start_sec(0, state.chain); - let object_root = response.message.tree_hash_root().0; - response.signature = sign_builder_root(state.chain, &state.signer, object_root); + let object_root = message.tree_hash_root(); + let signature = sign_builder_root(state.chain, &state.signer, object_root); + let response = SignedExecutionPayloadHeader { message, signature }; let response = GetHeaderResponse::Electra(response); (StatusCode::OK, Json(response)).into_response() @@ -147,12 +153,25 @@ async fn handle_register_validator( StatusCode::OK.into_response() } -async fn handle_submit_block_v1(State(state): State>) -> Response { +async fn handle_submit_block_v1( + State(state): State>, + Json(submit_block): Json, +) -> Response { state.received_submit_block.fetch_add(1, Ordering::Relaxed); if state.large_body() { (StatusCode::OK, Json(vec![1u8; 1 + MAX_SIZE_SUBMIT_BLOCK_RESPONSE])).into_response() } else { - let response = SubmitBlindedBlockResponse::default(); + let VersionedResponse::Electra(mut response) = SubmitBlindedBlockResponse::default(); + response.execution_payload.block_hash = submit_block.block_hash(); + + let BlindedBeaconBlock::Electra(body) = submit_block.message; + + response.blobs_bundle.blobs.push(Default::default()).unwrap(); + response.blobs_bundle.commitments = body.body.blob_kzg_commitments; + response.blobs_bundle.proofs.push(KzgProof([0; 48])).unwrap(); + + let response = VersionedResponse::Electra(response); + (StatusCode::OK, Json(response)).into_response() } } diff --git a/tests/src/mock_validator.rs b/tests/src/mock_validator.rs index ee860189..3a2f68c0 100644 --- a/tests/src/mock_validator.rs +++ b/tests/src/mock_validator.rs @@ -1,8 +1,9 @@ -use alloy::{ - primitives::B256, - rpc::types::beacon::{relay::ValidatorRegistration, BlsPublicKey}, +use alloy::{primitives::B256, rpc::types::beacon::relay::ValidatorRegistration}; +use cb_common::{ + pbs::{BuilderApiVersion, RelayClient, SignedBlindedBeaconBlock}, + types::BlsPublicKey, + utils::bls_pubkey_from_hex, }; -use cb_common::pbs::{BuilderApiVersion, RelayClient, SignedBlindedBeaconBlock}; use reqwest::Response; use crate::utils::generate_mock_relay; @@ -13,11 +14,14 @@ pub struct MockValidator { impl MockValidator { pub fn new(port: u16) -> eyre::Result { - Ok(Self { comm_boost: generate_mock_relay(port, BlsPublicKey::default())? }) + let pubkey = bls_pubkey_from_hex("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")?; + Ok(Self { comm_boost: generate_mock_relay(port, pubkey)? }) } pub async fn do_get_header(&self, pubkey: Option) -> eyre::Result { - let url = self.comm_boost.get_header_url(0, B256::ZERO, pubkey.unwrap_or_default())?; + let default_pubkey = bls_pubkey_from_hex("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")?; + let url = + self.comm_boost.get_header_url(0, &B256::ZERO, &pubkey.unwrap_or(default_pubkey))?; Ok(self.comm_boost.client.get(url).send().await?) } @@ -60,12 +64,16 @@ impl MockValidator { ) -> eyre::Result { let url = self.comm_boost.submit_block_url(api_version).unwrap(); - Ok(self - .comm_boost - .client - .post(url) - .json(&signed_blinded_block.unwrap_or_default()) - .send() - .await?) + let signed_blinded_block = + signed_blinded_block.unwrap_or_else(load_test_signed_blinded_block); + + Ok(self.comm_boost.client.post(url).json(&signed_blinded_block).send().await?) } } + +pub fn load_test_signed_blinded_block() -> SignedBlindedBeaconBlock { + let data_json = include_str!( + "../../crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.json" + ); + serde_json::from_str(data_json).unwrap() +} diff --git a/tests/src/utils.rs b/tests/src/utils.rs index 5392fd95..2ea202a8 100644 --- a/tests/src/utils.rs +++ b/tests/src/utils.rs @@ -4,7 +4,7 @@ use std::{ sync::{Arc, Once}, }; -use alloy::{primitives::U256, rpc::types::beacon::BlsPublicKey}; +use alloy::primitives::U256; use cb_common::{ config::{ PbsConfig, PbsModuleConfig, RelayConfig, SignerConfig, SignerType, StartSignerConfig, @@ -13,7 +13,7 @@ use cb_common::{ }, pbs::{RelayClient, RelayEntry}, signer::SignerLoader, - types::{Chain, ModuleId}, + types::{BlsPublicKey, Chain, ModuleId}, utils::default_host, }; use eyre::Result; diff --git a/tests/tests/pbs_get_header.rs b/tests/tests/pbs_get_header.rs index 10f30b6a..eaae5367 100644 --- a/tests/tests/pbs_get_header.rs +++ b/tests/tests/pbs_get_header.rs @@ -2,11 +2,8 @@ use std::{sync::Arc, time::Duration}; use alloy::primitives::{B256, U256}; use cb_common::{ - pbs::GetHeaderResponse, - signature::sign_builder_root, - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::{blst_pubkey_to_alloy, timestamp_of_slot_start_sec}, + pbs::GetHeaderResponse, signature::sign_builder_root, signer::random_secret, types::Chain, + utils::timestamp_of_slot_start_sec, }; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ @@ -23,7 +20,7 @@ use tree_hash::TreeHash; async fn test_get_header() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3200; @@ -54,11 +51,11 @@ async fn test_get_header() -> Result<()> { assert_eq!(res.message.header.block_hash.0[0], 1); assert_eq!(res.message.header.parent_hash, B256::ZERO); assert_eq!(res.message.value, U256::from(10)); - assert_eq!(res.message.pubkey, blst_pubkey_to_alloy(&mock_state.signer.sk_to_pk())); + assert_eq!(res.message.pubkey, mock_state.signer.public_key()); assert_eq!(res.message.header.timestamp, timestamp_of_slot_start_sec(0, chain)); assert_eq!( res.signature, - sign_builder_root(chain, &mock_state.signer, res.message.tree_hash_root().0) + sign_builder_root(chain, &mock_state.signer, res.message.tree_hash_root()) ); Ok(()) } @@ -67,7 +64,7 @@ async fn test_get_header() -> Result<()> { async fn test_get_header_returns_204_if_relay_down() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3300; @@ -101,7 +98,7 @@ async fn test_get_header_returns_204_if_relay_down() -> Result<()> { async fn test_get_header_returns_400_if_request_is_invalid() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3400; @@ -109,7 +106,7 @@ async fn test_get_header_returns_400_if_request_is_invalid() -> Result<()> { // Run a mock relay let mock_state = Arc::new(MockRelayState::new(chain, signer)); - let mock_relay = generate_mock_relay(relay_port, pubkey)?; + let mock_relay = generate_mock_relay(relay_port, pubkey.clone())?; tokio::spawn(start_mock_relay_service(mock_state.clone(), relay_port)); // Run the PBS service @@ -121,7 +118,7 @@ async fn test_get_header_returns_400_if_request_is_invalid() -> Result<()> { tokio::time::sleep(Duration::from_millis(100)).await; // Create an invalid URL by truncating the pubkey - let mut bad_url = mock_relay.get_header_url(0, B256::ZERO, pubkey).unwrap(); + let mut bad_url = mock_relay.get_header_url(0, &B256::ZERO, &pubkey).unwrap(); bad_url.set_path(&bad_url.path().replace(&pubkey.to_string(), &pubkey.to_string()[..10])); let mock_validator = MockValidator::new(pbs_port)?; @@ -131,7 +128,7 @@ async fn test_get_header_returns_400_if_request_is_invalid() -> Result<()> { assert_eq!(res.status(), StatusCode::BAD_REQUEST); // Attempt again by truncating the parent hash - let mut bad_url = mock_relay.get_header_url(0, B256::ZERO, pubkey).unwrap(); + let mut bad_url = mock_relay.get_header_url(0, &B256::ZERO, &pubkey).unwrap(); bad_url .set_path(&bad_url.path().replace(&B256::ZERO.to_string(), &B256::ZERO.to_string()[..10])); let res = mock_validator.comm_boost.client.get(bad_url).send().await?; diff --git a/tests/tests/pbs_get_status.rs b/tests/tests/pbs_get_status.rs index 3e913dc5..73a81e51 100644 --- a/tests/tests/pbs_get_status.rs +++ b/tests/tests/pbs_get_status.rs @@ -1,10 +1,6 @@ use std::{sync::Arc, time::Duration}; -use cb_common::{ - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::blst_pubkey_to_alloy, -}; +use cb_common::{signer::random_secret, types::Chain}; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ mock_relay::{start_mock_relay_service, MockRelayState}, @@ -19,7 +15,7 @@ use tracing::info; async fn test_get_status() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3500; @@ -27,7 +23,7 @@ async fn test_get_status() -> Result<()> { let relay_1_port = pbs_port + 2; let relays = vec![ - generate_mock_relay(relay_0_port, pubkey)?, + generate_mock_relay(relay_0_port, pubkey.clone())?, generate_mock_relay(relay_1_port, pubkey)?, ]; let mock_state = Arc::new(MockRelayState::new(chain, signer)); @@ -55,7 +51,7 @@ async fn test_get_status() -> Result<()> { async fn test_get_status_returns_502_if_relay_down() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3600; diff --git a/tests/tests/pbs_mux.rs b/tests/tests/pbs_mux.rs index 4d830e20..3c4f7a13 100644 --- a/tests/tests/pbs_mux.rs +++ b/tests/tests/pbs_mux.rs @@ -1,11 +1,6 @@ use std::{collections::HashMap, sync::Arc, time::Duration}; -use cb_common::{ - config::RuntimeMuxConfig, - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::blst_pubkey_to_alloy, -}; +use cb_common::{config::RuntimeMuxConfig, signer::random_secret, types::Chain}; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ mock_relay::{start_mock_relay_service, MockRelayState}, @@ -20,14 +15,14 @@ use tracing::info; async fn test_mux() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3700; - let mux_relay_1 = generate_mock_relay(pbs_port + 1, pubkey)?; - let mux_relay_2 = generate_mock_relay(pbs_port + 2, pubkey)?; - let default_relay = generate_mock_relay(pbs_port + 3, pubkey)?; + let mux_relay_1 = generate_mock_relay(pbs_port + 1, pubkey.clone())?; + let mux_relay_2 = generate_mock_relay(pbs_port + 2, pubkey.clone())?; + let default_relay = generate_mock_relay(pbs_port + 3, pubkey.clone())?; // Run 3 mock relays let mock_state = Arc::new(MockRelayState::new(chain, signer)); @@ -48,8 +43,8 @@ async fn test_mux() -> Result<()> { }; // Bind mux to a specific validator key - let validator_pubkey = blst_pubkey_to_alloy(&random_secret().sk_to_pk()); - config.muxes = Some(HashMap::from([(validator_pubkey, mux)])); + let validator_pubkey = random_secret().public_key(); + config.muxes = Some(HashMap::from([(validator_pubkey.clone(), mux)])); // Run PBS service let state = PbsState::new(config); diff --git a/tests/tests/pbs_post_blinded_blocks.rs b/tests/tests/pbs_post_blinded_blocks.rs index 9e91dfa9..81c81f4d 100644 --- a/tests/tests/pbs_post_blinded_blocks.rs +++ b/tests/tests/pbs_post_blinded_blocks.rs @@ -1,15 +1,14 @@ use std::{sync::Arc, time::Duration}; use cb_common::{ - pbs::{BuilderApiVersion, SignedBlindedBeaconBlock, SubmitBlindedBlockResponse}, - signer::{random_secret, BlsPublicKey}, + pbs::{BuilderApiVersion, SubmitBlindedBlockResponse}, + signer::random_secret, types::Chain, - utils::blst_pubkey_to_alloy, }; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ mock_relay::{start_mock_relay_service, MockRelayState}, - mock_validator::MockValidator, + mock_validator::{load_test_signed_blinded_block, MockValidator}, utils::{generate_mock_relay, get_pbs_static_config, setup_test_env, to_pbs_config}, }; use eyre::Result; @@ -21,8 +20,10 @@ async fn test_submit_block_v1() -> Result<()> { let res = submit_block_impl(3800, &BuilderApiVersion::V1).await?; assert_eq!(res.status(), StatusCode::OK); + let signed_blinded_block = load_test_signed_blinded_block(); + let response_body = serde_json::from_slice::(&res.bytes().await?)?; - assert_eq!(response_body.block_hash(), SubmitBlindedBlockResponse::default().block_hash()); + assert_eq!(response_body.block_hash(), signed_blinded_block.block_hash()); Ok(()) } @@ -38,7 +39,7 @@ async fn test_submit_block_v2() -> Result<()> { async fn test_submit_block_too_large() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3900; @@ -67,7 +68,7 @@ async fn test_submit_block_too_large() -> Result<()> { async fn submit_block_impl(pbs_port: u16, api_version: &BuilderApiVersion) -> Result { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; @@ -84,14 +85,15 @@ async fn submit_block_impl(pbs_port: u16, api_version: &BuilderApiVersion) -> Re // leave some time to start servers tokio::time::sleep(Duration::from_millis(100)).await; + let signed_blinded_block = load_test_signed_blinded_block(); let mock_validator = MockValidator::new(pbs_port)?; info!("Sending submit block"); let res = match api_version { BuilderApiVersion::V1 => { - mock_validator.do_submit_block_v1(Some(SignedBlindedBeaconBlock::default())).await? + mock_validator.do_submit_block_v1(Some(signed_blinded_block)).await? } BuilderApiVersion::V2 => { - mock_validator.do_submit_block_v2(Some(SignedBlindedBeaconBlock::default())).await? + mock_validator.do_submit_block_v2(Some(signed_blinded_block)).await? } }; assert_eq!(mock_state.received_submit_block(), 1); diff --git a/tests/tests/pbs_post_validators.rs b/tests/tests/pbs_post_validators.rs index f2480ac1..09a471a7 100644 --- a/tests/tests/pbs_post_validators.rs +++ b/tests/tests/pbs_post_validators.rs @@ -2,9 +2,8 @@ use std::{sync::Arc, time::Duration}; use alloy::rpc::types::beacon::relay::ValidatorRegistration; use cb_common::{ - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::blst_pubkey_to_alloy, + signer::random_secret, + types::{BlsPublicKey, Chain}, }; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ @@ -20,7 +19,7 @@ use tracing::info; async fn test_register_validators() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey: BlsPublicKey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 4000; @@ -66,7 +65,7 @@ async fn test_register_validators() -> Result<()> { async fn test_register_validators_returns_422_if_request_is_malformed() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey: BlsPublicKey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 4100; @@ -206,7 +205,7 @@ async fn test_register_validators_returns_422_if_request_is_malformed() -> Resul async fn test_register_validators_does_not_retry_on_429() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey: BlsPublicKey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 4200; @@ -259,7 +258,7 @@ async fn test_register_validators_does_not_retry_on_429() -> Result<()> { async fn test_register_validators_retries_on_500() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey: BlsPublicKey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 4300; diff --git a/tests/tests/signer_jwt_auth.rs b/tests/tests/signer_jwt_auth.rs index 90a0365f..5f8a7274 100644 --- a/tests/tests/signer_jwt_auth.rs +++ b/tests/tests/signer_jwt_auth.rs @@ -1,12 +1,11 @@ use std::{collections::HashMap, time::Duration}; -use alloy::{hex, primitives::FixedBytes}; use cb_common::{ commit::{constants::GET_PUBKEYS_PATH, request::GetPubkeysResponse}, config::StartSignerConfig, signer::{SignerLoader, ValidatorKeysFormat}, types::{Chain, ModuleId}, - utils::create_jwt, + utils::{bls_pubkey_from_hex, create_jwt}, }; use cb_signer::service::SigningService; use cb_tests::utils::{get_signer_config, get_start_signer_config, setup_test_env}; @@ -131,8 +130,8 @@ async fn verify_pubkeys(response: Response) -> Result<()> { let pubkey_json = response.json::().await?; assert_eq!(pubkey_json.keys.len(), 2); let expected_pubkeys = vec![ - FixedBytes::new(hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4")), - FixedBytes::new(hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9")), + bls_pubkey_from_hex("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4")?, + bls_pubkey_from_hex("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9")?, ]; for expected in expected_pubkeys { assert!(