• Stars
    star
    129
  • Rank 279,262 (Top 6 %)
  • Language
  • Created over 8 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🐴 Let's learn how to peer-to-peer!

P2P Handbook

Status: Living Document

This handbook is very much a work in progress. It's incomplete, and I'm filling in bits and pieces as I go!

You should file issues and ask questions about aspects of p2p you're interested in!

THE HANDBOOK

This handbook is an introduction to the primitives of peer-to-peer systems for the web, and a guide to the powerful abstractions you can build on top of those primitives to form distributed systems.

This handbook's goal is to prepare you to use the excellent ecosystem of p2p modules available on npm today, and to develop your own p2p modules and applications on top.

Table of Contents


introduction

This is the handbook I wish that I had when I started delving down the peer-to-peer rabbit hole.

what is p2p

why you should use p2p

why node & javascript

what superpowers does p2p grant?

technology grants us superpowers that we would otherwise not have

  • offline-first
  • abstract away corporate infrastructure
  • data can flow more freely

CAP theorum

Consistency. Availability. Partition tolerance. Choose two.

It's possible to "cheat" and get all three: eventual consistency

p2p "layers" (roles)

Whereas the OSI model breaks networks into 7 layers, and the TCP/IP model does that into 4, it's beneficial to think of P2P in terms of roles:

+=============================+
|            roles            |
+=============================+
| applications                |
+-----------------------------+
| protocols & data structures |
+-----------------------------+
| content routing             |
+-----------------------------+
| swarm topology              |
+-----------------------------+
| peer routing                |
+-----------------------------+
| discovery                   |
+-----------------------------+
| identity                    |
+-----------------------------+

Identity

In a centralized system, this is easy: ask the user to provide an identifier. Maybe an email address, maybe a username. The server checks whether that identifier has already been taken. If it has, the user must choose another identifier. If the identity server is down, nobody can sign in, and nobody can create new identities. In fact, the whole system might become unusable if the software can't verify you are who you say you are.

In a distributed system, you are permanently stuck with such restrictions:

  1. there is no single authority to register a new identifier with
  2. you cannot know of all other peers in the network, so any identity you choose may be in conflict with another peer now or in the future
  3. there is no single authority to corroborate your claim that you are who you say you are

One easy solution might be to have each peer generate a random number between 0 and some big number. If the number is big enough, you're unlikely to see a conflict now or in the foreseeable future (though the odds grow quadratically. This solution satisfies #1 and #2, but not #3: anyone who saw your identifier could impersonate you on the network, since there are no authorities to check who's who. We need a way for users to prove they are who they claim to be, without an authority to provide confirmation.

What if you could provide some sort of proof that you were the author of a given message? A digital signature that only the holder of that large random number could produce?

Public key cryptography does just this: it's like the above, except two "random" numbers are generated: one you share widely as your identity, and the other you keep secret. You can use the secret key to produce a signature on any data you'd like, which anybody else in possession of the message, the signature, and your public key can verify: all without any remote authorities.

Public keys are long and unwieldy for humans, like 7bc0bd9bd557547b81d53196674c869c6d698164c68b0033fd4b48849ce59110. You could use a human "friendly" encoding like proquint to make this bazol-rikur-lijit-rudij-jilam-kikag-satik-sipim-nojuk-hojam-rapis-gubab-rajuz-hafoh-jogun-bihan. Pronouncible, but still not particularly useful to a human being.

There is a conjecture called Zooko's Triangle that claims no system can achieve all three properties of being human-meaningful, decentralized, and secure.

discovery

given a key, find interested peers

bittorrent dht

The bittorrent dht, mainline, is huge: there are millions of nodes worldwide. You can store arbitrary data in them, but be warned that most nodes are configured to aggressively flush keypairs they receive.

This approach is great when the swarm lacks the resources to maintain a powerful reliable central server for discovery -- a DHT is an excellent means for free short-term storage of peer location information. Because of its low retention duration, it may be required for peers to republish their contact information at a regular interval.

  • dht
  • discovery-channel
  • webtorrent

tracker / signal server

Run a centralized server(s) at some known IP that many other peers also connect to. This server can act as a connection broker, exchanging ip:ports of peers to help them connect to each other directly.

This is also a partially effective means of traversing around certain types of NATs.

This approach need not be centralized: bittorrent employs a decentralized set of trackers, which peers are free to decide between to use for discovery.

This is useful when your potential swarm size is small, and your potential peers are located broadly across the open internet and require very accessible points (maybe served over port 80) to find.

  • signalhub

