Swift implementation of libp2p, a modular & extensible networking stack

Overview

Swift LibP2P

Swift Package Manager compatible

The Swift implementation of the libp2p networking stack

Table of Contents

Overview

libp2p is a networking stack and library modularized out of The IPFS Project, and bundled separately for other tools to use.

libp2p is the product of a long, and arduous quest of understanding -- a deep dive into the internet's network stack, and plentiful peer-to-peer protocols from the past. Building large-scale peer-to-peer systems has been complex and difficult in the last 15 years, and libp2p is a way to fix that. It is a "network stack" -- a protocol suite -- that cleanly separates concerns, and enables sophisticated applications to only use the protocols they absolutely need, without giving up interoperability and upgradeability. libp2p grew out of IPFS, but it is built so that lots of people can use it, for lots of different projects.

Docs & Examples

Note:

To learn more, check out the following resources:

Disclaimer

  • ‼️ This is a work in progress ‼️
  • ‼️ Please don't use swift-libp2p in anything other than experimental projects until it reaches 1.0 ‼️
  • ‼️ Help it get there sooner by contributing ‼️

Install

Include the following dependency in your Package.swift file

let package = Package(
    ...
    dependencies: [
        ...
        .package(name: "LibP2P", url: "https://github.com/swift-libp2p/swift-libp2p.git", .upToNextMajor(from: "0.0.1"))
    ],
        ...
        .target(
            ...
            dependencies: [
                ...
                .product(name: "LibP2P", package: "swift-libp2p"),
            ]),
    ...
)

Usage

Example

import LibP2P
import LibP2PNoise
import LibP2PMPLEX

/// Configure your Libp2p networking stack...
let lib = try Application(.development, peerID: PeerID(.Ed25519))
lib.security.use(.noise)
lib.muxers.use(.mplex)
lib.servers.use(.tcp(host: "127.0.0.1", port: 0))

/// Register your routes handlers...
/// - Note: Uses the same syntax as swift-vapor
try lib.routes()

/// Start libp2p
lib.start()

/// Do some networking stuff... 📡

/// At some later point, when you're done with libp2p...
lib.shutdown()

Packages

  • List of packages currently in existence for swift libp2p:
  • Legend: 🟢 = kinda works, 🟡 = doesn't really work yet, 🔴 = not started yet, but on the radar
Name Status Description
Libp2p
swift-libp2p 🟢 swift-libp2p entry point
swift-libp2p-core 🟢 core interfaces, types, and abstractions
Network
swift-libp2p-mss 🟢 MultistreamSelect transport upgrader
Transport
swift-libp2p-tcp 🟢 TCP transport
swift-libp2p-udp 🟡 UDP transport
swift-libp2p-ws 🟢 WebSocket transport
swift-libp2p-http 🔴 HTTP1 transport
swift-libp2p-http2 🔴 HTTP2 transport
Encrypted Channels
swift-libp2p-plaintext 🟢 Plaintext channel
swift-libp2p-noise 🟢 Noise crypto channel
swift-libp2p-tls 🔴 TLS 1.3+ crypto channel
Stream Muxers
swift-libp2p-mplex 🟢 MPLEX stream multiplexer
swift-libp2p-yamux 🔴 YAMUX stream multiplexer
Private Network
swift-libp2p-pnet 🔴 reference private networking implementation
NAT Traversal
swift-libp2p-nat 🔴 NAT Traversal
Peerstore
swift-libp2p-peerstore 🔴 reference implementation of peer metadata storage component
Connection Manager
swift-libp2p-connection-manager 🔴 reference implementation of connection manager
Routing
swift-libp2p-record 🟡 record type and validator logic
swift-libp2p-kad-dht 🟡 Kademlia-like router
swift-libp2p-kbucket 🟡 Kademlia routing table helper types
Pubsub
swift-libp2p-pubsub 🟡 multiple pubsub implementations
RPC
swift-libp2p-rpc 🔴 a simple RPC library for libp2p
Utilities/miscellaneous
swift-libp2p-dbsaddr 🟡 a dnsaddr resolver
swift-libp2p-mdns 🟡 MulticastDNS for LAN discovery
Testing and examples
swift-libp2p-testing 🔴 a collection of testing utilities for libp2p

API

/// TODO

Contributing

Contributions are welcomed! This code is very much a proof of concept. I can guarantee you there's a better / safer way to accomplish the same results. Any suggestions, improvements, or even just critques, are welcome!

Let's make this code better together! 🤝

Credits

License

MIT © 2022 Breth Inc.

