feat: Waku v2 bridge

Issue #12610
This commit is contained in:
Michal Iskierko
2023-11-12 13:29:38 +01:00
parent 56e7bd01ca
commit 6d31343205
6716 changed files with 1982502 additions and 5891 deletions

1
vendor/github.com/status-im/rendezvous/.gitignore generated vendored Normal file
View File

@@ -0,0 +1 @@
vendor/

15
vendor/github.com/status-im/rendezvous/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,15 @@
notifications:
email: false
language: go
go:
- 1.11.x
- 1.12.x
install: true
env:
- GO111MODULE=on
sudo: false
jobs:
include:
- stage: Unit tests
script:
- make test

13
vendor/github.com/status-im/rendezvous/Dockerfile generated vendored Normal file
View File

@@ -0,0 +1,13 @@
FROM golang:1.17.0-alpine as builder
RUN apk add --no-cache gcc musl-dev linux-headers
RUN mkdir -p /go/src/github.com/status-im/rendezvous
ADD . /go/src/github.com/status-im/rendezvous
RUN cd /go/src/github.com/status-im/rendezvous && go build -o rendezvous ./cmd/server/
FROM alpine:latest
RUN apk add --no-cache ca-certificates bash
COPY --from=builder /go/src/github.com/status-im/rendezvous/rendezvous /usr/local/bin/rendezvous

16
vendor/github.com/status-im/rendezvous/Makefile generated vendored Normal file
View File

@@ -0,0 +1,16 @@
test:
go test ./...
image: AUTHOR = $(shell echo $$USER)
image: GIT_COMMIT = $(shell tag=`git describe --exact-match --tag 2>/dev/null`; \
if [ $$? -eq 0 ]; then echo $$tag | sed 's/^v\(.*\)$$/\1/'; \
else git rev-parse --short HEAD; fi)
image:
docker build . \
--label "commit=$(GIT_COMMIT)" \
--label "author=$(AUTHOR)" \
-t statusteam/rendezvous:$(GIT_COMMIT) \
-t statusteam/rendezvous:latest
push:
docker push statusteam/rendezvous:latest

48
vendor/github.com/status-im/rendezvous/README.md generated vendored Normal file
View File

