Mallory - Single commit

This commit is contained in:
Age Manning
2025-05-12 15:23:29 +10:00
parent b35854b71f
commit 2b9aed4020
21 changed files with 679 additions and 184 deletions

279
Cargo.lock generated
View File

@@ -1334,9 +1334,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
version = "1.2.21"
version = "1.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1"
dependencies = [
"jobserver",
"libc",
@@ -1462,9 +1462,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.37"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
dependencies = [
"clap_builder",
"clap_derive",
@@ -1472,9 +1472,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.37"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
dependencies = [
"anstream",
"anstyle",
@@ -2021,11 +2021,11 @@ dependencies = [
[[package]]
name = "ctrlc"
version = "3.4.6"
version = "3.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c"
checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73"
dependencies = [
"nix 0.29.0",
"nix 0.30.1",
"windows-sys 0.59.0",
]
@@ -2402,8 +2402,7 @@ dependencies = [
[[package]]
name = "discv5"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4b4e7798d2ff74e29cee344dc490af947ae657d6ab5273dde35d58ce06a4d71"
source = "git+https://github.com/sigp/discv5?branch=mallory#fd2441ca1fe430618eaeb0b7011dec175ee74fd1"
dependencies = [
"aes 0.8.4",
"aes-gcm",
@@ -3732,9 +3731,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"js-sys",
@@ -4399,21 +4398,22 @@ dependencies = [
[[package]]
name = "icu_collections"
version = "1.5.0"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
dependencies = [
"displaydoc",
"potential_utf",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "icu_locid"
version = "1.5.0"
name = "icu_locale_core"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
dependencies = [
"displaydoc",
"litemap",
@@ -4422,31 +4422,11 @@ dependencies = [
"zerovec",
]
[[package]]
name = "icu_locid_transform"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
dependencies = [
"displaydoc",
"icu_locid",
"icu_locid_transform_data",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_locid_transform_data"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
[[package]]
name = "icu_normalizer"
version = "1.5.0"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
dependencies = [
"displaydoc",
"icu_collections",
@@ -4454,67 +4434,54 @@ dependencies = [
"icu_properties",
"icu_provider",
"smallvec",
"utf16_iter",
"utf8_iter",
"write16",
"zerovec",
]
[[package]]
name = "icu_normalizer_data"
version = "1.5.1"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
[[package]]
name = "icu_properties"
version = "1.5.1"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
checksum = "2549ca8c7241c82f59c80ba2a6f415d931c5b58d24fb8412caa1a1f02c49139a"
dependencies = [
"displaydoc",
"icu_collections",
"icu_locid_transform",
"icu_locale_core",
"icu_properties_data",
"icu_provider",
"tinystr",
"potential_utf",
"zerotrie",
"zerovec",
]
[[package]]
name = "icu_properties_data"
version = "1.5.1"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
checksum = "8197e866e47b68f8f7d95249e172903bec06004b18b2937f1095d40a0c57de04"
[[package]]
name = "icu_provider"
version = "1.5.0"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
dependencies = [
"displaydoc",
"icu_locid",
"icu_provider_macros",
"icu_locale_core",
"stable_deref_trait",
"tinystr",
"writeable",
"yoke",
"zerofrom",
"zerotrie",
"zerovec",
]
[[package]]
name = "icu_provider_macros"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -4534,9 +4501,9 @@ dependencies = [
[[package]]
name = "idna_adapter"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
dependencies = [
"icu_normalizer",
"icu_properties",
@@ -4845,7 +4812,7 @@ version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
dependencies = [
"getrandom 0.3.2",
"getrandom 0.3.3",
"libc",
]
@@ -5032,12 +4999,12 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "libloading"
version = "0.8.6"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c"
dependencies = [
"cfg-if",
"windows-targets 0.52.6",
"windows-targets 0.53.0",
]
[[package]]
@@ -5160,13 +5127,14 @@ dependencies = [
[[package]]
name = "libp2p-gossipsub"
version = "0.49.0"
source = "git+https://github.com/sigp/rust-libp2p.git?rev=61b2820#61b2820de7a3fab5ae5e1362c4dfa93bd7c41e98"
source = "git+https://github.com/sigp/rust-libp2p.git?branch=mallory-test#99360a194440d0d7d251d5971baabdbc675dd3be"
dependencies = [
"async-channel 2.3.1",
"asynchronous-codec",
"base64 0.22.1",
"byteorder",
"bytes",
"delay_map",
"either",
"fnv",
"futures",
@@ -5634,9 +5602,9 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
[[package]]
name = "litemap"
version = "0.7.5"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
[[package]]
name = "lmdb-rkv"
@@ -5747,6 +5715,12 @@ dependencies = [
"hashbrown 0.15.3",
]
[[package]]
name = "lru-slab"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "lru_cache"
version = "0.1.0"
@@ -6286,9 +6260,9 @@ dependencies = [
[[package]]
name = "nix"
version = "0.29.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags 2.9.0",
"cfg-if",
@@ -6936,6 +6910,15 @@ version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "potential_utf"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
dependencies = [
"zerovec",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
@@ -7281,9 +7264,9 @@ dependencies = [
[[package]]
name = "quinn"
version = "0.11.7"
version = "0.11.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012"
checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8"
dependencies = [
"bytes",
"cfg_aliases",
@@ -7302,12 +7285,13 @@ dependencies = [
[[package]]
name = "quinn-proto"
version = "0.11.11"
version = "0.11.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcbafbbdbb0f638fe3f35f3c56739f77a8a1d070cb25603226c83339b391472b"
checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e"
dependencies = [
"bytes",
"getrandom 0.3.2",
"getrandom 0.3.3",
"lru-slab",
"rand 0.9.1",
"ring",
"rustc-hash 2.1.1",
@@ -7445,7 +7429,7 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.2",
"getrandom 0.3.3",
]
[[package]]
@@ -7930,7 +7914,7 @@ dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki 0.103.2",
"rustls-webpki 0.103.3",
"subtle",
"zeroize",
]
@@ -7986,9 +7970,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
version = "0.103.2"
version = "0.103.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7149975849f1abb3832b246010ef62ccc80d3a76169517ada7188252b9cfb437"
checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
dependencies = [
"ring",
"rustls-pki-types",
@@ -8987,12 +8971,12 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.19.1"
version = "3.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
"fastrand",
"getrandom 0.3.2",
"getrandom 0.3.3",
"once_cell",
"rustix 1.0.7",
"windows-sys 0.59.0",
@@ -9193,9 +9177,9 @@ dependencies = [
[[package]]
name = "tinystr"
version = "0.7.6"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
dependencies = [
"displaydoc",
"zerovec",
@@ -9769,12 +9753,6 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "utf16_iter"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
[[package]]
name = "utf8_iter"
version = "1.0.4"
@@ -9803,7 +9781,7 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
dependencies = [
"getrandom 0.3.2",
"getrandom 0.3.3",
]
[[package]]
@@ -10569,13 +10547,29 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
dependencies = [
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
"windows_i686_gnullvm 0.53.0",
"windows_i686_msvc 0.53.0",
"windows_x86_64_gnu 0.53.0",
"windows_x86_64_gnullvm 0.53.0",
"windows_x86_64_msvc 0.53.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
@@ -10594,6 +10588,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
@@ -10612,6 +10612,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
@@ -10630,12 +10636,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
@@ -10654,6 +10672,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
@@ -10672,6 +10696,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
@@ -10690,6 +10720,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
@@ -10708,6 +10744,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.5.40"
@@ -10753,17 +10795,11 @@ dependencies = [
"quote",
]
[[package]]
name = "write16"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
[[package]]
name = "writeable"
version = "0.5.5"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
[[package]]
name = "ws_stream_wasm"
@@ -10910,9 +10946,9 @@ dependencies = [
[[package]]
name = "yoke"
version = "0.7.5"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
dependencies = [
"serde",
"stable_deref_trait",
@@ -10922,9 +10958,9 @@ dependencies = [
[[package]]
name = "yoke-derive"
version = "0.7.5"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
dependencies = [
"proc-macro2",
"quote",
@@ -10995,10 +11031,21 @@ dependencies = [
]
[[package]]
name = "zerovec"
version = "0.10.4"
name = "zerotrie"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
dependencies = [
"displaydoc",
"yoke",
"zerofrom",
]
[[package]]
name = "zerovec"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
dependencies = [
"yoke",
"zerofrom",
@@ -11007,9 +11054,9 @@ dependencies = [
[[package]]
name = "zerovec-derive"
version = "0.10.3"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
dependencies = [
"proc-macro2",
"quote",

View File

@@ -131,9 +131,9 @@ deposit_contract = { path = "common/deposit_contract" }
derivative = "2"
directory = { path = "common/directory" }
dirs = "3"
discv5 = { version = "0.9", features = ["libp2p"] }
doppelganger_service = { path = "validator_client/doppelganger_service" }
either = "1.9"
discv5 = { git= "https://github.com/sigp/discv5", features = ["libp2p"], branch = "mallory" }
env_logger = "0.9"
environment = { path = "lighthouse/environment" }
eth2 = { path = "common/eth2" }
@@ -159,8 +159,8 @@ fork_choice = { path = "consensus/fork_choice" }
fs2 = "0.4"
futures = "0.3"
genesis = { path = "beacon_node/genesis" }
gossipsub = { package = "libp2p-gossipsub", git = "https://github.com/sigp/rust-libp2p.git", rev = "61b2820" }
graffiti_file = { path = "validator_client/graffiti_file" }
gossipsub = { package = "libp2p-gossipsub", git = "https://github.com/sigp/rust-libp2p.git", branch = "mallory" }
hashlink = "0.9.0"
health_metrics = { path = "common/health_metrics" }
hex = "0.4"

View File

@@ -35,7 +35,7 @@ pub struct Config {
pub network_dir: PathBuf,
/// IP addresses to listen on.
pub(crate) listen_addresses: ListenAddress,
pub listen_addresses: ListenAddress,
/// The address to broadcast to peers about which address we are listening on. None indicates
/// that no discovery address has been set in the CLI args.
@@ -142,6 +142,9 @@ pub struct Config {
/// Flag for advertising a fake CGC to peers for testing ONLY.
pub advertise_false_custody_group_count: Option<u64>,
/// Extra configurations for Mallory.
#[serde(skip)]
pub attacker_config: crate::MalloryConfig,
}
impl Config {
@@ -367,6 +370,7 @@ impl Default for Config {
inbound_rate_limiter_config: None,
idontwant_message_size_threshold: DEFAULT_IDONTWANT_MESSAGE_SIZE_THRESHOLD,
advertise_false_custody_group_count: None,
attacker_config: Default::default(),
}
}
}

View File

@@ -241,14 +241,8 @@ impl<E: EthSpec> Discovery<E> {
quic = bootnode_enr.quic4(),
"Adding node to routing table"
);
let repr = bootnode_enr.to_string();
let _ = discv5.add_enr(bootnode_enr).map_err(|e| {
error!(
addr = repr,
error = e.to_string(),
"Could not add peer to the local routing table"
)
});
// Error is suppressed for mallory
let _ = discv5.add_enr(bootnode_enr);
}
// Start the discv5 service and obtain an event stream

View File

@@ -2,11 +2,12 @@
/// all required libp2p functionality.
///
/// This crate builds and manages the libp2p services required by the beacon node.
mod config;
pub mod config;
pub mod service;
pub mod discovery;
pub mod listen_addr;
mod mallory_config;
pub mod metrics;
pub mod peer_manager;
pub mod rpc;
@@ -38,6 +39,12 @@ impl FromStr for PeerIdSerialized {
}
}
impl From<PeerId> for PeerIdSerialized {
fn from(peer_id: PeerId) -> Self {
PeerIdSerialized(peer_id)
}
}
impl Serialize for PeerIdSerialized {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -111,8 +118,9 @@ pub use discovery::{CombinedKeyExt, EnrExt, Eth2Enr};
pub use discv5;
pub use gossipsub::{IdentTopic, MessageAcceptance, MessageId, Topic, TopicHash};
pub use libp2p;
pub use libp2p::{core::ConnectedPoint, PeerId, Swarm};
pub use libp2p::{core::ConnectedPoint, identity::Keypair, PeerId, Swarm};
pub use libp2p::{multiaddr, Multiaddr};
pub use mallory_config::MalloryConfig;
pub use metrics::scrape_discovery_metrics;
pub use peer_manager::{
peerdb::client::Client,
@@ -120,6 +128,7 @@ pub use peer_manager::{
peerdb::PeerDB,
ConnectionDirection, PeerConnectionStatus, PeerInfo, PeerManager, SyncInfo, SyncStatus,
};
pub use service::Behaviour;
// pub use service::{load_private_key, Context, Libp2pEvent, Service, NETWORK_KEY_FILENAME};
pub use service::api_types::Response;
pub use service::utils::*;

View File

@@ -0,0 +1,37 @@
/// Every configuration needed for Mallory.
#[derive(Debug, Clone)]
pub struct MalloryConfig {
/* Peer manager stuff */
/// Ping inbound peers this often (in seconds) instead of the default `PING_INTERVAL_INBOUND`.
pub inbound_peers_ping: Option<u64>,
/// Ping outbound peers this often (in seconds) instead of the default `PING_INTERVAL_OUTBOUND`.
pub outbound_peers_ping: Option<u64>,
/// Status peers this often (in seconds) instead of the default `STATUS_INTERVAL`.
pub status_interval: Option<u64>,
/* RPC stuff */
/// Duration in seconds after which an inbound connection with a peer times out instead of the
/// default `RESPONSE_TIMEOUT`.
pub inbound_rpc_timeout: Option<u64>,
/// Duration in seconds after which an outbound connection with a peer times out instead of the
/// default `RESPONSE_TIMEOUT`.
pub outbound_rpc_timeout: Option<u64>,
/* Behaviour Stuff */
// Allow the user to handle a ping request
pub user_handle_ping: bool,
}
impl Default for MalloryConfig {
fn default() -> Self {
Self {
inbound_peers_ping: None,
outbound_peers_ping: None,
status_interval: None,
inbound_rpc_timeout: None,
outbound_rpc_timeout: None,
user_handle_ping: false,
}
}
}

View File

@@ -3,11 +3,11 @@
//! Currently using identify to fingerprint.
use libp2p::identify::Info as IdentifyInfo;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use strum::{AsRefStr, EnumIter, IntoStaticStr};
/// Various client and protocol information related to a node.
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Client {
/// The client's name (Ex: lighthouse, prism, nimbus, etc)
pub kind: ClientKind,
@@ -21,7 +21,9 @@ pub struct Client {
pub agent_string: Option<String>,
}
#[derive(Clone, Copy, Debug, Serialize, PartialEq, AsRefStr, IntoStaticStr, EnumIter)]
#[derive(
Clone, Copy, Debug, Serialize, PartialEq, AsRefStr, IntoStaticStr, EnumIter, Deserialize,
)]
pub enum ClientKind {
/// A lighthouse node (the best kind).
Lighthouse,

View File

@@ -100,7 +100,7 @@ impl<E: EthSpec> SSZSnappyInboundCodec<E> {
}
}
},
RpcResponse::Error(_, err) => err.as_ssz_bytes(),
RpcResponse::Error(_, err) => err.as_bytes().to_vec().as_ssz_bytes(),
RpcResponse::StreamTermination(_) => {
unreachable!("Code error - attempting to encode a stream termination")
}
@@ -334,6 +334,14 @@ impl<E: EthSpec> Encoder<RequestType<E>> for SSZSnappyOutboundCodec<E> {
type Error = RPCError;
fn encode(&mut self, item: RequestType<E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
let compress = !matches!(
&item,
RequestType::Raw(RawRequest {
mode: RawMode::Raw,
..
})
);
let bytes = match item {
RequestType::Status(req) => {
// Send the status message based on the negotiated protocol
@@ -365,14 +373,25 @@ impl<E: EthSpec> Encoder<RequestType<E>> for SSZSnappyOutboundCodec<E> {
RequestType::MetaData(_)
| RequestType::LightClientOptimisticUpdate
| RequestType::LightClientFinalityUpdate => return Ok(()),
RequestType::Raw(RawRequest {
bytes,
protocol: _,
mode,
}) => match mode {
RawMode::EncodeAndCompress => bytes.as_ssz_bytes(),
RawMode::Compress | RawMode::Raw => bytes,
},
};
// Mallory doesn't care about inbound limits
/*
// SSZ encoded bytes should be within `max_packet_size`
if bytes.len() > self.max_packet_size {
return Err(RPCError::InternalError(
"attempting to encode data > max_packet_size",
));
}
*/
// Inserts the length prefix of the uncompressed bytes into dst
// encoded as a unsigned varint
@@ -380,12 +399,14 @@ impl<E: EthSpec> Encoder<RequestType<E>> for SSZSnappyOutboundCodec<E> {
.encode(bytes.len(), dst)
.map_err(RPCError::from)?;
let mut writer = FrameEncoder::new(Vec::new());
writer.write_all(&bytes).map_err(RPCError::from)?;
writer.flush().map_err(RPCError::from)?;
// Write compressed bytes to `dst`
dst.extend_from_slice(writer.get_ref());
if compress {
let mut writer = FrameEncoder::new(Vec::new());
writer.write_all(&bytes).map_err(RPCError::from)?;
writer.flush().map_err(RPCError::from)?;
dst.extend_from_slice(writer.get_ref());
} else {
dst.extend_from_slice(&bytes);
}
Ok(())
}
}

View File

@@ -4,6 +4,7 @@
use super::methods::{GoodbyeReason, RpcErrorResponse, RpcResponse};
use super::outbound::OutboundRequestContainer;
use super::protocol::{InboundOutput, Protocol, RPCError, RPCProtocol, RequestType};
use super::MalloryLocalConfig;
use super::{RPCReceived, RPCSend, ReqId};
use crate::rpc::outbound::OutboundFramed;
use crate::rpc::protocol::InboundFramed;
@@ -143,6 +144,9 @@ where
/// Timeout that will be used for inbound and outbound responses.
resp_timeout: Duration,
/// Additional configurations for the RPC Handler
config: MalloryLocalConfig,
}
enum HandlerState {
@@ -227,6 +231,7 @@ where
resp_timeout: Duration,
peer_id: PeerId,
connection_id: ConnectionId,
config: MalloryLocalConfig,
) -> Self {
RPCHandler {
connection_id,
@@ -247,6 +252,7 @@ where
fork_context,
waker: None,
resp_timeout,
config,
}
}
@@ -711,8 +717,10 @@ where
request,
};
substream_entry.max_remaining_chunks = Some(max_remaining_chunks);
self.outbound_substreams_delay
.reset(delay_key, self.resp_timeout);
self.outbound_substreams_delay.reset(
delay_key,
Duration::from_secs(self.config.outbound_timeout),
);
}
}
@@ -1031,9 +1039,10 @@ where
Some(max_responses)
};
// new outbound request. Store the stream and tag the output.
let delay_key = self
.outbound_substreams_delay
.insert(self.current_outbound_substream_id, self.resp_timeout);
let delay_key = self.outbound_substreams_delay.insert(
self.current_outbound_substream_id,
Duration::from_secs(self.config.outbound_timeout),
);
let awaiting_stream = OutboundSubstreamState::RequestPendingResponse {
substream: Box::new(substream),
request,

View File

@@ -1,5 +1,6 @@
//! Available RPC methods types and ids.
use super::protocol::SupportedProtocol;
use crate::types::{EnrAttestationBitfield, EnrSyncCommitteeBitfield};
use regex::bytes::Regex;
use serde::Serialize;
@@ -11,6 +12,7 @@ use std::marker::PhantomData;
use std::ops::Deref;
use std::sync::Arc;
use strum::IntoStaticStr;
use strum::{Display as StrumDisplay, EnumString};
use superstruct::superstruct;
use types::blob_sidecar::BlobIdentifier;
use types::light_client_update::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
@@ -129,6 +131,38 @@ pub struct Ping {
pub data: u64,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawRequest {
pub bytes: Vec<u8>,
pub protocol: SupportedProtocol,
pub mode: RawMode,
}
#[derive(Debug, Clone, PartialEq, EnumString, StrumDisplay)]
pub enum RawMode {
/// SSZ encode, Snappy compress.
#[strum(serialize = "encode-compress")]
EncodeAndCompress,
/// Only Snappy compress.
#[strum(serialize = "compress")]
Compress,
/// Do not alter the bytes.
#[strum(serialize = "raw")]
Raw,
}
impl Default for RawMode {
fn default() -> Self {
RawMode::EncodeAndCompress
}
}
impl std::fmt::Display for RawRequest {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
/// The METADATA request structure.
#[superstruct(
variants(V1, V2, V3),
@@ -411,6 +445,8 @@ impl DataColumnsByRangeRequest {
}
}
const MALLORY_MAX_REQUEST_BLOCKS: usize = 10000000000000000000;
/// Request a number of beacon block roots from a peer.
#[superstruct(
variants(V1, V2),
@@ -496,6 +532,11 @@ impl BlocksByRootRequest {
let block_roots = RuntimeVariableList::from_vec(block_roots, max_request_blocks);
Self::V1(BlocksByRootRequestV1 { block_roots })
}
pub fn mallory_new(block_roots: Vec<Hash256>) -> Self {
let block_roots = RuntimeVariableList::from_vec(block_roots, MALLORY_MAX_REQUEST_BLOCKS);
Self::V2(BlocksByRootRequestV2 { block_roots })
}
}
/// Request a number of beacon blocks and blobs from a peer.
@@ -653,10 +694,10 @@ impl ResponseTermination {
/// and the contents of the response
#[derive(Debug, Clone)]
pub enum RpcResponse<E: EthSpec> {
/// The response is a successful.
/// The response is successful.
Success(RpcSuccessResponse<E>),
Error(RpcErrorResponse, ErrorType),
Error(RpcErrorResponse, String),
/// Received a stream termination indicating which response is being terminated.
StreamTermination(ResponseTermination),
@@ -706,7 +747,7 @@ impl<E: EthSpec> RpcResponse<E> {
140 => RpcErrorResponse::BlobsNotFoundForBlock,
_ => RpcErrorResponse::Unknown,
};
RpcResponse::Error(code, err)
RpcResponse::Error(code, err.to_string())
}
/// Returns true if this response always terminates the stream.

View File

@@ -29,12 +29,14 @@ use self::protocol::RPCProtocol;
use self::self_limiter::SelfRateLimiter;
use crate::rpc::rate_limiter::RateLimiterItem;
use crate::rpc::response_limiter::ResponseLimiter;
use crate::MalloryConfig;
pub use handler::SubstreamId;
pub use methods::{
BlocksByRangeRequest, BlocksByRootRequest, GoodbyeReason, LightClientBootstrapRequest,
ResponseTermination, RpcErrorResponse, StatusMessage,
};
pub use protocol::{Protocol, RPCError};
pub use methods::{RawMode, RawRequest};
pub use protocol::{Protocol, RPCError, SupportedProtocol};
pub(crate) mod codec;
pub mod config;
@@ -142,6 +144,16 @@ pub struct NetworkParams {
pub resp_timeout: Duration,
}
/// Additional configurations for the RPC Behaviour.
#[derive(Clone, Copy)]
pub struct MalloryLocalConfig {
/// Timeout in seconds for inbound connections.
pub inbound_timeout: u64,
/// Timeout for outbound connections.
pub outbound_timeout: u64,
pub self_handle_ping: bool,
}
/// Implements the libp2p `NetworkBehaviour` trait and therefore manages network-level
/// logic.
pub struct RPC<Id: ReqId, E: EthSpec> {
@@ -159,6 +171,9 @@ pub struct RPC<Id: ReqId, E: EthSpec> {
network_params: NetworkParams,
/// A sequential counter indicating when data gets modified.
seq_number: u64,
/// Mallory Config
config: MalloryLocalConfig,
}
impl<Id: ReqId, E: EthSpec> RPC<Id, E> {
@@ -175,6 +190,7 @@ impl<Id: ReqId, E: EthSpec> RPC<Id, E> {
outbound_rate_limiter_config: Option<OutboundRateLimiterConfig>,
network_params: NetworkParams,
seq_number: u64,
mallory_config: &MalloryConfig,
) -> Self {
let response_limiter = inbound_rate_limiter_config.map(|config| {
debug!(?config, "Using response rate limiting params");
@@ -186,6 +202,16 @@ impl<Id: ReqId, E: EthSpec> RPC<Id, E> {
SelfRateLimiter::new(outbound_rate_limiter_config, fork_context.clone())
.expect("Outbound limiter configuration parameters are valid");
let mallory_config = MalloryLocalConfig {
inbound_timeout: mallory_config
.inbound_rpc_timeout
.unwrap_or(network_params.resp_timeout.as_secs()),
outbound_timeout: mallory_config
.outbound_rpc_timeout
.unwrap_or(network_params.resp_timeout.as_secs()),
self_handle_ping: mallory_config.user_handle_ping,
};
RPC {
response_limiter,
outbound_request_limiter,
@@ -195,6 +221,7 @@ impl<Id: ReqId, E: EthSpec> RPC<Id, E> {
enable_light_client_server,
network_params,
seq_number,
config: mallory_config,
}
}
@@ -323,6 +350,15 @@ impl<Id: ReqId, E: EthSpec> RPC<Id, E> {
trace!(%peer_id, "Sending Ping");
self.send_request(peer_id, id, RequestType::Ping(ping));
}
/// Sends a pong response
pub fn pong(&mut self, peer_id: PeerId, inbound_request_id: InboundRequestId, data: u64) {
self.send_response(
peer_id,
inbound_request_id,
RpcResponse::Success(RpcSuccessResponse::Pong(Ping { data })),
);
}
}
impl<Id, E> NetworkBehaviour for RPC<Id, E>
@@ -357,6 +393,7 @@ where
self.network_params.resp_timeout,
peer_id,
connection_id,
self.config.clone(),
);
Ok(handler)
@@ -387,6 +424,7 @@ where
self.network_params.resp_timeout,
peer_id,
connection_id,
self.config,
);
Ok(handler)
@@ -499,14 +537,16 @@ where
// If we received a Ping, we queue a Pong response.
if let RequestType::Ping(_) = request_type {
trace!(connection_id = %connection_id, %peer_id, "Received Ping, queueing Pong");
self.send_response(
peer_id,
request_id,
RpcResponse::Success(RpcSuccessResponse::Pong(Ping {
data: self.seq_number,
})),
);
if !self.config.self_handle_ping {
trace!(connection_id = %connection_id, %peer_id, "Received Ping, queueing Pong");
self.send_response(
peer_id,
request_id,
RpcResponse::Success(RpcSuccessResponse::Pong(Ping {
data: self.seq_number,
})),
);
}
}
self.events.push(ToSwarm::GenerateEvent(RPCMessage {

View File

@@ -731,6 +731,7 @@ pub enum RequestType<E: EthSpec> {
LightClientUpdatesByRange(LightClientUpdatesByRangeRequest),
Ping(Ping),
MetaData(MetadataRequest<E>),
Raw(RawRequest),
}
/// Implements the encoding per supported protocol for `RPCRequest`.
@@ -757,6 +758,7 @@ impl<E: EthSpec> RequestType<E> {
RequestType::LightClientOptimisticUpdate => 1,
RequestType::LightClientFinalityUpdate => 1,
RequestType::LightClientUpdatesByRange(req) => req.count,
RequestType::Raw(_) => 1,
}
}
@@ -796,6 +798,7 @@ impl<E: EthSpec> RequestType<E> {
RequestType::LightClientUpdatesByRange(_) => {
SupportedProtocol::LightClientUpdatesByRangeV1
}
RequestType::Raw(r) => r.protocol,
}
}
@@ -819,6 +822,7 @@ impl<E: EthSpec> RequestType<E> {
RequestType::LightClientFinalityUpdate => unreachable!(),
RequestType::LightClientOptimisticUpdate => unreachable!(),
RequestType::LightClientUpdatesByRange(_) => unreachable!(),
RequestType::Raw(_) => unreachable!(),
}
}
@@ -882,6 +886,7 @@ impl<E: EthSpec> RequestType<E> {
SupportedProtocol::LightClientUpdatesByRangeV1,
Encoding::SSZSnappy,
)],
RequestType::Raw(req) => vec![ProtocolId::new(req.protocol, Encoding::SSZSnappy)],
}
}
@@ -901,6 +906,7 @@ impl<E: EthSpec> RequestType<E> {
RequestType::LightClientOptimisticUpdate => true,
RequestType::LightClientFinalityUpdate => true,
RequestType::LightClientUpdatesByRange(_) => true,
RequestType::Raw(_) => true,
}
}
}
@@ -1022,6 +1028,7 @@ impl<E: EthSpec> std::fmt::Display for RequestType<E> {
RequestType::LightClientUpdatesByRange(_) => {
write!(f, "Light client updates by range request")
}
RequestType::Raw(raw) => write!(f, "Raw: {}", raw),
}
}
}

View File

@@ -1,6 +1,9 @@
use crate::rpc::methods::{ResponseTermination, RpcResponse, RpcSuccessResponse, StatusMessage};
use crate::rpc::methods::{
Ping, ResponseTermination, RpcResponse, RpcSuccessResponse, StatusMessage,
};
use std::fmt::{Display, Formatter};
use std::sync::Arc;
use strum::IntoStaticStr;
use types::{
BlobSidecar, DataColumnSidecar, Epoch, EthSpec, Hash256, LightClientBootstrap,
LightClientFinalityUpdate, LightClientOptimisticUpdate, LightClientUpdate, SignedBeaconBlock,
@@ -132,8 +135,9 @@ pub enum AppRequestId {
// sent. The main difference is the absense of Pong and Metadata, which don't leave the
// Behaviour. For all protocol reponses managed by RPC see `RPCResponse` and
// `RPCCodedResponse`.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, IntoStaticStr)]
pub enum Response<E: EthSpec> {
Ping(u64),
/// A Status message.
Status(StatusMessage),
/// A response to a get BLOCKS_BY_RANGE request. A None response signals the end of the batch.
@@ -186,6 +190,7 @@ impl<E: EthSpec> std::convert::From<Response<E>> for RpcResponse<E> {
None => RpcResponse::StreamTermination(ResponseTermination::DataColumnsByRange),
},
Response::Status(s) => RpcResponse::Success(RpcSuccessResponse::Status(s)),
Response::Ping(data) => RpcResponse::Success(RpcSuccessResponse::Pong(Ping { data })),
Response::LightClientBootstrap(b) => {
RpcResponse::Success(RpcSuccessResponse::LightClientBootstrap(b))
}

View File

@@ -0,0 +1,187 @@
use super::*;
use libp2p::core::transport::{ListenerId, TransportError};
use libp2p::core::ConnectedPoint;
use libp2p::swarm::*;
use std::io;
/// Custom error that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`].
#[derive(Debug)]
pub enum MallorySwarmEvent {
/// One of the listeners gracefully closed.
ListenerClosed {
/// The listener that closed.
listener_id: libp2p::core::transport::ListenerId,
/// The addresses that the listener was listening on. These addresses are now considered
/// expired, similar to if a [`ExpiredListenAddr`](SwarmEvent::ExpiredListenAddr) event
/// has been generated for each of them.
addresses: Vec<Multiaddr>,
/// Reason for the closure. Contains `Ok(())` if the stream produced `None`, or `Err`
/// if the stream produced an error.
reason: Result<(), std::io::Error>,
},
/// One of the listeners reported a non-fatal error.
ListenerError {
/// The listener that errored.
listener_id: ListenerId,
/// The listener error.
error: io::Error,
},
/// Outgoing connection attempt failed.
OutgoingConnectionError {
/// Identifier of the connection.
connection_id: ConnectionId,
/// If known, [`PeerId`] of the peer we tried to reach.
peer_id: Option<PeerId>,
/// Error that has been encountered.
error: DialError,
},
IncomingConnection {
/// Identifier of the connection.
connection_id: ConnectionId,
/// Local connection address.
/// This address has been earlier reported with a [`NewListenAddr`](SwarmEvent::NewListenAddr)
/// event.
local_addr: Multiaddr,
/// Address used to send back data to the remote.
send_back_addr: Multiaddr,
},
/// An error happened on a connection during its initial handshake.
///
/// This can include, for example, an error during the handshake of the encryption layer, or
/// the connection unexpectedly closed.
IncomingConnectionError {
/// Identifier of the connection.
connection_id: ConnectionId,
/// Local connection address.
/// This address has been earlier reported with a [`NewListenAddr`](SwarmEvent::NewListenAddr)
/// event.
local_addr: Multiaddr,
/// Address used to send back data to the remote.
send_back_addr: Multiaddr,
/// The error that happened.
error: ListenError,
},
Dialing {
/// Identity of the peer that we are connecting to.
peer_id: Option<PeerId>,
/// Identifier of the connection.
connection_id: ConnectionId,
},
ConnectionClosed {
/// Identity of the peer that we have connected to.
peer_id: PeerId,
/// Identifier of the connection.
connection_id: ConnectionId,
/// Endpoint of the connection that has been closed.
endpoint: ConnectedPoint,
/// Number of other remaining connections to this same peer.
num_established: u32,
/// Reason for the disconnection, if it was not a successful
/// active close.
cause: Option<String>,
},
/// A connection to the given peer has been opened.
ConnectionEstablished {
/// Identity of the peer that we have connected to.
peer_id: PeerId,
/// Identifier of the connection.
connection_id: ConnectionId,
/// Endpoint of the connection that has been opened.
endpoint: ConnectedPoint,
/// Number of established connections to this peer, including the one that has just been
/// opened.
num_established: std::num::NonZeroU32,
/// [`Some`] when the new connection is an outgoing connection.
/// Addresses are dialed concurrently. Contains the addresses and errors
/// of dial attempts that failed before the one successful dial.
concurrent_dial_errors: Option<Vec<(Multiaddr, TransportError<io::Error>)>>,
/// How long it took to establish this connection
established_in: std::time::Duration,
},
}
impl<B> TryFrom<SwarmEvent<B>> for MallorySwarmEvent {
type Error = SwarmEvent<B>;
fn try_from(event: SwarmEvent<B>) -> Result<MallorySwarmEvent, Self::Error> {
match event {
SwarmEvent::ListenerClosed {
listener_id,
addresses,
reason,
} => Ok(MallorySwarmEvent::ListenerClosed {
listener_id,
addresses,
reason,
}),
SwarmEvent::ListenerError { listener_id, error } => {
Ok(MallorySwarmEvent::ListenerError { listener_id, error })
}
SwarmEvent::OutgoingConnectionError {
connection_id,
peer_id,
error,
} => Ok(MallorySwarmEvent::OutgoingConnectionError {
connection_id,
peer_id,
error,
}),
SwarmEvent::IncomingConnection {
connection_id,
local_addr,
send_back_addr,
} => Ok(MallorySwarmEvent::IncomingConnection {
connection_id,
local_addr,
send_back_addr,
}),
SwarmEvent::IncomingConnectionError {
connection_id,
local_addr,
send_back_addr,
error,
} => Ok(MallorySwarmEvent::IncomingConnectionError {
connection_id,
local_addr,
send_back_addr,
error,
}),
SwarmEvent::Dialing {
peer_id,
connection_id,
} => Ok(MallorySwarmEvent::Dialing {
peer_id,
connection_id,
}),
SwarmEvent::ConnectionClosed {
peer_id,
connection_id,
endpoint,
num_established,
cause,
} => Ok(MallorySwarmEvent::ConnectionClosed {
peer_id,
connection_id,
endpoint,
num_established,
cause: cause.map(|v| format!("{:?}", v)),
}),
SwarmEvent::ConnectionEstablished {
peer_id,
connection_id,
endpoint,
num_established,
concurrent_dial_errors,
established_in,
} => Ok(MallorySwarmEvent::ConnectionEstablished {
peer_id,
connection_id,
endpoint,
num_established,
concurrent_dial_errors,
established_in,
}),
ev => Err(ev), // Don't pass other events up.
}
}
}
// Used for Mallory

View File

@@ -24,8 +24,8 @@ use crate::{metrics, Enr, NetworkGlobals, PubsubMessage, TopicHash};
use api_types::{AppRequestId, Response};
use futures::stream::StreamExt;
use gossipsub::{
IdentTopic as Topic, MessageAcceptance, MessageAuthenticity, MessageId, PublishError,
TopicScoreParams,
Config as GossipsubConfig, IdentTopic as Topic, MessageAcceptance, MessageAuthenticity,
MessageId, PublishError, RawMessage, TopicScoreParams,
};
use gossipsub_scoring_parameters::{lighthouse_gossip_thresholds, PeerScoreSettings};
use libp2p::multiaddr::{self, Multiaddr, Protocol as MProtocol};
@@ -49,7 +49,9 @@ use utils::{build_transport, strip_peer_id, Context as ServiceContext};
pub mod api_types;
mod gossip_cache;
pub mod gossipsub_scoring_parameters;
mod mallory;
pub mod utils;
pub use mallory::*;
/// The number of peers we target per subnet for discovery queries.
pub const TARGET_SUBNET_PEERS: usize = 3;
@@ -105,6 +107,10 @@ pub enum NetworkEvent<E: EthSpec> {
ZeroListeners,
/// A peer has an updated custody group count from MetaData.
PeerUpdatedCustodyGroupCount(PeerId),
/// Mallory: Identify has been received.
IdentifyReceived(PeerId),
/// Mallory: Pass swarm events to mallory to handle
MallorySwarmEvent(MallorySwarmEvent),
}
pub type Gossipsub = gossipsub::Behaviour<SnappyTransform, SubscriptionFilter>;
@@ -112,7 +118,7 @@ pub type SubscriptionFilter =
gossipsub::MaxCountSubscriptionFilter<gossipsub::WhitelistSubscriptionFilter>;
#[derive(NetworkBehaviour)]
pub(crate) struct Behaviour<E>
pub struct Behaviour<E>
where
E: EthSpec,
{
@@ -146,7 +152,7 @@ where
/// This core behaviour is managed by `Behaviour` which adds peer management to all core
/// behaviours.
pub struct Network<E: EthSpec> {
swarm: libp2p::swarm::Swarm<Behaviour<E>>,
pub swarm: libp2p::swarm::Swarm<Behaviour<E>>,
/* Auxiliary Fields */
/// A collections of variables accessible outside the network service.
network_globals: Arc<NetworkGlobals<E>>,
@@ -161,9 +167,11 @@ pub struct Network<E: EthSpec> {
score_settings: PeerScoreSettings<E>,
/// The interval for updating gossipsub scores
update_gossipsub_scores: tokio::time::Interval,
gossip_cache: GossipCache,
pub gossip_cache: GossipCache,
/// This node's PeerId.
pub local_peer_id: PeerId,
/// Mallory specific. User handles the ping requests.
user_handle_ping: bool,
}
/// Implements the combined behaviour for the libp2p service.
@@ -178,11 +186,12 @@ impl<E: EthSpec> Network<E> {
executor: task_executor::TaskExecutor,
mut ctx: ServiceContext<'_>,
custody_group_count: u64,
gs_config: Option<GossipsubConfig>,
) -> Result<(Self, Arc<NetworkGlobals<E>>), String> {
let config = ctx.config.clone();
trace!("Libp2p Service starting");
// initialise the node's ID
let local_keypair = utils::load_private_key(&config);
let local_keypair = ctx.keypair;
// Trusted peers will also be marked as explicit in GossipSub.
// Cfr. https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#explicit-peering-agreements
@@ -227,14 +236,18 @@ impl<E: EthSpec> Network<E> {
message_domain_valid_snappy: ctx.chain_spec.message_domain_valid_snappy,
gossipsub_max_transmit_size: ctx.chain_spec.max_message_size(),
};
let gs_config = gossipsub_config(
config.network_load,
ctx.fork_context.clone(),
gossipsub_config_params,
ctx.chain_spec.seconds_per_slot,
E::slots_per_epoch(),
config.idontwant_message_size_threshold,
);
let gs_config = match gs_config {
Some(config) => config,
None => gossipsub_config(
config.network_load,
ctx.fork_context.clone(),
gossipsub_config_params,
ctx.chain_spec.seconds_per_slot,
E::slots_per_epoch(),
config.idontwant_message_size_threshold,
),
};
let score_settings = PeerScoreSettings::new(&ctx.chain_spec, gs_config.mesh_n());
@@ -380,6 +393,7 @@ impl<E: EthSpec> Network<E> {
config.outbound_rate_limiter_config.clone(),
network_params,
seq_number,
&config.attacker_config,
);
let discovery = {
@@ -418,20 +432,35 @@ impl<E: EthSpec> Network<E> {
quic_enabled: !config.disable_quic_support,
metrics_enabled: config.metrics_enabled,
target_peer_count: config.target_peers,
ping_interval_inbound: config
.attacker_config
.inbound_peers_ping
.unwrap_or(crate::peer_manager::config::DEFAULT_PING_INTERVAL_INBOUND),
ping_interval_outbound: config
.attacker_config
.outbound_peers_ping
.unwrap_or(crate::peer_manager::config::DEFAULT_PING_INTERVAL_OUTBOUND),
status_interval: config
.attacker_config
.status_interval
.unwrap_or(crate::peer_manager::config::DEFAULT_STATUS_INTERVAL),
..Default::default()
};
PeerManager::new(peer_manager_cfg, network_globals.clone())?
};
let max_incomming = if let Some(connections) = ctx.incoming_connections.as_ref() {
*connections
} else {
(config.target_peers as f32 * (1.0 + PEER_EXCESS_FACTOR - MIN_OUTBOUND_ONLY_FACTOR))
.ceil() as u32
};
let connection_limits = {
let limits = libp2p::connection_limits::ConnectionLimits::default()
.with_max_pending_incoming(Some(5))
.with_max_pending_incoming(Some(max_incomming))
.with_max_pending_outgoing(Some(16))
.with_max_established_incoming(Some(
(config.target_peers as f32
* (1.0 + PEER_EXCESS_FACTOR - MIN_OUTBOUND_ONLY_FACTOR))
.ceil() as u32,
))
.with_max_established_incoming(Some(max_incomming))
.with_max_established_outgoing(Some(
(config.target_peers as f32 * (1.0 + PEER_EXCESS_FACTOR)).ceil() as u32,
))
@@ -515,6 +544,7 @@ impl<E: EthSpec> Network<E> {
update_gossipsub_scores,
gossip_cache,
local_peer_id,
user_handle_ping: config.attacker_config.user_handle_ping,
};
network.start(&config).await?;
@@ -1440,7 +1470,7 @@ impl<E: EthSpec> Network<E> {
name = "libp2p",
skip_all
)]
fn send_meta_data_request(&mut self, peer_id: PeerId) {
pub fn send_meta_data_request(&mut self, peer_id: PeerId) {
let event = if self.fork_context.spec.is_peer_das_scheduled() {
// Nodes with higher custody will probably start advertising it
// before peerdas is activated
@@ -1757,9 +1787,24 @@ impl<E: EthSpec> Network<E> {
/* Behaviour managed protocols: Ping and Metadata */
RequestType::Ping(ping) => {
// inform the peer manager and send the response
if self.user_handle_ping {
return Some(NetworkEvent::RequestReceived {
peer_id,
inbound_request_id,
request_type,
});
}
self.peer_manager_mut().ping_request(&peer_id, ping.data);
None
}
RequestType::Raw(_) => {
// inform the peer manager and send the response
return Some(NetworkEvent::RequestReceived {
peer_id,
inbound_request_id,
request_type,
});
}
RequestType::MetaData(req) => {
// send the requested meta-data
self.send_meta_data_response(req, inbound_request_id, peer_id);
@@ -2003,6 +2048,7 @@ impl<E: EthSpec> Network<E> {
}
// send peer info to the peer manager.
self.peer_manager_mut().identify(&peer_id, &info);
return Some(NetworkEvent::IdentifyReceived(peer_id));
}
identify::Event::Sent { .. } => {}
identify::Event::Error { .. } => {}
@@ -2132,7 +2178,15 @@ impl<E: EthSpec> Network<E> {
// Poll the libp2p `Swarm`.
// This will poll the swarm and do maintenance routines.
Some(event) = self.swarm.next() => {
if let Some(event) = self.parse_swarm_event(event) {
// Try convert to mallory event.This just passes some swarm events up to mallory,
// rather than processing here.
// Attempt passing swarm events up to Mallory
let swarm_event = match MallorySwarmEvent::try_from(event) {
Ok(ev) => return NetworkEvent::MallorySwarmEvent(ev),
Err(ev) => ev,
};
if let Some(event) = self.parse_swarm_event(swarm_event) {
return event;
}
},
@@ -2158,6 +2212,31 @@ impl<E: EthSpec> Network<E> {
}
}
}
#[instrument(parent = None,
level = "trace",
fields(service = "libp2p"),
name = "libp2p",
skip_all
)]
/// Publish a raw gossipsub RPC message to a specific target.
pub fn publish_raw_targeted(&mut self, msg: RawMessage, target: PeerId) {
if let Err(e) = self.gossipsub_mut().raw_publish_targeted(target, msg) {
warn!("error" = ?e, "Could not publish message");
}
}
#[instrument(parent = None,
level = "trace",
fields(service = "libp2p"),
name = "libp2p",
skip_all
)]
/// Publish a raw gossipsub RPC message to a specific target.
pub fn publish_raw(&mut self, msg: RawMessage, topic: Topic) {
if let Err(e) = self.gossipsub_mut().raw_publish(topic, msg) {
warn!("error" = ?e, "Could not publish message");
}
}
#[instrument(parent = None,
level = "trace",

View File

@@ -30,6 +30,8 @@ pub struct Context<'a> {
pub fork_context: Arc<ForkContext>,
pub chain_spec: Arc<ChainSpec>,
pub libp2p_registry: Option<&'a mut Registry>,
pub keypair: Keypair,
pub incoming_connections: Option<u32>,
}
type BoxedTransport = Boxed<(PeerId, StreamMuxerBox)>;

View File

@@ -1,7 +1,7 @@
use gossipsub::{IdentTopic as Topic, TopicHash};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use strum::AsRefStr;
use strum::{AsRefStr, IntoStaticStr};
use types::{ChainSpec, DataColumnSubnetId, EthSpec, ForkName, SubnetId, SyncSubnetId, Unsigned};
use crate::Subnet;
@@ -145,7 +145,7 @@ pub struct GossipTopic {
/// Enum that brings these topics into the rust type system.
// NOTE: There is intentionally no unknown type here. We only allow known gossipsub topics.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AsRefStr)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AsRefStr, IntoStaticStr)]
#[strum(serialize_all = "snake_case")]
pub enum GossipKind {
/// Topic for publishing beacon blocks.

View File

@@ -5,7 +5,7 @@ mod metrics;
mod nat;
mod network_beacon_processor;
mod persisted_dht;
mod router;
pub mod router;
mod status;
mod subnet_service;
mod sync;

View File

@@ -314,6 +314,7 @@ impl<T: BeaconChainTypes> Router<T> {
Response::LightClientBootstrap(_)
| Response::LightClientOptimisticUpdate(_)
| Response::LightClientFinalityUpdate(_)
| Response::Ping(_)
| Response::LightClientUpdatesByRange(_) => unreachable!(),
}
}

View File

@@ -266,6 +266,8 @@ impl<T: BeaconChainTypes> NetworkService<T> {
debug!(fork_name = ?fork_context.current_fork(), "Current fork");
let keypair = lighthouse_network::load_private_key(&config);
// construct the libp2p service context
let service_context = Context {
config: config.clone(),
@@ -273,6 +275,8 @@ impl<T: BeaconChainTypes> NetworkService<T> {
fork_context: fork_context.clone(),
chain_spec: beacon_chain.spec.clone(),
libp2p_registry,
keypair,
incoming_connections: None,
};
// launch libp2p service
@@ -283,6 +287,7 @@ impl<T: BeaconChainTypes> NetworkService<T> {
.data_availability_checker
.custody_context()
.custody_group_count_at_head(&beacon_chain.spec),
None,
)
.await?;
@@ -487,6 +492,11 @@ impl<T: BeaconChainTypes> NetworkService<T> {
shutdown_sender: &mut Sender<ShutdownReason>,
) {
match ev {
// mallory event
NetworkEvent::MallorySwarmEvent(_) => {}
// mallory event
NetworkEvent::IdentifyReceived(_) => {}
NetworkEvent::PeerConnectedOutgoing(peer_id) => {
self.send_to_router(RouterMessage::StatusPeer(peer_id));
}

View File

@@ -244,7 +244,7 @@ impl Eth2NetworkConfig {
}
}
fn get_genesis_state_from_bytes<E: EthSpec>(&self) -> Result<BeaconState<E>, String> {
pub fn get_genesis_state_from_bytes<E: EthSpec>(&self) -> Result<BeaconState<E>, String> {
let spec = self.chain_spec::<E>()?;
self.genesis_state_bytes
.as_ref()