Skip to content

Latest commit

 

History

History
122 lines (102 loc) · 3.35 KB

8-implementations.md

File metadata and controls

122 lines (102 loc) · 3.35 KB

8 Implementations

A libp2p implementation should (recommended) follow a certain level of granularity when implementing different modules and functionalities, so that common interfaces are easy to expose, test and check for interoperability with other implementations.

This is the list of current modules available for libp2p:

  • libp2p (entry point)
  • Swarm
  • Peer Routing
    • libp2p-kad-routing
    • libp2p-mDNS-routing
  • Discovery
    • libp2p-mdns-discovery
    • libp2p-random-walk
    • libp2p-railing
  • Distributed Record Store
  • Generic
    • PeerInfo
    • PeerId
    • multihash
    • multiaddr
    • multistream
    • multicodec
    • ipld
    • repo

Current known implementations (or WIP) are:

8.1 Swarm

8.1.1 Swarm Dialer

The swarm dialer manages making a successful connection to a target peer, given a stream of addresses as inputs, and making sure to respect any and all rate limits imposed. To this end, we have designed the following logic for dialing:

DialPeer(peerID) {
	if PeerIsBeingDialed(peerID) {
		waitForDialToComplete(peerID)
		return BestConnToPeer(peerID)
	}
	
	StartDial(peerID)

	waitForDialToComplete(peerID)
	return BestConnToPeer(peerID)
}

	
StartDial(peerID) {
	addrs = getAddressStream(peerID)

	addrs.onNewAddr(function(addr) {
		if rateLimitCanDial(peerID, addr) {
			doDialAsync(peerID, addr)
		} else {
			rateLimitScheduleDial(peerID, addr)
		}
	})
}

// doDialAsync starts dialing to a specific address without blocking.
// when the dial returns, it releases rate limit tokens, and if it
// succeeded, will finalize the dial process.
doDialAsync(peerID, addr) {
	go transportDial(addr, function(conn, err) {
		rateLimitReleaseTokens(peerID, addr)

		if err != null {
			// handle error
		}

		dialSuccess(conn)
	})
}

// rateLimitReleaseTokens checks for any tokens the given dial
// took, and then for each of them, checks if any other dial is waiting
// for any of those tokens. If waiting dials are found, those dials are started
// immediately. Otherwise, the tokens are released to their pools.
rateLimitReleaseTokens(peerID, addr) {
	tokens = tokensForDial(peerID, addr)

	for token in tokens {
		dial = dialWaitingForToken(token)
		if dial != null {
			doDialAsync(dial.peer, dial.addr)
		} else {
			token.release()
		}
	}
	
}