libp2p / js-libp2p

The JavaScript Implementation of libp2p networking stack.
https://libp2p.io
Other
2.3k stars 440 forks source link

bug: max call stack exceeded when duplicate /webrtc listeners added #2539

Open SgtPooki opened 4 months ago

SgtPooki commented 4 months ago

Severity:

Medium

Description:

Possibly fixed by https://github.com/libp2p/js-libp2p/pull/2133

I accidentally had two /webrtc entries in my listen: array passed to createLibp2p. It took me way too long to figure out what was actually happening. Note that this does not happen for duplicate TCP listen addresses.

The error that surfaces is

╰─ ✔ ❯ node src/listener.js
Listener ready, listening on:
file:///Users/sgtpooki/code/work/protocol.ai/test/SgtPooki/js-libp2p-examples/node_modules/libp2p/dist/src/transport-manager.js:115
        return Array.of(...this.listeners.values()).flat();
                     ^

RangeError: Maximum call stack size exceeded
    at [Symbol.iterator] (<anonymous>)
    at DefaultTransportManager.getListeners (file:///Users/sgtpooki/code/work/protocol.ai/test/SgtPooki/js-libp2p-examples/node_modules/libp2p/dist/src/transport-manager.js:115:22)
    at WebRTCPeerListener.getAddrs (file:///Users/sgtpooki/code/work/protocol.ai/test/SgtPooki/js-libp2p-examples/node_modules/@libp2p/webrtc/dist/src/private-to-private/listener.js:18:14)
    at file:///Users/sgtpooki/code/work/protocol.ai/test/SgtPooki/js-libp2p-examples/node_modules/@libp2p/webrtc/dist/src/private-to-private/listener.js:20:25
    at Array.map (<anonymous>)
    at WebRTCPeerListener.getAddrs (file:///Users/sgtpooki/code/work/protocol.ai/test/SgtPooki/js-libp2p-examples/node_modules/@libp2p/webrtc/dist/src/private-to-private/listener.js:20:14)
    at file:///Users/sgtpooki/code/work/protocol.ai/test/SgtPooki/js-libp2p-examples/node_modules/@libp2p/webrtc/dist/src/private-to-private/listener.js:20:25
    at Array.map (<anonymous>)
    at WebRTCPeerListener.getAddrs (file:///Users/sgtpooki/code/work/protocol.ai/test/SgtPooki/js-libp2p-examples/node_modules/@libp2p/webrtc/dist/src/private-to-private/listener.js:20:14)
    at file:///Users/sgtpooki/code/work/protocol.ai/test/SgtPooki/js-libp2p-examples/node_modules/@libp2p/webrtc/dist/src/private-to-private/listener.js:20:25

Node.js v18.16.1

Which seems to stem from here:

https://github.com/libp2p/js-libp2p/blob/7ae6063dfbc754f95a2c4bd0a6bd146f2989a5f5/packages/libp2p/src/transport-manager.ts#L152C3-L154

Steps to reproduce the error:

You can reproduce this on my branch of a js-libp2p-examples fork, https://github.com/SgtPooki/js-libp2p-examples/tree/bug/repro-dupe-listen-max-call-stack. See the tiny diff of changes required to repro the error here: https://github.com/libp2p/js-libp2p-examples/commit/8abf359b1ea680ef915f01ed8ff73fa312dda59b

Steps to reproduce:

git clone https://github.com/SgtPooki/js-libp2p-examples.git
cd js-libp2p-examples
git checkout bug/repro-dupe-listen-max-call-stack
npm i
node src/listener.js
SgtPooki commented 4 months ago

I also ran ncu '*libp2p*' -u to update all libp2p deps and it's also reproducible on latest:

 @chainsafe/libp2p-noise  ^14.0.0  →  ^15.0.0
 @chainsafe/libp2p-yamux   ^6.0.1  →   ^6.0.2
 @libp2p/peer-id-factory   ^4.0.0  →   ^4.1.1
 @libp2p/tcp               ^9.0.4  →  ^9.0.24
 @libp2p/websockets        ^8.0.4  →  ^8.0.22
 libp2p                    ^1.0.8  →   ^1.5.1

this was pushed to repro branch with https://github.com/libp2p/js-libp2p-examples/commit/6b459f6d2c023dfe04afa102670dbd6989be137c