multicast dns

Multicast DNS is a very well supported protocol (bonjour/zeroconf+apple/airplay, etc) for finding other machines that are on the same network as you.

It consists of sending a "query" message to the entire network. Based on its contents, machines who believe themselves applicable can respond with their information to facilitate direct contact between the two.

This is useful when your peers are likely to be on the same network as you.

  • mdns
  • discovery-channel

static bootstrap list

When all else fails, you can still ship your application with a list of hardcoded peer locations, to help peers join the larger network. This could be as simple as

[
  "QmVvUkSZqM2EG1SK9s49uN6pizNhXVFHpuJgh53my4A4pP": "tcp://12.62.93.214:9090",
  "QmawE3T8oyxMgz5KaYvsJ2BgQUZWvnKzebwLhqGPA8sqGb": "udp://24.243.12.9:1234",
  "QmQXV24ZjKPGiXfeQd4etZGgywzd4wfaGKGS48EGVdrS6C": "utp://99.4.78.181:97"
]

dns

Store peer IDs and IP addresses as low-TTL DNS entries (dns round robin). This relies on DNS' peer-to-peer-like record dissemination protocol to propagate new peers over the time domain.

This requires a central service that would function a lot like a tracker: it needs to both a) maintain a subset of active peers in the swarm, and b) publish a further subset of them to a DNS server.

This approach is so useful because your peer application doesn't even need to understand p2p protocols: it can just connect to some known example.com and get a new peer every time it connects.

  • Q: any modules for publishing round robin dns entries?

peer routing

given a peer-id and peer-info, get a duplex stream

"with this piece: what if we could map a public key to a duplex stream, across the world?"

sub-topics

  • NAT hole-punching
  • relaying

swarm / topology

  1. structured
  • fully-connected-topology
  • kademlia
  • chord
  1. unstructured
  • signalhub
  • bittorrent swarm

content routing

given a message, figure out which peers to route it to ^ need to get a more solid understanding on this

  1. examples
    1. gossip
      1. secure-gossip
      2. hyperlog / ssb (anti-entropy)

p2p data structures

data structures well suited to an unreliable network (or offline) with untrusted peers

  1. stream
  2. crdt
  1. append-only log
  2. hyperlog
  3. secure-scuttlebutt https://scuttlebot.io/more/protocols/secure-scuttlebutt.html
  4. content addressable store
  5. merkle linking (blockchain, hyperlog, ssb, etc) a. merkle dag (ipfs)
  6. dht

other handy not-strictly-p2p modules

  1. leveldb
  2. abstract-blob-store

protocol

what messages the peers of the network agree to exchange

  1. streams: the ultimate transport-agnostic abstraction
  2. multistream: multiplexing protocols over a stream

awesome p2p modules

TODO: sort these into their respective sections? or have tiny per-module bits?

  • signalhub (peer discovery)
  • hyperlog (identity, data structure, protocol)
  • discovery-channel (peer discovery)
  • discovery-swarm (peer discovery + content routing + swarm)
  • bittorrent-dht (peer discovery + swarm)
  • ssb-keys (identity)
  • pubsub-swarm (identity, peer discovery, swarm, content routing)
  • secure-gossip (content routing, protocol)

glueing p2p modules together to make apps

  1. p2p picture sharing service (walk through glueing together modules from the roles to do this)

Further Reading

Inspiration

More Repositories

1

art-of-readme

💌 Things I've learned about writing good READMEs.
7,030
star
2

common-readme

🌟 « a common readme for node »
JavaScript
378
star
3

git-ssb-intro

🔧 Learn git-ssb: a decentralized GitHub alternative.
372
star
4

hypergit

Manage and clone peer-to-peer git repositories.
JavaScript
205
star
5

hyperpad

🎍 A peer-to-peer collaborative text editor for people and their communities.
JavaScript
196
star
6

electron-speech

🎤 Easy speech recognition in Node!
JavaScript
170
star
7

wisdom

📜 My little collection of personal wisdom.
132
star
8

peer-npm

🐝 Publish and install node packages from the swarm.
JavaScript
117
star
9

web-udp

Experiment for a web standard for creating and using UDP sockets in the browser
79
star
10

airpipe

Create a stdin/stdout pipe easily over wifi or internet.
JavaScript
79
star
11

p2p-faq

❓ Commonly asked questions about peer-to-peer networks & programs.
60
star
12

nano-ecs

