From 356e55556f6db017444aff0d80d733c342210c2c Mon Sep 17 00:00:00 2001 From: Cayman Date: Mon, 2 Oct 2023 11:15:27 -0400 Subject: [PATCH 01/36] chore: bump libp2p deps --- package.json | 2 +- packages/beacon-node/package.json | 20 +- packages/cli/package.json | 6 +- packages/reqresp/package.json | 6 +- yarn.lock | 445 ++++++++++++++---------------- 5 files changed, 223 insertions(+), 256 deletions(-) diff --git a/package.json b/package.json index 06afdc19bb99..a46773404d91 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "karma-spec-reporter": "^0.0.36", "karma-webpack": "^5.0.0", "lerna": "^7.3.0", - "libp2p": "0.46.3", + "libp2p": "0.46.12", "mocha": "^10.2.0", "node-gyp": "^9.4.0", "npm-run-all": "^4.1.5", diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 7af605f6f603..a80027ad45ec 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -101,7 +101,7 @@ "@chainsafe/blst": "^0.2.9", "@chainsafe/discv5": "^5.1.0", "@chainsafe/libp2p-gossipsub": "^10.1.0", - "@chainsafe/libp2p-noise": "^13.0.0", + "@chainsafe/libp2p-noise": "^13.0.1", "@chainsafe/persistent-merkle-tree": "^0.5.0", "@chainsafe/prometheus-gc-stats": "^1.0.0", "@chainsafe/ssz": "^0.13.0", @@ -111,14 +111,14 @@ "@fastify/cors": "^8.2.1", "@fastify/swagger": "^8.10.0", "@fastify/swagger-ui": "^1.9.3", - "@libp2p/bootstrap": "^9.0.2", - "@libp2p/interface": "^0.1.1", - "@libp2p/mdns": "^9.0.2", - "@libp2p/mplex": "^9.0.2", - "@libp2p/peer-id": "^3.0.1", - "@libp2p/peer-id-factory": "^3.0.2", - "@libp2p/prometheus-metrics": "^2.0.2", - "@libp2p/tcp": "8.0.2", + "@libp2p/bootstrap": "^9.0.7", + "@libp2p/interface": "^0.1.2", + "@libp2p/mdns": "^9.0.9", + "@libp2p/mplex": "^9.0.7", + "@libp2p/peer-id": "^3.0.2", + "@libp2p/peer-id-factory": "^3.0.4", + "@libp2p/prometheus-metrics": "^2.0.7", + "@libp2p/tcp": "8.0.8", "@lodestar/api": "^1.11.3", "@lodestar/config": "^1.11.3", "@lodestar/db": "^1.11.3", @@ -143,7 +143,7 @@ "it-all": "^3.0.2", "it-pipe": "^3.0.1", "jwt-simple": "0.5.6", - "libp2p": "0.46.3", + "libp2p": "0.46.12", "multiformats": "^11.0.1", "prom-client": "^14.2.0", "qs": "^6.11.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index ab9e09e39a3c..75da9ed210f2 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -61,9 +61,9 @@ "@chainsafe/discv5": "^5.1.0", "@chainsafe/ssz": "^0.13.0", "@chainsafe/threads": "^1.11.1", - "@libp2p/crypto": "^2.0.2", - "@libp2p/peer-id": "^3.0.1", - "@libp2p/peer-id-factory": "^3.0.2", + "@libp2p/crypto": "^2.0.4", + "@libp2p/peer-id": "^3.0.2", + "@libp2p/peer-id-factory": "^3.0.4", "@lodestar/api": "^1.11.3", "@lodestar/beacon-node": "^1.11.3", "@lodestar/config": "^1.11.3", diff --git a/packages/reqresp/package.json b/packages/reqresp/package.json index 9c932516d758..af826c0467f2 100644 --- a/packages/reqresp/package.json +++ b/packages/reqresp/package.json @@ -55,7 +55,7 @@ }, "dependencies": { "@chainsafe/fast-crc32c": "^4.1.1", - "@libp2p/interface": "^0.1.1", + "@libp2p/interface": "^0.1.2", "@lodestar/config": "^1.11.3", "@lodestar/params": "^1.11.3", "@lodestar/utils": "^1.11.3", @@ -69,10 +69,10 @@ "devDependencies": { "@lodestar/logger": "^1.11.3", "@lodestar/types": "^1.11.3", - "libp2p": "0.46.3" + "libp2p": "0.46.12" }, "peerDependencies": { - "libp2p": "~0.46.3" + "libp2p": "~0.46.12" }, "keywords": [ "ethereum", diff --git a/yarn.lock b/yarn.lock index 03c4f41a0ba9..9f5d14a38e8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,14 +7,6 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@achingbrain/ip-address@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@achingbrain/ip-address/-/ip-address-8.1.0.tgz#24f2e9cd7289e33f433d771b23bea56cfd0242c9" - integrity sha512-Zus4vMKVRDm+R1o0QJNhD0PD/8qRGO3Zx8YPsFG5lANt5utVtGg3iHVGBSAF80TfQmhi8rP+Kg/OigdxY0BXHw== - dependencies: - jsbn "1.1.0" - sprintf-js "1.1.2" - "@achingbrain/nat-port-mapper@^1.0.9": version "1.0.9" resolved "https://registry.yarnpkg.com/@achingbrain/nat-port-mapper/-/nat-port-mapper-1.0.9.tgz#8e61cf6f5dbeaa55c4e64a0023a362d4a1f61a36" @@ -560,6 +552,11 @@ resolved "https://registry.yarnpkg.com/@chainsafe/is-ip/-/is-ip-2.0.1.tgz#62cb285669d91f88fd9fa285048dde3882f0993b" integrity sha512-nqSJ8u2a1Rv9FYbyI8qpDhTYujaKEyLknNrTejLYoSWmdeg+2WB7R6BZqPZYfrJzDxVi3rl6ZQuoaEvpKRZWgQ== +"@chainsafe/is-ip@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/is-ip/-/is-ip-2.0.2.tgz#7311e7403f11d8c5cfa48111f56fcecaac37c9f6" + integrity sha512-ndGqEMG1W5WkGagaqOZHpPU172AGdxr+LD15sv3WIUvT5oCFUrG1Y0CW/v2Egwj4JXEvSibaIIIqImsm98y1nA== + "@chainsafe/libp2p-gossipsub@^10.1.0": version "10.1.0" resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-gossipsub/-/libp2p-gossipsub-10.1.0.tgz#29c2e3da2bbf1dc68ae171c5ac777bce9ca88c2c" @@ -582,16 +579,16 @@ uint8arraylist "^2.4.3" uint8arrays "^4.0.4" -"@chainsafe/libp2p-noise@^13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-noise/-/libp2p-noise-13.0.0.tgz#6fa9352945d5dee79d33051ee4095e6ee65969c1" - integrity sha512-+kRW5GSTGYB42WjFa1f7Wc/1+VWLffOhwChi+CbPceidMHM5pbOQNb+xQM2/aqLre+A+WnBOKEopME7dnoqLNQ== +"@chainsafe/libp2p-noise@^13.0.1": + version "13.0.1" + resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-noise/-/libp2p-noise-13.0.1.tgz#d6309d50b2a36014e8fb4781c9d7af3723659d2a" + integrity sha512-eeOFubXyS9sK0oBg/qRfve6LVGzZX1vyULVidaKGTJr8Y4dtyU4+Btqw/aVo3o1lhdvb/qoY+p/Ep2pUsvJKhg== dependencies: "@libp2p/crypto" "^2.0.0" "@libp2p/interface" "^0.1.0" "@libp2p/logger" "^3.0.0" "@libp2p/peer-id" "^3.0.0" - "@noble/ciphers" "^0.1.4" + "@noble/ciphers" "^0.3.0" "@noble/curves" "^1.1.0" "@noble/hashes" "^1.3.1" it-byte-stream "^1.0.0" @@ -1491,39 +1488,39 @@ yargs "16.2.0" yargs-parser "20.2.4" -"@libp2p/bootstrap@^9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/bootstrap/-/bootstrap-9.0.2.tgz#a9c4374e715f3dda41653a293ee8936c34732fda" - integrity sha512-G16viuLQr+AHVnXtA1p9XQqJHo3I1mlScARroDfSG32uU5PgZpQRB2c7YoUy5vVTDzeIf82sq70HIOmwrr9ZTw== +"@libp2p/bootstrap@^9.0.7": + version "9.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/bootstrap/-/bootstrap-9.0.7.tgz#bcc7682ff153f48a021f3c085311962917403643" + integrity sha512-xpDJlxBGYSa4eVm3GWChtY9QL58Oh1PowtowMEuE5TEW1zcLzvQaQ9YiG2Mo9+q+0CNnAyemJF5rBequ7XbLBQ== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" - "@libp2p/peer-id" "^3.0.1" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" + "@libp2p/peer-id" "^3.0.2" "@multiformats/mafmt" "^12.1.2" - "@multiformats/multiaddr" "^12.1.3" + "@multiformats/multiaddr" "^12.1.5" -"@libp2p/crypto@^2.0.0", "@libp2p/crypto@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/crypto/-/crypto-2.0.2.tgz#c1c950e452c7a417631bf5b2b6bda96292bf35ee" - integrity sha512-CmKYBUpU/WKeLSGtqCtsPubwL7wS50toyO1wDNZsbstFDEXZB5YrAnSwPiSzXG33rgeoGW5VNsUShJvFylVPcw== +"@libp2p/crypto@^2.0.0", "@libp2p/crypto@^2.0.2", "@libp2p/crypto@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@libp2p/crypto/-/crypto-2.0.4.tgz#f0c6fcf246c8b6974e4fc92499a0bdce19c3c54c" + integrity sha512-1/PDtJC+k64Sd0bzK4DvGflk8Brj5fGskRCfBOndhNmitjHe8+ewbuA9lldTOerfkVgMn7Zb+sjNsytyr6BqlA== dependencies: - "@libp2p/interface" "^0.1.1" - "@noble/ed25519" "^1.6.0" - "@noble/secp256k1" "^1.5.4" + "@libp2p/interface" "^0.1.2" + "@noble/curves" "^1.1.0" + "@noble/hashes" "^1.3.1" multiformats "^12.0.1" node-forge "^1.1.0" protons-runtime "^5.0.0" uint8arraylist "^2.4.3" - uint8arrays "^4.0.4" + uint8arrays "^4.0.6" -"@libp2p/interface-internal@^0.1.0", "@libp2p/interface-internal@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@libp2p/interface-internal/-/interface-internal-0.1.2.tgz#790ff22961eed335bf803b3650e35ad299be5ab8" - integrity sha512-Ehz3+ry3VfzamoWwMyx/ltnTP4tM4OdQItRj7C6BPMd7V93H4EFqXL9zrXrNHV/ZGnayx3sIiuqb3pCDIoU5bQ== +"@libp2p/interface-internal@^0.1.0", "@libp2p/interface-internal@^0.1.2", "@libp2p/interface-internal@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@libp2p/interface-internal/-/interface-internal-0.1.5.tgz#819d15c3b0b2cd25e1be59aacc2c5cb42fe811e3" + integrity sha512-h6f1fk2M6BhqjooE4I1iODmY/jorCvJ1bX1IOMHOMNkrbwsMS2BOpDkBJD+u+QlKMoRIA2zEfWezXB4Pa8GASw== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/peer-collections" "^4.0.2" - "@multiformats/multiaddr" "^12.1.3" + "@libp2p/interface" "^0.1.2" + "@libp2p/peer-collections" "^4.0.4" + "@multiformats/multiaddr" "^12.1.5" uint8arraylist "^2.4.3" "@libp2p/interface-peer-id@^2.0.2": @@ -1533,20 +1530,7 @@ dependencies: multiformats "^11.0.0" -"@libp2p/interface@^0.1.0", "@libp2p/interface@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@libp2p/interface/-/interface-0.1.1.tgz#c1853bfe86bcd5a4b209891e501d6d208a065b77" - integrity sha512-Uk+4YnEShx4gfzweYdJCHdLxcA1gAnTiZ8vlvr5DnSHJrg8yUN6VYkk96W3iJQ7H7hqV/ULIoIRQLHjLtDDCkw== - dependencies: - "@multiformats/multiaddr" "^12.1.3" - abortable-iterator "^5.0.1" - it-pushable "^3.2.0" - it-stream-types "^2.0.1" - multiformats "^12.0.1" - p-defer "^4.0.0" - uint8arraylist "^2.4.3" - -"@libp2p/interface@^0.1.2": +"@libp2p/interface@^0.1.0", "@libp2p/interface@^0.1.1", "@libp2p/interface@^0.1.2": version "0.1.2" resolved "https://registry.yarnpkg.com/@libp2p/interface/-/interface-0.1.2.tgz#4ea5a4fa8bbd46c3fe4c945ff6b8c6d5d41f10b0" integrity sha512-Q5t27434Mvn+R6AUJlRH+q/jSXarDpP+KXVkyGY7S1fKPI2berqoFPqT61bRRBYsCH2OPZiKBB53VUzxL9uEvg== @@ -1559,19 +1543,19 @@ p-defer "^4.0.0" uint8arraylist "^2.4.3" -"@libp2p/keychain@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/keychain/-/keychain-3.0.2.tgz#e4b6dd31c504b3246209c7bf3538adbf3e54bb44" - integrity sha512-pAw/Te1q2F5HYQk+fJl64XOzOf1MTIptdYI0BIGKrx28d96zOe78fPEGqvj6rLvrHnKGa7PRj/BsLcmRS9OF8Q== +"@libp2p/keychain@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@libp2p/keychain/-/keychain-3.0.4.tgz#94d04a592ea18d83ebed6d6d8457e9aa8cc72e91" + integrity sha512-qt9Ttv2lczOpxkbe5YmqwqJx9nty4pWEE9sJ4rY2Ci2k1K+Bt2vMla610BFBzcYq0QqYYqNN4pawFZ33sc3iLg== dependencies: - "@libp2p/crypto" "^2.0.2" - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" - "@libp2p/peer-id" "^3.0.1" + "@libp2p/crypto" "^2.0.4" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" + "@libp2p/peer-id" "^3.0.2" interface-datastore "^8.2.0" merge-options "^3.0.4" sanitize-filename "^1.6.3" - uint8arrays "^4.0.4" + uint8arrays "^4.0.6" "@libp2p/logger@^2.0.0": version "2.1.1" @@ -1584,54 +1568,55 @@ interface-datastore "^8.2.0" multiformats "^11.0.2" -"@libp2p/logger@^3.0.0", "@libp2p/logger@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-3.0.1.tgz#e89332c691a1652e1abefde7e03886ca1765b4bf" - integrity sha512-sm2ewSZ1f0xnhYDcdUWsakD/mLS5SpyZwWOhgIb02TGJqb79lXVrxYTzOnzK4mCeVmqvv2u6g/ifFZyrt4O0cg== +"@libp2p/logger@^3.0.0", "@libp2p/logger@^3.0.1", "@libp2p/logger@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-3.0.2.tgz#aa507db233c6905692ffaf9f4daba1e6326992c4" + integrity sha512-2JtRGBXiGfm1t5XneUIXQ2JusW7QwyYmxsW7hSAYS5J73RQJUicpt5le5obVRt7+OM39ei+nWEuC6Xvm1ugHkw== dependencies: - "@libp2p/interface" "^0.1.1" - "@multiformats/multiaddr" "^12.1.3" + "@libp2p/interface" "^0.1.2" + "@multiformats/multiaddr" "^12.1.5" debug "^4.3.4" interface-datastore "^8.2.0" multiformats "^12.0.1" -"@libp2p/mdns@^9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/mdns/-/mdns-9.0.2.tgz#ed307c88edb988f67cd57678cc80bec75196a4b3" - integrity sha512-3CB5cddx+rrb5gxQlZYy6qgRes8Z4gzEUxCs4F3si3zXsf5XyqaNXsnNHWfMEqh0kFa41sgr4kUAWDYAydfa3A== +"@libp2p/mdns@^9.0.9": + version "9.0.9" + resolved "https://registry.yarnpkg.com/@libp2p/mdns/-/mdns-9.0.9.tgz#9ef4944b71204e6578f2283c9634dec61da58ada" + integrity sha512-Id3iPJa1TRomYH1rIgcPxQTFpVlhscU5b8wqulzYSyzShggnM4MoxisrgLoSSySVzIrgIlKRTG8/m03neLIrZw== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" - "@libp2p/peer-id" "^3.0.1" - "@multiformats/multiaddr" "^12.1.3" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" + "@libp2p/peer-id" "^3.0.2" + "@libp2p/utils" "^4.0.3" + "@multiformats/multiaddr" "^12.1.5" "@types/multicast-dns" "^7.2.1" dns-packet "^5.4.0" multicast-dns "^7.2.5" -"@libp2p/mplex@^9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/mplex/-/mplex-9.0.2.tgz#139dc566dac49bcaf7b0edd8c9cf5d9a2448fc85" - integrity sha512-2vLLlMCDP2TNRD+lJlFQUDp8Q/HzPUB22R8qaJ8jZF+aVac05VAsImsTW2oQ7Oq5zhOXWbGDZyvbk2JBmfsteQ== +"@libp2p/mplex@^9.0.7": + version "9.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/mplex/-/mplex-9.0.7.tgz#c8233d184c5142453776bc59cc66edb3b399050b" + integrity sha512-ycIjBdEPnVSjW3ZuMVuFk7cwJwK6/Hjd1KFCSXTZ9E8M6df+EQg9m8iw5ObMJNQ5+GWIHUu5+Fq1HquZO06Y9g== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" abortable-iterator "^5.0.1" benchmark "^2.1.4" it-batched-bytes "^2.0.2" it-pushable "^3.2.0" it-stream-types "^2.0.1" - rate-limiter-flexible "^2.3.11" + rate-limiter-flexible "^3.0.0" + uint8-varint "^2.0.0" uint8arraylist "^2.4.3" - uint8arrays "^4.0.4" - varint "^6.0.0" + uint8arrays "^4.0.6" -"@libp2p/multistream-select@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@libp2p/multistream-select/-/multistream-select-4.0.1.tgz#5563693362b36e5574e6da123012cafcad4bbfd1" - integrity sha512-0GDpEdV5cdS+3G6WfA+63E9wDIWJqHru5THU8f6+ybJ6wamXLRlUzqCm2giqQXsvMdWDCXocAgzhf5eJjIxRnQ== +"@libp2p/multistream-select@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@libp2p/multistream-select/-/multistream-select-4.0.2.tgz#547ebc682907d1e02f0f3eec311010ebf3b62ec1" + integrity sha512-Ss3kPD+1Z8RFLUT+oN9I2ynEtp/Yj2+rOngU1XjIxustg1nt5lq0kk9hvWJyBexzmuML0xCknNjUXovpRbFPgQ== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" abortable-iterator "^5.0.1" it-first "^3.0.1" it-handshake "^4.1.3" @@ -1642,83 +1627,83 @@ it-reader "^6.0.1" it-stream-types "^2.0.1" uint8arraylist "^2.4.3" - uint8arrays "^4.0.4" + uint8arrays "^4.0.6" -"@libp2p/peer-collections@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/peer-collections/-/peer-collections-4.0.2.tgz#46efc5b3730493c08cc5b837a07f5a3aa3314eeb" - integrity sha512-vk3jra8S9ifRdP4M5GDndwhvVZTdhgt0KAqlU5Vw7PH2Ex8t0OvNXBRy+ZDqGeCkkK+SytYlrRrVSMW2/mR2Cw== +"@libp2p/peer-collections@^4.0.2", "@libp2p/peer-collections@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@libp2p/peer-collections/-/peer-collections-4.0.4.tgz#56163995e6f7b3178e927b92b9c6e894a93e7f12" + integrity sha512-MGuTtt6a2TLUlr4b1dUAOd43SAe/lxLZX3E9iYeRqI9IWzw6cwvvOzGNTYwAlkBpASCmm0aJpGXDA/r6lpIzMQ== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/peer-id" "^3.0.1" + "@libp2p/interface" "^0.1.2" + "@libp2p/peer-id" "^3.0.2" -"@libp2p/peer-id-factory@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/peer-id-factory/-/peer-id-factory-3.0.2.tgz#6f3c374fbe0f86c753d57e262421da7ff610d950" - integrity sha512-M/3rmJeJxO1HtdYBpODisyFL4r6o5KVI13/fPyNr3V0bzVxMGvY7SqZPgyfjOx1ak5fS9NPsTR2D0i7HL0YQRA== +"@libp2p/peer-id-factory@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@libp2p/peer-id-factory/-/peer-id-factory-3.0.4.tgz#8dc6890a99fbd4c6f4a295761cc495e214c81369" + integrity sha512-9xpKb1UdAhKVmPHy/jssOnyJkuyyyIeP5tO3HlaiBQNtDZU66UMQORnEUD6HdYHKfBRInah2JHxTCtm2nUhGcw== dependencies: - "@libp2p/crypto" "^2.0.2" - "@libp2p/interface" "^0.1.1" - "@libp2p/peer-id" "^3.0.1" + "@libp2p/crypto" "^2.0.4" + "@libp2p/interface" "^0.1.2" + "@libp2p/peer-id" "^3.0.2" multiformats "^12.0.1" protons-runtime "^5.0.0" uint8arraylist "^2.4.3" - uint8arrays "^4.0.4" + uint8arrays "^4.0.6" -"@libp2p/peer-id@^3.0.0", "@libp2p/peer-id@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@libp2p/peer-id/-/peer-id-3.0.1.tgz#4f27c04f34cc189f14c82aabc74cbd4a91f8eef2" - integrity sha512-iR4lP9nEnIl1fW7beuB55A262lW78sOdH6r/57XcyMtsE/mCZiRhUVhGfvcM4GgLWm26vyla/UV3FVr7hIpMIQ== +"@libp2p/peer-id@^3.0.0", "@libp2p/peer-id@^3.0.1", "@libp2p/peer-id@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@libp2p/peer-id/-/peer-id-3.0.2.tgz#5ca40a687a513c53744513f0c23a44d291e4399d" + integrity sha512-133qGXu9UBiqsYm7nBDJaAh4eiKe79DPLKF+/aRu0Z7gKcX7I0+LewEky4kBt3olhYQSF1CAnJIzD8Dmsn40Yw== dependencies: - "@libp2p/interface" "^0.1.1" + "@libp2p/interface" "^0.1.2" multiformats "^12.0.1" - uint8arrays "^4.0.4" + uint8arrays "^4.0.6" -"@libp2p/peer-record@^6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/peer-record/-/peer-record-6.0.2.tgz#a047c9319eb9bf6586a30ecc8d55501effb38cfd" - integrity sha512-iOBTmQdryKp8GMwQ2YoHe/u1POuUPvyXq4r1wlqwVsxILgBO+lWlsHuASRhHqESH2x6wOF8mh3k+hHs3WWJcyA== +"@libp2p/peer-record@^6.0.5": + version "6.0.5" + resolved "https://registry.yarnpkg.com/@libp2p/peer-record/-/peer-record-6.0.5.tgz#19e102ecd96b50421ed10e5563e0e5a5d6aeaa7c" + integrity sha512-+nJpi9L6X+cYdu1UWL/W36+3pmL0Ev7/HpX9J/bESsICP8rSN2N1aFlekqJq2v7TW4dJ3VJO7TcMZCcKcLhZCQ== dependencies: - "@libp2p/crypto" "^2.0.2" - "@libp2p/interface" "^0.1.1" - "@libp2p/peer-id" "^3.0.1" - "@libp2p/utils" "^4.0.1" - "@multiformats/multiaddr" "^12.1.3" + "@libp2p/crypto" "^2.0.4" + "@libp2p/interface" "^0.1.2" + "@libp2p/peer-id" "^3.0.2" + "@libp2p/utils" "^4.0.3" + "@multiformats/multiaddr" "^12.1.5" protons-runtime "^5.0.0" - uint8-varint "^1.0.2" + uint8-varint "^2.0.0" uint8arraylist "^2.4.3" - uint8arrays "^4.0.4" + uint8arrays "^4.0.6" -"@libp2p/peer-store@^9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/peer-store/-/peer-store-9.0.2.tgz#230b6451a4c44102f294a027f78396011e6d6144" - integrity sha512-hADoXpCWXgA2kIJXaVO+vpI8erZp0MZQWFYfk+0s96gJMgpwmJZl1tOTXWWvUXgo5M+MlAwRGoxdL1CF2/g9/A== +"@libp2p/peer-store@^9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@libp2p/peer-store/-/peer-store-9.0.5.tgz#1beeda7aac7c186e2663de1f65e0aa1df833595e" + integrity sha512-LUYN2i58F/eVvrFEYCIfArMNZaCGy2J2xSG9kd3/iHZqHAyLkuQHnYfHdoJLSUJFcS2pZsFo+c9atVvlOD7w5A== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" - "@libp2p/peer-collections" "^4.0.2" - "@libp2p/peer-id" "^3.0.1" - "@libp2p/peer-id-factory" "^3.0.2" - "@libp2p/peer-record" "^6.0.2" - "@multiformats/multiaddr" "^12.1.3" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" + "@libp2p/peer-collections" "^4.0.4" + "@libp2p/peer-id" "^3.0.2" + "@libp2p/peer-id-factory" "^3.0.4" + "@libp2p/peer-record" "^6.0.5" + "@multiformats/multiaddr" "^12.1.5" interface-datastore "^8.2.0" it-all "^3.0.2" mortice "^3.0.1" multiformats "^12.0.1" protons-runtime "^5.0.0" uint8arraylist "^2.4.3" - uint8arrays "^4.0.4" + uint8arrays "^4.0.6" -"@libp2p/prometheus-metrics@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/prometheus-metrics/-/prometheus-metrics-2.0.2.tgz#b303ee58e6ff1a45c9a7d53285afc3a1f0dc0fbe" - integrity sha512-jDZxg8338KU9Ptfc26f+dblIqNDMT+Np2Rx0WgMXodbBQeIvprEgIAzX1M0RUzVoxTrPRpSAND960hHjiU8xdQ== +"@libp2p/prometheus-metrics@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/prometheus-metrics/-/prometheus-metrics-2.0.7.tgz#4d93bd3f4bb9221356cc16797d4ad1f2ba5a05b6" + integrity sha512-P2F8xRY3usuw0W39ZMsem9PXQ8UFn3pFbxTEhplN4OCfe9wpfT5UYBK212s8eIKcPhMSvQSx7er41ObqXJeIUg== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" it-foreach "^2.0.3" it-stream-types "^2.0.1" - prom-client "^14.1.0" + prom-client "^14.2.0" "@libp2p/pubsub@^8.0.0": version "8.0.3" @@ -1740,28 +1725,29 @@ uint8arraylist "^2.4.3" uint8arrays "^4.0.4" -"@libp2p/tcp@8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/tcp/-/tcp-8.0.2.tgz#ae656d3dcd8200b4791a0de538090ae316866298" - integrity sha512-bZARZOnX6hRMZPkQ4xMCFnkgNrf24x7d1ifiorivOPPPZ2ulCb73HdnK1PgASHF4T2kJIidtihJD2zIiPOK6vA== +"@libp2p/tcp@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@libp2p/tcp/-/tcp-8.0.8.tgz#e692bbd04f79c37b9a42bc7d51583226c61b1242" + integrity sha512-hIjAKWQOP4MCS2yUhWMdfweFK/ykDiaMZSrgIJJ+YEikxi0HihB5fRtk08oLvOew0B52GsGXQsfQg8I9sOncWg== dependencies: - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" - "@libp2p/utils" "^4.0.1" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" + "@libp2p/utils" "^4.0.3" "@multiformats/mafmt" "^12.1.2" - "@multiformats/multiaddr" "^12.1.3" + "@multiformats/multiaddr" "^12.1.5" "@types/sinon" "^10.0.15" stream-to-it "^0.2.2" -"@libp2p/utils@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@libp2p/utils/-/utils-4.0.1.tgz#0c31544542b74edee0f2fb51a04c322dff4a6ba6" - integrity sha512-Jo6K+st+F2n/IaJ5PQwDE4GHZW0DWdWhC9YdSuK0M/ZrOBqjLaUfayAoXu3ygqY4lqTLmRkm7mlCza6IWMWZAA== +"@libp2p/utils@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@libp2p/utils/-/utils-4.0.3.tgz#e27e46930fd0bf72fc9344127194dbff90c25d45" + integrity sha512-jusH8y4G9YluKRm63EPIiN9fNv0hVtfKY7O0nsLI14o0/W/WJhTsQWm+kPOfvoAgCIqAVrxefBqAmFGiiYPnvg== dependencies: - "@achingbrain/ip-address" "^8.1.0" - "@libp2p/interface" "^0.1.1" - "@libp2p/logger" "^3.0.1" - "@multiformats/multiaddr" "^12.1.3" + "@chainsafe/is-ip" "^2.0.2" + "@libp2p/interface" "^0.1.2" + "@libp2p/logger" "^3.0.2" + "@multiformats/multiaddr" "^12.1.5" + "@multiformats/multiaddr-matcher" "^1.0.1" is-loopback-addr "^2.0.1" it-stream-types "^2.0.1" private-ip "^3.0.0" @@ -1779,6 +1765,15 @@ dependencies: "@multiformats/multiaddr" "^12.0.0" +"@multiformats/multiaddr-matcher@^1.0.0", "@multiformats/multiaddr-matcher@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@multiformats/multiaddr-matcher/-/multiaddr-matcher-1.0.2.tgz#014b8bf34106363b7c2635c01b5627d216fa192f" + integrity sha512-YzviFV31TsDbatWhEmkNnpWC82F/Wfc+alaOBT94Lk6KJeKKfzsaLhYPsjyhElXiUtCKvB3p5e4+WsE5ZYy1kg== + dependencies: + "@chainsafe/is-ip" "^2.0.1" + "@multiformats/multiaddr" "^12.0.0" + multiformats "^12.0.1" + "@multiformats/multiaddr@^12.0.0", "@multiformats/multiaddr@^12.1.3", "@multiformats/multiaddr@^12.1.5": version "12.1.7" resolved "https://registry.yarnpkg.com/@multiformats/multiaddr/-/multiaddr-12.1.7.tgz#eb71733be20dd9f0ac0ff4c3ffe4bae422726beb" @@ -1857,10 +1852,10 @@ resolved "https://registry.yarnpkg.com/@napi-rs/snappy-win32-x64-msvc/-/snappy-win32-x64-msvc-7.2.2.tgz#4f598d3a5d50904d9f72433819f68b21eaec4f7d" integrity sha512-a43cyx1nK0daw6BZxVcvDEXxKMFLSBSDTAhsFD0VqSKcC7MGUBMaqyoWUcMiI7LBSz4bxUmxDWKfCYzpEmeb3w== -"@noble/ciphers@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.1.4.tgz#96327dca147829ed9eee0d96cfdf7c57915765f0" - integrity sha512-d3ZR8vGSpy3v/nllS+bD/OMN5UZqusWiQqkyj7AwzTnhXFH72pF5oB4Ach6DQ50g5kXxC28LdaYBEpsyv9KOUQ== +"@noble/ciphers@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.3.0.tgz#6ba3090afdc7a7051393486f6af210e62e0f04ec" + integrity sha512-ldbrnOjmNRwFdXcTM6uXDcxpMIFrbzAWNnpBPp4oTJTFF0XByGD6vf45WrehZGXRQTRVV+Zm8YP+EgEf+e4cWA== "@noble/curves@1.0.0", "@noble/curves@~1.0.0": version "1.0.0" @@ -1876,11 +1871,6 @@ dependencies: "@noble/hashes" "1.3.1" -"@noble/ed25519@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.6.0.tgz#b55f7c9e532b478bf1d7c4f609e1f3a37850b583" - integrity sha512-UKju89WV37IUALIMfKhKW3psO8AqmrE/GvH6QbPKjzolQ98zM7WmGUeY+xdIgSf5tqPFf75ZCYMgym6E9Jsw3Q== - "@noble/hashes@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" @@ -1911,11 +1901,6 @@ resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== -"@noble/secp256k1@^1.5.4": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.0.tgz#602afbbfcfb7e169210469b697365ef740d7e930" - integrity sha512-DWSsg8zMHOYMYBqIQi96BQuthZrp98LCeMNcUOaffCIVYQ5yxDbNikLF+H7jEnmNNmXbtVic46iCuVWzar+MgA== - "@node-rs/crc32-android-arm-eabi@1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@node-rs/crc32-android-arm-eabi/-/crc32-android-arm-eabi-1.6.0.tgz#860faa69635a50efdc0ecf5d4e338d2c610419b7" @@ -3028,11 +3013,16 @@ dependencies: "@types/node" "*" -"@types/retry@*", "@types/retry@0.12.1": +"@types/retry@*": version "0.12.1" resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz" integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== +"@types/retry@0.12.2": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a" + integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow== + "@types/secp256k1@^4.0.1": version "4.0.2" resolved "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz" @@ -4400,13 +4390,6 @@ byline@^5.0.0: resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" integrity sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q== -byte-access@^1.0.0, byte-access@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/byte-access/-/byte-access-1.0.1.tgz#84badd99be3671c03f0dd6a039a9c963983724af" - integrity sha512-GKYa+lvxnzhgHWj9X+LCsQ4s2/C5uvib573eAOiQKywXMkzFFErY2+yQdzmdE5iWVpmqecsRx3bOtOY4/1eINw== - dependencies: - uint8arraylist "^2.0.0" - byte-size@8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae" @@ -5495,6 +5478,11 @@ define-properties@^1.2.0: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delay@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-6.0.0.tgz#43749aefdf6cabd9e17b0d00bd3904525137e607" + integrity sha512-2NJozoOHQ4NuZuVIr5CWd0iiLVIRSDepakaovIN+9eIDHEhdCAEvSy2cuf1DCrPPQLvHmbqTHODlhHg8UCy4zw== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -8094,6 +8082,11 @@ is-negative-zero@^2.0.1, is-negative-zero@^2.0.2: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-network-error@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-network-error/-/is-network-error-1.0.0.tgz#757d7af42263f18f616626e63af12abb19002bbc" + integrity sha512-P3fxi10Aji2FZmHTrMPSNFbNC6nnp4U5juPAIjXPHkUNubi4+qK7vvdsaNpAUwXslhYm9oyjEYTxs1xd/+Ph0w== + is-number-object@^1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" @@ -8645,11 +8638,6 @@ js-yaml@4.1.0, js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsbn@1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz" - integrity sha1-sBMHyym2GKHtJux56RH4A8TaAEA= - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" @@ -9047,29 +9035,30 @@ libnpmpublish@7.3.0: sigstore "^1.4.0" ssri "^10.0.1" -libp2p@0.46.3: - version "0.46.3" - resolved "https://registry.yarnpkg.com/libp2p/-/libp2p-0.46.3.tgz#32de7b8106795ded5c1deaf11ca1dca774166f57" - integrity sha512-fnw2ub5HSSACa0Op/8XtCiLothB8NecYfq8vEnL+eZiLkdDmg4abUBps3cINxSw4YD7H7ljA8rofPKUo/EKYQA== +libp2p@0.46.12: + version "0.46.12" + resolved "https://registry.yarnpkg.com/libp2p/-/libp2p-0.46.12.tgz#de913134c7f5d98e59bfe0356b0067e881985a76" + integrity sha512-LPEfSVW/tsFNaUplNo/QqDsg9C7wed+lBGPUUhUsRcnPnKQTqZnKBpA9pSv2+A0ST9B++uiyCOk+JK7nIlpjeA== dependencies: "@achingbrain/nat-port-mapper" "^1.0.9" - "@libp2p/crypto" "^2.0.2" - "@libp2p/interface" "^0.1.1" - "@libp2p/interface-internal" "^0.1.2" - "@libp2p/keychain" "^3.0.2" - "@libp2p/logger" "^3.0.1" - "@libp2p/multistream-select" "^4.0.1" - "@libp2p/peer-collections" "^4.0.2" - "@libp2p/peer-id" "^3.0.1" - "@libp2p/peer-id-factory" "^3.0.2" - "@libp2p/peer-record" "^6.0.2" - "@libp2p/peer-store" "^9.0.2" - "@libp2p/utils" "^4.0.1" + "@libp2p/crypto" "^2.0.4" + "@libp2p/interface" "^0.1.2" + "@libp2p/interface-internal" "^0.1.5" + "@libp2p/keychain" "^3.0.4" + "@libp2p/logger" "^3.0.2" + "@libp2p/multistream-select" "^4.0.2" + "@libp2p/peer-collections" "^4.0.4" + "@libp2p/peer-id" "^3.0.2" + "@libp2p/peer-id-factory" "^3.0.4" + "@libp2p/peer-record" "^6.0.5" + "@libp2p/peer-store" "^9.0.5" + "@libp2p/utils" "^4.0.3" "@multiformats/mafmt" "^12.1.2" - "@multiformats/multiaddr" "^12.1.3" - abortable-iterator "^5.0.1" + "@multiformats/multiaddr" "^12.1.5" + "@multiformats/multiaddr-matcher" "^1.0.0" any-signal "^4.1.1" datastore-core "^9.0.1" + delay "^6.0.0" interface-datastore "^8.2.0" it-all "^3.0.2" it-drain "^3.0.2" @@ -9088,12 +9077,12 @@ libp2p@0.46.3: multiformats "^12.0.1" p-defer "^4.0.0" p-queue "^7.3.4" - p-retry "^5.0.0" + p-retry "^6.0.0" private-ip "^3.0.0" protons-runtime "^5.0.0" - rate-limiter-flexible "^2.3.11" + rate-limiter-flexible "^3.0.0" uint8arraylist "^2.4.3" - uint8arrays "^4.0.4" + uint8arrays "^4.0.6" wherearewe "^2.0.1" xsalsa20 "^1.1.0" @@ -9306,14 +9295,6 @@ long@^5.0.0: resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== -longbits@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/longbits/-/longbits-1.1.0.tgz#d6a7b2411dead1cf4b79ee4586816e65c7356ab9" - integrity sha512-22U2exkkYy7sr7nuQJYx2NEZ2kEMsC69+BxM5h8auLvkVIJa+LwAB5mFIExnuW2dFuYXFOWsFMKXjaWiq/htYQ== - dependencies: - byte-access "^1.0.1" - uint8arraylist "^2.0.0" - loupe@^2.3.1: version "2.3.4" resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" @@ -10789,12 +10770,13 @@ p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== -p-retry@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-5.1.1.tgz#1950b9be441474a67f852811c1d4ec955885d2c8" - integrity sha512-i69WkEU5ZAL8mrmdmVviWwU+DN+IUF8f4sSJThoJ3z5A7Nn5iuO5ROX3Boye0u+uYQLOSfgFl7SuFZCjlAVbQA== +p-retry@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-6.1.0.tgz#ea5c188f9f818a5bfa89a27bdf043c74fa9be472" + integrity sha512-fJLEQ2KqYBJRuaA/8cKMnqhulqNM+bpcjYtXNex2t3mOXKRYPitAJt9NacSf8XAFzcYahSAbKpobiWDSqHSh2g== dependencies: - "@types/retry" "0.12.1" + "@types/retry" "0.12.2" + is-network-error "^1.0.0" retry "^0.13.1" p-timeout@^3.2.0: @@ -11183,7 +11165,7 @@ progress@^2.0.3: resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prom-client@^14.1.0, prom-client@^14.2.0: +prom-client@^14.2.0: version "14.2.0" resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-14.2.0.tgz#ca94504e64156f6506574c25fb1c34df7812cf11" integrity sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA== @@ -11413,10 +11395,10 @@ range-parser@^1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -rate-limiter-flexible@^2.3.11: - version "2.4.1" - resolved "https://registry.yarnpkg.com/rate-limiter-flexible/-/rate-limiter-flexible-2.4.1.tgz#c74cfe36ac2cbfe56f68ded9a3b4b2fde1963c41" - integrity sha512-dgH4T44TzKVO9CLArNto62hJOwlWJMLUjVVr/ii0uUzZXEXthDNr7/yefW5z/1vvHAfycc1tnuiYyNJ8CTRB3g== +rate-limiter-flexible@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rate-limiter-flexible/-/rate-limiter-flexible-3.0.0.tgz#1dba6de44d4d5a5e6494774c2ff7657e82856673" + integrity sha512-janAJkWxWxmLka0hV+XvCTo0M8keeSeOuz8ZL33cTXrkS4ek9mQ2VJm9ri7fm03oTVth19Sfqb1ijCmo7K/vAg== raw-body@2.5.1: version "2.5.1" @@ -12312,7 +12294,7 @@ split@^1.0.1: dependencies: through "2" -sprintf-js@1.1.2, sprintf-js@^1.1.2: +sprintf-js@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== @@ -13259,17 +13241,7 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.2.tgz#f55f668b9a64b213977ae688703b6bbb7ca861c6" integrity sha512-bbxglRjsGQMchfvXZNusUcYgiB9Hx2K4AHYXQy2DITZ9Rd+JzhX7+hoocE5Winr7z2oHvPsekkBwXtigvxevXg== -uint8-varint@^1.0.2: - version "1.0.8" - resolved "https://registry.yarnpkg.com/uint8-varint/-/uint8-varint-1.0.8.tgz#3f6c268e4c1a1ece232f660ec37729faca7cc7d0" - integrity sha512-QS03THS87Wlc0fBCC3xP5sqScDwfvVZLUrTCeMAQbQxQUWJosPC7C8uTNhpVUEgpTbV1Ut2Fer9Se3kI1KbnlQ== - dependencies: - byte-access "^1.0.0" - longbits "^1.1.0" - uint8arraylist "^2.0.0" - uint8arrays "^4.0.2" - -uint8-varint@^2.0.1: +uint8-varint@^2.0.0, uint8-varint@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/uint8-varint/-/uint8-varint-2.0.1.tgz#e8f73c24974b384f6f0e1cd73c884c5a19e32f53" integrity sha512-euvmpuulJstK5+xNuI4S1KfnxJnbI5QP52RXIR3GZ3/ZMkOsEK2AgCtFpNvEQLXMxMx2o0qcyevK1fJwOZJagQ== @@ -13298,7 +13270,7 @@ uint8arrays@^4.0.3: dependencies: multiformats "^11.0.0" -uint8arrays@^4.0.4: +uint8arrays@^4.0.4, uint8arrays@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-4.0.6.tgz#bae68b536c2e87147045b95d73d29e503e45ecab" integrity sha512-4ZesjQhqOU2Ip6GPReIwN60wRxIupavL8T0Iy36BBHr2qyMrNxsPJvr7vpS4eFt8F8kSguWUPad6ZM9izs/vyw== @@ -13539,11 +13511,6 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -varint@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz" - integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== - vary@^1: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" From db5928bbb87b618a0d24e1a71de9f3edaed6c9a5 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 12:43:44 +0200 Subject: [PATCH 02/36] Add resource leak detection in mocha for e2e --- packages/beacon-node/package.json | 6 ++-- packages/beacon-node/test/e2e/hooks.ts | 40 ++++++++++++++++++++++++++ yarn.lock | 10 +++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 packages/beacon-node/test/e2e/hooks.ts diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index a80027ad45ec..076a4d8dc5bb 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -80,7 +80,7 @@ "test:unit:minimal": "nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit/**/*.test.ts'", "test:unit:mainnet": "LODESTAR_PRESET=mainnet nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit-mainnet/**/*.test.ts'", "test:unit": "yarn test:unit:minimal && yarn test:unit:mainnet", - "test:e2e": "LODESTAR_PRESET=minimal mocha 'test/e2e/**/*.test.ts'", + "test:e2e": "LODESTAR_PRESET=minimal mocha --require test/e2e/hooks.ts 'test/e2e/**/*.test.ts'", "test:sim": "mocha 'test/sim/**/*.test.ts'", "test:sim:merge-interop": "mocha 'test/sim/merge-interop.test.ts'", "test:sim:mergemock": "mocha 'test/sim/mergemock.test.ts'", @@ -161,13 +161,15 @@ "@types/qs": "^6.9.7", "@types/supertest": "^2.0.12", "@types/tmp": "^0.2.3", + "@types/wtfnode": "^0.7.1", "eventsource": "^2.0.2", "it-pair": "^2.0.6", "it-drain": "^3.0.3", "leveldown": "^6.1.1", "rewiremock": "^3.14.5", "rimraf": "^4.4.1", - "tmp": "^0.2.1" + "tmp": "^0.2.1", + "wtfnode": "^0.9.1" }, "keywords": [ "ethereum", diff --git a/packages/beacon-node/test/e2e/hooks.ts b/packages/beacon-node/test/e2e/hooks.ts new file mode 100644 index 000000000000..7ef19aac1be3 --- /dev/null +++ b/packages/beacon-node/test/e2e/hooks.ts @@ -0,0 +1,40 @@ +import {dump} from "wtfnode"; + +// Consider it a leak if process does not exit within this time +const LEAK_TIMEOUT_MS = 10_000; + +function registerLeakDetection(): void { + console.info("Registering leak detection hooks"); + + const timeout = Date.now() + LEAK_TIMEOUT_MS; + const timer: NodeJS.Timeout = setInterval(detectLeak, 100); + + function detectLeak(): void { + if (Date.now() > timeout) { + clearInterval(timer); + + console.error("Process did not terminate, dumping remaining handles and exiting"); + dump(); + + process.removeAllListeners("exit"); + process.exit(-1); + } else { + // eslint-disable-next-line @typescript-eslint/naming-convention + const activeHandles = (process as NodeJS.Process & {_getActiveHandles: () => {fd: number}[]}) + ._getActiveHandles() + .filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles + + // Allow this timer to be running + if (activeHandles.length <= 1) { + console.info("Seems no leak found. Clearing leak detection hooks."); + clearInterval(timer); + } + } + } +} + +export const mochaHooks = { + async afterAll() { + registerLeakDetection(); + }, +}; diff --git a/yarn.lock b/yarn.lock index 9f5d14a38e8f..532aa4467865 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3158,6 +3158,11 @@ dependencies: "@types/node" "*" +"@types/wtfnode@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@types/wtfnode/-/wtfnode-0.7.1.tgz#b570b1fd3faeb35a477111feef376b2acbf12639" + integrity sha512-0uo9YyPSCbYsHNfoQrEhpLbT/PuGBzaJhItss2Eb2uH+/XEsBabupPVAARmAdEY73wKIQFOZ2L2z9TZ2HbKOxQ== + "@types/yargs-parser@*": version "20.2.0" resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz" @@ -14069,6 +14074,11 @@ ws@~8.2.3: resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== +wtfnode@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/wtfnode/-/wtfnode-0.9.1.tgz#c385679d2df6fb4d64d734eeeaab767fcee3e0d3" + integrity sha512-Ip6C2KeQPl/F3aP1EfOnPoQk14Udd9lffpoqWDNH3Xt78svxPbv53ngtmtfI0q2Te3oTq79XKTnRNXVIn/GsPA== + xml2js@0.4.19: version "0.4.19" resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz" From 36bee0822be37ad57261bef4687b2cfddb3f3ef8 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 14:09:48 +0200 Subject: [PATCH 03/36] Remove all retries from network tests --- packages/beacon-node/test/e2e/hooks.ts | 1 + .../beacon-node/test/e2e/network/gossipsub.test.ts | 11 +++++------ packages/beacon-node/test/e2e/network/mdns.test.ts | 1 - packages/beacon-node/test/e2e/network/network.test.ts | 1 - packages/beacon-node/test/e2e/network/reqresp.test.ts | 1 - 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/beacon-node/test/e2e/hooks.ts b/packages/beacon-node/test/e2e/hooks.ts index 7ef19aac1be3..d19c8d2ccec0 100644 --- a/packages/beacon-node/test/e2e/hooks.ts +++ b/packages/beacon-node/test/e2e/hooks.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import {dump} from "wtfnode"; // Consider it a leak if process does not exit within this time diff --git a/packages/beacon-node/test/e2e/network/gossipsub.test.ts b/packages/beacon-node/test/e2e/network/gossipsub.test.ts index eed9f68cd4ce..c3f3fac7cae4 100644 --- a/packages/beacon-node/test/e2e/network/gossipsub.test.ts +++ b/packages/beacon-node/test/e2e/network/gossipsub.test.ts @@ -7,9 +7,9 @@ import {Network} from "../../../src/network/index.js"; import {GossipType, GossipHandlers, GossipHandlerParamGeneric} from "../../../src/network/gossip/index.js"; import {connect, onPeerConnect, getNetworkForTest} from "../../utils/network.js"; -describe("gossipsub / main thread", function () { - runTests.bind(this)({useWorker: false}); -}); +// describe("gossipsub / main thread", function () { +// runTests.bind(this)({useWorker: false}); +// }); describe("gossipsub / worker", function () { runTests.bind(this)({useWorker: true}); @@ -19,7 +19,6 @@ describe("gossipsub / worker", function () { function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { if (this.timeout() < 20 * 1000) this.timeout(150 * 1000); - this.retries(2); // This test fail sometimes, with a 5% rate. const afterEachCallbacks: (() => Promise | void)[] = []; afterEach(async () => { @@ -41,11 +40,11 @@ function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function mockModules(gossipHandlersPartial?: Partial) { - const [netA, closeA] = await getNetworkForTest("A", config, {opts: {useWorker}, gossipHandlersPartial}); + const [netA] = await getNetworkForTest("A", config, {opts: {useWorker}, gossipHandlersPartial}); const [netB, closeB] = await getNetworkForTest("B", config, {opts: {useWorker}, gossipHandlersPartial}); afterEachCallbacks.push(async () => { - await closeA(); + // await closeA(); await closeB(); }); diff --git a/packages/beacon-node/test/e2e/network/mdns.test.ts b/packages/beacon-node/test/e2e/network/mdns.test.ts index a18e939cfda5..7903b5ad3c45 100644 --- a/packages/beacon-node/test/e2e/network/mdns.test.ts +++ b/packages/beacon-node/test/e2e/network/mdns.test.ts @@ -28,7 +28,6 @@ const mu = "/ip4/127.0.0.1/tcp/0"; // eslint-disable-next-line mocha/no-skipped-tests describe.skip("mdns", function () { this.timeout(50000); - this.retries(2); // This test fail sometimes, with a 5% rate. const afterEachCallbacks: (() => Promise | void)[] = []; afterEach(async () => { diff --git a/packages/beacon-node/test/e2e/network/network.test.ts b/packages/beacon-node/test/e2e/network/network.test.ts index 7610bedca162..9080ae7e5374 100644 --- a/packages/beacon-node/test/e2e/network/network.test.ts +++ b/packages/beacon-node/test/e2e/network/network.test.ts @@ -21,7 +21,6 @@ describe("network / worker", function () { function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { this.timeout(50000); - this.retries(2); // This test fail sometimes, with a 5% rate. const afterEachCallbacks: (() => Promise | void)[] = []; afterEach(async () => { diff --git a/packages/beacon-node/test/e2e/network/reqresp.test.ts b/packages/beacon-node/test/e2e/network/reqresp.test.ts index 1a334350a08a..0df24a0a569d 100644 --- a/packages/beacon-node/test/e2e/network/reqresp.test.ts +++ b/packages/beacon-node/test/e2e/network/reqresp.test.ts @@ -29,7 +29,6 @@ describe("network / reqresp / worker", function () { function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { if (this.timeout() < 60_000) this.timeout(60_000); - this.retries(2); // This test fail sometimes, with a 5% rate. // Schedule ALTAIR_FORK_EPOCH to trigger registering lightclient ReqResp protocols immediately const config = createChainForkConfig({ From ce0b8f1a3401de2a722d6541ab66aba047e8f55b Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 14:12:21 +0200 Subject: [PATCH 04/36] Remove the timeout from workflow actions --- .github/workflows/test.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2598f3f3947e..d3355d36fb86 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -217,11 +217,7 @@ jobs: run: scripts/run_e2e_env.sh start - name: E2E tests - # E2E tests are sometimes stalling until timeout is reached but we know that - # after 15 minutes those should have passed already if there are no failed test cases. - # In this case, just set the job status to passed as there was likely no actual issue. - # See https://github.com/ChainSafe/lodestar/issues/5913 - run: timeout 15m yarn test:e2e || { test $? -eq 124 || exit 1; } + run: yarn test:e2e env: GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL!=0 && secrets.GOERLI_RPC_URL || env.GOERLI_RPC_DEFAULT_URL }} From 2550eb7a3e76f07b06c9a91d23a5d7f272eab815 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 14:13:29 +0200 Subject: [PATCH 05/36] Uncomment a test --- packages/beacon-node/test/e2e/network/gossipsub.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/beacon-node/test/e2e/network/gossipsub.test.ts b/packages/beacon-node/test/e2e/network/gossipsub.test.ts index c3f3fac7cae4..92e9271fdeea 100644 --- a/packages/beacon-node/test/e2e/network/gossipsub.test.ts +++ b/packages/beacon-node/test/e2e/network/gossipsub.test.ts @@ -7,9 +7,9 @@ import {Network} from "../../../src/network/index.js"; import {GossipType, GossipHandlers, GossipHandlerParamGeneric} from "../../../src/network/gossip/index.js"; import {connect, onPeerConnect, getNetworkForTest} from "../../utils/network.js"; -// describe("gossipsub / main thread", function () { -// runTests.bind(this)({useWorker: false}); -// }); +describe("gossipsub / main thread", function () { + runTests.bind(this)({useWorker: false}); +}); describe("gossipsub / worker", function () { runTests.bind(this)({useWorker: true}); From 1df7905023012560256c828efb58204eac826de4 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 14:51:26 +0200 Subject: [PATCH 06/36] Update hooks to show time in the log --- packages/beacon-node/test/e2e/hooks.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/beacon-node/test/e2e/hooks.ts b/packages/beacon-node/test/e2e/hooks.ts index d19c8d2ccec0..a4ce84a7941e 100644 --- a/packages/beacon-node/test/e2e/hooks.ts +++ b/packages/beacon-node/test/e2e/hooks.ts @@ -5,13 +5,20 @@ import {dump} from "wtfnode"; const LEAK_TIMEOUT_MS = 10_000; function registerLeakDetection(): void { - console.info("Registering leak detection hooks"); - - const timeout = Date.now() + LEAK_TIMEOUT_MS; + const now = Date.now(); + const timeout = now + LEAK_TIMEOUT_MS; + console.info(`Registering leak detection hooks. now='${new Date(now).toLocaleString()}'`); const timer: NodeJS.Timeout = setInterval(detectLeak, 100); function detectLeak(): void { - if (Date.now() > timeout) { + const now = Date.now(); + console.info( + `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( + timeout + ).toLocaleString()}'` + ); + + if (now > timeout) { clearInterval(timer); console.error("Process did not terminate, dumping remaining handles and exiting"); @@ -25,6 +32,8 @@ function registerLeakDetection(): void { ._getActiveHandles() .filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles + console.info("Active handles:", activeHandles.length); + // Allow this timer to be running if (activeHandles.length <= 1) { console.info("Seems no leak found. Clearing leak detection hooks."); From b52e7e03ce22f0a582e42ab626ec1ed3a70af403 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 16:55:59 +0200 Subject: [PATCH 07/36] Add a custom mocha wrapper to detected leaked resources --- packages/beacon-node/test/e2e/hooks.ts | 50 ------------------ scripts/mocha/mocha_failover.mjs | 52 ++++++++++++++++++ scripts/mocha/mocha_failover_cli.mjs | 41 +++++++++++++++ scripts/mocha/mocha_run.mjs | 73 ++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 50 deletions(-) delete mode 100644 packages/beacon-node/test/e2e/hooks.ts create mode 100755 scripts/mocha/mocha_failover.mjs create mode 100755 scripts/mocha/mocha_failover_cli.mjs create mode 100644 scripts/mocha/mocha_run.mjs diff --git a/packages/beacon-node/test/e2e/hooks.ts b/packages/beacon-node/test/e2e/hooks.ts deleted file mode 100644 index a4ce84a7941e..000000000000 --- a/packages/beacon-node/test/e2e/hooks.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* eslint-disable no-console */ -import {dump} from "wtfnode"; - -// Consider it a leak if process does not exit within this time -const LEAK_TIMEOUT_MS = 10_000; - -function registerLeakDetection(): void { - const now = Date.now(); - const timeout = now + LEAK_TIMEOUT_MS; - console.info(`Registering leak detection hooks. now='${new Date(now).toLocaleString()}'`); - const timer: NodeJS.Timeout = setInterval(detectLeak, 100); - - function detectLeak(): void { - const now = Date.now(); - console.info( - `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( - timeout - ).toLocaleString()}'` - ); - - if (now > timeout) { - clearInterval(timer); - - console.error("Process did not terminate, dumping remaining handles and exiting"); - dump(); - - process.removeAllListeners("exit"); - process.exit(-1); - } else { - // eslint-disable-next-line @typescript-eslint/naming-convention - const activeHandles = (process as NodeJS.Process & {_getActiveHandles: () => {fd: number}[]}) - ._getActiveHandles() - .filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles - - console.info("Active handles:", activeHandles.length); - - // Allow this timer to be running - if (activeHandles.length <= 1) { - console.info("Seems no leak found. Clearing leak detection hooks."); - clearInterval(timer); - } - } - } -} - -export const mochaHooks = { - async afterAll() { - registerLeakDetection(); - }, -}; diff --git a/scripts/mocha/mocha_failover.mjs b/scripts/mocha/mocha_failover.mjs new file mode 100755 index 000000000000..b46120ad3e45 --- /dev/null +++ b/scripts/mocha/mocha_failover.mjs @@ -0,0 +1,52 @@ +#!/usr/bin/env node +/* eslint-disable import/no-extraneous-dependencies */ + +import {spawn} from "node:child_process"; +import os from "node:os"; +import url from "node:url"; +import path from "node:path"; +import {loadOptions} from "mocha/lib/cli/cli.js"; +import unparse from "yargs-unparser"; + +const dirName = url.fileURLToPath(new URL(".", import.meta.url)); +const mochaPath = path.join(dirName, "mocha_failover_cli.mjs"); + +process.stdout.write("====================================================\n"); +process.stdout.write("%%%%%%% ITS NOT MOCHA BINARY - ITS A WRAPPER %%%%%%%\n"); +process.stdout.write("====================================================\n"); + +const argv = process.argv.slice(2); +const mochaArgs = loadOptions(argv); + +const nodeArgv = mochaArgs["node-option"] && mochaArgs["node-option"].map((v) => "--" + v); + +delete mochaArgs["node-option"]; + +const args = [].concat(nodeArgv, mochaPath, unparse(mochaArgs)); + +const proc = spawn(process.execPath, args, { + stdio: "inherit", +}); + +proc.on("exit", (code, signal) => { + process.on("exit", () => { + if (signal) { + process.kill(process.pid, signal); + } else { + process.exit(code); + } + }); +}); + +// terminate children. +process.on("SIGINT", () => { + proc.kill("SIGINT"); + if (!args.parallel || args.jobs < 2) { + // win32 does not support SIGTERM, so use next best thing. + if (os.platform() === "win32") { + proc.kill("SIGKILL"); + } else { + proc.kill("SIGTERM"); + } + } +}); diff --git a/scripts/mocha/mocha_failover_cli.mjs b/scripts/mocha/mocha_failover_cli.mjs new file mode 100755 index 000000000000..e72a994a18f5 --- /dev/null +++ b/scripts/mocha/mocha_failover_cli.mjs @@ -0,0 +1,41 @@ +#!/usr/bin/env node +/* eslint-disable import/no-extraneous-dependencies */ +import {loadOptions} from "mocha/lib/cli/cli.js"; +import yargs from "yargs/yargs"; +import mochaPackage from "mocha/package.json" assert {type: "json"}; +import runCommand from "./mocha_run.mjs"; + +const argv = process.argv.slice(2); +const args = loadOptions(argv); + +const yargsOptions = { + "combine-arrays": true, + "short-option-groups": false, + "dot-notation": false, + "strip-aliased": true, +}; + +yargs() + .scriptName("mocha") + .command(runCommand) + .updateStrings({ + "Positionals:": "Positional Arguments", + "Options:": "Other Options", + "Commands:": "Commands", + }) + .fail((msg, err, yargs) => { + yargs.showHelp(); + process.exitCode = 1; + }) + .help("help", "Show usage information & exit") + .alias("help", "h") + .version("version", "Show version number & exit", mochaPackage.version) + .alias("version", "V") + .wrap(process.stdout.columns ? Math.min(process.stdout.columns, 80) : 80) + .parserConfiguration(yargsOptions) + .config(args) + .parse(args._) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs new file mode 100644 index 000000000000..84381c186a94 --- /dev/null +++ b/scripts/mocha/mocha_run.mjs @@ -0,0 +1,73 @@ +/* eslint-disable no-console */ +/* eslint-disable import/no-extraneous-dependencies */ +import Mocha from "mocha"; +import runCommand from "mocha/lib/cli/run.js"; +import collectFiles from "mocha/lib/cli/collect-files.js"; +import {dump} from "wtfnode"; + +// Consider it a leak if process does not exit within this time +const LEAK_TIMEOUT_MS = 10_000; + +// Code is typically the number of failures +async function exitScenarioHandler(code) { + const now = Date.now(); + const timeout = now + LEAK_TIMEOUT_MS; + console.info(`Leak detection after mocha finishes. code=${code} now='${new Date(now).toLocaleString()}'`); + const timer = setInterval(detectLeak, 100); + + function detectLeak() { + const now = Date.now(); + console.info( + `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( + timeout + ).toLocaleString()}'` + ); + + if (now > timeout) { + clearInterval(timer); + + console.error("Process did not terminate, dumping remaining handles and exiting"); + dump(); + + process.removeAllListeners("exit"); + process.exit(-1); + } else { + const activeHandles = process._getActiveHandles().filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles + + console.info("Active handles:", activeHandles.length); + + // Allow this timer to be running + if (activeHandles.length <= 1) { + console.info("Seems no leak found. Clearing leak detection hooks."); + clearInterval(timer); + } + } + } +} + +async function wrappedRunHandler(argv) { + const mocha = new Mocha(argv); + + const {extension = [], ignore = [], file = [], recursive = false, sort = false, spec = []} = argv; + + const fileCollectParams = { + ignore, + extension, + file, + recursive, + sort, + spec, + }; + + const files = collectFiles(fileCollectParams); + console.info("single run with %d file(s)", files.length); + mocha.files = files; + + await mocha.loadFilesAsync(); + mocha.run(exitScenarioHandler); +} + +export default { + ...runCommand, + handler: wrappedRunHandler, +}; From 5c5d51eebad1309443aa98b67aae572f0b3bfd62 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 16:57:23 +0200 Subject: [PATCH 08/36] Use mocha wrapper for beacon-node e2e tests --- packages/beacon-node/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 076a4d8dc5bb..1c7419d47516 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -80,7 +80,7 @@ "test:unit:minimal": "nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit/**/*.test.ts'", "test:unit:mainnet": "LODESTAR_PRESET=mainnet nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit-mainnet/**/*.test.ts'", "test:unit": "yarn test:unit:minimal && yarn test:unit:mainnet", - "test:e2e": "LODESTAR_PRESET=minimal mocha --require test/e2e/hooks.ts 'test/e2e/**/*.test.ts'", + "test:e2e": "LODESTAR_PRESET=minimal ../../scripts/mocha/mocha_failover.mjs 'test/e2e/**/*.test.ts'", "test:sim": "mocha 'test/sim/**/*.test.ts'", "test:sim:merge-interop": "mocha 'test/sim/merge-interop.test.ts'", "test:sim:mergemock": "mocha 'test/sim/mergemock.test.ts'", From a495e37ecb9b392e91cf608784a56dd420512702 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 17:18:36 +0200 Subject: [PATCH 09/36] Add multiple exit to mocha run --- scripts/mocha/mocha_run.mjs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs index 84381c186a94..38c2974b4c04 100644 --- a/scripts/mocha/mocha_run.mjs +++ b/scripts/mocha/mocha_run.mjs @@ -5,6 +5,8 @@ import runCommand from "mocha/lib/cli/run.js"; import collectFiles from "mocha/lib/cli/collect-files.js"; import {dump} from "wtfnode"; +const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + // Consider it a leak if process does not exit within this time const LEAK_TIMEOUT_MS = 10_000; @@ -13,9 +15,9 @@ async function exitScenarioHandler(code) { const now = Date.now(); const timeout = now + LEAK_TIMEOUT_MS; console.info(`Leak detection after mocha finishes. code=${code} now='${new Date(now).toLocaleString()}'`); - const timer = setInterval(detectLeak, 100); + const timer = setInterval(detectLeak, 1000); - function detectLeak() { + async function detectLeak() { const now = Date.now(); console.info( `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( @@ -30,7 +32,17 @@ async function exitScenarioHandler(code) { dump(); process.removeAllListeners("exit"); - process.exit(-1); + + // Process does not seems to exit with one `process.exit(-1)`, so we try a few times + for (let i = 0; i < 5; i++) { + process.exit(-1); + await sleep(100); + } + + // If process still does not exit, we try to kill with signals + for (const signal of ["SIGINT", "SIGTERM", "SIGQUIT"]) { + process.kill(signal); + } } else { const activeHandles = process._getActiveHandles().filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles From d7b654b219f9816180a837cedc6341bf7d1c0df6 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 17:38:16 +0200 Subject: [PATCH 10/36] Add mocha exit with failure count --- scripts/mocha/mocha_run.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs index 38c2974b4c04..abb4b1700c61 100644 --- a/scripts/mocha/mocha_run.mjs +++ b/scripts/mocha/mocha_run.mjs @@ -35,7 +35,8 @@ async function exitScenarioHandler(code) { // Process does not seems to exit with one `process.exit(-1)`, so we try a few times for (let i = 0; i < 5; i++) { - process.exit(-1); + // If there are some failures in the test, we exit with -1 + process.exit(code > 0 ? -1 : 0); await sleep(100); } From a784688fdc0682ab5ec051906c452de891c21d31 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 21:33:52 +0200 Subject: [PATCH 11/36] Update the process exit strategy --- scripts/mocha/mocha_run.mjs | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs index abb4b1700c61..3fcc73654976 100644 --- a/scripts/mocha/mocha_run.mjs +++ b/scripts/mocha/mocha_run.mjs @@ -11,19 +11,14 @@ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const LEAK_TIMEOUT_MS = 10_000; // Code is typically the number of failures -async function exitScenarioHandler(code) { +async function exitScenarioHandler(failCount) { const now = Date.now(); const timeout = now + LEAK_TIMEOUT_MS; - console.info(`Leak detection after mocha finishes. code=${code} now='${new Date(now).toLocaleString()}'`); + console.info(`Leak detection after mocha finishes. failures=${failCount} now='${new Date(now).toLocaleString()}'`); const timer = setInterval(detectLeak, 1000); async function detectLeak() { const now = Date.now(); - console.info( - `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( - timeout - ).toLocaleString()}'` - ); if (now > timeout) { clearInterval(timer); @@ -33,25 +28,23 @@ async function exitScenarioHandler(code) { process.removeAllListeners("exit"); - // Process does not seems to exit with one `process.exit(-1)`, so we try a few times - for (let i = 0; i < 5; i++) { - // If there are some failures in the test, we exit with -1 - process.exit(code > 0 ? -1 : 0); - await sleep(100); - } + process.exit(failCount > 0 ? 1 : 0); // If process still does not exit, we try to kill with signals - for (const signal of ["SIGINT", "SIGTERM", "SIGQUIT"]) { + for (const signal of ["SIGTERM", "SIGQUIT", "SIGKILL"]) { process.kill(signal); } } else { const activeHandles = process._getActiveHandles().filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles - - console.info("Active handles:", activeHandles.length); + console.info( + `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( + timeout + ).toLocaleString()}' activeHandlers: ${activeHandles.length}` + ); // Allow this timer to be running if (activeHandles.length <= 1) { - console.info("Seems no leak found. Clearing leak detection hooks."); + console.info("Seems there is no leak. Clearing leak detection hooks."); clearInterval(timer); } } From af4c6030d87b6fe049381ae402022061f354e7bd Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 22:00:26 +0200 Subject: [PATCH 12/36] Exit the process with signal --- scripts/mocha/mocha_run.mjs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs index 3fcc73654976..c994f5c58eac 100644 --- a/scripts/mocha/mocha_run.mjs +++ b/scripts/mocha/mocha_run.mjs @@ -28,11 +28,14 @@ async function exitScenarioHandler(failCount) { process.removeAllListeners("exit"); - process.exit(failCount > 0 ? 1 : 0); - - // If process still does not exit, we try to kill with signals - for (const signal of ["SIGTERM", "SIGQUIT", "SIGKILL"]) { - process.kill(signal); + if (failCount > 0) { + process.exit(0); + } else { + // Observed that process.exit(1) is not exiting the process + // If process still does not exit, we try to kill with signals + for (const signal of ["SIGTERM", "SIGQUIT", "SIGKILL"]) { + process.kill(signal); + } } } else { const activeHandles = process._getActiveHandles().filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles From 652294cea01437536c78580ed476db91afeda155 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 22:24:10 +0200 Subject: [PATCH 13/36] Exit the process with signal --- scripts/mocha/mocha_run.mjs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs index c994f5c58eac..cb2e2faf3dc9 100644 --- a/scripts/mocha/mocha_run.mjs +++ b/scripts/mocha/mocha_run.mjs @@ -28,14 +28,12 @@ async function exitScenarioHandler(failCount) { process.removeAllListeners("exit"); - if (failCount > 0) { - process.exit(0); - } else { - // Observed that process.exit(1) is not exiting the process - // If process still does not exit, we try to kill with signals - for (const signal of ["SIGTERM", "SIGQUIT", "SIGKILL"]) { - process.kill(signal); - } + // This is not working, process still does not exit + // process.exit(failCount > 0 ? 0 : 1); + + // If process still does not exit, we try to kill with signals + for (const signal of ["SIGTERM", "SIGQUIT", "SIGKILL"]) { + process.kill(signal); } } else { const activeHandles = process._getActiveHandles().filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles From b3406a34997bd3bfbbdb57ede05724beb58a089e Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 23:00:32 +0200 Subject: [PATCH 14/36] Stop the beacon node once --- packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts index 95ebcaa955fb..1ffd77533bf0 100644 --- a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts +++ b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts @@ -73,8 +73,6 @@ describe("sync / unknown block sync", function () { logger: loggerNodeA, }); - afterEachCallbacks.push(() => bn.close()); - const {validators} = await getAndInitDevValidators({ node: bn, validatorsPerClient: validatorCount, From b471c54fde2f79522a259083d25357b310429652 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 4 Oct 2023 23:32:30 +0200 Subject: [PATCH 15/36] Abort the process --- scripts/mocha/mocha_run.mjs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs index cb2e2faf3dc9..bcea38441f5a 100644 --- a/scripts/mocha/mocha_run.mjs +++ b/scripts/mocha/mocha_run.mjs @@ -31,10 +31,13 @@ async function exitScenarioHandler(failCount) { // This is not working, process still does not exit // process.exit(failCount > 0 ? 0 : 1); + // This is not working, process still does not exit // If process still does not exit, we try to kill with signals - for (const signal of ["SIGTERM", "SIGQUIT", "SIGKILL"]) { - process.kill(signal); - } + // for (const signal of ["SIGTERM", "SIGQUIT", "SIGKILL"]) { + // process.kill(signal); + // } + + process.abort(); } else { const activeHandles = process._getActiveHandles().filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles console.info( From 04e34d603ea7748b7b469402dc981b129362a8ca Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 00:05:48 +0200 Subject: [PATCH 16/36] Enable debug logging for e2e tests --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d3355d36fb86..0f66276c3556 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -220,6 +220,8 @@ jobs: run: yarn test:e2e env: GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL!=0 && secrets.GOERLI_RPC_URL || env.GOERLI_RPC_DEFAULT_URL }} + DEBUG: 1 + LOG_LEVEL: debug - name: Stop the e2e test environment run: scripts/run_e2e_env.sh stop From 96fdaa85a0ac81b36d0d4e0e99f040db6024a0ac Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 14:43:25 +0200 Subject: [PATCH 17/36] Add unique name to each node for identification --- .../test/e2e/network/gossipsub.test.ts | 10 +++++-- .../beacon-node/test/e2e/network/mdns.test.ts | 2 +- .../test/e2e/network/network.test.ts | 26 ++++++++++++------- .../test/e2e/network/reqresp.test.ts | 10 +++++-- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/packages/beacon-node/test/e2e/network/gossipsub.test.ts b/packages/beacon-node/test/e2e/network/gossipsub.test.ts index 92e9271fdeea..9a97619125c6 100644 --- a/packages/beacon-node/test/e2e/network/gossipsub.test.ts +++ b/packages/beacon-node/test/e2e/network/gossipsub.test.ts @@ -40,8 +40,14 @@ function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function mockModules(gossipHandlersPartial?: Partial) { - const [netA] = await getNetworkForTest("A", config, {opts: {useWorker}, gossipHandlersPartial}); - const [netB, closeB] = await getNetworkForTest("B", config, {opts: {useWorker}, gossipHandlersPartial}); + const [netA] = await getNetworkForTest(`gossipsub-${useWorker ? "worker" : "main"}-A`, config, { + opts: {useWorker}, + gossipHandlersPartial, + }); + const [netB, closeB] = await getNetworkForTest(`gossipsub-${useWorker ? "worker" : "main"}-B`, config, { + opts: {useWorker}, + gossipHandlersPartial, + }); afterEachCallbacks.push(async () => { // await closeA(); diff --git a/packages/beacon-node/test/e2e/network/mdns.test.ts b/packages/beacon-node/test/e2e/network/mdns.test.ts index 7903b5ad3c45..91c01f81a44f 100644 --- a/packages/beacon-node/test/e2e/network/mdns.test.ts +++ b/packages/beacon-node/test/e2e/network/mdns.test.ts @@ -120,7 +120,7 @@ describe.skip("mdns", function () { // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function createTestNodesAB() { - return Promise.all([createTestNode("A"), createTestNode("B")]); + return Promise.all([createTestNode("mdns-A"), createTestNode("mdns-B")]); } it("should connect two peers on a LAN", async function () { diff --git a/packages/beacon-node/test/e2e/network/network.test.ts b/packages/beacon-node/test/e2e/network/network.test.ts index 9080ae7e5374..bdbc68424dbd 100644 --- a/packages/beacon-node/test/e2e/network/network.test.ts +++ b/packages/beacon-node/test/e2e/network/network.test.ts @@ -24,13 +24,18 @@ function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { const afterEachCallbacks: (() => Promise | void)[] = []; afterEach(async () => { - await Promise.all(afterEachCallbacks.map((cb) => cb())); - afterEachCallbacks.splice(0, afterEachCallbacks.length); + while (afterEachCallbacks.length > 0) { + const callback = afterEachCallbacks.pop(); + if (callback) await callback(); + } }); let controller: AbortController; beforeEach(() => (controller = new AbortController())); - afterEach(() => controller.abort()); + afterEach(() => { + controller.abort(); + sinon.restore(); + }); // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function createTestNode(nodeName: string) { @@ -38,24 +43,25 @@ function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { afterEachCallbacks.push(async () => { await closeAll(); - sinon.restore(); }); return network; } - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - async function createTestNodesAB() { - return Promise.all([createTestNode("A"), createTestNode("B")]); + async function createTestNodesAB(): Promise<[Network, Network]> { + return Promise.all([ + createTestNode(`network-${useWorker ? "worker" : "main"}-A`), + createTestNode(`network-${useWorker ? "worker" : "main"}-A`), + ]); } it("Disconnect peer", async () => { - const network = await createTestNode("A"); + const network = await createTestNode(`network-${useWorker ? "worker" : "main"}-DP`); await network.disconnectPeer(getValidPeerId().toString()); }); it("return getNetworkIdentity", async () => { - const network = await createTestNode("A"); + const network = await createTestNode(`network-${useWorker ? "worker" : "main"}-NI`); const networkIdentity = await network.getNetworkIdentity(); expect(networkIdentity.peerId).equals(network.peerId.toString()); }); @@ -124,7 +130,7 @@ function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { }); it("Should subscribe to gossip core topics on demand", async () => { - const netA = await createTestNode("A"); + const netA = await createTestNode(`network-${useWorker ? "worker" : "main"}-CT`); expect(await getTopics(netA)).deep.equals([]); diff --git a/packages/beacon-node/test/e2e/network/reqresp.test.ts b/packages/beacon-node/test/e2e/network/reqresp.test.ts index 0df24a0a569d..acbf799bb013 100644 --- a/packages/beacon-node/test/e2e/network/reqresp.test.ts +++ b/packages/beacon-node/test/e2e/network/reqresp.test.ts @@ -55,8 +55,14 @@ function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { getReqRespHandler?: GetReqRespHandlerFn, opts?: ReqRespBeaconNodeOpts ): Promise<[Network, Network, PeerIdStr, PeerIdStr]> { - const [netA, closeA] = await getNetworkForTest("A", config, {getReqRespHandler, opts: {...opts, useWorker}}); - const [netB, closeB] = await getNetworkForTest("B", config, {getReqRespHandler, opts: {...opts, useWorker}}); + const [netA, closeA] = await getNetworkForTest(`reqresp-${useWorker ? "worker" : "main"}-A`, config, { + getReqRespHandler, + opts: {...opts, useWorker}, + }); + const [netB, closeB] = await getNetworkForTest(`reqresp-${useWorker ? "worker" : "main"}-B`, config, { + getReqRespHandler, + opts: {...opts, useWorker}, + }); afterEachCallbacks.push(async () => { await closeA(); From 7d2256e43d3d1f0a53dcef5f053845619a8900e7 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 15:02:03 +0200 Subject: [PATCH 18/36] Add unique name to each node for identification --- packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts index 1ffd77533bf0..37cd39e87b26 100644 --- a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts +++ b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts @@ -59,8 +59,8 @@ describe("sync / unknown block sync", function () { }, }; - const loggerNodeA = testLogger("Node-A", testLoggerOpts); - const loggerNodeB = testLogger("Node-B", testLoggerOpts); + const loggerNodeA = testLogger("UnknownSync-Node-A", testLoggerOpts); + const loggerNodeB = testLogger("UnknownSync-Node-B", testLoggerOpts); const bn = await getDevBeaconNode({ params: testParams, From ca2a6d3bcffb9617f6553bc6bf8089b77b0467a3 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 15:24:23 +0200 Subject: [PATCH 19/36] Fix gossip test close --- packages/beacon-node/test/e2e/network/gossipsub.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/beacon-node/test/e2e/network/gossipsub.test.ts b/packages/beacon-node/test/e2e/network/gossipsub.test.ts index 9a97619125c6..c8c28c01eeb7 100644 --- a/packages/beacon-node/test/e2e/network/gossipsub.test.ts +++ b/packages/beacon-node/test/e2e/network/gossipsub.test.ts @@ -40,7 +40,7 @@ function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function mockModules(gossipHandlersPartial?: Partial) { - const [netA] = await getNetworkForTest(`gossipsub-${useWorker ? "worker" : "main"}-A`, config, { + const [netA, closeA] = await getNetworkForTest(`gossipsub-${useWorker ? "worker" : "main"}-A`, config, { opts: {useWorker}, gossipHandlersPartial, }); @@ -50,7 +50,7 @@ function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { }); afterEachCallbacks.push(async () => { - // await closeA(); + await closeA(); await closeB(); }); From 1aeee1ae91a4371bd99cce9bb1b5406f4a741f38 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 15:59:13 +0200 Subject: [PATCH 20/36] Fixing peer manager close handler --- .../beacon-node/test/e2e/network/peers/peerManager.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/beacon-node/test/e2e/network/peers/peerManager.test.ts b/packages/beacon-node/test/e2e/network/peers/peerManager.test.ts index 000e48dfcf3a..0fbbaa398c65 100644 --- a/packages/beacon-node/test/e2e/network/peers/peerManager.test.ts +++ b/packages/beacon-node/test/e2e/network/peers/peerManager.test.ts @@ -20,7 +20,7 @@ import {IAttnetsService} from "../../../../src/network/subnets/index.js"; import {Clock} from "../../../../src/util/clock.js"; import {LocalStatusCache} from "../../../../src/network/statusCache.js"; -const logger = testLogger(); +const logger = testLogger("peerManager"); describe("network / peers / PeerManager", function () { const peerId1 = getValidPeerId(); @@ -93,6 +93,10 @@ describe("network / peers / PeerManager", function () { null ); + afterEachCallbacks.push(async () => { + await peerManager.close(); + }); + return {statusCache, clock, libp2p, reqResp, peerManager, networkEventBus}; } From cdb9771457493ef7c92d234fecc68a00f9745473 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 16:23:36 +0200 Subject: [PATCH 21/36] Update the process of finding active resources --- scripts/mocha/mocha_run.mjs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs index bcea38441f5a..0bd2b6d75c01 100644 --- a/scripts/mocha/mocha_run.mjs +++ b/scripts/mocha/mocha_run.mjs @@ -39,17 +39,20 @@ async function exitScenarioHandler(failCount) { process.abort(); } else { - const activeHandles = process._getActiveHandles().filter((h) => typeof h.fd !== "number" || h.fd > 2); // Filter out stdio handles + const resources = process.getActiveResourcesInfo(); + const uniqueResources = new Set(resources); console.info( `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( timeout - ).toLocaleString()}' activeHandlers: ${activeHandles.length}` + ).toLocaleString()}' activeResources: ${resources}` ); - // Allow this timer to be running - if (activeHandles.length <= 1) { + // There must be at least TTY used by mocha + if (uniqueResources.size <= 1) { console.info("Seems there is no leak. Clearing leak detection hooks."); clearInterval(timer); + // Dumping resources for debugging purposes + dump(); } } } From a5c69293aab8e5516c4f63a6a90e55e7128fd1ee Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 17:02:07 +0200 Subject: [PATCH 22/36] Add log prefix to validators to debug --- .../test/e2e/api/impl/beacon/node/endpoints.test.ts | 1 + .../test/e2e/api/impl/lightclient/endpoint.test.ts | 3 ++- packages/beacon-node/test/e2e/chain/lightclient.test.ts | 3 ++- .../beacon-node/test/e2e/doppelganger/doppelganger.test.ts | 3 ++- packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts | 1 + packages/beacon-node/test/sim/4844-interop.test.ts | 1 + packages/beacon-node/test/sim/merge-interop.test.ts | 1 + packages/beacon-node/test/sim/mergemock.test.ts | 1 + packages/beacon-node/test/sim/withdrawal-interop.test.ts | 1 + packages/beacon-node/test/utils/node/validator.ts | 4 +++- 10 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/beacon-node/test/e2e/api/impl/beacon/node/endpoints.test.ts b/packages/beacon-node/test/e2e/api/impl/beacon/node/endpoints.test.ts index a9f672c25d62..db2f63117fc4 100644 --- a/packages/beacon-node/test/e2e/api/impl/beacon/node/endpoints.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/beacon/node/endpoints.test.ts @@ -93,6 +93,7 @@ describe("beacon node api", function () { // To make BN communicate with EL, it needs to produce some blocks and for that need validators const {validators} = await getAndInitDevValidators({ + logPrefix: "Offline-BN", node: bnElOffline, validatorClientCount: 1, validatorsPerClient: validatorCount, diff --git a/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts b/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts index 716c4d196367..2b3a2266338d 100644 --- a/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts @@ -24,7 +24,7 @@ describe("lightclient api", function () { const genesisValidatorsRoot = Buffer.alloc(32, 0xaa); const config = createBeaconConfig(chainConfig, genesisValidatorsRoot); const testLoggerOpts: TestLoggerOpts = {level: LogLevel.info}; - const loggerNodeA = testLogger("Node-A", testLoggerOpts); + const loggerNodeA = testLogger("lightclient-api", testLoggerOpts); const validatorCount = 2; let bn: BeaconNode; @@ -54,6 +54,7 @@ describe("lightclient api", function () { validators = ( await getAndInitDevValidators({ node: bn, + logPrefix: "lightclient-api", validatorsPerClient: validatorCount, validatorClientCount: 1, startIndex: 0, diff --git a/packages/beacon-node/test/e2e/chain/lightclient.test.ts b/packages/beacon-node/test/e2e/chain/lightclient.test.ts index 1a9edbefc432..40740728b476 100644 --- a/packages/beacon-node/test/e2e/chain/lightclient.test.ts +++ b/packages/beacon-node/test/e2e/chain/lightclient.test.ts @@ -67,7 +67,7 @@ describe("chain / lightclient", function () { }, }; - const loggerNodeA = testLogger("Node", testLoggerOpts); + const loggerNodeA = testLogger("lightclientNode", testLoggerOpts); const loggerLC = testLogger("LC", {...testLoggerOpts, level: LogLevel.debug}); const bn = await getDevBeaconNode({ @@ -89,6 +89,7 @@ describe("chain / lightclient", function () { const {validators} = await getAndInitDevValidators({ node: bn, + logPrefix: "lightclientNode", validatorsPerClient: validatorCount, validatorClientCount, startIndex: 0, diff --git a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts index 65c6eb387393..89588324bb29 100644 --- a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts +++ b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts @@ -47,7 +47,7 @@ describe.skip("doppelganger / doppelganger test", function () { async function createBNAndVC(config?: TestConfig): Promise<{beaconNode: BeaconNode; validators: Validator[]}> { const testLoggerOpts: TestLoggerOpts = {level: LogLevel.info}; - const loggerNodeA = testLogger("Node-A", testLoggerOpts); + const loggerNodeA = testLogger("doppelganger", testLoggerOpts); const bn = await getDevBeaconNode({ params: beaconParams, @@ -65,6 +65,7 @@ describe.skip("doppelganger / doppelganger test", function () { const {validators: validatorsWithDoppelganger} = await getAndInitDevValidators({ node: bn, + logPrefix: "doppelganger", validatorsPerClient: validatorCount, validatorClientCount: 1, startIndex: 0, diff --git a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts index 37cd39e87b26..34df0264640e 100644 --- a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts +++ b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts @@ -75,6 +75,7 @@ describe("sync / unknown block sync", function () { const {validators} = await getAndInitDevValidators({ node: bn, + logPrefix: "UnknownSync", validatorsPerClient: validatorCount, validatorClientCount: 1, startIndex: 0, diff --git a/packages/beacon-node/test/sim/4844-interop.test.ts b/packages/beacon-node/test/sim/4844-interop.test.ts index a2e7657769c5..014339a3d2d8 100644 --- a/packages/beacon-node/test/sim/4844-interop.test.ts +++ b/packages/beacon-node/test/sim/4844-interop.test.ts @@ -171,6 +171,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { const {data: bnIdentity} = await bn.api.node.getNetworkIdentity(); const {validators} = await getAndInitDevValidators({ + logPrefix: "Node-A", node: bn, validatorsPerClient, validatorClientCount, diff --git a/packages/beacon-node/test/sim/merge-interop.test.ts b/packages/beacon-node/test/sim/merge-interop.test.ts index 3f9d6f934bd8..c9b7f3989d62 100644 --- a/packages/beacon-node/test/sim/merge-interop.test.ts +++ b/packages/beacon-node/test/sim/merge-interop.test.ts @@ -339,6 +339,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { } as ValidatorProposerConfig; const {validators} = await getAndInitDevValidators({ + logPrefix: "Node-A", node: bn, validatorsPerClient, validatorClientCount, diff --git a/packages/beacon-node/test/sim/mergemock.test.ts b/packages/beacon-node/test/sim/mergemock.test.ts index d835aafa6a44..c1efa6d6837e 100644 --- a/packages/beacon-node/test/sim/mergemock.test.ts +++ b/packages/beacon-node/test/sim/mergemock.test.ts @@ -192,6 +192,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { } as ValidatorProposerConfig; const {validators} = await getAndInitDevValidators({ + logPrefix: "mergemock", node: bn, validatorsPerClient, validatorClientCount, diff --git a/packages/beacon-node/test/sim/withdrawal-interop.test.ts b/packages/beacon-node/test/sim/withdrawal-interop.test.ts index 8976ae9e89d0..8067565fc84c 100644 --- a/packages/beacon-node/test/sim/withdrawal-interop.test.ts +++ b/packages/beacon-node/test/sim/withdrawal-interop.test.ts @@ -285,6 +285,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { } as ValidatorProposerConfig; const {validators} = await getAndInitDevValidators({ + logPrefix: "withdrawal-interop", node: bn, validatorsPerClient, validatorClientCount, diff --git a/packages/beacon-node/test/utils/node/validator.ts b/packages/beacon-node/test/utils/node/validator.ts index 240e48b8a3d1..0a567ca17320 100644 --- a/packages/beacon-node/test/utils/node/validator.ts +++ b/packages/beacon-node/test/utils/node/validator.ts @@ -10,6 +10,7 @@ import {testLogger, TestLoggerOpts} from "../logger.js"; export async function getAndInitDevValidators({ node, + logPrefix, validatorsPerClient = 8, validatorClientCount = 1, startIndex = 0, @@ -20,6 +21,7 @@ export async function getAndInitDevValidators({ valProposerConfig, }: { node: BeaconNode; + logPrefix: string; validatorsPerClient: number; validatorClientCount: number; startIndex: number; @@ -36,7 +38,7 @@ export async function getAndInitDevValidators({ for (let clientIndex = 0; clientIndex < validatorClientCount; clientIndex++) { const startIndexVc = startIndex + clientIndex * validatorsPerClient; const endIndex = startIndexVc + validatorsPerClient - 1; - const logger = testLogger(`Vali ${startIndexVc}-${endIndex}`, testLoggerOpts); + const logger = testLogger(`${logPrefix}-VAL-${startIndexVc}-${endIndex}`, testLoggerOpts); const tmpDir = tmp.dirSync({unsafeCleanup: true}); const db = await LevelDbController.create({name: tmpDir.name}, {logger}); const slashingProtection = new SlashingProtection(db); From 519f626bbc1fc8984402613bf065db60a808ea16 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 17:11:03 +0200 Subject: [PATCH 23/36] Add log prefix to validators to debug --- packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts index 89588324bb29..4548e967e4cd 100644 --- a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts +++ b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts @@ -162,6 +162,7 @@ describe.skip("doppelganger / doppelganger test", function () { }); const {validators: validator0WithoutDoppelganger} = await getAndInitDevValidators({ + logPrefix: "doppelganger2", node: bn, validatorsPerClient: validatorCount, validatorClientCount: 1, From c8c4f2860351d905af423c55409dfef26e02c3a0 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Thu, 5 Oct 2023 18:16:01 +0200 Subject: [PATCH 24/36] Add try/catch for network core close --- .../src/network/core/networkCore.ts | 41 ++++++++++--------- .../network/core/networkCoreWorkerHandler.ts | 1 + 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/packages/beacon-node/src/network/core/networkCore.ts b/packages/beacon-node/src/network/core/networkCore.ts index 34733739a996..d7500f50c75a 100644 --- a/packages/beacon-node/src/network/core/networkCore.ts +++ b/packages/beacon-node/src/network/core/networkCore.ts @@ -253,25 +253,28 @@ export class NetworkCore implements INetworkCore { /** Destroy this instance. Can only be called once. */ async close(): Promise { if (this.closed) return; - - this.clock.off(ClockEvent.epoch, this.onEpoch); - - // Must goodbye and disconnect before stopping libp2p - await this.peerManager.goodbyeAndDisconnectAllPeers(); - this.logger.debug("network sent goodbye to all peers"); - await this.peerManager.close(); - this.logger.debug("network peerManager closed"); - await this.gossip.stop(); - this.logger.debug("network gossip closed"); - await this.reqResp.stop(); - await this.reqResp.unregisterAllProtocols(); - this.logger.debug("network reqResp closed"); - this.attnetsService.close(); - this.syncnetsService.close(); - await this.libp2p.stop(); - this.logger.debug("network lib2p closed"); - - this.closed = true; + try { + this.clock.off(ClockEvent.epoch, this.onEpoch); + + // Must goodbye and disconnect before stopping libp2p + await this.peerManager.goodbyeAndDisconnectAllPeers(); + this.logger.debug("network sent goodbye to all peers"); + await this.peerManager.close(); + this.logger.debug("network peerManager closed"); + await this.gossip.stop(); + this.logger.debug("network gossip closed"); + await this.reqResp.stop(); + await this.reqResp.unregisterAllProtocols(); + this.logger.debug("network reqResp closed"); + this.attnetsService.close(); + this.syncnetsService.close(); + await this.libp2p.stop(); + this.logger.debug("network lib2p closed"); + + this.closed = true; + } catch (err) { + this.logger.error("Error on NetworkCore.close()", {}, err as Error); + } } async scrapeMetrics(): Promise { diff --git a/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts b/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts index 73ca9e9c5fd0..074fc3a46774 100644 --- a/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts +++ b/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts @@ -146,6 +146,7 @@ export class WorkerNetworkCore implements INetworkCore { } async close(): Promise { + this.modules.logger.debug("closing network core in worker"); await this.getApi().close(); this.modules.logger.debug("terminating network worker"); await terminateWorkerThread({ From 1c1168a5ba3e6f2bc354e68d331fb16a507a41f1 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 6 Oct 2023 10:40:40 +0200 Subject: [PATCH 25/36] Wait for peer disconnect --- packages/beacon-node/src/network/peers/peerManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/beacon-node/src/network/peers/peerManager.ts b/packages/beacon-node/src/network/peers/peerManager.ts index 0ce3fdbb107c..7bdbd44b2db5 100644 --- a/packages/beacon-node/src/network/peers/peerManager.ts +++ b/packages/beacon-node/src/network/peers/peerManager.ts @@ -660,7 +660,7 @@ export class PeerManager { } catch (e) { this.logger.verbose("Failed to send goodbye", {peer: prettyPrintPeerId(peer)}, e as Error); } finally { - void this.disconnect(peer); + await this.disconnect(peer); } } From efbd4fb85db80c7f9f9e2f2ef86862f5c1ed6223 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 6 Oct 2023 11:03:01 +0200 Subject: [PATCH 26/36] Updat the exit strategy to ignore default resources --- scripts/mocha/mocha_run.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs index 0bd2b6d75c01..e6b5231601d4 100644 --- a/scripts/mocha/mocha_run.mjs +++ b/scripts/mocha/mocha_run.mjs @@ -5,7 +5,7 @@ import runCommand from "mocha/lib/cli/run.js"; import collectFiles from "mocha/lib/cli/collect-files.js"; import {dump} from "wtfnode"; -const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); +const ignoredResources = ["MessagePort", "Timeout", "PipeWrap", "TTYWrap"]; // Consider it a leak if process does not exit within this time const LEAK_TIMEOUT_MS = 10_000; @@ -40,7 +40,7 @@ async function exitScenarioHandler(failCount) { process.abort(); } else { const resources = process.getActiveResourcesInfo(); - const uniqueResources = new Set(resources); + const uniqueResources = [...new Set(resources)].filter((r) => !ignoredResources.includes(r)); console.info( `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( timeout @@ -48,7 +48,7 @@ async function exitScenarioHandler(failCount) { ); // There must be at least TTY used by mocha - if (uniqueResources.size <= 1) { + if (uniqueResources.length === 0) { console.info("Seems there is no leak. Clearing leak detection hooks."); clearInterval(timer); // Dumping resources for debugging purposes From 88a6acfe4a2006fd55d6db2976888c94ae84ee66 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 6 Oct 2023 12:33:34 +0200 Subject: [PATCH 27/36] Add more logs to investigate --- packages/beacon-node/src/network/peers/peerManager.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/beacon-node/src/network/peers/peerManager.ts b/packages/beacon-node/src/network/peers/peerManager.ts index 7bdbd44b2db5..4a82c87848a7 100644 --- a/packages/beacon-node/src/network/peers/peerManager.ts +++ b/packages/beacon-node/src/network/peers/peerManager.ts @@ -201,6 +201,7 @@ export class PeerManager { } async close(): Promise { + this.logger.info("Closing peer mananger from inside"); await this.discovery?.stop(); this.libp2p.services.components.events.removeEventListener(Libp2pEvent.connectionOpen, this.onLibp2pPeerConnect); this.libp2p.services.components.events.removeEventListener( @@ -209,6 +210,7 @@ export class PeerManager { ); this.networkEventBus.off(NetworkEvent.reqRespRequest, this.onRequest); for (const interval of this.intervals) clearInterval(interval); + this.logger.info("Closed peer mananger from inside"); } /** @@ -639,7 +641,9 @@ export class PeerManager { private async disconnect(peer: PeerId): Promise { try { + this.logger.info("Disconnecting peer", {peer: prettyPrintPeerId(peer)}); await this.libp2p.hangUp(peer); + this.logger.info("Disconnected", {peer: prettyPrintPeerId(peer)}); } catch (e) { this.logger.debug("Unclean disconnect", {peer: prettyPrintPeerId(peer)}, e as Error); } @@ -647,6 +651,7 @@ export class PeerManager { private async goodbyeAndDisconnect(peer: PeerId, goodbye: GoodByeReasonCode): Promise { try { + this.logger.info("Sending goodbye", {peer: prettyPrintPeerId(peer), goodbye}); const reason = GOODBYE_KNOWN_CODES[goodbye.toString()] || ""; this.metrics?.peerGoodbyeSent.inc({reason}); @@ -657,10 +662,11 @@ export class PeerManager { // Wrap with shorter timeout than regular ReqResp requests to speed up shutdown await withTimeout(() => this.reqResp.sendGoodbye(peer, BigInt(goodbye)), 1_000); + this.logger.info("Sent goodbye", {peer: prettyPrintPeerId(peer), goodbye}); } catch (e) { this.logger.verbose("Failed to send goodbye", {peer: prettyPrintPeerId(peer)}, e as Error); } finally { - await this.disconnect(peer); + void this.disconnect(peer); } } From b4217869a7622aa09db9ec7199758027f8924157 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 6 Oct 2023 16:25:43 +0200 Subject: [PATCH 28/36] Await for disconnect --- packages/beacon-node/src/network/peers/peerManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/beacon-node/src/network/peers/peerManager.ts b/packages/beacon-node/src/network/peers/peerManager.ts index 4a82c87848a7..ae721623d3ec 100644 --- a/packages/beacon-node/src/network/peers/peerManager.ts +++ b/packages/beacon-node/src/network/peers/peerManager.ts @@ -666,7 +666,7 @@ export class PeerManager { } catch (e) { this.logger.verbose("Failed to send goodbye", {peer: prettyPrintPeerId(peer)}, e as Error); } finally { - void this.disconnect(peer); + await this.disconnect(peer); } } From f8e20256c7bfd1ee4742ce3ad94ff512424628cf Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 6 Oct 2023 16:51:30 +0200 Subject: [PATCH 29/36] Add debug level logs threads --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0f66276c3556..56a9a10eef22 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -220,7 +220,7 @@ jobs: run: yarn test:e2e env: GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL!=0 && secrets.GOERLI_RPC_URL || env.GOERLI_RPC_DEFAULT_URL }} - DEBUG: 1 + DEBUG: threads:* LOG_LEVEL: debug - name: Stop the e2e test environment From 1d6fcf57b8ac8a795a04a9ac23f48c7528ab3b4e Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 6 Oct 2023 16:51:50 +0200 Subject: [PATCH 30/36] Remove exit option for the mocha --- packages/beacon-node/.mocharc.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/beacon-node/.mocharc.yml b/packages/beacon-node/.mocharc.yml index 861a30e276e3..0f160045fd35 100644 --- a/packages/beacon-node/.mocharc.yml +++ b/packages/beacon-node/.mocharc.yml @@ -3,7 +3,6 @@ require: - ./test/setupPreset.ts - ./test/setup.ts timeout: 5000 -exit: true extension: ["ts"] node-option: - "loader=ts-node/esm" From 5c851571289eef5310605444ceb24382e9934fa6 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 10 Oct 2023 16:23:29 +0200 Subject: [PATCH 31/36] Cleanup extra code --- .github/workflows/test.yml | 8 +- packages/beacon-node/package.json | 6 +- .../src/api/impl/validator/index.ts | 3 + .../network/core/networkCoreWorkerHandler.ts | 2 +- .../src/network/peers/peerManager.ts | 2 - .../e2e/network/gossipsub-without-mocha.ts | 69 +++++++++++++++ .../test/e2e/network/test-libp2p.js | 11 +++ .../test/e2e/network/test-main-process.js | 51 +++++++++++ .../test/e2e/network/test-server.js | 31 +++++++ .../test/e2e/network/test-theads.js | 45 ++++++++++ .../validator/produceAttestationData.test.ts | 3 +- .../test/unit/monitoring/service.test.ts | 2 +- packages/logger/src/utils/consoleTransport.ts | 33 +++---- scripts/mocha/mocha_failover.mjs | 52 ----------- scripts/mocha/mocha_failover_cli.mjs | 41 --------- scripts/mocha/mocha_run.mjs | 86 ------------------- yarn.lock | 10 --- 17 files changed, 238 insertions(+), 217 deletions(-) create mode 100644 packages/beacon-node/test/e2e/network/gossipsub-without-mocha.ts create mode 100644 packages/beacon-node/test/e2e/network/test-libp2p.js create mode 100644 packages/beacon-node/test/e2e/network/test-main-process.js create mode 100644 packages/beacon-node/test/e2e/network/test-server.js create mode 100644 packages/beacon-node/test/e2e/network/test-theads.js delete mode 100755 scripts/mocha/mocha_failover.mjs delete mode 100755 scripts/mocha/mocha_failover_cli.mjs delete mode 100644 scripts/mocha/mocha_run.mjs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 56a9a10eef22..2598f3f3947e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -217,11 +217,13 @@ jobs: run: scripts/run_e2e_env.sh start - name: E2E tests - run: yarn test:e2e + # E2E tests are sometimes stalling until timeout is reached but we know that + # after 15 minutes those should have passed already if there are no failed test cases. + # In this case, just set the job status to passed as there was likely no actual issue. + # See https://github.com/ChainSafe/lodestar/issues/5913 + run: timeout 15m yarn test:e2e || { test $? -eq 124 || exit 1; } env: GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL!=0 && secrets.GOERLI_RPC_URL || env.GOERLI_RPC_DEFAULT_URL }} - DEBUG: threads:* - LOG_LEVEL: debug - name: Stop the e2e test environment run: scripts/run_e2e_env.sh stop diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 1c7419d47516..a80027ad45ec 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -80,7 +80,7 @@ "test:unit:minimal": "nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit/**/*.test.ts'", "test:unit:mainnet": "LODESTAR_PRESET=mainnet nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit-mainnet/**/*.test.ts'", "test:unit": "yarn test:unit:minimal && yarn test:unit:mainnet", - "test:e2e": "LODESTAR_PRESET=minimal ../../scripts/mocha/mocha_failover.mjs 'test/e2e/**/*.test.ts'", + "test:e2e": "LODESTAR_PRESET=minimal mocha 'test/e2e/**/*.test.ts'", "test:sim": "mocha 'test/sim/**/*.test.ts'", "test:sim:merge-interop": "mocha 'test/sim/merge-interop.test.ts'", "test:sim:mergemock": "mocha 'test/sim/mergemock.test.ts'", @@ -161,15 +161,13 @@ "@types/qs": "^6.9.7", "@types/supertest": "^2.0.12", "@types/tmp": "^0.2.3", - "@types/wtfnode": "^0.7.1", "eventsource": "^2.0.2", "it-pair": "^2.0.6", "it-drain": "^3.0.3", "leveldown": "^6.1.1", "rewiremock": "^3.14.5", "rimraf": "^4.4.1", - "tmp": "^0.2.1", - "wtfnode": "^0.9.1" + "tmp": "^0.2.1" }, "keywords": [ "ethereum", diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index c827e121da62..65e09d864c8f 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -342,13 +342,16 @@ export function getValidatorApi({ produceBlindedBlock, async produceAttestationData(committeeIndex, slot) { + console.log("%%%%%% produceAttestationData"); notWhileSyncing(); + console.log("%%%%%% produceAttestationData 2"); await waitForSlot(slot); // Must never request for a future slot > currentSlot // This needs a state in the same epoch as `slot` such that state.currentJustifiedCheckpoint is correct. // Note: This may trigger an epoch transition if there skipped slots at the beginning of the epoch. const headState = chain.getHeadState(); + console.log({chain, headState}); const headSlot = headState.slot; const attEpoch = computeEpochAtSlot(slot); const headBlockRootHex = chain.forkChoice.getHead().blockRoot; diff --git a/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts b/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts index 074fc3a46774..f0023fb46a06 100644 --- a/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts +++ b/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts @@ -146,7 +146,7 @@ export class WorkerNetworkCore implements INetworkCore { } async close(): Promise { - this.modules.logger.debug("closing network core in worker"); + this.modules.logger.debug("closing network core running in network worker"); await this.getApi().close(); this.modules.logger.debug("terminating network worker"); await terminateWorkerThread({ diff --git a/packages/beacon-node/src/network/peers/peerManager.ts b/packages/beacon-node/src/network/peers/peerManager.ts index ae721623d3ec..85ab47d6cab5 100644 --- a/packages/beacon-node/src/network/peers/peerManager.ts +++ b/packages/beacon-node/src/network/peers/peerManager.ts @@ -201,7 +201,6 @@ export class PeerManager { } async close(): Promise { - this.logger.info("Closing peer mananger from inside"); await this.discovery?.stop(); this.libp2p.services.components.events.removeEventListener(Libp2pEvent.connectionOpen, this.onLibp2pPeerConnect); this.libp2p.services.components.events.removeEventListener( @@ -210,7 +209,6 @@ export class PeerManager { ); this.networkEventBus.off(NetworkEvent.reqRespRequest, this.onRequest); for (const interval of this.intervals) clearInterval(interval); - this.logger.info("Closed peer mananger from inside"); } /** diff --git a/packages/beacon-node/test/e2e/network/gossipsub-without-mocha.ts b/packages/beacon-node/test/e2e/network/gossipsub-without-mocha.ts new file mode 100644 index 000000000000..c9837c1c406f --- /dev/null +++ b/packages/beacon-node/test/e2e/network/gossipsub-without-mocha.ts @@ -0,0 +1,69 @@ +import {expect} from "chai"; +import {createChainForkConfig, defaultChainConfig} from "@lodestar/config"; +import {sleep} from "@lodestar/utils"; +import {ssz} from "@lodestar/types"; +import {Network} from "../../../src/network/index.js"; +import {GossipType, GossipHandlerParamGeneric} from "../../../src/network/gossip/index.js"; +import {connect, onPeerConnect, getNetworkForTest} from "../../utils/network.js"; + +await runTests({useWorker: false}); +await runTests({useWorker: true}); + +async function runTests({useWorker}: {useWorker: boolean}): Promise { + const afterEachCallbacks: (() => Promise | void)[] = []; + const config = createChainForkConfig({ + ...defaultChainConfig, + ALTAIR_FORK_EPOCH: 1, + BELLATRIX_FORK_EPOCH: 1, + CAPELLA_FORK_EPOCH: 1, + }); + + let onVoluntaryExit: (ve: Uint8Array) => void; + const onVoluntaryExitPromise = new Promise((resolve) => (onVoluntaryExit = resolve)); + + const gossipHandlersPartial = { + [GossipType.voluntary_exit]: async ({gossipData}: GossipHandlerParamGeneric) => { + onVoluntaryExit(gossipData.serializedData); + }, + }; + const [netA, closeA] = await getNetworkForTest("A", config, {opts: {useWorker}, gossipHandlersPartial}); + const [netB, closeB] = await getNetworkForTest("B", config, {opts: {useWorker}, gossipHandlersPartial}); + + afterEachCallbacks.push(async () => { + await closeA(); + await closeB(); + }); + + await Promise.all([onPeerConnect(netA), onPeerConnect(netB), connect(netA, netB)]); + expect(netA.getConnectedPeerCount()).to.equal(1); + expect(netB.getConnectedPeerCount()).to.equal(1); + + await netA.subscribeGossipCoreTopics(); + await netB.subscribeGossipCoreTopics(); + + // Wait to have a peer connected to a topic + while (!netA.closed) { + await sleep(500); + if (await hasSomeMeshPeer(netA)) { + break; + } + } + + const voluntaryExit = ssz.phase0.SignedVoluntaryExit.defaultValue(); + voluntaryExit.message.epoch = config.ALTAIR_FORK_EPOCH; + await netA.publishVoluntaryExit(voluntaryExit); + + const receivedVoluntaryExit = await onVoluntaryExitPromise; + expect(receivedVoluntaryExit).to.deep.equal(ssz.phase0.SignedVoluntaryExit.serialize(voluntaryExit)); + + console.log(receivedVoluntaryExit); + + while (afterEachCallbacks.length > 0) { + const callback = afterEachCallbacks.pop(); + if (callback) await callback(); + } +} + +async function hasSomeMeshPeer(net: Network): Promise { + return Object.values(await net.dumpMeshPeers()).some((peers) => peers.length > 0); +} diff --git a/packages/beacon-node/test/e2e/network/test-libp2p.js b/packages/beacon-node/test/e2e/network/test-libp2p.js new file mode 100644 index 000000000000..e51aabb23334 --- /dev/null +++ b/packages/beacon-node/test/e2e/network/test-libp2p.js @@ -0,0 +1,11 @@ +import {tcp} from "@libp2p/tcp"; +import {multiaddr} from "@multiformats/multiaddr"; + +const transport = tcp({})(); +const listener = transport.createListener({ + handler: (connection) => { + console.info(connection); + }, +}); +await listener.listen(multiaddr("/ip4/127.0.0.1/tcp/9999")); +await listener.close(); diff --git a/packages/beacon-node/test/e2e/network/test-main-process.js b/packages/beacon-node/test/e2e/network/test-main-process.js new file mode 100644 index 000000000000..28f56724a4c4 --- /dev/null +++ b/packages/beacon-node/test/e2e/network/test-main-process.js @@ -0,0 +1,51 @@ +import net from "node:net"; +import wtf from "wtfnode"; + +async function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +const sockets = []; + +const server = net.createServer({keepAlive: true}, (socket) => { + sockets.push(socket); + + socket.on("error", (err) => { + console.error("socket error", err); + }); + socket.on("end", () => { + socket.end(); + sockets.splice(sockets.indexOf(socket), 1); + console.info("Client ended..."); + wtf.dump(); + }); + + socket.once("close", () => { + console.info("socket closed on server side"); + socket.end(); + sockets.splice(sockets.indexOf(socket), 1); + }); +}); + +server + .on("listening", () => { + console.info("Server started listening...", server.address()); + wtf.dump(); + }) + .on("close", () => { + console.info("\n\nServer closed..."); + wtf.dump(); + }) + .on("error", (err) => { + console.error("\n\nServer error: ", err); + }); + +server.listen({host: "localhost", port: 9999}); + +const client = net.createConnection({host: "localhost", port: 9999}, () => { + console.info("Client connected..."); + wtf.dump(); +}); +await sleep(2000); +client.end(); +server.close(); diff --git a/packages/beacon-node/test/e2e/network/test-server.js b/packages/beacon-node/test/e2e/network/test-server.js new file mode 100644 index 000000000000..85f7105d0d07 --- /dev/null +++ b/packages/beacon-node/test/e2e/network/test-server.js @@ -0,0 +1,31 @@ +import net from "node:net"; + +const sockets = []; +const server = net.createServer({keepAlive: true}, function req(socket) { + sockets.push(socket); + socket.on("close", () => { + console.log("socket closed", socket.remoteAddress, socket.remotePort); + sockets.splice(sockets.indexOf(socket), 1); + }); +}); + +server.listen(9999); + +for (let i = 0; i < 10; i++) { + const socket = net.createConnection({host: "localhost", port: 9999}); + socket.on("ready", () => { + console.log("socket ready", socket.remoteAddress, socket.remotePort); + }); +} + +// server.close(); + +setTimeout(() => { + console.log("server closing...", server.listening); + server.close(); + console.log("server closed...", server.listening); + for (const socket of sockets) { + socket.destroy(); + } + console.log("server closed...", server.listening); +}, 4000); diff --git a/packages/beacon-node/test/e2e/network/test-theads.js b/packages/beacon-node/test/e2e/network/test-theads.js new file mode 100644 index 000000000000..7c418a501c54 --- /dev/null +++ b/packages/beacon-node/test/e2e/network/test-theads.js @@ -0,0 +1,45 @@ +import net from "node:net"; +import {isMainThread, Worker} from "node:worker_threads"; +import wtf from "wtfnode"; + +async function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +if (isMainThread) { + new Worker(new URL(import.meta.url)); +} else { + const sockets = []; + const server = net.createServer({keepAlive: true}, (socket) => { + sockets.push(socket); + + socket.on("error", (err) => { + console.error("socket error", err); + }); + socket.once("close", () => { + sockets.splice(sockets.indexOf(socket), 1); + }); + }); + + server + .on("listening", () => { + console.info("Server started listening...", server.address()); + wtf.dump(); + }) + .on("close", () => { + console.info("\n\nServer closed..."); + wtf.dump(); + }) + .on("error", (err) => { + console.error("\n\nServer error: ", err); + }); + + server.listen({host: "localhost", port: 9999}); + const client = net.createConnection({host: "localhost", port: 9999}, () => { + console.info("Client connected..."); + wtf.dump(); + }); + await sleep(2000); + client.end(); + server.close(); +} diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts index fd1cfb7ff526..ce497a1d0481 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts @@ -32,10 +32,11 @@ describe("api - validator - produceAttestationData", function () { }; }); - it("Should throw when node is not synced", async function () { + it.only("Should throw when node is not synced", async function () { // Set the node's state to way back from current slot const currentSlot = 100000; const headSlot = 0; + console.log(server.chainStub); server.chainStub.clock = {currentSlot} as IClock; sinon.replaceGetter(syncStub, "state", () => SyncState.SyncingFinalized); server.forkChoiceStub.getHead.returns({slot: headSlot} as ProtoBlock); diff --git a/packages/beacon-node/test/unit/monitoring/service.test.ts b/packages/beacon-node/test/unit/monitoring/service.test.ts index ecc085917cf6..824491a3d906 100644 --- a/packages/beacon-node/test/unit/monitoring/service.test.ts +++ b/packages/beacon-node/test/unit/monitoring/service.test.ts @@ -9,7 +9,7 @@ import {MonitoringOptions} from "../../../src/monitoring/options.js"; import {sleep} from "../../utils/sleep.js"; import {startRemoteService, remoteServiceRoutes, remoteServiceError} from "./remoteService.js"; -describe("monitoring / service", () => { +describe.skip("monitoring / service", () => { const sandbox = sinon.createSandbox(); const endpoint = "https://test.example.com/api/v1/client/metrics"; diff --git a/packages/logger/src/utils/consoleTransport.ts b/packages/logger/src/utils/consoleTransport.ts index 41a1084b4b83..17d0792e4d63 100644 --- a/packages/logger/src/utils/consoleTransport.ts +++ b/packages/logger/src/utils/consoleTransport.ts @@ -1,5 +1,6 @@ import {Logger, transports} from "winston"; -import {LEVEL, LogLevel, WinstonLogInfo} from "../interface.js"; +// import {LEVEL, LogLevel, WinstonLogInfo} from "../interface.js"; +import {LogLevel} from "../interface.js"; export class ConsoleDynamicLevel extends transports.Console { private readonly levelByModule = new Map(); @@ -15,7 +16,7 @@ export class ConsoleDynamicLevel extends transports.Console { this.defaultLevel = opts.defaultLevel; // Set level and parent to undefined so that underlying transport logs everything - this.level = undefined; + // this.level = undefined; } setModuleLevel(module: string, level: LogLevel): void { @@ -26,21 +27,21 @@ export class ConsoleDynamicLevel extends transports.Console { return this.levelByModule.delete(module); } - _write(info: WinstonLogInfo, enc: BufferEncoding, callback: (error?: Error | null | undefined) => void): void { - const moduleLevel = this.levelByModule.get(info.module) ?? this.defaultLevel; + // _write(info: WinstonLogInfo, enc: BufferEncoding, callback: (error?: Error | null | undefined) => void): void { + // const moduleLevel = this.levelByModule.get(info.module) ?? this.defaultLevel; - // Min number is highest prio log level - // levels = {error: 0, warn: 1, info: 2, ...} + // // Min number is highest prio log level + // // levels = {error: 0, warn: 1, info: 2, ...} - if (this.levels[moduleLevel] >= this.levels[info[LEVEL]]) { - // Set level and parent to undefined so that underlying transport logs everything - if (this.parent) { - this.parent = undefined; - } + // if (this.levels[moduleLevel] >= this.levels[info[LEVEL]]) { + // // Set level and parent to undefined so that underlying transport logs everything + // if (this.parent) { + // this.parent = undefined; + // } - super._write(info, enc, callback); - } else { - callback(null); - } - } + // super._write(info, enc, callback); + // } else { + // callback(null); + // } + // } } diff --git a/scripts/mocha/mocha_failover.mjs b/scripts/mocha/mocha_failover.mjs deleted file mode 100755 index b46120ad3e45..000000000000 --- a/scripts/mocha/mocha_failover.mjs +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env node -/* eslint-disable import/no-extraneous-dependencies */ - -import {spawn} from "node:child_process"; -import os from "node:os"; -import url from "node:url"; -import path from "node:path"; -import {loadOptions} from "mocha/lib/cli/cli.js"; -import unparse from "yargs-unparser"; - -const dirName = url.fileURLToPath(new URL(".", import.meta.url)); -const mochaPath = path.join(dirName, "mocha_failover_cli.mjs"); - -process.stdout.write("====================================================\n"); -process.stdout.write("%%%%%%% ITS NOT MOCHA BINARY - ITS A WRAPPER %%%%%%%\n"); -process.stdout.write("====================================================\n"); - -const argv = process.argv.slice(2); -const mochaArgs = loadOptions(argv); - -const nodeArgv = mochaArgs["node-option"] && mochaArgs["node-option"].map((v) => "--" + v); - -delete mochaArgs["node-option"]; - -const args = [].concat(nodeArgv, mochaPath, unparse(mochaArgs)); - -const proc = spawn(process.execPath, args, { - stdio: "inherit", -}); - -proc.on("exit", (code, signal) => { - process.on("exit", () => { - if (signal) { - process.kill(process.pid, signal); - } else { - process.exit(code); - } - }); -}); - -// terminate children. -process.on("SIGINT", () => { - proc.kill("SIGINT"); - if (!args.parallel || args.jobs < 2) { - // win32 does not support SIGTERM, so use next best thing. - if (os.platform() === "win32") { - proc.kill("SIGKILL"); - } else { - proc.kill("SIGTERM"); - } - } -}); diff --git a/scripts/mocha/mocha_failover_cli.mjs b/scripts/mocha/mocha_failover_cli.mjs deleted file mode 100755 index e72a994a18f5..000000000000 --- a/scripts/mocha/mocha_failover_cli.mjs +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env node -/* eslint-disable import/no-extraneous-dependencies */ -import {loadOptions} from "mocha/lib/cli/cli.js"; -import yargs from "yargs/yargs"; -import mochaPackage from "mocha/package.json" assert {type: "json"}; -import runCommand from "./mocha_run.mjs"; - -const argv = process.argv.slice(2); -const args = loadOptions(argv); - -const yargsOptions = { - "combine-arrays": true, - "short-option-groups": false, - "dot-notation": false, - "strip-aliased": true, -}; - -yargs() - .scriptName("mocha") - .command(runCommand) - .updateStrings({ - "Positionals:": "Positional Arguments", - "Options:": "Other Options", - "Commands:": "Commands", - }) - .fail((msg, err, yargs) => { - yargs.showHelp(); - process.exitCode = 1; - }) - .help("help", "Show usage information & exit") - .alias("help", "h") - .version("version", "Show version number & exit", mochaPackage.version) - .alias("version", "V") - .wrap(process.stdout.columns ? Math.min(process.stdout.columns, 80) : 80) - .parserConfiguration(yargsOptions) - .config(args) - .parse(args._) - .catch((error) => { - console.error(error); - process.exit(1); - }); diff --git a/scripts/mocha/mocha_run.mjs b/scripts/mocha/mocha_run.mjs deleted file mode 100644 index e6b5231601d4..000000000000 --- a/scripts/mocha/mocha_run.mjs +++ /dev/null @@ -1,86 +0,0 @@ -/* eslint-disable no-console */ -/* eslint-disable import/no-extraneous-dependencies */ -import Mocha from "mocha"; -import runCommand from "mocha/lib/cli/run.js"; -import collectFiles from "mocha/lib/cli/collect-files.js"; -import {dump} from "wtfnode"; - -const ignoredResources = ["MessagePort", "Timeout", "PipeWrap", "TTYWrap"]; - -// Consider it a leak if process does not exit within this time -const LEAK_TIMEOUT_MS = 10_000; - -// Code is typically the number of failures -async function exitScenarioHandler(failCount) { - const now = Date.now(); - const timeout = now + LEAK_TIMEOUT_MS; - console.info(`Leak detection after mocha finishes. failures=${failCount} now='${new Date(now).toLocaleString()}'`); - const timer = setInterval(detectLeak, 1000); - - async function detectLeak() { - const now = Date.now(); - - if (now > timeout) { - clearInterval(timer); - - console.error("Process did not terminate, dumping remaining handles and exiting"); - dump(); - - process.removeAllListeners("exit"); - - // This is not working, process still does not exit - // process.exit(failCount > 0 ? 0 : 1); - - // This is not working, process still does not exit - // If process still does not exit, we try to kill with signals - // for (const signal of ["SIGTERM", "SIGQUIT", "SIGKILL"]) { - // process.kill(signal); - // } - - process.abort(); - } else { - const resources = process.getActiveResourcesInfo(); - const uniqueResources = [...new Set(resources)].filter((r) => !ignoredResources.includes(r)); - console.info( - `Detecting resource leaks. now='${new Date(now).toLocaleString()}' timeout='${new Date( - timeout - ).toLocaleString()}' activeResources: ${resources}` - ); - - // There must be at least TTY used by mocha - if (uniqueResources.length === 0) { - console.info("Seems there is no leak. Clearing leak detection hooks."); - clearInterval(timer); - // Dumping resources for debugging purposes - dump(); - } - } - } -} - -async function wrappedRunHandler(argv) { - const mocha = new Mocha(argv); - - const {extension = [], ignore = [], file = [], recursive = false, sort = false, spec = []} = argv; - - const fileCollectParams = { - ignore, - extension, - file, - recursive, - sort, - spec, - }; - - const files = collectFiles(fileCollectParams); - console.info("single run with %d file(s)", files.length); - mocha.files = files; - - await mocha.loadFilesAsync(); - mocha.run(exitScenarioHandler); -} - -export default { - ...runCommand, - handler: wrappedRunHandler, -}; diff --git a/yarn.lock b/yarn.lock index 532aa4467865..9f5d14a38e8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3158,11 +3158,6 @@ dependencies: "@types/node" "*" -"@types/wtfnode@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@types/wtfnode/-/wtfnode-0.7.1.tgz#b570b1fd3faeb35a477111feef376b2acbf12639" - integrity sha512-0uo9YyPSCbYsHNfoQrEhpLbT/PuGBzaJhItss2Eb2uH+/XEsBabupPVAARmAdEY73wKIQFOZ2L2z9TZ2HbKOxQ== - "@types/yargs-parser@*": version "20.2.0" resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz" @@ -14074,11 +14069,6 @@ ws@~8.2.3: resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== -wtfnode@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/wtfnode/-/wtfnode-0.9.1.tgz#c385679d2df6fb4d64d734eeeaab767fcee3e0d3" - integrity sha512-Ip6C2KeQPl/F3aP1EfOnPoQk14Udd9lffpoqWDNH3Xt78svxPbv53ngtmtfI0q2Te3oTq79XKTnRNXVIn/GsPA== - xml2js@0.4.19: version "0.4.19" resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz" From 274cc1904f74fdfa527fe213806fb02e457028bb Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 10 Oct 2023 16:28:57 +0200 Subject: [PATCH 32/36] Cleanup the PR --- packages/beacon-node/.mocharc.yml | 1 + .../src/api/impl/validator/index.ts | 3 - .../src/network/peers/peerManager.ts | 4 -- .../e2e/network/gossipsub-without-mocha.ts | 69 ------------------- .../test/e2e/network/test-libp2p.js | 11 --- .../test/e2e/network/test-main-process.js | 51 -------------- .../test/e2e/network/test-server.js | 31 --------- .../test/e2e/network/test-theads.js | 45 ------------ packages/logger/src/utils/consoleTransport.ts | 32 ++++----- 9 files changed, 17 insertions(+), 230 deletions(-) delete mode 100644 packages/beacon-node/test/e2e/network/gossipsub-without-mocha.ts delete mode 100644 packages/beacon-node/test/e2e/network/test-libp2p.js delete mode 100644 packages/beacon-node/test/e2e/network/test-main-process.js delete mode 100644 packages/beacon-node/test/e2e/network/test-server.js delete mode 100644 packages/beacon-node/test/e2e/network/test-theads.js diff --git a/packages/beacon-node/.mocharc.yml b/packages/beacon-node/.mocharc.yml index 0f160045fd35..861a30e276e3 100644 --- a/packages/beacon-node/.mocharc.yml +++ b/packages/beacon-node/.mocharc.yml @@ -3,6 +3,7 @@ require: - ./test/setupPreset.ts - ./test/setup.ts timeout: 5000 +exit: true extension: ["ts"] node-option: - "loader=ts-node/esm" diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index 65e09d864c8f..c827e121da62 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -342,16 +342,13 @@ export function getValidatorApi({ produceBlindedBlock, async produceAttestationData(committeeIndex, slot) { - console.log("%%%%%% produceAttestationData"); notWhileSyncing(); - console.log("%%%%%% produceAttestationData 2"); await waitForSlot(slot); // Must never request for a future slot > currentSlot // This needs a state in the same epoch as `slot` such that state.currentJustifiedCheckpoint is correct. // Note: This may trigger an epoch transition if there skipped slots at the beginning of the epoch. const headState = chain.getHeadState(); - console.log({chain, headState}); const headSlot = headState.slot; const attEpoch = computeEpochAtSlot(slot); const headBlockRootHex = chain.forkChoice.getHead().blockRoot; diff --git a/packages/beacon-node/src/network/peers/peerManager.ts b/packages/beacon-node/src/network/peers/peerManager.ts index 85ab47d6cab5..7bdbd44b2db5 100644 --- a/packages/beacon-node/src/network/peers/peerManager.ts +++ b/packages/beacon-node/src/network/peers/peerManager.ts @@ -639,9 +639,7 @@ export class PeerManager { private async disconnect(peer: PeerId): Promise { try { - this.logger.info("Disconnecting peer", {peer: prettyPrintPeerId(peer)}); await this.libp2p.hangUp(peer); - this.logger.info("Disconnected", {peer: prettyPrintPeerId(peer)}); } catch (e) { this.logger.debug("Unclean disconnect", {peer: prettyPrintPeerId(peer)}, e as Error); } @@ -649,7 +647,6 @@ export class PeerManager { private async goodbyeAndDisconnect(peer: PeerId, goodbye: GoodByeReasonCode): Promise { try { - this.logger.info("Sending goodbye", {peer: prettyPrintPeerId(peer), goodbye}); const reason = GOODBYE_KNOWN_CODES[goodbye.toString()] || ""; this.metrics?.peerGoodbyeSent.inc({reason}); @@ -660,7 +657,6 @@ export class PeerManager { // Wrap with shorter timeout than regular ReqResp requests to speed up shutdown await withTimeout(() => this.reqResp.sendGoodbye(peer, BigInt(goodbye)), 1_000); - this.logger.info("Sent goodbye", {peer: prettyPrintPeerId(peer), goodbye}); } catch (e) { this.logger.verbose("Failed to send goodbye", {peer: prettyPrintPeerId(peer)}, e as Error); } finally { diff --git a/packages/beacon-node/test/e2e/network/gossipsub-without-mocha.ts b/packages/beacon-node/test/e2e/network/gossipsub-without-mocha.ts deleted file mode 100644 index c9837c1c406f..000000000000 --- a/packages/beacon-node/test/e2e/network/gossipsub-without-mocha.ts +++ /dev/null @@ -1,69 +0,0 @@ -import {expect} from "chai"; -import {createChainForkConfig, defaultChainConfig} from "@lodestar/config"; -import {sleep} from "@lodestar/utils"; -import {ssz} from "@lodestar/types"; -import {Network} from "../../../src/network/index.js"; -import {GossipType, GossipHandlerParamGeneric} from "../../../src/network/gossip/index.js"; -import {connect, onPeerConnect, getNetworkForTest} from "../../utils/network.js"; - -await runTests({useWorker: false}); -await runTests({useWorker: true}); - -async function runTests({useWorker}: {useWorker: boolean}): Promise { - const afterEachCallbacks: (() => Promise | void)[] = []; - const config = createChainForkConfig({ - ...defaultChainConfig, - ALTAIR_FORK_EPOCH: 1, - BELLATRIX_FORK_EPOCH: 1, - CAPELLA_FORK_EPOCH: 1, - }); - - let onVoluntaryExit: (ve: Uint8Array) => void; - const onVoluntaryExitPromise = new Promise((resolve) => (onVoluntaryExit = resolve)); - - const gossipHandlersPartial = { - [GossipType.voluntary_exit]: async ({gossipData}: GossipHandlerParamGeneric) => { - onVoluntaryExit(gossipData.serializedData); - }, - }; - const [netA, closeA] = await getNetworkForTest("A", config, {opts: {useWorker}, gossipHandlersPartial}); - const [netB, closeB] = await getNetworkForTest("B", config, {opts: {useWorker}, gossipHandlersPartial}); - - afterEachCallbacks.push(async () => { - await closeA(); - await closeB(); - }); - - await Promise.all([onPeerConnect(netA), onPeerConnect(netB), connect(netA, netB)]); - expect(netA.getConnectedPeerCount()).to.equal(1); - expect(netB.getConnectedPeerCount()).to.equal(1); - - await netA.subscribeGossipCoreTopics(); - await netB.subscribeGossipCoreTopics(); - - // Wait to have a peer connected to a topic - while (!netA.closed) { - await sleep(500); - if (await hasSomeMeshPeer(netA)) { - break; - } - } - - const voluntaryExit = ssz.phase0.SignedVoluntaryExit.defaultValue(); - voluntaryExit.message.epoch = config.ALTAIR_FORK_EPOCH; - await netA.publishVoluntaryExit(voluntaryExit); - - const receivedVoluntaryExit = await onVoluntaryExitPromise; - expect(receivedVoluntaryExit).to.deep.equal(ssz.phase0.SignedVoluntaryExit.serialize(voluntaryExit)); - - console.log(receivedVoluntaryExit); - - while (afterEachCallbacks.length > 0) { - const callback = afterEachCallbacks.pop(); - if (callback) await callback(); - } -} - -async function hasSomeMeshPeer(net: Network): Promise { - return Object.values(await net.dumpMeshPeers()).some((peers) => peers.length > 0); -} diff --git a/packages/beacon-node/test/e2e/network/test-libp2p.js b/packages/beacon-node/test/e2e/network/test-libp2p.js deleted file mode 100644 index e51aabb23334..000000000000 --- a/packages/beacon-node/test/e2e/network/test-libp2p.js +++ /dev/null @@ -1,11 +0,0 @@ -import {tcp} from "@libp2p/tcp"; -import {multiaddr} from "@multiformats/multiaddr"; - -const transport = tcp({})(); -const listener = transport.createListener({ - handler: (connection) => { - console.info(connection); - }, -}); -await listener.listen(multiaddr("/ip4/127.0.0.1/tcp/9999")); -await listener.close(); diff --git a/packages/beacon-node/test/e2e/network/test-main-process.js b/packages/beacon-node/test/e2e/network/test-main-process.js deleted file mode 100644 index 28f56724a4c4..000000000000 --- a/packages/beacon-node/test/e2e/network/test-main-process.js +++ /dev/null @@ -1,51 +0,0 @@ -import net from "node:net"; -import wtf from "wtfnode"; - -async function sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -const sockets = []; - -const server = net.createServer({keepAlive: true}, (socket) => { - sockets.push(socket); - - socket.on("error", (err) => { - console.error("socket error", err); - }); - socket.on("end", () => { - socket.end(); - sockets.splice(sockets.indexOf(socket), 1); - console.info("Client ended..."); - wtf.dump(); - }); - - socket.once("close", () => { - console.info("socket closed on server side"); - socket.end(); - sockets.splice(sockets.indexOf(socket), 1); - }); -}); - -server - .on("listening", () => { - console.info("Server started listening...", server.address()); - wtf.dump(); - }) - .on("close", () => { - console.info("\n\nServer closed..."); - wtf.dump(); - }) - .on("error", (err) => { - console.error("\n\nServer error: ", err); - }); - -server.listen({host: "localhost", port: 9999}); - -const client = net.createConnection({host: "localhost", port: 9999}, () => { - console.info("Client connected..."); - wtf.dump(); -}); -await sleep(2000); -client.end(); -server.close(); diff --git a/packages/beacon-node/test/e2e/network/test-server.js b/packages/beacon-node/test/e2e/network/test-server.js deleted file mode 100644 index 85f7105d0d07..000000000000 --- a/packages/beacon-node/test/e2e/network/test-server.js +++ /dev/null @@ -1,31 +0,0 @@ -import net from "node:net"; - -const sockets = []; -const server = net.createServer({keepAlive: true}, function req(socket) { - sockets.push(socket); - socket.on("close", () => { - console.log("socket closed", socket.remoteAddress, socket.remotePort); - sockets.splice(sockets.indexOf(socket), 1); - }); -}); - -server.listen(9999); - -for (let i = 0; i < 10; i++) { - const socket = net.createConnection({host: "localhost", port: 9999}); - socket.on("ready", () => { - console.log("socket ready", socket.remoteAddress, socket.remotePort); - }); -} - -// server.close(); - -setTimeout(() => { - console.log("server closing...", server.listening); - server.close(); - console.log("server closed...", server.listening); - for (const socket of sockets) { - socket.destroy(); - } - console.log("server closed...", server.listening); -}, 4000); diff --git a/packages/beacon-node/test/e2e/network/test-theads.js b/packages/beacon-node/test/e2e/network/test-theads.js deleted file mode 100644 index 7c418a501c54..000000000000 --- a/packages/beacon-node/test/e2e/network/test-theads.js +++ /dev/null @@ -1,45 +0,0 @@ -import net from "node:net"; -import {isMainThread, Worker} from "node:worker_threads"; -import wtf from "wtfnode"; - -async function sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -if (isMainThread) { - new Worker(new URL(import.meta.url)); -} else { - const sockets = []; - const server = net.createServer({keepAlive: true}, (socket) => { - sockets.push(socket); - - socket.on("error", (err) => { - console.error("socket error", err); - }); - socket.once("close", () => { - sockets.splice(sockets.indexOf(socket), 1); - }); - }); - - server - .on("listening", () => { - console.info("Server started listening...", server.address()); - wtf.dump(); - }) - .on("close", () => { - console.info("\n\nServer closed..."); - wtf.dump(); - }) - .on("error", (err) => { - console.error("\n\nServer error: ", err); - }); - - server.listen({host: "localhost", port: 9999}); - const client = net.createConnection({host: "localhost", port: 9999}, () => { - console.info("Client connected..."); - wtf.dump(); - }); - await sleep(2000); - client.end(); - server.close(); -} diff --git a/packages/logger/src/utils/consoleTransport.ts b/packages/logger/src/utils/consoleTransport.ts index 17d0792e4d63..11d3831f340a 100644 --- a/packages/logger/src/utils/consoleTransport.ts +++ b/packages/logger/src/utils/consoleTransport.ts @@ -1,5 +1,5 @@ import {Logger, transports} from "winston"; -// import {LEVEL, LogLevel, WinstonLogInfo} from "../interface.js"; +import {LEVEL, LogLevel, WinstonLogInfo} from "../interface.js"; import {LogLevel} from "../interface.js"; export class ConsoleDynamicLevel extends transports.Console { @@ -16,7 +16,7 @@ export class ConsoleDynamicLevel extends transports.Console { this.defaultLevel = opts.defaultLevel; // Set level and parent to undefined so that underlying transport logs everything - // this.level = undefined; + this.level = undefined; } setModuleLevel(module: string, level: LogLevel): void { @@ -27,21 +27,21 @@ export class ConsoleDynamicLevel extends transports.Console { return this.levelByModule.delete(module); } - // _write(info: WinstonLogInfo, enc: BufferEncoding, callback: (error?: Error | null | undefined) => void): void { - // const moduleLevel = this.levelByModule.get(info.module) ?? this.defaultLevel; + _write(info: WinstonLogInfo, enc: BufferEncoding, callback: (error?: Error | null | undefined) => void): void { + const moduleLevel = this.levelByModule.get(info.module) ?? this.defaultLevel; - // // Min number is highest prio log level - // // levels = {error: 0, warn: 1, info: 2, ...} + // Min number is highest prio log level + // levels = {error: 0, warn: 1, info: 2, ...} - // if (this.levels[moduleLevel] >= this.levels[info[LEVEL]]) { - // // Set level and parent to undefined so that underlying transport logs everything - // if (this.parent) { - // this.parent = undefined; - // } + if (this.levels[moduleLevel] >= this.levels[info[LEVEL]]) { + // Set level and parent to undefined so that underlying transport logs everything + if (this.parent) { + this.parent = undefined; + } - // super._write(info, enc, callback); - // } else { - // callback(null); - // } - // } + super._write(info, enc, callback); + } else { + callback(null); + } + } } From abe067fd259d91b956ff56c90c4e422d1dce5804 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 10 Oct 2023 16:32:08 +0200 Subject: [PATCH 33/36] Cleanup a duplicate variable --- packages/logger/src/utils/consoleTransport.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/logger/src/utils/consoleTransport.ts b/packages/logger/src/utils/consoleTransport.ts index 11d3831f340a..41a1084b4b83 100644 --- a/packages/logger/src/utils/consoleTransport.ts +++ b/packages/logger/src/utils/consoleTransport.ts @@ -1,6 +1,5 @@ import {Logger, transports} from "winston"; import {LEVEL, LogLevel, WinstonLogInfo} from "../interface.js"; -import {LogLevel} from "../interface.js"; export class ConsoleDynamicLevel extends transports.Console { private readonly levelByModule = new Map(); From 4c42132efd4fc9541d3c250ab0bddcd9c2b2d45b Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 10 Oct 2023 16:41:58 +0200 Subject: [PATCH 34/36] Fix the unused tests --- .../unit/api/impl/validator/produceAttestationData.test.ts | 3 +-- packages/beacon-node/test/unit/monitoring/service.test.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts index ce497a1d0481..fd1cfb7ff526 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts @@ -32,11 +32,10 @@ describe("api - validator - produceAttestationData", function () { }; }); - it.only("Should throw when node is not synced", async function () { + it("Should throw when node is not synced", async function () { // Set the node's state to way back from current slot const currentSlot = 100000; const headSlot = 0; - console.log(server.chainStub); server.chainStub.clock = {currentSlot} as IClock; sinon.replaceGetter(syncStub, "state", () => SyncState.SyncingFinalized); server.forkChoiceStub.getHead.returns({slot: headSlot} as ProtoBlock); diff --git a/packages/beacon-node/test/unit/monitoring/service.test.ts b/packages/beacon-node/test/unit/monitoring/service.test.ts index 824491a3d906..ecc085917cf6 100644 --- a/packages/beacon-node/test/unit/monitoring/service.test.ts +++ b/packages/beacon-node/test/unit/monitoring/service.test.ts @@ -9,7 +9,7 @@ import {MonitoringOptions} from "../../../src/monitoring/options.js"; import {sleep} from "../../utils/sleep.js"; import {startRemoteService, remoteServiceRoutes, remoteServiceError} from "./remoteService.js"; -describe.skip("monitoring / service", () => { +describe("monitoring / service", () => { const sandbox = sinon.createSandbox(); const endpoint = "https://test.example.com/api/v1/client/metrics"; From 9144fdc5326b5e3ab6d2a2d3ef1f815dd346eb13 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 13 Oct 2023 11:24:45 +0200 Subject: [PATCH 35/36] Revert some code change --- .../src/network/core/networkCore.ts | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/packages/beacon-node/src/network/core/networkCore.ts b/packages/beacon-node/src/network/core/networkCore.ts index d7500f50c75a..f0757c624bbb 100644 --- a/packages/beacon-node/src/network/core/networkCore.ts +++ b/packages/beacon-node/src/network/core/networkCore.ts @@ -253,28 +253,24 @@ export class NetworkCore implements INetworkCore { /** Destroy this instance. Can only be called once. */ async close(): Promise { if (this.closed) return; - try { - this.clock.off(ClockEvent.epoch, this.onEpoch); - - // Must goodbye and disconnect before stopping libp2p - await this.peerManager.goodbyeAndDisconnectAllPeers(); - this.logger.debug("network sent goodbye to all peers"); - await this.peerManager.close(); - this.logger.debug("network peerManager closed"); - await this.gossip.stop(); - this.logger.debug("network gossip closed"); - await this.reqResp.stop(); - await this.reqResp.unregisterAllProtocols(); - this.logger.debug("network reqResp closed"); - this.attnetsService.close(); - this.syncnetsService.close(); - await this.libp2p.stop(); - this.logger.debug("network lib2p closed"); - - this.closed = true; - } catch (err) { - this.logger.error("Error on NetworkCore.close()", {}, err as Error); - } + this.clock.off(ClockEvent.epoch, this.onEpoch); + + // Must goodbye and disconnect before stopping libp2p + await this.peerManager.goodbyeAndDisconnectAllPeers(); + this.logger.debug("network sent goodbye to all peers"); + await this.peerManager.close(); + this.logger.debug("network peerManager closed"); + await this.gossip.stop(); + this.logger.debug("network gossip closed"); + await this.reqResp.stop(); + await this.reqResp.unregisterAllProtocols(); + this.logger.debug("network reqResp closed"); + this.attnetsService.close(); + this.syncnetsService.close(); + await this.libp2p.stop(); + this.logger.debug("network lib2p closed"); + + this.closed = true; } async scrapeMetrics(): Promise { From 47df4398689d9b20718c1676c64e9b90b135a824 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Fri, 13 Oct 2023 11:52:42 +0200 Subject: [PATCH 36/36] Remove unrelated diff --- packages/beacon-node/src/network/core/networkCore.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/beacon-node/src/network/core/networkCore.ts b/packages/beacon-node/src/network/core/networkCore.ts index f0757c624bbb..34733739a996 100644 --- a/packages/beacon-node/src/network/core/networkCore.ts +++ b/packages/beacon-node/src/network/core/networkCore.ts @@ -253,6 +253,7 @@ export class NetworkCore implements INetworkCore { /** Destroy this instance. Can only be called once. */ async close(): Promise { if (this.closed) return; + this.clock.off(ClockEvent.epoch, this.onEpoch); // Must goodbye and disconnect before stopping libp2p