Update to spec v1.0.0-rc.0 and BLSv4 (#1765)

## Issue Addressed

Closes #1504 
Closes #1505
Replaces #1703
Closes #1707

## Proposed Changes

* Update BLST and Milagro to versions compatible with BLSv4 spec
* Update Lighthouse to spec v1.0.0-rc.0, and update EF test vectors
* Use the v1.0.0 constants for `MainnetEthSpec`.
* Rename `InteropEthSpec` -> `V012LegacyEthSpec`
    * Change all constants to suit the mainnet `v0.12.3` specification (i.e., Medalla).
* Deprecate the `--spec` flag for the `lighthouse` binary
    * This value is now obtained from the `config_name` field of the `YamlConfig`.
        * Built in testnet YAML files have been updated.
    * Ignore the `--spec` value, if supplied, log a warning that it will be deprecated
    * `lcli` still has the spec flag, that's fine because it's dev tooling.
* Remove the `E: EthSpec` from `YamlConfig`
    * This means we need to deser the genesis `BeaconState` on-demand, but this is fine.
* Swap the old "minimal", "mainnet" strings over to the new `EthSpecId` enum.
* Always require a `CONFIG_NAME` field in `YamlConfig` (it used to have a default).

## Additional Info

Lots of breaking changes, do not merge! ~~We will likely need a Lighthouse v0.4.0 branch, and possibly a long-term v0.3.0 branch to keep Medalla alive~~.

Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
Michael Sproul 2020-10-28 22:19:38 +00:00
parent ad846ad280
commit 36bd4d87f0
55 changed files with 596 additions and 661 deletions

263
Cargo.lock generated
View File

@ -2,7 +2,7 @@
# It is not intended for manual editing.
[[package]]
name = "account_manager"
version = "0.3.1"
version = "0.3.2"
dependencies = [
"account_utils",
"bls",
@ -18,8 +18,8 @@ dependencies = [
"eth2_testnet_config",
"eth2_wallet",
"eth2_wallet_manager",
"futures 0.3.6",
"hex 0.4.2",
"futures 0.3.7",
"hex",
"libc",
"rand 0.7.3",
"rayon",
@ -172,12 +172,8 @@ dependencies = [
[[package]]
name = "amcl"
version = "0.2.0"
source = "git+https://github.com/sigp/milagro_bls?branch=paulh#7662690845f3f2594e46cfe71b6b0bb91d5e1f82"
dependencies = [
"hex 0.3.2",
"lazy_static",
]
version = "0.3.0"
source = "git+https://github.com/sigp/milagro_bls?tag=v1.4.0#45a076a776a6f1d9f8157fd2d574bfefaee2c81a"
[[package]]
name = "ansi_term"
@ -226,9 +222,9 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "asn1_der"
@ -357,7 +353,7 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
name = "beacon_chain"
version = "0.2.0"
dependencies = [
"bitvec 0.19.3",
"bitvec 0.19.4",
"bls",
"bus",
"derivative",
@ -370,7 +366,7 @@ dependencies = [
"eth2_ssz_types",
"exit-future",
"fork_choice",
"futures 0.3.6",
"futures 0.3.7",
"genesis",
"int_to_bytes",
"integer-sqrt",
@ -409,7 +405,7 @@ dependencies = [
[[package]]
name = "beacon_node"
version = "0.3.1"
version = "0.3.2"
dependencies = [
"beacon_chain",
"clap",
@ -424,9 +420,9 @@ dependencies = [
"eth2_ssz",
"eth2_testnet_config",
"exit-future",
"futures 0.3.6",
"futures 0.3.7",
"genesis",
"hex 0.4.2",
"hex",
"hyper 0.13.8",
"lighthouse_version",
"logging",
@ -487,9 +483,9 @@ dependencies = [
[[package]]
name = "bitvec"
version = "0.19.3"
version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11593270830d9b037fbead730bb0c05ef6fbf6be55537a1e8e5892edef7e1f03"
checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
dependencies = [
"funty",
"radium 0.5.3",
@ -499,15 +495,13 @@ dependencies = [
[[package]]
name = "blake2"
version = "0.9.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84ce5b6108f8e154604bd4eb76a2f726066c3464d5a552a4229262a18c9bb471"
checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4"
dependencies = [
"byte-tools",
"byteorder",
"crypto-mac 0.8.0",
"digest 0.9.0",
"opaque-debug 0.2.3",
"opaque-debug 0.3.0",
]
[[package]]
@ -587,7 +581,7 @@ dependencies = [
"eth2_hashing",
"eth2_ssz",
"ethereum-types",
"hex 0.4.2",
"hex",
"milagro_bls",
"rand 0.7.3",
"serde",
@ -599,8 +593,8 @@ dependencies = [
[[package]]
name = "blst"
version = "0.1.1"
source = "git+https://github.com/sigp/blst.git?rev=284f7059642851c760a09fb1708bcb59c7ca323c#284f7059642851c760a09fb1708bcb59c7ca323c"
version = "0.2.0"
source = "git+https://github.com/sigp/blst.git?rev=7cf47864627ca479cad06c2a164f30d0cbaf16ce#7cf47864627ca479cad06c2a164f30d0cbaf16ce"
dependencies = [
"cc",
"glob",
@ -609,15 +603,15 @@ dependencies = [
[[package]]
name = "boot_node"
version = "0.3.1"
version = "0.3.2"
dependencies = [
"beacon_node",
"clap",
"eth2_libp2p",
"eth2_ssz",
"eth2_testnet_config",
"futures 0.3.6",
"hex 0.4.2",
"futures 0.3.7",
"hex",
"log 0.4.11",
"logging",
"slog",
@ -839,7 +833,7 @@ dependencies = [
"dirs 3.0.1",
"eth2_ssz",
"eth2_testnet_config",
"hex 0.4.2",
"hex",
"types",
]
@ -857,7 +851,7 @@ dependencies = [
"eth2_config",
"eth2_libp2p",
"eth2_ssz",
"futures 0.3.6",
"futures 0.3.7",
"genesis",
"http_api",
"http_metrics",
@ -1267,7 +1261,7 @@ version = "0.2.0"
dependencies = [
"eth2_ssz",
"ethabi",
"hex 0.4.2",
"hex",
"reqwest",
"serde_json",
"sha2 0.9.1",
@ -1384,8 +1378,8 @@ dependencies = [
"digest 0.9.0",
"enr",
"fnv",
"futures 0.3.6",
"hex 0.4.2",
"futures 0.3.7",
"hex",
"hkdf",
"k256",
"lazy_static",
@ -1416,8 +1410,8 @@ dependencies = [
"digest 0.9.0",
"enr",
"fnv",
"futures 0.3.6",
"hex 0.4.2",
"futures 0.3.7",
"hex",
"hkdf",
"k256",
"lazy_static",
@ -1487,7 +1481,7 @@ dependencies = [
"eth2_ssz",
"eth2_ssz_derive",
"ethereum-types",
"hex 0.4.2",
"hex",
"rayon",
"serde",
"serde_derive",
@ -1541,7 +1535,7 @@ dependencies = [
"base64 0.12.3",
"bs58",
"ed25519-dalek",
"hex 0.4.2",
"hex",
"k256",
"log 0.4.11",
"rand 0.7.3",
@ -1572,7 +1566,7 @@ dependencies = [
"eth2_config",
"eth2_testnet_config",
"exit-future",
"futures 0.3.6",
"futures 0.3.7",
"logging",
"parking_lot 0.11.0",
"slog",
@ -1604,8 +1598,8 @@ dependencies = [
"eth2_hashing",
"eth2_ssz",
"eth2_ssz_derive",
"futures 0.3.6",
"hex 0.4.2",
"futures 0.3.7",
"hex",
"lazy_static",
"libflate",
"lighthouse_metrics",
@ -1630,7 +1624,7 @@ name = "eth1_test_rig"
version = "0.2.0"
dependencies = [
"deposit_contract",
"futures 0.3.6",
"futures 0.3.7",
"serde_json",
"tokio 0.2.22",
"types",
@ -1646,7 +1640,7 @@ dependencies = [
"eth2_keystore",
"eth2_libp2p",
"eth2_ssz",
"hex 0.4.2",
"hex",
"libsecp256k1",
"procinfo",
"proto_array",
@ -1688,7 +1682,7 @@ dependencies = [
"base64 0.13.0",
"bls",
"eth2_hashing",
"hex 0.4.2",
"hex",
"lazy_static",
"num-bigint",
"serde",
@ -1701,7 +1695,7 @@ name = "eth2_key_derivation"
version = "0.1.0"
dependencies = [
"bls",
"hex 0.4.2",
"hex",
"num-bigint-dig",
"ring",
"sha2 0.9.1",
@ -1716,7 +1710,7 @@ dependencies = [
"bls",
"eth2_key_derivation",
"eth2_ssz",
"hex 0.4.2",
"hex",
"hmac 0.9.0",
"pbkdf2 0.5.0",
"rand 0.7.3",
@ -1744,9 +1738,9 @@ dependencies = [
"eth2_ssz_types",
"exit-future",
"fnv",
"futures 0.3.6",
"futures 0.3.7",
"hashset_delay",
"hex 0.4.2",
"hex",
"lazy_static",
"libp2p",
"lighthouse_metrics",
@ -1825,7 +1819,7 @@ version = "0.1.0"
dependencies = [
"eth2_key_derivation",
"eth2_keystore",
"hex 0.4.2",
"hex",
"rand 0.7.3",
"serde",
"serde_json",
@ -1891,7 +1885,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5"
dependencies = [
"futures 0.3.6",
"futures 0.3.7",
]
[[package]]
@ -2005,7 +1999,7 @@ dependencies = [
"beacon_chain",
"eth2_ssz",
"eth2_ssz_derive",
"hex 0.4.2",
"hex",
"proto_array",
"slot_clock",
"state_processing",
@ -2050,9 +2044,9 @@ checksum = "4c7e4c2612746b0df8fed4ce0c69156021b704c9aefa360311c04e6e9e002eed"
[[package]]
name = "futures"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d8e3078b7b2a8a671cb7a3d17b4760e4181ea243227776ba83fd043b4ca034e"
checksum = "95314d38584ffbfda215621d723e0a3906f032e03ae5551e650058dac83d4797"
dependencies = [
"futures-channel",
"futures-core",
@ -2065,9 +2059,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a4d35f7401e948629c9c3d6638fb9bf94e0b2121e96c3b428cc4e631f3eb74"
checksum = "0448174b01148032eed37ac4aed28963aaaa8cfa93569a08e5b479bbc6c2c151"
dependencies = [
"futures-core",
"futures-sink",
@ -2075,9 +2069,9 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d674eaa0056896d5ada519900dbf97ead2e46a7b6621e8160d79e2f2e1e2784b"
checksum = "18eaa56102984bed2c88ea39026cff3ce3b4c7f508ca970cedf2450ea10d4e46"
[[package]]
name = "futures-cpupool"
@ -2091,9 +2085,9 @@ dependencies = [
[[package]]
name = "futures-executor"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc709ca1da6f66143b8c9bec8e6260181869893714e9b5a490b169b0414144ab"
checksum = "f5f8e0c9258abaea85e78ebdda17ef9666d390e987f006be6080dfe354b708cb"
dependencies = [
"futures-core",
"futures-task",
@ -2103,15 +2097,15 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fc94b64bb39543b4e432f1790b6bf18e3ee3b74653c5449f63310e9a74b123c"
checksum = "6e1798854a4727ff944a7b12aa999f58ce7aa81db80d2dfaaf2ba06f065ddd2b"
[[package]]
name = "futures-macro"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f57ed14da4603b2554682e9f2ff3c65d7567b53188db96cb71538217fc64581b"
checksum = "e36fccf3fc58563b4a14d265027c627c3b665d7fed489427e88e7cc929559efe"
dependencies = [
"proc-macro-hack",
"proc-macro2",
@ -2121,15 +2115,15 @@ dependencies = [
[[package]]
name = "futures-sink"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8764258ed64ebc5d9ed185cf86a95db5cac810269c5d20ececb32e0088abbd"
checksum = "0e3ca3f17d6e8804ae5d3df7a7d35b2b3a6fe89dac84b31872720fc3060a0b11"
[[package]]
name = "futures-task"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dd26820a9f3637f1302da8bceba3ff33adbe53464b54ca24d4e2d4f1db30f94"
checksum = "96d502af37186c4fef99453df03e374683f8a1eec9dcc1e66b3b82dc8278ce3c"
dependencies = [
"once_cell",
]
@ -2142,9 +2136,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
[[package]]
name = "futures-util"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a894a0acddba51a2d49a6f4263b1e64b8c579ece8af50fa86503d52cd1eea34"
checksum = "abcb44342f62e6f3e8ac427b8aa815f724fd705dfad060b18ac7866c15bb8e34"
dependencies = [
"futures 0.1.30",
"futures-channel",
@ -2154,7 +2148,7 @@ dependencies = [
"futures-sink",
"futures-task",
"memchr",
"pin-project 0.4.27",
"pin-project 1.0.1",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
@ -2168,7 +2162,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce54d63f8b0c75023ed920d46fd71d0cbbb830b0ee012726b5b4f506fb6dea5b"
dependencies = [
"bytes 0.5.6",
"futures 0.3.6",
"futures 0.3.7",
"memchr",
"pin-project 0.4.27",
]
@ -2221,7 +2215,7 @@ dependencies = [
"eth2_hashing",
"eth2_ssz",
"exit-future",
"futures 0.3.6",
"futures 0.3.7",
"int_to_bytes",
"merkle_proof",
"parking_lot 0.11.0",
@ -2342,9 +2336,9 @@ dependencies = [
[[package]]
name = "h2"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53"
checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
dependencies = [
"bytes 0.5.6",
"fnv",
@ -2357,6 +2351,7 @@ dependencies = [
"tokio 0.2.22",
"tokio-util",
"tracing",
"tracing-futures",
]
[[package]]
@ -2397,7 +2392,7 @@ dependencies = [
name = "hashset_delay"
version = "0.2.0"
dependencies = [
"futures 0.3.6",
"futures 0.3.7",
"tokio 0.2.22",
]
@ -2444,12 +2439,6 @@ dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
[[package]]
name = "hex"
version = "0.4.2"
@ -2570,7 +2559,7 @@ dependencies = [
"eth2_libp2p",
"eth2_ssz",
"fork_choice",
"hex 0.4.2",
"hex",
"lazy_static",
"lighthouse_metrics",
"lighthouse_version",
@ -2691,7 +2680,7 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-util",
"h2 0.2.6",
"h2 0.2.7",
"http 0.2.1",
"http-body 0.3.1",
"httparse",
@ -2814,11 +2803,11 @@ dependencies = [
[[package]]
name = "instant"
version = "0.1.7"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66"
checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613"
dependencies = [
"cfg-if 0.1.10",
"cfg-if 1.0.0",
]
[[package]]
@ -2826,7 +2815,7 @@ name = "int_to_bytes"
version = "0.2.0"
dependencies = [
"bytes 0.5.6",
"hex 0.4.2",
"hex",
"yaml-rust",
]
@ -2902,9 +2891,9 @@ dependencies = [
[[package]]
name = "k256"
version = "0.5.9"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2967b7caf19e57f5d01ac0893551b0aaae1a8e2e2b2a28996e12c9c51b3b486"
checksum = "3934640b1efbc660af5889d041854b6985d403771dc4d5fee984e13e8f82f313"
dependencies = [
"cfg-if 1.0.0",
"ecdsa",
@ -2951,7 +2940,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lcli"
version = "0.3.1"
version = "0.3.2"
dependencies = [
"bls",
"clap",
@ -2964,9 +2953,9 @@ dependencies = [
"eth2_libp2p",
"eth2_ssz",
"eth2_testnet_config",
"futures 0.3.6",
"futures 0.3.7",
"genesis",
"hex 0.4.2",
"hex",
"lighthouse_version",
"log 0.4.11",
"rand 0.7.3",
@ -3006,15 +2995,15 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.79"
version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743"
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
[[package]]
name = "libflate"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9bac9023e1db29c084f9f8cd9d3852e5e8fddf98fb47c4964a0ea4663d95949"
checksum = "389de7875e06476365974da3e7ff85d55f1972188ccd9f6020dd7c8156e17914"
dependencies = [
"adler32",
"crc32fast",
@ -3041,7 +3030,7 @@ source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72
dependencies = [
"atomic",
"bytes 0.5.6",
"futures 0.3.6",
"futures 0.3.7",
"lazy_static",
"libp2p-core 0.22.2",
"libp2p-core-derive",
@ -3072,7 +3061,7 @@ dependencies = [
"ed25519-dalek",
"either",
"fnv",
"futures 0.3.6",
"futures 0.3.7",
"futures-timer",
"lazy_static",
"libsecp256k1",
@ -3105,7 +3094,7 @@ dependencies = [
"ed25519-dalek",
"either",
"fnv",
"futures 0.3.6",
"futures 0.3.7",
"futures-timer",
"lazy_static",
"libsecp256k1",
@ -3142,7 +3131,7 @@ name = "libp2p-dns"
version = "0.22.0"
source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72fb134dea5f9669#8c6ce6eb1228de568568f6cd72fb134dea5f9669"
dependencies = [
"futures 0.3.6",
"futures 0.3.7",
"libp2p-core 0.22.2",
"log 0.4.11",
]
@ -3156,7 +3145,7 @@ dependencies = [
"byteorder",
"bytes 0.5.6",
"fnv",
"futures 0.3.6",
"futures 0.3.7",
"futures_codec",
"hex_fmt",
"libp2p-core 0.22.2",
@ -3176,7 +3165,7 @@ name = "libp2p-identify"
version = "0.22.0"
source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72fb134dea5f9669#8c6ce6eb1228de568568f6cd72fb134dea5f9669"
dependencies = [
"futures 0.3.6",
"futures 0.3.7",
"libp2p-core 0.22.2",
"libp2p-swarm",
"log 0.4.11",
@ -3193,7 +3182,7 @@ source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72
dependencies = [
"bytes 0.5.6",
"fnv",
"futures 0.3.6",
"futures 0.3.7",
"futures_codec",
"libp2p-core 0.22.2",
"log 0.4.11",
@ -3208,7 +3197,7 @@ source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72
dependencies = [
"bytes 0.5.6",
"curve25519-dalek",
"futures 0.3.6",
"futures 0.3.7",
"lazy_static",
"libp2p-core 0.22.2",
"log 0.4.11",
@ -3228,7 +3217,7 @@ version = "0.22.0"
source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72fb134dea5f9669#8c6ce6eb1228de568568f6cd72fb134dea5f9669"
dependencies = [
"either",
"futures 0.3.6",
"futures 0.3.7",
"libp2p-core 0.22.2",
"log 0.4.11",
"rand 0.7.3",
@ -3242,7 +3231,7 @@ name = "libp2p-tcp"
version = "0.22.0"
source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72fb134dea5f9669#8c6ce6eb1228de568568f6cd72fb134dea5f9669"
dependencies = [
"futures 0.3.6",
"futures 0.3.7",
"futures-timer",
"get_if_addrs",
"ipnet",
@ -3259,7 +3248,7 @@ source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72
dependencies = [
"async-tls",
"either",
"futures 0.3.6",
"futures 0.3.7",
"libp2p-core 0.22.2",
"log 0.4.11",
"quicksink",
@ -3312,7 +3301,7 @@ dependencies = [
[[package]]
name = "lighthouse"
version = "0.3.1"
version = "0.3.2"
dependencies = [
"account_manager",
"account_utils",
@ -3325,7 +3314,7 @@ dependencies = [
"env_logger",
"environment",
"eth2_testnet_config",
"futures 0.3.6",
"futures 0.3.7",
"lighthouse_version",
"logging",
"slashing_protection",
@ -3481,9 +3470,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memchr"
version = "2.3.3"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "memoffset"
@ -3508,11 +3497,11 @@ dependencies = [
[[package]]
name = "milagro_bls"
version = "1.1.0"
source = "git+https://github.com/sigp/milagro_bls?branch=paulh#7662690845f3f2594e46cfe71b6b0bb91d5e1f82"
version = "1.4.0"
source = "git+https://github.com/sigp/milagro_bls?tag=v1.4.0#45a076a776a6f1d9f8157fd2d574bfefaee2c81a"
dependencies = [
"amcl",
"hex 0.4.2",
"hex",
"lazy_static",
"rand 0.7.3",
"zeroize",
@ -3683,7 +3672,7 @@ version = "0.8.3"
source = "git+https://github.com/sigp/rust-libp2p?rev=8c6ce6eb1228de568568f6cd72fb134dea5f9669#8c6ce6eb1228de568568f6cd72fb134dea5f9669"
dependencies = [
"bytes 0.5.6",
"futures 0.3.6",
"futures 0.3.7",
"log 0.4.11",
"pin-project 0.4.27",
"smallvec 1.4.2",
@ -3697,7 +3686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36a6aa6e32fbaf16795142335967214b8564a7a4661eb6dc846ef343a6e00ac1"
dependencies = [
"bytes 0.5.6",
"futures 0.3.6",
"futures 0.3.7",
"log 0.4.11",
"pin-project 1.0.1",
"smallvec 1.4.2",
@ -3744,11 +3733,11 @@ dependencies = [
"eth2_ssz_types",
"exit-future",
"fnv",
"futures 0.3.6",
"futures 0.3.7",
"genesis",
"get_if_addrs",
"hashset_delay",
"hex 0.4.2",
"hex",
"igd",
"itertools 0.9.0",
"lazy_static",
@ -3805,7 +3794,7 @@ dependencies = [
"environment",
"eth2",
"eth2_config",
"futures 0.3.6",
"futures 0.3.7",
"genesis",
"reqwest",
"serde",
@ -4273,9 +4262,9 @@ dependencies = [
[[package]]
name = "proc-macro-hack"
version = "0.5.18"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
@ -4914,7 +4903,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020"
dependencies = [
"futures 0.3.6",
"futures 0.3.7",
"pin-project 0.4.27",
"static_assertions",
]
@ -5137,7 +5126,7 @@ dependencies = [
name = "serde_utils"
version = "0.1.0"
dependencies = [
"hex 0.4.2",
"hex",
"serde",
"serde_derive",
"serde_json",
@ -5274,7 +5263,7 @@ dependencies = [
"env_logger",
"eth1",
"eth1_test_rig",
"futures 0.3.6",
"futures 0.3.7",
"node_test_rig",
"parking_lot 0.11.0",
"rayon",
@ -5477,7 +5466,7 @@ dependencies = [
"base64 0.12.3",
"bytes 0.5.6",
"flate2",
"futures 0.3.6",
"futures 0.3.7",
"httparse",
"log 0.4.11",
"rand 0.7.3",
@ -5663,9 +5652,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.46"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ad5de3220ea04da322618ded2c42233d02baca219d6f160a3e9c87cda16c942"
checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
dependencies = [
"proc-macro2",
"quote",
@ -5707,7 +5696,7 @@ name = "task_executor"
version = "0.1.0"
dependencies = [
"exit-future",
"futures 0.3.6",
"futures 0.3.7",
"lazy_static",
"lighthouse_metrics",
"slog",
@ -5866,7 +5855,7 @@ name = "timer"
version = "0.2.0"
dependencies = [
"beacon_chain",
"futures 0.3.6",
"futures 0.3.7",
"parking_lot 0.11.0",
"slog",
"slot_clock",
@ -6469,7 +6458,7 @@ dependencies = [
"eth2_ssz_derive",
"eth2_ssz_types",
"ethereum-types",
"hex 0.4.2",
"hex",
"int_to_bytes",
"log 0.4.11",
"merkle_proof",
@ -6652,7 +6641,7 @@ dependencies = [
[[package]]
name = "validator_client"
version = "0.3.1"
version = "0.3.2"
dependencies = [
"account_utils",
"bincode",
@ -6670,8 +6659,8 @@ dependencies = [
"eth2_ssz",
"eth2_ssz_derive",
"exit-future",
"futures 0.3.6",
"hex 0.4.2",
"futures 0.3.7",
"hex",
"hyper 0.13.8",
"libc",
"libsecp256k1",
@ -6709,7 +6698,7 @@ dependencies = [
"bls",
"deposit_contract",
"eth2_keystore",
"hex 0.4.2",
"hex",
"rand 0.7.3",
"rayon",
"slog",
@ -6786,7 +6775,7 @@ version = "0.2.5"
source = "git+https://github.com/paulhauner/warp?branch=cors-wildcard#a7685b76d70c3e5628e31d60aee510acec3c5c30"
dependencies = [
"bytes 0.5.6",
"futures 0.3.6",
"futures 0.3.7",
"headers",
"http 0.2.1",
"hyper 0.13.8",
@ -6932,7 +6921,7 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
dependencies = [
"futures 0.3.6",
"futures 0.3.7",
"js-sys",
"parking_lot 0.11.0",
"pin-utils",
@ -7029,7 +7018,7 @@ dependencies = [
name = "websocket_server"
version = "0.2.0"
dependencies = [
"futures 0.3.6",
"futures 0.3.7",
"serde",
"serde_derive",
"slog",

View File

@ -42,7 +42,7 @@ endif
# optimized CPU functions that may not be available on some systems. This
# results in a more portable binary with ~20% slower BLS verification.
build-x86_64:
cross build --release --manifest-path lighthouse/Cargo.toml --target x86_64-unknown-linux-gnu
cross build --release --manifest-path lighthouse/Cargo.toml --target x86_64-unknown-linux-gnu --features modern
build-x86_64-portable:
cross build --release --manifest-path lighthouse/Cargo.toml --target x86_64-unknown-linux-gnu --features portable
build-aarch64:

View File

@ -1,6 +1,6 @@
[package]
name = "account_manager"
version = "0.3.1"
version = "0.3.2"
authors = ["Paul Hauner <paul@paulhauner.com>", "Luke Anderson <luke@sigmaprime.io>"]
edition = "2018"

View File

@ -5,7 +5,7 @@ use slashing_protection::{
};
use std::fs::File;
use std::path::PathBuf;
use types::EthSpec;
use types::{BeaconState, EthSpec};
pub const CMD: &str = "slashing-protection";
pub const IMPORT_CMD: &str = "import";
@ -46,18 +46,18 @@ pub fn cli_run<T: EthSpec>(
) -> Result<(), String> {
let slashing_protection_db_path = validator_base_dir.join(SLASHING_PROTECTION_FILENAME);
let genesis_validators_root = env
let testnet_config = env
.testnet
.and_then(|testnet_config| {
Some(
testnet_config
.genesis_state
.as_ref()?
.genesis_validators_root,
.ok_or_else(|| "Unable to get testnet configuration from the environment".to_string())?;
let genesis_validators_root = testnet_config
.beacon_state::<T>()
.map(|state: BeaconState<T>| state.genesis_validators_root)
.map_err(|e| {
format!(
"Unable to get genesis state, has genesis occurred? Detail: {:?}",
e
)
})
.ok_or_else(|| {
"Unable to get genesis validators root from testnet config, has genesis occurred?"
})?;
match matches.subcommand() {

View File

@ -1,6 +1,6 @@
[package]
name = "beacon_node"
version = "0.3.1"
version = "0.3.2"
authors = ["Paul Hauner <paul@paulhauner.com>", "Age Manning <Age@AgeManning.com"]
edition = "2018"

View File

@ -5,9 +5,6 @@ use std::fs;
use std::path::PathBuf;
use types::Graffiti;
/// The number initial validators when starting the `Minimal`.
const TESTNET_SPEC_CONSTANTS: &str = "minimal";
/// Default directory name for the freezer database under the top-level data dir.
const DEFAULT_FREEZER_DB_DIR: &str = "freezer_db";
@ -46,7 +43,6 @@ pub struct Config {
/// Path where the freezer database will be located.
pub freezer_db_path: Option<PathBuf>,
pub log_file: PathBuf,
pub spec_constants: String,
/// If true, the node will use co-ordinated junk for eth1 values.
///
/// This is the method used for the 2019 client interop in Canada.
@ -81,7 +77,6 @@ impl Default for Config {
network: NetworkConfig::default(),
chain: <_>::default(),
websocket_server: <_>::default(),
spec_constants: TESTNET_SPEC_CONSTANTS.into(),
dummy_eth1_backend: false,
sync_eth1_chain: false,
eth1: <_>::default(),

View File

@ -5,8 +5,7 @@ use client::{ClientConfig, ClientGenesis};
use directory::{DEFAULT_BEACON_NODE_DIR, DEFAULT_NETWORK_DIR, DEFAULT_ROOT_DIR};
use eth2_libp2p::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSerialized};
use eth2_testnet_config::Eth2TestnetConfig;
use slog::{crit, info, warn, Logger};
use ssz::Encode;
use slog::{info, warn, Logger};
use std::cmp;
use std::fs;
use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
@ -23,7 +22,6 @@ use types::{ChainSpec, Checkpoint, Epoch, EthSpec, Hash256, GRAFFITI_BYTES_LEN};
/// response of some remote server.
pub fn get_config<E: EthSpec>(
cli_args: &ArgMatches,
spec_constants: &str,
spec: &ChainSpec,
log: Logger,
) -> Result<ClientConfig, String> {
@ -67,8 +65,6 @@ pub fn get_config<E: EthSpec>(
log_dir.pop();
info!(log, "Data directory initialised"; "datadir" => log_dir.into_os_string().into_string().expect("Datadir should be a valid os string"));
client_config.spec_constants = spec_constants.into();
/*
* Networking
*/
@ -222,14 +218,6 @@ pub fn get_config<E: EthSpec>(
.map_err(|_| "block-cache-size is not a valid integer".to_string())?;
}
if spec_constants != client_config.spec_constants {
crit!(log, "Specification constants do not match.";
"client_config" => client_config.spec_constants,
"eth2_config" => spec_constants
);
return Err("Specification constant mismatch".into());
}
/*
* Zero-ports
*
@ -255,7 +243,7 @@ pub fn get_config<E: EthSpec>(
/*
* Load the eth2 testnet dir to obtain some additional config values.
*/
let eth2_testnet_config: Eth2TestnetConfig<E> = get_eth2_testnet_config(&cli_args)?;
let eth2_testnet_config = get_eth2_testnet_config(&cli_args)?;
client_config.eth1.deposit_contract_address =
format!("{:?}", eth2_testnet_config.deposit_contract_address()?);
@ -275,12 +263,12 @@ pub fn get_config<E: EthSpec>(
client_config.network.boot_nodes_enr.append(&mut boot_nodes)
}
if let Some(genesis_state) = eth2_testnet_config.genesis_state {
if let Some(genesis_state_bytes) = eth2_testnet_config.genesis_state_bytes {
// Note: re-serializing the genesis state is not so efficient, however it avoids adding
// trait bounds to the `ClientGenesis` enum. This would have significant flow-on
// effects.
client_config.genesis = ClientGenesis::SszBytes {
genesis_state_bytes: genesis_state.as_ssz_bytes(),
genesis_state_bytes,
};
} else {
client_config.genesis = ClientGenesis::DepositContract;
@ -545,9 +533,7 @@ pub fn get_data_dir(cli_args: &ArgMatches) -> PathBuf {
/// Try to parse the eth2 testnet config from the `testnet`, `testnet-dir` flags in that order.
/// Returns the default hardcoded testnet if neither flags are set.
pub fn get_eth2_testnet_config<E: EthSpec>(
cli_args: &ArgMatches,
) -> Result<Eth2TestnetConfig<E>, String> {
pub fn get_eth2_testnet_config(cli_args: &ArgMatches) -> Result<Eth2TestnetConfig, String> {
let optional_testnet_config = if cli_args.is_present("testnet") {
clap_utils::parse_hardcoded_network(cli_args, "testnet")?
} else if cli_args.is_present("testnet-dir") {

View File

@ -53,12 +53,8 @@ impl<E: EthSpec> ProductionBeaconNode<E> {
context: RuntimeContext<E>,
matches: ArgMatches<'static>,
) -> Result<Self, String> {
let client_config = get_config::<E>(
&matches,
&context.eth2_config.spec_constants,
&context.eth2_config().spec,
context.log().clone(),
)?;
let client_config =
get_config::<E>(&matches, &context.eth2_config().spec, context.log().clone())?;
Self::new(context, client_config).await
}

View File

@ -18,17 +18,15 @@ project.
The `Makefile` in the project contains four targets for cross-compiling:
- `build-x86_64`: builds an optimized version for x86_64 processors (suitable
for most users).
- `build-x86_64-portable`: builds a version x86_64 processors which avoids
using some modern CPU instructions that might cause an "illegal
instruction" error on older CPUs.
- `build-aarch64`: builds an optimized version for 64bit ARM processors
- `build-x86_64`: builds an optimized version for x86_64 processors (suitable for most users).
Supports Intel Broadwell (2014) and newer, and AMD Ryzen (2017) and newer.
- `build-x86_64-portable`: builds a version for x86_64 processors which avoids using some modern CPU
instructions that are incompatible with older CPUs. Suitable for pre-Broadwell/Ryzen CPUs.
- `build-aarch64`: builds an optimized version for 64-bit ARM processors
(suitable for Raspberry Pi 4).
- `build-aarch64-portable`: builds a version 64 bit ARM processors which avoids
using some modern CPU instructions that might cause an "illegal
instruction" error on older CPUs.
- `build-aarch64-portable`: builds a version for 64-bit ARM processors which avoids using some
modern CPU instructions. In practice, very few ARM processors lack the instructions necessary to
run the faster non-portable build.
### Example

View File

@ -43,9 +43,6 @@ OPTIONS:
--secrets-dir <SECRETS_DIR>
The path where the validator keystore passwords will be stored. Defaults to ~/.lighthouse/{testnet}/secrets
-s, --spec <TITLE>
Specifies the default eth2 spec type. [default: mainnet] [possible values: mainnet, minimal, interop]
--testnet <testnet>
Name of network lighthouse will connect to [possible values: medalla, altona]

View File

@ -43,9 +43,6 @@ OPTIONS:
A path to a file containing the password which will unlock the wallet. If the file does not exist, a random
password will be generated and saved at that path. To avoid confusion, if the file does not already exist it
must include a '.pass' suffix.
-s, --spec <TITLE>
Specifies the default eth2 spec type. [default: mainnet] [possible values: mainnet, minimal, interop]
-t, --testnet-dir <DIR>
Path to directory containing eth2_testnet specs. Defaults to a hard-coded Lighthouse testnet. Only effective
if there is no existing database.

View File

@ -1,6 +1,6 @@
[package]
name = "boot_node"
version = "0.3.1"
version = "0.3.2"
authors = ["Sigma Prime <contact@sigmaprime.io>"]
edition = "2018"

View File

@ -5,7 +5,6 @@ use eth2_libp2p::{
discovery::{create_enr_builder_from_config, use_or_load_enr},
load_private_key, CombinedKeyExt, NetworkConfig,
};
use eth2_testnet_config::Eth2TestnetConfig;
use ssz::Encode;
use std::convert::TryFrom;
use std::marker::PhantomData;
@ -30,7 +29,7 @@ impl<T: EthSpec> TryFrom<&ArgMatches<'_>> for BootNodeConfig<T> {
let data_dir = get_data_dir(matches);
// Try and grab testnet config from input CLI params
let eth2_testnet_config: Option<Eth2TestnetConfig<T>> = {
let eth2_testnet_config = {
if matches.is_present("testnet") {
Some(get_eth2_testnet_config(&matches)?)
} else {
@ -95,7 +94,9 @@ impl<T: EthSpec> TryFrom<&ArgMatches<'_>> for BootNodeConfig<T> {
.apply_to_chain_spec::<T>(&T::default_spec())
.ok_or_else(|| "The loaded config is not compatible with the current spec")?;
if let Some(genesis_state) = config.genesis_state.as_ref() {
if config.beacon_state_is_known() {
let genesis_state = config.beacon_state::<T>()?;
slog::info!(logger, "Genesis state found"; "root" => genesis_state.canonical_root().to_string());
let enr_fork = spec.enr_fork_id(
types::Slot::from(0u64),

View File

@ -8,12 +8,12 @@ mod config;
mod server;
pub use cli::cli_app;
use config::BootNodeConfig;
use types::EthSpec;
use types::{EthSpec, EthSpecId};
const LOG_CHANNEL_SIZE: usize = 2048;
/// Run the bootnode given the CLI configuration.
pub fn run(matches: &ArgMatches<'_>, debug_level: String) {
pub fn run(matches: &ArgMatches<'_>, eth_spec_id: EthSpecId, debug_level: String) {
let debug_level = match debug_level.as_str() {
"trace" => log::Level::Trace,
"debug" => log::Level::Debug,
@ -48,11 +48,10 @@ pub fn run(matches: &ArgMatches<'_>, debug_level: String) {
let log = slog_scope::logger();
// Run the main function emitting any errors
if let Err(e) = match matches.value_of("spec") {
Some("minimal") => main::<types::MinimalEthSpec>(matches, log),
Some("mainnet") => main::<types::MainnetEthSpec>(matches, log),
Some("interop") => main::<types::InteropEthSpec>(matches, log),
spec => unreachable!("Unknown spec configuration: {:?}", spec),
if let Err(e) = match eth_spec_id {
EthSpecId::Minimal => main::<types::MinimalEthSpec>(matches, log),
EthSpecId::Mainnet => main::<types::MainnetEthSpec>(matches, log),
EthSpecId::V012Legacy => main::<types::V012LegacyEthSpec>(matches, log),
} {
slog::crit!(slog_scope::logger(), "{}", e);
}

View File

@ -5,7 +5,6 @@ use eth2_testnet_config::Eth2TestnetConfig;
use ssz::Decode;
use std::path::PathBuf;
use std::str::FromStr;
use types::EthSpec;
pub const BAD_TESTNET_DIR_MESSAGE: &str = "The hard-coded testnet directory was invalid. \
This happens when Lighthouse is migrating between spec versions \
@ -14,10 +13,10 @@ pub const BAD_TESTNET_DIR_MESSAGE: &str = "The hard-coded testnet directory was
/// Attempts to load the testnet dir at the path if `name` is in `matches`, returning an error if
/// the path cannot be found or the testnet dir is invalid.
pub fn parse_testnet_dir<E: EthSpec>(
pub fn parse_testnet_dir(
matches: &ArgMatches,
name: &'static str,
) -> Result<Option<Eth2TestnetConfig<E>>, String> {
) -> Result<Option<Eth2TestnetConfig>, String> {
let path = parse_required::<PathBuf>(matches, name)?;
Eth2TestnetConfig::load(path.clone())
.map_err(|e| format!("Unable to open testnet dir at {:?}: {}", path, e))
@ -26,10 +25,10 @@ pub fn parse_testnet_dir<E: EthSpec>(
/// Attempts to load a hardcoded network config if `name` is in `matches`, returning an error if
/// the name is not a valid network name.
pub fn parse_hardcoded_network<E: EthSpec>(
pub fn parse_hardcoded_network(
matches: &ArgMatches,
name: &str,
) -> Result<Option<Eth2TestnetConfig<E>>, String> {
) -> Result<Option<Eth2TestnetConfig>, String> {
let network_name = parse_required::<String>(matches, name)?;
Eth2TestnetConfig::constant(network_name.as_str())
}

View File

@ -1,7 +1,7 @@
use serde_derive::{Deserialize, Serialize};
use std::env;
use std::path::PathBuf;
use types::ChainSpec;
use types::{ChainSpec, EthSpecId};
// A macro is used to define this constant so it can be used with `include_bytes!`.
#[macro_export]
@ -19,14 +19,14 @@ pub const GENESIS_ZIP_FILE_NAME: &str = "genesis.ssz.zip";
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct Eth2Config {
pub spec_constants: String,
pub eth_spec_id: EthSpecId,
pub spec: ChainSpec,
}
impl Default for Eth2Config {
fn default() -> Self {
Self {
spec_constants: "minimal".to_string(),
eth_spec_id: EthSpecId::Minimal,
spec: ChainSpec::minimal(),
}
}
@ -35,22 +35,22 @@ impl Default for Eth2Config {
impl Eth2Config {
pub fn mainnet() -> Self {
Self {
spec_constants: "mainnet".to_string(),
eth_spec_id: EthSpecId::Mainnet,
spec: ChainSpec::mainnet(),
}
}
pub fn minimal() -> Self {
Self {
spec_constants: "minimal".to_string(),
eth_spec_id: EthSpecId::Minimal,
spec: ChainSpec::minimal(),
}
}
pub fn interop() -> Self {
pub fn v012_legacy() -> Self {
Self {
spec_constants: "interop".to_string(),
spec: ChainSpec::interop(),
eth_spec_id: EthSpecId::V012Legacy,
spec: ChainSpec::v012_legacy(),
}
}
}

View File

@ -1,3 +1,4 @@
CONFIG_NAME: "altona"
MAX_COMMITTEES_PER_SLOT: 64
TARGET_COMMITTEE_SIZE: 128
MAX_VALIDATORS_PER_COMMITTEE: 2048
@ -56,3 +57,4 @@ DOMAIN_SELECTION_PROOF: 0x05000000
DOMAIN_AGGREGATE_AND_PROOF: 0x06000000
DEPOSIT_CHAIN_ID: 5
DEPOSIT_NETWORK_ID: 5
PROPORTIONAL_SLASHING_MULTIPLIER: 3

View File

@ -1,3 +1,4 @@
CONFIG_NAME: "medalla"
MAX_COMMITTEES_PER_SLOT: 64
TARGET_COMMITTEE_SIZE: 128
MAX_VALIDATORS_PER_COMMITTEE: 2048
@ -56,3 +57,4 @@ DOMAIN_SELECTION_PROOF: 0x05000000
DOMAIN_AGGREGATE_AND_PROOF: 0x06000000
DEPOSIT_CHAIN_ID: 5
DEPOSIT_NETWORK_ID: 5
PROPORTIONAL_SLASHING_MULTIPLIER: 3

View File

@ -1,3 +1,4 @@
CONFIG_NAME: "spadina"
MAX_COMMITTEES_PER_SLOT: 64
TARGET_COMMITTEE_SIZE: 128
MAX_VALIDATORS_PER_COMMITTEE: 2048

View File

@ -13,11 +13,11 @@ use eth2_config::{
};
use enr::{CombinedKey, Enr};
use ssz::{Decode, Encode};
use ssz::Decode;
use std::fs::{create_dir_all, File};
use std::io::{Read, Write};
use std::path::PathBuf;
use types::{Address, BeaconState, EthSpec, YamlConfig};
use types::{Address, BeaconState, EthSpec, EthSpecId, YamlConfig};
pub const ADDRESS_FILE: &str = "deposit_contract.txt";
pub const DEPLOY_BLOCK_FILE: &str = "deploy_block.txt";
@ -33,7 +33,7 @@ pub struct HardcodedNet {
pub deploy_block: &'static [u8],
pub boot_enr: &'static [u8],
pub deposit_contract_address: &'static [u8],
pub genesis_state: &'static [u8],
pub genesis_state_bytes: &'static [u8],
}
macro_rules! define_net {
@ -47,7 +47,7 @@ macro_rules! define_net {
deploy_block: $include_file!("../", "deploy_block.txt"),
boot_enr: $include_file!("../", "boot_enr.yaml"),
deposit_contract_address: $include_file!("../", "deposit_contract.txt"),
genesis_state: $include_file!("../", "genesis.ssz"),
genesis_state_bytes: $include_file!("../", "genesis.ssz"),
}
}};
}
@ -64,15 +64,15 @@ pub const DEFAULT_HARDCODED_TESTNET: &str = "medalla";
///
/// See the crate-level documentation for more details.
#[derive(Clone, PartialEq, Debug)]
pub struct Eth2TestnetConfig<E: EthSpec> {
pub struct Eth2TestnetConfig {
pub deposit_contract_address: String,
pub deposit_contract_deploy_block: u64,
pub boot_enr: Option<Vec<Enr<CombinedKey>>>,
pub genesis_state: Option<BeaconState<E>>,
pub genesis_state_bytes: Option<Vec<u8>>,
pub yaml_config: Option<YamlConfig>,
}
impl<E: EthSpec> Eth2TestnetConfig<E> {
impl Eth2TestnetConfig {
/// Returns the default hard coded testnet.
pub fn hard_coded_default() -> Result<Option<Self>, String> {
Self::constant(DEFAULT_HARDCODED_TESTNET)
@ -89,15 +89,6 @@ impl<E: EthSpec> Eth2TestnetConfig<E> {
/// Instantiates `Self` from a `HardcodedNet`.
fn from_hardcoded_net(net: &HardcodedNet) -> Result<Self, String> {
let genesis_state = if net.genesis_state.is_empty() {
None
} else {
Some(
BeaconState::from_ssz_bytes(net.genesis_state)
.map_err(|e| format!("Unable to parse genesis state: {:?}", e))?,
)
};
Ok(Self {
deposit_contract_address: serde_yaml::from_reader(net.deposit_contract_address)
.map_err(|e| format!("Unable to parse contract address: {:?}", e))?,
@ -107,7 +98,8 @@ impl<E: EthSpec> Eth2TestnetConfig<E> {
serde_yaml::from_reader(net.boot_enr)
.map_err(|e| format!("Unable to parse boot enr: {:?}", e))?,
),
genesis_state,
genesis_state_bytes: Some(net.genesis_state_bytes.to_vec())
.filter(|bytes| !bytes.is_empty()),
yaml_config: Some(
serde_yaml::from_reader(net.yaml_config)
.map_err(|e| format!("Unable to parse yaml config: {:?}", e))?,
@ -115,9 +107,38 @@ impl<E: EthSpec> Eth2TestnetConfig<E> {
})
}
// Write the files to the directory.
//
// Overwrites files if specified to do so.
/// Returns an identifier that should be used for selecting an `EthSpec` instance for this
/// testnet.
pub fn eth_spec_id(&self) -> Result<EthSpecId, String> {
self.yaml_config
.as_ref()
.ok_or_else(|| "YAML specification file missing".to_string())
.and_then(|config| {
config
.eth_spec_id()
.ok_or_else(|| format!("Unknown CONFIG_NAME: {}", config.config_name))
})
}
/// Returns `true` if this configuration contains a `BeaconState`.
pub fn beacon_state_is_known(&self) -> bool {
self.genesis_state_bytes.is_some()
}
/// Attempts to deserialize `self.beacon_state`, returning an error if it's missing or invalid.
pub fn beacon_state<E: EthSpec>(&self) -> Result<BeaconState<E>, String> {
let genesis_state_bytes = self
.genesis_state_bytes
.as_ref()
.ok_or_else(|| "Genesis state is unknown".to_string())?;
BeaconState::from_ssz_bytes(genesis_state_bytes)
.map_err(|e| format!("Genesis state SSZ bytes are invalid: {:?}", e))
}
/// Write the files to the directory.
///
/// Overwrites files if specified to do so.
pub fn write_to_file(&self, base_dir: PathBuf, overwrite: bool) -> Result<(), String> {
if base_dir.exists() && !overwrite {
return Err("Testnet directory already exists".to_string());
@ -126,7 +147,7 @@ impl<E: EthSpec> Eth2TestnetConfig<E> {
self.force_write_to_file(base_dir)
}
// Write the files to the directory, even if the directory already exists.
/// Write the files to the directory, even if the directory already exists.
pub fn force_write_to_file(&self, base_dir: PathBuf) -> Result<(), String> {
create_dir_all(&base_dir)
.map_err(|e| format!("Unable to create testnet directory: {:?}", e))?;
@ -167,13 +188,13 @@ impl<E: EthSpec> Eth2TestnetConfig<E> {
}
// The genesis state is a special case because it uses SSZ, not YAML.
if let Some(genesis_state) = &self.genesis_state {
if let Some(genesis_state_bytes) = &self.genesis_state_bytes {
let file = base_dir.join(GENESIS_STATE_FILE);
File::create(&file)
.map_err(|e| format!("Unable to create {:?}: {:?}", file, e))
.and_then(|mut file| {
file.write_all(&genesis_state.as_ssz_bytes())
file.write_all(genesis_state_bytes)
.map_err(|e| format!("Unable to write {:?}: {:?}", file, e))
})?;
}
@ -210,19 +231,15 @@ impl<E: EthSpec> Eth2TestnetConfig<E> {
// The genesis state is a special case because it uses SSZ, not YAML.
let genesis_file_path = base_dir.join(GENESIS_STATE_FILE);
let genesis_state = if genesis_file_path.exists() {
Some(
File::open(&genesis_file_path)
.map_err(|e| format!("Unable to open {:?}: {:?}", genesis_file_path, e))
.and_then(|mut file| {
let mut bytes = vec![];
file.read_to_end(&mut bytes)
.map_err(|e| format!("Unable to read {:?}: {:?}", file, e))?;
BeaconState::from_ssz_bytes(&bytes)
.map_err(|e| format!("Unable to SSZ decode {:?}: {:?}", file, e))
})?,
)
let genesis_state_bytes = if genesis_file_path.exists() {
let mut bytes = vec![];
File::open(&genesis_file_path)
.map_err(|e| format!("Unable to open {:?}: {:?}", genesis_file_path, e))
.and_then(|mut file| {
file.read_to_end(&mut bytes)
.map_err(|e| format!("Unable to read {:?}: {:?}", file, e))
})?;
Some(bytes)
} else {
None
};
@ -231,7 +248,7 @@ impl<E: EthSpec> Eth2TestnetConfig<E> {
deposit_contract_address,
deposit_contract_deploy_block,
boot_enr,
genesis_state,
genesis_state_bytes,
yaml_config,
})
}
@ -250,18 +267,28 @@ impl<E: EthSpec> Eth2TestnetConfig<E> {
#[cfg(test)]
mod tests {
use super::*;
use ssz::Encode;
use tempdir::TempDir;
use types::{Eth1Data, Hash256, MainnetEthSpec, YamlConfig};
use types::{Eth1Data, Hash256, V012LegacyEthSpec, YamlConfig};
type E = MainnetEthSpec;
type E = V012LegacyEthSpec;
#[test]
fn hard_coded_nets_work() {
for net in HARDCODED_NETS {
let config =
Eth2TestnetConfig::<E>::from_hardcoded_net(net).expect(&format!("{:?}", net.name));
Eth2TestnetConfig::from_hardcoded_net(net).expect(&format!("{:?}", net.name));
// Ensure we can parse the YAML config to a chain spec.
config
.yaml_config
.as_ref()
.unwrap()
.apply_to_chain_spec::<E>(&E::default_spec())
.unwrap();
assert_eq!(
config.genesis_state.is_some(),
config.genesis_state_bytes.is_some(),
net.genesis_is_known,
"{:?}",
net.name
@ -298,11 +325,11 @@ mod tests {
let deposit_contract_address = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".to_string();
let deposit_contract_deploy_block = 42;
let testnet: Eth2TestnetConfig<E> = Eth2TestnetConfig {
let testnet: Eth2TestnetConfig = Eth2TestnetConfig {
deposit_contract_address,
deposit_contract_deploy_block,
boot_enr,
genesis_state,
genesis_state_bytes: genesis_state.as_ref().map(Encode::as_ssz_bytes),
yaml_config,
};

View File

@ -10,7 +10,7 @@ use target_info::Target;
/// `Lighthouse/v0.2.0-1419501f2+`
pub const VERSION: &str = git_version!(
args = ["--always", "--dirty=+"],
prefix = "Lighthouse/v0.3.1-",
prefix = "Lighthouse/v0.3.2-",
fallback = "unknown"
);

View File

@ -5,7 +5,7 @@ authors = ["Sigma Prime <contact@sigmaprime.io>"]
edition = "2018"
[dependencies]
tokio = "0.2.22"
tokio = { version = "0.2.22", features = ["rt-threaded", "macros", "blocking"] }
slog = "2.5.2"
futures = "0.3.5"
exit-future = "0.2.0"

View File

@ -264,7 +264,6 @@ impl ChainSpec {
hysteresis_quotient: 4,
hysteresis_downward_multiplier: 1,
hysteresis_upward_multiplier: 5,
proportional_slashing_multiplier: 3,
/*
* Gwei values
@ -283,7 +282,7 @@ impl ChainSpec {
/*
* Time parameters
*/
genesis_delay: 172800, // 2 days
genesis_delay: 604800, // 7 days
milliseconds_per_slot: 12_000,
min_attestation_inclusion_delay: 1,
min_seed_lookahead: Epoch::new(1),
@ -298,8 +297,9 @@ impl ChainSpec {
base_reward_factor: 64,
whistleblower_reward_quotient: 512,
proposer_reward_quotient: 8,
inactivity_penalty_quotient: u64::pow(2, 24),
min_slashing_penalty_quotient: 32,
inactivity_penalty_quotient: u64::pow(2, 26),
min_slashing_penalty_quotient: 128,
proportional_slashing_multiplier: 1,
/*
* Signature domains
@ -320,7 +320,7 @@ impl ChainSpec {
/*
* Eth1
*/
eth1_follow_distance: 1_024,
eth1_follow_distance: 2048,
seconds_per_eth1_block: 14,
deposit_chain_id: 1,
deposit_network_id: 1,
@ -359,6 +359,9 @@ impl ChainSpec {
shard_committee_period: 64,
genesis_delay: 300,
milliseconds_per_slot: 6_000,
inactivity_penalty_quotient: u64::pow(2, 25),
min_slashing_penalty_quotient: 64,
proportional_slashing_multiplier: 2,
safe_slots_to_update_justified: 2,
network_id: 2, // lighthouse testnet network id
deposit_chain_id: 5,
@ -368,17 +371,19 @@ impl ChainSpec {
}
}
/// Interop testing spec
/// Suits the `v0.12.3` version of the eth2 spec:
/// https://github.com/ethereum/eth2.0-specs/blob/v0.12.3/configs/mainnet/phase0.yaml
///
/// This allows us to customize a chain spec for interop testing.
pub fn interop() -> Self {
/// This method only needs to exist whilst we provide support for "legacy" testnets prior to v1.0.0
/// (e.g., Medalla, Zinken, Spadina, Altona, etc.).
pub fn v012_legacy() -> Self {
let boot_nodes = vec![];
Self {
milliseconds_per_slot: 12_000,
target_committee_size: 4,
shuffle_round_count: 10,
network_id: 13,
genesis_delay: 172_800, // 2 days
inactivity_penalty_quotient: u64::pow(2, 24),
min_slashing_penalty_quotient: 32,
eth1_follow_distance: 1024,
boot_nodes,
..ChainSpec::mainnet()
}
@ -448,8 +453,7 @@ mod tests {
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "UPPERCASE", deny_unknown_fields)]
pub struct YamlConfig {
#[serde(default)]
config_name: String,
pub config_name: String,
// ChainSpec
#[serde(with = "serde_utils::quoted_u64")]
max_committees_per_slot: u64,
@ -481,10 +485,6 @@ pub struct YamlConfig {
hysteresis_downward_multiplier: u64,
#[serde(with = "serde_utils::quoted_u64")]
hysteresis_upward_multiplier: u64,
// Proportional slashing multiplier defaults to 3 for compatibility with Altona and Medalla.
#[serde(default = "default_proportional_slashing_multiplier")]
#[serde(with = "serde_utils::quoted_u64")]
proportional_slashing_multiplier: u64,
#[serde(with = "serde_utils::bytes_4_hex")]
genesis_fork_version: [u8; 4],
#[serde(with = "serde_utils::u8_hex")]
@ -514,6 +514,8 @@ pub struct YamlConfig {
#[serde(with = "serde_utils::quoted_u64")]
min_slashing_penalty_quotient: u64,
#[serde(with = "serde_utils::quoted_u64")]
proportional_slashing_multiplier: u64,
#[serde(with = "serde_utils::quoted_u64")]
safe_slots_to_update_justified: u64,
#[serde(with = "serde_utils::u32_hex")]
@ -575,11 +577,6 @@ pub struct YamlConfig {
deposit_contract_address: Address,
}
// Compatibility shim for proportional slashing multpilier on Altona and Medalla.
fn default_proportional_slashing_multiplier() -> u64 {
3
}
impl Default for YamlConfig {
fn default() -> Self {
let chain_spec = MainnetEthSpec::default_spec();
@ -594,6 +591,21 @@ fn milliseconds_to_seconds(millis: u64) -> u64 {
/// Spec v0.12.1
impl YamlConfig {
/// Maps `self.config_name` to an identifier for an `EthSpec` instance.
///
/// Returns `None` if there is no match.
pub fn eth_spec_id(&self) -> Option<EthSpecId> {
Some(match self.config_name.as_str() {
"mainnet" => EthSpecId::Mainnet,
"minimal" => EthSpecId::Minimal,
"zinken" => EthSpecId::V012Legacy,
"spadina" => EthSpecId::V012Legacy,
"medalla" => EthSpecId::V012Legacy,
"altona" => EthSpecId::V012Legacy,
_ => return None,
})
}
pub fn from_spec<T: EthSpec>(spec: &ChainSpec) -> Self {
Self {
config_name: T::spec_name().to_string(),

View File

@ -6,7 +6,45 @@ use ssz_types::typenum::{
Unsigned, U0, U1024, U1099511627776, U128, U16, U16777216, U2, U2048, U32, U4, U4096, U64,
U65536, U8, U8192,
};
use std::fmt::Debug;
use std::fmt::{self, Debug};
use std::str::FromStr;
const MAINNET: &str = "mainnet";
const MINIMAL: &str = "minimal";
const LEGACY: &str = "v0.12-legacy";
/// Used to identify one of the `EthSpec` instances defined here.
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum EthSpecId {
Mainnet,
Minimal,
V012Legacy,
}
impl FromStr for EthSpecId {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
MAINNET => Ok(EthSpecId::Mainnet),
MINIMAL => Ok(EthSpecId::Minimal),
LEGACY => Ok(EthSpecId::V012Legacy),
_ => Err(format!("Unknown eth spec: {}", s)),
}
}
}
impl fmt::Display for EthSpecId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
EthSpecId::Mainnet => MAINNET,
EthSpecId::Minimal => MINIMAL,
EthSpecId::V012Legacy => LEGACY,
};
write!(f, "{}", s)
}
}
pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + Eq {
/*
@ -56,7 +94,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
fn default_spec() -> ChainSpec;
fn spec_name() -> &'static str;
fn spec_name() -> EthSpecId;
fn genesis_epoch() -> Epoch {
Epoch::new(Self::GenesisEpoch::to_u64())
@ -144,7 +182,7 @@ impl EthSpec for MainnetEthSpec {
type MaxValidatorsPerCommittee = U2048;
type GenesisEpoch = U0;
type SlotsPerEpoch = U32;
type EpochsPerEth1VotingPeriod = U32;
type EpochsPerEth1VotingPeriod = U64;
type SlotsPerHistoricalRoot = U8192;
type EpochsPerHistoricalVector = U65536;
type EpochsPerSlashingsVector = U8192;
@ -156,14 +194,14 @@ impl EthSpec for MainnetEthSpec {
type MaxDeposits = U16;
type MaxVoluntaryExits = U16;
type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch
type SlotsPerEth1VotingPeriod = U1024; // 32 epochs * 32 slots per epoch
type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch
fn default_spec() -> ChainSpec {
ChainSpec::mainnet()
}
fn spec_name() -> &'static str {
"mainnet"
fn spec_name() -> EthSpecId {
EthSpecId::Mainnet
}
}
@ -203,28 +241,32 @@ impl EthSpec for MinimalEthSpec {
ChainSpec::minimal()
}
fn spec_name() -> &'static str {
"minimal"
fn spec_name() -> EthSpecId {
EthSpecId::Minimal
}
}
pub type MinimalBeaconState = BeaconState<MinimalEthSpec>;
/// Interop testnet spec
/// Suits the `v0.12.3` version of the eth2 spec:
/// https://github.com/ethereum/eth2.0-specs/blob/v0.12.3/configs/mainnet/phase0.yaml
///
/// This struct only needs to exist whilst we provide support for "legacy" testnets prior to v1.0.0
/// (e.g., Medalla, Zinken, Spadina, Altona, etc.).
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
pub struct InteropEthSpec;
pub struct V012LegacyEthSpec;
impl EthSpec for InteropEthSpec {
type SlotsPerEpoch = U8;
type EpochsPerEth1VotingPeriod = U2;
type SlotsPerHistoricalRoot = U64;
type EpochsPerHistoricalVector = U64;
type EpochsPerSlashingsVector = U64;
type MaxPendingAttestations = U1024; // 128 max attestations * 8 slots per epoch
type SlotsPerEth1VotingPeriod = U16; // 2 epochs * 8 slots per epoch
impl EthSpec for V012LegacyEthSpec {
type EpochsPerEth1VotingPeriod = U32;
type SlotsPerEth1VotingPeriod = U1024; // 32 epochs * 32 slots per epoch
params_from_eth_spec!(MainnetEthSpec {
SlotsPerEpoch,
SlotsPerHistoricalRoot,
EpochsPerHistoricalVector,
EpochsPerSlashingsVector,
MaxPendingAttestations,
JustificationBitsLength,
SubnetBitfieldLength,
MaxValidatorsPerCommittee,
@ -239,12 +281,10 @@ impl EthSpec for InteropEthSpec {
});
fn default_spec() -> ChainSpec {
ChainSpec::interop()
ChainSpec::v012_legacy()
}
fn spec_name() -> &'static str {
"interop"
fn spec_name() -> EthSpecId {
EthSpecId::V012Legacy
}
}
pub type InteropBeaconState = BeaconState<InteropEthSpec>;

View File

@ -73,6 +73,7 @@ pub use crate::deposit_data::DepositData;
pub use crate::deposit_message::DepositMessage;
pub use crate::enr_fork_id::EnrForkId;
pub use crate::eth1_data::Eth1Data;
pub use crate::eth_spec::EthSpecId;
pub use crate::fork::Fork;
pub use crate::fork_data::ForkData;
pub use crate::free_attestation::FreeAttestation;

View File

@ -8,6 +8,7 @@ use ssz_derive::{Decode, Encode};
use std::fmt;
use test_random_derive::TestRandom;
use tree_hash::TreeHash;
use tree_hash_derive::TreeHash;
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
@ -41,7 +42,7 @@ impl From<SignedBeaconBlockHash> for Hash256 {
///
/// Spec v0.12.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TestRandom)]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
#[serde(bound = "E: EthSpec")]
pub struct SignedBeaconBlock<E: EthSpec> {
pub message: BeaconBlock<E>,

View File

@ -7,7 +7,7 @@ edition = "2018"
[dependencies]
eth2_ssz = "0.1.2"
tree_hash = "0.1.1"
milagro_bls = { git = "https://github.com/sigp/milagro_bls", branch = "paulh" }
milagro_bls = { git = "https://github.com/sigp/milagro_bls", tag = "v1.4.0" }
rand = "0.7.3"
serde = "1.0.116"
serde_derive = "1.0.116"
@ -17,7 +17,7 @@ eth2_hashing = "0.1.0"
ethereum-types = "0.9.2"
arbitrary = { version = "0.4.6", features = ["derive"], optional = true }
zeroize = { version = "1.1.1", features = ["zeroize_derive"] }
blst = { git = "https://github.com/sigp/blst.git", rev = "284f7059642851c760a09fb1708bcb59c7ca323c" }
blst = { git = "https://github.com/sigp/blst.git", rev = "7cf47864627ca479cad06c2a164f30d0cbaf16ce" }
[features]
default = ["supranational"]
@ -25,3 +25,4 @@ fake_crypto = []
milagro = []
supranational = []
supranational-portable = ["supranational", "blst/portable"]
supranational-force-adx = ["supranational", "blst/force-adx"]

View File

@ -1,17 +1,5 @@
use crate::{Error, PUBLIC_KEY_BYTES_LEN};
/// Implemented on some struct from a BLS library so it may be used internally in this crate.
pub trait TAggregatePublicKey: Sized + Clone {
/// Initialize `Self` to the infinity value which can then have other public keys aggregated
/// upon it.
fn infinity() -> Self;
/// Serialize `self` as compressed bytes.
fn serialize(&self) -> [u8; PUBLIC_KEY_BYTES_LEN];
/// Deserialize `self` from compressed bytes.
fn deserialize(bytes: &[u8]) -> Result<Self, Error>;
}
pub trait TAggregatePublicKey: Sized + Clone {}
/*
* Note: there is no immediate need for a `GenericAggregatePublicKey` struct.

View File

@ -183,13 +183,6 @@ where
return false;
}
if self.is_infinity
&& pubkeys.len() == 1
&& pubkeys.first().map_or(false, |pk| pk.is_infinity)
{
return true;
}
match self.point.as_ref() {
Some(point) => point.fast_aggregate_verify(msg, pubkeys),
None => false,
@ -207,13 +200,6 @@ where
return false;
}
if self.is_infinity
&& pubkeys.len() == 1
&& pubkeys.first().map_or(false, |pk| pk.is_infinity)
{
return true;
}
match self.point.as_ref() {
Some(point) => point.aggregate_verify(msgs, pubkeys),
None => false,

View File

@ -33,8 +33,6 @@ pub trait TPublicKey: Sized + Clone {
pub struct GenericPublicKey<Pub> {
/// The underlying point which performs *actual* cryptographic operations.
point: Pub,
/// True if this point is equal to the `INFINITY_PUBLIC_KEY`.
pub(crate) is_infinity: bool,
}
impl<Pub> GenericPublicKey<Pub>
@ -42,8 +40,8 @@ where
Pub: TPublicKey,
{
/// Instantiates `Self` from a `point`.
pub(crate) fn from_point(point: Pub, is_infinity: bool) -> Self {
Self { point, is_infinity }
pub(crate) fn from_point(point: Pub) -> Self {
Self { point }
}
/// Returns a reference to the underlying BLS point.
@ -63,10 +61,13 @@ where
/// Deserialize `self` from compressed bytes.
pub fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
Ok(Self {
point: Pub::deserialize(bytes)?,
is_infinity: bytes == &INFINITY_PUBLIC_KEY[..],
})
if bytes == &INFINITY_PUBLIC_KEY[..] {
Err(Error::InvalidInfinityPublicKey)
} else {
Ok(Self {
point: Pub::deserialize(bytes)?,
})
}
}
}

View File

@ -1,6 +1,6 @@
use crate::{
generic_public_key::{GenericPublicKey, TPublicKey},
Error, INFINITY_PUBLIC_KEY, PUBLIC_KEY_BYTES_LEN,
Error, PUBLIC_KEY_BYTES_LEN,
};
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
@ -32,8 +32,7 @@ where
///
/// May fail if the bytes are invalid.
pub fn decompress(&self) -> Result<GenericPublicKey<Pub>, Error> {
let is_infinity = self.bytes[..] == INFINITY_PUBLIC_KEY[..];
Pub::deserialize(&self.bytes).map(|point| GenericPublicKey::from_point(point, is_infinity))
GenericPublicKey::deserialize(&self.bytes)
}
}

View File

@ -58,8 +58,7 @@ where
/// Returns the public key that corresponds to self.
pub fn public_key(&self) -> GenericPublicKey<Pub> {
let is_infinity = false;
GenericPublicKey::from_point(self.point.public_key(), is_infinity)
GenericPublicKey::from_point(self.point.public_key())
}
/// Serialize `self` as compressed bytes.
@ -79,6 +78,8 @@ where
got: bytes.len(),
expected: SECRET_KEY_BYTES_LEN,
})
} else if bytes.iter().all(|b| *b == 0) {
Err(Error::InvalidZeroSecretKey)
} else {
Ok(Self {
point: Sec::deserialize(bytes)?,

View File

@ -125,10 +125,6 @@ where
{
/// Returns `true` if `self` is a signature across `msg` by `pubkey`.
pub fn verify(&self, pubkey: &GenericPublicKey<Pub>, msg: Hash256) -> bool {
if self.is_infinity && pubkey.is_infinity {
return true;
}
if let Some(point) = &self.point {
point.verify(pubkey.point(), msg)
} else {

View File

@ -4,7 +4,7 @@ use crate::{
generic_public_key::{GenericPublicKey, TPublicKey, PUBLIC_KEY_BYTES_LEN},
generic_secret_key::TSecretKey,
generic_signature::{TSignature, SIGNATURE_BYTES_LEN},
Error, Hash256, ZeroizeHash, INFINITY_PUBLIC_KEY, INFINITY_SIGNATURE,
Error, Hash256, ZeroizeHash, INFINITY_SIGNATURE,
};
pub use blst::min_pk as blst_core;
use blst::{blst_scalar, BLST_ERROR};
@ -50,18 +50,12 @@ pub fn verify_signature_sets<'a>(
let mut pks = Vec::with_capacity(sets.len());
for set in &sets {
// If this set is simply an infinity signature and infinity pubkey then skip verification.
// This has the effect of always declaring that this sig/pubkey combination is valid.
if set.signature.is_infinity
&& set.signing_keys.len() == 1
&& set.signing_keys.first().map_or(false, |pk| pk.is_infinity)
{
continue;
}
// Generate random scalars.
let mut vals = [0u64; 4];
vals[0] = rng.gen();
while vals[0] == 0 {
// Do not use zero
vals[0] = rng.gen();
}
let mut rand_i = std::mem::MaybeUninit::<blst_scalar>::uninit();
// TODO: remove this `unsafe` code-block once we get a safe option from `blst`.
@ -75,8 +69,12 @@ pub fn verify_signature_sets<'a>(
// Grab a slice of the message, to satisfy the blst API.
msgs_refs.push(set.message.as_bytes());
// Convert the aggregate signature into a signature.
if let Some(point) = set.signature.point() {
// Subgroup check the signature
if !point.0.subgroup_check() {
return false;
}
// Convert the aggregate signature into a signature.
sigs.push(point.0.to_signature())
} else {
// Any "empty" signature should cause a signature failure.
@ -103,12 +101,6 @@ pub fn verify_signature_sets<'a>(
pks.push(blst_core::AggregatePublicKey::aggregate(&signing_keys).to_public_key());
}
// Due to an earlier check, the only case this can be empty is if all the sets consisted of
// infinity pubkeys/sigs. In such a case we wish to return `true`.
if msgs_refs.is_empty() {
return true;
}
let (sig_refs, pks_refs): (Vec<_>, Vec<_>) = sigs.iter().zip(pks.iter()).unzip();
let err = blst_core::Signature::verify_multiple_aggregate_signatures(
@ -124,7 +116,15 @@ impl TPublicKey for blst_core::PublicKey {
}
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
Self::uncompress(&bytes).map_err(Into::into)
// key_validate accepts uncompressed bytes too so enforce byte length here.
// It also does subgroup checks, noting infinity check is done in `generic_public_key.rs`.
if bytes.len() != PUBLIC_KEY_BYTES_LEN {
return Err(Error::InvalidByteLength {
got: bytes.len(),
expected: PUBLIC_KEY_BYTES_LEN,
});
}
Self::key_validate(&bytes).map_err(Into::into)
}
}
@ -145,25 +145,7 @@ impl PartialEq for BlstAggregatePublicKey {
}
}
impl TAggregatePublicKey for BlstAggregatePublicKey {
fn infinity() -> Self {
blst_core::PublicKey::from_bytes(&INFINITY_PUBLIC_KEY)
.map(|pk| blst_core::AggregatePublicKey::from_public_key(&pk))
.map(Self)
.expect("should decode infinity public key")
}
fn serialize(&self) -> [u8; PUBLIC_KEY_BYTES_LEN] {
self.0.to_public_key().compress()
}
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
blst_core::PublicKey::from_bytes(&bytes)
.map_err(Into::into)
.map(|pk| blst_core::AggregatePublicKey::from_public_key(&pk))
.map(Self)
}
}
impl TAggregatePublicKey for BlstAggregatePublicKey {}
impl TSignature<blst_core::PublicKey> for blst_core::Signature {
fn serialize(&self) -> [u8; SIGNATURE_BYTES_LEN] {
@ -175,6 +157,9 @@ impl TSignature<blst_core::PublicKey> for blst_core::Signature {
}
fn verify(&self, pubkey: &blst_core::PublicKey, msg: Hash256) -> bool {
if !self.subgroup_check() {
return false;
}
self.verify(msg.as_bytes(), DST, &[], pubkey) == BLST_ERROR::BLST_SUCCESS
}
}
@ -232,6 +217,9 @@ impl TAggregateSignature<blst_core::PublicKey, BlstAggregatePublicKey, blst_core
) -> bool {
let pubkeys = pubkeys.iter().map(|pk| pk.point()).collect::<Vec<_>>();
let signature = self.0.clone().to_signature();
if !signature.subgroup_check() {
return false;
}
signature.fast_aggregate_verify(msg.as_bytes(), DST, &pubkeys) == BLST_ERROR::BLST_SUCCESS
}
@ -243,6 +231,9 @@ impl TAggregateSignature<blst_core::PublicKey, BlstAggregatePublicKey, blst_core
let pubkeys = pubkeys.iter().map(|pk| pk.point()).collect::<Vec<_>>();
let msgs = msgs.iter().map(|hash| hash.as_bytes()).collect::<Vec<_>>();
let signature = self.0.clone().to_signature();
if !signature.subgroup_check() {
return false;
}
signature.aggregate_verify(&msgs, DST, &pubkeys) == BLST_ERROR::BLST_SUCCESS
}
}

View File

@ -63,25 +63,7 @@ impl PartialEq for PublicKey {
#[derive(Clone)]
pub struct AggregatePublicKey([u8; PUBLIC_KEY_BYTES_LEN]);
impl TAggregatePublicKey for AggregatePublicKey {
fn infinity() -> Self {
Self([0; PUBLIC_KEY_BYTES_LEN])
}
fn serialize(&self) -> [u8; PUBLIC_KEY_BYTES_LEN] {
let mut bytes = [0; PUBLIC_KEY_BYTES_LEN];
bytes[..].copy_from_slice(&self.0);
bytes
}
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
let mut key = [0; PUBLIC_KEY_BYTES_LEN];
key[..].copy_from_slice(&bytes);
Ok(Self(key))
}
}
impl TAggregatePublicKey for AggregatePublicKey {}
impl Eq for AggregatePublicKey {}

View File

@ -4,7 +4,7 @@ use crate::{
generic_public_key::{GenericPublicKey, TPublicKey, PUBLIC_KEY_BYTES_LEN},
generic_secret_key::{TSecretKey, SECRET_KEY_BYTES_LEN},
generic_signature::{TSignature, SIGNATURE_BYTES_LEN},
Error, Hash256, ZeroizeHash, INFINITY_PUBLIC_KEY,
Error, Hash256, ZeroizeHash,
};
pub use milagro_bls as milagro;
use rand::thread_rng;
@ -86,21 +86,7 @@ impl TPublicKey for milagro::PublicKey {
}
}
impl TAggregatePublicKey for milagro::AggregatePublicKey {
fn infinity() -> Self {
Self::from_bytes(&INFINITY_PUBLIC_KEY).expect("should decode infinity public key")
}
fn serialize(&self) -> [u8; PUBLIC_KEY_BYTES_LEN] {
let mut bytes = [0; PUBLIC_KEY_BYTES_LEN];
bytes[..].copy_from_slice(&self.as_bytes());
bytes
}
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
Self::from_bytes(&bytes).map_err(Into::into)
}
}
impl TAggregatePublicKey for milagro::AggregatePublicKey {}
impl TSignature<milagro::PublicKey> for milagro::Signature {
fn serialize(&self) -> [u8; SIGNATURE_BYTES_LEN] {

View File

@ -56,6 +56,10 @@ pub enum Error {
InvalidByteLength { got: usize, expected: usize },
/// The provided secret key bytes were an incorrect length.
InvalidSecretKeyLength { got: usize, expected: usize },
/// The public key represents the point at infinity, which is invalid.
InvalidInfinityPublicKey,
/// The secret key is all zero bytes, which is invalid.
InvalidZeroSecretKey,
}
impl From<AmclError> for Error {

View File

@ -1,4 +1,4 @@
use bls::{Hash256, INFINITY_PUBLIC_KEY, INFINITY_SIGNATURE};
use bls::{Hash256, INFINITY_SIGNATURE, SECRET_KEY_BYTES_LEN};
use ssz::{Decode, Encode};
use std::borrow::Cow;
use std::fmt::Debug;
@ -19,6 +19,11 @@ macro_rules! test_suite {
SecretKey::deserialize(&secret_bytes).unwrap()
}
#[test]
fn invalid_zero_secret_key() {
assert!(SecretKey::deserialize(&[0; SECRET_KEY_BYTES_LEN]).is_err());
}
#[test]
fn infinity_agg_sig() {
assert_eq!(
@ -131,11 +136,6 @@ macro_rules! test_suite {
self
}
pub fn infinity_pubkey(mut self) -> Self {
self.pubkey = PublicKey::deserialize(&INFINITY_PUBLIC_KEY[..]).unwrap();
self
}
pub fn assert_verify(self, is_valid: bool) {
assert_eq!(self.sig.verify(&self.pubkey, self.msg), is_valid);
@ -153,14 +153,6 @@ macro_rules! test_suite {
SignatureTester::default().assert_verify(true)
}
#[test]
fn infinity_signature_is_valid_with_infinity_pubkey() {
SignatureTester::default()
.infinity_sig()
.infinity_pubkey()
.assert_verify(true)
}
#[test]
fn infinity_signature_is_invalid_with_standard_pubkey() {
SignatureTester::default()
@ -168,13 +160,6 @@ macro_rules! test_suite {
.assert_verify(false)
}
#[test]
fn standard_signature_is_invalid_with_infinity_pubkey() {
SignatureTester::default()
.infinity_pubkey()
.assert_verify(false)
}
/// A helper struct for composing tests via the builder pattern.
struct AggregateSignatureTester {
sig: AggregateSignature,
@ -234,17 +219,6 @@ macro_rules! test_suite {
self
}
pub fn single_infinity_pubkey(mut self) -> Self {
self.pubkeys = vec![PublicKey::deserialize(&INFINITY_PUBLIC_KEY[..]).unwrap()];
self
}
pub fn push_infinity_pubkey(mut self) -> Self {
self.pubkeys
.push(PublicKey::deserialize(&INFINITY_PUBLIC_KEY[..]).unwrap());
self
}
pub fn assert_single_message_verify(self, is_valid: bool) {
assert!(self.msgs.len() == 1);
let msg = self.msgs.first().unwrap();
@ -304,15 +278,6 @@ macro_rules! test_suite {
.assert_single_message_verify(false)
}
/// The infinity signature and one infinity pubkey should verify.
#[test]
fn fast_aggregate_verify_infinity_signature_with_one_infinity_pubkey() {
AggregateSignatureTester::new_with_single_msg(1)
.infinity_sig()
.single_infinity_pubkey()
.assert_single_message_verify(true)
}
/// Adding a infinity signature (without an infinity pubkey) should verify.
#[test]
fn fast_aggregate_verify_with_one_aggregated_infinity_sig() {
@ -332,34 +297,6 @@ macro_rules! test_suite {
.assert_single_message_verify(true)
}
/// Adding a infinity pubkey and an infinity signature should verify.
#[test]
fn fast_aggregate_verify_with_one_additional_infinity_pubkey_and_matching_sig() {
AggregateSignatureTester::new_with_single_msg(1)
.aggregate_infinity_sig()
.push_infinity_pubkey()
.assert_single_message_verify(true)
}
/// Adding a single infinity pubkey **without** updating the signature **should verify**.
#[test]
fn fast_aggregate_verify_with_one_additional_infinity_pubkey() {
AggregateSignatureTester::new_with_single_msg(1)
.push_infinity_pubkey()
.assert_single_message_verify(true)
}
/// Adding multiple infinity pubkeys **without** updating the signature **should verify**.
#[test]
fn fast_aggregate_verify_with_four_additional_infinity_pubkeys() {
AggregateSignatureTester::new_with_single_msg(1)
.push_infinity_pubkey()
.push_infinity_pubkey()
.push_infinity_pubkey()
.push_infinity_pubkey()
.assert_single_message_verify(true)
}
/// The wrong signature should not verify.
#[test]
fn fast_aggregate_verify_wrong_signature() {
@ -463,18 +400,6 @@ macro_rules! test_suite {
self
}
pub fn push_invalid_sig_infinity_set(mut self) -> Self {
let mut signature = AggregateSignature::infinity();
signature.add_assign(&secret_from_u64(42).sign(Hash256::zero()));
self.owned_sets.push(OwnedSignatureSet {
signature,
signing_keys: vec![PublicKey::deserialize(&INFINITY_PUBLIC_KEY).unwrap()],
message: Hash256::zero(),
should_be_valid: false,
});
self
}
pub fn push_invalid_pubkey_infinity_set(mut self) -> Self {
self.owned_sets.push(OwnedSignatureSet {
signature: AggregateSignature::deserialize(&INFINITY_SIGNATURE).unwrap(),
@ -485,16 +410,6 @@ macro_rules! test_suite {
self
}
pub fn push_valid_infinity_set(mut self) -> Self {
self.owned_sets.push(OwnedSignatureSet {
signature: AggregateSignature::deserialize(&INFINITY_SIGNATURE).unwrap(),
signing_keys: vec![PublicKey::deserialize(&INFINITY_PUBLIC_KEY).unwrap()],
message: Hash256::zero(),
should_be_valid: true,
});
self
}
pub fn run_checks(self) {
assert!(!self.owned_sets.is_empty(), "empty test is meaningless");
@ -568,22 +483,6 @@ macro_rules! test_suite {
.run_checks()
}
#[test]
fn signature_set_1_valid_set_with_1_infinity_set() {
SignatureSetTester::default()
.push_valid_infinity_set()
.run_checks()
}
#[test]
fn signature_set_3_sets_with_one_valid_infinity_set() {
SignatureSetTester::default()
.push_valid_set(2)
.push_valid_infinity_set()
.push_valid_set(2)
.run_checks()
}
#[test]
fn signature_set_3_sets_with_one_invalid_pubkey_infinity_set() {
SignatureSetTester::default()
@ -592,15 +491,6 @@ macro_rules! test_suite {
.push_valid_set(2)
.run_checks()
}
#[test]
fn signature_set_3_sets_with_one_invalid_sig_infinity_set() {
SignatureSetTester::default()
.push_valid_set(2)
.push_invalid_sig_infinity_set()
.push_valid_set(2)
.run_checks()
}
};
}

View File

@ -1,7 +1,7 @@
[package]
name = "lcli"
description = "Lighthouse CLI (modeled after zcli)"
version = "0.3.1"
version = "0.3.2"
authors = ["Paul Hauner <paul@paulhauner.com>"]
edition = "2018"

View File

@ -2,6 +2,7 @@ use clap::ArgMatches;
use environment::Environment;
use eth2_testnet_config::Eth2TestnetConfig;
use genesis::{Eth1Config, Eth1GenesisService};
use ssz::Encode;
use std::path::PathBuf;
use std::time::Duration;
use types::EthSpec;
@ -24,8 +25,7 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches<'_>) -> Res
.expect("should locate home directory")
});
let mut eth2_testnet_config: Eth2TestnetConfig<T> =
Eth2TestnetConfig::load(testnet_dir.clone())?;
let mut eth2_testnet_config = Eth2TestnetConfig::load(testnet_dir.clone())?;
let spec = eth2_testnet_config
.yaml_config
@ -35,7 +35,7 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches<'_>) -> Res
.ok_or_else(|| {
format!(
"The loaded config is not compatible with the {} spec",
&env.core_context().eth2_config.spec_constants
&env.core_context().eth2_config.eth_spec_id
)
})?;
@ -51,10 +51,10 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches<'_>) -> Res
env.runtime().block_on(async {
let _ = genesis_service
.wait_for_genesis_state(ETH1_GENESIS_UPDATE_INTERVAL, spec)
.wait_for_genesis_state::<T>(ETH1_GENESIS_UPDATE_INTERVAL, spec)
.await
.map(move |genesis_state| {
eth2_testnet_config.genesis_state = Some(genesis_state);
eth2_testnet_config.genesis_state_bytes = Some(genesis_state.as_ssz_bytes());
eth2_testnet_config.force_write_to_file(testnet_dir)
})
.map_err(|e| format!("Failed to find genesis: {}", e))?;

View File

@ -3,6 +3,7 @@ use clap_utils::parse_ssz_optional;
use environment::Environment;
use eth2_testnet_config::Eth2TestnetConfig;
use genesis::interop_genesis_state;
use ssz::Encode;
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
use types::{test_utils::generate_deterministic_keypairs, EthSpec};
@ -35,8 +36,7 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches) -> Result<
.expect("should locate home directory")
});
let mut eth2_testnet_config: Eth2TestnetConfig<T> =
Eth2TestnetConfig::load(testnet_dir.clone())?;
let mut eth2_testnet_config = Eth2TestnetConfig::load(testnet_dir.clone())?;
let mut spec = eth2_testnet_config
.yaml_config
@ -46,7 +46,7 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches) -> Result<
.ok_or_else(|| {
format!(
"The loaded config is not compatible with the {} spec",
&env.core_context().eth2_config.spec_constants
&env.core_context().eth2_config.eth_spec_id
)
})?;
@ -55,9 +55,9 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches) -> Result<
}
let keypairs = generate_deterministic_keypairs(validator_count);
let genesis_state = interop_genesis_state(&keypairs, genesis_time, &spec)?;
let genesis_state = interop_genesis_state::<T>(&keypairs, genesis_time, &spec)?;
eth2_testnet_config.genesis_state = Some(genesis_state);
eth2_testnet_config.genesis_state_bytes = Some(genesis_state.as_ssz_bytes());
eth2_testnet_config.force_write_to_file(testnet_dir)?;
Ok(())

View File

@ -20,9 +20,12 @@ use parse_hex::run_parse_hex;
use std::fs::File;
use std::path::PathBuf;
use std::process;
use std::str::FromStr;
use std::time::{SystemTime, UNIX_EPOCH};
use transition_blocks::run_transition_blocks;
use types::{test_utils::TestingBeaconStateBuilder, EthSpec, MainnetEthSpec, MinimalEthSpec};
use types::{
test_utils::TestingBeaconStateBuilder, EthSpec, EthSpecId, MainnetEthSpec, MinimalEthSpec,
};
fn main() {
simple_logger::SimpleLogger::new()
@ -482,25 +485,21 @@ fn main() {
)
.get_matches();
macro_rules! run_with_spec {
($env_builder: expr) => {
match run($env_builder, &matches) {
Ok(()) => process::exit(0),
Err(e) => {
println!("Failed to run lcli: {}", e);
process::exit(1)
}
}
};
}
let result = matches
.value_of("spec")
.ok_or_else(|| "Missing --spec flag".to_string())
.and_then(FromStr::from_str)
.and_then(|eth_spec_id| match eth_spec_id {
EthSpecId::Minimal => run(EnvironmentBuilder::minimal(), &matches),
EthSpecId::Mainnet => run(EnvironmentBuilder::mainnet(), &matches),
EthSpecId::V012Legacy => run(EnvironmentBuilder::v012_legacy(), &matches),
});
match matches.value_of("spec") {
Some("minimal") => run_with_spec!(EnvironmentBuilder::minimal()),
Some("mainnet") => run_with_spec!(EnvironmentBuilder::mainnet()),
Some("interop") => run_with_spec!(EnvironmentBuilder::interop()),
spec => {
// This path should be unreachable due to slog having a `default_value`
unreachable!("Unknown spec configuration: {:?}", spec);
match result {
Ok(()) => process::exit(0),
Err(e) => {
println!("Failed to run lcli: {}", e);
process::exit(1)
}
}
}

View File

@ -51,11 +51,11 @@ pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
spec.genesis_fork_version = v;
}
let testnet: Eth2TestnetConfig<T> = Eth2TestnetConfig {
let testnet = Eth2TestnetConfig {
deposit_contract_address: format!("{:?}", deposit_contract_address),
deposit_contract_deploy_block,
boot_enr: Some(vec![]),
genesis_state: None,
genesis_state_bytes: None,
yaml_config: Some(YamlConfig::from_spec::<T>(&spec)),
};

View File

@ -1,6 +1,6 @@
[package]
name = "lighthouse"
version = "0.3.1"
version = "0.3.2"
authors = ["Sigma Prime <contact@sigmaprime.io>"]
edition = "2018"
@ -9,6 +9,8 @@ edition = "2018"
write_ssz_files = ["beacon_node/write_ssz_files"]
# Compiles the BLS crypto code so that the binary is portable across machines.
portable = ["bls/supranational-portable"]
# Compiles BLST so that it always uses ADX instructions.
modern = ["bls/supranational-force-adx"]
# Uses the slower Milagro BLS library, which is written in native Rust.
milagro = ["bls/milagro"]

View File

@ -24,7 +24,7 @@ use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
use task_executor::TaskExecutor;
use tokio::runtime::{Builder as RuntimeBuilder, Runtime};
use types::{EthSpec, InteropEthSpec, MainnetEthSpec, MinimalEthSpec};
use types::{EthSpec, MainnetEthSpec, MinimalEthSpec, V012LegacyEthSpec};
pub const ETH2_CONFIG_FILENAME: &str = "eth2-spec.toml";
const LOG_CHANNEL_SIZE: usize = 2048;
@ -37,7 +37,7 @@ pub struct EnvironmentBuilder<E: EthSpec> {
log: Option<Logger>,
eth_spec_instance: E,
eth2_config: Eth2Config,
testnet: Option<Eth2TestnetConfig<E>>,
testnet: Option<Eth2TestnetConfig>,
}
impl EnvironmentBuilder<MinimalEthSpec> {
@ -66,14 +66,14 @@ impl EnvironmentBuilder<MainnetEthSpec> {
}
}
impl EnvironmentBuilder<InteropEthSpec> {
/// Creates a new builder using the `interop` eth2 specification.
pub fn interop() -> Self {
impl EnvironmentBuilder<V012LegacyEthSpec> {
/// Creates a new builder using the v0.12.x eth2 specification.
pub fn v012_legacy() -> Self {
Self {
runtime: None,
log: None,
eth_spec_instance: InteropEthSpec,
eth2_config: Eth2Config::interop(),
eth_spec_instance: V012LegacyEthSpec,
eth2_config: Eth2Config::v012_legacy(),
testnet: None,
}
}
@ -238,7 +238,7 @@ impl<E: EthSpec> EnvironmentBuilder<E> {
/// Adds a testnet configuration to the environment.
pub fn eth2_testnet_config(
mut self,
eth2_testnet_config: Eth2TestnetConfig<E>,
eth2_testnet_config: Eth2TestnetConfig,
) -> Result<Self, String> {
// Create a new chain spec from the default configuration.
self.eth2_config.spec = eth2_testnet_config
@ -249,7 +249,7 @@ impl<E: EthSpec> EnvironmentBuilder<E> {
.ok_or_else(|| {
format!(
"The loaded config is not compatible with the {} spec",
&self.eth2_config.spec_constants
&self.eth2_config.eth_spec_id
)
})?;
@ -261,7 +261,7 @@ impl<E: EthSpec> EnvironmentBuilder<E> {
/// Optionally adds a testnet configuration to the environment.
pub fn optional_eth2_testnet_config(
self,
optional_config: Option<Eth2TestnetConfig<E>>,
optional_config: Option<Eth2TestnetConfig>,
) -> Result<Self, String> {
if let Some(config) = optional_config {
self.eth2_testnet_config(config)
@ -339,7 +339,7 @@ pub struct Environment<E: EthSpec> {
log: Logger,
eth_spec_instance: E,
pub eth2_config: Eth2Config,
pub testnet: Option<Eth2TestnetConfig<E>>,
pub testnet: Option<Eth2TestnetConfig>,
}
impl<E: EthSpec> Environment<E> {

View File

@ -3,17 +3,17 @@
use environment::EnvironmentBuilder;
use eth2_testnet_config::Eth2TestnetConfig;
use std::path::PathBuf;
use types::{MainnetEthSpec, YamlConfig};
use types::{V012LegacyEthSpec, YamlConfig};
fn builder() -> EnvironmentBuilder<MainnetEthSpec> {
EnvironmentBuilder::mainnet()
fn builder() -> EnvironmentBuilder<V012LegacyEthSpec> {
EnvironmentBuilder::v012_legacy()
.single_thread_tokio_runtime()
.expect("should set runtime")
.null_logger()
.expect("should set logger")
}
fn eth2_testnet_config() -> Option<Eth2TestnetConfig<MainnetEthSpec>> {
fn eth2_testnet_config() -> Option<Eth2TestnetConfig> {
Eth2TestnetConfig::hard_coded_default().expect("should decode hard_coded params")
}

View File

@ -7,7 +7,7 @@ use lighthouse_version::VERSION;
use slog::{crit, info, warn};
use std::path::PathBuf;
use std::process::exit;
use types::EthSpec;
use types::{EthSpec, EthSpecId};
use validator_client::ProductionValidatorClient;
pub const ETH2_CONFIG_FILENAME: &str = "eth2-spec.toml";
@ -15,6 +15,8 @@ pub const ETH2_CONFIG_FILENAME: &str = "eth2-spec.toml";
fn bls_library_name() -> &'static str {
if cfg!(feature = "portable") {
"blst-portable"
} else if cfg!(feature = "modern") {
"blst-modern"
} else if cfg!(feature = "milagro") {
"milagro"
} else {
@ -43,12 +45,11 @@ fn main() {
Arg::with_name("spec")
.short("s")
.long("spec")
.value_name("TITLE")
.help("Specifies the default eth2 spec type.")
.value_name("DEPRECATED")
.help("This flag is deprecated, it will be disallowed in a future release. This \
value is now derived from the --testnet or --testnet-dir flags.")
.takes_value(true)
.possible_values(&["mainnet", "minimal", "interop"])
.global(true)
.default_value("mainnet"),
)
.arg(
Arg::with_name("env_log")
@ -126,37 +127,35 @@ fn main() {
.subcommand(account_manager::cli_app())
.get_matches();
// boot node subcommand circumvents the environment
if let Some(bootnode_matches) = matches.subcommand_matches("boot_node") {
// The bootnode uses the main debug-level flag
let debug_info = matches
.value_of("debug-level")
.expect("Debug-level must be present")
.into();
boot_node::run(bootnode_matches, debug_info);
return;
}
// Debugging output for libp2p and external crates.
if matches.is_present("env_log") {
Builder::from_env(Env::default()).init();
}
macro_rules! run_with_spec {
($env_builder: expr) => {
run($env_builder, &matches)
};
}
let result = load_testnet_config(&matches).and_then(|testnet_config| {
let eth_spec_id = testnet_config.eth_spec_id()?;
let result = match matches.value_of("spec") {
Some("minimal") => run_with_spec!(EnvironmentBuilder::minimal()),
Some("mainnet") => run_with_spec!(EnvironmentBuilder::mainnet()),
Some("interop") => run_with_spec!(EnvironmentBuilder::interop()),
spec => {
// This path should be unreachable due to slog having a `default_value`
unreachable!("Unknown spec configuration: {:?}", spec);
// boot node subcommand circumvents the environment
if let Some(bootnode_matches) = matches.subcommand_matches("boot_node") {
// The bootnode uses the main debug-level flag
let debug_info = matches
.value_of("debug-level")
.expect("Debug-level must be present")
.into();
boot_node::run(bootnode_matches, eth_spec_id, debug_info);
return Ok(());
}
};
match eth_spec_id {
EthSpecId::Minimal => run(EnvironmentBuilder::minimal(), &matches, testnet_config),
EthSpecId::Mainnet => run(EnvironmentBuilder::mainnet(), &matches, testnet_config),
EthSpecId::V012Legacy => {
run(EnvironmentBuilder::v012_legacy(), &matches, testnet_config)
}
}
});
// `std::process::exit` does not run destructors so we drop manually.
drop(matches);
@ -172,9 +171,23 @@ fn main() {
}
}
fn load_testnet_config(matches: &ArgMatches) -> Result<Eth2TestnetConfig, String> {
if matches.is_present("testnet-dir") {
clap_utils::parse_testnet_dir(matches, "testnet-dir")?
.ok_or_else(|| "Unable to load testnet dir".to_string())
} else if matches.is_present("testnet") {
clap_utils::parse_hardcoded_network(matches, "testnet")?
.ok_or_else(|| "Unable to load hard coded network config".to_string())
} else {
Eth2TestnetConfig::hard_coded_default()?
.ok_or_else(|| "Unable to load default network config".to_string())
}
}
fn run<E: EthSpec>(
environment_builder: EnvironmentBuilder<E>,
matches: &ArgMatches,
testnet_config: Eth2TestnetConfig,
) -> Result<(), String> {
if std::mem::size_of::<usize>() != 8 {
return Err(format!(
@ -183,25 +196,19 @@ fn run<E: EthSpec>(
));
}
#[cfg(all(feature = "modern", target_arch = "x86_64"))]
if !std::is_x86_feature_detected!("adx") {
return Err(format!(
"CPU incompatible with optimized binary, please try Lighthouse portable build"
));
}
let debug_level = matches
.value_of("debug-level")
.ok_or_else(|| "Expected --debug-level flag".to_string())?;
let log_format = matches.value_of("log-format");
// Parse testnet config from the `testnet` and `testnet-dir` flag in that order
// else, use the default
let mut optional_testnet_config = None;
if matches.is_present("testnet") {
optional_testnet_config = clap_utils::parse_hardcoded_network(matches, "testnet")?;
};
if matches.is_present("testnet-dir") {
optional_testnet_config = clap_utils::parse_testnet_dir(matches, "testnet-dir")?;
};
if optional_testnet_config.is_none() {
optional_testnet_config = Eth2TestnetConfig::hard_coded_default()?;
}
let builder = if let Some(log_path) = matches.value_of("logfile") {
let path = log_path
.parse::<PathBuf>()
@ -213,11 +220,18 @@ fn run<E: EthSpec>(
let mut environment = builder
.multi_threaded_tokio_runtime()?
.optional_eth2_testnet_config(optional_testnet_config)?
.optional_eth2_testnet_config(Some(testnet_config))?
.build()?;
let log = environment.core_context().log().clone();
if matches.is_present("spec") {
warn!(
log,
"The --spec flag is deprecated and will be removed in a future release"
);
}
// Note: the current code technically allows for starting a beacon node _and_ a validator
// client at the same time.
//
@ -264,7 +278,6 @@ fn run<E: EthSpec>(
let executor = context.executor.clone();
let config = beacon_node::get_config::<E>(
matches,
&context.eth2_config.spec_constants,
&context.eth2_config().spec,
context.log().clone(),
)?;

View File

@ -1,4 +1,4 @@
TESTS_TAG := v0.12.3
TESTS_TAG := v1.0.0-rc.0
TESTS = general minimal mainnet
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))

View File

@ -1,13 +1,13 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use bls::{AggregateSignature, PublicKey};
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use types::Hash256;
#[derive(Debug, Clone, Deserialize)]
pub struct BlsAggregateVerifyInput {
pub pubkeys: Vec<PublicKey>,
pub pubkeys: Vec<PublicKeyBytes>,
pub messages: Vec<String>,
pub signature: String,
}
@ -33,14 +33,29 @@ impl Case for BlsAggregateVerify {
})
.collect::<Result<Vec<_>, _>>()?;
let pubkey_refs = self.input.pubkeys.iter().collect::<Vec<_>>();
let pubkeys_result = self
.input
.pubkeys
.iter()
.map(|pkb| pkb.decompress())
.collect::<Result<Vec<_>, _>>();
let pubkeys = match pubkeys_result {
Ok(pubkeys) => pubkeys,
Err(bls::Error::InvalidInfinityPublicKey) if !self.output => {
return Ok(());
}
Err(e) => return Err(Error::FailedToParseTest(format!("{:?}", e))),
};
let pubkey_refs = pubkeys.iter().collect::<Vec<_>>();
let signature_bytes = hex::decode(&self.input.signature[2..])
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
let signature_valid = AggregateSignature::deserialize(&signature_bytes)
.ok()
.map(|signature| signature.aggregate_verify(&messages, &pubkey_refs))
.map(|signature| signature.aggregate_verify(&messages, &pubkey_refs[..]))
.unwrap_or(false);
compare_result::<bool, ()>(&Ok(signature_valid), &Some(self.output))

View File

@ -1,7 +1,7 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use bls::{AggregateSignature, PublicKey, PublicKeyBytes};
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use std::convert::TryInto;
use types::Hash256;
@ -9,6 +9,7 @@ use types::Hash256;
#[derive(Debug, Clone, Deserialize)]
pub struct BlsFastAggregateVerifyInput {
pub pubkeys: Vec<PublicKeyBytes>,
#[serde(alias = "messages")]
pub message: String,
pub signature: String,
}
@ -28,13 +29,20 @@ impl Case for BlsFastAggregateVerify {
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?,
);
let pubkeys = self
let pubkeys_result = self
.input
.pubkeys
.iter()
.map(|pkb| pkb.try_into())
.collect::<Result<Vec<PublicKey>, bls::Error>>()
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
.collect::<Result<Vec<_>, _>>();
let pubkeys = match pubkeys_result {
Ok(pubkeys) => pubkeys,
Err(bls::Error::InvalidInfinityPublicKey) if !self.output => {
return Ok(());
}
Err(e) => return Err(Error::FailedToParseTest(format!("{:?}", e))),
};
let pubkey_refs = pubkeys.iter().collect::<Vec<_>>();

View File

@ -14,7 +14,7 @@ pub struct BlsSignInput {
#[derive(Debug, Clone, Deserialize)]
pub struct BlsSign {
pub input: BlsSignInput,
pub output: String,
pub output: Option<String>,
}
impl BlsCase for BlsSign {}
@ -27,16 +27,25 @@ impl Case for BlsSign {
assert_eq!(sk.len(), 32);
let sk = SecretKey::deserialize(&sk).unwrap();
let sk = match SecretKey::deserialize(&sk) {
Ok(sk) => sk,
Err(_) if self.output.is_none() => {
return Ok(());
}
Err(e) => return Err(Error::FailedToParseTest(format!("{:?}", e))),
};
let msg = hex::decode(&self.input.message[2..])
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
let signature = sk.sign(Hash256::from_slice(&msg));
// Convert the output to one set of bytes
let decoded = hex::decode(&self.output[2..])
let decoded = self
.output
.as_ref()
.map(|output| hex::decode(&output[2..]))
.transpose()
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
compare_result::<Vec<u8>, Vec<u8>>(&Ok(signature.serialize().to_vec()), &Some(decoded))
compare_result::<Vec<u8>, Vec<u8>>(&Ok(signature.serialize().to_vec()), &decoded)
}
}

View File

@ -1,14 +1,14 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use bls::{PublicKey, Signature, SignatureBytes};
use bls::{PublicKeyBytes, Signature, SignatureBytes};
use serde_derive::Deserialize;
use std::convert::TryInto;
use types::Hash256;
#[derive(Debug, Clone, Deserialize)]
pub struct BlsVerifyInput {
pub pubkey: PublicKey,
pub pubkey: PublicKeyBytes,
pub message: String,
pub signature: SignatureBytes,
}
@ -28,8 +28,9 @@ impl Case for BlsVerify {
let signature_ok = (&self.input.signature)
.try_into()
.map(|signature: Signature| {
signature.verify(&self.input.pubkey, Hash256::from_slice(&message))
.and_then(|signature: Signature| {
let pk = self.input.pubkey.decompress()?;
Ok(signature.verify(&pk, Hash256::from_slice(&message)))
})
.unwrap_or(false);

View File

@ -36,6 +36,7 @@ macro_rules! type_name_generic {
type_name!(MinimalEthSpec, "minimal");
type_name!(MainnetEthSpec, "mainnet");
type_name_generic!(AggregateAndProof);
type_name_generic!(Attestation);
type_name!(AttestationData);
type_name_generic!(AttesterSlashing);
@ -46,12 +47,18 @@ type_name_generic!(BeaconState);
type_name!(Checkpoint);
type_name!(Deposit);
type_name!(DepositData);
type_name!(DepositMessage);
type_name!(Eth1Data);
type_name!(Fork);
type_name!(ForkData);
type_name_generic!(HistoricalBatch);
type_name_generic!(IndexedAttestation);
type_name_generic!(PendingAttestation);
type_name!(ProposerSlashing);
type_name_generic!(SignedAggregateAndProof);
type_name_generic!(SignedBeaconBlock);
type_name!(SignedBeaconBlockHeader);
type_name!(SignedVoluntaryExit);
type_name!(SigningData);
type_name!(Validator);
type_name!(VoluntaryExit);

View File

@ -172,6 +172,7 @@ mod ssz_static {
use ef_tests::{Handler, SszStaticHandler, SszStaticTHCHandler};
use types::*;
ssz_static_test!(aggregate_and_proof, AggregateAndProof<_>);
ssz_static_test!(attestation, Attestation<_>);
ssz_static_test!(attestation_data, AttestationData);
ssz_static_test!(attester_slashing, AttesterSlashing<_>);
@ -188,12 +189,24 @@ mod ssz_static {
ssz_static_test!(checkpoint, Checkpoint);
ssz_static_test!(deposit, Deposit);
ssz_static_test!(deposit_data, DepositData);
ssz_static_test!(deposit_message, DepositMessage);
// FIXME(sproul): move Eth1Block to consensus/types
//
// Tracked at: https://github.com/sigp/lighthouse/issues/1835
//
// ssz_static_test!(eth1_block, Eth1Block);
ssz_static_test!(eth1_data, Eth1Data);
ssz_static_test!(fork, Fork);
ssz_static_test!(fork_data, ForkData);
ssz_static_test!(historical_batch, HistoricalBatch<_>);
ssz_static_test!(indexed_attestation, IndexedAttestation<_>);
ssz_static_test!(pending_attestation, PendingAttestation<_>);
ssz_static_test!(proposer_slashing, ProposerSlashing);
ssz_static_test!(signed_aggregate_and_proof, SignedAggregateAndProof<_>);
ssz_static_test!(signed_beacon_block, SignedBeaconBlock<_>);
ssz_static_test!(signed_beacon_block_header, SignedBeaconBlockHeader);
ssz_static_test!(signed_voluntary_exit, SignedVoluntaryExit);
ssz_static_test!(signing_data, SigningData);
ssz_static_test!(validator, Validator);
ssz_static_test!(voluntary_exit, VoluntaryExit);
}
@ -217,7 +230,7 @@ fn epoch_processing_justification_and_finalization() {
#[test]
fn epoch_processing_rewards_and_penalties() {
EpochProcessingHandler::<MinimalEthSpec, RewardsAndPenalties>::run();
// Note: there are no reward and penalty tests for mainnet yet
EpochProcessingHandler::<MainnetEthSpec, RewardsAndPenalties>::run();
}
#[test]

View File

@ -1,6 +1,6 @@
[package]
name = "validator_client"
version = "0.3.1"
version = "0.3.2"
authors = ["Paul Hauner <paul@paulhauner.com>", "Age Manning <Age@AgeManning.com>", "Luke Anderson <luke@lukeanderson.com.au>"]
edition = "2018"