mirror of
https://github.com/logos-messaging/go-libp2p-rendezvous.git
synced 2026-01-02 12:53:13 +00:00
refactor: use newer .proto version, update deps and remove rendevous point sync
This commit is contained in:
parent
ac456647dc
commit
9806ad621c
139
client.go
139
client.go
@ -6,12 +6,12 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ggio "github.com/gogo/protobuf/io"
|
|
||||||
"github.com/libp2p/go-libp2p/core/host"
|
"github.com/libp2p/go-libp2p/core/host"
|
||||||
inet "github.com/libp2p/go-libp2p/core/network"
|
inet "github.com/libp2p/go-libp2p/core/network"
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
"github.com/libp2p/go-msgio/pbio"
|
||||||
|
|
||||||
pb "github.com/berty/go-libp2p-rendezvous/pb"
|
pb "github.com/waku-org/go-libp2p-rendezvous/pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -23,7 +23,6 @@ type RendezvousPoint interface {
|
|||||||
Unregister(ctx context.Context, ns string) error
|
Unregister(ctx context.Context, ns string) error
|
||||||
Discover(ctx context.Context, ns string, limit int, cookie []byte) ([]Registration, []byte, error)
|
Discover(ctx context.Context, ns string, limit int, cookie []byte) ([]Registration, []byte, error)
|
||||||
DiscoverAsync(ctx context.Context, ns string) (<-chan Registration, error)
|
DiscoverAsync(ctx context.Context, ns string) (<-chan Registration, error)
|
||||||
DiscoverSubscribe(ctx context.Context, ns string, serviceTypes []RendezvousSyncClient) (<-chan peer.AddrInfo, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Registration struct {
|
type Registration struct {
|
||||||
@ -37,7 +36,6 @@ type RendezvousClient interface {
|
|||||||
Unregister(ctx context.Context, ns string) error
|
Unregister(ctx context.Context, ns string) error
|
||||||
Discover(ctx context.Context, ns string, limit int, cookie []byte) ([]peer.AddrInfo, []byte, 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)
|
DiscoverAsync(ctx context.Context, ns string) (<-chan peer.AddrInfo, error)
|
||||||
DiscoverSubscribe(ctx context.Context, ns string) (<-chan peer.AddrInfo, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRendezvousPoint(host host.Host, p peer.ID, opts ...RendezvousPointOption) RendezvousPoint {
|
func NewRendezvousPoint(host host.Host, p peer.ID, opts ...RendezvousPointOption) RendezvousPoint {
|
||||||
@ -56,17 +54,16 @@ type rendezvousPoint struct {
|
|||||||
p peer.ID
|
p peer.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRendezvousClient(host host.Host, rp peer.ID, sync ...RendezvousSyncClient) RendezvousClient {
|
func NewRendezvousClient(host host.Host, rp peer.ID) RendezvousClient {
|
||||||
return NewRendezvousClientWithPoint(NewRendezvousPoint(host, rp), sync...)
|
return NewRendezvousClientWithPoint(NewRendezvousPoint(host, rp))
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRendezvousClientWithPoint(rp RendezvousPoint, syncClientList ...RendezvousSyncClient) RendezvousClient {
|
func NewRendezvousClientWithPoint(rp RendezvousPoint) RendezvousClient {
|
||||||
return &rendezvousClient{rp: rp, syncClients: syncClientList}
|
return &rendezvousClient{rp: rp}
|
||||||
}
|
}
|
||||||
|
|
||||||
type rendezvousClient struct {
|
type rendezvousClient struct {
|
||||||
rp RendezvousPoint
|
rp RendezvousPoint
|
||||||
syncClients []RendezvousSyncClient
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rp *rendezvousPoint) Register(ctx context.Context, ns string, ttl int) (time.Duration, error) {
|
func (rp *rendezvousPoint) Register(ctx context.Context, ns string, ttl int) (time.Duration, error) {
|
||||||
@ -76,8 +73,8 @@ func (rp *rendezvousPoint) Register(ctx context.Context, ns string, ttl int) (ti
|
|||||||
}
|
}
|
||||||
defer s.Reset()
|
defer s.Reset()
|
||||||
|
|
||||||
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
|
r := pbio.NewDelimitedReader(s, inet.MessageSizeMax)
|
||||||
w := ggio.NewDelimitedWriter(s)
|
w := pbio.NewDelimitedWriter(s)
|
||||||
|
|
||||||
addrs := rp.addrFactory(rp.host.Addrs())
|
addrs := rp.addrFactory(rp.host.Addrs())
|
||||||
if len(addrs) == 0 {
|
if len(addrs) == 0 {
|
||||||
@ -85,7 +82,13 @@ func (rp *rendezvousPoint) Register(ctx context.Context, ns string, ttl int) (ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("advertising on `%s` with: %v", ns, addrs)
|
log.Debugf("advertising on `%s` with: %v", ns, addrs)
|
||||||
req := newRegisterMessage(ns, peer.AddrInfo{ID: rp.host.ID(), Addrs: addrs}, ttl)
|
|
||||||
|
privKey := rp.host.Peerstore().PrivKey(rp.host.ID())
|
||||||
|
req, err := newRegisterMessage(privKey, ns, peer.AddrInfo{ID: rp.host.ID(), Addrs: addrs}, ttl)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
err = w.WriteMsg(req)
|
err = w.WriteMsg(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -163,7 +166,7 @@ func (rp *rendezvousPoint) Unregister(ctx context.Context, ns string) error {
|
|||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
w := ggio.NewDelimitedWriter(s)
|
w := pbio.NewDelimitedWriter(s)
|
||||||
req := newUnregisterMessage(ns, rp.host.ID())
|
req := newUnregisterMessage(ns, rp.host.ID())
|
||||||
return w.WriteMsg(req)
|
return w.WriteMsg(req)
|
||||||
}
|
}
|
||||||
@ -179,13 +182,13 @@ func (rp *rendezvousPoint) Discover(ctx context.Context, ns string, limit int, c
|
|||||||
}
|
}
|
||||||
defer s.Reset()
|
defer s.Reset()
|
||||||
|
|
||||||
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
|
r := pbio.NewDelimitedReader(s, inet.MessageSizeMax)
|
||||||
w := ggio.NewDelimitedWriter(s)
|
w := pbio.NewDelimitedWriter(s)
|
||||||
|
|
||||||
return discoverQuery(ns, limit, cookie, r, w)
|
return discoverQuery(ns, limit, cookie, r, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverQuery(ns string, limit int, cookie []byte, r ggio.Reader, w ggio.Writer) ([]Registration, []byte, error) {
|
func discoverQuery(ns string, limit int, cookie []byte, r pbio.Reader, w pbio.Writer) ([]Registration, []byte, error) {
|
||||||
req := newDiscoverMessage(ns, limit, cookie)
|
req := newDiscoverMessage(ns, limit, cookie)
|
||||||
err := w.WriteMsg(req)
|
err := w.WriteMsg(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -199,7 +202,7 @@ func discoverQuery(ns string, limit int, cookie []byte, r ggio.Reader, w ggio.Wr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if res.GetType() != pb.Message_DISCOVER_RESPONSE {
|
if res.GetType() != pb.Message_DISCOVER_RESPONSE {
|
||||||
return nil, nil, fmt.Errorf("Unexpected response: %s", res.GetType().String())
|
return nil, nil, fmt.Errorf("unexpected response: %s", res.GetType().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
status := res.GetDiscoverResponse().GetStatus()
|
status := res.GetDiscoverResponse().GetStatus()
|
||||||
@ -210,7 +213,7 @@ func discoverQuery(ns string, limit int, cookie []byte, r ggio.Reader, w ggio.Wr
|
|||||||
regs := res.GetDiscoverResponse().GetRegistrations()
|
regs := res.GetDiscoverResponse().GetRegistrations()
|
||||||
result := make([]Registration, 0, len(regs))
|
result := make([]Registration, 0, len(regs))
|
||||||
for _, reg := range regs {
|
for _, reg := range regs {
|
||||||
pi, err := pbToPeerInfo(reg.GetPeer())
|
pi, err := pbToPeerRecord(reg.SignedPeerRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Invalid peer info: %s", err.Error())
|
log.Errorf("Invalid peer info: %s", err.Error())
|
||||||
continue
|
continue
|
||||||
@ -236,8 +239,8 @@ func discoverAsync(ctx context.Context, ns string, s inet.Stream, ch chan Regist
|
|||||||
defer s.Reset()
|
defer s.Reset()
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
|
|
||||||
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
|
r := pbio.NewDelimitedReader(s, inet.MessageSizeMax)
|
||||||
w := ggio.NewDelimitedWriter(s)
|
w := pbio.NewDelimitedWriter(s)
|
||||||
|
|
||||||
const batch = 200
|
const batch = 200
|
||||||
|
|
||||||
@ -320,99 +323,3 @@ func discoverPeersAsync(ctx context.Context, rch <-chan Registration, ch chan pe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *rendezvousClient) DiscoverSubscribe(ctx context.Context, ns string) (<-chan peer.AddrInfo, error) {
|
|
||||||
return rc.rp.DiscoverSubscribe(ctx, ns, rc.syncClients)
|
|
||||||
}
|
|
||||||
|
|
||||||
func subscribeServiceTypes(serviceTypeClients []RendezvousSyncClient) []string {
|
|
||||||
serviceTypes := []string(nil)
|
|
||||||
for _, serviceType := range serviceTypeClients {
|
|
||||||
serviceTypes = append(serviceTypes, serviceType.GetServiceType())
|
|
||||||
}
|
|
||||||
|
|
||||||
return serviceTypes
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rp *rendezvousPoint) DiscoverSubscribe(ctx context.Context, ns string, serviceTypeClients []RendezvousSyncClient) (<-chan peer.AddrInfo, error) {
|
|
||||||
serviceTypes := subscribeServiceTypes(serviceTypeClients)
|
|
||||||
|
|
||||||
s, err := rp.host.NewStream(ctx, rp.p, RendezvousProto)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
|
|
||||||
w := ggio.NewDelimitedWriter(s)
|
|
||||||
|
|
||||||
subType, subDetails, err := discoverSubscribeQuery(ns, serviceTypes, r, w)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("discover subscribe error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
subClient := RendezvousSyncClient(nil)
|
|
||||||
for _, subClient = range serviceTypeClients {
|
|
||||||
if subClient.GetServiceType() == subType {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if subClient == nil {
|
|
||||||
return nil, fmt.Errorf("unrecognized client type")
|
|
||||||
}
|
|
||||||
|
|
||||||
regCh, err := subClient.Subscribe(ctx, subDetails)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to subscribe to updates: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ch := make(chan peer.AddrInfo)
|
|
||||||
go func() {
|
|
||||||
defer close(ch)
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case result, ok := <-regCh:
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ch <- result.Peer
|
|
||||||
case <-ctx.Done():
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return ch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func discoverSubscribeQuery(ns string, serviceTypes []string, r ggio.Reader, w ggio.Writer) (subType string, subDetails string, err error) {
|
|
||||||
req := &pb.Message{
|
|
||||||
Type: pb.Message_DISCOVER_SUBSCRIBE,
|
|
||||||
DiscoverSubscribe: newDiscoverSubscribeMessage(ns, serviceTypes),
|
|
||||||
}
|
|
||||||
err = w.WriteMsg(req)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", fmt.Errorf("write err: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var res pb.Message
|
|
||||||
err = r.ReadMsg(&res)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", fmt.Errorf("read err: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if res.GetType() != pb.Message_DISCOVER_SUBSCRIBE_RESPONSE {
|
|
||||||
return "", "", fmt.Errorf("unexpected response: %s", res.GetType().String())
|
|
||||||
}
|
|
||||||
|
|
||||||
status := res.GetDiscoverSubscribeResponse().GetStatus()
|
|
||||||
if status != pb.Message_OK {
|
|
||||||
return "", "", RendezvousError{Status: status, Text: res.GetDiscoverSubscribeResponse().GetStatusText()}
|
|
||||||
}
|
|
||||||
|
|
||||||
subType = res.GetDiscoverSubscribeResponse().GetSubscriptionType()
|
|
||||||
subDetails = res.GetDiscoverSubscribeResponse().GetSubscriptionDetails()
|
|
||||||
|
|
||||||
return subType, subDetails, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import (
|
|||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
||||||
|
|
||||||
"github.com/berty/go-libp2p-rendezvous/test_utils"
|
|
||||||
"github.com/libp2p/go-libp2p/core/host"
|
"github.com/libp2p/go-libp2p/core/host"
|
||||||
|
"github.com/waku-org/go-libp2p-rendezvous/test_utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getRendezvousClients(t *testing.T, hosts []host.Host) []RendezvousClient {
|
func getRendezvousClients(t *testing.T, hosts []host.Host) []RendezvousClient {
|
||||||
|
|||||||
@ -6,14 +6,14 @@ import (
|
|||||||
|
|
||||||
type RegistrationRecord struct {
|
type RegistrationRecord struct {
|
||||||
Id peer.ID
|
Id peer.ID
|
||||||
Addrs [][]byte
|
SignedPeerRecord []byte
|
||||||
Ns string
|
Ns string
|
||||||
Ttl int
|
Ttl int
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB interface {
|
type DB interface {
|
||||||
Close() error
|
Close() error
|
||||||
Register(p peer.ID, ns string, addrs [][]byte, ttl int) (uint64, error)
|
Register(p peer.ID, ns string, signedPeerRecord []byte, ttl int) (uint64, error)
|
||||||
Unregister(p peer.ID, ns string) error
|
Unregister(p peer.ID, ns string) error
|
||||||
CountRegistrations(p peer.ID) (int, error)
|
CountRegistrations(p peer.ID) (int, error)
|
||||||
Discover(ns string, cookie []byte, limit int) ([]RegistrationRecord, []byte, error)
|
Discover(ns string, cookie []byte, limit int) ([]RegistrationRecord, []byte, error)
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
dbi "github.com/berty/go-libp2p-rendezvous/db"
|
dbi "github.com/waku-org/go-libp2p-rendezvous/db"
|
||||||
|
|
||||||
_ "github.com/mutecomm/go-sqlcipher/v4"
|
_ "github.com/mutecomm/go-sqlcipher/v4"
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ func (db *DB) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) prepareDB() error {
|
func (db *DB) prepareDB() error {
|
||||||
_, err := db.db.Exec("CREATE TABLE Registrations (counter INTEGER PRIMARY KEY AUTOINCREMENT, peer VARCHAR(64), ns VARCHAR, expire INTEGER, addrs VARBINARY)")
|
_, err := db.db.Exec("CREATE TABLE Registrations (counter INTEGER PRIMARY KEY AUTOINCREMENT, peer VARCHAR(64), ns VARCHAR, expire INTEGER, signedPeerRecord VARBINARY)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -199,9 +199,8 @@ func (db *DB) prepareStmts() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) Register(p peer.ID, ns string, addrs [][]byte, ttl int) (uint64, error) {
|
func (db *DB) Register(p peer.ID, ns string, signedPeerRecord []byte, ttl int) (uint64, error) {
|
||||||
pid := p.Pretty()
|
pid := p.Pretty()
|
||||||
maddrs := packAddrs(addrs)
|
|
||||||
expire := time.Now().Unix() + int64(ttl)
|
expire := time.Now().Unix() + int64(ttl)
|
||||||
|
|
||||||
tx, err := db.db.Begin()
|
tx, err := db.db.Begin()
|
||||||
@ -219,7 +218,7 @@ func (db *DB) Register(p peer.ID, ns string, addrs [][]byte, ttl int) (uint64, e
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = insertNew.Exec(pid, ns, expire, maddrs)
|
_, err = insertNew.Exec(pid, ns, expire, signedPeerRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -307,12 +306,11 @@ func (db *DB) Discover(ns string, cookie []byte, limit int) ([]dbi.RegistrationR
|
|||||||
rid string
|
rid string
|
||||||
rns string
|
rns string
|
||||||
expire int64
|
expire int64
|
||||||
raddrs []byte
|
signedPeerRecord []byte
|
||||||
addrs [][]byte
|
|
||||||
p peer.ID
|
p peer.ID
|
||||||
)
|
)
|
||||||
|
|
||||||
err = rows.Scan(&counter, &rid, &rns, &expire, &raddrs)
|
err = rows.Scan(&counter, &rid, &rns, &expire, &signedPeerRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("row scan error: %s", err.Error())
|
log.Errorf("row scan error: %s", err.Error())
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -324,14 +322,8 @@ func (db *DB) Discover(ns string, cookie []byte, limit int) ([]dbi.RegistrationR
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
addrs, err := unpackAddrs(raddrs)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("error unpacking address: %s", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
reg.Id = p
|
reg.Id = p
|
||||||
reg.Addrs = addrs
|
reg.SignedPeerRecord = signedPeerRecord
|
||||||
reg.Ttl = int(expire - now)
|
reg.Ttl = int(expire - now)
|
||||||
|
|
||||||
if ns == "" {
|
if ns == "" {
|
||||||
@ -377,47 +369,6 @@ func (db *DB) cleanupExpired() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func packAddrs(addrs [][]byte) []byte {
|
|
||||||
packlen := 0
|
|
||||||
for _, addr := range addrs {
|
|
||||||
packlen = packlen + 2 + len(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
packed := make([]byte, packlen)
|
|
||||||
buf := packed
|
|
||||||
for _, addr := range addrs {
|
|
||||||
binary.BigEndian.PutUint16(buf, uint16(len(addr)))
|
|
||||||
buf = buf[2:]
|
|
||||||
copy(buf, addr)
|
|
||||||
buf = buf[len(addr):]
|
|
||||||
}
|
|
||||||
|
|
||||||
return packed
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackAddrs(packed []byte) ([][]byte, error) {
|
|
||||||
var addrs [][]byte
|
|
||||||
|
|
||||||
buf := packed
|
|
||||||
for len(buf) > 1 {
|
|
||||||
l := binary.BigEndian.Uint16(buf)
|
|
||||||
buf = buf[2:]
|
|
||||||
if len(buf) < int(l) {
|
|
||||||
return nil, fmt.Errorf("bad packed address: not enough bytes %v %v", packed, buf)
|
|
||||||
}
|
|
||||||
addr := make([]byte, l)
|
|
||||||
copy(addr, buf[:l])
|
|
||||||
buf = buf[l:]
|
|
||||||
addrs = append(addrs, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(buf) > 0 {
|
|
||||||
return nil, fmt.Errorf("bad packed address: unprocessed bytes: %v %v", packed, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
return addrs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// cookie: counter:SHA256(nonce + ns + counter)
|
// cookie: counter:SHA256(nonce + ns + counter)
|
||||||
func packCookie(counter int64, ns string, nonce []byte) []byte {
|
func packCookie(counter int64, ns string, nonce []byte) []byte {
|
||||||
cbits := make([]byte, 8)
|
cbits := make([]byte, 8)
|
||||||
|
|||||||
@ -8,41 +8,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPackAddrs(t *testing.T) {
|
|
||||||
addrs := make([][]byte, 5)
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
addrs[i] = make([]byte, rand.Intn(256))
|
|
||||||
}
|
|
||||||
|
|
||||||
packed := packAddrs(addrs)
|
|
||||||
unpacked, err := unpackAddrs(packed)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !equalAddrs(addrs, unpacked) {
|
|
||||||
t.Fatal("unpacked addr not equal to original")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func equalAddrs(addrs1, addrs2 [][]byte) bool {
|
|
||||||
if len(addrs1) != len(addrs2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, addr1 := range addrs1 {
|
|
||||||
addr2 := addrs2[i]
|
|
||||||
if !bytes.Equal(addr1, addr2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackCookie(t *testing.T) {
|
func TestPackCookie(t *testing.T) {
|
||||||
nonce := make([]byte, 16)
|
nonce := make([]byte, 16)
|
||||||
_, err := rand.Read(nonce)
|
_, err := rand.Read(nonce)
|
||||||
@ -136,20 +103,11 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr1, err := ma.NewMultiaddr("/ip4/1.1.1.1/tcp/9999")
|
signedPeerRecord1 := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
if err != nil {
|
signedPeerRecord2 := []byte{8, 7, 6, 5, 4, 3, 2, 1}
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs1 := [][]byte{addr1.Bytes()}
|
|
||||||
|
|
||||||
addr2, err := ma.NewMultiaddr("/ip4/2.2.2.2/tcp/9999")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs2 := [][]byte{addr2.Bytes()}
|
|
||||||
|
|
||||||
// register p1 and do discovery
|
// register p1 and do discovery
|
||||||
_, err = db.Register(p1, "foo1", addrs1, 60)
|
_, err = db.Register(p1, "foo1", signedPeerRecord1, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -173,12 +131,12 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p1 {
|
if rr.Id != p1 {
|
||||||
t.Fatal("expected p1 ID in registration")
|
t.Fatal("expected p1 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's signed record in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
// register p2 and do progressive discovery
|
// register p2 and do progressive discovery
|
||||||
_, err = db.Register(p2, "foo1", addrs2, 60)
|
_, err = db.Register(p2, "foo1", signedPeerRecord2, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -202,12 +160,12 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p2 {
|
if rr.Id != p2 {
|
||||||
t.Fatal("expected p2 ID in registration")
|
t.Fatal("expected p2 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs2) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord2) {
|
||||||
t.Fatal("expected p2's addrs in registration")
|
t.Fatal("expected p2's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
// reregister p1 and do progressive discovery
|
// reregister p1 and do progressive discovery
|
||||||
_, err = db.Register(p1, "foo1", addrs1, 60)
|
_, err = db.Register(p1, "foo1", signedPeerRecord1, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -231,7 +189,7 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p1 {
|
if rr.Id != p1 {
|
||||||
t.Fatal("expected p1 ID in registration")
|
t.Fatal("expected p1 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +205,7 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p2 {
|
if rr.Id != p2 {
|
||||||
t.Fatal("expected p2 ID in registration")
|
t.Fatal("expected p2 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs2) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord2) {
|
||||||
t.Fatal("expected p2's addrs in registration")
|
t.Fatal("expected p2's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +213,7 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p1 {
|
if rr.Id != p1 {
|
||||||
t.Fatal("expected p1 ID in registration")
|
t.Fatal("expected p1 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +242,7 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p1 {
|
if rr.Id != p1 {
|
||||||
t.Fatal("expected p1 ID in registration")
|
t.Fatal("expected p1 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,24 +265,15 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr1, err := ma.NewMultiaddr("/ip4/1.1.1.1/tcp/9999")
|
signedPeerRecord1 := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
if err != nil {
|
signedPeerRecord2 := []byte{8, 7, 6, 5, 4, 3, 2, 1}
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs1 := [][]byte{addr1.Bytes()}
|
|
||||||
|
|
||||||
addr2, err := ma.NewMultiaddr("/ip4/2.2.2.2/tcp/9999")
|
_, err = db.Register(p1, "foo1", signedPeerRecord1, 60)
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs2 := [][]byte{addr2.Bytes()}
|
|
||||||
|
|
||||||
_, err = db.Register(p1, "foo1", addrs1, 60)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Register(p1, "foo2", addrs1, 60)
|
_, err = db.Register(p1, "foo2", signedPeerRecord1, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -351,7 +300,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo1" {
|
if rr.Ns != "foo1" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,16 +311,16 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo2" {
|
if rr.Ns != "foo2" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Register(p2, "foo1", addrs2, 60)
|
_, err = db.Register(p2, "foo1", signedPeerRecord2, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Register(p2, "foo2", addrs2, 60)
|
_, err = db.Register(p2, "foo2", signedPeerRecord2, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -398,7 +347,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo1" {
|
if rr.Ns != "foo1" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs2) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord2) {
|
||||||
t.Fatal("expected p2's addrs in registration")
|
t.Fatal("expected p2's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +358,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo2" {
|
if rr.Ns != "foo2" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs2) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord2) {
|
||||||
t.Fatal("expected p2's addrs in registration")
|
t.Fatal("expected p2's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +389,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo1" {
|
if rr.Ns != "foo1" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +400,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo2" {
|
if rr.Ns != "foo2" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,13 +418,9 @@ func TestDBCleanup(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr1, err := ma.NewMultiaddr("/ip4/1.1.1.1/tcp/9999")
|
signedPeerRecord1 := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs1 := [][]byte{addr1.Bytes()}
|
|
||||||
|
|
||||||
_, err = db.Register(p1, "foo1", addrs1, 1)
|
_, err = db.Register(p1, "foo1", signedPeerRecord1, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
dbi "github.com/berty/go-libp2p-rendezvous/db"
|
dbi "github.com/waku-org/go-libp2p-rendezvous/db"
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ func (db *DB) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) prepareDB() error {
|
func (db *DB) prepareDB() error {
|
||||||
_, err := db.db.Exec("CREATE TABLE Registrations (counter INTEGER PRIMARY KEY AUTOINCREMENT, peer VARCHAR(64), ns VARCHAR, expire INTEGER, addrs VARBINARY)")
|
_, err := db.db.Exec("CREATE TABLE Registrations (counter INTEGER PRIMARY KEY AUTOINCREMENT, peer VARCHAR(64), ns VARCHAR, expire INTEGER, signedPeerRecord VARBINARY)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -199,9 +199,8 @@ func (db *DB) prepareStmts() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) Register(p peer.ID, ns string, addrs [][]byte, ttl int) (uint64, error) {
|
func (db *DB) Register(p peer.ID, ns string, signedPeerRecord []byte, ttl int) (uint64, error) {
|
||||||
pid := p.Pretty()
|
pid := p.Pretty()
|
||||||
maddrs := packAddrs(addrs)
|
|
||||||
expire := time.Now().Unix() + int64(ttl)
|
expire := time.Now().Unix() + int64(ttl)
|
||||||
|
|
||||||
tx, err := db.db.Begin()
|
tx, err := db.db.Begin()
|
||||||
@ -219,7 +218,7 @@ func (db *DB) Register(p peer.ID, ns string, addrs [][]byte, ttl int) (uint64, e
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = insertNew.Exec(pid, ns, expire, maddrs)
|
_, err = insertNew.Exec(pid, ns, expire, signedPeerRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -307,12 +306,11 @@ func (db *DB) Discover(ns string, cookie []byte, limit int) ([]dbi.RegistrationR
|
|||||||
rid string
|
rid string
|
||||||
rns string
|
rns string
|
||||||
expire int64
|
expire int64
|
||||||
raddrs []byte
|
signedPeerRecord []byte
|
||||||
addrs [][]byte
|
|
||||||
p peer.ID
|
p peer.ID
|
||||||
)
|
)
|
||||||
|
|
||||||
err = rows.Scan(&counter, &rid, &rns, &expire, &raddrs)
|
err = rows.Scan(&counter, &rid, &rns, &expire, &signedPeerRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("row scan error: %s", err.Error())
|
log.Errorf("row scan error: %s", err.Error())
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -324,14 +322,8 @@ func (db *DB) Discover(ns string, cookie []byte, limit int) ([]dbi.RegistrationR
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
addrs, err := unpackAddrs(raddrs)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("error unpacking address: %s", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
reg.Id = p
|
reg.Id = p
|
||||||
reg.Addrs = addrs
|
reg.SignedPeerRecord = signedPeerRecord
|
||||||
reg.Ttl = int(expire - now)
|
reg.Ttl = int(expire - now)
|
||||||
|
|
||||||
if ns == "" {
|
if ns == "" {
|
||||||
@ -377,47 +369,6 @@ func (db *DB) cleanupExpired() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func packAddrs(addrs [][]byte) []byte {
|
|
||||||
packlen := 0
|
|
||||||
for _, addr := range addrs {
|
|
||||||
packlen = packlen + 2 + len(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
packed := make([]byte, packlen)
|
|
||||||
buf := packed
|
|
||||||
for _, addr := range addrs {
|
|
||||||
binary.BigEndian.PutUint16(buf, uint16(len(addr)))
|
|
||||||
buf = buf[2:]
|
|
||||||
copy(buf, addr)
|
|
||||||
buf = buf[len(addr):]
|
|
||||||
}
|
|
||||||
|
|
||||||
return packed
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackAddrs(packed []byte) ([][]byte, error) {
|
|
||||||
var addrs [][]byte
|
|
||||||
|
|
||||||
buf := packed
|
|
||||||
for len(buf) > 1 {
|
|
||||||
l := binary.BigEndian.Uint16(buf)
|
|
||||||
buf = buf[2:]
|
|
||||||
if len(buf) < int(l) {
|
|
||||||
return nil, fmt.Errorf("bad packed address: not enough bytes %v %v", packed, buf)
|
|
||||||
}
|
|
||||||
addr := make([]byte, l)
|
|
||||||
copy(addr, buf[:l])
|
|
||||||
buf = buf[l:]
|
|
||||||
addrs = append(addrs, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(buf) > 0 {
|
|
||||||
return nil, fmt.Errorf("bad packed address: unprocessed bytes: %v %v", packed, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
return addrs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// cookie: counter:SHA256(nonce + ns + counter)
|
// cookie: counter:SHA256(nonce + ns + counter)
|
||||||
func packCookie(counter int64, ns string, nonce []byte) []byte {
|
func packCookie(counter int64, ns string, nonce []byte) []byte {
|
||||||
cbits := make([]byte, 8)
|
cbits := make([]byte, 8)
|
||||||
|
|||||||
@ -8,41 +8,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPackAddrs(t *testing.T) {
|
|
||||||
addrs := make([][]byte, 5)
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
addrs[i] = make([]byte, rand.Intn(256))
|
|
||||||
}
|
|
||||||
|
|
||||||
packed := packAddrs(addrs)
|
|
||||||
unpacked, err := unpackAddrs(packed)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !equalAddrs(addrs, unpacked) {
|
|
||||||
t.Fatal("unpacked addr not equal to original")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func equalAddrs(addrs1, addrs2 [][]byte) bool {
|
|
||||||
if len(addrs1) != len(addrs2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, addr1 := range addrs1 {
|
|
||||||
addr2 := addrs2[i]
|
|
||||||
if !bytes.Equal(addr1, addr2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackCookie(t *testing.T) {
|
func TestPackCookie(t *testing.T) {
|
||||||
nonce := make([]byte, 16)
|
nonce := make([]byte, 16)
|
||||||
_, err := rand.Read(nonce)
|
_, err := rand.Read(nonce)
|
||||||
@ -136,20 +103,11 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr1, err := ma.NewMultiaddr("/ip4/1.1.1.1/tcp/9999")
|
signedPeerRecord1 := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
if err != nil {
|
signedPeerRecord2 := []byte{8, 7, 6, 5, 4, 3, 2, 1}
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs1 := [][]byte{addr1.Bytes()}
|
|
||||||
|
|
||||||
addr2, err := ma.NewMultiaddr("/ip4/2.2.2.2/tcp/9999")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs2 := [][]byte{addr2.Bytes()}
|
|
||||||
|
|
||||||
// register p1 and do discovery
|
// register p1 and do discovery
|
||||||
_, err = db.Register(p1, "foo1", addrs1, 60)
|
_, err = db.Register(p1, "foo1", signedPeerRecord1, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -173,12 +131,12 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p1 {
|
if rr.Id != p1 {
|
||||||
t.Fatal("expected p1 ID in registration")
|
t.Fatal("expected p1 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's signed record in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
// register p2 and do progressive discovery
|
// register p2 and do progressive discovery
|
||||||
_, err = db.Register(p2, "foo1", addrs2, 60)
|
_, err = db.Register(p2, "foo1", signedPeerRecord2, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -202,12 +160,12 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p2 {
|
if rr.Id != p2 {
|
||||||
t.Fatal("expected p2 ID in registration")
|
t.Fatal("expected p2 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs2) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord2) {
|
||||||
t.Fatal("expected p2's addrs in registration")
|
t.Fatal("expected p2's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
// reregister p1 and do progressive discovery
|
// reregister p1 and do progressive discovery
|
||||||
_, err = db.Register(p1, "foo1", addrs1, 60)
|
_, err = db.Register(p1, "foo1", signedPeerRecord1, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -231,8 +189,8 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p1 {
|
if rr.Id != p1 {
|
||||||
t.Fatal("expected p1 ID in registration")
|
t.Fatal("expected p1 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's signed record in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
// do a full discovery
|
// do a full discovery
|
||||||
@ -247,7 +205,7 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p2 {
|
if rr.Id != p2 {
|
||||||
t.Fatal("expected p2 ID in registration")
|
t.Fatal("expected p2 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs2) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord2) {
|
||||||
t.Fatal("expected p2's addrs in registration")
|
t.Fatal("expected p2's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,8 +213,8 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p1 {
|
if rr.Id != p1 {
|
||||||
t.Fatal("expected p1 ID in registration")
|
t.Fatal("expected p1 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's signed record in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
// unregister p2 and redo discovery
|
// unregister p2 and redo discovery
|
||||||
@ -284,8 +242,8 @@ func TestDBRegistrationAndDiscovery(t *testing.T) {
|
|||||||
if rr.Id != p1 {
|
if rr.Id != p1 {
|
||||||
t.Fatal("expected p1 ID in registration")
|
t.Fatal("expected p1 ID in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's signed record in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
db.Close()
|
db.Close()
|
||||||
@ -307,24 +265,15 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr1, err := ma.NewMultiaddr("/ip4/1.1.1.1/tcp/9999")
|
signedPeerRecord1 := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
if err != nil {
|
signedPeerRecord2 := []byte{8, 7, 6, 5, 4, 3, 2, 1}
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs1 := [][]byte{addr1.Bytes()}
|
|
||||||
|
|
||||||
addr2, err := ma.NewMultiaddr("/ip4/2.2.2.2/tcp/9999")
|
_, err = db.Register(p1, "foo1", signedPeerRecord1, 60)
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs2 := [][]byte{addr2.Bytes()}
|
|
||||||
|
|
||||||
_, err = db.Register(p1, "foo1", addrs1, 60)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Register(p1, "foo2", addrs1, 60)
|
_, err = db.Register(p1, "foo2", signedPeerRecord1, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -351,8 +300,8 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo1" {
|
if rr.Ns != "foo1" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's signed record in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
rr = rrs[1]
|
rr = rrs[1]
|
||||||
@ -362,16 +311,16 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo2" {
|
if rr.Ns != "foo2" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's signed record in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Register(p2, "foo1", addrs2, 60)
|
_, err = db.Register(p2, "foo1", signedPeerRecord2, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Register(p2, "foo2", addrs2, 60)
|
_, err = db.Register(p2, "foo2", signedPeerRecord2, 60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -398,7 +347,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo1" {
|
if rr.Ns != "foo1" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs2) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord2) {
|
||||||
t.Fatal("expected p2's addrs in registration")
|
t.Fatal("expected p2's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +358,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo2" {
|
if rr.Ns != "foo2" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs2) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord2) {
|
||||||
t.Fatal("expected p2's addrs in registration")
|
t.Fatal("expected p2's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +389,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo1" {
|
if rr.Ns != "foo1" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +400,7 @@ func TestDBRegistrationAndDiscoveryMultipleNS(t *testing.T) {
|
|||||||
if rr.Ns != "foo2" {
|
if rr.Ns != "foo2" {
|
||||||
t.Fatal("expected namespace foo1 in registration")
|
t.Fatal("expected namespace foo1 in registration")
|
||||||
}
|
}
|
||||||
if !equalAddrs(rr.Addrs, addrs1) {
|
if !bytes.Equal(rr.SignedPeerRecord, signedPeerRecord1) {
|
||||||
t.Fatal("expected p1's addrs in registration")
|
t.Fatal("expected p1's addrs in registration")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,13 +418,9 @@ func TestDBCleanup(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr1, err := ma.NewMultiaddr("/ip4/1.1.1.1/tcp/9999")
|
signedPeerRecord1 := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
addrs1 := [][]byte{addr1.Bytes()}
|
|
||||||
|
|
||||||
_, err = db.Register(p1, "foo1", addrs1, 1)
|
_, err = db.Register(p1, "foo1", signedPeerRecord1, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,12 +21,12 @@ type rendezvousDiscovery struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type discoveryCache struct {
|
type discoveryCache struct {
|
||||||
recs map[peer.ID]*record
|
recs map[peer.ID]*peerRecord
|
||||||
cookie []byte
|
cookie []byte
|
||||||
mux sync.Mutex
|
mux sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type record struct {
|
type peerRecord struct {
|
||||||
peer peer.AddrInfo
|
peer peer.AddrInfo
|
||||||
expire int64
|
expire int64
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ func (c *rendezvousDiscovery) FindPeers(ctx context.Context, ns string, opts ...
|
|||||||
c.peerCacheMux.Lock()
|
c.peerCacheMux.Lock()
|
||||||
cache, ok = c.peerCache[ns]
|
cache, ok = c.peerCache[ns]
|
||||||
if !ok {
|
if !ok {
|
||||||
cache = &discoveryCache{recs: make(map[peer.ID]*record)}
|
cache = &discoveryCache{recs: make(map[peer.ID]*peerRecord)}
|
||||||
c.peerCache[ns] = cache
|
c.peerCache[ns] = cache
|
||||||
}
|
}
|
||||||
c.peerCacheMux.Unlock()
|
c.peerCacheMux.Unlock()
|
||||||
@ -114,7 +114,7 @@ func (c *rendezvousDiscovery) FindPeers(ctx context.Context, ns string, opts ...
|
|||||||
var newCookie []byte
|
var newCookie []byte
|
||||||
if regs, newCookie, err = c.rp.Discover(ctx, ns, limit, cookie); err == nil {
|
if regs, newCookie, err = c.rp.Discover(ctx, ns, limit, cookie); err == nil {
|
||||||
for _, reg := range regs {
|
for _, reg := range regs {
|
||||||
rec := &record{peer: reg.Peer, expire: int64(reg.Ttl) + currentTime}
|
rec := &peerRecord{peer: reg.Peer, expire: int64(reg.Ttl) + currentTime}
|
||||||
cache.recs[rec.peer.ID] = rec
|
cache.recs[rec.peer.ID] = rec
|
||||||
}
|
}
|
||||||
cache.cookie = newCookie
|
cache.cookie = newCookie
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
//go:generate protoc --proto_path=pb/ --gofast_opt="Mrendezvous.proto=.;rendezvous_pb" --gofast_out=./pb ./pb/rendezvous.proto
|
|
||||||
package rendezvous
|
|
||||||
87
go.mod
87
go.mod
@ -1,62 +1,81 @@
|
|||||||
module github.com/berty/go-libp2p-rendezvous
|
module github.com/waku-org/go-libp2p-rendezvous
|
||||||
|
|
||||||
go 1.18
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gogo/protobuf v1.3.2
|
|
||||||
github.com/golang/protobuf v1.5.2
|
|
||||||
github.com/google/uuid v1.3.0
|
|
||||||
github.com/ipfs/go-log/v2 v2.5.1
|
github.com/ipfs/go-log/v2 v2.5.1
|
||||||
github.com/libp2p/go-libp2p v0.23.3
|
github.com/libp2p/go-libp2p v0.27.3
|
||||||
|
github.com/libp2p/go-msgio v0.3.0
|
||||||
github.com/mattn/go-sqlite3 v1.14.16
|
github.com/mattn/go-sqlite3 v1.14.16
|
||||||
github.com/multiformats/go-multiaddr v0.7.0
|
github.com/multiformats/go-multiaddr v0.9.0
|
||||||
github.com/mutecomm/go-sqlcipher/v4 v4.4.2
|
github.com/mutecomm/go-sqlcipher/v4 v4.4.2
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.2
|
||||||
|
google.golang.org/protobuf v1.30.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
||||||
|
github.com/flynn/noise v1.0.0 // indirect
|
||||||
|
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||||
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/google/gopacket v1.1.19 // indirect
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
github.com/huin/goupnp v1.0.3 // indirect
|
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect
|
||||||
github.com/ipfs/go-cid v0.3.2 // indirect
|
github.com/huin/goupnp v1.1.0 // indirect
|
||||||
|
github.com/ipfs/go-cid v0.4.1 // indirect
|
||||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.1.1 // indirect
|
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
|
||||||
github.com/koron/go-ssdp v0.0.3 // indirect
|
github.com/klauspost/compress v1.16.4 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||||
|
github.com/koron/go-ssdp v0.0.4 // indirect
|
||||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||||
github.com/libp2p/go-cidranger v1.1.0 // indirect
|
github.com/libp2p/go-cidranger v1.1.0 // indirect
|
||||||
github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect
|
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
|
||||||
github.com/libp2p/go-msgio v0.2.0 // indirect
|
|
||||||
github.com/libp2p/go-nat v0.1.0 // indirect
|
github.com/libp2p/go-nat v0.1.0 // indirect
|
||||||
github.com/libp2p/go-netroute v0.2.0 // indirect
|
github.com/libp2p/go-netroute v0.2.1 // indirect
|
||||||
github.com/libp2p/go-openssl v0.1.0 // indirect
|
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mattn/go-pointer v0.0.1 // indirect
|
github.com/miekg/dns v1.1.53 // indirect
|
||||||
github.com/miekg/dns v1.1.50 // indirect
|
|
||||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
github.com/multiformats/go-base32 v0.1.0 // indirect
|
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||||
github.com/multiformats/go-base36 v0.1.0 // indirect
|
github.com/multiformats/go-base36 v0.2.0 // indirect
|
||||||
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
|
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
|
||||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
|
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
|
||||||
github.com/multiformats/go-multibase v0.1.1 // indirect
|
github.com/multiformats/go-multibase v0.2.0 // indirect
|
||||||
github.com/multiformats/go-multicodec v0.6.0 // indirect
|
github.com/multiformats/go-multicodec v0.8.1 // indirect
|
||||||
github.com/multiformats/go-multihash v0.2.1 // indirect
|
github.com/multiformats/go-multihash v0.2.1 // indirect
|
||||||
github.com/multiformats/go-multistream v0.3.3 // indirect
|
github.com/multiformats/go-multistream v0.4.1 // indirect
|
||||||
github.com/multiformats/go-varint v0.0.6 // indirect
|
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||||
|
github.com/onsi/ginkgo/v2 v2.9.2 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||||
|
github.com/prometheus/client_model v0.3.0 // indirect
|
||||||
|
github.com/prometheus/common v0.42.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.9.0 // indirect
|
||||||
|
github.com/quic-go/qpack v0.4.0 // indirect
|
||||||
|
github.com/quic-go/qtls-go1-19 v0.3.2 // indirect
|
||||||
|
github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.33.0 // indirect
|
||||||
|
github.com/quic-go/webtransport-go v0.5.2 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
go.uber.org/atomic v1.10.0 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
go.uber.org/multierr v1.8.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.23.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
|
golang.org/x/crypto v0.7.0 // indirect
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
|
||||||
golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 // indirect
|
golang.org/x/mod v0.10.0 // indirect
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
golang.org/x/net v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
|
golang.org/x/sync v0.1.0 // indirect
|
||||||
golang.org/x/tools v0.1.12 // indirect
|
golang.org/x/sys v0.7.0 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
golang.org/x/text v0.8.0 // indirect
|
||||||
|
golang.org/x/tools v0.7.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
lukechampine.com/blake3 v1.1.7 // indirect
|
lukechampine.com/blake3 v1.1.7 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
369
go.sum
generated
369
go.sum
generated
@ -1,44 +1,91 @@
|
|||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
|
||||||
|
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||||
|
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||||
|
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||||
|
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||||
|
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||||
|
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||||
github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA=
|
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/coreos/go-systemd/v22 v22.4.0 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU=
|
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||||
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d h1:t5Wuyh53qYyg9eqn4BbnlIT+vmhyww0TatL+zT3uWgI=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
|
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
|
||||||
|
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U=
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4=
|
github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4=
|
||||||
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
|
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
|
||||||
|
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||||
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||||
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
|
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||||
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4=
|
||||||
|
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
|
||||||
|
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||||
|
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||||
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
|
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
|
||||||
github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ=
|
github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU=
|
||||||
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
|
github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
|
||||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||||
github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc=
|
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
|
||||||
github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw=
|
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
|
||||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||||
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
||||||
@ -46,19 +93,25 @@ github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOL
|
|||||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
|
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
|
||||||
|
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo=
|
github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU=
|
||||||
|
github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0=
|
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||||
github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||||
github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
|
github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
|
||||||
github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8=
|
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
|
||||||
github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA=
|
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||||
@ -66,192 +119,298 @@ github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QT
|
|||||||
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
|
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
|
||||||
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
|
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
|
||||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||||
github.com/libp2p/go-libp2p v0.23.3 h1:/n3i0VtJF0iZ9YMUxl/teOY3h+M8NfgaCjOSYr9D+uI=
|
github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs=
|
||||||
github.com/libp2p/go-libp2p v0.23.3/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI=
|
github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE=
|
||||||
github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw=
|
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
|
||||||
github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI=
|
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
|
||||||
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
|
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
|
||||||
github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU=
|
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
|
||||||
github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY=
|
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
|
||||||
github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg=
|
github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg=
|
||||||
github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM=
|
github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM=
|
||||||
github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk=
|
github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk=
|
||||||
github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE=
|
github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU=
|
||||||
github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI=
|
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
|
||||||
github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo=
|
|
||||||
github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc=
|
|
||||||
github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560=
|
github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560=
|
||||||
github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k=
|
github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k=
|
||||||
github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ=
|
github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ=
|
||||||
github.com/lucas-clemente/quic-go v0.29.1 h1:Z+WMJ++qMLhvpFkRZA+jl3BTxUjm415YBmWanXB8zP0=
|
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||||
github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM=
|
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU=
|
|
||||||
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk=
|
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
|
|
||||||
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
|
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
|
||||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||||
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc=
|
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc=
|
||||||
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc=
|
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc=
|
||||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||||
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||||
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
|
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
|
||||||
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
||||||
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
|
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||||
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
|
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||||
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
|
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
|
||||||
github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
|
github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
|
||||||
github.com/multiformats/go-multiaddr v0.7.0 h1:gskHcdaCyPtp9XskVwtvEeQOG465sCohbQIirSyqxrc=
|
github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ=
|
||||||
github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs=
|
github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0=
|
||||||
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
|
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
|
||||||
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
|
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
|
||||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
|
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
|
||||||
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
|
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
|
||||||
github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI=
|
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||||
github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8=
|
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
||||||
github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE=
|
github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8=
|
||||||
github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw=
|
github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
|
||||||
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
||||||
github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108=
|
github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108=
|
||||||
github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc=
|
github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc=
|
||||||
github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o=
|
github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo=
|
||||||
github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg=
|
github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q=
|
||||||
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||||
github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY=
|
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
||||||
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||||
github.com/mutecomm/go-sqlcipher/v4 v4.4.2 h1:eM10bFtI4UvibIsKr10/QT7Yfz+NADfjZYh0GKrXUNc=
|
github.com/mutecomm/go-sqlcipher/v4 v4.4.2 h1:eM10bFtI4UvibIsKr10/QT7Yfz+NADfjZYh0GKrXUNc=
|
||||||
github.com/mutecomm/go-sqlcipher/v4 v4.4.2/go.mod h1:mF2UmIpBnzFeBdu/ypTDb/LdbS0nk0dfSN1WUsWTjMA=
|
github.com/mutecomm/go-sqlcipher/v4 v4.4.2/go.mod h1:mF2UmIpBnzFeBdu/ypTDb/LdbS0nk0dfSN1WUsWTjMA=
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
|
||||||
|
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
|
||||||
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
|
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
|
||||||
|
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
|
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
|
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||||
|
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||||
|
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
|
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||||
|
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||||
|
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||||
|
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||||
|
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||||
|
github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U=
|
||||||
|
github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
|
||||||
|
github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E=
|
||||||
|
github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
|
||||||
|
github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0=
|
||||||
|
github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA=
|
||||||
|
github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk=
|
||||||
|
github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU=
|
||||||
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
||||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||||
|
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||||
|
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||||
|
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||||
|
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||||
|
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
|
||||||
|
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
|
||||||
|
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
|
||||||
|
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
|
||||||
|
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
|
||||||
|
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
|
||||||
|
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
|
||||||
|
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||||
|
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
|
||||||
|
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
|
||||||
|
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
|
||||||
|
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
|
||||||
|
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||||
|
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||||
|
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||||
|
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||||
|
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||||
|
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||||
|
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
|
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
|
go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8=
|
||||||
|
go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY=
|
||||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||||
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
|
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||||
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||||
|
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||||
|
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||||
|
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||||
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
|
||||||
|
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
|
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 h1:KafLifaRFIuSJ5C+7CyFJOF9haxKNC1CEIDk8GX6X0k=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||||
|
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||||
|
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
|
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
|
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||||
|
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
|
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||||
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||||
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
||||||
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
||||||
|
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
|
||||||
|
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||||
|
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||||
|
|||||||
3
pb/generate.go
Normal file
3
pb/generate.go
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package rendezvous_pb
|
||||||
|
|
||||||
|
//go:generate protoc -I. --proto_path=./ --go_opt=paths=source_relative --go_opt=Mrendezvous.proto=github.com/waku-org/go-libp2p-rendezvous/rendezvous_pb --go_out=. ./rendezvous.proto
|
||||||
3674
pb/rendezvous.pb.go
generated
3674
pb/rendezvous.pb.go
generated
File diff suppressed because it is too large
Load Diff
@ -9,15 +9,12 @@ message Message {
|
|||||||
UNREGISTER = 2;
|
UNREGISTER = 2;
|
||||||
DISCOVER = 3;
|
DISCOVER = 3;
|
||||||
DISCOVER_RESPONSE = 4;
|
DISCOVER_RESPONSE = 4;
|
||||||
|
|
||||||
DISCOVER_SUBSCRIBE = 100;
|
|
||||||
DISCOVER_SUBSCRIBE_RESPONSE = 101;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ResponseStatus {
|
enum ResponseStatus {
|
||||||
OK = 0;
|
OK = 0;
|
||||||
E_INVALID_NAMESPACE = 100;
|
E_INVALID_NAMESPACE = 100;
|
||||||
E_INVALID_PEER_INFO = 101;
|
E_INVALID_SIGNED_PEER_RECORD = 101;
|
||||||
E_INVALID_TTL = 102;
|
E_INVALID_TTL = 102;
|
||||||
E_INVALID_COOKIE = 103;
|
E_INVALID_COOKIE = 103;
|
||||||
E_NOT_AUTHORIZED = 200;
|
E_NOT_AUTHORIZED = 200;
|
||||||
@ -25,31 +22,26 @@ message Message {
|
|||||||
E_UNAVAILABLE = 400;
|
E_UNAVAILABLE = 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PeerInfo {
|
|
||||||
bytes id = 1;
|
|
||||||
repeated bytes addrs = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Register {
|
message Register {
|
||||||
string ns = 1;
|
string ns = 1;
|
||||||
PeerInfo peer = 2;
|
bytes signedPeerRecord = 2;
|
||||||
int64 ttl = 3; // in seconds
|
uint64 ttl = 3; // in seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
message RegisterResponse {
|
message RegisterResponse {
|
||||||
ResponseStatus status = 1;
|
ResponseStatus status = 1;
|
||||||
string statusText = 2;
|
string statusText = 2;
|
||||||
int64 ttl = 3;
|
uint64 ttl = 3; // in seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
message Unregister {
|
message Unregister {
|
||||||
string ns = 1;
|
string ns = 1;
|
||||||
bytes id = 2;
|
// bytes id = 2; deprecated as per https://github.com/libp2p/specs/issues/335
|
||||||
}
|
}
|
||||||
|
|
||||||
message Discover {
|
message Discover {
|
||||||
string ns = 1;
|
string ns = 1;
|
||||||
int64 limit = 2;
|
uint64 limit = 2;
|
||||||
bytes cookie = 3;
|
bytes cookie = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,32 +52,10 @@ message Message {
|
|||||||
string statusText = 4;
|
string statusText = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DiscoverSubscribe {
|
|
||||||
repeated string supported_subscription_types = 1;
|
|
||||||
string ns = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message DiscoverSubscribeResponse {
|
|
||||||
string subscription_type = 1;
|
|
||||||
string subscription_details = 2;
|
|
||||||
ResponseStatus status = 3;
|
|
||||||
string statusText = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageType type = 1;
|
MessageType type = 1;
|
||||||
Register register = 2;
|
Register register = 2;
|
||||||
RegisterResponse registerResponse = 3;
|
RegisterResponse registerResponse = 3;
|
||||||
Unregister unregister = 4;
|
Unregister unregister = 4;
|
||||||
Discover discover = 5;
|
Discover discover = 5;
|
||||||
DiscoverResponse discoverResponse = 6;
|
DiscoverResponse discoverResponse = 6;
|
||||||
|
|
||||||
DiscoverSubscribe discoverSubscribe = 100;
|
|
||||||
DiscoverSubscribeResponse discoverSubscribeResponse = 101;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RegistrationRecord{
|
|
||||||
string id = 1;
|
|
||||||
repeated bytes addrs = 2;
|
|
||||||
string ns = 3;
|
|
||||||
int64 ttl = 4;
|
|
||||||
}
|
}
|
||||||
|
|||||||
107
proto.go
107
proto.go
@ -3,14 +3,16 @@ package rendezvous
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
db "github.com/berty/go-libp2p-rendezvous/db"
|
db "github.com/waku-org/go-libp2p-rendezvous/db"
|
||||||
pb "github.com/berty/go-libp2p-rendezvous/pb"
|
pb "github.com/waku-org/go-libp2p-rendezvous/pb"
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
crypto "github.com/libp2p/go-libp2p/core/crypto"
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
"github.com/libp2p/go-libp2p/core/protocol"
|
"github.com/libp2p/go-libp2p/core/protocol"
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
"github.com/libp2p/go-libp2p/core/record"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.Logger("rendezvous")
|
var log = logging.Logger("rendezvous")
|
||||||
@ -30,11 +32,11 @@ func (e RendezvousError) Error() string {
|
|||||||
return fmt.Sprintf("Rendezvous error: %s (%s)", e.Text, e.Status.String())
|
return fmt.Sprintf("Rendezvous error: %s (%s)", e.Text, e.Status.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegisterMessage(ns string, pi peer.AddrInfo, ttl int) *pb.Message {
|
func NewRegisterMessage(privKey crypto.PrivKey, ns string, pi peer.AddrInfo, ttl int) (*pb.Message, error) {
|
||||||
return newRegisterMessage(ns, pi, ttl)
|
return newRegisterMessage(privKey, ns, pi, ttl)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRegisterMessage(ns string, pi peer.AddrInfo, ttl int) *pb.Message {
|
func newRegisterMessage(privKey crypto.PrivKey, ns string, pi peer.AddrInfo, ttl int) (*pb.Message, error) {
|
||||||
msg := new(pb.Message)
|
msg := new(pb.Message)
|
||||||
msg.Type = pb.Message_REGISTER
|
msg.Type = pb.Message_REGISTER
|
||||||
msg.Register = new(pb.Message_Register)
|
msg.Register = new(pb.Message_Register)
|
||||||
@ -43,15 +45,28 @@ func newRegisterMessage(ns string, pi peer.AddrInfo, ttl int) *pb.Message {
|
|||||||
}
|
}
|
||||||
if ttl > 0 {
|
if ttl > 0 {
|
||||||
ttl64 := int64(ttl)
|
ttl64 := int64(ttl)
|
||||||
msg.Register.Ttl = ttl64
|
msg.Register.Ttl = uint64(ttl64)
|
||||||
}
|
}
|
||||||
msg.Register.Peer = new(pb.Message_PeerInfo)
|
|
||||||
msg.Register.Peer.Id = []byte(pi.ID)
|
peerInfo := &peer.PeerRecord{
|
||||||
msg.Register.Peer.Addrs = make([][]byte, len(pi.Addrs))
|
PeerID: pi.ID,
|
||||||
for i, addr := range pi.Addrs {
|
Addrs: pi.Addrs,
|
||||||
msg.Register.Peer.Addrs[i] = addr.Bytes()
|
Seq: uint64(time.Now().Unix()),
|
||||||
}
|
}
|
||||||
return msg
|
|
||||||
|
envelope, err := record.Seal(peerInfo, privKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
envPayload, err := envelope.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Register.SignedPeerRecord = envPayload
|
||||||
|
|
||||||
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUnregisterMessage(ns string, pid peer.ID) *pb.Message {
|
func newUnregisterMessage(ns string, pid peer.ID) *pb.Message {
|
||||||
@ -61,7 +76,6 @@ func newUnregisterMessage(ns string, pid peer.ID) *pb.Message {
|
|||||||
if ns != "" {
|
if ns != "" {
|
||||||
msg.Unregister.Ns = ns
|
msg.Unregister.Ns = ns
|
||||||
}
|
}
|
||||||
msg.Unregister.Id = []byte(pid)
|
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,42 +91,37 @@ func newDiscoverMessage(ns string, limit int, cookie []byte) *pb.Message {
|
|||||||
msg.Discover.Ns = ns
|
msg.Discover.Ns = ns
|
||||||
}
|
}
|
||||||
if limit > 0 {
|
if limit > 0 {
|
||||||
limit64 := int64(limit)
|
limitu64 := uint64(limit)
|
||||||
msg.Discover.Limit = limit64
|
msg.Discover.Limit = limitu64
|
||||||
}
|
}
|
||||||
if cookie != nil {
|
if cookie != nil {
|
||||||
msg.Discover.Cookie = cookie
|
msg.Discover.Cookie = cookie
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
func pbToPeerRecord(envelopeBytes []byte) (peer.AddrInfo, error) {
|
||||||
func pbToPeerInfo(p *pb.Message_PeerInfo) (peer.AddrInfo, error) {
|
envelope, rec, err := record.ConsumeEnvelope(envelopeBytes, peer.PeerRecordEnvelopeDomain)
|
||||||
if p == nil {
|
|
||||||
return peer.AddrInfo{}, errors.New("missing peer info")
|
|
||||||
}
|
|
||||||
|
|
||||||
id, err := peer.IDFromBytes(p.Id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return peer.AddrInfo{}, err
|
return peer.AddrInfo{}, err
|
||||||
}
|
}
|
||||||
addrs := make([]ma.Multiaddr, 0, len(p.Addrs))
|
|
||||||
for _, bs := range p.Addrs {
|
peerRec, ok := rec.(*peer.PeerRecord)
|
||||||
addr, err := ma.NewMultiaddrBytes(bs)
|
if !ok {
|
||||||
if err != nil {
|
return peer.AddrInfo{}, errors.New("invalid peer record")
|
||||||
log.Errorf("Error parsing multiaddr: %s", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
addrs = append(addrs, addr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return peer.AddrInfo{ID: id, Addrs: addrs}, nil
|
if !peerRec.PeerID.MatchesPublicKey(envelope.PublicKey) {
|
||||||
|
return peer.AddrInfo{}, errors.New("signing key does not match peer record")
|
||||||
|
}
|
||||||
|
|
||||||
|
return peer.AddrInfo{ID: peerRec.PeerID, Addrs: peerRec.Addrs}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRegisterResponse(ttl int) *pb.Message_RegisterResponse {
|
func newRegisterResponse(ttl int) *pb.Message_RegisterResponse {
|
||||||
ttl64 := int64(ttl)
|
ttlu64 := uint64(ttl)
|
||||||
r := new(pb.Message_RegisterResponse)
|
r := new(pb.Message_RegisterResponse)
|
||||||
r.Status = pb.Message_OK
|
r.Status = pb.Message_OK
|
||||||
r.Ttl = ttl64
|
r.Ttl = ttlu64
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,10 +141,8 @@ func newDiscoverResponse(regs []db.RegistrationRecord, cookie []byte) *pb.Messag
|
|||||||
rreg := new(pb.Message_Register)
|
rreg := new(pb.Message_Register)
|
||||||
rns := reg.Ns
|
rns := reg.Ns
|
||||||
rreg.Ns = rns
|
rreg.Ns = rns
|
||||||
rreg.Peer = new(pb.Message_PeerInfo)
|
rreg.SignedPeerRecord = reg.SignedPeerRecord
|
||||||
rreg.Peer.Id = []byte(reg.Id)
|
rttl := uint64(reg.Ttl)
|
||||||
rreg.Peer.Addrs = reg.Addrs
|
|
||||||
rttl := int64(reg.Ttl)
|
|
||||||
rreg.Ttl = rttl
|
rreg.Ttl = rttl
|
||||||
rregs[i] = rreg
|
rregs[i] = rreg
|
||||||
}
|
}
|
||||||
@ -152,27 +159,3 @@ func newDiscoverResponseError(status pb.Message_ResponseStatus, text string) *pb
|
|||||||
r.StatusText = text
|
r.StatusText = text
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDiscoverSubscribeResponse(subscriptionType string, subscriptionDetails string) *pb.Message_DiscoverSubscribeResponse {
|
|
||||||
r := new(pb.Message_DiscoverSubscribeResponse)
|
|
||||||
r.Status = pb.Message_OK
|
|
||||||
|
|
||||||
r.SubscriptionDetails = subscriptionDetails
|
|
||||||
r.SubscriptionType = subscriptionType
|
|
||||||
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDiscoverSubscribeResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_DiscoverSubscribeResponse {
|
|
||||||
r := new(pb.Message_DiscoverSubscribeResponse)
|
|
||||||
r.Status = status
|
|
||||||
r.StatusText = text
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDiscoverSubscribeMessage(ns string, supportedSubscriptionTypes []string) *pb.Message_DiscoverSubscribe {
|
|
||||||
r := new(pb.Message_DiscoverSubscribe)
|
|
||||||
r.Ns = ns
|
|
||||||
r.SupportedSubscriptionTypes = supportedSubscriptionTypes
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|||||||
105
svc.go
105
svc.go
@ -1,15 +1,13 @@
|
|||||||
package rendezvous
|
package rendezvous
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
ggio "github.com/gogo/protobuf/io"
|
|
||||||
"github.com/libp2p/go-libp2p/core/host"
|
"github.com/libp2p/go-libp2p/core/host"
|
||||||
inet "github.com/libp2p/go-libp2p/core/network"
|
inet "github.com/libp2p/go-libp2p/core/network"
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
"github.com/libp2p/go-msgio/pbio"
|
||||||
|
|
||||||
db "github.com/berty/go-libp2p-rendezvous/db"
|
db "github.com/waku-org/go-libp2p-rendezvous/db"
|
||||||
pb "github.com/berty/go-libp2p-rendezvous/pb"
|
pb "github.com/waku-org/go-libp2p-rendezvous/pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -22,11 +20,10 @@ const (
|
|||||||
|
|
||||||
type RendezvousService struct {
|
type RendezvousService struct {
|
||||||
DB db.DB
|
DB db.DB
|
||||||
rzs []RendezvousSync
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRendezvousService(host host.Host, db db.DB, rzs ...RendezvousSync) *RendezvousService {
|
func NewRendezvousService(host host.Host, db db.DB) *RendezvousService {
|
||||||
rz := &RendezvousService{DB: db, rzs: rzs}
|
rz := &RendezvousService{DB: db}
|
||||||
host.SetStreamHandler(RendezvousProto, rz.handleStream)
|
host.SetStreamHandler(RendezvousProto, rz.handleStream)
|
||||||
return rz
|
return rz
|
||||||
}
|
}
|
||||||
@ -37,8 +34,8 @@ func (rz *RendezvousService) handleStream(s inet.Stream) {
|
|||||||
pid := s.Conn().RemotePeer()
|
pid := s.Conn().RemotePeer()
|
||||||
log.Debugf("New stream from %s", pid.Pretty())
|
log.Debugf("New stream from %s", pid.Pretty())
|
||||||
|
|
||||||
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
|
r := pbio.NewDelimitedReader(s, inet.MessageSizeMax)
|
||||||
w := ggio.NewDelimitedWriter(s)
|
w := pbio.NewDelimitedWriter(s)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var req pb.Message
|
var req pb.Message
|
||||||
@ -77,16 +74,6 @@ func (rz *RendezvousService) handleStream(s inet.Stream) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
case pb.Message_DISCOVER_SUBSCRIBE:
|
|
||||||
r := rz.handleDiscoverSubscribe(pid, req.GetDiscoverSubscribe())
|
|
||||||
res.Type = pb.Message_DISCOVER_SUBSCRIBE_RESPONSE
|
|
||||||
res.DiscoverSubscribeResponse = r
|
|
||||||
err = w.WriteMsg(&res)
|
|
||||||
if err != nil {
|
|
||||||
log.Debugf("Error writing response: %s", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Debugf("Unexpected message: %s", t.String())
|
log.Debugf("Unexpected message: %s", t.String())
|
||||||
return
|
return
|
||||||
@ -104,34 +91,30 @@ func (rz *RendezvousService) handleRegister(p peer.ID, m *pb.Message_Register) *
|
|||||||
return newRegisterResponseError(pb.Message_E_INVALID_NAMESPACE, "namespace too long")
|
return newRegisterResponseError(pb.Message_E_INVALID_NAMESPACE, "namespace too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
mpi := m.GetPeer()
|
signedPeerRecord := m.GetSignedPeerRecord()
|
||||||
if mpi == nil {
|
if signedPeerRecord == nil {
|
||||||
return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "missing peer info")
|
return newRegisterResponseError(pb.Message_E_INVALID_SIGNED_PEER_RECORD, "missing signed peer record")
|
||||||
}
|
}
|
||||||
|
|
||||||
mpid := mpi.GetId()
|
peerRecord, err := pbToPeerRecord(signedPeerRecord)
|
||||||
if mpid != nil {
|
|
||||||
mp, err := peer.IDFromBytes(mpid)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "bad peer id")
|
return newRegisterResponseError(pb.Message_E_INVALID_SIGNED_PEER_RECORD, "invalid peer record")
|
||||||
}
|
}
|
||||||
|
|
||||||
if mp != p {
|
if peerRecord.ID != p {
|
||||||
return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "peer id mismatch")
|
return newRegisterResponseError(pb.Message_E_INVALID_SIGNED_PEER_RECORD, "peer id mismatch")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
maddrs := mpi.GetAddrs()
|
if len(peerRecord.Addrs) == 0 {
|
||||||
if len(maddrs) == 0 {
|
return newRegisterResponseError(pb.Message_E_INVALID_SIGNED_PEER_RECORD, "missing peer addresses")
|
||||||
return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "missing peer addresses")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mlen := 0
|
mlen := 0
|
||||||
for _, maddr := range maddrs {
|
for _, maddr := range peerRecord.Addrs {
|
||||||
mlen += len(maddr)
|
mlen += len(maddr.Bytes())
|
||||||
}
|
}
|
||||||
if mlen > MaxPeerAddressLength {
|
if mlen > MaxPeerAddressLength {
|
||||||
return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "peer info too long")
|
return newRegisterResponseError(pb.Message_E_INVALID_SIGNED_PEER_RECORD, "peer info too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note:
|
// Note:
|
||||||
@ -139,7 +122,7 @@ func (rz *RendezvousService) handleRegister(p peer.ID, m *pb.Message_Register) *
|
|||||||
// Perhaps we should though.
|
// Perhaps we should though.
|
||||||
|
|
||||||
mttl := m.GetTtl()
|
mttl := m.GetTtl()
|
||||||
if mttl < 0 || mttl > MaxTTL {
|
if mttl > MaxTTL {
|
||||||
return newRegisterResponseError(pb.Message_E_INVALID_TTL, "bad ttl")
|
return newRegisterResponseError(pb.Message_E_INVALID_TTL, "bad ttl")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +146,7 @@ func (rz *RendezvousService) handleRegister(p peer.ID, m *pb.Message_Register) *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ok, seems like we can register
|
// ok, seems like we can register
|
||||||
counter, err := rz.DB.Register(p, ns, maddrs, ttl)
|
_, err = rz.DB.Register(p, ns, signedPeerRecord, ttl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error registering: %s", err.Error())
|
log.Errorf("Error registering: %s", err.Error())
|
||||||
return newRegisterResponseError(pb.Message_E_INTERNAL_ERROR, "database error")
|
return newRegisterResponseError(pb.Message_E_INTERNAL_ERROR, "database error")
|
||||||
@ -171,28 +154,12 @@ func (rz *RendezvousService) handleRegister(p peer.ID, m *pb.Message_Register) *
|
|||||||
|
|
||||||
log.Infof("registered peer %s %s (%d)", p, ns, ttl)
|
log.Infof("registered peer %s %s (%d)", p, ns, ttl)
|
||||||
|
|
||||||
for _, rzs := range rz.rzs {
|
|
||||||
rzs.Register(p, ns, maddrs, ttl, counter)
|
|
||||||
}
|
|
||||||
|
|
||||||
return newRegisterResponse(ttl)
|
return newRegisterResponse(ttl)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rz *RendezvousService) handleUnregister(p peer.ID, m *pb.Message_Unregister) error {
|
func (rz *RendezvousService) handleUnregister(p peer.ID, m *pb.Message_Unregister) error {
|
||||||
ns := m.GetNs()
|
ns := m.GetNs()
|
||||||
|
|
||||||
mpid := m.GetId()
|
|
||||||
if mpid != nil {
|
|
||||||
mp, err := peer.IDFromBytes(mpid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if mp != p {
|
|
||||||
return fmt.Errorf("peer id mismatch: %s asked to unregister %s", p.Pretty(), mp.Pretty())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := rz.DB.Unregister(p, ns)
|
err := rz.DB.Unregister(p, ns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -200,10 +167,6 @@ func (rz *RendezvousService) handleUnregister(p peer.ID, m *pb.Message_Unregiste
|
|||||||
|
|
||||||
log.Infof("unregistered peer %s %s", p, ns)
|
log.Infof("unregistered peer %s %s", p, ns)
|
||||||
|
|
||||||
for _, rzs := range rz.rzs {
|
|
||||||
rzs.Unregister(p, ns)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +179,7 @@ func (rz *RendezvousService) handleDiscover(p peer.ID, m *pb.Message_Discover) *
|
|||||||
|
|
||||||
limit := MaxDiscoverLimit
|
limit := MaxDiscoverLimit
|
||||||
mlimit := m.GetLimit()
|
mlimit := m.GetLimit()
|
||||||
if mlimit > 0 && mlimit < int64(limit) {
|
if mlimit > 0 && mlimit < uint64(limit) {
|
||||||
limit = int(mlimit)
|
limit = int(mlimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,27 +198,3 @@ func (rz *RendezvousService) handleDiscover(p peer.ID, m *pb.Message_Discover) *
|
|||||||
|
|
||||||
return newDiscoverResponse(regs, cookie)
|
return newDiscoverResponse(regs, cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rz *RendezvousService) handleDiscoverSubscribe(_ peer.ID, m *pb.Message_DiscoverSubscribe) *pb.Message_DiscoverSubscribeResponse {
|
|
||||||
ns := m.GetNs()
|
|
||||||
|
|
||||||
for _, s := range rz.rzs {
|
|
||||||
rzSub, ok := s.(RendezvousSyncSubscribable)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, supportedSubType := range m.GetSupportedSubscriptionTypes() {
|
|
||||||
if rzSub.GetServiceType() == supportedSubType {
|
|
||||||
sub, err := rzSub.Subscribe(ns)
|
|
||||||
if err != nil {
|
|
||||||
return newDiscoverSubscribeResponseError(pb.Message_E_INTERNAL_ERROR, "error while subscribing")
|
|
||||||
}
|
|
||||||
|
|
||||||
return newDiscoverSubscribeResponse(supportedSubType, sub)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newDiscoverSubscribeResponseError(pb.Message_E_INTERNAL_ERROR, "subscription type not found")
|
|
||||||
}
|
|
||||||
|
|||||||
84
svc_test.go
84
svc_test.go
@ -7,16 +7,16 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ggio "github.com/gogo/protobuf/io"
|
|
||||||
"github.com/libp2p/go-libp2p/core/host"
|
"github.com/libp2p/go-libp2p/core/host"
|
||||||
inet "github.com/libp2p/go-libp2p/core/network"
|
inet "github.com/libp2p/go-libp2p/core/network"
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
||||||
|
"github.com/libp2p/go-msgio/pbio"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
db "github.com/berty/go-libp2p-rendezvous/db/sqlite"
|
db "github.com/waku-org/go-libp2p-rendezvous/db/sqlite"
|
||||||
pb "github.com/berty/go-libp2p-rendezvous/pb"
|
pb "github.com/waku-org/go-libp2p-rendezvous/pb"
|
||||||
"github.com/berty/go-libp2p-rendezvous/test_utils"
|
"github.com/waku-org/go-libp2p-rendezvous/test_utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getRendezvousHosts(t *testing.T, ctx context.Context, m mocknet.Mocknet, n int) []host.Host {
|
func getRendezvousHosts(t *testing.T, ctx context.Context, m mocknet.Mocknet, n int) []host.Host {
|
||||||
@ -127,6 +127,16 @@ func checkHostRegistration(t *testing.T, rr Registration, host host.Host) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
|
||||||
|
func RandStringBytes(n int) string {
|
||||||
|
b := make([]byte, n)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = letterBytes[rand.Intn(len(letterBytes))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
func TestSVCErrors(t *testing.T) {
|
func TestSVCErrors(t *testing.T) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -141,51 +151,59 @@ func TestSVCErrors(t *testing.T) {
|
|||||||
defer svc.DB.Close()
|
defer svc.DB.Close()
|
||||||
|
|
||||||
// testable registration errors
|
// testable registration errors
|
||||||
res, err := doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
privKey := hosts[1].Peerstore().PrivKey(hosts[1].ID())
|
||||||
newRegisterMessage("", peer.AddrInfo{}, 0))
|
rm, err := newRegisterMessage(privKey, "", peer.AddrInfo{}, 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
res, err := doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_INVALID_NAMESPACE, res.GetRegisterResponse().GetStatus())
|
require.Equal(t, pb.Message_E_INVALID_NAMESPACE, res.GetRegisterResponse().GetStatus())
|
||||||
|
|
||||||
badns := make([]byte, 2*MaxNamespaceLength)
|
badns := RandStringBytes(2 * MaxNamespaceLength)
|
||||||
rand.Read(badns)
|
rm, err = newRegisterMessage(privKey, badns, peer.AddrInfo{}, 0)
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
require.NoError(t, err)
|
||||||
newRegisterMessage(string(badns), peer.AddrInfo{}, 0))
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_INVALID_NAMESPACE, res.GetRegisterResponse().GetStatus())
|
require.Equal(t, pb.Message_E_INVALID_NAMESPACE, res.GetRegisterResponse().GetStatus())
|
||||||
|
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
rm, err = newRegisterMessage(privKey, "foo", peer.AddrInfo{}, 0)
|
||||||
newRegisterMessage("foo", peer.AddrInfo{}, 0))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_INVALID_PEER_INFO, res.GetRegisterResponse().GetStatus())
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, pb.Message_E_INVALID_SIGNED_PEER_RECORD, res.GetRegisterResponse().GetStatus())
|
||||||
|
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
rm, err = newRegisterMessage(privKey, "foo", peer.AddrInfo{ID: peer.ID("blah")}, 0)
|
||||||
newRegisterMessage("foo", peer.AddrInfo{ID: peer.ID("blah")}, 0))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_INVALID_PEER_INFO, res.GetRegisterResponse().GetStatus())
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, pb.Message_E_INVALID_SIGNED_PEER_RECORD, res.GetRegisterResponse().GetStatus())
|
||||||
|
|
||||||
p, err := peer.Decode("QmVr26fY1tKyspEJBniVhqxQeEjhF78XerGiqWAwraVLQH")
|
p, err := peer.Decode("QmVr26fY1tKyspEJBniVhqxQeEjhF78XerGiqWAwraVLQH")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
rm, err = newRegisterMessage(privKey, "foo", peer.AddrInfo{ID: p}, 0)
|
||||||
newRegisterMessage("foo", peer.AddrInfo{ID: p}, 0))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_INVALID_PEER_INFO, res.GetRegisterResponse().GetStatus())
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
|
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
|
||||||
newRegisterMessage("foo", peer.AddrInfo{ID: hosts[1].ID()}, 0))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_INVALID_PEER_INFO, res.GetRegisterResponse().GetStatus())
|
require.Equal(t, pb.Message_E_INVALID_SIGNED_PEER_RECORD, res.GetRegisterResponse().GetStatus())
|
||||||
|
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
rm, err = newRegisterMessage(privKey, "foo", peer.AddrInfo{ID: hosts[1].ID()}, 0)
|
||||||
newRegisterMessage("foo", peer.AddrInfo{ID: hosts[1].ID(), Addrs: hosts[1].Addrs()}, 2*MaxTTL))
|
require.NoError(t, err)
|
||||||
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, pb.Message_E_INVALID_SIGNED_PEER_RECORD, res.GetRegisterResponse().GetStatus())
|
||||||
|
|
||||||
|
rm, err = newRegisterMessage(privKey, "foo", peer.AddrInfo{ID: hosts[1].ID(), Addrs: hosts[1].Addrs()}, 2*MaxTTL)
|
||||||
|
require.NoError(t, err)
|
||||||
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_INVALID_TTL, res.GetRegisterResponse().GetStatus())
|
require.Equal(t, pb.Message_E_INVALID_TTL, res.GetRegisterResponse().GetStatus())
|
||||||
|
|
||||||
// do MaxRegistrations
|
// do MaxRegistrations
|
||||||
for i := 0; i < MaxRegistrations+1; i++ {
|
for i := 0; i < MaxRegistrations+1; i++ {
|
||||||
ns := fmt.Sprintf("foo%d", i)
|
ns := fmt.Sprintf("foo%d", i)
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
rm, err = newRegisterMessage(privKey, ns, peer.AddrInfo{ID: hosts[1].ID(), Addrs: hosts[1].Addrs()}, 0)
|
||||||
newRegisterMessage(ns, peer.AddrInfo{ID: hosts[1].ID(), Addrs: hosts[1].Addrs()}, 0))
|
require.NoError(t, err)
|
||||||
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -194,14 +212,14 @@ func TestSVCErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// and now fail
|
// and now fail
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
rm, err = newRegisterMessage(privKey, "foo", peer.AddrInfo{ID: hosts[1].ID(), Addrs: hosts[1].Addrs()}, 0)
|
||||||
newRegisterMessage("foo", peer.AddrInfo{ID: hosts[1].ID(), Addrs: hosts[1].Addrs()}, 0))
|
require.NoError(t, err)
|
||||||
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), rm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_NOT_AUTHORIZED, res.GetRegisterResponse().GetStatus())
|
require.Equal(t, pb.Message_E_NOT_AUTHORIZED, res.GetRegisterResponse().GetStatus())
|
||||||
|
|
||||||
// testable discovery errors
|
// testable discovery errors
|
||||||
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(),
|
res, err = doTestRequest(ctx, hosts[1], hosts[0].ID(), newDiscoverMessage(badns, 0, nil))
|
||||||
newDiscoverMessage(string(badns), 0, nil))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pb.Message_E_INVALID_NAMESPACE, res.GetDiscoverResponse().GetStatus())
|
require.Equal(t, pb.Message_E_INVALID_NAMESPACE, res.GetDiscoverResponse().GetStatus())
|
||||||
|
|
||||||
@ -227,8 +245,8 @@ func doTestRequest(ctx context.Context, host host.Host, rp peer.ID, m *pb.Messag
|
|||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
|
r := pbio.NewDelimitedReader(s, inet.MessageSizeMax)
|
||||||
w := ggio.NewDelimitedWriter(s)
|
w := pbio.NewDelimitedWriter(s)
|
||||||
|
|
||||||
err = w.WriteMsg(m)
|
err = w.WriteMsg(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
package rendezvous
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RendezvousSync interface {
|
|
||||||
Register(p peer.ID, ns string, addrs [][]byte, ttl int, counter uint64)
|
|
||||||
Unregister(p peer.ID, ns string)
|
|
||||||
}
|
|
||||||
|
|
||||||
type RendezvousSyncSubscribable interface {
|
|
||||||
Subscribe(ns string) (syncDetails string, err error)
|
|
||||||
GetServiceType() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type RendezvousSyncClient interface {
|
|
||||||
Subscribe(ctx context.Context, syncDetails string) (<-chan *Registration, error)
|
|
||||||
GetServiceType() string
|
|
||||||
}
|
|
||||||
@ -1,156 +0,0 @@
|
|||||||
package rendezvous
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
ggio "github.com/gogo/protobuf/io"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/libp2p/go-libp2p/core/host"
|
|
||||||
inet "github.com/libp2p/go-libp2p/core/network"
|
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
|
||||||
"github.com/multiformats/go-multiaddr"
|
|
||||||
|
|
||||||
pb "github.com/berty/go-libp2p-rendezvous/pb"
|
|
||||||
)
|
|
||||||
|
|
||||||
type client struct {
|
|
||||||
ctx context.Context
|
|
||||||
host host.Host
|
|
||||||
mu sync.Mutex
|
|
||||||
streams map[string]inet.Stream
|
|
||||||
subscriptions map[string]map[string]chan *Registration
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSyncInMemClient(ctx context.Context, h host.Host) *client {
|
|
||||||
return &client{
|
|
||||||
ctx: ctx,
|
|
||||||
host: h,
|
|
||||||
streams: map[string]inet.Stream{},
|
|
||||||
subscriptions: map[string]map[string]chan *Registration{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) getStreamToPeer(pidStr string) (inet.Stream, error) {
|
|
||||||
c.mu.Lock()
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
|
|
||||||
if stream, ok := c.streams[pidStr]; ok {
|
|
||||||
return stream, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pid, err := peer.Decode(pidStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to decode peer id: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
stream, err := c.host.NewStream(c.ctx, pid, ServiceProto)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to connect to peer: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go c.streamListener(stream)
|
|
||||||
|
|
||||||
return stream, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) streamListener(s inet.Stream) {
|
|
||||||
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
|
|
||||||
record := &pb.RegistrationRecord{}
|
|
||||||
|
|
||||||
for {
|
|
||||||
err := r.ReadMsg(record)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("unable to decode message: %s", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pid, err := peer.Decode(record.Id)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("invalid peer id: %s", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
maddrs := make([]multiaddr.Multiaddr, len(record.Addrs))
|
|
||||||
for i, addrBytes := range record.Addrs {
|
|
||||||
maddrs[i], err = multiaddr.NewMultiaddrBytes(addrBytes)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("invalid multiaddr: %s", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.mu.Lock()
|
|
||||||
subscriptions, ok := c.subscriptions[record.Ns]
|
|
||||||
if ok {
|
|
||||||
for _, subscription := range subscriptions {
|
|
||||||
subscription <- &Registration{
|
|
||||||
Peer: peer.AddrInfo{
|
|
||||||
ID: pid,
|
|
||||||
Addrs: maddrs,
|
|
||||||
},
|
|
||||||
Ns: record.Ns,
|
|
||||||
Ttl: int(record.Ttl),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.mu.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) Subscribe(ctx context.Context, syncDetails string) (<-chan *Registration, error) {
|
|
||||||
ctxUUID, err := uuid.NewRandom()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to generate uuid: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
psDetails := &PubSubSubscriptionDetails{}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(syncDetails), psDetails)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to decode json: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s, err := c.getStreamToPeer(psDetails.PeerID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to get stream to peer: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
w := ggio.NewDelimitedWriter(s)
|
|
||||||
|
|
||||||
err = w.WriteMsg(&pb.Message{
|
|
||||||
Type: pb.Message_DISCOVER_SUBSCRIBE,
|
|
||||||
DiscoverSubscribe: &pb.Message_DiscoverSubscribe{
|
|
||||||
Ns: psDetails.ChannelName,
|
|
||||||
}})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to query server")
|
|
||||||
}
|
|
||||||
|
|
||||||
ch := make(chan *Registration)
|
|
||||||
c.mu.Lock()
|
|
||||||
if _, ok := c.subscriptions[psDetails.ChannelName]; !ok {
|
|
||||||
c.subscriptions[psDetails.ChannelName] = map[string]chan *Registration{}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.subscriptions[psDetails.ChannelName][ctxUUID.String()] = ch
|
|
||||||
c.mu.Unlock()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
<-ctx.Done()
|
|
||||||
c.mu.Lock()
|
|
||||||
delete(c.subscriptions[psDetails.ChannelName], ctxUUID.String())
|
|
||||||
c.mu.Unlock()
|
|
||||||
close(ch)
|
|
||||||
}()
|
|
||||||
|
|
||||||
return ch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) GetServiceType() string {
|
|
||||||
return ServiceType
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ RendezvousSyncClient = (*client)(nil)
|
|
||||||
@ -1,156 +0,0 @@
|
|||||||
package rendezvous
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
pb "github.com/berty/go-libp2p-rendezvous/pb"
|
|
||||||
ggio "github.com/gogo/protobuf/io"
|
|
||||||
"github.com/libp2p/go-libp2p/core/host"
|
|
||||||
inet "github.com/libp2p/go-libp2p/core/network"
|
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
|
||||||
"github.com/libp2p/go-libp2p/core/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
ServiceType = "inmem"
|
|
||||||
ServiceProto = protocol.ID("/rendezvous/sync/inmem/1.0.0")
|
|
||||||
)
|
|
||||||
|
|
||||||
type PubSub struct {
|
|
||||||
mu sync.RWMutex
|
|
||||||
host host.Host
|
|
||||||
topics map[string]*PubSubSubscribers
|
|
||||||
}
|
|
||||||
|
|
||||||
type PubSubSubscribers struct {
|
|
||||||
mu sync.RWMutex
|
|
||||||
subscribers map[peer.ID]ggio.Writer
|
|
||||||
lastAnnouncement *pb.RegistrationRecord
|
|
||||||
}
|
|
||||||
|
|
||||||
type PubSubSubscriptionDetails struct {
|
|
||||||
PeerID string
|
|
||||||
ChannelName string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSyncInMemProvider(host host.Host) (*PubSub, error) {
|
|
||||||
ps := &PubSub{
|
|
||||||
host: host,
|
|
||||||
topics: map[string]*PubSubSubscribers{},
|
|
||||||
}
|
|
||||||
|
|
||||||
ps.Listen()
|
|
||||||
|
|
||||||
return ps, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ps *PubSub) Subscribe(ns string) (syncDetails string, err error) {
|
|
||||||
details, err := json.Marshal(&PubSubSubscriptionDetails{
|
|
||||||
PeerID: ps.host.ID().String(),
|
|
||||||
ChannelName: ns,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("unable to marshal subscription details: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(details), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ps *PubSub) GetServiceType() string {
|
|
||||||
return ServiceType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ps *PubSub) getOrCreateTopic(ns string) *PubSubSubscribers {
|
|
||||||
ps.mu.Lock()
|
|
||||||
defer ps.mu.Unlock()
|
|
||||||
|
|
||||||
if subscribers, ok := ps.topics[ns]; ok {
|
|
||||||
return subscribers
|
|
||||||
}
|
|
||||||
|
|
||||||
ps.topics[ns] = &PubSubSubscribers{
|
|
||||||
subscribers: map[peer.ID]ggio.Writer{},
|
|
||||||
lastAnnouncement: nil,
|
|
||||||
}
|
|
||||||
return ps.topics[ns]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ps *PubSub) Register(pid peer.ID, ns string, addrs [][]byte, ttlAsSeconds int, counter uint64) {
|
|
||||||
topic := ps.getOrCreateTopic(ns)
|
|
||||||
dataToSend := &pb.RegistrationRecord{
|
|
||||||
Id: pid.String(),
|
|
||||||
Addrs: addrs,
|
|
||||||
Ns: ns,
|
|
||||||
Ttl: time.Now().Add(time.Duration(ttlAsSeconds) * time.Second).UnixMilli(),
|
|
||||||
}
|
|
||||||
|
|
||||||
topic.mu.Lock()
|
|
||||||
topic.lastAnnouncement = dataToSend
|
|
||||||
toNotify := topic.subscribers
|
|
||||||
for _, stream := range toNotify {
|
|
||||||
if err := stream.WriteMsg(dataToSend); err != nil {
|
|
||||||
log.Errorf("unable to notify rendezvous data update: %s", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
topic.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ps *PubSub) Unregister(p peer.ID, ns string) {
|
|
||||||
// TODO: unsupported
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ps *PubSub) Listen() {
|
|
||||||
ps.host.SetStreamHandler(ServiceProto, ps.handleStream)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ps *PubSub) handleStream(s inet.Stream) {
|
|
||||||
defer s.Reset()
|
|
||||||
|
|
||||||
r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
|
|
||||||
w := ggio.NewDelimitedWriter(s)
|
|
||||||
|
|
||||||
subscribedTopics := map[string]struct{}{}
|
|
||||||
|
|
||||||
for {
|
|
||||||
var req pb.Message
|
|
||||||
|
|
||||||
err := r.ReadMsg(&req)
|
|
||||||
if err != nil {
|
|
||||||
for ns := range subscribedTopics {
|
|
||||||
topic := ps.getOrCreateTopic(ns)
|
|
||||||
topic.mu.Lock()
|
|
||||||
delete(topic.subscribers, s.Conn().RemotePeer())
|
|
||||||
topic.mu.Unlock()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Type != pb.Message_DISCOVER_SUBSCRIBE {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
topic := ps.getOrCreateTopic(req.DiscoverSubscribe.Ns)
|
|
||||||
topic.mu.Lock()
|
|
||||||
if _, ok := topic.subscribers[s.Conn().RemotePeer()]; ok {
|
|
||||||
topic.mu.Unlock()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
topic.subscribers[s.Conn().RemotePeer()] = w
|
|
||||||
subscribedTopics[req.DiscoverSubscribe.Ns] = struct{}{}
|
|
||||||
lastAnnouncement := topic.lastAnnouncement
|
|
||||||
if lastAnnouncement != nil {
|
|
||||||
if err := w.WriteMsg(lastAnnouncement); err != nil {
|
|
||||||
log.Errorf("unable to write announcement: %s", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
topic.mu.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ RendezvousSync = (*PubSub)(nil)
|
|
||||||
var _ RendezvousSyncSubscribable = (*PubSub)(nil)
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
package rendezvous_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
rendezvous "github.com/berty/go-libp2p-rendezvous"
|
|
||||||
db "github.com/berty/go-libp2p-rendezvous/db/sqlite"
|
|
||||||
"github.com/berty/go-libp2p-rendezvous/test_utils"
|
|
||||||
"github.com/libp2p/go-libp2p/core/host"
|
|
||||||
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
|
||||||
)
|
|
||||||
|
|
||||||
func makeRendezvousService(ctx context.Context, host host.Host, path string, rzs ...rendezvous.RendezvousSync) (*rendezvous.RendezvousService, error) {
|
|
||||||
dbi, err := db.OpenDB(ctx, path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return rendezvous.NewRendezvousService(host, dbi, rzs...), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRendezvousClients(ctx context.Context, t *testing.T, hosts []host.Host) []rendezvous.RendezvousClient {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
clients := make([]rendezvous.RendezvousClient, len(hosts)-1)
|
|
||||||
for i, host := range hosts[1:] {
|
|
||||||
syncClient := rendezvous.NewSyncInMemClient(ctx, host)
|
|
||||||
clients[i] = rendezvous.NewRendezvousClient(host, hosts[0].ID(), syncClient)
|
|
||||||
}
|
|
||||||
return clients
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFlow(t *testing.T) {
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
m := mocknet.New()
|
|
||||||
defer m.Close()
|
|
||||||
|
|
||||||
// Instantiate server and clients
|
|
||||||
hosts := test_utils.GetRendezvousHosts(t, ctx, m, 4)
|
|
||||||
|
|
||||||
inmemPubSubSync, err := rendezvous.NewSyncInMemProvider(hosts[0])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
svc, err := makeRendezvousService(ctx, hosts[0], ":memory:", inmemPubSubSync)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer svc.DB.Close()
|
|
||||||
|
|
||||||
clients := getRendezvousClients(ctx, t, hosts)
|
|
||||||
|
|
||||||
regFound := int64(0)
|
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
|
|
||||||
const announcementCount = 5
|
|
||||||
|
|
||||||
for _, client := range clients[1:] {
|
|
||||||
wg.Add(1)
|
|
||||||
ctx, cancel := context.WithTimeout(ctx, time.Second*5)
|
|
||||||
ch, err := client.DiscoverSubscribe(ctx, "foo1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
regFoundForPeer := 0
|
|
||||||
|
|
||||||
defer cancel()
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
for p := range ch {
|
|
||||||
if test_utils.CheckPeerInfo(t, p, hosts[2], false) == true {
|
|
||||||
regFoundForPeer++
|
|
||||||
atomic.AddInt64(®Found, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if regFoundForPeer == announcementCount {
|
|
||||||
go func() {
|
|
||||||
// this allows more events to be received
|
|
||||||
time.Sleep(time.Millisecond * 500)
|
|
||||||
cancel()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < announcementCount; i++ {
|
|
||||||
_, err = clients[1].Register(ctx, "foo1", rendezvous.DefaultTTL)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
if regFound != int64(len(clients[1:]))*announcementCount {
|
|
||||||
t.Fatalf("expected %d records to be found got %d", int64(len(clients[1:])), regFound)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user