@@ -0,0 +1,48 @@
Rendezvous server
=================
In order to build a docker image, run:
```bash
make image
```
Server usage:
```
-a, --address string listener ip address (default "0.0.0.0")
-d, --data string path where ENR infos will be stored. (default "/tmp/rendevouz")
-g, --generate dump private key and exit.
-h, --keyhex string private key hex
-k, --keypath string path to load private key
-p, --port int listener port (default 9090)
-v, --verbosity string verbosity level, options: crit, error, warning, info, debug (default "info")
```
Option `-g` can be used to generate hex of the private key for convenience.
Option `-h` should be used only in tests.
The only mandatory parameter is keypath `-k`, and not mandatory but i suggest to change data path `-d` not to a temporary
directory.
# Differences with original rendezvous
Original rendezvous description by members of libp2p team - [rendezvous](https://github.com/libp2p/specs/pull/56).
We are using current implementation for a similar purposes, but mainly as a light-peer discovery protocol for mobile
devices. Discovery v5 that depends on the kademlia implementation was too slow for mobile and consumed noticeable amount
of traffic to find peers.
Some differences with original implementation:
1. We are using ENR ([Ethereum Node Records](https://eips.ethereum.org/EIPS/eip-778)) for encoding information
about peers. ENR must be signed.
2. We are using RLP instead of protobuf. Mainly for convenience, because ENR already had util for rlp serialization.
3. Smaller liveness TTL for records. At the time of writing liveness TTL is set to be 20s.
This way we want to provide minimal guarantees that peer is online and dialable.
4. ENRs are fetched from storage randomly. And we don't provide a way to fetch "new" records.
It was done as a naive measure against spamming rendezvous servers with invalid records.
And at the same time spread load of new peers between multiple servers.
5. We don't use UNREGISTER request, since we assume that TTL is very low.
Those are mostly implementation details while idea is pretty much the same, but it is important to note that this implementation
is not compatible with one from libp2p team.

178
vendor/github.com/status-im/rendezvous/client.go generated vendored Normal file
View File

@@ -0,0 +1,178 @@
package rendezvous
import (
"context"
"crypto/rand"
"fmt"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/ethereum/go-ethereum/rlp"
libp2p "github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
ma "github.com/multiformats/go-multiaddr"
ethv4 "github.com/status-im/go-multiaddr-ethv4"
"github.com/status-im/rendezvous/protocol"
)
var logger = log.New("package", "rendezvous/client")
func NewEphemeral() (c Client, err error) {
priv, _, err := crypto.GenerateKeyPairWithReader(crypto.Secp256k1, 0, rand.Reader) // bits are ignored with edwards or secp251k1
if err != nil {
return Client{}, err
}
return New(priv)
}
func New(identity crypto.PrivKey) (c Client, err error) {
opts := []libp2p.Option{
libp2p.Identity(identity),
}
h, err := libp2p.New(opts...)
if err != nil {
return c, err
}
return Client{
h: h,
}, nil
}
func NewWithHost(h host.Host) (c Client, err error) {
return Client{
h: h,
}, nil
}
type Client struct {
h host.Host
}
func (c Client) Register(ctx context.Context, srv ma.Multiaddr, topic string, record enr.Record, ttl time.Duration) error {
s, err := c.newStream(ctx, srv)
if err != nil {
return err
}
defer s.Close()
if err = rlp.Encode(s, protocol.REGISTER); err != nil {
return err
}
if err = rlp.Encode(s, protocol.Register{Topic: topic, Record: record, TTL: uint64(ttl)}); err != nil {
return err
}
rs := rlp.NewStream(s, 0)
typ, err := rs.Uint()
if err != nil {
return err
}
if protocol.MessageType(typ) != protocol.REGISTER_RESPONSE {
return fmt.Errorf("expected %v as response, but got %v", protocol.REGISTER_RESPONSE, typ)
}
var val protocol.RegisterResponse
if err = rs.Decode(&val); err != nil {
return err
}
logger.Debug("received response to register", "status", val.Status, "message", val.Message)
if val.Status != protocol.OK {
return fmt.Errorf("register failed. status code %v", val.Status)
}
return nil
}
func (c Client) Discover(ctx context.Context, srv ma.Multiaddr, topic string, limit int) (rst []enr.Record, err error) {
s, err := c.newStream(ctx, srv)
if err != nil {
return
}
defer s.Close()
if err = rlp.Encode(s, protocol.DISCOVER); err != nil {
return
}
if err = rlp.Encode(s, protocol.Discover{Topic: topic, Limit: uint(limit)}); err != nil {
return
}
rs := rlp.NewStream(s, 0)
typ, err := rs.Uint()
if err != nil {
return nil, err
}
if protocol.MessageType(typ) != protocol.DISCOVER_RESPONSE {
return nil, fmt.Errorf("expected %v as response, but got %v", protocol.REGISTER_RESPONSE, typ)
}
var val protocol.DiscoverResponse
if err = rs.Decode(&val); err != nil {
return
}
if val.Status != protocol.OK {
return nil, fmt.Errorf("discover request failed. status code %v", val.Status)
}
logger.Debug("received response to discover request", "status", val.Status, "records lth", len(val.Records))
return val.Records, nil
}
func (c Client) RemoteIp(ctx context.Context, srv ma.Multiaddr) (value string, err error) {
s, err := c.newStream(ctx, srv)
if err != nil {
return
}
defer s.Close()
if err = rlp.Encode(s, protocol.REMOTEIP); err != nil {
return
}
rs := rlp.NewStream(s, 0)
typ, err := rs.Uint()
if err != nil {
return
}
if protocol.MessageType(typ) != protocol.REMOTEIP_RESPONSE {
err = fmt.Errorf("expected %v as response, but got %v", protocol.REMOTEIP_RESPONSE, typ)
return
}
var val protocol.RemoteIpResponse
if err = rs.Decode(&val); err != nil {
return
}
if val.Status != protocol.OK {
err = fmt.Errorf("remoteip request failed. status code %v", val.Status)
return
}
logger.Debug("received response to remoteip request", "status", val.Status, "ip", val.IP)
value = val.IP
return
}
func (c Client) newStream(ctx context.Context, srv ma.Multiaddr) (rw network.Stream, err error) {
pid, err := srv.ValueForProtocol(ethv4.P_ETHv4)
if err != nil {
return
}
peerid, err := peer.Decode(pid)
if err != nil {
return
}
// TODO there must be a better interface
targetPeerAddr, err := ma.NewMultiaddr(fmt.Sprintf("/ethv4/%s", pid))
if err != nil {
return
}
targetAddr := srv.Decapsulate(targetPeerAddr)
c.h.Peerstore().AddAddr(peerid, targetAddr, 5*time.Second)
s, err := c.h.NewStream(ctx, peerid, "/rend/0.1.0")
if err != nil {
return nil, err
}
return &InstrumentedStream{s}, nil
}
// Close shutdowns the host and all open connections.
func (c Client) Close() error {
return c.h.Close()
}

View File

@@ -0,0 +1,58 @@
package protocol
import (
"github.com/ethereum/go-ethereum/p2p/enr"
)
type ResponseStatus uint
type MessageType uint64
const (
VERSION = "/rend/0.1.0"
REGISTER MessageType = iota
REGISTER_RESPONSE
DISCOVER
DISCOVER_RESPONSE
REMOTEIP
REMOTEIP_RESPONSE
OK ResponseStatus = 0
E_INVALID_NAMESPACE ResponseStatus = 100
E_INVALID_ENR ResponseStatus = 101
E_INVALID_TTL ResponseStatus = 102
E_INVALID_LIMIT ResponseStatus = 103
E_INVALID_CONTENT ResponseStatus = 104
E_NOT_AUTHORIZED ResponseStatus = 200
E_INTERNAL_ERROR ResponseStatus = 300
)
type Register struct {
Topic string
Record enr.Record
TTL uint64
}
type RegisterResponse struct {
Status ResponseStatus
Message string
}
type Discover struct {
Limit uint
Topic string
}
type DiscoverResponse struct {
Status ResponseStatus
Message string
Records []enr.Record
}
type RemoteIp struct {
}
type RemoteIpResponse struct {
Status ResponseStatus
IP string
}

83
vendor/github.com/status-im/rendezvous/stream.go generated vendored Normal file
View File

@@ -0,0 +1,83 @@
package rendezvous
import (
"time"
"github.com/ethereum/go-ethereum/metrics"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/protocol"
)
var (
ingressTrafficMeter = metrics.NewRegisteredMeter("rendezvous/InboundTraffic", nil)
egressTrafficMeter = metrics.NewRegisteredMeter("rendezvous/OutboundTraffic", nil)
)
// InstrumentedStream implements read writer interface and collects metrics.
type InstrumentedStream struct {
s network.Stream
}
func (si InstrumentedStream) CloseWrite() error {
return si.s.CloseWrite()
}
func (si InstrumentedStream) CloseRead() error {
return si.s.CloseRead()
}
func (si InstrumentedStream) ID() string {
return si.s.ID()
}
func (si InstrumentedStream) Write(p []byte) (int, error) {
n, err := si.s.Write(p)
egressTrafficMeter.Mark(int64(n))
return n, err
}
func (si InstrumentedStream) Read(p []byte) (int, error) {
n, err := si.s.Read(p)
ingressTrafficMeter.Mark(int64(n))
return n, err
}
func (si InstrumentedStream) Close() error {
return si.s.Close()
}
func (si InstrumentedStream) Reset() error {
return si.s.Reset()
}
func (si InstrumentedStream) SetDeadline(timeout time.Time) error {
return si.s.SetDeadline(timeout)
}
func (si InstrumentedStream) SetReadDeadline(timeout time.Time) error {
return si.s.SetReadDeadline(timeout)
}
func (si InstrumentedStream) SetWriteDeadline(timeout time.Time) error {
return si.s.SetWriteDeadline(timeout)
}
func (si InstrumentedStream) Protocol() protocol.ID {
return si.s.Protocol()
}
func (si InstrumentedStream) SetProtocol(pid protocol.ID) error {
return si.s.SetProtocol(pid)
}
func (si InstrumentedStream) Conn() network.Conn {
return si.s.Conn()
}
func (si InstrumentedStream) Stat() network.Stats {
return si.s.Stat()
}
func (si InstrumentedStream) Scope() network.StreamScope {
return si.s.Scope()
}