diff --git a/Cargo.lock b/Cargo.lock index f1daf4dbdfb..9973acde09b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,7 +245,7 @@ dependencies = [ "asn1-rs-derive 0.1.0", "asn1-rs-impl", "displaydoc", - "nom 7.1.2", + "nom 7.1.3", "num-traits", "rusticata-macros", "thiserror", @@ -261,7 +261,7 @@ dependencies = [ "asn1-rs-derive 0.4.0", "asn1-rs-impl", "displaydoc", - "nom 7.1.2", + "nom 7.1.3", "num-traits", "rusticata-macros", "thiserror", @@ -397,9 +397,9 @@ dependencies = [ [[package]] name = "atomic-waker" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" +checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" [[package]] name = "attohttpc" @@ -530,6 +530,18 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + [[package]] name = "base64ct" version = "1.5.3" @@ -845,9 +857,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byte-slice-cast" @@ -935,7 +947,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "nom 7.1.2", + "nom 7.1.3", ] [[package]] @@ -1118,9 +1130,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" dependencies = [ "crossbeam-utils", ] @@ -1198,9 +1210,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" [[package]] name = "crc32fast" @@ -1394,7 +1406,7 @@ version = "3.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1631ca6e3c59112501a9d87fd86f21591ff77acd31331e8a73f8d80a65bbdd71" dependencies = [ - "nix 0.26.1", + "nix 0.26.2", "windows-sys", ] @@ -1652,7 +1664,7 @@ checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" dependencies = [ "asn1-rs 0.3.1", "displaydoc", - "nom 7.1.2", + "nom 7.1.3", "num-bigint", "num-traits", "rusticata-macros", @@ -1666,7 +1678,7 @@ checksum = "42d4bc9b0db0a0df9ae64634ac5bdefb7afcb534e182275ca0beadbe486701c1" dependencies = [ "asn1-rs 0.5.1", "displaydoc", - "nom 7.1.2", + "nom 7.1.3", "num-bigint", "num-traits", "rusticata-macros", @@ -1873,9 +1885,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "signature", ] @@ -1968,7 +1980,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26fa0a0be8915790626d5759eb51fe47435a8eac92c2f212bd2da9aa7f30ea56" dependencies = [ - "base64", + "base64 0.13.1", "bs58", "bytes", "ed25519-dalek", @@ -2145,7 +2157,7 @@ dependencies = [ name = "eth2_interop_keypairs" version = "0.2.0" dependencies = [ - "base64", + "base64 0.13.1", "bls", "eth2_hashing", "hex", @@ -2226,9 +2238,10 @@ dependencies = [ [[package]] name = "eth2_ssz_derive" -version = "0.3.0" +version = "0.3.1" dependencies = [ "darling 0.13.4", + "eth2_ssz", "proc-macro2", "quote", "syn", @@ -2239,12 +2252,14 @@ name = "eth2_ssz_types" version = "0.2.2" dependencies = [ "arbitrary", + "base64 0.20.0", "derivative", "eth2_serde_utils", "eth2_ssz", "serde", "serde_derive", "serde_json", + "serde_with", "smallvec", "tree_hash", "tree_hash_derive", @@ -2422,7 +2437,7 @@ checksum = "a1a9e0597aa6b2fdc810ff58bc95e4eeaa2c219b3e615ed025106ecb027407d8" dependencies = [ "async-trait", "auto_impl", - "base64", + "base64 0.13.1", "ethers-core", "futures-channel", "futures-core", @@ -2789,7 +2804,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" dependencies = [ "futures-io", - "rustls 0.20.7", + "rustls 0.20.8", "webpki 0.22.0", ] @@ -3042,7 +3057,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ - "base64", + "base64 0.13.1", "bitflags", "bytes", "headers-core", @@ -3309,7 +3324,7 @@ checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ "http", "hyper", - "rustls 0.20.7", + "rustls 0.20.8", "tokio", "tokio-rustls 0.23.4", ] @@ -3456,7 +3471,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.2.1", + "parity-scale-codec 3.2.2", ] [[package]] @@ -3625,7 +3640,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f4f04699947111ec1733e71778d763555737579e44b85844cae8e1940a1828" dependencies = [ - "base64", + "base64 0.13.1", "pem", "ring", "serde", @@ -3695,6 +3710,7 @@ dependencies = [ "environment", "eth1_test_rig", "eth2", + "eth2_hashing", "eth2_network_config", "eth2_ssz", "eth2_wallet", @@ -3926,7 +3942,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a173171c71c29bb156f98886c7c4824596de3903dadf01e2e79d2ccdcf38cd9f" dependencies = [ "asynchronous-codec", - "base64", + "base64 0.13.1", "byteorder", "bytes", "fnv", @@ -4077,7 +4093,7 @@ dependencies = [ "parking_lot 0.12.1", "quinn-proto", "rand 0.8.5", - "rustls 0.20.7", + "rustls 0.20.8", "thiserror", "tokio", ] @@ -4142,7 +4158,7 @@ dependencies = [ "libp2p-core 0.38.0", "rcgen 0.10.0", "ring", - "rustls 0.20.7", + "rustls 0.20.8", "thiserror", "webpki 0.22.0", "x509-parser 0.14.0", @@ -4220,7 +4236,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" dependencies = [ "arrayref", - "base64", + "base64 0.13.1", "digest 0.9.0", "hmac-drbg", "libsecp256k1-core", @@ -5006,9 +5022,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a58d1d356c6597d08cde02c2f09d785b09e28711837b1ed667dc652c08a694" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ "bitflags", "cfg-if", @@ -5045,9 +5061,9 @@ checksum = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" [[package]] name = "nom" -version = "7.1.2" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", @@ -5153,9 +5169,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.1" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d864c91689fdc196779b98dba0aceac6118594c2df6ee5d943eb6a8df4d107a" +checksum = "2b8c786513eb403643f2a88c244c2aaa270ef2153f55094587d0c48a3cf22a83" dependencies = [ "memchr", ] @@ -5360,15 +5376,15 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.2.1" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366e44391a8af4cfd6002ef6ba072bae071a96aafca98d7d448a34c5dca38b6a" +checksum = "e7ab01d0f889e957861bc65888d5ccbe82c158d0270136ba46820d43837cdf72" dependencies = [ "arrayvec", "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.1.3", + "parity-scale-codec-derive 3.1.4", "serde", ] @@ -5386,9 +5402,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.3" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" +checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5420,7 +5436,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.5", + "parking_lot_core 0.9.6", ] [[package]] @@ -5439,9 +5455,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" dependencies = [ "cfg-if", "libc", @@ -5482,11 +5498,11 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pem" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" dependencies = [ - "base64", + "base64 0.13.1", ] [[package]] @@ -5506,9 +5522,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6e86fb9e7026527a0d46bc308b841d73170ef8f443e1807f6ef88526a816d4" +checksum = "4257b4a04d91f7e9e6290be5d3da4804dd5784fafde3a497d73eb2b4a158c30a" dependencies = [ "thiserror", "ucd-trie", @@ -5761,9 +5777,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] @@ -5820,9 +5836,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c01db6702aa05baa3f57dec92b8eeeeb4cb19e894e73996b32a4093289e54592" +checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" dependencies = [ "bytes", "prost-derive", @@ -5830,9 +5846,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5320c680de74ba083512704acb90fe00f28f79207286a848e730c45dd73ed6" +checksum = "a3f8ad728fb08fe212df3c05169e940fbb6d9d16a877ddde14644a983ba2012e" dependencies = [ "bytes", "heck", @@ -5865,9 +5881,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8842bad1a5419bca14eac663ba798f6bc19c413c2fdceb5f3ba3b0932d96720" +checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" dependencies = [ "anyhow", "itertools", @@ -5878,9 +5894,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "017f79637768cde62820bc2d4fe0e45daaa027755c323ad077767c6c5f173091" +checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" dependencies = [ "bytes", "prost", @@ -5974,7 +5990,7 @@ dependencies = [ "rand 0.8.5", "ring", "rustc-hash", - "rustls 0.20.7", + "rustls 0.20.8", "slab", "thiserror", "tinyvec", @@ -6212,7 +6228,7 @@ version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" dependencies = [ - "base64", + "base64 0.13.1", "bytes", "encoding_rs", "futures-core", @@ -6231,7 +6247,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.9", - "rustls 0.20.7", + "rustls 0.20.8", "rustls-pemfile", "serde", "serde_json", @@ -6428,7 +6444,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" dependencies = [ - "nom 7.1.2", + "nom 7.1.3", ] [[package]] @@ -6437,7 +6453,7 @@ version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" dependencies = [ - "base64", + "base64 0.13.1", "log", "ring", "sct 0.6.1", @@ -6446,9 +6462,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.7" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log", "ring", @@ -6458,11 +6474,11 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64", + "base64 0.21.0", ] [[package]] @@ -6524,7 +6540,7 @@ checksum = "001cf62ece89779fd16105b5f515ad0e5cedcd5440d3dd806bb067978e7c3608" dependencies = [ "cfg-if", "derive_more", - "parity-scale-codec 3.2.1", + "parity-scale-codec 3.2.2", "scale-info-derive", ] @@ -6808,6 +6824,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" dependencies = [ + "base64 0.13.1", "serde", "serde_with_macros", ] @@ -7213,7 +7230,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ - "base64", + "base64 0.13.1", "bytes", "flate2", "futures", @@ -7374,7 +7391,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7e94b1ec00bad60e6410e058b52f1c66de3dc5fe4d62d09b3e52bb7d3b73e25" dependencies = [ - "base64", + "base64 0.13.1", "crc", "lazy_static", "md-5", @@ -7456,9 +7473,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.26.8" +version = "0.26.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ddf41e393a9133c81d5f0974195366bd57082deac6e0eb02ed39b8341c2bb6" +checksum = "5c18a6156d1f27a9592ee18c1a846ca8dd5c258b7179fc193ae87c74ebb666f5" dependencies = [ "cfg-if", "core-foundation-sys", @@ -7568,9 +7585,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -7744,9 +7761,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.24.1" +version = "1.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" +checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" dependencies = [ "autocfg 1.1.0", "bytes", @@ -7810,7 +7827,7 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.7", + "rustls 0.20.8", "tokio", "webpki 0.22.0", ] @@ -7848,7 +7865,7 @@ checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" dependencies = [ "futures-util", "log", - "rustls 0.20.7", + "rustls 0.20.8", "tokio", "tokio-rustls 0.23.4", "tungstenite 0.17.3", @@ -8127,7 +8144,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" dependencies = [ - "base64", + "base64 0.13.1", "byteorder", "bytes", "http", @@ -8146,14 +8163,14 @@ version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" dependencies = [ - "base64", + "base64 0.13.1", "byteorder", "bytes", "http", "httparse", "log", "rand 0.8.5", - "rustls 0.20.7", + "rustls 0.20.8", "sha-1 0.10.1", "thiserror", "url", @@ -8168,7 +8185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4712ee30d123ec7ae26d1e1b218395a16c87cdbaf4b3925d170d684af62ea5e8" dependencies = [ "async-trait", - "base64", + "base64 0.13.1", "futures", "log", "md-5", @@ -8715,7 +8732,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44f258e254752d210b84fe117b31f1e3cc9cbf04c0d747eb7f8cf7cf5e370f6d" dependencies = [ "arrayvec", - "base64", + "base64 0.13.1", "bytes", "derive_more", "ethabi 16.0.0", @@ -9116,19 +9133,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_x86_64_msvc 0.42.1", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" @@ -9138,9 +9155,9 @@ checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" @@ -9150,9 +9167,9 @@ checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" @@ -9162,9 +9179,9 @@ checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" @@ -9174,15 +9191,15 @@ checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" @@ -9192,9 +9209,9 @@ checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "winreg" @@ -9267,11 +9284,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" dependencies = [ "asn1-rs 0.3.1", - "base64", + "base64 0.13.1", "data-encoding", "der-parser 7.0.0", "lazy_static", - "nom 7.1.2", + "nom 7.1.3", "oid-registry 0.4.0", "ring", "rusticata-macros", @@ -9286,11 +9303,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" dependencies = [ "asn1-rs 0.5.1", - "base64", + "base64 0.13.1", "data-encoding", "der-parser 8.1.0", "lazy_static", - "nom 7.1.2", + "nom 7.1.3", "oid-registry 0.6.1", "rusticata-macros", "thiserror", diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index dd185ac7571..5b85833048b 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -33,7 +33,7 @@ slot_clock = { path = "../../common/slot_clock" } eth2_hashing = "0.3.0" eth2_ssz = "0.4.1" eth2_ssz_types = "0.2.2" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" state_processing = { path = "../../consensus/state_processing" } tree_hash = "0.4.1" types = { path = "../../consensus/types" } diff --git a/beacon_node/beacon_chain/src/merge_readiness.rs b/beacon_node/beacon_chain/src/merge_readiness.rs index 4ef2102fd51..3f5aff297d2 100644 --- a/beacon_node/beacon_chain/src/merge_readiness.rs +++ b/beacon_node/beacon_chain/src/merge_readiness.rs @@ -163,7 +163,7 @@ impl BeaconChain { }; } - if !el.is_synced_for_notifier().await { + if !el.is_synced().await { // The EL is not synced. return MergeReadiness::NotSynced; } diff --git a/beacon_node/eth1/Cargo.toml b/beacon_node/eth1/Cargo.toml index 7e99c43e7db..e0dd797bfaf 100644 --- a/beacon_node/eth1/Cargo.toml +++ b/beacon_node/eth1/Cargo.toml @@ -21,7 +21,7 @@ hex = "0.4.2" types = { path = "../../consensus/types"} merkle_proof = { path = "../../consensus/merkle_proof"} eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" tree_hash = "0.4.1" parking_lot = "0.12.0" slog = "2.5.2" diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index ba0a37736b0..5009e5ce70e 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -6,8 +6,8 @@ use reqwest::StatusCode; use serde::{Deserialize, Serialize}; use strum::IntoStaticStr; pub use types::{ - Address, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader, FixedVector, - Hash256, Uint256, VariableList, + Address, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader, + ExecutionWitness, FixedVector, Hash256, Uint256, VariableList, }; pub mod auth; @@ -114,6 +114,7 @@ pub struct ExecutionBlock { /// Representation of an exection block with enough detail to reconstruct a payload. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] +#[serde(bound = "T: EthSpec")] pub struct ExecutionBlockWithTransactions { pub parent_hash: ExecutionBlockHash, #[serde(alias = "miner")] @@ -138,6 +139,7 @@ pub struct ExecutionBlockWithTransactions { #[serde(rename = "hash")] pub block_hash: ExecutionBlockHash, pub transactions: Vec, + pub execution_witness: ExecutionWitness, } #[derive(Clone, Copy, Debug, PartialEq)] diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 74536630128..43eb2c1ac18 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -877,6 +877,7 @@ mod test { "extraData": "0x", "baseFeePerGas": "0x1", "blockHash": HASH_01, + "executionWitness": "null", }); // Take advantage of the fact that we own `transactions` and don't need to reserialize it. json.as_object_mut() @@ -1124,6 +1125,7 @@ mod test { base_fee_per_gas: Uint256::from(1), block_hash: ExecutionBlockHash::repeat_byte(1), transactions: vec![].into(), + execution_witness: ExecutionWitness::default(), }) .await; }, @@ -1146,6 +1148,7 @@ mod test { "baseFeePerGas": "0x1", "blockHash": HASH_01, "transactions": [], + "executionWitness": "null", }] }), ) @@ -1169,6 +1172,7 @@ mod test { base_fee_per_gas: Uint256::from(1), block_hash: ExecutionBlockHash::repeat_byte(1), transactions: vec![].into(), + execution_witness: ExecutionWitness::default(), }) .await }) @@ -1353,7 +1357,8 @@ mod test { "extraData":"0x", "baseFeePerGas":"0x7", "blockHash":"0x6359b8381a370e2f54072a5784ddd78b6ed024991558c511d4452eb4f6ac898c", - "transactions":[] + "transactions":[], + "executionWitness": "null", } })], |client| async move { @@ -1376,7 +1381,8 @@ mod test { extra_data: vec![].into(), base_fee_per_gas: Uint256::from(7), block_hash: ExecutionBlockHash::from_str("0x6359b8381a370e2f54072a5784ddd78b6ed024991558c511d4452eb4f6ac898c").unwrap(), - transactions: vec![].into(), + transactions: vec![].into(), + execution_witness: ExecutionWitness::default(), }; assert_eq!(payload, expected); @@ -1402,6 +1408,7 @@ mod test { base_fee_per_gas: Uint256::from(7), block_hash: ExecutionBlockHash::from_str("0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858").unwrap(), transactions: vec![].into(), + execution_witness: ExecutionWitness::default(), }) .await; }, @@ -1423,7 +1430,8 @@ mod test { "extraData":"0x", "baseFeePerGas":"0x7", "blockHash":"0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", - "transactions":[] + "transactions":[], + "executionWitness":"null", }], }) ) diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 560569c92f2..66a8e2b125a 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -1,7 +1,9 @@ use super::*; use serde::{Deserialize, Serialize}; use strum::EnumString; -use types::{EthSpec, ExecutionBlockHash, FixedVector, Transaction, Unsigned, VariableList}; +use types::{ + EthSpec, ExecutionBlockHash, ExecutionWitness, FixedVector, Transaction, Unsigned, VariableList, +}; #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -80,6 +82,7 @@ pub struct JsonExecutionPayloadHeaderV1 { pub base_fee_per_gas: Uint256, pub block_hash: ExecutionBlockHash, pub transactions_root: Hash256, + pub execution_witness_root: Hash256, } impl From> for ExecutionPayloadHeader { @@ -100,6 +103,7 @@ impl From> for ExecutionPayloadHeade base_fee_per_gas, block_hash, transactions_root, + execution_witness_root, } = e; Self { @@ -117,6 +121,7 @@ impl From> for ExecutionPayloadHeade base_fee_per_gas, block_hash, transactions_root, + execution_witness_root, } } } @@ -147,6 +152,7 @@ pub struct JsonExecutionPayloadV1 { #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] pub transactions: VariableList, T::MaxTransactionsPerPayload>, + pub execution_witness: ExecutionWitness, } impl From> for JsonExecutionPayloadV1 { @@ -167,6 +173,7 @@ impl From> for JsonExecutionPayloadV1 { base_fee_per_gas, block_hash, transactions, + execution_witness, } = e; Self { @@ -184,6 +191,7 @@ impl From> for JsonExecutionPayloadV1 { base_fee_per_gas, block_hash, transactions, + execution_witness, } } } @@ -206,6 +214,7 @@ impl From> for ExecutionPayload { base_fee_per_gas, block_hash, transactions, + execution_witness, } = e; Self { @@ -223,6 +232,7 @@ impl From> for ExecutionPayload { base_fee_per_gas, block_hash, transactions, + execution_witness, } } } diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index a4d15abb364..6e215b0cd8f 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -1529,6 +1529,7 @@ impl ExecutionLayer { base_fee_per_gas: block.base_fee_per_gas, block_hash: block.block_hash, transactions, + execution_witness: block.execution_witness, })) } diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index 22dcb400708..1fd83442553 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use tree_hash::TreeHash; use tree_hash_derive::TreeHash; -use types::{EthSpec, ExecutionBlockHash, ExecutionPayload, Hash256, Uint256}; +use types::{EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionWitness, Hash256, Uint256}; const GAS_LIMIT: u64 = 16384; const GAS_USED: u64 = GAS_LIMIT - 1; @@ -89,6 +89,7 @@ impl Block { base_fee_per_gas: payload.base_fee_per_gas, block_hash: payload.block_hash, transactions: vec![], + execution_witness: payload.execution_witness.clone(), }), Block::PoW(_) => None, } @@ -477,6 +478,7 @@ impl ExecutionBlockGenerator { base_fee_per_gas: Uint256::one(), block_hash: ExecutionBlockHash::zero(), transactions: vec![].into(), + execution_witness: ExecutionWitness::default(), }; execution_payload.block_hash = diff --git a/beacon_node/lighthouse_network/Cargo.toml b/beacon_node/lighthouse_network/Cargo.toml index 474ebebb507..1607d21aad2 100644 --- a/beacon_node/lighthouse_network/Cargo.toml +++ b/beacon_node/lighthouse_network/Cargo.toml @@ -12,7 +12,7 @@ eth2_ssz_types = "0.2.2" serde = { version = "1.0.116", features = ["derive"] } serde_derive = "1.0.116" eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" slog = { version = "2.5.2", features = ["max_level_trace"] } lighthouse_version = { path = "../../common/lighthouse_version" } tokio = { version = "1.14.0", features = ["time", "macros"] } diff --git a/beacon_node/operation_pool/Cargo.toml b/beacon_node/operation_pool/Cargo.toml index 1d67ecdccc2..8483233589f 100644 --- a/beacon_node/operation_pool/Cargo.toml +++ b/beacon_node/operation_pool/Cargo.toml @@ -13,7 +13,7 @@ parking_lot = "0.12.0" types = { path = "../../consensus/types" } state_processing = { path = "../../consensus/state_processing" } eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" rayon = "1.5.0" serde = "1.0.116" serde_derive = "1.0.116" diff --git a/beacon_node/store/Cargo.toml b/beacon_node/store/Cargo.toml index 20ae37b3b14..09d960535e4 100644 --- a/beacon_node/store/Cargo.toml +++ b/beacon_node/store/Cargo.toml @@ -14,7 +14,7 @@ leveldb = { version = "0.8.6", default-features = false } parking_lot = "0.12.0" itertools = "0.10.0" eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" types = { path = "../../consensus/types" } state_processing = { path = "../../consensus/state_processing" } slog = "2.5.2" diff --git a/common/eth2/Cargo.toml b/common/eth2/Cargo.toml index 294f8ec8a3d..eca086d838f 100644 --- a/common/eth2/Cargo.toml +++ b/common/eth2/Cargo.toml @@ -21,7 +21,7 @@ bytes = "1.0.1" account_utils = { path = "../../common/account_utils" } sensitive_url = { path = "../../common/sensitive_url" } eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" futures-util = "0.3.8" futures = "0.3.8" store = { path = "../../beacon_node/store", optional = true } diff --git a/consensus/cached_tree_hash/Cargo.toml b/consensus/cached_tree_hash/Cargo.toml index cd03b37a448..0e0ef0707e2 100644 --- a/consensus/cached_tree_hash/Cargo.toml +++ b/consensus/cached_tree_hash/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" ethereum-types = "0.14.1" eth2_ssz_types = "0.2.2" eth2_hashing = "0.3.0" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" eth2_ssz = "0.4.1" tree_hash = "0.4.1" smallvec = "1.6.1" diff --git a/consensus/fork_choice/Cargo.toml b/consensus/fork_choice/Cargo.toml index 52a738351ef..f0381e5ad99 100644 --- a/consensus/fork_choice/Cargo.toml +++ b/consensus/fork_choice/Cargo.toml @@ -11,7 +11,7 @@ types = { path = "../types" } state_processing = { path = "../state_processing" } proto_array = { path = "../proto_array" } eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" slog = { version = "2.5.2", features = ["max_level_trace", "release_max_level_trace"] } [dev-dependencies] diff --git a/consensus/proto_array/Cargo.toml b/consensus/proto_array/Cargo.toml index dfab6fda567..205ef8f5210 100644 --- a/consensus/proto_array/Cargo.toml +++ b/consensus/proto_array/Cargo.toml @@ -11,7 +11,7 @@ path = "src/bin.rs" [dependencies] types = { path = "../types" } eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" serde = "1.0.116" serde_derive = "1.0.116" serde_yaml = "0.8.13" diff --git a/consensus/ssz/Cargo.toml b/consensus/ssz/Cargo.toml index 1eef2a55571..d39ad10875a 100644 --- a/consensus/ssz/Cargo.toml +++ b/consensus/ssz/Cargo.toml @@ -10,7 +10,7 @@ license = "Apache-2.0" name = "ssz" [dev-dependencies] -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" [dependencies] ethereum-types = "0.14.1" diff --git a/consensus/ssz/tests/tests.rs b/consensus/ssz/tests/tests.rs index b4b91da4b58..f52d2c5cdfe 100644 --- a/consensus/ssz/tests/tests.rs +++ b/consensus/ssz/tests/tests.rs @@ -388,145 +388,3 @@ mod round_trip { round_trip(data); } } - -mod derive_macro { - use ssz::{Decode, Encode}; - use ssz_derive::{Decode, Encode}; - use std::fmt::Debug; - - fn assert_encode(item: &T, bytes: &[u8]) { - assert_eq!(item.as_ssz_bytes(), bytes); - } - - fn assert_encode_decode(item: &T, bytes: &[u8]) { - assert_encode(item, bytes); - assert_eq!(T::from_ssz_bytes(bytes).unwrap(), *item); - } - - #[derive(PartialEq, Debug, Encode, Decode)] - #[ssz(enum_behaviour = "union")] - enum TwoFixedUnion { - U8(u8), - U16(u16), - } - - #[derive(PartialEq, Debug, Encode, Decode)] - struct TwoFixedUnionStruct { - a: TwoFixedUnion, - } - - #[test] - fn two_fixed_union() { - let eight = TwoFixedUnion::U8(1); - let sixteen = TwoFixedUnion::U16(1); - - assert_encode_decode(&eight, &[0, 1]); - assert_encode_decode(&sixteen, &[1, 1, 0]); - - assert_encode_decode(&TwoFixedUnionStruct { a: eight }, &[4, 0, 0, 0, 0, 1]); - assert_encode_decode(&TwoFixedUnionStruct { a: sixteen }, &[4, 0, 0, 0, 1, 1, 0]); - } - - #[derive(PartialEq, Debug, Encode, Decode)] - struct VariableA { - a: u8, - b: Vec, - } - - #[derive(PartialEq, Debug, Encode, Decode)] - struct VariableB { - a: Vec, - b: u8, - } - - #[derive(PartialEq, Debug, Encode)] - #[ssz(enum_behaviour = "transparent")] - enum TwoVariableTrans { - A(VariableA), - B(VariableB), - } - - #[derive(PartialEq, Debug, Encode)] - struct TwoVariableTransStruct { - a: TwoVariableTrans, - } - - #[derive(PartialEq, Debug, Encode, Decode)] - #[ssz(enum_behaviour = "union")] - enum TwoVariableUnion { - A(VariableA), - B(VariableB), - } - - #[derive(PartialEq, Debug, Encode, Decode)] - struct TwoVariableUnionStruct { - a: TwoVariableUnion, - } - - #[test] - fn two_variable_trans() { - let trans_a = TwoVariableTrans::A(VariableA { - a: 1, - b: vec![2, 3], - }); - let trans_b = TwoVariableTrans::B(VariableB { - a: vec![1, 2], - b: 3, - }); - - assert_encode(&trans_a, &[1, 5, 0, 0, 0, 2, 3]); - assert_encode(&trans_b, &[5, 0, 0, 0, 3, 1, 2]); - - assert_encode( - &TwoVariableTransStruct { a: trans_a }, - &[4, 0, 0, 0, 1, 5, 0, 0, 0, 2, 3], - ); - assert_encode( - &TwoVariableTransStruct { a: trans_b }, - &[4, 0, 0, 0, 5, 0, 0, 0, 3, 1, 2], - ); - } - - #[test] - fn two_variable_union() { - let union_a = TwoVariableUnion::A(VariableA { - a: 1, - b: vec![2, 3], - }); - let union_b = TwoVariableUnion::B(VariableB { - a: vec![1, 2], - b: 3, - }); - - assert_encode_decode(&union_a, &[0, 1, 5, 0, 0, 0, 2, 3]); - assert_encode_decode(&union_b, &[1, 5, 0, 0, 0, 3, 1, 2]); - - assert_encode_decode( - &TwoVariableUnionStruct { a: union_a }, - &[4, 0, 0, 0, 0, 1, 5, 0, 0, 0, 2, 3], - ); - assert_encode_decode( - &TwoVariableUnionStruct { a: union_b }, - &[4, 0, 0, 0, 1, 5, 0, 0, 0, 3, 1, 2], - ); - } - - #[derive(PartialEq, Debug, Encode, Decode)] - #[ssz(enum_behaviour = "union")] - enum TwoVecUnion { - A(Vec), - B(Vec), - } - - #[test] - fn two_vec_union() { - assert_encode_decode(&TwoVecUnion::A(vec![]), &[0]); - assert_encode_decode(&TwoVecUnion::B(vec![]), &[1]); - - assert_encode_decode(&TwoVecUnion::A(vec![0]), &[0, 0]); - assert_encode_decode(&TwoVecUnion::B(vec![0]), &[1, 0]); - - assert_encode_decode(&TwoVecUnion::A(vec![0, 1]), &[0, 0, 1]); - assert_encode_decode(&TwoVecUnion::B(vec![0, 1]), &[1, 0, 1]); - } -} diff --git a/consensus/ssz_derive/Cargo.toml b/consensus/ssz_derive/Cargo.toml index cac617d3917..d3b2865a61d 100644 --- a/consensus/ssz_derive/Cargo.toml +++ b/consensus/ssz_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "eth2_ssz_derive" -version = "0.3.0" +version = "0.3.1" authors = ["Paul Hauner "] edition = "2021" description = "Procedural derive macros to accompany the eth2_ssz crate." @@ -15,3 +15,6 @@ syn = "1.0.42" proc-macro2 = "1.0.23" quote = "1.0.7" darling = "0.13.0" + +[dev-dependencies] +eth2_ssz = "0.4.1" diff --git a/consensus/ssz_derive/src/lib.rs b/consensus/ssz_derive/src/lib.rs index a5a5a0dddf2..9f8270e6dd5 100644 --- a/consensus/ssz_derive/src/lib.rs +++ b/consensus/ssz_derive/src/lib.rs @@ -1,23 +1,170 @@ #![recursion_limit = "256"] //! Provides procedural derive macros for the `Encode` and `Decode` traits of the `eth2_ssz` crate. //! -//! Supports field attributes, see each derive macro for more information. +//! ## Attributes +//! +//! The following struct/enum attributes are available: +//! +//! - `#[ssz(enum_behaviour = "union")]`: encodes and decodes an `enum` with a one-byte variant selector. +//! - `#[ssz(enum_behaviour = "transparent")]`: allows encoding an `enum` by serializing only the +//! value whilst ignoring outermost the `enum`. +//! - `#[ssz(struct_behaviour = "container")]`: encodes and decodes the `struct` as an SSZ +//! "container". +//! - `#[ssz(struct_behaviour = "transparent")]`: encodes and decodes a `struct` with exactly one +//! non-skipped field as if the outermost `struct` does not exist. +//! +//! The following field attributes are available: +//! +//! - `#[ssz(with = "module")]`: uses the methods in `module` to implement `ssz::Encode` and +//! `ssz::Decode`. This is useful when it's not possible to create an `impl` for that type +//! (e.g. the type is defined in another crate). +//! - `#[ssz(skip_serializing)]`: this field will not be included in the serialized SSZ vector. +//! - `#[ssz(skip_deserializing)]`: this field will not be expected in the serialized +//! SSZ vector and it will be initialized from a `Default` implementation. +//! +//! ## Examples +//! +//! ### Structs +//! +//! ```rust +//! use ssz::{Encode, Decode}; +//! use ssz_derive::{Encode, Decode}; +//! +//! /// Represented as an SSZ "list" wrapped in an SSZ "container". +//! #[derive(Debug, PartialEq, Encode, Decode)] +//! #[ssz(struct_behaviour = "container")] // "container" is the default behaviour +//! struct TypicalStruct { +//! foo: Vec +//! } +//! +//! assert_eq!( +//! TypicalStruct { foo: vec![42] }.as_ssz_bytes(), +//! vec![4, 0, 0, 0, 42] +//! ); +//! +//! assert_eq!( +//! TypicalStruct::from_ssz_bytes(&[4, 0, 0, 0, 42]).unwrap(), +//! TypicalStruct { foo: vec![42] }, +//! ); +//! +//! /// Represented as an SSZ "list" *without* an SSZ "container". +//! #[derive(Encode, Decode)] +//! #[ssz(struct_behaviour = "transparent")] +//! struct WrapperStruct { +//! foo: Vec +//! } +//! +//! assert_eq!( +//! WrapperStruct { foo: vec![42] }.as_ssz_bytes(), +//! vec![42] +//! ); +//! +//! /// Represented as an SSZ "list" *without* an SSZ "container". The `bar` byte is ignored. +//! #[derive(Debug, PartialEq, Encode, Decode)] +//! #[ssz(struct_behaviour = "transparent")] +//! struct WrapperStructSkippedField { +//! foo: Vec, +//! #[ssz(skip_serializing, skip_deserializing)] +//! bar: u8, +//! } +//! +//! assert_eq!( +//! WrapperStructSkippedField { foo: vec![42], bar: 99 }.as_ssz_bytes(), +//! vec![42] +//! ); +//! assert_eq!( +//! WrapperStructSkippedField::from_ssz_bytes(&[42]).unwrap(), +//! WrapperStructSkippedField { foo: vec![42], bar: 0 } +//! ); +//! +//! /// Represented as an SSZ "list" *without* an SSZ "container". +//! #[derive(Encode, Decode)] +//! #[ssz(struct_behaviour = "transparent")] +//! struct NewType(Vec); +//! +//! assert_eq!( +//! NewType(vec![42]).as_ssz_bytes(), +//! vec![42] +//! ); +//! +//! /// Represented as an SSZ "list" *without* an SSZ "container". The `bar` byte is ignored. +//! #[derive(Debug, PartialEq, Encode, Decode)] +//! #[ssz(struct_behaviour = "transparent")] +//! struct NewTypeSkippedField(Vec, #[ssz(skip_serializing, skip_deserializing)] u8); +//! +//! assert_eq!( +//! NewTypeSkippedField(vec![42], 99).as_ssz_bytes(), +//! vec![42] +//! ); +//! assert_eq!( +//! NewTypeSkippedField::from_ssz_bytes(&[42]).unwrap(), +//! NewTypeSkippedField(vec![42], 0) +//! ); +//! ``` +//! +//! ### Enums +//! +//! ```rust +//! use ssz::{Encode, Decode}; +//! use ssz_derive::{Encode, Decode}; +//! +//! /// Represented as an SSZ "union". +//! #[derive(Debug, PartialEq, Encode, Decode)] +//! #[ssz(enum_behaviour = "union")] +//! enum UnionEnum { +//! Foo(u8), +//! Bar(Vec), +//! } +//! +//! assert_eq!( +//! UnionEnum::Foo(42).as_ssz_bytes(), +//! vec![0, 42] +//! ); +//! assert_eq!( +//! UnionEnum::from_ssz_bytes(&[1, 42, 42]).unwrap(), +//! UnionEnum::Bar(vec![42, 42]), +//! ); +//! +//! /// Represented as only the value in the enum variant. +//! #[derive(Debug, PartialEq, Encode)] +//! #[ssz(enum_behaviour = "transparent")] +//! enum TransparentEnum { +//! Foo(u8), +//! Bar(Vec), +//! } +//! +//! assert_eq!( +//! TransparentEnum::Foo(42).as_ssz_bytes(), +//! vec![42] +//! ); +//! assert_eq!( +//! TransparentEnum::Bar(vec![42, 42]).as_ssz_bytes(), +//! vec![42, 42] +//! ); +//! ``` use darling::{FromDeriveInput, FromMeta}; use proc_macro::TokenStream; use quote::quote; use std::convert::TryInto; -use syn::{parse_macro_input, DataEnum, DataStruct, DeriveInput, Ident}; +use syn::{parse_macro_input, DataEnum, DataStruct, DeriveInput, Ident, Index}; /// The highest possible union selector value (higher values are reserved for backwards compatible /// extensions). const MAX_UNION_SELECTOR: u8 = 127; +const ENUM_TRANSPARENT: &str = "transparent"; +const ENUM_UNION: &str = "union"; +const NO_ENUM_BEHAVIOUR_ERROR: &str = "enums require an \"enum_behaviour\" attribute with \ + a \"transparent\" or \"union\" value, e.g., #[ssz(enum_behaviour = \"transparent\")]"; + #[derive(Debug, FromDeriveInput)] #[darling(attributes(ssz))] struct StructOpts { #[darling(default)] enum_behaviour: Option, + #[darling(default)] + struct_behaviour: Option, } /// Field-level configuration. @@ -31,40 +178,87 @@ struct FieldOpts { skip_deserializing: bool, } -const ENUM_TRANSPARENT: &str = "transparent"; -const ENUM_UNION: &str = "union"; -const ENUM_VARIANTS: &[&str] = &[ENUM_TRANSPARENT, ENUM_UNION]; -const NO_ENUM_BEHAVIOUR_ERROR: &str = "enums require an \"enum_behaviour\" attribute, \ - e.g., #[ssz(enum_behaviour = \"transparent\")]"; +enum Procedure<'a> { + Struct { + data: &'a syn::DataStruct, + behaviour: StructBehaviour, + }, + Enum { + data: &'a syn::DataEnum, + behaviour: EnumBehaviour, + }, +} -enum EnumBehaviour { +enum StructBehaviour { + Container, Transparent, +} + +enum EnumBehaviour { Union, + Transparent, } -impl EnumBehaviour { - pub fn new(s: Option) -> Option { - s.map(|s| match s.as_ref() { - ENUM_TRANSPARENT => EnumBehaviour::Transparent, - ENUM_UNION => EnumBehaviour::Union, - other => panic!( - "{} is an invalid enum_behaviour, use either {:?}", - other, ENUM_VARIANTS - ), - }) +impl<'a> Procedure<'a> { + fn read(item: &'a DeriveInput) -> Self { + let opts = StructOpts::from_derive_input(item).unwrap(); + + match &item.data { + syn::Data::Struct(data) => { + if opts.enum_behaviour.is_some() { + panic!("cannot use \"enum_behaviour\" for a struct"); + } + + match opts.struct_behaviour.as_deref() { + Some("container") | None => Procedure::Struct { + data, + behaviour: StructBehaviour::Container, + }, + Some("transparent") => Procedure::Struct { + data, + behaviour: StructBehaviour::Transparent, + }, + Some(other) => panic!( + "{} is not a valid struct behaviour, use \"container\" or \"transparent\"", + other + ), + } + } + syn::Data::Enum(data) => { + if opts.struct_behaviour.is_some() { + panic!("cannot use \"struct_behaviour\" for an enum"); + } + + match opts.enum_behaviour.as_deref() { + Some("union") => Procedure::Enum { + data, + behaviour: EnumBehaviour::Union, + }, + Some("transparent") => Procedure::Enum { + data, + behaviour: EnumBehaviour::Transparent, + }, + Some(other) => panic!( + "{} is not a valid enum behaviour, use \"container\" or \"transparent\"", + other + ), + None => panic!("{}", NO_ENUM_BEHAVIOUR_ERROR), + } + } + _ => panic!("ssz_derive only supports structs and enums"), + } } } -fn parse_ssz_fields(struct_data: &syn::DataStruct) -> Vec<(&syn::Type, &syn::Ident, FieldOpts)> { +fn parse_ssz_fields( + struct_data: &syn::DataStruct, +) -> Vec<(&syn::Type, Option<&syn::Ident>, FieldOpts)> { struct_data .fields .iter() .map(|field| { let ty = &field.ty; - let ident = match &field.ident { - Some(ref ident) => ident, - _ => panic!("ssz_derive only supports named struct fields."), - }; + let ident = field.ident.as_ref(); let field_opts_candidates = field .attrs @@ -93,21 +287,17 @@ fn parse_ssz_fields(struct_data: &syn::DataStruct) -> Vec<(&syn::Type, &syn::Ide #[proc_macro_derive(Encode, attributes(ssz))] pub fn ssz_encode_derive(input: TokenStream) -> TokenStream { let item = parse_macro_input!(input as DeriveInput); - let opts = StructOpts::from_derive_input(&item).unwrap(); - let enum_opt = EnumBehaviour::new(opts.enum_behaviour); + let procedure = Procedure::read(&item); - match &item.data { - syn::Data::Struct(s) => { - if enum_opt.is_some() { - panic!("enum_behaviour is invalid for structs"); - } - ssz_encode_derive_struct(&item, s) - } - syn::Data::Enum(s) => match enum_opt.expect(NO_ENUM_BEHAVIOUR_ERROR) { - EnumBehaviour::Transparent => ssz_encode_derive_enum_transparent(&item, s), - EnumBehaviour::Union => ssz_encode_derive_enum_union(&item, s), + match procedure { + Procedure::Struct { data, behaviour } => match behaviour { + StructBehaviour::Transparent => ssz_encode_derive_struct_transparent(&item, data), + StructBehaviour::Container => ssz_encode_derive_struct(&item, data), + }, + Procedure::Enum { data, behaviour } => match behaviour { + EnumBehaviour::Transparent => ssz_encode_derive_enum_transparent(&item, data), + EnumBehaviour::Union => ssz_encode_derive_enum_union(&item, data), }, - _ => panic!("ssz_derive only supports structs and enums"), } } @@ -132,6 +322,13 @@ fn ssz_encode_derive_struct(derive_input: &DeriveInput, struct_data: &DataStruct continue; } + let ident = match ident { + Some(ref ident) => ident, + _ => panic!( + "#[ssz(struct_behaviour = \"container\")] only supports named struct fields." + ), + }; + if let Some(module) = field_opts.with { let module = quote! { #module::encode }; field_is_ssz_fixed_len.push(quote! { #module::is_ssz_fixed_len() }); @@ -219,6 +416,86 @@ fn ssz_encode_derive_struct(derive_input: &DeriveInput, struct_data: &DataStruct output.into() } +/// Derive `ssz::Encode` "transparently" for a struct which has exactly one non-skipped field. +/// +/// The single field is encoded directly, making the outermost `struct` transparent. +/// +/// ## Field attributes +/// +/// - `#[ssz(skip_serializing)]`: the field will not be serialized. +fn ssz_encode_derive_struct_transparent( + derive_input: &DeriveInput, + struct_data: &DataStruct, +) -> TokenStream { + let name = &derive_input.ident; + let (impl_generics, ty_generics, where_clause) = &derive_input.generics.split_for_impl(); + let ssz_fields = parse_ssz_fields(struct_data); + let num_fields = ssz_fields + .iter() + .filter(|(_, _, field_opts)| !field_opts.skip_deserializing) + .count(); + + if num_fields != 1 { + panic!( + "A \"transparent\" struct must have exactly one non-skipped field ({} fields found)", + num_fields + ); + } + + let (index, (ty, ident, _field_opts)) = ssz_fields + .iter() + .enumerate() + .find(|(_, (_, _, field_opts))| !field_opts.skip_deserializing) + .expect("\"transparent\" struct must have at least one non-skipped field"); + + // Remove the `_usize` suffix from the value to avoid a compiler warning. + let index = Index::from(index); + + let output = if let Some(field_name) = ident { + quote! { + impl #impl_generics ssz::Encode for #name #ty_generics #where_clause { + fn is_ssz_fixed_len() -> bool { + <#ty as ssz::Encode>::is_ssz_fixed_len() + } + + fn ssz_fixed_len() -> usize { + <#ty as ssz::Encode>::ssz_fixed_len() + } + + fn ssz_bytes_len(&self) -> usize { + self.#field_name.ssz_bytes_len() + } + + fn ssz_append(&self, buf: &mut Vec) { + self.#field_name.ssz_append(buf) + } + } + } + } else { + quote! { + impl #impl_generics ssz::Encode for #name #ty_generics #where_clause { + fn is_ssz_fixed_len() -> bool { + <#ty as ssz::Encode>::is_ssz_fixed_len() + } + + fn ssz_fixed_len() -> usize { + <#ty as ssz::Encode>::ssz_fixed_len() + } + + fn ssz_bytes_len(&self) -> usize { + self.#index.ssz_bytes_len() + } + + fn ssz_append(&self, buf: &mut Vec) { + self.#index.ssz_append(buf) + } + } + } + }; + + output.into() +} + /// Derive `ssz::Encode` for an enum in the "transparent" method. /// /// The "transparent" method is distinct from the "union" method specified in the SSZ specification. @@ -367,24 +644,20 @@ fn ssz_encode_derive_enum_union(derive_input: &DeriveInput, enum_data: &DataEnum #[proc_macro_derive(Decode, attributes(ssz))] pub fn ssz_decode_derive(input: TokenStream) -> TokenStream { let item = parse_macro_input!(input as DeriveInput); - let opts = StructOpts::from_derive_input(&item).unwrap(); - let enum_opt = EnumBehaviour::new(opts.enum_behaviour); + let procedure = Procedure::read(&item); - match &item.data { - syn::Data::Struct(s) => { - if enum_opt.is_some() { - panic!("enum_behaviour is invalid for structs"); - } - ssz_decode_derive_struct(&item, s) - } - syn::Data::Enum(s) => match enum_opt.expect(NO_ENUM_BEHAVIOUR_ERROR) { + match procedure { + Procedure::Struct { data, behaviour } => match behaviour { + StructBehaviour::Transparent => ssz_decode_derive_struct_transparent(&item, data), + StructBehaviour::Container => ssz_decode_derive_struct(&item, data), + }, + Procedure::Enum { data, behaviour } => match behaviour { + EnumBehaviour::Union => ssz_decode_derive_enum_union(&item, data), EnumBehaviour::Transparent => panic!( "Decode cannot be derived for enum_behaviour \"{}\", only \"{}\" is valid.", ENUM_TRANSPARENT, ENUM_UNION ), - EnumBehaviour::Union => ssz_decode_derive_enum_union(&item, s), }, - _ => panic!("ssz_derive only supports structs and enums"), } } @@ -409,6 +682,13 @@ fn ssz_decode_derive_struct(item: &DeriveInput, struct_data: &DataStruct) -> Tok let mut fixed_lens = vec![]; for (ty, ident, field_opts) in parse_ssz_fields(struct_data) { + let ident = match ident { + Some(ref ident) => ident, + _ => panic!( + "#[ssz(struct_behaviour = \"container\")] only supports named struct fields." + ), + }; + field_names.push(quote! { #ident }); @@ -545,6 +825,90 @@ fn ssz_decode_derive_struct(item: &DeriveInput, struct_data: &DataStruct) -> Tok output.into() } +/// Implements `ssz::Decode` "transparently" for a `struct` with exactly one non-skipped field. +/// +/// The bytes will be decoded as if they are the inner field, without the outermost struct. The +/// outermost struct will then be applied artificially. +/// +/// ## Field attributes +/// +/// - `#[ssz(skip_deserializing)]`: during de-serialization the field will be instantiated from a +/// `Default` implementation. The decoder will assume that the field was not serialized at all +/// (e.g., if it has been serialized, an error will be raised instead of `Default` overriding it). +fn ssz_decode_derive_struct_transparent( + item: &DeriveInput, + struct_data: &DataStruct, +) -> TokenStream { + let name = &item.ident; + let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl(); + let ssz_fields = parse_ssz_fields(struct_data); + let num_fields = ssz_fields + .iter() + .filter(|(_, _, field_opts)| !field_opts.skip_deserializing) + .count(); + + if num_fields != 1 { + panic!( + "A \"transparent\" struct must have exactly one non-skipped field ({} fields found)", + num_fields + ); + } + + let mut fields = vec![]; + let mut wrapped_type = None; + + for (i, (ty, ident, field_opts)) in ssz_fields.into_iter().enumerate() { + if let Some(name) = ident { + if field_opts.skip_deserializing { + fields.push(quote! { + #name: <_>::default(), + }); + } else { + fields.push(quote! { + #name: <_>::from_ssz_bytes(bytes)?, + }); + wrapped_type = Some(ty); + } + } else { + let index = syn::Index::from(i); + if field_opts.skip_deserializing { + fields.push(quote! { + #index:<_>::default(), + }); + } else { + fields.push(quote! { + #index:<_>::from_ssz_bytes(bytes)?, + }); + wrapped_type = Some(ty); + } + } + } + + let ty = wrapped_type.unwrap(); + + let output = quote! { + impl #impl_generics ssz::Decode for #name #ty_generics #where_clause { + fn is_ssz_fixed_len() -> bool { + <#ty as ssz::Decode>::is_ssz_fixed_len() + } + + fn ssz_fixed_len() -> usize { + <#ty as ssz::Decode>::ssz_fixed_len() + } + + fn from_ssz_bytes(bytes: &[u8]) -> std::result::Result { + Ok(Self { + #( + #fields + )* + + }) + } + } + }; + output.into() +} + /// Derive `ssz::Decode` for an `enum` following the "union" SSZ spec. fn ssz_decode_derive_enum_union(derive_input: &DeriveInput, enum_data: &DataEnum) -> TokenStream { let name = &derive_input.ident; diff --git a/consensus/ssz_derive/tests/tests.rs b/consensus/ssz_derive/tests/tests.rs new file mode 100644 index 00000000000..040d2a34761 --- /dev/null +++ b/consensus/ssz_derive/tests/tests.rs @@ -0,0 +1,236 @@ +use ssz::{Decode, Encode}; +use ssz_derive::{Decode, Encode}; +use std::fmt::Debug; +use std::marker::PhantomData; + +fn assert_encode(item: &T, bytes: &[u8]) { + assert_eq!(item.as_ssz_bytes(), bytes); +} + +fn assert_encode_decode(item: &T, bytes: &[u8]) { + assert_encode(item, bytes); + assert_eq!(T::from_ssz_bytes(bytes).unwrap(), *item); +} + +#[derive(PartialEq, Debug, Encode, Decode)] +#[ssz(enum_behaviour = "union")] +enum TwoFixedUnion { + U8(u8), + U16(u16), +} + +#[derive(PartialEq, Debug, Encode, Decode)] +struct TwoFixedUnionStruct { + a: TwoFixedUnion, +} + +#[test] +fn two_fixed_union() { + let eight = TwoFixedUnion::U8(1); + let sixteen = TwoFixedUnion::U16(1); + + assert_encode_decode(&eight, &[0, 1]); + assert_encode_decode(&sixteen, &[1, 1, 0]); + + assert_encode_decode(&TwoFixedUnionStruct { a: eight }, &[4, 0, 0, 0, 0, 1]); + assert_encode_decode(&TwoFixedUnionStruct { a: sixteen }, &[4, 0, 0, 0, 1, 1, 0]); +} + +#[derive(PartialEq, Debug, Encode, Decode)] +struct VariableA { + a: u8, + b: Vec, +} + +#[derive(PartialEq, Debug, Encode, Decode)] +struct VariableB { + a: Vec, + b: u8, +} + +#[derive(PartialEq, Debug, Encode)] +#[ssz(enum_behaviour = "transparent")] +enum TwoVariableTrans { + A(VariableA), + B(VariableB), +} + +#[derive(PartialEq, Debug, Encode)] +struct TwoVariableTransStruct { + a: TwoVariableTrans, +} + +#[derive(PartialEq, Debug, Encode, Decode)] +#[ssz(enum_behaviour = "union")] +enum TwoVariableUnion { + A(VariableA), + B(VariableB), +} + +#[derive(PartialEq, Debug, Encode, Decode)] +struct TwoVariableUnionStruct { + a: TwoVariableUnion, +} + +#[test] +fn two_variable_trans() { + let trans_a = TwoVariableTrans::A(VariableA { + a: 1, + b: vec![2, 3], + }); + let trans_b = TwoVariableTrans::B(VariableB { + a: vec![1, 2], + b: 3, + }); + + assert_encode(&trans_a, &[1, 5, 0, 0, 0, 2, 3]); + assert_encode(&trans_b, &[5, 0, 0, 0, 3, 1, 2]); + + assert_encode( + &TwoVariableTransStruct { a: trans_a }, + &[4, 0, 0, 0, 1, 5, 0, 0, 0, 2, 3], + ); + assert_encode( + &TwoVariableTransStruct { a: trans_b }, + &[4, 0, 0, 0, 5, 0, 0, 0, 3, 1, 2], + ); +} + +#[test] +fn two_variable_union() { + let union_a = TwoVariableUnion::A(VariableA { + a: 1, + b: vec![2, 3], + }); + let union_b = TwoVariableUnion::B(VariableB { + a: vec![1, 2], + b: 3, + }); + + assert_encode_decode(&union_a, &[0, 1, 5, 0, 0, 0, 2, 3]); + assert_encode_decode(&union_b, &[1, 5, 0, 0, 0, 3, 1, 2]); + + assert_encode_decode( + &TwoVariableUnionStruct { a: union_a }, + &[4, 0, 0, 0, 0, 1, 5, 0, 0, 0, 2, 3], + ); + assert_encode_decode( + &TwoVariableUnionStruct { a: union_b }, + &[4, 0, 0, 0, 1, 5, 0, 0, 0, 3, 1, 2], + ); +} + +#[derive(PartialEq, Debug, Encode, Decode)] +#[ssz(enum_behaviour = "union")] +enum TwoVecUnion { + A(Vec), + B(Vec), +} + +#[test] +fn two_vec_union() { + assert_encode_decode(&TwoVecUnion::A(vec![]), &[0]); + assert_encode_decode(&TwoVecUnion::B(vec![]), &[1]); + + assert_encode_decode(&TwoVecUnion::A(vec![0]), &[0, 0]); + assert_encode_decode(&TwoVecUnion::B(vec![0]), &[1, 0]); + + assert_encode_decode(&TwoVecUnion::A(vec![0, 1]), &[0, 0, 1]); + assert_encode_decode(&TwoVecUnion::B(vec![0, 1]), &[1, 0, 1]); +} + +#[derive(PartialEq, Debug, Encode, Decode)] +#[ssz(struct_behaviour = "transparent")] +struct TransparentStruct { + inner: Vec, +} + +impl TransparentStruct { + fn new(inner: u8) -> Self { + Self { inner: vec![inner] } + } +} + +#[test] +fn transparent_struct() { + assert_encode_decode(&TransparentStruct::new(42), &vec![42_u8].as_ssz_bytes()); +} + +#[derive(PartialEq, Debug, Encode, Decode)] +#[ssz(struct_behaviour = "transparent")] +struct TransparentStructSkippedField { + inner: Vec, + #[ssz(skip_serializing, skip_deserializing)] + skipped: PhantomData, +} + +impl TransparentStructSkippedField { + fn new(inner: u8) -> Self { + Self { + inner: vec![inner], + skipped: PhantomData, + } + } +} + +#[test] +fn transparent_struct_skipped_field() { + assert_encode_decode( + &TransparentStructSkippedField::new(42), + &vec![42_u8].as_ssz_bytes(), + ); +} + +#[derive(PartialEq, Debug, Encode, Decode)] +#[ssz(struct_behaviour = "transparent")] +struct TransparentStructNewType(Vec); + +#[test] +fn transparent_struct_newtype() { + assert_encode_decode( + &TransparentStructNewType(vec![42_u8]), + &vec![42_u8].as_ssz_bytes(), + ); +} + +#[derive(PartialEq, Debug, Encode, Decode)] +#[ssz(struct_behaviour = "transparent")] +struct TransparentStructNewTypeSkippedField( + Vec, + #[ssz(skip_serializing, skip_deserializing)] PhantomData, +); + +impl TransparentStructNewTypeSkippedField { + fn new(inner: Vec) -> Self { + Self(inner, PhantomData) + } +} + +#[test] +fn transparent_struct_newtype_skipped_field() { + assert_encode_decode( + &TransparentStructNewTypeSkippedField::new(vec![42_u8]), + &vec![42_u8].as_ssz_bytes(), + ); +} + +#[derive(PartialEq, Debug, Encode, Decode)] +#[ssz(struct_behaviour = "transparent")] +struct TransparentStructNewTypeSkippedFieldReverse( + #[ssz(skip_serializing, skip_deserializing)] PhantomData, + Vec, +); + +impl TransparentStructNewTypeSkippedFieldReverse { + fn new(inner: Vec) -> Self { + Self(PhantomData, inner) + } +} + +#[test] +fn transparent_struct_newtype_skipped_field_reverse() { + assert_encode_decode( + &TransparentStructNewTypeSkippedFieldReverse::new(vec![42_u8]), + &vec![42_u8].as_ssz_bytes(), + ); +} diff --git a/consensus/ssz_types/Cargo.toml b/consensus/ssz_types/Cargo.toml index 2baa8994fb8..a2408ff2c41 100644 --- a/consensus/ssz_types/Cargo.toml +++ b/consensus/ssz_types/Cargo.toml @@ -19,6 +19,8 @@ typenum = "1.12.0" arbitrary = { version = "1.0", features = ["derive"], optional = true } derivative = "2.1.1" smallvec = "1.8.0" +base64 = "0.20.0" +serde_with = { version = "1.0.116", features = ["base64"] } [dev-dependencies] serde_json = "1.0.58" diff --git a/consensus/ssz_types/src/serde_utils/base64_fixed_vec.rs b/consensus/ssz_types/src/serde_utils/base64_fixed_vec.rs new file mode 100644 index 00000000000..7e2e523c8e8 --- /dev/null +++ b/consensus/ssz_types/src/serde_utils/base64_fixed_vec.rs @@ -0,0 +1,27 @@ +//! Serialize `FixedVec` as a base64 string. +use crate::FixedVector; +use base64; +use serde::{Deserializer, Serializer}; +use serde_with::{ + base64::{Base64, Standard}, + DeserializeAs, +}; +use typenum::Unsigned; + +pub fn serialize(bytes: &FixedVector, serializer: S) -> Result +where + S: Serializer, + U: Unsigned, +{ + serializer.serialize_str(&base64::encode(&bytes[..])) +} + +pub fn deserialize<'de, D, U>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, + U: Unsigned, +{ + let vec = Base64::::deserialize_as(deserializer)?; + FixedVector::new(vec) + .map_err(|e| serde::de::Error::custom(format!("invalid fixed vector: {:?}", e))) +} diff --git a/consensus/ssz_types/src/serde_utils/base64_var_list.rs b/consensus/ssz_types/src/serde_utils/base64_var_list.rs new file mode 100644 index 00000000000..48c2b847be2 --- /dev/null +++ b/consensus/ssz_types/src/serde_utils/base64_var_list.rs @@ -0,0 +1,27 @@ +//! Serialize `VariableList` as a base64 string. +use crate::VariableList; +use base64; +use serde::{Deserializer, Serializer}; +use serde_with::{ + base64::{Base64, Standard}, + DeserializeAs, +}; +use typenum::Unsigned; + +pub fn serialize(bytes: &VariableList, serializer: S) -> Result +where + S: Serializer, + N: Unsigned, +{ + serializer.serialize_str(&base64::encode(&**bytes)) +} + +pub fn deserialize<'de, D, N>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, + N: Unsigned, +{ + let bytes = Base64::::deserialize_as(deserializer)?; + VariableList::new(bytes) + .map_err(|e| serde::de::Error::custom(format!("invalid variable list: {:?}", e))) +} diff --git a/consensus/ssz_types/src/serde_utils/mod.rs b/consensus/ssz_types/src/serde_utils/mod.rs index cd6d49cc856..275d362aa5a 100644 --- a/consensus/ssz_types/src/serde_utils/mod.rs +++ b/consensus/ssz_types/src/serde_utils/mod.rs @@ -1,3 +1,5 @@ +pub mod base64_fixed_vec; +pub mod base64_var_list; pub mod hex_fixed_vec; pub mod hex_var_list; pub mod list_of_hex_var_list; diff --git a/consensus/state_processing/Cargo.toml b/consensus/state_processing/Cargo.toml index 46ac2bae577..ccb41830be8 100644 --- a/consensus/state_processing/Cargo.toml +++ b/consensus/state_processing/Cargo.toml @@ -14,7 +14,7 @@ bls = { path = "../../crypto/bls" } integer-sqrt = "0.1.5" itertools = "0.10.0" eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" eth2_ssz_types = "0.2.2" merkle_proof = { path = "../merkle_proof" } safe_arith = { path = "../safe_arith" } diff --git a/consensus/tree_hash/Cargo.toml b/consensus/tree_hash/Cargo.toml index 731e2f177e5..b2630d4bf60 100644 --- a/consensus/tree_hash/Cargo.toml +++ b/consensus/tree_hash/Cargo.toml @@ -12,7 +12,7 @@ tree_hash_derive = "0.4.0" types = { path = "../types" } beacon_chain = { path = "../../beacon_node/beacon_chain" } eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" [dependencies] ethereum-types = "0.14.1" diff --git a/consensus/tree_hash/src/impls.rs b/consensus/tree_hash/src/impls.rs index cf05d2a3d5a..8a0f35c92a1 100644 --- a/consensus/tree_hash/src/impls.rs +++ b/consensus/tree_hash/src/impls.rs @@ -166,6 +166,31 @@ impl TreeHash for H256 { } } +impl TreeHash for Option +where + T: TreeHash, +{ + fn tree_hash_type() -> TreeHashType { + TreeHashType::Container + } + + fn tree_hash_packed_encoding(&self) -> PackedEncoding { + unreachable!("Option should never be packed") + } + + fn tree_hash_packing_factor() -> usize { + unreachable!("Option should never be packed") + } + + fn tree_hash_root(&self) -> Hash256 { + let (selector, root) = match self { + None => (0, Hash256::zero()), + Some(t) => (1, t.tree_hash_root()), + }; + mix_in_selector(&root, selector).expect("an option cannot overflow the selector") + } +} + #[cfg(test)] mod test { use super::*; @@ -199,4 +224,16 @@ mod test { ] ); } + + #[test] + fn option() { + assert_eq!( + None::.tree_hash_root(), + mix_in_selector(&Hash256::zero(), 0).unwrap() + ); + assert_eq!( + Some(42_u64).tree_hash_root(), + mix_in_selector(&42_u64.tree_hash_root(), 1).unwrap() + ); + } } diff --git a/consensus/types/Cargo.toml b/consensus/types/Cargo.toml index 6ae185f7fff..a63993ebcf9 100644 --- a/consensus/types/Cargo.toml +++ b/consensus/types/Cargo.toml @@ -26,7 +26,7 @@ serde = {version = "1.0.116" , features = ["rc"] } serde_derive = "1.0.116" slog = "2.5.2" eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" eth2_ssz_types = "0.2.2" swap_or_not_shuffle = { path = "../swap_or_not_shuffle" } test_random_derive = { path = "../../common/test_random_derive" } diff --git a/consensus/types/src/eth_spec.rs b/consensus/types/src/eth_spec.rs index e6169760264..fd58222478b 100644 --- a/consensus/types/src/eth_spec.rs +++ b/consensus/types/src/eth_spec.rs @@ -3,8 +3,8 @@ use crate::*; use safe_arith::SafeArith; use serde_derive::{Deserialize, Serialize}; use ssz_types::typenum::{ - bit::B0, UInt, Unsigned, U0, U1024, U1048576, U1073741824, U1099511627776, U128, U16, - U16777216, U2, U2048, U256, U32, U4, U4096, U512, U625, U64, U65536, U8, U8192, + bit::B0, Prod, UInt, Unsigned, U0, U1024, U1048576, U1073741824, U1099511627776, U128, U16, + U16777216, U2, U2048, U256, U31, U32, U33, U4, U4096, U512, U625, U64, U65536, U8, U8192, }; use std::fmt::{self, Debug}; use std::str::FromStr; @@ -113,6 +113,18 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + /// Must be set to `SyncCommitteeSize / SyncCommitteeSubnetCount`. type SyncSubcommitteeSize: Unsigned + Clone + Sync + Send + Debug + PartialEq; + /* + * New in Verkle + */ + type BytesPerBandersnatchElement: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type MaxStems: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type MaxStemLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type MaxCommittmentsPerStem: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type MaxCommittments: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type BytesPerSuffixStateDiffValue: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type MaxVerkleWidth: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type IpaProofDepth: Unsigned + Clone + Sync + Send + Debug + PartialEq; + fn default_spec() -> ChainSpec; fn spec_name() -> EthSpecId; @@ -265,6 +277,14 @@ impl EthSpec for MainnetEthSpec { type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch + type BytesPerBandersnatchElement = U32; + type MaxStems = U65536; + type MaxStemLength = U31; + type MaxCommittmentsPerStem = U33; + type MaxCommittments = Prod; + type BytesPerSuffixStateDiffValue = U32; + type MaxVerkleWidth = U256; + type IpaProofDepth = U8; fn default_spec() -> ChainSpec { ChainSpec::mainnet() @@ -309,7 +329,15 @@ impl EthSpec for MinimalEthSpec { BytesPerLogsBloom, GasLimitDenominator, MinGasLimit, - MaxExtraDataBytes + MaxExtraDataBytes, + BytesPerBandersnatchElement, + MaxStems, + MaxStemLength, + MaxCommittmentsPerStem, + MaxCommittments, + BytesPerSuffixStateDiffValue, + MaxVerkleWidth, + IpaProofDepth }); fn default_spec() -> ChainSpec { @@ -354,6 +382,15 @@ impl EthSpec for GnosisEthSpec { type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count type MaxPendingAttestations = U2048; // 128 max attestations * 16 slots per epoch type SlotsPerEth1VotingPeriod = U1024; // 64 epochs * 16 slots per epoch + type BytesPerBandersnatchElement = U32; + type MaxStems = U65536; + type MaxStemLength = U31; + type MaxCommittmentsPerStem = U33; + type MaxCommittments = Prod; + //type MaxCommittments = U4194304; + type BytesPerSuffixStateDiffValue = U32; + type MaxVerkleWidth = U256; + type IpaProofDepth = U8; fn default_spec() -> ChainSpec { ChainSpec::gnosis() diff --git a/consensus/types/src/execution_block_hash.rs b/consensus/types/src/execution_block_hash.rs index 988dcece5e8..2a1e28c1da9 100644 --- a/consensus/types/src/execution_block_hash.rs +++ b/consensus/types/src/execution_block_hash.rs @@ -10,7 +10,7 @@ use std::fmt; #[derive(Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash, Derivative)] #[derivative(Debug = "transparent")] #[serde(transparent)] -pub struct ExecutionBlockHash(Hash256); +pub struct ExecutionBlockHash(pub Hash256); impl ExecutionBlockHash { pub fn zero() -> Self { diff --git a/consensus/types/src/execution_payload.rs b/consensus/types/src/execution_payload.rs index 412e5a8df3a..efac73ed94f 100644 --- a/consensus/types/src/execution_payload.rs +++ b/consensus/types/src/execution_payload.rs @@ -41,6 +41,7 @@ pub struct ExecutionPayload { pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] pub transactions: Transactions, + pub execution_witness: ExecutionWitness, } impl ExecutionPayload { diff --git a/consensus/types/src/execution_payload_header.rs b/consensus/types/src/execution_payload_header.rs index 01780fa1c32..bbb6522d911 100644 --- a/consensus/types/src/execution_payload_header.rs +++ b/consensus/types/src/execution_payload_header.rs @@ -11,6 +11,7 @@ use tree_hash_derive::TreeHash; Default, Debug, Clone, Serialize, Deserialize, Derivative, Encode, Decode, TreeHash, TestRandom, )] #[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] pub struct ExecutionPayloadHeader { pub parent_hash: ExecutionBlockHash, pub fee_recipient: Address, @@ -33,6 +34,7 @@ pub struct ExecutionPayloadHeader { pub base_fee_per_gas: Uint256, pub block_hash: ExecutionBlockHash, pub transactions_root: Hash256, + pub execution_witness_root: Hash256,//ExecutionWitness, } impl ExecutionPayloadHeader { @@ -58,6 +60,7 @@ impl<'a, T: EthSpec> From<&'a ExecutionPayload> for ExecutionPayloadHeader base_fee_per_gas: payload.base_fee_per_gas, block_hash: payload.block_hash, transactions_root: payload.transactions.tree_hash_root(), + execution_witness_root: payload.execution_witness.tree_hash_root(), } } } diff --git a/consensus/types/src/execution_witness.rs b/consensus/types/src/execution_witness.rs new file mode 100644 index 00000000000..87300012c4f --- /dev/null +++ b/consensus/types/src/execution_witness.rs @@ -0,0 +1,143 @@ +use crate::{test_utils::TestRandom, *}; +use derivative::Derivative; +use serde_derive::{Deserialize, Serialize}; +use ssz_derive::{Decode, Encode}; +use test_random_derive::TestRandom; +use tree_hash_derive::TreeHash; + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[ssz(struct_behaviour = "transparent")] +#[serde(transparent)] +pub struct BandersnatchGroupElement { + #[serde(with = "ssz_types::serde_utils::hex_fixed_vec")] + inner: FixedVector, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[ssz(struct_behaviour = "transparent")] +#[serde(transparent)] +pub struct BandersnatchFieldElement { + #[serde(with = "ssz_types::serde_utils::hex_fixed_vec")] + inner: FixedVector, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[ssz(struct_behaviour = "transparent")] +#[serde(transparent)] +pub struct Stem { + #[serde(with = "ssz_types::serde_utils::hex_fixed_vec")] + inner: FixedVector, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[ssz(struct_behaviour = "transparent")] +#[serde(transparent)] +pub struct StateDiffValue { + #[serde(with = "ssz_types::serde_utils::hex_fixed_vec")] + inner: FixedVector, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[serde(rename_all = "camelCase")] +pub struct SuffixStateDiff { + //#[serde(with = "eth2_serde_utils::quoted_u8")] + suffix: u8, + // `None` means not currently present. + current_value: Option>, + // `None` means value is not updated. + // Not present for the Kaustinen testnet. + //new_value: Option>, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[serde(rename_all = "camelCase")] +pub struct StemStateDiff { + stem: Stem, + suffix_diffs: VariableList, T::MaxVerkleWidth>, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[ssz(struct_behaviour = "transparent")] +#[serde(transparent)] +pub struct StateDiff { + inner: VariableList, T::MaxStems>, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[serde(rename_all = "camelCase")] +pub struct IpaProof { + cl: FixedVector, T::IpaProofDepth>, + cr: FixedVector, T::IpaProofDepth>, + final_evaluation: BandersnatchFieldElement, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[ssz(struct_behaviour = "transparent")] +#[serde(transparent)] +pub struct StemValue { + #[serde(with = "ssz_types::serde_utils::hex_fixed_vec")] + inner: FixedVector, +} + +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[serde(rename_all = "camelCase")] +pub struct VerkleProof { + other_stems: VariableList, T::MaxStems>, + #[serde(with = "ssz_types::serde_utils::hex_var_list")] + depth_extension_present: VariableList, + commitments_by_path: VariableList, T::MaxCommittments>, + d: BandersnatchGroupElement, + ipa_proof: IpaProof, +} + +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] +#[derive( + Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative, +)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +#[serde(bound = "T: EthSpec")] +#[serde(rename_all = "camelCase")] +pub struct ExecutionWitness { + state_diff: StateDiff, + verkle_proof: VerkleProof, +} diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index 87f5ebe8b3c..66f6850b8a2 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -43,6 +43,7 @@ pub mod eth_spec; pub mod execution_block_hash; pub mod execution_payload; pub mod execution_payload_header; +pub mod execution_witness; pub mod fork; pub mod fork_data; pub mod fork_name; @@ -131,6 +132,7 @@ pub use crate::execution_block_hash::ExecutionBlockHash; pub use crate::execution_block_header::ExecutionBlockHeader; pub use crate::execution_payload::{ExecutionPayload, Transaction, Transactions}; pub use crate::execution_payload_header::ExecutionPayloadHeader; +pub use crate::execution_witness::ExecutionWitness; pub use crate::fork::Fork; pub use crate::fork_context::ForkContext; pub use crate::fork_data::ForkData; diff --git a/consensus/types/src/test_utils/test_random.rs b/consensus/types/src/test_utils/test_random.rs index 43396dedc0d..4c84ee570e7 100644 --- a/consensus/types/src/test_utils/test_random.rs +++ b/consensus/types/src/test_utils/test_random.rs @@ -86,6 +86,18 @@ where } } +impl TestRandom for Option +where + T: TestRandom, +{ + fn random_for_test(rng: &mut impl RngCore) -> Self { + match bool::random_for_test(rng) { + false => None, + true => Some(T::random_for_test(rng)), + } + } +} + impl TestRandom for FixedVector where T: TestRandom, diff --git a/lcli/Cargo.toml b/lcli/Cargo.toml index 93e529755d7..ab7bc43dfa7 100644 --- a/lcli/Cargo.toml +++ b/lcli/Cargo.toml @@ -21,6 +21,7 @@ types = { path = "../consensus/types" } state_processing = { path = "../consensus/state_processing" } int_to_bytes = { path = "../consensus/int_to_bytes" } eth2_ssz = "0.4.1" +eth2_hashing = "0.3.0" environment = { path = "../lighthouse/environment" } eth2_network_config = { path = "../common/eth2_network_config" } genesis = { path = "../beacon_node/genesis" } diff --git a/lcli/src/generate_ssz.rs b/lcli/src/generate_ssz.rs new file mode 100644 index 00000000000..32951ed3c43 --- /dev/null +++ b/lcli/src/generate_ssz.rs @@ -0,0 +1,54 @@ +use clap::ArgMatches; +use serde::{Deserialize, Serialize}; +use ssz::Encode; +use std::fs; +use std::fs::File; +use std::io::Write; +use std::path::Path; +use types::*; + +#[derive(Serialize, Deserialize)] +#[serde(bound = "T: EthSpec")] +#[serde(untagged)] +#[allow(clippy::large_enum_variant)] +enum SszType { + BaseState(BeaconStateBase), + AltairState(BeaconStateAltair), + BellatrixState(BeaconStateMerge), + BaseBlock(BeaconBlockBase), + AltairBlock(BeaconBlockAltair), + BellatrixBlock(BeaconBlockMerge), +} + +pub fn run_parse_json(matches: &ArgMatches) -> Result<(), String> { + let file_path = Path::new(matches.value_of("file").ok_or("No file supplied")?); + let output_path = Path::new( + matches + .value_of("output") + .ok_or("No output file supplied")?, + ); + + let data = fs::read_to_string(file_path).expect("Unable to read file"); + + let ssz_type: SszType = serde_json::from_str(&data).unwrap_or_else(|_| { + serde_yaml::from_str(&data) + .map_err(|_| "Unable to parse as either JSON or YAML".to_string()) + })?; + + let bytes = match ssz_type { + SszType::BaseState(bases) => bases.as_ssz_bytes(), + SszType::AltairState(altairs) => altairs.as_ssz_bytes(), + SszType::BellatrixState(bellatrixs) => bellatrixs.as_ssz_bytes(), + SszType::BaseBlock(baseb) => baseb.as_ssz_bytes(), + SszType::AltairBlock(altairb) => altairb.as_ssz_bytes(), + SszType::BellatrixBlock(bellatrixb) => bellatrixb.as_ssz_bytes(), + }; + + let mut output = + File::create(output_path).map_err(|e| format!("Error creating output file: {}", e))?; + output + .write_all(&bytes) + .map_err(|e| format!("Error writing to output to file: {}", e))?; + + Ok(()) +} diff --git a/lcli/src/main.rs b/lcli/src/main.rs index 137a4534b46..8415d3ef54f 100644 --- a/lcli/src/main.rs +++ b/lcli/src/main.rs @@ -7,6 +7,7 @@ mod create_payload_header; mod deploy_deposit_contract; mod eth1_genesis; mod generate_bootnode_enr; +mod generate_ssz; mod indexed_attestations; mod insecure_validators; mod interop_genesis; @@ -19,6 +20,7 @@ mod transition_blocks; use clap::{App, Arg, ArgMatches, SubCommand}; use clap_utils::parse_path_with_default_in_home_dir; use environment::{EnvironmentBuilder, LoggerConfig}; +use generate_ssz::run_parse_json; use parse_ssz::run_parse_ssz; use std::path::PathBuf; use std::process; @@ -201,6 +203,28 @@ fn main() { the block."), ) ) + .subcommand( + SubCommand::with_name("generate-ssz") + .about("Generates the corresponding SSZ from JSON-encoded data in a file") + .arg( + Arg::with_name("file") + .short("f") + .long("file") + .value_name("FILE") + .takes_value(true) + .required(true) + .help("Path of the file containing the JSON-encoded data") + ) + .arg( + Arg::with_name("output") + .short("o") + .long("output") + .value_name("FILE") + .takes_value(true) + .required(true) + .help("Path of the file to write the SSZ to") + ) + ) .subcommand( SubCommand::with_name("pretty-ssz") .about("Parses SSZ-encoded data from a file") @@ -559,14 +583,23 @@ fn main() { ), ) .arg( - Arg::with_name("merge-fork-epoch") - .long("merge-fork-epoch") + Arg::with_name("bellatrix-fork-epoch") + .long("bellatrix-fork-epoch") .value_name("EPOCH") .takes_value(true) .help( "The epoch at which to enable the Merge hard fork", ), ) + .arg( + Arg::with_name("ttd") + .long("ttd") + .value_name("TTD") + .takes_value(true) + .help( + "The terminal total difficulty", + ), + ) .arg( Arg::with_name("eth1-block-hash") .long("eth1-block-hash") @@ -816,6 +849,9 @@ fn run( ("skip-slots", Some(matches)) => { skip_slots::run::(env, matches).map_err(|e| format!("Failed to skip slots: {}", e)) } + ("generate-ssz", Some(matches)) => { + run_parse_json::(matches).map_err(|e| format!("Failed to generate ssz: {}", e)) + } ("pretty-ssz", Some(matches)) => { run_parse_ssz::(matches).map_err(|e| format!("Failed to pretty print hex: {}", e)) } diff --git a/lcli/src/new_testnet.rs b/lcli/src/new_testnet.rs index b2760829cb8..f1f599fa316 100644 --- a/lcli/src/new_testnet.rs +++ b/lcli/src/new_testnet.rs @@ -1,15 +1,20 @@ use clap::ArgMatches; use clap_utils::{parse_optional, parse_required, parse_ssz_optional}; +use eth2_hashing::hash; use eth2_network_config::Eth2NetworkConfig; -use genesis::interop_genesis_state; use ssz::Decode; use ssz::Encode; +use state_processing::process_activations; +use state_processing::upgrade::{upgrade_to_altair, upgrade_to_bellatrix}; use std::fs::File; use std::io::Read; use std::path::PathBuf; +use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; +use types::ExecutionBlockHash; use types::{ - test_utils::generate_deterministic_keypairs, Address, Config, EthSpec, ExecutionPayloadHeader, + test_utils::generate_deterministic_keypairs, Address, BeaconState, ChainSpec, Config, Eth1Data, + EthSpec, ExecutionPayloadHeader, Hash256, Keypair, PublicKey, Validator, }; pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Result<(), String> { @@ -66,10 +71,14 @@ pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul spec.altair_fork_epoch = Some(fork_epoch); } - if let Some(fork_epoch) = parse_optional(matches, "merge-fork-epoch")? { + if let Some(fork_epoch) = parse_optional(matches, "bellatrix-fork-epoch")? { spec.bellatrix_fork_epoch = Some(fork_epoch); } + if let Some(ttd) = parse_optional(matches, "ttd")? { + spec.terminal_total_difficulty = ttd; + } + let genesis_state_bytes = if matches.is_present("interop-genesis-state") { let execution_payload_header: Option> = parse_optional(matches, "execution-payload-header")? @@ -109,7 +118,7 @@ pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul let keypairs = generate_deterministic_keypairs(validator_count); - let genesis_state = interop_genesis_state::( + let genesis_state = initialize_state_with_validators::( &keypairs, genesis_time, eth1_block_hash.into_root(), @@ -131,3 +140,104 @@ pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul testnet.write_to_file(testnet_dir_path, overwrite_files) } + +/// Returns a `BeaconState` with the given validator keypairs embedded into the +/// genesis state. This allows us to start testnets without having to deposit validators +/// manually. +/// +/// The optional `execution_payload_header` allows us to start a network from the bellatrix +/// fork without the need to transition to altair and bellatrix. +/// +/// We need to ensure that `eth1_block_hash` is equal to the genesis block hash that is +/// generated from the execution side `genesis.json`. +fn initialize_state_with_validators( + keypairs: &[Keypair], + genesis_time: u64, + eth1_block_hash: Hash256, + execution_payload_header: Option>, + spec: &ChainSpec, +) -> Result, String> { + let default_header: ExecutionPayloadHeader = ExecutionPayloadHeader { + block_hash: ExecutionBlockHash(eth1_block_hash), + parent_hash: ExecutionBlockHash::zero(), + ..ExecutionPayloadHeader::default() + }; + let execution_payload_header = execution_payload_header.or(Some(default_header)); + // Empty eth1 data + let eth1_data = Eth1Data { + block_hash: eth1_block_hash, + deposit_count: 0, + deposit_root: Hash256::from_str( + "0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e", + ) + .unwrap(), // empty deposit tree root + }; + let mut state = BeaconState::new(genesis_time, eth1_data, spec); + + // Seed RANDAO with Eth1 entropy + state.fill_randao_mixes_with(eth1_block_hash); + + for keypair in keypairs.iter() { + let withdrawal_credentials = |pubkey: &PublicKey| { + let mut credentials = hash(&pubkey.as_ssz_bytes()); + credentials[0] = spec.bls_withdrawal_prefix_byte; + Hash256::from_slice(&credentials) + }; + let amount = spec.max_effective_balance; + // Create a new validator. + let validator = Validator { + pubkey: keypair.pk.clone().into(), + withdrawal_credentials: withdrawal_credentials(&keypair.pk), + activation_eligibility_epoch: spec.far_future_epoch, + activation_epoch: spec.far_future_epoch, + exit_epoch: spec.far_future_epoch, + withdrawable_epoch: spec.far_future_epoch, + effective_balance: std::cmp::min( + amount - amount % (spec.effective_balance_increment), + spec.max_effective_balance, + ), + slashed: false, + }; + state.validators_mut().push(validator).unwrap(); + state.balances_mut().push(amount).unwrap(); + } + + process_activations(&mut state, spec).unwrap(); + + if spec + .altair_fork_epoch + .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) + { + upgrade_to_altair(&mut state, spec).unwrap(); + + state.fork_mut().previous_version = spec.altair_fork_version; + } + + // Similarly, perform an upgrade to the merge if configured from genesis. + if spec + .bellatrix_fork_epoch + .map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch()) + { + upgrade_to_bellatrix(&mut state, spec).unwrap(); + + // Remove intermediate Altair fork from `state.fork`. + state.fork_mut().previous_version = spec.bellatrix_fork_version; + + // Override latest execution payload header. + // See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/beacon-chain.md#testing + + if let Some(ref header) = execution_payload_header { + *state.latest_execution_payload_header_mut().map_err(|_| { + "State must contain bellatrix execution payload header".to_string() + })? = header.clone(); + } + } + + // Now that we have our validators, initialize the caches (including the committees) + state.build_all_caches(spec).unwrap(); + + // Set genesis validators root for domain separation and chain versioning + *state.genesis_validators_root_mut() = state.update_validators_tree_hash_cache().unwrap(); + + Ok(state) +} diff --git a/scripts/local_testnet/beacon_node.sh b/scripts/local_testnet/beacon_node.sh index ac61b54dfb3..3738a05e8ae 100755 --- a/scripts/local_testnet/beacon_node.sh +++ b/scripts/local_testnet/beacon_node.sh @@ -30,6 +30,8 @@ while getopts "d:sh" flag; do echo " DATADIR Value for --datadir parameter" echo " NETWORK-PORT Value for --enr-udp-port, --enr-tcp-port and --port" echo " HTTP-PORT Value for --http-port" + echo " EXECUTION-ENDPOINT Value for --execution-endpoint" + echo " EXECUTION-JWT Value for --execution-jwt" exit ;; esac @@ -39,8 +41,12 @@ done data_dir=${@:$OPTIND+0:1} network_port=${@:$OPTIND+1:1} http_port=${@:$OPTIND+2:1} +execution_endpoint=${@:$OPTIND+3:1} +execution_jwt=${@:$OPTIND+4:1} -exec lighthouse \ +lighthouse_binary=lighthouse + +exec $lighthouse_binary \ --debug-level $DEBUG_LEVEL \ bn \ $SUBSCRIBE_ALL_SUBNETS \ @@ -54,4 +60,6 @@ exec lighthouse \ --port $network_port \ --http-port $http_port \ --disable-packet-filter \ - --target-peers $((BN_COUNT - 1)) + --target-peers $((BN_COUNT - 1)) \ + --execution-endpoint $execution_endpoint \ + --execution-jwt $execution_jwt diff --git a/scripts/local_testnet/el_bootnode.sh b/scripts/local_testnet/el_bootnode.sh new file mode 100755 index 00000000000..332610d84d9 --- /dev/null +++ b/scripts/local_testnet/el_bootnode.sh @@ -0,0 +1,4 @@ +priv_key="02fd74636e96a8ffac8e7b01b0de8dea94d6bcf4989513b38cf59eb32163ff91" + + +bootnode --nodekeyhex $priv_key diff --git a/scripts/local_testnet/genesis.json b/scripts/local_testnet/genesis.json new file mode 100644 index 00000000000..c650197fa62 --- /dev/null +++ b/scripts/local_testnet/genesis.json @@ -0,0 +1,854 @@ +{ + "config": { + "chainId": 4242, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "cancunBlock": 0, + "mergeForkBlock": 0, + "terminalTotalDifficulty": 0 + }, + "alloc": { + "0xf3c4A483ca812fE2e6ABFBd5d74b4b6a1Fb6B21C": { + "balance": "1000000000000000000000000000" + }, + "0x0000000000000000000000000000000000000000": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000005": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000006": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000007": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000008": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000009": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "1" + }, + "0x4242424242424242424242424242424242424242": { + "balance": "0", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0x9a4aa7d9C2F6386e5F24d790eB2FFB9fd543A170": { + "balance": "1000000000000000000000000000" + }, + "0x5E3141B900ac5f5608b0d057D10d45a0e4927cD9": { + "balance": "1000000000000000000000000000" + }, + "0x7cF5Dbc49F0904065664b5B6C0d69CaB55F33988": { + "balance": "1000000000000000000000000000" + }, + "0x8D12b071A6F3823A535D38C4a583a2FA1859e822": { + "balance": "1000000000000000000000000000" + }, + "0x3B575D3cda6b30736A38B031E0d245E646A21135": { + "balance": "1000000000000000000000000000" + }, + "0x53bDe6CF93461674F590E532006b4022dA57A724": { + "balance": "1000000000000000000000000000" + } + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x01", + "extraData": "", + "gasLimit": "0x400000", + "nonce": "0x1234", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "1662465600" +} diff --git a/scripts/local_testnet/geth.sh b/scripts/local_testnet/geth.sh new file mode 100755 index 00000000000..f7398451d8c --- /dev/null +++ b/scripts/local_testnet/geth.sh @@ -0,0 +1,59 @@ +set -Eeuo pipefail + +source ./vars.env + +# Get options +while getopts "d:sh" flag; do + case "${flag}" in + d) DEBUG_LEVEL=${OPTARG};; + s) SUBSCRIBE_ALL_SUBNETS="--subscribe-all-subnets";; + h) + echo "Start a geth node" + echo + echo "usage: $0 " + echo + echo "Options:" + echo " -h: this help" + echo + echo "Positional arguments:" + echo " DATADIR Value for --datadir parameter" + echo " NETWORK-PORT Value for --port" + echo " HTTP-PORT Value for --http.port" + echo " AUTH-PORT Value for --authrpc.port" + echo " GENESIS_FILE Value for geth init" + exit + ;; + esac +done + +# Get positional arguments +data_dir=${@:$OPTIND+0:1} +network_port=${@:$OPTIND+1:1} +http_port=${@:$OPTIND+2:1} +auth_port=${@:$OPTIND+3:1} +genesis_file=${@:$OPTIND+4:1} + + +# Init +$GETH_BINARY init \ + --datadir $data_dir \ + $genesis_file + +cp ./keystore/f3c4a483ca812fe2e6abfbd5d74b4b6a1fb6b21c $1/keystore/ + +echo "Completed init" + +exec $GETH_BINARY \ + --datadir $data_dir \ + --vmodule=5 \ + --allow-insecure-unlock \ + --unlock=f3c4a483ca812fe2e6abfbd5d74b4b6a1fb6b21c \ + --password=./keystore/password \ + --http \ + --http.api="engine,eth,web3,net,debug" \ + --networkid=$CHAIN_ID \ + --syncmode=full \ + --bootnodes $EL_BOOTNODE_ENODE \ + --port $network_port \ + --http.port $http_port \ + --authrpc.port $auth_port diff --git a/scripts/local_testnet/json_rpc_snoop b/scripts/local_testnet/json_rpc_snoop new file mode 100755 index 00000000000..91d611787b2 Binary files /dev/null and b/scripts/local_testnet/json_rpc_snoop differ diff --git a/scripts/local_testnet/keystore/f3c4a483ca812fe2e6abfbd5d74b4b6a1fb6b21c b/scripts/local_testnet/keystore/f3c4a483ca812fe2e6abfbd5d74b4b6a1fb6b21c new file mode 100644 index 00000000000..57815017782 --- /dev/null +++ b/scripts/local_testnet/keystore/f3c4a483ca812fe2e6abfbd5d74b4b6a1fb6b21c @@ -0,0 +1 @@ +{"address":"f3c4a483ca812fe2e6abfbd5d74b4b6a1fb6b21c","crypto":{"cipher":"aes-128-ctr","ciphertext":"53dd14e5bb092c4dc040446ae732df281ee4cb7afd1e940ebc72b597c936c6e9","cipherparams":{"iv":"2e988d89df5df27430c1e4012f3cb729"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"bd20a76c732bf8cd6038f29e1fd4d3f4a11320adbc40c8838937638b4c7b906d"},"mac":"25ae88a52cb1b776cef32c37f3f43b20723cb6802513bb75a2dbed438042f6bb"},"id":"f51d72fe-e41b-45c2-8d2f-59ad067b1f4f","version":3} \ No newline at end of file diff --git a/scripts/local_testnet/keystore/password b/scripts/local_testnet/keystore/password new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/local_testnet/kill_processes.sh b/scripts/local_testnet/kill_processes.sh index d63725ac14f..83a0027337a 100755 --- a/scripts/local_testnet/kill_processes.sh +++ b/scripts/local_testnet/kill_processes.sh @@ -12,7 +12,7 @@ if [ -f "$1" ]; then [[ -n "$pid" ]] || continue echo killing $pid - kill $pid + kill $pid || true done < $1 fi diff --git a/scripts/local_testnet/setup.sh b/scripts/local_testnet/setup.sh index 82336984afb..21cbbb71a23 100755 --- a/scripts/local_testnet/setup.sh +++ b/scripts/local_testnet/setup.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash # -# Deploys the deposit contract and makes deposits for $VALIDATOR_COUNT insecure deterministic validators. # Produces a testnet specification and a genesis state where the genesis time # is now + $GENESIS_DELAY. # @@ -13,11 +12,6 @@ set -o nounset -o errexit -o pipefail source ./vars.env -lcli \ - deploy-deposit-contract \ - --eth1-http http://localhost:8545 \ - --confirmations 1 \ - --validator-count $VALIDATOR_COUNT NOW=`date +%s` GENESIS_TIME=`expr $NOW + $GENESIS_DELAY` @@ -32,14 +26,19 @@ lcli \ --genesis-delay $GENESIS_DELAY \ --genesis-fork-version $GENESIS_FORK_VERSION \ --altair-fork-epoch $ALTAIR_FORK_EPOCH \ + --bellatrix-fork-epoch $BELLATRIX_FORK_EPOCH \ + --ttd $TTD \ + --eth1-block-hash $ETH1_BLOCK_HASH \ --eth1-id $CHAIN_ID \ --eth1-follow-distance 1 \ --seconds-per-slot $SECONDS_PER_SLOT \ --seconds-per-eth1-block $SECONDS_PER_ETH1_BLOCK \ --proposer-score-boost "$PROPOSER_SCORE_BOOST" \ + --validator-count $GENESIS_VALIDATOR_COUNT \ + --interop-genesis-state \ --force -echo Specification generated at $TESTNET_DIR. +echo Specification and genesis.ssz generated at $TESTNET_DIR. echo "Generating $VALIDATOR_COUNT validators concurrently... (this may take a while)" lcli \ @@ -49,13 +48,3 @@ lcli \ --node-count $BN_COUNT echo Validators generated with keystore passwords at $DATADIR. -echo "Building genesis state... (this might take a while)" - -lcli \ - interop-genesis \ - --spec $SPEC_PRESET \ - --genesis-time $GENESIS_TIME \ - --testnet-dir $TESTNET_DIR \ - $GENESIS_VALIDATOR_COUNT - -echo Created genesis state in $TESTNET_DIR diff --git a/scripts/local_testnet/start_local_testnet.sh b/scripts/local_testnet/start_local_testnet.sh index dcc0a5382a9..20f0f35ba1c 100755 --- a/scripts/local_testnet/start_local_testnet.sh +++ b/scripts/local_testnet/start_local_testnet.sh @@ -40,6 +40,8 @@ if (( $VC_COUNT > $BN_COUNT )); then exit fi +genesis_file=${@:$OPTIND+0:1} + # Init some constants PID_FILE=$TESTNET_DIR/PIDS.pid LOG_DIR=$TESTNET_DIR @@ -55,6 +57,9 @@ mkdir -p $LOG_DIR for (( bn=1; bn<=$BN_COUNT; bn++ )); do touch $LOG_DIR/beacon_node_$bn.log done +for (( el=1; el<=$BN_COUNT; el++ )); do + touch $LOG_DIR/geth_$el.log +done for (( vc=1; vc<=$VC_COUNT; vc++ )); do touch $LOG_DIR/validator_node_$vc.log done @@ -92,12 +97,6 @@ execute_command_add_PID() { echo "$!" >> $PID_FILE } -# Start ganache, setup things up and start the bootnode. -# The delays are necessary, hopefully there is a better way :( - -# Delay to let ganache to get started -execute_command_add_PID ganache_test_node.log ./ganache_test_node.sh -sleeping 10 # Setup data echo "executing: ./setup.sh >> $LOG_DIR/setup.log" @@ -107,16 +106,47 @@ echo "executing: ./setup.sh >> $LOG_DIR/setup.log" execute_command_add_PID bootnode.log ./bootnode.sh sleeping 1 +execute_command_add_PID el_bootnode.log ./el_bootnode.sh +sleeping 1 + +# Start json_rpc_snoop +SNOOP_PORT=8646 +SNOOP_LISTEN=8999 +snoop() { + exec ./json_rpc_snoop -p $SNOOP_PORT http://localhost:$SNOOP_LISTEN +} +execute_command_add_PID snoop.log snoop + + # Start beacon nodes BN_udp_tcp_base=9000 BN_http_port_base=8000 +EL_base_network=7000 +EL_base_http=6000 +EL_base_auth_http=5000 + (( $VC_COUNT < $BN_COUNT )) && SAS=-s || SAS= -for (( bn=1; bn<=$BN_COUNT; bn++ )); do - execute_command_add_PID beacon_node_$bn.log ./beacon_node.sh $SAS -d $DEBUG_LEVEL $DATADIR/node_$bn $((BN_udp_tcp_base + $bn)) $((BN_http_port_base + $bn)) +for (( el=2; el<=$BN_COUNT; el++ )); do + execute_command_add_PID geth_$el.log ./geth.sh $DATADIR/geth_datadir$el $((EL_base_network + $el)) $((EL_base_http + $el)) $((EL_base_auth_http + $el)) $genesis_file +done + +# Start geth which is connected to json_rpc_snoop +execute_command_add_PID geth_1.log ./geth.sh $DATADIR/geth_datadir1 $((EL_base_network + 1)) $((EL_base_http + 1)) $SNOOP_LISTEN $genesis_file + + +sleeping 20 + +for (( bn=2; bn<=$BN_COUNT; bn++ )); do + secret=$DATADIR/geth_datadir$bn/geth/jwtsecret + echo $secret + execute_command_add_PID beacon_node_$bn.log ./beacon_node.sh $SAS -d $DEBUG_LEVEL $DATADIR/node_$bn $((BN_udp_tcp_base + $bn)) $((BN_http_port_base + $bn)) http://localhost:$((EL_base_auth_http + $bn)) $secret done +# Start beacon node which is connected to json_rpc_snoop +execute_command_add_PID beacon_node_1.log ./beacon_node.sh $SAS -d $DEBUG_LEVEL $DATADIR/node_1 $((BN_udp_tcp_base + 1)) $((BN_http_port_base + 1)) http://localhost:$SNOOP_PORT $DATADIR/geth_datadir1/geth/jwtsecret + # Start requested number of validator clients for (( vc=1; vc<=$VC_COUNT; vc++ )); do execute_command_add_PID validator_node_$vc.log ./validator_client.sh $BUILDER_PROPOSALS -d $DEBUG_LEVEL $DATADIR/node_$vc http://localhost:$((BN_http_port_base + $vc)) diff --git a/scripts/local_testnet/validator_client.sh b/scripts/local_testnet/validator_client.sh index 975a2a6753c..d88a1833cb5 100755 --- a/scripts/local_testnet/validator_client.sh +++ b/scripts/local_testnet/validator_client.sh @@ -30,4 +30,5 @@ exec lighthouse \ --testnet-dir $TESTNET_DIR \ --init-slashing-protection \ --beacon-nodes ${@:$OPTIND+1:1} \ + --suggested-fee-recipient 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 \ $VC_ARGS diff --git a/scripts/local_testnet/vars.env b/scripts/local_testnet/vars.env index 2506e9e1cdf..29d44c6ad13 100644 --- a/scripts/local_testnet/vars.env +++ b/scripts/local_testnet/vars.env @@ -1,17 +1,22 @@ +# Path to the geth binary +GETH_BINARY=geth + # Base directories for the validator keys and secrets DATADIR=~/.lighthouse/local-testnet # Directory for the eth2 config TESTNET_DIR=$DATADIR/testnet -# Mnemonic for the ganache test network -ETH1_NETWORK_MNEMONIC="vast thought differ pull jewel broom cook wrist tribe word before omit" +EL_BOOTNODE_ENODE="enode://51ea9bb34d31efc3491a842ed13b8cab70e753af108526b57916d716978b380ed713f4336a80cdb85ec2a115d5a8c0ae9f3247bed3c84d3cb025c6bab311062c@127.0.0.1:0?discport=30301" -# Hardcoded deposit contract based on ETH1_NETWORK_MNEMONIC -DEPOSIT_CONTRACT_ADDRESS=8c594691c0e592ffa21f153a16ae41db5befcaaa +# Hardcoded deposit contract +DEPOSIT_CONTRACT_ADDRESS=4242424242424242424242424242424242424242 GENESIS_FORK_VERSION=0x42424242 +# Block hash generated from genesis.json in directory +ETH1_BLOCK_HASH=9507ddf40445f24370f499312df02cb1eaaab986fafb1801b25201301802c6d3 + VALIDATOR_COUNT=80 GENESIS_VALIDATOR_COUNT=80 @@ -33,7 +38,10 @@ BOOTNODE_PORT=4242 CHAIN_ID=4242 # Hard fork configuration -ALTAIR_FORK_EPOCH=18446744073709551615 +ALTAIR_FORK_EPOCH=0 +BELLATRIX_FORK_EPOCH=0 + +TTD=0 # Spec version (mainnet or minimal) SPEC_PRESET=mainnet diff --git a/slasher/Cargo.toml b/slasher/Cargo.toml index 0f24fe9f04f..c5ce8793ad4 100644 --- a/slasher/Cargo.toml +++ b/slasher/Cargo.toml @@ -13,7 +13,7 @@ lmdb = ["lmdb-rkv", "lmdb-rkv-sys"] bincode = "1.3.1" byteorder = "1.3.4" eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" flate2 = { version = "1.0.14", features = ["zlib"], default-features = false } lazy_static = "1.4.0" lighthouse_metrics = { path = "../common/lighthouse_metrics" } diff --git a/testing/ef_tests/Cargo.toml b/testing/ef_tests/Cargo.toml index d969c9727d7..79664a26228 100644 --- a/testing/ef_tests/Cargo.toml +++ b/testing/ef_tests/Cargo.toml @@ -23,7 +23,7 @@ serde_derive = "1.0.116" serde_repr = "0.1.6" serde_yaml = "0.8.13" eth2_ssz = "0.4.1" -eth2_ssz_derive = "0.3.0" +eth2_ssz_derive = "0.3.1" tree_hash = "0.4.1" tree_hash_derive = "0.4.0" cached_tree_hash = { path = "../../consensus/cached_tree_hash" }