Lighthouse bootnode (#1265)

* Initial bootnode structure

* Add boot_node subcommand

* Add bootnode subcommand

* fmt corrections

* Extend help message

* Move boot_node crate

* Update discv5 dep

* Improve logging and boot-node logging

Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
Age Manning 2020-06-19 16:30:07 +10:00 committed by GitHub
parent f3380c00b8
commit f3d05c15d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 509 additions and 93 deletions

188
Cargo.lock generated
View File

@ -41,9 +41,9 @@ dependencies = [
[[package]]
name = "adler32"
version = "1.1.0"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
[[package]]
name = "aes-ctr"
@ -132,9 +132,9 @@ dependencies = [
[[package]]
name = "arc-swap"
version = "0.4.7"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
checksum = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62"
[[package]]
name = "arrayref"
@ -225,14 +225,13 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "backtrace"
version = "0.3.49"
version = "0.3.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c"
checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
@ -261,9 +260,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]]
name = "base64"
version = "0.12.2"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e223af0dc48c96d4f8342ec01a4974f139df863896b316681efd36742f22cc67"
checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
[[package]]
name = "beacon_chain"
@ -443,6 +442,25 @@ dependencies = [
"zeroize",
]
[[package]]
name = "boot_node"
version = "0.1.0"
dependencies = [
"clap",
"discv5",
"eth2_libp2p",
"futures 0.3.5",
"log 0.4.8",
"logging",
"slog",
"slog-async",
"slog-scope",
"slog-stdlog",
"slog-term",
"sloggers",
"tokio 0.2.21",
]
[[package]]
name = "bs58"
version = "0.3.1"
@ -844,13 +862,12 @@ dependencies = [
[[package]]
name = "crossbeam-queue"
version = "0.2.3"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
checksum = "ab6bffe714b6bb07e42f201352c34f51fefd355ace793f9e638ebd52d23f98d2"
dependencies = [
"cfg-if",
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
@ -992,9 +1009,9 @@ dependencies = [
[[package]]
name = "derive_more"
version = "0.99.8"
version = "0.99.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc655351f820d774679da6cdc23355a93de496867d8203496675162e17b1d671"
checksum = "2127768764f1556535c01b5326ef94bd60ff08dcfbdc544d53e69ed155610f5d"
dependencies = [
"proc-macro2",
"quote",
@ -1022,10 +1039,11 @@ dependencies = [
[[package]]
name = "dirs-sys"
version = "0.3.5"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
dependencies = [
"cfg-if",
"libc",
"redox_users",
"winapi 0.3.8",
@ -1076,9 +1094,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "dtoa"
version = "0.4.6"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
[[package]]
name = "ed25519-dalek"
@ -1136,7 +1154,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3cd1bccf1bd78eee44d89c0f81b60008b40153db2b99c0fc01abf353781e13"
dependencies = [
"base64 0.12.2",
"base64 0.12.1",
"bs58",
"ed25519-dalek",
"hex 0.4.2",
@ -1261,7 +1279,7 @@ dependencies = [
name = "eth2_interop_keypairs"
version = "0.2.0"
dependencies = [
"base64 0.12.2",
"base64 0.12.1",
"eth2_hashing",
"hex 0.4.2",
"lazy_static",
@ -1304,7 +1322,7 @@ dependencies = [
name = "eth2_libp2p"
version = "0.1.2"
dependencies = [
"base64 0.12.2",
"base64 0.12.1",
"dirs",
"discv5",
"environment",
@ -1858,9 +1876,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.14"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909"
checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71"
dependencies = [
"libc",
]
@ -2174,9 +2192,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "0.4.6"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
[[package]]
name = "js-sys"
@ -2620,6 +2638,7 @@ version = "0.1.2"
dependencies = [
"account_manager",
"beacon_node",
"boot_node",
"clap",
"clap_utils",
"env_logger",
@ -2809,9 +2828,9 @@ dependencies = [
[[package]]
name = "miniz_oxide"
version = "0.3.7"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
dependencies = [
"adler32",
]
@ -2855,7 +2874,7 @@ checksum = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3"
dependencies = [
"log 0.4.8",
"mio",
"miow 0.3.5",
"miow 0.3.4",
"winapi 0.3.8",
]
@ -2884,9 +2903,9 @@ dependencies = [
[[package]]
name = "miow"
version = "0.3.5"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e"
checksum = "22dfdd1d51b2639a5abd17ed07005c3af05fb7a2a3b1a1d0d7af1000a520c1c7"
dependencies = [
"socket2",
"winapi 0.3.8",
@ -3072,9 +3091,9 @@ dependencies = [
[[package]]
name = "num-integer"
version = "0.1.43"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
dependencies = [
"autocfg 1.0.0",
"num-traits",
@ -3082,9 +3101,9 @@ dependencies = [
[[package]]
name = "num-iter"
version = "0.1.41"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
dependencies = [
"autocfg 1.0.0",
"num-integer",
@ -3093,9 +3112,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.12"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg 1.0.0",
]
@ -3112,9 +3131,9 @@ dependencies = [
[[package]]
name = "object"
version = "0.20.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2"
[[package]]
name = "once_cell"
@ -3127,9 +3146,9 @@ dependencies = [
[[package]]
name = "oorandom"
version = "11.1.2"
version = "11.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a170cebd8021a008ea92e4db85a72f80b35df514ec664b296fdcbb654eac0b2c"
checksum = "94af325bc33c7f60191be4e2c984d48aaa21e2854f473b85398344b60c9b6358"
[[package]]
name = "opaque-debug"
@ -3159,9 +3178,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
[[package]]
name = "openssl-sys"
version = "0.9.58"
version = "0.9.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
checksum = "7410fef80af8ac071d4f63755c0ab89ac3df0fd1ea91f1d1f37cf5cec4395990"
dependencies = [
"autocfg 1.0.0",
"cc",
@ -3306,18 +3325,18 @@ dependencies = [
[[package]]
name = "pin-project"
version = "0.4.22"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17"
checksum = "ba3a1acf4a3e70849f8a673497ef984f043f95d2d8252dcdf74d54e6a1e47e8a"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "0.4.22"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7"
checksum = "194e88048b71a3e02eb4ee36a6995fed9b8236c11a7bb9f7247a9d9835b3f265"
dependencies = [
"proc-macro2",
"quote",
@ -3387,9 +3406,9 @@ checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
[[package]]
name = "proc-macro-nested"
version = "0.1.6"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
[[package]]
name = "proc-macro2"
@ -3557,9 +3576,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.7"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
dependencies = [
"proc-macro2",
]
@ -3694,11 +3713,10 @@ dependencies = [
[[package]]
name = "rayon"
version = "1.3.1"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
dependencies = [
"autocfg 1.0.0",
"crossbeam-deque",
"either",
"rayon-core",
@ -3706,9 +3724,9 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.7.1"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
dependencies = [
"crossbeam-deque",
"crossbeam-queue",
@ -3790,9 +3808,9 @@ dependencies = [
[[package]]
name = "remove_dir_all"
version = "0.5.3"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
dependencies = [
"winapi 0.3.8",
]
@ -3803,7 +3821,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680"
dependencies = [
"base64 0.12.2",
"base64 0.12.1",
"bytes 0.5.4",
"encoding_rs",
"futures-core",
@ -4157,18 +4175,18 @@ checksum = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4"
[[package]]
name = "serde"
version = "1.0.112"
version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "736aac72d1eafe8e5962d1d1c3d99b0df526015ba40915cb3c49d042e92ec243"
checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.112"
version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf0343ce212ac0d3d6afd9391ac8e9c9efe06b533c8d33f660f6390cc4093f57"
checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
dependencies = [
"proc-macro2",
"quote",
@ -4185,9 +4203,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.55"
version = "1.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2"
dependencies = [
"itoa",
"ryu",
@ -4196,9 +4214,9 @@ dependencies = [
[[package]]
name = "serde_repr"
version = "0.1.6"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
checksum = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
dependencies = [
"proc-macro2",
"quote",
@ -4219,9 +4237,9 @@ dependencies = [
[[package]]
name = "serde_yaml"
version = "0.8.13"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5"
checksum = "16c7a592a1ec97c9c1c68d75b6e537dcbf60c7618e038e7841e00af1d9ccf0c4"
dependencies = [
"dtoa",
"linked-hash-map",
@ -4712,9 +4730,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.31"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
checksum = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2"
dependencies = [
"proc-macro2",
"quote",
@ -4723,9 +4741,9 @@ dependencies = [
[[package]]
name = "synstructure"
version = "0.12.4"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
dependencies = [
"proc-macro2",
"quote",
@ -4807,18 +4825,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.20"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
checksum = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.20"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479"
dependencies = [
"proc-macro2",
"quote",
@ -4940,12 +4958,6 @@ dependencies = [
"serde_json",
]
[[package]]
name = "tinyvec"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed"
[[package]]
name = "tokio"
version = "0.1.22"
@ -5449,11 +5461,11 @@ dependencies = [
[[package]]
name = "unicode-normalization"
version = "0.1.13"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
dependencies = [
"tinyvec",
"smallvec 1.4.0",
]
[[package]]
@ -5587,9 +5599,9 @@ dependencies = [
[[package]]
name = "vcpkg"
version = "0.2.10"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
checksum = "55d1e41d56121e07f1e223db0a4def204e45c85425f6a16d462fd07c8d10d74c"
[[package]]
name = "vec_map"
@ -5785,7 +5797,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a681e8d15deced7c510db88c59133d2eafa7b6298b6e91b545e2a3fed93b3fe"
dependencies = [
"arrayvec 0.5.1",
"base64 0.12.2",
"base64 0.12.1",
"derive_more",
"ethabi",
"ethereum-types",

View File

@ -1,6 +1,7 @@
[workspace]
members = [
"account_manager",
"beacon_node",
"beacon_node/beacon_chain",
"beacon_node/client",
@ -13,6 +14,8 @@ members = [
"beacon_node/version",
"beacon_node/websocket_server",
"boot_node",
"common/clap_utils",
"common/compare_fields",
"common/compare_fields_derive",

View File

@ -12,6 +12,9 @@ pub trait EnrExt {
/// Returns a list of multiaddrs if the ENR has an `ip` and either a `tcp` or `udp` key **or** an `ip6` and either a `tcp6` or `udp6`.
/// The vector remains empty if these fields are not defined.
fn multiaddr(&self) -> Vec<Multiaddr>;
/// Returns the multiaddr with the `PeerId` prepended.
fn multiaddr_p2p(&self) -> Vec<Multiaddr>;
}
/// Extend ENR CombinedPublicKey for libp2p types.
@ -34,8 +37,6 @@ impl EnrExt for Enr {
/// Returns a list of multiaddrs if the ENR has an `ip` and either a `tcp` or `udp` key **or** an `ip6` and either a `tcp6` or `udp6`.
/// The vector remains empty if these fields are not defined.
///
/// Note: Only available with the `libp2p` feature flag.
fn multiaddr(&self) -> Vec<Multiaddr> {
let mut multiaddrs: Vec<Multiaddr> = Vec::new();
if let Some(ip) = self.ip() {
@ -66,6 +67,46 @@ impl EnrExt for Enr {
}
multiaddrs
}
/// Returns a list of multiaddrs if the ENR has an `ip` and either a `tcp` or `udp` key **or** an `ip6` and either a `tcp6` or `udp6`.
/// The vector remains empty if these fields are not defined.
///
/// This also prepends the `PeerId` into each multiaddr with the `P2p` protocol.
fn multiaddr_p2p(&self) -> Vec<Multiaddr> {
let peer_id = self.peer_id();
let mut multiaddrs: Vec<Multiaddr> = Vec::new();
if let Some(ip) = self.ip() {
if let Some(udp) = self.udp() {
let mut multiaddr: Multiaddr = ip.into();
multiaddr.push(Protocol::Udp(udp));
multiaddr.push(Protocol::P2p(peer_id.clone().into()));
multiaddrs.push(multiaddr);
}
if let Some(tcp) = self.tcp() {
let mut multiaddr: Multiaddr = ip.into();
multiaddr.push(Protocol::Tcp(tcp));
multiaddr.push(Protocol::P2p(peer_id.clone().into()));
multiaddrs.push(multiaddr);
}
}
if let Some(ip6) = self.ip6() {
if let Some(udp6) = self.udp6() {
let mut multiaddr: Multiaddr = ip6.into();
multiaddr.push(Protocol::Udp(udp6));
multiaddr.push(Protocol::P2p(peer_id.clone().into()));
multiaddrs.push(multiaddr);
}
if let Some(tcp6) = self.tcp6() {
let mut multiaddr: Multiaddr = ip6.into();
multiaddr.push(Protocol::Tcp(tcp6));
multiaddr.push(Protocol::P2p(peer_id.into()));
multiaddrs.push(multiaddr);
}
}
multiaddrs
}
}
impl CombinedKeyPublicExt for CombinedPublicKey {

20
boot_node/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "boot_node"
version = "0.1.0"
authors = ["Age Manning <Age@AgeManning.com>"]
edition = "2018"
[dependencies]
clap = "2.33.0"
eth2_libp2p = { path = "../beacon_node/eth2_libp2p" }
slog = "2.5.2"
sloggers = "1.0.1"
tokio = "0.2.21"
log = "0.4.8"
slog-term = "2.6.0"
logging = { path = "../common/logging" }
slog-async = "2.5.0"
slog-scope = "4.3.0"
slog-stdlog = "4.0.0"
futures = "0.3.5"
discv5 = "0.1.0-alpha.5"

60
boot_node/src/cli.rs Normal file
View File

@ -0,0 +1,60 @@
//! Simple logic for spawning a Lighthouse BootNode.
use clap::{App, Arg};
// TODO: Add DOS prevention CLI params
pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
App::new("boot_node")
.about("Start a special Lighthouse process that only serves as a discv5 boot-node. This
process will *not* import blocks or perform most typical beacon node functions. Instead, it
will simply run the discv5 service and assist nodes on the network to discover each other.
This is the recommended way to provide a network boot-node since it has a reduced attack
surface compared to a full beacon node.")
.settings(&[clap::AppSettings::ColoredHelp])
.arg(
Arg::with_name("boot-node-enr-address")
.value_name("IP-ADDRESS")
.help("The external IP address/ DNS address to broadcast to other peers on how to reach this node. \
If a DNS address is provided, the enr-address is set to the IP address it resolves to and \
does not auto-update based on PONG responses in discovery.")
.required(true)
.takes_value(true),
)
.arg(
Arg::with_name("port")
.value_name("PORT")
.help("The UDP port to listen on.")
.default_value("9000")
.takes_value(true),
)
.arg(
Arg::with_name("listen-address")
.long("listen-address")
.value_name("ADDRESS")
.help("The address the bootnode will listen for UDP connections.")
.default_value("0.0.0.0")
.takes_value(true)
)
.arg(
Arg::with_name("boot-nodes")
.long("boot-nodes")
.allow_hyphen_values(true)
.value_name("ENR-LIST/Multiaddr")
.help("One or more comma-delimited base64-encoded ENR's or multiaddr strings of peers to initially add to the local routing table")
.takes_value(true),
)
.arg(
Arg::with_name("enr-port")
.long("enr-port")
.value_name("PORT")
.help("The UDP port of the boot node's ENR. This is the port that external peers will dial to reach this boot node. Set this only if the external port differs from the listening port.")
.takes_value(true),
)
.arg(
Arg::with_name("enable-enr-auto-update")
.short("x")
.long("enable-enr-auto-update")
.help("Discovery can automatically update the node's local ENR with an external IP address and port as seen by other peers on the network. \
This enables this feature.")
)
}

102
boot_node/src/config.rs Normal file
View File

@ -0,0 +1,102 @@
use clap::ArgMatches;
use discv5::{enr::CombinedKey, Enr};
use std::convert::TryFrom;
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
/// A set of configuration parameters for the bootnode, established from CLI arguments.
pub struct BootNodeConfig {
pub listen_socket: SocketAddr,
// TODO: Generalise to multiaddr
pub boot_nodes: Vec<Enr>,
pub local_enr: Enr,
pub local_key: CombinedKey,
pub auto_update: bool,
}
impl TryFrom<&ArgMatches<'_>> for BootNodeConfig {
type Error = String;
fn try_from(matches: &ArgMatches<'_>) -> Result<Self, Self::Error> {
let listen_address = matches
.value_of("listen-address")
.expect("required parameter")
.parse::<IpAddr>()
.map_err(|_| format!("Invalid listening address"))?;
let listen_port = matches
.value_of("port")
.expect("required parameter")
.parse::<u16>()
.map_err(|_| format!("Invalid listening port"))?;
let boot_nodes = {
if let Some(boot_nodes) = matches.value_of("boot-nodes") {
boot_nodes
.split(',')
.map(|enr| enr.parse().map_err(|_| format!("Invalid ENR: {}", enr)))
.collect::<Result<Vec<Enr>, _>>()?
} else {
Vec::new()
}
};
let enr_port = {
if let Some(port) = matches.value_of("boot-node-enr-port") {
port.parse::<u16>()
.map_err(|_| format!("Invalid ENR port"))?
} else {
listen_port
}
};
let enr_address = {
let address_string = matches
.value_of("boot-node-enr-address")
.expect("required parameter");
resolve_address(address_string.into(), enr_port)?
};
let auto_update = matches.is_present("enable-enr_auto_update");
// the address to listen on
let listen_socket = SocketAddr::new(listen_address.into(), enr_port);
// Generate a new key and build a new ENR
let local_key = CombinedKey::generate_secp256k1();
let local_enr = discv5::enr::EnrBuilder::new("v4")
.ip(enr_address)
.udp(enr_port)
.build(&local_key)
.map_err(|e| format!("Failed to build ENR: {:?}", e))?;
Ok(BootNodeConfig {
listen_socket,
boot_nodes,
local_enr,
local_key,
auto_update,
})
}
}
/// Resolves an IP/DNS string to an IpAddr.
fn resolve_address(address_string: String, port: u16) -> Result<IpAddr, String> {
match address_string.parse::<IpAddr>() {
Ok(addr) => Ok(addr), // valid IpAddr
Err(_) => {
let mut addr = address_string.clone();
// Appending enr-port to the dns hostname to appease `to_socket_addrs()` parsing.
addr.push_str(&format!(":{}", port.to_string()));
// `to_socket_addr()` does the dns resolution
// Note: `to_socket_addrs()` is a blocking call
addr.to_socket_addrs()
.map(|mut resolved_addrs|
// Pick the first ip from the list of resolved addresses
resolved_addrs
.next()
.map(|a| a.ip())
.ok_or_else(|| format!("Resolved dns addr contains no entries")))
.map_err(|_| format!("Failed to parse enr-address: {}", address_string))?
}
}
}

65
boot_node/src/lib.rs Normal file
View File

@ -0,0 +1,65 @@
//! Creates a simple DISCV5 server which can be used to bootstrap an Eth2 network.
use clap::ArgMatches;
use slog;
use slog::{o, Drain, Level, Logger};
use std::convert::TryFrom;
mod cli;
mod config;
mod server;
pub use cli::cli_app;
use config::BootNodeConfig;
/// Run the bootnode given the CLI configuration.
pub fn run(matches: &ArgMatches<'_>, debug_level: String) {
let debug_level = match debug_level.as_str() {
"trace" => log::Level::Trace,
"debug" => log::Level::Debug,
"info" => log::Level::Info,
"warn" => log::Level::Warn,
"error" => log::Level::Error,
"crit" => log::Level::Error,
_ => unreachable!(),
};
// Setting up the initial logger format and building it.
let drain = {
let decorator = slog_term::TermDecorator::new().build();
let decorator = logging::AlignedTermDecorator::new(decorator, logging::MAX_MESSAGE_WIDTH);
let drain = slog_term::FullFormat::new(decorator).build().fuse();
slog_async::Async::new(drain).build()
};
let drain = match debug_level {
log::Level::Info => drain.filter_level(Level::Info),
log::Level::Debug => drain.filter_level(Level::Debug),
log::Level::Trace => drain.filter_level(Level::Trace),
log::Level::Warn => drain.filter_level(Level::Warning),
log::Level::Error => drain.filter_level(Level::Error),
};
let logger = Logger::root(drain.fuse(), o!());
let _scope_guard = slog_scope::set_global_logger(logger);
let _log_guard = slog_stdlog::init_with_level(debug_level).unwrap();
// Run the main function emitting any errors
if let Err(e) = main(matches, slog_scope::logger()) {
slog::crit!(slog_scope::logger(), "{}", e);
}
}
fn main(matches: &ArgMatches<'_>, log: slog::Logger) -> Result<(), String> {
// Builds a custom executor for the bootnode
let mut runtime = tokio::runtime::Builder::new()
.threaded_scheduler()
.enable_all()
.build()
.map_err(|e| format!("Failed to build runtime: {}", e))?;
// parse the CLI args into a useable config
let config = BootNodeConfig::try_from(matches)?;
// Run the boot node
runtime.block_on(server::run(config, log));
Ok(())
}

89
boot_node/src/server.rs Normal file
View File

@ -0,0 +1,89 @@
//! The main bootnode server execution.
use super::BootNodeConfig;
use discv5::{Discv5, Discv5ConfigBuilder, Discv5Event};
use eth2_libp2p::EnrExt;
use futures::prelude::*;
use slog::info;
pub async fn run(config: BootNodeConfig, log: slog::Logger) {
// Print out useful information about the generated ENR
let enr_socket = config.local_enr.udp_socket().expect("Enr has a UDP socket");
info!(log, "Configuration parameters"; "listening_address" => format!("{}:{}", config.listen_socket.ip(), config.listen_socket.port()), "broadcast_address" => format!("{}:{}",enr_socket.ip(), enr_socket.port()));
info!(log, "Identity established"; "peer_id" => config.local_enr.peer_id().to_string(), "node_id" => config.local_enr.node_id().to_string());
// build the contactable multiaddr list, adding the p2p protocol
info!(log, "Contact information"; "enr" => config.local_enr.to_base64());
info!(log, "Contact information"; "multiaddrs" => format!("{:?}", config.local_enr.multiaddr_p2p()));
// Build the discv5 server
// default configuration with packet filtering
let discv5_config = {
let mut builder = Discv5ConfigBuilder::new();
builder.enable_packet_filter();
if !config.auto_update {
builder.disable_enr_update();
}
builder.build()
};
// construct the discv5 server
let mut discv5 = Discv5::new(config.local_enr, config.local_key, discv5_config).unwrap();
// If there are any bootnodes add them to the routing table
for enr in config.boot_nodes {
info!(log, "Adding bootnode"; "address" => format!("{:?}", enr.udp_socket()), "peer_id" => enr.peer_id().to_string(), "node_id" => enr.node_id().to_string());
if let Err(e) = discv5.add_enr(enr) {
slog::warn!(log, "Failed adding ENR"; "error" => e.to_string());
}
}
// start the server
discv5.start(config.listen_socket);
// if there are peers in the local routing table, establish a session by running a query
if !discv5.table_entries_id().is_empty() {
info!(log, "Executing bootstrap query...");
let _ = discv5.find_node(discv5::enr::NodeId::random()).await;
}
// respond with metrics every 10 seconds
let mut metric_interval = tokio::time::interval(tokio::time::Duration::from_secs(10));
// get an event stream
let mut event_stream = match discv5.event_stream().await {
Ok(stream) => stream,
Err(e) => {
slog::crit!(log, "Failed to obtain event stream"; "error" => e.to_string());
return;
}
};
// listen for events
loop {
tokio::select! {
_ = metric_interval.next() => {
// display server metrics
let metrics = discv5.metrics();
info!(log, "Server metrics"; "connected_peers" => discv5.connected_peers(), "active_sessions" => metrics.active_sessions, "requests/s" => format!("{:.2}", metrics.unsolicited_requests_per_second));
}
Some(event) = event_stream.recv() => {
match event {
Discv5Event::Discovered(_enr) => {
// An ENR has bee obtained by the server
// Ignore these events here
}
Discv5Event::EnrAdded { .. } => {} // Ignore
Discv5Event::NodeInserted { .. } => {} // Ignore
Discv5Event::SocketUpdated(socket_addr) => {
info!(log, "External socket address updated"; "socket_addr" => format!("{:?}", socket_addr));
}
}
}
}
}
}

View File

@ -19,6 +19,7 @@ logging = { path = "../common/logging" }
slog-term = "2.5.0"
slog-async = "2.5.0"
environment = { path = "./environment" }
boot_node = { path = "../boot_node" }
futures = "0.3.5"
validator_client = { "path" = "../validator_client" }
account_manager = { "path" = "../account_manager" }

View File

@ -18,13 +18,11 @@ pub const CLIENT_CONFIG_FILENAME: &str = "beacon-node.toml";
pub const ETH2_CONFIG_FILENAME: &str = "eth2-spec.toml";
fn main() {
// Debugging output for libp2p and external crates.
Builder::from_env(Env::default()).init();
// Parse the CLI parameters.
let matches = App::new("Lighthouse")
.version(crate_version!())
.author("Sigma Prime <contact@sigmaprime.io>")
.setting(clap::AppSettings::ColoredHelp)
.about(
"Ethereum 2.0 client by Sigma Prime. Provides a full-featured beacon \
node, a validator client and utilities for managing validator accounts.",
@ -40,6 +38,13 @@ fn main() {
.global(true)
.default_value("mainnet"),
)
.arg(
Arg::with_name("env_log")
.short("l")
.help("Enables environment logging giving access to sub-protocol logs such as discv5 and libp2p",
)
.takes_value(false),
)
.arg(
Arg::with_name("logfile")
.long("logfile")
@ -64,6 +69,7 @@ fn main() {
.help("The verbosity level for emitting logs.")
.takes_value(true)
.possible_values(&["info", "debug", "trace", "warn", "error", "crit"])
.global(true)
.default_value("info"),
)
.arg(
@ -89,10 +95,27 @@ fn main() {
.global(true),
)
.subcommand(beacon_node::cli_app())
.subcommand(boot_node::cli_app())
.subcommand(validator_client::cli_app())
.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)