rendezvous

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2026 License: MIT Imports: 19 Imported by: 0

README

go-libp2p-rendezvous

Rendezvous (meeting point) protocol implementation for libp2p, used to register and discover peers within a namespace.

This repository provides:

  • Server: RendezvousService (handles /rendezvous/1.0.0 streams)
  • Client: RendezvousClient / RendezvousPoint
  • Discovery adapter: RendezvousDiscovery implements github.com/libp2p/go-libp2p/core/discovery.Discovery
  • Storage backends: SQLite / SQLCipher (see db/sqlite, db/sqlcipher)

Requirements

  • Go: go1.25.7 (go.mod includes toolchain go1.25.7)

Install

go get github.com/kaleidra/go-libp2p-rendezvous@latest

Quickstart

The following snippets show the basic flow: run a rendezvous server, register from a client, then discover peers.

1) Run a server (RendezvousService)

The server needs a libp2p host.Host and a database implementing db.DB (e.g. sqlite).

package main

import (
  "context"
  "log"

  libp2p "github.com/libp2p/go-libp2p"
  rendezvous "github.com/kaleidra/go-libp2p-rendezvous"
  sqlite "github.com/kaleidra/go-libp2p-rendezvous/db/sqlite"
)

func main() {
  ctx := context.Background()

  h, err := libp2p.New()
  if err != nil {
    log.Fatal(err)
  }
  defer h.Close()

  db, err := sqlite.OpenDB(ctx, ":memory:")
  if err != nil {
    log.Fatal(err)
  }
  defer db.Close()

  _ = rendezvous.NewRendezvousService(h, db)

  // Keep your process alive; omitted for brevity.
  select {}
}
2) Register (RendezvousClient.Register)

The TTL parameter is in seconds (int). The client will refresh registrations in the background (see registerRefresh).

rc := rendezvous.NewRendezvousClient(myHost, rendezvousServerPeerID)

// Register this host under the "chat" namespace
ttl := rendezvous.DefaultTTL
recordTTL, err := rc.Register(ctx, "chat", ttl)
if err != nil {
  // handle err
}
_ = recordTTL
3) Discover (RendezvousClient.Discover)

Discover supports pagination via a cookie:

peers, cookie, err := rc.Discover(ctx, "chat", 100, nil)
if err != nil {
  // handle err
}

// peers is []peer.AddrInfo; you can connect via myHost.Connect(ctx, peers[i]).
_ = peers
_ = cookie
4) Using libp2p Discovery (RendezvousDiscovery)

If your code already uses core/discovery.Discovery, you can plug this in directly:

rd := rendezvous.NewRendezvousDiscovery(myHost, rendezvousServerPeerID)

// Advertise uses discovery.TTL(time.Duration) (e.g. 2 hours)
_, err := rd.Advertise(ctx, "chat")
if err != nil {
  // handle err
}

ch, err := rd.FindPeers(ctx, "chat")
if err != nil {
  // handle err
}
for pi := range ch {
  _ = pi // peer.AddrInfo
}

Run tests

go test ./...
go test -race ./...

FAQ

What is the TTL unit?
  • Registration TTL is in seconds.
  • RendezvousDiscovery.Advertise converts discovery.Options.Ttl to seconds before registering.
  • Cookies are used for incremental discovery (pagination).
  • Cookie validity is checked by the server DB (nonce + namespace + counter). Clients just echo it back.
Which backend should I use: sqlite or sqlcipher?
  • db/sqlite: plain SQLite for local/non-encrypted use cases.
  • db/sqlcipher: SQLCipher (requires environment support) for encrypted-at-rest use cases.

Documentation

Index

Constants

View Source
const (
	RendezvousProto = protocol.ID("/rendezvous/1.0.0")

	DefaultTTL = 2 * 3600 // 2hr
)
View Source
const (
	MaxTTL               = 72 * 3600 // 72hr
	MaxNamespaceLength   = 256
	MaxPeerAddressLength = 2048
	MaxRegistrations     = 1000
	MaxDiscoverLimit     = 1000
)

Variables

View Source
var DefaultAddrFactory = func(addrs []ma.Multiaddr) []ma.Multiaddr { return addrs }
View Source
var (
	DiscoverAsyncInterval = 2 * time.Minute
)

Functions

func NewDiscoverMessage

func NewDiscoverMessage(ns string, limit int, cookie []byte) *pb.Message

func NewRegisterMessage

func NewRegisterMessage(privKey crypto.PrivKey, ns string, pi peer.AddrInfo, ttl int) (*pb.Message, error)

func NewRendezvousDiscovery

func NewRendezvousDiscovery(host host.Host, rendezvousPeer peer.ID) discovery.Discovery

Types

type AddrsFactory

type AddrsFactory func(addrs []ma.Multiaddr) []ma.Multiaddr

type Registration

type Registration struct {
	Peer peer.AddrInfo
	Ns   string
	Ttl  int
}

type RendezvousClient

type RendezvousClient interface {
	Register(ctx context.Context, ns string, ttl int) (time.Duration, error)
	Unregister(ctx context.Context, ns string) error
	Discover(ctx context.Context, ns string, limit int, cookie []byte) ([]peer.AddrInfo, []byte, error)
	DiscoverAsync(ctx context.Context, ns string) (<-chan peer.AddrInfo, error)
}

func NewRendezvousClient

func NewRendezvousClient(host host.Host, rp peer.ID) RendezvousClient

func NewRendezvousClientWithPoint

func NewRendezvousClientWithPoint(rp RendezvousPoint) RendezvousClient

type RendezvousError

type RendezvousError struct {
	Status pb.Message_ResponseStatus
	Text   string
}

func (RendezvousError) Error

func (e RendezvousError) Error() string

type RendezvousPoint

type RendezvousPoint interface {
	Register(ctx context.Context, ns string, ttl int) (time.Duration, error)
	Unregister(ctx context.Context, ns string) error
	Discover(ctx context.Context, ns string, limit int, cookie []byte) ([]Registration, []byte, error)
	DiscoverAsync(ctx context.Context, ns string) (<-chan Registration, error)
}

func NewRendezvousPoint

func NewRendezvousPoint(host host.Host, p peer.ID, opts ...RendezvousPointOption) RendezvousPoint

type RendezvousPointOption

type RendezvousPointOption func(cfg *rendezvousPointConfig)

func ClientWithAddrsFactory

func ClientWithAddrsFactory(factory AddrsFactory) RendezvousPointOption

AddrsFactory configures libp2p to use the given address factory.

type RendezvousService

type RendezvousService struct {
	DB db.DB
}

func NewRendezvousService

func NewRendezvousService(host host.Host, db db.DB) *RendezvousService

Directories

Path Synopsis
db

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址