I’m trying to implement a simple p2p messaging infrastructure that will allow me to experiment with different blockchain consensus algorithms. For this to work I need to be able to relay messages between peers, but I don’t want a fully-connected topology as that wouldn’t be scalable. I stumbled upon libp2p and saw that is was being used by parties with similar goals (such as Polkadot).
I’ve tried using the examples on GitHub but what I don’t understand is how to manage peers using the discovery mechanism. The examples are a bit lacking in that department.
I have 3 events: peer:discover, peer:connect and peer:disconnect. peer:discovery gets invoked when a peer gets found. Using either Railing or MulticastDNS I am able to find other peers using this mechanism. I have tried storing the return value (a discovered peer) in a sort of key-value pair structure called PotentialPeers where the key is the PeerId of the peer.
I then presumably dial the newly discovered peer to establish a connection with it but this is where I run into problems. When I instantiate 2 peers on different ports they both discover each other, and then both try to dial each other. This leads to the following output:
[QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu] socket running [QmSEYKVqHYJEWw9uLBs7sf9V2jab9LLRQcHpJLCjnrTWCs] socket running [QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu] Discovered: QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu [QmSEYKVqHYJEWw9uLBs7sf9V2jab9LLRQcHpJLCjnrTWCs] Discovered: QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu [QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu] Connected: QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu [QmSEYKVqHYJEWw9uLBs7sf9V2jab9LLRQcHpJLCjnrTWCs] Connected: QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu [QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu] dialed QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu using protocol: /hyper/1.0.0 [QmSEYKVqHYJEWw9uLBs7sf9V2jab9LLRQcHpJLCjnrTWCs] dialed QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu using protocol: /hyper/1.0.0 [QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu] Connected: QmRQd68mqUv8bvFcCgTqMLGgxbeMysCSKDvsqvCCRW2PCu
Here’s the code:
Where this.potentialPeers is an object so I can quickly lookup peers by PeerId.
As you can see, because both nodes are dialing each other I presume I’m establishing multiple connections. This, I think, is not desirable because I believe only one connection between two peers is enough.
What am I missing?