Comments
  • Linux support

    Linux support

    Is your feature request related to a problem? Please describe. swift-libp2p currently doesn't compile on Linux (64bit Ubuntu specifically)

    Describe the solution you'd like ensure swift-libp2p and all of it's dependencies can compile on Linux (at least 64bit, 32bit arm would be cool too)

    Describe alternatives you've considered n/a

    Additional context I think at the moment the primary blocker is swift-libp2p-crypto/issues/2.

    enhancement 
    opened by btoms20 1
  • Explicitly declared package name in Package.swift file

    Explicitly declared package name in Package.swift file

    This PR...

    Fixes:

    • When using Swift 5.4 (and SPM 5.4) we receive a Package resolution error stating the product SwiftProtobuf can't be found in the package swift-protobuf.
    • This issue happens when packages specify a different Package.name property compared to the GitHub repo name.

    By:

    • Explicitly declares the SwiftProtobuf package name in the Package.swift file
    opened by btoms20 0
  • Connections, ConnectionManager, PeerStore and Misc Improvements

    Connections, ConnectionManager, PeerStore and Misc Improvements

    This PR introduces...

    • A new Connection implementation (ARCConnection)
      • ARCConnections are an attempt at creating a Connection that closes itself after a given idle time
      • Idle being 0 active Streams open within the idle grace period (250ms to start)
    • An updated ConnectionManager
      • Ability to force close / prune active connections when we're at our max connection limit.
      • Implemented a buffer zone where outgoing connections are allowed while incoming connections aren't
      • Better connection history logging
    • An updated PeerStore
      • Ability to prune peers once we reach the maximum peer amount
      • Ability to compact peerstore records
    • API Change from ResponseType to Response
    /// OLD
    host.routes.on("echo", "1.0.0") { req -> ResponseType<ByteBuffer> in ... }
    
    /// NEW
    host.routes.on("echo", "1.0.0") { req -> Response<ByteBuffer> in ... }
    
    • Identify Protocol Improvements
    • General bug fixes
    opened by btoms20 0
  • Multiple Servers Support Pull Request

    Multiple Servers Support Pull Request

    Multiple Servers

    Updated the Application+Servers storage to support multiple servers. The Server protocol now enforces a static Key that prevents multiple servers of the same type from being instantiated and installed on the app at the same time.

    Installing/registering servers works via

    app.servers.use(.tcp)
    /// or with the listen shortcut
    app.listen(.ws(host: ..., port: ...))
    

    You can access a specific transports server via

    app.servers.server(for: TCPServer.self)
    

    Note: The serve command needs some TLC to reflect the multiple server use case now.

    Note: This hasn't been extensively tested. But seems to work internally (swift-swift) and externally with (swift-go) & (swift-js).

    opened by btoms20 0
  • Connection Stream Count Entry Not Clearing

    Connection Stream Count Entry Not Clearing

    Describe the bug The DefaultConnectionManager introduced Stream Counting on Connections in order to close connections who are idle with zero streams. The ConnectionStreamCount dictionary entry isn't always being removed with removed connections. After running the DHT for 12 hours you can see the leak in the number of entries vs the active connections.

    --- ConnectionManager Stats ---
    Connections: 31
    ConHistory: 110
    ConStrCnt: 279
    -------------------------------
    

    To Reproduce Just run the DHT (or another Connection heavy service) and have the connection manager dump its stats every so often...

    Expected behavior ConnectionStreamCount to only ever have as many entries as the current number of Connections (31 in this case)

    Desktop (please complete the following information):

    • Ubuntu / Linux
    bug 
    opened by btoms20 0
  • Remove / Prune peer when we fail to dial them

    Remove / Prune peer when we fail to dial them

    Is your feature request related to a problem? Please describe. Currently if we fail to dial a peer, either due to a connection timeout or a PeerID mismatch, we don't remove the peer from our peerstore.

    Describe the solution you'd like We should remove this peer from the peerstore and issue an event / notification so services (such as the DHT) can be notified of the removal.

    Describe alternatives you've considered We could perhaps just penalize the peer in question instead of immediately removing them. But that would require implementing a peer scoring system, which we should eventually do, but would take a little more effort.

    bug 
    opened by btoms20 0
  • Metrics

    Metrics

    Is your feature request related to a problem? Please describe. Nope

    Describe the solution you'd like We should integrate swift-metrics into swift-libp2p so we can keep track of metrics and monitor performance!

    Describe alternatives you've considered None

    Additional context Things you can measure tend to get better! 🧐🔬

    enhancement 
    opened by btoms20 0
  • Reuse Pending/Un-opened Connections

    Reuse Pending/Un-opened Connections

    Is your feature request related to a problem? Please describe. Sort of... Libp2p should reuse connections to peers whenever possible. And swfit-libp2p does currently check for existing suitable connections before establishing a new one. But if we fire off two separate requests to the same peer immediately after one another, swift-libp2p will open two individual connections, due to the call to ConnectionManager.getConnectionsTo(:Multiaddr, ...) returning an empty array because we haven't had time to instantiate a connection.

    Describe the solution you'd like The ConnectionManager should keep track of pending connections and bundle/queue multiple requests to the same remote peer while we're waiting for a single connection to establish. Once established, flush the pending requests through the connection.

    Describe alternatives you've considered No other alternatives

    Additional context None

    bug 
    opened by btoms20 0
