libp2p
libp2p — модульный P2P-фреймворк изначально созданный для IPFS, потом выделенный в отдельный проект. Позволяет собирать P2P-приложения из сменяемых компонентов: транспорты, шифрование, мультиплексирование, discovery, DHT, pubsub. Используется в IPFS, Filecoin, Ethereum 2.0 (Beacon Chain), Polkadot.
Модули
| Слой | Опции |
|---|---|
| Транспорт | TCP, WebSocket, WebRTC, QUIC, WebTransport, TLS/TCP |
| Шифрование | Noise (по умолчанию), TLS 1.3, secio (deprecated) |
| Мультиплексирование | yamux, mplex, QUIC (встроен) |
| Discovery | mDNS (локально), Kademlia DHT, bootstrap, rendezvous |
| Content routing | Kademlia DHT, delegated routing (HTTP) |
| Pubsub | GossipSub, FloodSub |
| NAT | AutoNAT, DCUtR (Direct Connection Upgrade through Relay), Circuit Relay |
Multiaddr
libp2p использует multiaddr — self-describing формат адресов:
/ip4/1.2.3.4/tcp/9090
/ip6/::1/udp/4001/quic
/dns4/example.com/tcp/443/tls/ws/p2p/QmPeerID
/p2p-circuit/p2p/QmDestPeer # через relay
Читаемо как «слой за слоем». Легко добавить новые протоколы без ломания формата.
PeerID
Идентификатор пира = хеш публичного ключа. Часто CID-подобный: QmPeerID... (base58) или 12D3KooW... (base32-CIDv1). Криптографический — можно верифицировать что подписал именно этот пир.
Реализации
- go-libp2p — эталонная, самая полная. Go.
- rust-libp2p — активно развивается. Используется в Polkadot, Ethereum-клиентах.
- js-libp2p — TypeScript. Для браузеров и Node.
- py-libp2p — экспериментальный.
- nim-libp2p — Nimbus (Ethereum client).
- jvm-libp2p — для JVM-клиентов Ethereum.
Simple Go example
import "github.com/libp2p/go-libp2p"
host, _ := libp2p.New(
libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0"),
libp2p.Security(noise.ID, noise.New),
libp2p.Muxer(yamux.ID, yamux.DefaultTransport),
)
fmt.Println("peer:", host.ID())
fmt.Println("addrs:", host.Addrs())
DCUtR — NAT hole punching
Одна из killer-фич libp2p 2022+. Использует relay как «signaling» для синхронного hole-punch:
- A и B оба подключены к relay-узлу.
- A хочет прямое соединение с B — шлёт запрос через relay.
- Relay помогает синхронизировать время: A и B одновременно шлют TCP SYN друг к другу.
- Если оба NAT не symmetric — hole punching удаётся, дальше прямое P2P.
Аналог WebRTC ICE, но не для медиа, а для универсальных P2P-стримов.
GossipSub
Pubsub-протокол libp2p — узлы подписываются на «топики», сообщения расходятся через gossip. Используется в Ethereum 2.0 для broadcast блоков и аттестейшнов. Устойчив к спаму (score-based peering).
Circuit Relay v2
Когда прямое соединение невозможно, узел может арендовать relay у другого узла (reservation). Другие пиры подключаются к нему через /p2p/A/p2p-circuit/p2p/B. Ограничено скоростью и временем — фолбэк, не постоянка.