🔹 A nano-sized Entity-Component-System library.
JavaScript
59
star
13

ipfs-hyperlog

🔗 IPFS Merkle DAG that replicates based on append-only logs and causal linking.
JavaScript
58
star
14

gitverse

local offline p2p social git frontend
JavaScript
56
star
15

ice-box

❄️ Create immutable directory pipelines.
JavaScript
52
star
16

ipfs-blog

🌐 Host a blog ..without the hosting!
JavaScript
47
star
17

hyperpad-desktop

🎍 A peer-to-peer collaborative text editor for people and their communities.
CSS
45
star
18

airfile

📤 Painlessly transfer files from a web browser to your local machine
JavaScript
44
star
19

friendpm

👭 Share, publish, and install node packages from your cache over the local network.
JavaScript
42
star
20

secure-gossip

📞 Secure, transport agnostic, message gossip protocol.
JavaScript
40
star
21

ssb-npm-101

Installing & using npm with secure scuttlebutt.
38
star
22

hyper-string

conflict-free p2p string data structure powered by a hyperlog of operations
JavaScript
38
star
23

pubsub-swarm

🐝 Form a p2p swarm of nodes around a topic and exchange messages.
JavaScript
34
star
24

sailing-patchfoo

Sail the high seas of scuttlebutt with Patchfoo! ⛵
34
star
25

txt-blit

Draw lines of text onto other lines of text. Cooler than it sounds.
JavaScript
28
star
26

hyperdb-index

Build a realtime index over a hyperdb.
JavaScript
28
star
27

voicetube

🎵 Voice controlled YouTube music player in the browser, ideal for hands-free environments.
JavaScript
25
star
28

recs

🔔 functional entity-component-system experiment
JavaScript
23
star
29

ssb-webify

publish a local directory into a scuttlebutt website
JavaScript
22
star
30

kappa-chat

p2p anarchist real-time communication protocol using append-only logs
JavaScript
22
star
31

screen-stream

📹 Get a video stream of your computer's display.
JavaScript
22
star
32

mic-stream

[UNMAINTAINED] 🎤 Get a stream of audio data from the microphone on the browser or with Node!
JavaScript
22
star
33

noffle-business-card

JavaScript
21
star
34

exrot

📷 Snap webcam photos from the command line.
JavaScript
21
star
35

ipcat

🐈 Retrieve IPFS object data and send it to stdout.
Go
19
star
36

textarea-op-stream

readable stream of a textarea's inserts and deletes
JavaScript
18
star
37

hyper-textarea

Back a textarea with a hyper-string for conflict-free p2p replication!
JavaScript
18
star
38

binary-fsk

encode & decode binary frequency-shift keyed signals to/from data
JavaScript
18
star
39

github-dependency-crawl

🪲 Crawl GitHub issues to build a dependency graph
JavaScript
18
star
40

hypercore-private-box

Encrypt messages that only members from a set of hypercores can decrypt.
JavaScript
16
star
41

phaser-capture