Extensible HTTP Networking for iOS

Bridge Simple Typed JSON HTTP Networking in Swift 4.0 GET GET<Dict>("http://httpbin.org/ip").execute(success: { (response) in let ip: Dict = respo

null 90 Nov 19, 2022
Elegant HTTP Networking in Swift

Alamofire is an HTTP networking library written in Swift. Features Component Libraries Requirements Migration Guides Communication Installation Usage

Alamofire 38.7k Jan 8, 2023
Robust Swift networking for web APIs

Conduit Conduit is a session-based Swift HTTP networking and auth library. Within each session, requests are sent through a serial pipeline before bei

Mindbody 52 Oct 26, 2022
Versatile HTTP Networking in Swift

Net is a versatile HTTP networking library written in Swift. ?? Features URL / JSON / Property List Parameter Encoding Upload File / Data / Stream / M

Intelygenz 124 Dec 6, 2022
A type-safe, high-level networking solution for Swift apps

What Type-safe network calls made easy Netswift offers an easy way to perform network calls in a structured and type-safe way. Why Networking in Swift

Dorian Grolaux 23 Apr 27, 2022
🏇 A Swift HTTP / HTTPS networking library just incidentally execute on machines

Thus, programs must be written for people to read, and only incidentally for machines to execute. Harold Abelson, "Structure and Interpretation of Com

John Lui 845 Oct 30, 2022
A Swift Multiplatform Single-threaded Non-blocking Web and Networking Framework

Serverside non-blocking IO in Swift Ask questions in our Slack channel! Lightning (formerly Edge) Node Lightning is an HTTP Server and TCP Client/Serv

SkyLab 316 Oct 6, 2022
Simple asynchronous HTTP networking class for Swift

YYHRequest YYHRequest is a simple and lightweight class for loading asynchronous HTTP requests in Swift. Built on NSURLConnection and NSOperationQueue

yayuhh 77 May 18, 2022
RSNetworking is a networking library written entirly for the Swift programming language.

RSNetworking is a networking library written entirly for the Swift programming language.

null 18 Feb 25, 2018
ServiceData is an HTTP networking library written in Swift which can download different types of data.

ServiceData Package Description : ServiceData is an HTTP networking library written in Swift which can download different types of data. Features List

Mubarak Alseif 0 Nov 11, 2021
Easy HTTP Networking in Swift a NSURLSession wrapper with image caching support

Networking was born out of the necessity of having a simple networking library that doesn't have crazy programming abstractions or uses the latest rea

Nes 1.3k Dec 17, 2022
A networking library for Swift

Nikka Nikka is a super simple Swift HTTP networking library that comes with many extensions to make it modular and really powerful. Installation Usage

Emilien Stremsdoerfer 29 Nov 4, 2022
Declarative and Reactive Networking for Swift.

Squid Squid is a declarative and reactive networking library for Swift. Developed for Swift 5, it aims to make use of the latest language features. Th

Oliver Borchert 69 Dec 18, 2022
AsyncHTTP - Generic networking library written using Swift async/await

Generic networking library written using Swift async/await

Laszlo Teveli 7 Aug 3, 2022
A lightweight generic networking API written purely in Swift

SwiftyNetworking SwiftyNetworking library is a generic networking library writte

Zaid Rahhawi 0 Dec 24, 2021
Type-safe networking abstraction layer that associates request type with response type.

APIKit APIKit is a type-safe networking abstraction layer that associates request type with response type. // SearchRepositoriesRequest conforms to Re

Yosuke Ishikawa 1.9k Dec 30, 2022
Lightweight Concurrent Networking Framework

Dots Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 8.0+ / macOS 10.10+ /

Amr Salman 37 Nov 19, 2022
Sherlock Holmes of the networking layer. :male_detective:

ResponseDetective is a non-intrusive framework for intercepting any outgoing requests and incoming responses between your app and your server for debu

Netguru 1.9k Dec 24, 2022
🌏 A zero-dependency networking solution for building modern and secure iOS, watchOS, macOS and tvOS applications.

A zero-dependency networking solution for building modern and secure iOS, watchOS, macOS and tvOS applications. ?? TermiNetwork was tested in a produc

Bill Panagiotopoulos 90 Dec 17, 2022