Repository: op-rs/kona
Pull request #1495: chore(node/p2p): Forward Discovery Events
Author: login: refcell
Labels: name: K-chore
description: Kind: chore
name: A-node
description: Area: cl node (eq. Go op-node) handles single-chain consensus
Created: 2025-04-23T17:59:28Z | Merged: 2025-04-28T17:56:57Z

### Description

Fixes the `kona-node` discovery driver to properly forward valid ENRs discovered through `discv5` to the gossip driver


Diff:
diff --git a/Cargo.lock b/Cargo.lock
index f5eba2c400..87b72049ff 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -485,7 +485,7 @@ checksum = "a40e1ef334153322fd878d07e86af7a529bcb86b2439525920a88eba87bcf943"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -654,7 +654,7 @@ dependencies = [
  "proc-macro-error2",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -670,7 +670,7 @@ dependencies = [
  "proc-macro-error2",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "syn-solidity",
  "tiny-keccak",
 ]
@@ -687,7 +687,7 @@ dependencies = [
  "macro-string",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "syn-solidity",
 ]
 
@@ -1040,7 +1040,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60"
 dependencies = [
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1078,7 +1078,7 @@ dependencies = [
  "num-traits",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1167,7 +1167,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1239,7 +1239,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "synstructure",
 ]
 
@@ -1251,7 +1251,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1310,7 +1310,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1332,7 +1332,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1343,7 +1343,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1405,7 +1405,7 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1476,7 +1476,7 @@ dependencies = [
  "regex",
  "rustc-hash 1.1.0",
  "shlex",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1635,7 +1635,7 @@ checksum = "efb7846e0cb180355c2dec69e721edafa36919850f1a9f52ffba4ebc0393cb71"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1714,9 +1714,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.2.19"
+version = "1.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"
+checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a"
 dependencies = [
  "jobserver",
  "libc",
@@ -1867,7 +1867,7 @@ dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2244,7 +2244,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2268,7 +2268,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "strsim",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2279,7 +2279,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2319,7 +2319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976"
 dependencies = [
  "data-encoding",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2395,7 +2395,7 @@ checksum = "2364b9aa47e460ce9bca6ac1777d14c98eef7e274eb077beed49f3adc94183ed"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2406,7 +2406,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2427,7 +2427,7 @@ dependencies = [
  "convert_case",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "unicode-xid",
 ]
 
@@ -2514,7 +2514,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2599,7 +2599,7 @@ dependencies = [
  "enum-ordinalize",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2668,7 +2668,7 @@ dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2688,7 +2688,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2699,7 +2699,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2719,7 +2719,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2775,7 +2775,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -3030,7 +3030,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -3701,7 +3701,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -3802,7 +3802,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -3877,7 +3877,7 @@ dependencies = [
  "indoc",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -4211,7 +4211,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -4224,7 +4224,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -5056,7 +5056,7 @@ dependencies = [
  "kona-std-fpvm",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -5373,7 +5373,7 @@ dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -5620,7 +5620,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -5831,7 +5831,7 @@ checksum = "0ac7d860b767c6398e88fe93db73ce53eb496057aa6895ffa4d60cb02e1d1c6b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6069,7 +6069,7 @@ checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6253,7 +6253,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6350,7 +6350,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6455,7 +6455,7 @@ dependencies = [
  "phf_shared",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6484,7 +6484,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6622,7 +6622,7 @@ version = "0.2.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
 dependencies = [
- "zerocopy 0.8.24",
+ "zerocopy 0.8.25",
 ]
 
 [[package]]
@@ -6673,7 +6673,7 @@ dependencies = [
  "proc-macro-error-attr2",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6743,7 +6743,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6774,7 +6774,7 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6794,7 +6794,7 @@ checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -7467,7 +7467,7 @@ checksum = "246b40ac189af6c675d124b802e8ef6d5246c53e17367ce9501f8f66a81abb7a"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -7522,7 +7522,7 @@ dependencies = [
  "regex",
  "relative-path",
  "rustc_version 0.4.1",
- "syn 2.0.100",
+ "syn 2.0.101",
  "unicode-ident",
 ]
 
@@ -7705,9 +7705,9 @@ dependencies = [
 
 [[package]]
 name = "rustls-platform-verifier"
-version = "0.5.1"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a5467026f437b4cb2a533865eaa73eb840019a0916f4b9ec563c6e617e086c9"
+checksum = "4937d110d34408e9e5ad30ba0b0ca3b6a8a390f8db3636db60144ac4fa792750"
 dependencies = [
  "core-foundation 0.10.0",
  "core-foundation-sys",
@@ -7940,7 +7940,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -7964,7 +7964,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8015,7 +8015,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8322,7 +8322,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "rustversion",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8335,7 +8335,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "rustversion",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8380,9 +8380,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.100"
+version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -8398,7 +8398,7 @@ dependencies = [
  "paste",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8418,7 +8418,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8463,7 +8463,7 @@ dependencies = [
  "proc-macro-error2",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8526,7 +8526,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8537,7 +8537,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8660,7 +8660,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -8728,9 +8728,9 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.8.20"
+version = "0.8.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
+checksum = "900f6c86a685850b1bc9f6223b20125115ee3f31e01207d81655bbcc0aea9231"
 dependencies = [
  "serde",
  "serde_spanned",
@@ -8740,18 +8740,18 @@ dependencies = [
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.8"
+version = "0.6.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "toml_edit"
-version = "0.22.24"
+version = "0.22.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
+checksum = "10558ed0bd2a1562e630926a2d1f0b98c827da99fabd3fe20920a59642504485"
 dependencies = [
  "indexmap 2.9.0",
  "serde",
@@ -8834,7 +8834,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -9171,7 +9171,7 @@ dependencies = [
  "log",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "wasm-bindgen-shared",
 ]
 
@@ -9206,7 +9206,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -9256,18 +9256,18 @@ dependencies = [
 
 [[package]]
 name = "webpki-root-certs"
-version = "0.26.8"
+version = "0.26.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09aed61f5e8d2c18344b3faa33a4c837855fe56642757754775548fee21386c4"
+checksum = "180d2741b6115c3d906577e6533ad89472d48d96df00270fccb78233073d77f7"
 dependencies = [
  "rustls-pki-types",
 ]
 
 [[package]]
 name = "webpki-roots"
-version = "0.26.8"
+version = "0.26.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9"
+checksum = "29aad86cec885cafd03e8305fd727c418e970a521322c91688414d5b8efba16b"
 dependencies = [
  "rustls-pki-types",
 ]
@@ -9373,7 +9373,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -9384,7 +9384,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -9395,7 +9395,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -9406,7 +9406,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -9931,7 +9931,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "synstructure",
 ]
 
@@ -9946,11 +9946,11 @@ dependencies = [
 
 [[package]]
 name = "zerocopy"
-version = "0.8.24"
+version = "0.8.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
+checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
 dependencies = [
- "zerocopy-derive 0.8.24",
+ "zerocopy-derive 0.8.25",
 ]
 
 [[package]]
@@ -9961,18 +9961,18 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.8.24"
+version = "0.8.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
+checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -9992,7 +9992,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "synstructure",
 ]
 
@@ -10013,7 +10013,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -10035,5 +10035,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
diff --git a/crates/node/p2p/src/discv5/driver.rs b/crates/node/p2p/src/discv5/driver.rs
index 5ed23b8857..6ce6b7525c 100644
--- a/crates/node/p2p/src/discv5/driver.rs
+++ b/crates/node/p2p/src/discv5/driver.rs
@@ -279,6 +279,28 @@ impl Discv5Driver {
             // Step 3: Forward ENRs in the bootstore to the enr receiver.
             self.forward(enr_sender.clone()).await;
 
+            // Continuously attempt to start the event stream with a retry limit and shutdown
+            // signal.
+            let mut retries = 0;
+            let max_retries = 10; // Maximum number of retries before giving up.
+            let mut event_stream = loop {
+                if retries >= max_retries {
+                    error!(target: "discovery", "Exceeded maximum retries for event stream startup. Aborting...");
+                    return; // Exit the task if the retry limit is reached.
+                }
+                match self.disc.event_stream().await {
+                    Ok(event_stream) => {
+                        break event_stream;
+                    }
+                    Err(e) => {
+                        warn!(target: "discovery", "Failed to start event stream: {:?}", e);
+                        retries += 1;
+                        sleep(Duration::from_secs(2)).await;
+                        info!(target: "discovery", "Retrying event stream startup... (Attempt {}/{})", retries, max_retries);
+                    }
+                }
+            };
+
             // Step 4: Run the core driver loop.
             loop {
                 tokio::select! {
@@ -334,6 +356,53 @@ impl Discv5Driver {
                             }
                         }
                     }
+                    event = event_stream.recv() => {
+                        let Some(event) = event else {
+                            trace!(target: "discovery", "Received `None` event");
+                            continue;
+                        };
+                        match event {
+                            discv5::Event::Discovered(enr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+                            }
+                            discv5::Event::SessionEstablished(enr, addr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Session established with valid ENR, forwarding to swarm. Address: {:?}, ENR: {:?}", addr, enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+                            }
+                            discv5::Event::UnverifiableEnr { enr, .. } => {
+                                debug!(target: "discovery", "Unverifiable ENR discovered: {:?}", enr);
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+
+                            }
+                            _ => {}
+                        }
+                    }
                     _ = interval.tick() => {
                         let id = NodeId::random();
                         debug!(target: "discovery", "Finding random node: {}", id);
diff --git a/deny.toml b/deny.toml
index 2df70d6cc2..f0ad6b08a8 100644
--- a/deny.toml
+++ b/deny.toml
@@ -25,6 +25,7 @@ allow = [
     "MPL-2.0",
     "Zlib",
     "0BSD",
+    "CDLA-Permissive-2.0",
 ]
 confidence-threshold = 0.8
 exceptions = [


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR addresses the issue of properly forwarding valid ENRs from the discv5 discovery driver to the gossip driver. Key changes include:
- Adding a retry loop to continuously attempt to start the event stream.
- Incorporating new event handling branches for both Discovered and SessionEstablished events.
- Forwarding valid ENRs to the store and asynchronously sending them to the swarm.




state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T18:00:17Z
user: login: emhane
body: check out reth's discv5 workaround for geth enrs. sigp/discv5 is much stricter about correct enr configuration for its peers than geth, so we had to ask sigp to add this special new event for being geth compatible when using sigp/discv5 for EL
https://github.com/paradigmxyz/reth/blob/dd4aa1a85b5babbcedf2a5978cd88b631bc486e8/crates/net/discv5/src/lib.rs#L255-L283
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T16:04:26Z
user: login: theochap
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-28T16:45:07Z
user: login: theochap
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-28T16:47:25Z
user: login: theochap
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-28T16:51:19Z
user: login: refcell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T16:58:51Z
user: login: refcell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T17:01:21Z
user: login: refcell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T17:01:57Z
user: login: theochap
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-28T17:09:21Z

Review comments:
diff_hunk: @@ -237,6 +237,20 @@ impl Discv5Driver {
             // Interval at which to sync the boot store.
             let mut store_interval = tokio::time::interval(Duration::from_secs(60));
 
+            // Continuously attempt to start the event stream.
+            let mut event_stream = loop {
+                match self.disc.event_stream().await {
+                    Ok(event_stream) => {
+                        break event_stream;
+                    }
+                    Err(e) => {
+                        warn!(target: "discovery", "Failed to start event stream: {:?}", e);
+                        sleep(Duration::from_secs(2)).await;
+                        info!(target: "discovery", "Retrying event stream startup...");
path: crates/node/p2p/src/discv5/driver.rs
user: login: Copilot
body: The infinite retry loop for starting the event stream could potentially block shutdown or recovery when the event stream is permanently failing. Consider adding a termination condition or a cancellation mechanism to prevent an endless loop.
```suggestion
            // Continuously attempt to start the event stream with a retry limit and shutdown signal.
            let mut retries = 0;
            let max_retries = 10; // Maximum number of retries before giving up.
            let mut event_stream = loop {
                if retries >= max_retries {
                    error!(target: "discovery", "Exceeded maximum retries for event stream startup. Aborting...");
                    return; // Exit the task if the retry limit is reached.
                }
                if shutdown_signal.has_changed().unwrap_or(false) && *shutdown_signal.borrow() {
                    info!(target: "discovery", "Shutdown signal received. Exiting event stream startup loop...");
                    return; // Exit the task if a shutdown signal is received.
                }
                match self.disc.event_stream().await {
                    Ok(event_stream) => {
                        break event_stream;
                    }
                    Err(e) => {
                        warn!(target: "discovery", "Failed to start event stream: {:?}", e);
                        retries += 1;
                        sleep(Duration::from_secs(2)).await;
                        info!(target: "discovery", "Retrying event stream startup... (Attempt {}/{})", retries, max_retries);
```
created_at: 2025-04-23T18:00:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -292,6 +306,39 @@ impl Discv5Driver {
                             }
                         }
                     }
+                    event = event_stream.recv() => {
+                        let Some(event) = event else {
+                            trace!(target: "discovery", "Receiver `None` event");
+                            continue;
path: crates/node/p2p/src/discv5/driver.rs
user: login: Copilot
body: If event_stream.recv() returns None, the current logic only logs a trace and continues, which might lead to continuous looping without a clear shutdown pathway. Consider explicitly handling the None case to allow proper termination or error propagation.
```suggestion
                            trace!(target: "discovery", "Receiver `None` event, terminating loop");
                            break;
```
created_at: 2025-04-23T18:00:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -314,6 +328,39 @@ impl Discv5Driver {
                             }
                         }
                     }
+                    event = event_stream.recv() => {
+                        let Some(event) = event else {
+                            trace!(target: "discovery", "Receiver `None` event");
path: crates/node/p2p/src/discv5/driver.rs
user: login: emhane
body: ```suggestion
                            trace!(target: "discovery", "Received `None` event");
```
created_at: 2025-04-24T15:57:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -314,6 +328,39 @@ impl Discv5Driver {
                             }
                         }
                     }
+                    event = event_stream.recv() => {
+                        let Some(event) = event else {
+                            trace!(target: "discovery", "Receiver `None` event");
+                            continue;
+                        };
+                        match event {
+                            discv5::Event::Discovered(enr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+                            }
+                            discv5::Event::SessionEstablished(enr, addr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Session established with valid ENR, forwarding to swarm. Address: {:?}, ENR: {:?}", addr, enr);
path: crates/node/p2p/src/discv5/driver.rs
user: login: emhane
body: ```suggestion
                                    debug!(target: "discovery",
                                        %addr,
                                        ?enr,
                                        "Session established with valid ENR, forwarding to swarm"
                                    );
```
let's use the logs the way they were designed to be used with kv pairs. the above log will output
`.. addr=<the socket addr value> enr=<the enr in human readable format> ..`
NOTE! use the debug operator for enrs, ie `?enr`, otherwise they serialise in base 64 which is super unhelpful for debugging
created_at: 2025-04-24T16:02:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -279,6 +279,28 @@ impl Discv5Driver {
             // Step 3: Forward ENRs in the bootstore to the enr receiver.
             self.forward(enr_sender.clone()).await;
 
+            // Continuously attempt to start the event stream with a retry limit and shutdown
+            // signal.
+            let mut retries = 0;
+            let max_retries = 10; // Maximum number of retries before giving up.
+            let mut event_stream = loop {
+                if retries >= max_retries {
+                    error!(target: "discovery", "Exceeded maximum retries for event stream startup. Aborting...");
+                    return; // Exit the task if the retry limit is reached.
+                }
+                match self.disc.event_stream().await {
+                    Ok(event_stream) => {
+                        break event_stream;
+                    }
+                    Err(e) => {
+                        warn!(target: "discovery", "Failed to start event stream: {:?}", e);
+                        retries += 1;
+                        sleep(Duration::from_secs(2)).await;
+                        info!(target: "discovery", "Retrying event stream startup... (Attempt {}/{})", retries, max_retries);
+                    }
+                }
+            };
path: crates/node/p2p/src/discv5/driver.rs
user: login: theochap
body: question: did we have issues starting the discovery event stream? That's interesting, never noticed it on my end
created_at: 2025-04-28T16:45:06Z
author_association: MEMBER
diff_hunk: @@ -334,6 +356,53 @@ impl Discv5Driver {
                             }
                         }
                     }
+                    event = event_stream.recv() => {
+                        let Some(event) = event else {
+                            trace!(target: "discovery", "Received `None` event");
+                            continue;
+                        };
+                        match event {
+                            discv5::Event::Discovered(enr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+                            }
+                            discv5::Event::SessionEstablished(enr, addr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Session established with valid ENR, forwarding to swarm. Address: {:?}, ENR: {:?}", addr, enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+                            }
+                            discv5::Event::UnverifiableEnr { enr, .. } => {
+                                debug!(target: "discovery", "Unverifiable ENR discovered: {:?}", enr);
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+
+                            }
+                            _ => {}
+                        }
+                    }
path: crates/node/p2p/src/discv5/driver.rs
user: login: theochap
body: Just checking: do we unit test the `EnrValidation::validate` method? If not, maybe we should add a couple of unit tests just to be on the safe side. Can be done in a separate PR
created_at: 2025-04-28T16:47:25Z
author_association: MEMBER
diff_hunk: @@ -334,6 +356,53 @@ impl Discv5Driver {
                             }
                         }
                     }
+                    event = event_stream.recv() => {
+                        let Some(event) = event else {
+                            trace!(target: "discovery", "Received `None` event");
+                            continue;
+                        };
+                        match event {
+                            discv5::Event::Discovered(enr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
path: crates/node/p2p/src/discv5/driver.rs
user: login: theochap
body: Just checking: below ([here](https://github.com/op-rs/kona/pull/1495/files#diff-e3c2d30d9bcd63009fc8fd07a05b5a190843f0c2b78f8c58f5d63493288c64ecR426)), don't we already add the ENRs to the store? Maybe we should try to remove this merge below so that we only have one place where we mutate the store (that is provided we are confident that all the enr update events are handled here)
created_at: 2025-04-28T16:51:19Z
author_association: MEMBER
diff_hunk: @@ -279,6 +279,28 @@ impl Discv5Driver {
             // Step 3: Forward ENRs in the bootstore to the enr receiver.
             self.forward(enr_sender.clone()).await;
 
+            // Continuously attempt to start the event stream with a retry limit and shutdown
+            // signal.
+            let mut retries = 0;
+            let max_retries = 10; // Maximum number of retries before giving up.
+            let mut event_stream = loop {
+                if retries >= max_retries {
+                    error!(target: "discovery", "Exceeded maximum retries for event stream startup. Aborting...");
+                    return; // Exit the task if the retry limit is reached.
+                }
+                match self.disc.event_stream().await {
+                    Ok(event_stream) => {
+                        break event_stream;
+                    }
+                    Err(e) => {
+                        warn!(target: "discovery", "Failed to start event stream: {:?}", e);
+                        retries += 1;
+                        sleep(Duration::from_secs(2)).await;
+                        info!(target: "discovery", "Retrying event stream startup... (Attempt {}/{})", retries, max_retries);
+                    }
+                }
+            };
path: crates/node/p2p/src/discv5/driver.rs
user: login: refcell
body: We didn't have the event stream in the first place, this pr adds it. We could also just error here if we fail to get it, but I think it's nice to have some gentle retry logic.
created_at: 2025-04-28T16:58:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -334,6 +356,53 @@ impl Discv5Driver {
                             }
                         }
                     }
+                    event = event_stream.recv() => {
+                        let Some(event) = event else {
+                            trace!(target: "discovery", "Received `None` event");
+                            continue;
+                        };
+                        match event {
+                            discv5::Event::Discovered(enr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
path: crates/node/p2p/src/discv5/driver.rs
user: login: refcell
body: If it is successfully added, then this becomes a no-op since the bootstore will check if it contains the peer before adding it again inside [`add_enr`](https://github.com/op-rs/kona/blob/main/crates/node/p2p/src/peers/store.rs#L52-L54). So we don't have to worry about calling `add_enr` with redundant ENRs by design. Better to call again in case the discovery service discovers an ENR outside of the find node query.
created_at: 2025-04-28T17:01:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -334,6 +356,53 @@ impl Discv5Driver {
                             }
                         }
                     }
+                    event = event_stream.recv() => {
+                        let Some(event) = event else {
+                            trace!(target: "discovery", "Received `None` event");
+                            continue;
+                        };
+                        match event {
+                            discv5::Event::Discovered(enr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+                            }
+                            discv5::Event::SessionEstablished(enr, addr) => {
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Session established with valid ENR, forwarding to swarm. Address: {:?}, ENR: {:?}", addr, enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+                            }
+                            discv5::Event::UnverifiableEnr { enr, .. } => {
+                                debug!(target: "discovery", "Unverifiable ENR discovered: {:?}", enr);
+                                if EnrValidation::validate(&enr, chain_id).is_valid() {
+                                    debug!(target: "discovery", "Valid ENR discovered, forwarding to swarm: {:?}", enr);
+                                    self.store.add_enr(enr.clone());
+                                    let sender = enr_sender.clone();
+                                    tokio::spawn(async move {
+                                        if let Err(e) = sender.send(enr).await {
+                                            debug!(target: "discovery", "Failed to send enr: {:?}", e);
+                                        }
+                                    });
+                                }
+
+                            }
+                            _ => {}
+                        }
+                    }
path: crates/node/p2p/src/discv5/driver.rs
user: login: refcell
body: Good callout. I have an open pr [here](https://github.com/op-rs/kona/pull/1552) that could make sense to add those tests.
created_at: 2025-04-28T17:01:57Z
author_association: CONTRIBUTOR

PR comments:
user: login: refcell
created_at: 2025-04-23T17:59:30Z
body: ## 📚 $\text{Stack Overview}$

Pulls submitted in this stack:
* #1495 👈
* `main`

_This comment was automatically generated by [`st`](https://github.com/clabby/st)._
author_association: CONTRIBUTOR
user: login: codecov[bot]
created_at: 2025-04-23T18:02:53Z
body: ## [Codecov](https://app.codecov.io/gh/op-rs/kona/pull/1495?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=op-rs) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 92.8%. Comparing base [(`ac74b1b`)](https://app.codecov.io/gh/op-rs/kona/commit/ac74b1b4ad61f9216e9039631faffa227631e4f9?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=op-rs) to head [(`3b5a72c`)](https://app.codecov.io/gh/op-rs/kona/commit/3b5a72c60e44d5b0c1a06a955e4666180fc9d0d8?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=op-rs).
> Report is 6 commits behind head on main.

:white_check_mark: All tests successful. No failed tests found.


[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/op-rs/kona/pull/1495?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=op-rs).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=op-rs).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: theochap
created_at: 2025-04-28T17:09:34Z
body: Looks great thanks for taking care of it!
author_association: MEMBER