Phaser (http://www.phaser.io) plugin for easily capturing screenshots (PNG, JPEG) and videos (GIF, WebM).
JavaScript
16
star
42

tdag

Plaintext task management for graph nerds.
JavaScript
15
star
43

git-remote-hypergit

git remote for hypergit
JavaScript
15
star
44

docstrings

Interpret a string literal at the beginning of a function as its documentation.
JavaScript
15
star
45

ssb-exchange

Fully sync two secure-scuttlebutt databases over a duplex stream.
JavaScript
15
star
46

latest-tweets

🐦 Get a JSON array of a Twitter user's latest tweets -- no Twitter API required!
JavaScript
15
star
47

hyperdb-git-repo

p2p git repo primitive
JavaScript
14
star
48

dotfiles

🔩 Most of my *nix-y configuration files.
Vim Script
13
star
49

picast

📺 Play media from your computer on a Raspberry Pi.
JavaScript
13
star
50

twitter-kv

🐦 Key-value store over twitter user feeds
JavaScript
13
star
51

agenda-cli

📆 Keep track of things in the future.
JavaScript
12
star
52

bisecting-between

🔪 Produces a unique value that sorts between two other given values.
JavaScript
11
star
53

internet-of-buckets

http wrapper for controlling The Internet of Buckets art installation
JavaScript
11
star
54

osm-tty

Interactive offline OpenStreetMap viewer in the terminal.
JavaScript
11
star
55

raycast-2d-tilemap

🔳 Test a ray for intersections against a 2D tile map.
JavaScript
11
star
56

grid-point-store

Fast 2D point insertions and spatial querying over grid of fixed size cells.
JavaScript
11
star
57

hyperdb-git

JavaScript
10
star
58

goertzel

🎤 Fast frequency detection using the Goertzel algorithm.
JavaScript
10
star
59

hpad

📄 Peer-to-peer documents from the command line.
JavaScript
9
star
60

hyperswarm

🐜 Create a p2p webrtc swarm around a hyperlog.
JavaScript
9
star
61

danceparty

👯 👯 👯 👯 👯 👯 👯 👯
JavaScript
9
star
62

rotating_8bit_wallpapers

A little script that sets up rotating wallpapers on your desktop based on the time of day. Hooray!
Shell
9
star
63

mapbox-style-downloader

JavaScript
8
star
64

twitter-rss-noauth

🐦 Retrieves a Twitter timeline and outputs an RSS feed -- without the Twitter API!
JavaScript
8
star
65

p2p-db

An open-ended peer-to-peer database.
JavaScript
8
star
66

hypercore-progress

Track upload/download progress of a hypercore replication stream.
JavaScript
7
star
67

collide-2d-aabb-aabb

💥 Determines whether a moving axis-aligned bounding box (AABB) collides with other AABBs.
JavaScript
7
star
68

tile-dl

JavaScript
7
star
69

ssb-web-resolver

JavaScript
7
star
70

goertzel-stream

🎵 Detects the presence of a single frequency in a stream of signal samples.
JavaScript
7
star
71

argv-or-stdin

use the 1st argument, or, if none is present, standard input
JavaScript
7
star
72

gdx-immediate-gui

🎮 Immediate-style GUI for Java and libgdx, inspired by imgui.
Java
7
star
73

geohash-point-store

🌏 Store and query spatial points using geohashes and LevelDB.
JavaScript
6
star
74

chacha-stream

Encryption and decryption streams of libsodium's chacha20 implementation.
JavaScript
6
star
75

hyperlog-reduce

Implement an async reduce function over a hyperlog.
JavaScript
6
star
76

collide-2d-aabb-tilemap

💥 Collision handling for bounding boxes and a tile map.
JavaScript
6
star
77

hyperlog-doctor

💊 cli tool for checking and repairing hyperlogs
JavaScript
6
star
78

handshake-stream

wrap a duplex stream in a two-way handshake
JavaScript
6
star
79

fallback-ipfs-shell

Provides access to either a running or new IPFS node, in that order of preference.
Go
6
star
80

web-ready

CLI to not exit until a button is pressed on a local website.
JavaScript
5
star
81

pi-voice-command-google

Recognize a single voice command on a Raspberry Pi using the Google Speech API.
JavaScript
5
star
82

sort-subset

sort a subset of an array in-place
JavaScript
5
star
83

ipfs-twitter-resolver

resolve /twitter/user/key to an IPFS address
JavaScript
5
star
84

behaviortree-sexp

A S-expression parser for behaviour trees.
JavaScript
5
star
85

p2p-file-store

Filesystem-based blob store that syncs to other fs-based blob stores.
JavaScript
5
star
86

geo-cli

🌍 Output your device's current longitude/latitude geolocation to stdout.
JavaScript
4
star
87

strapdown-cli

✨ Produce pretty web pages from markdown.
JavaScript
4
star
88

parallel

(Go) ⏩ Run many functions in parallel, but fast-bail on errors.
Go
4
star
89

abstract-point-store

Test suite & interface to implement a geographic point storage backend.
JavaScript
4
star
90

talks

🎤 Talks that I've given.
HTML
4
star
91

patchfoo

github mirror of patchfoo (from git-ssb). maybe not quite so up-to-date
JavaScript
4
star
92

bisecting-numbers

✂️ Integer-like number system where any number can be bisected to form infinite integer subsystems.
JavaScript
4
star
93

ssb-clientkit

TypeScript
4
star
94

CHAIN_SWORD

JavaScript
4
star
95

tone-cli

Generate a tone from the command line.
JavaScript
4
star
96

geo-legacy

📦 🌍 Get the geo-coordinates of every package at every version an author has published.
JavaScript
4
star
97

field-trip

🚩 Walk an unknown directed graph async
JavaScript
4
star
98

merkle-treehouse

experiment
3
star
99

mapeo-protocol

JavaScript
3
star
100

append-only-log

🚋 🚋 🚋 Test suite & interface for append-only log modules.
JavaScript
3
star