deprecate this repo

This commit is contained in:
Marten Seemann 2022-08-18 18:54:48 +03:00
parent 1185a08119
commit 525c8942a9
122 changed files with 1749 additions and 19430 deletions

View File

@ -1,3 +1,8 @@
# DEPRECATION NOTICE
This package has moved into go-libp2p as a sub-package, `github.com/libp2p/go-libp2p/core`.
# go-libp2p-core
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)

View File

@ -1,50 +1,56 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core.
//
// Package core provides convenient access to foundational, central go-libp2p primitives via type aliases.
package core
import (
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p/core"
)
// Multiaddr aliases the Multiaddr type from github.com/multiformats/go-multiaddr.
//
// Refer to the docs on that type for more info.
type Multiaddr = multiaddr.Multiaddr
// Deprecated: use github.com/libp2p/go-libp2p/core.Multiaddr instead
type Multiaddr = core.Multiaddr
// PeerID aliases peer.ID.
//
// Refer to the docs on that type for more info.
type PeerID = peer.ID
// Deprecated: use github.com/libp2p/go-libp2p/core.PeerID instead
type PeerID = core.PeerID
// ProtocolID aliases protocol.ID.
//
// Refer to the docs on that type for more info.
type ProtocolID = protocol.ID
// Deprecated: use github.com/libp2p/go-libp2p/core.ProtocolID instead
type ProtocolID = core.ProtocolID
// PeerAddrInfo aliases peer.AddrInfo.
//
// Refer to the docs on that type for more info.
type PeerAddrInfo = peer.AddrInfo
// Deprecated: use github.com/libp2p/go-libp2p/core.PeerAddrInfo instead
type PeerAddrInfo = core.PeerAddrInfo
// Host aliases host.Host.
//
// Refer to the docs on that type for more info.
type Host = host.Host
// Deprecated: use github.com/libp2p/go-libp2p/core.Host instead
type Host = core.Host
// Network aliases network.Network.
//
// Refer to the docs on that type for more info.
type Network = network.Network
// Deprecated: use github.com/libp2p/go-libp2p/core.Network instead
type Network = core.Network
// Conn aliases network.Conn.
//
// Refer to the docs on that type for more info.
type Conn = network.Conn
// Deprecated: use github.com/libp2p/go-libp2p/core.Conn instead
type Conn = core.Conn
// Stream aliases network.Stream.
//
// Refer to the docs on that type for more info.
type Stream = network.Stream
// Deprecated: use github.com/libp2p/go-libp2p/core.Stream instead
type Stream = core.Stream

View File

@ -1,37 +1,29 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/canonicallog.
package canonicallog
import (
"fmt"
"math/rand"
"net"
"strings"
logging "github.com/ipfs/go-log/v2"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/canonicallog"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
)
var log = logging.WithSkip(logging.Logger("canonical-log"), 1)
// LogMisbehavingPeer is the canonical way to log a misbehaving peer.
// Protocols should use this to identify a misbehaving peer to allow the end
// user to easily identify these nodes across protocols and libp2p.
// Deprecated: use github.com/libp2p/go-libp2p/core/canonicallog.LogMisbehavingPeer instead
func LogMisbehavingPeer(p peer.ID, peerAddr multiaddr.Multiaddr, component string, err error, msg string) {
log.Warnf("CANONICAL_MISBEHAVING_PEER: peer=%s addr=%s component=%s err=%q msg=%q", p, peerAddr.String(), component, err, msg)
canonicallog.LogMisbehavingPeer(p, peerAddr, component, err, msg)
}
// LogMisbehavingPeerNetAddr is the canonical way to log a misbehaving peer.
// Protocols should use this to identify a misbehaving peer to allow the end
// user to easily identify these nodes across protocols and libp2p.
// Deprecated: use github.com/libp2p/go-libp2p/core/canonicallog.LogMisbehavingPeerNetAddr instead
func LogMisbehavingPeerNetAddr(p peer.ID, peerAddr net.Addr, component string, originalErr error, msg string) {
ma, err := manet.FromNetAddr(peerAddr)
if err != nil {
log.Warnf("CANONICAL_MISBEHAVING_PEER: peer=%s net_addr=%s component=%s err=%q msg=%q", p, peerAddr.String(), component, originalErr, msg)
return
}
LogMisbehavingPeer(p, ma, component, originalErr, msg)
canonicallog.LogMisbehavingPeerNetAddr(p, peerAddr, component, originalErr, msg)
}
// LogPeerStatus logs any useful information about a peer. It takes in a sample
@ -41,16 +33,7 @@ func LogMisbehavingPeerNetAddr(p peer.ID, peerAddr net.Addr, component string, o
// is normal. 10,000 connections from that same IP address is not normal. libp2p
// itself does nothing besides emitting this log. Hook this up to another tool
// like fail2ban to action on the log.
// Deprecated: use github.com/libp2p/go-libp2p/core/canonicallog.LogPeerStatus instead
func LogPeerStatus(sampleRate int, p peer.ID, peerAddr multiaddr.Multiaddr, keyVals ...string) {
if rand.Intn(sampleRate) == 0 {
keyValsStr := strings.Builder{}
for i, kOrV := range keyVals {
if i%2 == 0 {
fmt.Fprintf(&keyValsStr, " %v=", kOrV)
} else {
fmt.Fprintf(&keyValsStr, "%q", kOrV)
}
}
log.Infof("CANONICAL_PEER_STATUS: peer=%s addr=%s sample_rate=%v%s", p, peerAddr.String(), sampleRate, keyValsStr.String())
}
canonicallog.LogPeerStatus(sampleRate, p, peerAddr, keyVals...)
}

View File

@ -1,25 +0,0 @@
package canonicallog
import (
"fmt"
"net"
"testing"
logging "github.com/ipfs/go-log/v2"
"github.com/libp2p/go-libp2p-core/test"
"github.com/multiformats/go-multiaddr"
)
func TestLogs(t *testing.T) {
err := logging.SetLogLevel("canonical-log", "info")
if err != nil {
t.Fatal(err)
}
LogMisbehavingPeer(test.RandPeerIDFatal(t), multiaddr.StringCast("/ip4/1.2.3.4"), "somecomponent", fmt.Errorf("something"), "hi")
netAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 80}
LogMisbehavingPeerNetAddr(test.RandPeerIDFatal(t), netAddr, "somecomponent", fmt.Errorf("something"), "hello \"world\"")
LogPeerStatus(1, test.RandPeerIDFatal(t), multiaddr.StringCast("/ip4/1.2.3.4"), "extra", "info")
}

View File

@ -1,10 +1,7 @@
package connmgr
import (
"io"
"time"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/connmgr"
)
// Decayer is implemented by connection managers supporting decaying tags. A
@ -22,88 +19,35 @@ import (
// Such a pluggable design affords a great deal of flexibility and versatility.
// Behaviours that are straightforward to implement include:
//
// * Decay a tag by -1, or by half its current value, on every tick.
// * Every time a value is bumped, sum it to its current value.
// * Exponentially boost a score with every bump.
// * Sum the incoming score, but keep it within min, max bounds.
// - Decay a tag by -1, or by half its current value, on every tick.
// - Every time a value is bumped, sum it to its current value.
// - Exponentially boost a score with every bump.
// - Sum the incoming score, but keep it within min, max bounds.
//
// Commonly used DecayFns and BumpFns are provided in this package.
type Decayer interface {
io.Closer
// RegisterDecayingTag creates and registers a new decaying tag, if and only
// if a tag with the supplied name doesn't exist yet. Otherwise, an error is
// returned.
//
// The caller provides the interval at which the tag is refreshed, as well
// as the decay function and the bump function. Refer to godocs on DecayFn
// and BumpFn for more info.
RegisterDecayingTag(name string, interval time.Duration, decayFn DecayFn, bumpFn BumpFn) (DecayingTag, error)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.Decayer instead
type Decayer = connmgr.Decayer
// DecayFn applies a decay to the peer's score. The implementation must call
// DecayFn at the interval supplied when registering the tag.
//
// It receives a copy of the decaying value, and returns the score after
// applying the decay, as well as a flag to signal if the tag should be erased.
type DecayFn func(value DecayingValue) (after int, rm bool)
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.DecayFn instead
type DecayFn = connmgr.DecayFn
// BumpFn applies a delta onto an existing score, and returns the new score.
//
// Non-trivial bump functions include exponential boosting, moving averages,
// ceilings, etc.
type BumpFn func(value DecayingValue, delta int) (after int)
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.BumpFn instead
type BumpFn = connmgr.BumpFn
// DecayingTag represents a decaying tag. The tag is a long-lived general
// object, used to operate on tag values for peers.
type DecayingTag interface {
// Name returns the name of the tag.
Name() string
// Interval is the effective interval at which this tag will tick. Upon
// registration, the desired interval may be overwritten depending on the
// decayer's resolution, and this method allows you to obtain the effective
// interval.
Interval() time.Duration
// Bump applies a delta to a tag value, calling its bump function. The bump
// will be applied asynchronously, and a non-nil error indicates a fault
// when queuing.
Bump(peer peer.ID, delta int) error
// Remove removes a decaying tag from a peer. The removal will be applied
// asynchronously, and a non-nil error indicates a fault when queuing.
Remove(peer peer.ID) error
// Close closes a decaying tag. The Decayer will stop tracking this tag,
// and the state of all peers in the Connection Manager holding this tag
// will be updated.
//
// The deletion is performed asynchronously.
//
// Once deleted, a tag should not be used, and further calls to Bump/Remove
// will error.
//
// Duplicate calls to Remove will not return errors, but a failure to queue
// the first actual removal, will (e.g. when the system is backlogged).
Close() error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.DecayingTag instead
type DecayingTag = connmgr.DecayingTag
// DecayingValue represents a value for a decaying tag.
type DecayingValue struct {
// Tag points to the tag this value belongs to.
Tag DecayingTag
// Peer is the peer ID to whom this value is associated.
Peer peer.ID
// Added is the timestamp when this value was added for the first time for
// a tag and a peer.
Added time.Time
// LastVisit is the timestamp of the last visit.
LastVisit time.Time
// Value is the current value of the tag.
Value int
}
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.DecayingValue instead
type DecayingValue = connmgr.DecayingValue

View File

@ -1,11 +1,7 @@
package connmgr
import (
ma "github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p-core/control"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/connmgr"
)
// ConnectionGater can be implemented by a type that supports active
@ -17,25 +13,25 @@ import (
// of a connection being established/upgraded. Specific functions will be called
// throughout the process, to allow you to intercept the connection at that stage.
//
// InterceptPeerDial is called on an imminent outbound peer dial request, prior
// to the addresses of that peer being available/resolved. Blocking connections
// at this stage is typical for blacklisting scenarios.
// InterceptPeerDial is called on an imminent outbound peer dial request, prior
// to the addresses of that peer being available/resolved. Blocking connections
// at this stage is typical for blacklisting scenarios.
//
// InterceptAddrDial is called on an imminent outbound dial to a peer on a
// particular address. Blocking connections at this stage is typical for
// address filtering.
// InterceptAddrDial is called on an imminent outbound dial to a peer on a
// particular address. Blocking connections at this stage is typical for
// address filtering.
//
// InterceptAccept is called as soon as a transport listener receives an
// inbound connection request, before any upgrade takes place. Transports who
// accept already secure and/or multiplexed connections (e.g. possibly QUIC)
// MUST call this method regardless, for correctness/consistency.
// InterceptAccept is called as soon as a transport listener receives an
// inbound connection request, before any upgrade takes place. Transports who
// accept already secure and/or multiplexed connections (e.g. possibly QUIC)
// MUST call this method regardless, for correctness/consistency.
//
// InterceptSecured is called for both inbound and outbound connections,
// after a security handshake has taken place and we've authenticated the peer.
// InterceptSecured is called for both inbound and outbound connections,
// after a security handshake has taken place and we've authenticated the peer.
//
// InterceptUpgraded is called for inbound and outbound connections, after
// libp2p has finished upgrading the connection entirely to a secure,
// multiplexed channel.
// InterceptUpgraded is called for inbound and outbound connections, after
// libp2p has finished upgrading the connection entirely to a secure,
// multiplexed channel.
//
// This interface can be used to implement *strict/active* connection management
// policies, such as hard limiting of connections once a maximum count has been
@ -51,40 +47,5 @@ import (
// as we solidify this feature. The reason why only this method can handle
// DisconnectReasons is that we require stream multiplexing capability to open a
// control protocol stream to transmit the message.
type ConnectionGater interface {
// InterceptPeerDial tests whether we're permitted to Dial the specified peer.
//
// This is called by the network.Network implementation when dialling a peer.
InterceptPeerDial(p peer.ID) (allow bool)
// InterceptAddrDial tests whether we're permitted to dial the specified
// multiaddr for the given peer.
//
// This is called by the network.Network implementation after it has
// resolved the peer's addrs, and prior to dialling each.
InterceptAddrDial(peer.ID, ma.Multiaddr) (allow bool)
// InterceptAccept tests whether an incipient inbound connection is allowed.
//
// This is called by the upgrader, or by the transport directly (e.g. QUIC,
// Bluetooth), straight after it has accepted a connection from its socket.
InterceptAccept(network.ConnMultiaddrs) (allow bool)
// InterceptSecured tests whether a given connection, now authenticated,
// is allowed.
//
// This is called by the upgrader, after it has performed the security
// handshake, and before it negotiates the muxer, or by the directly by the
// transport, at the exact same checkpoint.
InterceptSecured(network.Direction, peer.ID, network.ConnMultiaddrs) (allow bool)
// InterceptUpgraded tests whether a fully capable connection is allowed.
//
// At this point, the connection a multiplexer has been selected.
// When rejecting a connection, the gater can return a DisconnectReason.
// Refer to the godoc on the ConnectionGater type for more information.
//
// NOTE: the go-libp2p implementation currently IGNORES the disconnect reason.
InterceptUpgraded(network.Conn) (allow bool, reason control.DisconnectReason)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.ConnectionGater instead
type ConnectionGater = connmgr.ConnectionGater

View File

@ -1,3 +1,5 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/connmgr.
//
// Package connmgr provides connection tracking and management interfaces for libp2p.
//
// The ConnManager interface exported from this package allows libp2p to enforce an
@ -7,18 +9,14 @@
package connmgr
import (
"context"
"time"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/connmgr"
)
// SupportsDecay evaluates if the provided ConnManager supports decay, and if
// so, it returns the Decayer object. Refer to godocs on Decayer for more info.
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.SupportsDecay instead
func SupportsDecay(mgr ConnManager) (Decayer, bool) {
d, ok := mgr.(Decayer)
return d, ok
return connmgr.SupportsDecay(mgr)
}
// ConnManager tracks connections to peers, and allows consumers to associate
@ -30,62 +28,9 @@ func SupportsDecay(mgr ConnManager) (Decayer, bool) {
//
// ConnManagers supporting decaying tags implement Decayer. Use the
// SupportsDecay function to safely cast an instance to Decayer, if supported.
type ConnManager interface {
// TagPeer tags a peer with a string, associating a weight with the tag.
TagPeer(peer.ID, string, int)
// Untag removes the tagged value from the peer.
UntagPeer(p peer.ID, tag string)
// UpsertTag updates an existing tag or inserts a new one.
//
// The connection manager calls the upsert function supplying the current
// value of the tag (or zero if inexistent). The return value is used as
// the new value of the tag.
UpsertTag(p peer.ID, tag string, upsert func(int) int)
// GetTagInfo returns the metadata associated with the peer,
// or nil if no metadata has been recorded for the peer.
GetTagInfo(p peer.ID) *TagInfo
// TrimOpenConns terminates open connections based on an implementation-defined
// heuristic.
TrimOpenConns(ctx context.Context)
// Notifee returns an implementation that can be called back to inform of
// opened and closed connections.
Notifee() network.Notifiee
// Protect protects a peer from having its connection(s) pruned.
//
// Tagging allows different parts of the system to manage protections without interfering with one another.
//
// Calls to Protect() with the same tag are idempotent. They are not refcounted, so after multiple calls
// to Protect() with the same tag, a single Unprotect() call bearing the same tag will revoke the protection.
Protect(id peer.ID, tag string)
// Unprotect removes a protection that may have been placed on a peer, under the specified tag.
//
// The return value indicates whether the peer continues to be protected after this call, by way of a different tag.
// See notes on Protect() for more info.
Unprotect(id peer.ID, tag string) (protected bool)
// IsProtected returns true if the peer is protected for some tag; if the tag is the empty string
// then it will return true if the peer is protected for any tag
IsProtected(id peer.ID, tag string) (protected bool)
// Close closes the connection manager and stops background processes.
Close() error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.ConnManager instead
type ConnManager = connmgr.ConnManager
// TagInfo stores metadata associated with a peer.
type TagInfo struct {
FirstSeen time.Time
Value int
// Tags maps tag ids to the numerical values.
Tags map[string]int
// Conns maps connection ids (such as remote multiaddr) to their creation time.
Conns map[string]time.Time
}
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.TagInfo instead
type TagInfo = connmgr.TagInfo

View File

@ -1,24 +1,9 @@
package connmgr
import (
"context"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/connmgr"
)
// NullConnMgr is a ConnMgr that provides no functionality.
type NullConnMgr struct{}
var _ ConnManager = (*NullConnMgr)(nil)
func (NullConnMgr) TagPeer(peer.ID, string, int) {}
func (NullConnMgr) UntagPeer(peer.ID, string) {}
func (NullConnMgr) UpsertTag(peer.ID, string, func(int) int) {}
func (NullConnMgr) GetTagInfo(peer.ID) *TagInfo { return &TagInfo{} }
func (NullConnMgr) TrimOpenConns(ctx context.Context) {}
func (NullConnMgr) Notifee() network.Notifiee { return network.GlobalNoopNotifiee }
func (NullConnMgr) Protect(peer.ID, string) {}
func (NullConnMgr) Unprotect(peer.ID, string) bool { return false }
func (NullConnMgr) IsProtected(peer.ID, string) bool { return false }
func (NullConnMgr) Close() error { return nil }
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.NullConnMgr instead
type NullConnMgr = connmgr.NullConnMgr

View File

@ -1,67 +1,52 @@
package connmgr
import (
"math"
"time"
"github.com/libp2p/go-libp2p/core/connmgr"
)
// DecayNone applies no decay.
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.DecayNone instead
func DecayNone() DecayFn {
return func(value DecayingValue) (_ int, rm bool) {
return value.Value, false
}
return connmgr.DecayNone()
}
// DecayFixed subtracts from by the provided minuend, and deletes the tag when
// first reaching 0 or negative.
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.DecayFixed instead
func DecayFixed(minuend int) DecayFn {
return func(value DecayingValue) (_ int, rm bool) {
v := value.Value - minuend
return v, v <= 0
}
return connmgr.DecayFixed(minuend)
}
// DecayLinear applies a fractional coefficient to the value of the current tag,
// rounding down via math.Floor. It erases the tag when the result is zero.
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.DecayLinear instead
func DecayLinear(coef float64) DecayFn {
return func(value DecayingValue) (after int, rm bool) {
v := math.Floor(float64(value.Value) * coef)
return int(v), v <= 0
}
return connmgr.DecayLinear(coef)
}
// DecayExpireWhenInactive expires a tag after a certain period of no bumps.
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.DecayExpireWhenInactive instead
func DecayExpireWhenInactive(after time.Duration) DecayFn {
return func(value DecayingValue) (_ int, rm bool) {
rm = time.Until(value.LastVisit) >= after
return 0, rm
}
return connmgr.DecayExpireWhenInactive(after)
}
// BumpSumUnbounded adds the incoming value to the peer's score.
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.BumpSumUnbounded instead
func BumpSumUnbounded() BumpFn {
return func(value DecayingValue, delta int) (after int) {
return value.Value + delta
}
return connmgr.BumpSumUnbounded()
}
// BumpSumBounded keeps summing the incoming score, keeping it within a
// [min, max] range.
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.BumpSumBounded instead
func BumpSumBounded(min, max int) BumpFn {
return func(value DecayingValue, delta int) (after int) {
v := value.Value + delta
if v >= max {
return max
} else if v <= min {
return min
}
return v
}
return connmgr.BumpSumBounded(min, max)
}
// BumpOverwrite replaces the current value of the tag with the incoming one.
// Deprecated: use github.com/libp2p/go-libp2p/core/connmgr.BumpOverwrite instead
func BumpOverwrite() BumpFn {
return func(value DecayingValue, delta int) (after int) {
return delta
}
return connmgr.BumpOverwrite()
}

View File

@ -1,9 +1,13 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/control.
package control
import "github.com/libp2p/go-libp2p/core/control"
// DisconnectReason communicates the reason why a connection is being closed.
//
// A zero value stands for "no reason" / NA.
//
// This is an EXPERIMENTAL type. It will change in the future. Refer to the
// connmgr.ConnectionGater godoc for more info.
type DisconnectReason int
// Deprecated: use github.com/libp2p/go-libp2p/core/control instead
type DisconnectReason = control.DisconnectReason

View File

@ -1,84 +0,0 @@
package crypto
import "testing"
func BenchmarkSignRSA1B(b *testing.B) { RunBenchmarkSignRSA(b, 1) }
func BenchmarkSignRSA10B(b *testing.B) { RunBenchmarkSignRSA(b, 10) }
func BenchmarkSignRSA100B(b *testing.B) { RunBenchmarkSignRSA(b, 100) }
func BenchmarkSignRSA1000B(b *testing.B) { RunBenchmarkSignRSA(b, 1000) }
func BenchmarkSignRSA10000B(b *testing.B) { RunBenchmarkSignRSA(b, 10000) }
func BenchmarkSignRSA100000B(b *testing.B) { RunBenchmarkSignRSA(b, 100000) }
func BenchmarkVerifyRSA1B(b *testing.B) { RunBenchmarkVerifyRSA(b, 1) }
func BenchmarkVerifyRSA10B(b *testing.B) { RunBenchmarkVerifyRSA(b, 10) }
func BenchmarkVerifyRSA100B(b *testing.B) { RunBenchmarkVerifyRSA(b, 100) }
func BenchmarkVerifyRSA1000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 1000) }
func BenchmarkVerifyRSA10000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 10000) }
func BenchmarkVerifyRSA100000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 100000) }
func BenchmarkSignEd255191B(b *testing.B) { RunBenchmarkSignEd25519(b, 1) }
func BenchmarkSignEd2551910B(b *testing.B) { RunBenchmarkSignEd25519(b, 10) }
func BenchmarkSignEd25519100B(b *testing.B) { RunBenchmarkSignEd25519(b, 100) }
func BenchmarkSignEd255191000B(b *testing.B) { RunBenchmarkSignEd25519(b, 1000) }
func BenchmarkSignEd2551910000B(b *testing.B) { RunBenchmarkSignEd25519(b, 10000) }
func BenchmarkSignEd25519100000B(b *testing.B) { RunBenchmarkSignEd25519(b, 100000) }
func BenchmarkVerifyEd255191B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 1) }
func BenchmarkVerifyEd2551910B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 10) }
func BenchmarkVerifyEd25519100B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 100) }
func BenchmarkVerifyEd255191000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 1000) }
func BenchmarkVerifyEd2551910000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 10000) }
func BenchmarkVerifyEd25519100000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 100000) }
func RunBenchmarkSignRSA(b *testing.B, numBytes int) {
runBenchmarkSign(b, numBytes, RSA)
}
func RunBenchmarkSignEd25519(b *testing.B, numBytes int) {
runBenchmarkSign(b, numBytes, Ed25519)
}
func runBenchmarkSign(b *testing.B, numBytes int, t int) {
secret, _, err := GenerateKeyPair(t, 1024)
if err != nil {
b.Fatal(err)
}
someData := make([]byte, numBytes)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := secret.Sign(someData)
if err != nil {
b.Fatal(err)
}
}
}
func RunBenchmarkVerifyRSA(b *testing.B, numBytes int) {
runBenchmarkVerify(b, numBytes, RSA)
}
func RunBenchmarkVerifyEd25519(b *testing.B, numBytes int) {
runBenchmarkVerify(b, numBytes, Ed25519)
}
func runBenchmarkVerify(b *testing.B, numBytes int, t int) {
secret, public, err := GenerateKeyPair(t, 1024)
if err != nil {
b.Fatal(err)
}
someData := make([]byte, numBytes)
signature, err := secret.Sign(someData)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
valid, err := public.Verify(someData, signature)
if err != nil {
b.Fatal(err)
}
if !valid {
b.Fatal("signature should be valid")
}
}
}

View File

@ -3,185 +3,85 @@ package crypto
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/asn1"
"errors"
"io"
"math/big"
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
"github.com/libp2p/go-libp2p-core/internal/catch"
"github.com/minio/sha256-simd"
"github.com/libp2p/go-libp2p/core/crypto"
)
// ECDSAPrivateKey is an implementation of an ECDSA private key
type ECDSAPrivateKey struct {
priv *ecdsa.PrivateKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ECDSAPrivateKey instead
type ECDSAPrivateKey = crypto.ECDSAPrivateKey
// ECDSAPublicKey is an implementation of an ECDSA public key
type ECDSAPublicKey struct {
pub *ecdsa.PublicKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ECDSAPublicKey instead
type ECDSAPublicKey = crypto.ECDSAPublicKey
// ECDSASig holds the r and s values of an ECDSA signature
type ECDSASig struct {
R, S *big.Int
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ECDSASig instead
type ECDSASig = crypto.ECDSASig
var (
// ErrNotECDSAPubKey is returned when the public key passed is not an ecdsa public key
ErrNotECDSAPubKey = errors.New("not an ecdsa public key")
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ErrNotECDSAPubKey instead
ErrNotECDSAPubKey = crypto.ErrNotECDSAPubKey
// ErrNilSig is returned when the signature is nil
ErrNilSig = errors.New("sig is nil")
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ErrNilSig instead
ErrNilSig = crypto.ErrNilSig
// ErrNilPrivateKey is returned when a nil private key is provided
ErrNilPrivateKey = errors.New("private key is nil")
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ErrNilPrivateKey instead
ErrNilPrivateKey = crypto.ErrNilPrivateKey
// ErrNilPublicKey is returned when a nil public key is provided
ErrNilPublicKey = errors.New("public key is nil")
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ErrNilPublicKey instead
ErrNilPublicKey = crypto.ErrNilPublicKey
// ECDSACurve is the default ecdsa curve used
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ECDSACurve instead
ECDSACurve = elliptic.P256()
)
// GenerateECDSAKeyPair generates a new ecdsa private and public key
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateECDSAKeyPair instead
func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) {
return GenerateECDSAKeyPairWithCurve(ECDSACurve, src)
return crypto.GenerateECDSAKeyPair(src)
}
// GenerateECDSAKeyPairWithCurve generates a new ecdsa private and public key with a speicified curve
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateECDSAKeyPairWithCurve instead
func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) (PrivKey, PubKey, error) {
priv, err := ecdsa.GenerateKey(curve, src)
if err != nil {
return nil, nil, err
}
return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil
return crypto.GenerateECDSAKeyPairWithCurve(curve, src)
}
// ECDSAKeyPairFromKey generates a new ecdsa private and public key from an input private key
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ECDSAKeyPairFromKey instead
func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) {
if priv == nil {
return nil, nil, ErrNilPrivateKey
}
return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil
return crypto.ECDSAKeyPairFromKey(priv)
}
// ECDSAPublicKeyFromPubKey generates a new ecdsa public key from an input public key
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ECDSAPublicKeyFromPubKey instead
func ECDSAPublicKeyFromPubKey(pub ecdsa.PublicKey) (PubKey, error) {
return &ECDSAPublicKey{pub: &pub}, nil
return crypto.ECDSAPublicKeyFromPubKey(pub)
}
// MarshalECDSAPrivateKey returns x509 bytes from a private key
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.MarshalECDSAPrivateKey instead
func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key marshal") }()
return x509.MarshalECPrivateKey(ePriv.priv)
return crypto.MarshalECDSAPrivateKey(ePriv)
}
// MarshalECDSAPublicKey returns x509 bytes from a public key
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.MarshalECDSAPublicKey instead
func MarshalECDSAPublicKey(ePub ECDSAPublicKey) (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "ECDSA public-key marshal") }()
return x509.MarshalPKIXPublicKey(ePub.pub)
return crypto.MarshalECDSAPublicKey(ePub)
}
// UnmarshalECDSAPrivateKey returns a private key from x509 bytes
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.MarshalECDSAPrivateKey instead
func UnmarshalECDSAPrivateKey(data []byte) (res PrivKey, err error) {
defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key unmarshal") }()
priv, err := x509.ParseECPrivateKey(data)
if err != nil {
return nil, err
}
return &ECDSAPrivateKey{priv}, nil
return crypto.UnmarshalECDSAPrivateKey(data)
}
// UnmarshalECDSAPublicKey returns the public key from x509 bytes
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalECDSAPublicKey instead
func UnmarshalECDSAPublicKey(data []byte) (key PubKey, err error) {
defer func() { catch.HandlePanic(recover(), &err, "ECDSA public-key unmarshal") }()
pubIfc, err := x509.ParsePKIXPublicKey(data)
if err != nil {
return nil, err
}
pub, ok := pubIfc.(*ecdsa.PublicKey)
if !ok {
return nil, ErrNotECDSAPubKey
}
return &ECDSAPublicKey{pub}, nil
}
// Type returns the key type
func (ePriv *ECDSAPrivateKey) Type() pb.KeyType {
return pb.KeyType_ECDSA
}
// Raw returns x509 bytes from a private key
func (ePriv *ECDSAPrivateKey) Raw() (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key marshal") }()
return x509.MarshalECPrivateKey(ePriv.priv)
}
// Equals compares two private keys
func (ePriv *ECDSAPrivateKey) Equals(o Key) bool {
return basicEquals(ePriv, o)
}
// Sign returns the signature of the input data
func (ePriv *ECDSAPrivateKey) Sign(data []byte) (sig []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "ECDSA signing") }()
hash := sha256.Sum256(data)
r, s, err := ecdsa.Sign(rand.Reader, ePriv.priv, hash[:])
if err != nil {
return nil, err
}
return asn1.Marshal(ECDSASig{
R: r,
S: s,
})
}
// GetPublic returns a public key
func (ePriv *ECDSAPrivateKey) GetPublic() PubKey {
return &ECDSAPublicKey{&ePriv.priv.PublicKey}
}
// Type returns the key type
func (ePub *ECDSAPublicKey) Type() pb.KeyType {
return pb.KeyType_ECDSA
}
// Raw returns x509 bytes from a public key
func (ePub *ECDSAPublicKey) Raw() ([]byte, error) {
return x509.MarshalPKIXPublicKey(ePub.pub)
}
// Equals compares to public keys
func (ePub *ECDSAPublicKey) Equals(o Key) bool {
return basicEquals(ePub, o)
}
// Verify compares data to a signature
func (ePub *ECDSAPublicKey) Verify(data, sigBytes []byte) (success bool, err error) {
defer func() {
catch.HandlePanic(recover(), &err, "ECDSA signature verification")
// Just to be extra paranoid.
if err != nil {
success = false
}
}()
sig := new(ECDSASig)
if _, err := asn1.Unmarshal(sigBytes, sig); err != nil {
return false, err
}
hash := sha256.Sum256(data)
return ecdsa.Verify(ePub.pub, hash[:], sig.R, sig.S), nil
return crypto.UnmarshalECDSAPublicKey(data)
}

View File

@ -1,142 +0,0 @@
package crypto
import (
"crypto/ecdsa"
"crypto/rand"
"testing"
)
func TestECDSABasicSignAndVerify(t *testing.T) {
priv, pub, err := GenerateECDSAKeyPair(rand.Reader)
if err != nil {
t.Fatal(err)
}
data := []byte("hello! and welcome to some awesome crypto primitives")
sig, err := priv.Sign(data)
if err != nil {
t.Fatal(err)
}
ok, err := pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didnt match")
}
// change data
data[0] = ^data[0]
ok, err = pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if ok {
t.Fatal("signature matched and shouldn't")
}
}
func TestECDSASignZero(t *testing.T) {
priv, pub, err := GenerateECDSAKeyPair(rand.Reader)
if err != nil {
t.Fatal(err)
}
data := make([]byte, 0)
sig, err := priv.Sign(data)
if err != nil {
t.Fatal(err)
}
ok, err := pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didn't match")
}
}
func TestECDSAMarshalLoop(t *testing.T) {
priv, pub, err := GenerateECDSAKeyPair(rand.Reader)
if err != nil {
t.Fatal(err)
}
privB, err := MarshalPrivateKey(priv)
if err != nil {
t.Fatal(err)
}
privNew, err := UnmarshalPrivateKey(privB)
if err != nil {
t.Fatal(err)
}
if !priv.Equals(privNew) || !privNew.Equals(priv) {
t.Fatal("keys are not equal")
}
pubB, err := MarshalPublicKey(pub)
if err != nil {
t.Fatal(err)
}
pubNew, err := UnmarshalPublicKey(pubB)
if err != nil {
t.Fatal(err)
}
if !pub.Equals(pubNew) || !pubNew.Equals(pub) {
t.Fatal("keys are not equal")
}
}
func TestECDSAPublicKeyFromPubKey(t *testing.T) {
ecdsaPrivK, err := ecdsa.GenerateKey(ECDSACurve, rand.Reader)
if err != nil {
t.Fatal(err)
}
privK, _, err := ECDSAKeyPairFromKey(ecdsaPrivK)
if err != nil {
t.Fatal(err)
}
data := []byte("Hello world!")
signature, err := privK.Sign(data)
if err != nil {
t.Fatal(err)
}
pubKey, err := ECDSAPublicKeyFromPubKey(ecdsaPrivK.PublicKey)
if err != nil {
t.Fatal(err)
}
ok, err := pubKey.Verify(data, signature)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didn't match")
}
pubB, err := MarshalPublicKey(pubKey)
if err != nil {
t.Fatal(err)
}
pubNew, err := UnmarshalPublicKey(pubB)
if err != nil {
t.Fatal(err)
}
if !pubKey.Equals(pubNew) || !pubNew.Equals(pubKey) {
t.Fatal("keys are not equal")
}
}

View File

@ -1,156 +1,33 @@
package crypto
import (
"bytes"
"crypto/ed25519"
"crypto/subtle"
"errors"
"fmt"
"io"
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
"github.com/libp2p/go-libp2p-core/internal/catch"
"github.com/libp2p/go-libp2p/core/crypto"
)
// Ed25519PrivateKey is an ed25519 private key.
type Ed25519PrivateKey struct {
k ed25519.PrivateKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.Ed25519PrivateKey instead
type Ed25519PrivateKey = crypto.Ed25519PrivateKey
// Ed25519PublicKey is an ed25519 public key.
type Ed25519PublicKey struct {
k ed25519.PublicKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.Ed25519PublicKey instead
type Ed25519PublicKey = crypto.Ed25519PublicKey
// GenerateEd25519Key generates a new ed25519 private and public key pair.
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateEd25519Key instead
func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) {
pub, priv, err := ed25519.GenerateKey(src)
if err != nil {
return nil, nil, err
}
return &Ed25519PrivateKey{
k: priv,
},
&Ed25519PublicKey{
k: pub,
},
nil
}
// Type of the private key (Ed25519).
func (k *Ed25519PrivateKey) Type() pb.KeyType {
return pb.KeyType_Ed25519
}
// Raw private key bytes.
func (k *Ed25519PrivateKey) Raw() ([]byte, error) {
// The Ed25519 private key contains two 32-bytes curve points, the private
// key and the public key.
// It makes it more efficient to get the public key without re-computing an
// elliptic curve multiplication.
buf := make([]byte, len(k.k))
copy(buf, k.k)
return buf, nil
}
func (k *Ed25519PrivateKey) pubKeyBytes() []byte {
return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:]
}
// Equals compares two ed25519 private keys.
func (k *Ed25519PrivateKey) Equals(o Key) bool {
edk, ok := o.(*Ed25519PrivateKey)
if !ok {
return basicEquals(k, o)
}
return subtle.ConstantTimeCompare(k.k, edk.k) == 1
}
// GetPublic returns an ed25519 public key from a private key.
func (k *Ed25519PrivateKey) GetPublic() PubKey {
return &Ed25519PublicKey{k: k.pubKeyBytes()}
}
// Sign returns a signature from an input message.
func (k *Ed25519PrivateKey) Sign(msg []byte) (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "ed15519 signing") }()
return ed25519.Sign(k.k, msg), nil
}
// Type of the public key (Ed25519).
func (k *Ed25519PublicKey) Type() pb.KeyType {
return pb.KeyType_Ed25519
}
// Raw public key bytes.
func (k *Ed25519PublicKey) Raw() ([]byte, error) {
return k.k, nil
}
// Equals compares two ed25519 public keys.
func (k *Ed25519PublicKey) Equals(o Key) bool {
edk, ok := o.(*Ed25519PublicKey)
if !ok {
return basicEquals(k, o)
}
return bytes.Equal(k.k, edk.k)
}
// Verify checks a signature agains the input data.
func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (success bool, err error) {
defer func() {
catch.HandlePanic(recover(), &err, "ed15519 signature verification")
// To be safe.
if err != nil {
success = false
}
}()
return ed25519.Verify(k.k, data, sig), nil
return crypto.GenerateEd25519Key(src)
}
// UnmarshalEd25519PublicKey returns a public key from input bytes.
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalEd25519PublicKey instead
func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) {
if len(data) != 32 {
return nil, errors.New("expect ed25519 public key data size to be 32")
}
return &Ed25519PublicKey{
k: ed25519.PublicKey(data),
}, nil
return crypto.UnmarshalEd25519PublicKey(data)
}
// UnmarshalEd25519PrivateKey returns a private key from input bytes.
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalEd25519PrivateKey instead
func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) {
switch len(data) {
case ed25519.PrivateKeySize + ed25519.PublicKeySize:
// Remove the redundant public key. See issue #36.
redundantPk := data[ed25519.PrivateKeySize:]
pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize]
if subtle.ConstantTimeCompare(pk, redundantPk) == 0 {
return nil, errors.New("expected redundant ed25519 public key to be redundant")
}
// No point in storing the extra data.
newKey := make([]byte, ed25519.PrivateKeySize)
copy(newKey, data[:ed25519.PrivateKeySize])
data = newKey
case ed25519.PrivateKeySize:
default:
return nil, fmt.Errorf(
"expected ed25519 data size to be %d or %d, got %d",
ed25519.PrivateKeySize,
ed25519.PrivateKeySize+ed25519.PublicKeySize,
len(data),
)
}
return &Ed25519PrivateKey{
k: ed25519.PrivateKey(data),
}, nil
return crypto.UnmarshalEd25519PrivateKey(data)
}

View File

@ -1,217 +0,0 @@
package crypto
import (
"crypto/ed25519"
"crypto/rand"
"testing"
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
)
func TestBasicSignAndVerify(t *testing.T) {
priv, pub, err := GenerateEd25519Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
data := []byte("hello! and welcome to some awesome crypto primitives")
sig, err := priv.Sign(data)
if err != nil {
t.Fatal(err)
}
ok, err := pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didn't match")
}
// change data
data[0] = ^data[0]
ok, err = pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if ok {
t.Fatal("signature matched and shouldn't")
}
}
func TestSignZero(t *testing.T) {
priv, pub, err := GenerateEd25519Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
data := make([]byte, 0)
sig, err := priv.Sign(data)
if err != nil {
t.Fatal(err)
}
ok, err := pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didn't match")
}
}
func TestMarshalLoop(t *testing.T) {
priv, pub, err := GenerateEd25519Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
t.Run("PrivateKey", func(t *testing.T) {
for name, f := range map[string]func() ([]byte, error){
"Marshal": func() ([]byte, error) {
return MarshalPrivateKey(priv)
},
"Redundant": func() ([]byte, error) {
// See issue #36.
// Ed25519 private keys used to contain the public key twice.
// For backwards-compatibility, we need to continue supporting
// that scenario.
pbmes := new(pb.PrivateKey)
pbmes.Type = priv.Type()
data, err := priv.Raw()
if err != nil {
t.Fatal(err)
}
pbmes.Data = append(data, data[len(data)-ed25519.PublicKeySize:]...)
return pbmes.Marshal()
},
} {
t.Run(name, func(t *testing.T) {
bts, err := f()
if err != nil {
t.Fatal(err)
}
privNew, err := UnmarshalPrivateKey(bts)
if err != nil {
t.Fatal(err)
}
if !priv.Equals(privNew) || !privNew.Equals(priv) {
t.Fatal("keys are not equal")
}
msg := []byte("My child, my sister,\nThink of the rapture\nOf living together there!")
signed, err := privNew.Sign(msg)
if err != nil {
t.Fatal(err)
}
ok, err := privNew.GetPublic().Verify(msg, signed)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didn't match")
}
})
}
})
t.Run("PublicKey", func(t *testing.T) {
for name, f := range map[string]func() ([]byte, error){
"Marshal": func() ([]byte, error) {
return MarshalPublicKey(pub)
},
} {
t.Run(name, func(t *testing.T) {
bts, err := f()
if err != nil {
t.Fatal(err)
}
pubNew, err := UnmarshalPublicKey(bts)
if err != nil {
t.Fatal(err)
}
if !pub.Equals(pubNew) || !pubNew.Equals(pub) {
t.Fatal("keys are not equal")
}
})
}
})
}
func TestUnmarshalErrors(t *testing.T) {
t.Run("PublicKey", func(t *testing.T) {
t.Run("Invalid data length", func(t *testing.T) {
pbmes := &pb.PublicKey{
Type: pb.KeyType_Ed25519,
Data: []byte{42},
}
data, err := pbmes.Marshal()
if err != nil {
t.Fatal(err)
}
_, err = UnmarshalPublicKey(data)
if err == nil {
t.Fatal("expected an error")
}
})
})
t.Run("PrivateKey", func(t *testing.T) {
t.Run("Redundant public key mismatch", func(t *testing.T) {
priv, _, err := GenerateEd25519Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
pbmes := new(pb.PrivateKey)
pbmes.Type = priv.Type()
data, err := priv.Raw()
if err != nil {
t.Fatal(err)
}
// Append the private key instead of the public key.
pbmes.Data = append(data, data[:ed25519.PublicKeySize]...)
b, err := pbmes.Marshal()
if err != nil {
t.Fatal(err)
}
_, err = UnmarshalPrivateKey(b)
if err == nil {
t.Fatal("expected an error")
}
if err.Error() != "expected redundant ed25519 public key to be redundant" {
t.Fatalf("invalid error received: %s", err.Error())
}
})
t.Run("Invalid data length", func(t *testing.T) {
pbmes := &pb.PrivateKey{
Type: pb.KeyType_Ed25519,
Data: []byte{42},
}
data, err := pbmes.Marshal()
if err != nil {
t.Fatal(err)
}
_, err = UnmarshalPrivateKey(data)
if err == nil {
t.Fatal("expected an error")
}
})
})
}

View File

@ -1,132 +0,0 @@
package crypto_test
import (
"bytes"
"crypto/rand"
"fmt"
"io"
"os"
"testing"
"github.com/libp2p/go-libp2p-core/crypto"
crypto_pb "github.com/libp2p/go-libp2p-core/crypto/pb"
)
var message = []byte("Libp2p is the _best_!")
type testCase struct {
keyType crypto_pb.KeyType
gen func(i io.Reader) (crypto.PrivKey, crypto.PubKey, error)
sigDeterministic bool
}
var keyTypes = []testCase{
{
keyType: crypto_pb.KeyType_ECDSA,
gen: crypto.GenerateECDSAKeyPair,
},
{
keyType: crypto_pb.KeyType_Secp256k1,
sigDeterministic: true,
gen: crypto.GenerateSecp256k1Key,
},
{
keyType: crypto_pb.KeyType_RSA,
sigDeterministic: true,
gen: func(i io.Reader) (crypto.PrivKey, crypto.PubKey, error) {
return crypto.GenerateRSAKeyPair(2048, i)
},
},
}
func fname(kt crypto_pb.KeyType, ext string) string {
return fmt.Sprintf("test_data/%d.%s", kt, ext)
}
func TestFixtures(t *testing.T) {
for _, tc := range keyTypes {
t.Run(tc.keyType.String(), func(t *testing.T) {
pubBytes, err := os.ReadFile(fname(tc.keyType, "pub"))
if err != nil {
t.Fatal(err)
}
privBytes, err := os.ReadFile(fname(tc.keyType, "priv"))
if err != nil {
t.Fatal(err)
}
sigBytes, err := os.ReadFile(fname(tc.keyType, "sig"))
if err != nil {
t.Fatal(err)
}
pub, err := crypto.UnmarshalPublicKey(pubBytes)
if err != nil {
t.Fatal(err)
}
pubBytes2, err := crypto.MarshalPublicKey(pub)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(pubBytes2, pubBytes) {
t.Fatal("encoding round-trip failed")
}
priv, err := crypto.UnmarshalPrivateKey(privBytes)
if err != nil {
t.Fatal(err)
}
privBytes2, err := crypto.MarshalPrivateKey(priv)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(privBytes2, privBytes) {
t.Fatal("encoding round-trip failed")
}
ok, err := pub.Verify(message, sigBytes)
if !ok || err != nil {
t.Fatal("failed to validate signature with public key")
}
if tc.sigDeterministic {
sigBytes2, err := priv.Sign(message)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(sigBytes2, sigBytes) {
t.Fatal("signature not deterministic")
}
}
})
}
}
func init() {
// set to true to re-generate test data
if false {
generate()
panic("generated")
}
}
// generate re-generates test data
func generate() {
for _, tc := range keyTypes {
priv, pub, err := tc.gen(rand.Reader)
if err != nil {
panic(err)
}
pubb, err := crypto.MarshalPublicKey(pub)
if err != nil {
panic(err)
}
privb, err := crypto.MarshalPrivateKey(priv)
if err != nil {
panic(err)
}
sig, err := priv.Sign(message)
if err != nil {
panic(err)
}
os.WriteFile(fname(tc.keyType, "pub"), pubb, 0666)
os.WriteFile(fname(tc.keyType, "priv"), privb, 0666)
os.WriteFile(fname(tc.keyType, "sig"), sig, 0666)
}
}

View File

@ -1,20 +1,16 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/crypto.
//
// Package crypto implements various cryptographic utilities used by libp2p.
// This includes a Public and Private key interface and key implementations
// for supported key algorithms.
package crypto
import (
"crypto/elliptic"
"crypto/rand"
"crypto/subtle"
"encoding/base64"
"errors"
"fmt"
"io"
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
"github.com/gogo/protobuf/proto"
"github.com/libp2p/go-libp2p/core/crypto"
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
)
const (
@ -41,250 +37,113 @@ var (
)
// PubKeyUnmarshaller is a func that creates a PubKey from a given slice of bytes
type PubKeyUnmarshaller func(data []byte) (PubKey, error)
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PubKeyUnmarshaller instead
type PubKeyUnmarshaller = crypto.PubKeyUnmarshaller
// PrivKeyUnmarshaller is a func that creates a PrivKey from a given slice of bytes
type PrivKeyUnmarshaller func(data []byte) (PrivKey, error)
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PrivKeyUnmarshaller instead
type PrivKeyUnmarshaller = crypto.PrivKeyUnmarshaller
// PubKeyUnmarshallers is a map of unmarshallers by key type
var PubKeyUnmarshallers = map[pb.KeyType]PubKeyUnmarshaller{
pb.KeyType_RSA: UnmarshalRsaPublicKey,
pb.KeyType_Ed25519: UnmarshalEd25519PublicKey,
pb.KeyType_Secp256k1: UnmarshalSecp256k1PublicKey,
pb.KeyType_ECDSA: UnmarshalECDSAPublicKey,
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PubKeyUnmarshallers instead
var PubKeyUnmarshallers = crypto.PubKeyUnmarshallers
// PrivKeyUnmarshallers is a map of unmarshallers by key type
var PrivKeyUnmarshallers = map[pb.KeyType]PrivKeyUnmarshaller{
pb.KeyType_RSA: UnmarshalRsaPrivateKey,
pb.KeyType_Ed25519: UnmarshalEd25519PrivateKey,
pb.KeyType_Secp256k1: UnmarshalSecp256k1PrivateKey,
pb.KeyType_ECDSA: UnmarshalECDSAPrivateKey,
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PrivKeyUnmarshallers instead
var PrivKeyUnmarshallers = crypto.PrivKeyUnmarshallers
// Key represents a crypto key that can be compared to another key
type Key interface {
// Equals checks whether two PubKeys are the same
Equals(Key) bool
// Raw returns the raw bytes of the key (not wrapped in the
// libp2p-crypto protobuf).
//
// This function is the inverse of {Priv,Pub}KeyUnmarshaler.
Raw() ([]byte, error)
// Type returns the protobuf key type.
Type() pb.KeyType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.Key instead
type Key = crypto.Key
// PrivKey represents a private key that can be used to generate a public key and sign data
type PrivKey interface {
Key
// Cryptographically sign the given bytes
Sign([]byte) ([]byte, error)
// Return a public key paired with this private key
GetPublic() PubKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PrivKey instead
type PrivKey = crypto.PrivKey
// PubKey is a public key that can be used to verifiy data signed with the corresponding private key
type PubKey interface {
Key
// Verify that 'sig' is the signed hash of 'data'
Verify(data []byte, sig []byte) (bool, error)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PubKey instead
type PubKey = crypto.PubKey
// GenSharedKey generates the shared key from a given private key
type GenSharedKey func([]byte) ([]byte, error)
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenSharedKey instead
type GenSharedKey = crypto.GenSharedKey
// GenerateKeyPair generates a private and public key
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateKeyPair instead
func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
return GenerateKeyPairWithReader(typ, bits, rand.Reader)
return crypto.GenerateKeyPair(typ, bits)
}
// GenerateKeyPairWithReader returns a keypair of the given type and bitsize
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateKeyPairWithReader instead
func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, error) {
switch typ {
case RSA:
return GenerateRSAKeyPair(bits, src)
case Ed25519:
return GenerateEd25519Key(src)
case Secp256k1:
return GenerateSecp256k1Key(src)
case ECDSA:
return GenerateECDSAKeyPair(src)
default:
return nil, nil, ErrBadKeyType
}
return crypto.GenerateKeyPairWithReader(typ, bits, src)
}
// GenerateEKeyPair returns an ephemeral public key and returns a function that will compute
// the shared secret key. Used in the identify module.
//
// Focuses only on ECDH now, but can be made more general in the future.
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateEKeyPair instead
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
var curve elliptic.Curve
switch curveName {
case "P-256":
curve = elliptic.P256()
case "P-384":
curve = elliptic.P384()
case "P-521":
curve = elliptic.P521()
default:
return nil, nil, fmt.Errorf("unknown curve name")
}
priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
if err != nil {
return nil, nil, err
}
pubKey := elliptic.Marshal(curve, x, y)
done := func(theirPub []byte) ([]byte, error) {
// Verify and unpack node's public key.
x, y := elliptic.Unmarshal(curve, theirPub)
if x == nil {
return nil, fmt.Errorf("malformed public key: %d %v", len(theirPub), theirPub)
}
if !curve.IsOnCurve(x, y) {
return nil, errors.New("invalid public key")
}
// Generate shared secret.
secret, _ := curve.ScalarMult(x, y, priv)
return secret.Bytes(), nil
}
return pubKey, done, nil
return crypto.GenerateEKeyPair(curveName)
}
// UnmarshalPublicKey converts a protobuf serialized public key into its
// representative object
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalPublicKey instead
func UnmarshalPublicKey(data []byte) (PubKey, error) {
pmes := new(pb.PublicKey)
err := proto.Unmarshal(data, pmes)
if err != nil {
return nil, err
}
return PublicKeyFromProto(pmes)
return crypto.UnmarshalPublicKey(data)
}
// PublicKeyFromProto converts an unserialized protobuf PublicKey message
// into its representative object.
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PublicKeyFromProto instead
func PublicKeyFromProto(pmes *pb.PublicKey) (PubKey, error) {
um, ok := PubKeyUnmarshallers[pmes.GetType()]
if !ok {
return nil, ErrBadKeyType
}
data := pmes.GetData()
pk, err := um(data)
if err != nil {
return nil, err
}
switch tpk := pk.(type) {
case *RsaPublicKey:
tpk.cached, _ = pmes.Marshal()
}
return pk, nil
return crypto.PublicKeyFromProto(pmes)
}
// MarshalPublicKey converts a public key object into a protobuf serialized
// public key
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.MarshalPublicKey instead
func MarshalPublicKey(k PubKey) ([]byte, error) {
pbmes, err := PublicKeyToProto(k)
if err != nil {
return nil, err
}
return proto.Marshal(pbmes)
return crypto.MarshalPublicKey(k)
}
// PublicKeyToProto converts a public key object into an unserialized
// protobuf PublicKey message.
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PublicKeyToProto instead
func PublicKeyToProto(k PubKey) (*pb.PublicKey, error) {
pbmes := new(pb.PublicKey)
pbmes.Type = k.Type()
data, err := k.Raw()
if err != nil {
return nil, err
}
pbmes.Data = data
return pbmes, nil
return crypto.PublicKeyToProto(k)
}
// UnmarshalPrivateKey converts a protobuf serialized private key into its
// representative object
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalPrivateKey instead
func UnmarshalPrivateKey(data []byte) (PrivKey, error) {
pmes := new(pb.PrivateKey)
err := proto.Unmarshal(data, pmes)
if err != nil {
return nil, err
}
um, ok := PrivKeyUnmarshallers[pmes.GetType()]
if !ok {
return nil, ErrBadKeyType
}
return um(pmes.GetData())
return crypto.UnmarshalPrivateKey(data)
}
// MarshalPrivateKey converts a key object into its protobuf serialized form.
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.MarshalPrivateKey instead
func MarshalPrivateKey(k PrivKey) ([]byte, error) {
pbmes := new(pb.PrivateKey)
pbmes.Type = k.Type()
data, err := k.Raw()
if err != nil {
return nil, err
}
pbmes.Data = data
return proto.Marshal(pbmes)
return crypto.MarshalPrivateKey(k)
}
// ConfigDecodeKey decodes from b64 (for config file) to a byte array that can be unmarshalled.
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ConfigDecodeKey instead
func ConfigDecodeKey(b string) ([]byte, error) {
return base64.StdEncoding.DecodeString(b)
return crypto.ConfigDecodeKey(b)
}
// ConfigEncodeKey encodes a marshalled key to b64 (for config file).
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ConfigEncodeKey instead
func ConfigEncodeKey(b []byte) string {
return base64.StdEncoding.EncodeToString(b)
return crypto.ConfigEncodeKey(b)
}
// KeyEqual checks whether two Keys are equivalent (have identical byte representations).
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.KeyEqual instead
func KeyEqual(k1, k2 Key) bool {
if k1 == k2 {
return true
}
return k1.Equals(k2)
}
func basicEquals(k1, k2 Key) bool {
if k1.Type() != k2.Type() {
return false
}
a, err := k1.Raw()
if err != nil {
return false
}
b, err := k2.Raw()
if err != nil {
return false
}
return subtle.ConstantTimeCompare(a, b) == 1
return crypto.KeyEqual(k1, k2)
}

View File

@ -4,78 +4,25 @@
package crypto
import (
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
stdcrypto "crypto"
btcec "github.com/btcsuite/btcd/btcec/v2"
"github.com/libp2p/go-libp2p/core/crypto"
)
// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p-core/crypto keys
func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) {
if priv == nil {
return nil, nil, ErrNilPrivateKey
}
switch p := priv.(type) {
case *rsa.PrivateKey:
return &RsaPrivateKey{*p}, &RsaPublicKey{k: p.PublicKey}, nil
case *ecdsa.PrivateKey:
return &ECDSAPrivateKey{p}, &ECDSAPublicKey{&p.PublicKey}, nil
case *ed25519.PrivateKey:
pubIfc := p.Public()
pub, _ := pubIfc.(ed25519.PublicKey)
return &Ed25519PrivateKey{*p}, &Ed25519PublicKey{pub}, nil
case *btcec.PrivateKey:
sPriv := Secp256k1PrivateKey(*p)
sPub := Secp256k1PublicKey(*p.PubKey())
return &sPriv, &sPub, nil
default:
return nil, nil, ErrBadKeyType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.KeyPairFromStdKey instead
func KeyPairFromStdKey(priv stdcrypto.PrivateKey) (PrivKey, PubKey, error) {
return crypto.KeyPairFromStdKey(priv)
}
// PrivKeyToStdKey converts libp2p/go-libp2p-core/crypto private keys to standard library (and secp256k1) private keys
func PrivKeyToStdKey(priv PrivKey) (crypto.PrivateKey, error) {
if priv == nil {
return nil, ErrNilPrivateKey
}
switch p := priv.(type) {
case *RsaPrivateKey:
return &p.sk, nil
case *ECDSAPrivateKey:
return p.priv, nil
case *Ed25519PrivateKey:
return &p.k, nil
case *Secp256k1PrivateKey:
return p, nil
default:
return nil, ErrBadKeyType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PrivKeyToStdKey instead
func PrivKeyToStdKey(priv PrivKey) (stdcrypto.PrivateKey, error) {
return crypto.PrivKeyToStdKey(priv)
}
// PubKeyToStdKey converts libp2p/go-libp2p-core/crypto private keys to standard library (and secp256k1) public keys
func PubKeyToStdKey(pub PubKey) (crypto.PublicKey, error) {
if pub == nil {
return nil, ErrNilPublicKey
}
switch p := pub.(type) {
case *RsaPublicKey:
return &p.k, nil
case *ECDSAPublicKey:
return p.pub, nil
case *Ed25519PublicKey:
return p.k, nil
case *Secp256k1PublicKey:
return p, nil
default:
return nil, ErrBadKeyType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PubKeyToStdKey instead
func PubKeyToStdKey(pub PubKey) (stdcrypto.PublicKey, error) {
return crypto.PubKeyToStdKey(pub)
}

View File

@ -4,98 +4,25 @@
package crypto
import (
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"crypto/x509"
stdcrypto "crypto"
btcec "github.com/btcsuite/btcd/btcec/v2"
openssl "github.com/libp2p/go-openssl"
"github.com/libp2p/go-libp2p-core/internal/catch"
"github.com/libp2p/go-libp2p/core/crypto"
)
// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p-core/crypto keys
func KeyPairFromStdKey(priv crypto.PrivateKey) (_priv PrivKey, _pub PubKey, err error) {
if priv == nil {
return nil, nil, ErrNilPrivateKey
}
switch p := priv.(type) {
case *rsa.PrivateKey:
defer func() { catch.HandlePanic(recover(), &err, "x509 private key marshaling") }()
pk, err := openssl.LoadPrivateKeyFromDER(x509.MarshalPKCS1PrivateKey(p))
if err != nil {
return nil, nil, err
}
return &opensslPrivateKey{pk}, &opensslPublicKey{key: pk}, nil
case *ecdsa.PrivateKey:
return &ECDSAPrivateKey{p}, &ECDSAPublicKey{&p.PublicKey}, nil
case *ed25519.PrivateKey:
pubIfc := p.Public()
pub, _ := pubIfc.(ed25519.PublicKey)
return &Ed25519PrivateKey{*p}, &Ed25519PublicKey{pub}, nil
case *btcec.PrivateKey:
sPriv := Secp256k1PrivateKey(*p)
sPub := Secp256k1PublicKey(*p.PubKey())
return &sPriv, &sPub, nil
default:
return nil, nil, ErrBadKeyType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.KeyPairFromStdKey instead
func KeyPairFromStdKey(priv stdcrypto.PrivateKey) (_priv PrivKey, _pub PubKey, err error) {
return crypto.KeyPairFromStdKey(priv)
}
// PrivKeyToStdKey converts libp2p/go-libp2p-core/crypto private keys to standard library (and secp256k1) private keys
func PrivKeyToStdKey(priv PrivKey) (_priv crypto.PrivateKey, err error) {
if priv == nil {
return nil, ErrNilPrivateKey
}
switch p := priv.(type) {
case *opensslPrivateKey:
defer func() { catch.HandlePanic(recover(), &err, "x509 private key parsing") }()
raw, err := p.Raw()
if err != nil {
return nil, err
}
return x509.ParsePKCS1PrivateKey(raw)
case *ECDSAPrivateKey:
return p.priv, nil
case *Ed25519PrivateKey:
return &p.k, nil
case *Secp256k1PrivateKey:
return p, nil
default:
return nil, ErrBadKeyType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PrivKeyToStdKey instead
func PrivKeyToStdKey(priv PrivKey) (_priv stdcrypto.PrivateKey, err error) {
return crypto.PrivKeyToStdKey(priv)
}
// PubKeyToStdKey converts libp2p/go-libp2p-core/crypto private keys to standard library (and secp256k1) public keys
func PubKeyToStdKey(pub PubKey) (key crypto.PublicKey, err error) {
if pub == nil {
return nil, ErrNilPublicKey
}
switch p := pub.(type) {
case *opensslPublicKey:
defer func() { catch.HandlePanic(recover(), &err, "x509 public key parsing") }()
raw, err := p.Raw()
if err != nil {
return nil, err
}
return x509.ParsePKIXPublicKey(raw)
case *ECDSAPublicKey:
return p.pub, nil
case *Ed25519PublicKey:
return p.k, nil
case *Secp256k1PublicKey:
return p, nil
default:
return nil, ErrBadKeyType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.PubKeyToStdKey instead
func PubKeyToStdKey(pub PubKey) (key stdcrypto.PublicKey, err error) {
return crypto.PubKeyToStdKey(pub)
}

View File

@ -1,304 +0,0 @@
package crypto_test
import (
"bytes"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"fmt"
"reflect"
"testing"
btcec "github.com/btcsuite/btcd/btcec/v2"
btcececdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa"
. "github.com/libp2p/go-libp2p-core/crypto"
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
"github.com/libp2p/go-libp2p-core/test"
"github.com/minio/sha256-simd"
)
func TestKeys(t *testing.T) {
for _, typ := range KeyTypes {
testKeyType(typ, t)
}
}
func TestKeyPairFromKey(t *testing.T) {
var (
data = []byte(`hello world`)
hashed = sha256.Sum256(data)
)
privk, err := btcec.NewPrivateKey()
if err != nil {
t.Fatalf("err generating btcec priv key:\n%v", err)
}
sigK := btcececdsa.Sign(privk, hashed[:])
eKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatalf("err generating ecdsa priv key:\n%v", err)
}
sigE, err := eKey.Sign(rand.Reader, hashed[:], crypto.SHA256)
if err != nil {
t.Fatalf("err generating ecdsa sig:\n%v", err)
}
rKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("err generating rsa priv key:\n%v", err)
}
sigR, err := rKey.Sign(rand.Reader, hashed[:], crypto.SHA256)
if err != nil {
t.Fatalf("err generating rsa sig:\n%v", err)
}
_, edKey, err := ed25519.GenerateKey(rand.Reader)
sigEd := ed25519.Sign(edKey, data[:])
if err != nil {
t.Fatalf("err generating ed25519 sig:\n%v", err)
}
for i, tt := range []struct {
in crypto.PrivateKey
typ pb.KeyType
sig []byte
}{
{
eKey,
ECDSA,
sigE,
},
{
privk,
Secp256k1,
sigK.Serialize(),
},
{
rKey,
RSA,
sigR,
},
{
&edKey,
Ed25519,
sigEd,
},
} {
t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
priv, pub, err := KeyPairFromStdKey(tt.in)
if err != nil {
t.Fatal(err)
}
if priv == nil || pub == nil {
t.Errorf("received nil private key or public key: %v, %v", priv, pub)
}
if priv == nil || priv.Type() != tt.typ {
t.Errorf("want %v; got %v", tt.typ, priv.Type())
}
v, err := pub.Verify(data[:], tt.sig)
if err != nil {
t.Error(err)
}
if !v {
t.Error("signature was not verified")
}
stdPub, err := PubKeyToStdKey(pub)
if stdPub == nil {
t.Errorf("err getting std public key from key: %v", err)
}
var stdPubBytes []byte
switch p := stdPub.(type) {
case *Secp256k1PublicKey:
stdPubBytes, err = p.Raw()
case ed25519.PublicKey:
stdPubBytes = []byte(p)
default:
stdPubBytes, err = x509.MarshalPKIXPublicKey(stdPub)
}
if err != nil {
t.Errorf("Error while marshaling %v key: %v", reflect.TypeOf(stdPub), err)
}
pubBytes, err := pub.Raw()
if err != nil {
t.Errorf("err getting raw bytes for %v key: %v", reflect.TypeOf(pub), err)
}
if !bytes.Equal(stdPubBytes, pubBytes) {
t.Errorf("err roundtripping %v key", reflect.TypeOf(pub))
}
stdPriv, err := PrivKeyToStdKey(priv)
if stdPub == nil {
t.Errorf("err getting std private key from key: %v", err)
}
var stdPrivBytes []byte
switch p := stdPriv.(type) {
case *Secp256k1PrivateKey:
stdPrivBytes, err = p.Raw()
case *ecdsa.PrivateKey:
stdPrivBytes, err = x509.MarshalECPrivateKey(p)
case *ed25519.PrivateKey:
stdPrivBytes = *p
case *rsa.PrivateKey:
stdPrivBytes = x509.MarshalPKCS1PrivateKey(p)
}
if err != nil {
t.Errorf("err marshaling %v key: %v", reflect.TypeOf(stdPriv), err)
}
privBytes, err := priv.Raw()
if err != nil {
t.Errorf("err getting raw bytes for %v key: %v", reflect.TypeOf(priv), err)
}
if !bytes.Equal(stdPrivBytes, privBytes) {
t.Errorf("err roundtripping %v key", reflect.TypeOf(priv))
}
})
}
}
func testKeyType(typ int, t *testing.T) {
bits := 512
if typ == RSA {
bits = 2048
}
sk, pk, err := test.RandTestKeyPair(typ, bits)
if err != nil {
t.Fatal(err)
}
testKeySignature(t, sk)
testKeyEncoding(t, sk)
testKeyEquals(t, sk)
testKeyEquals(t, pk)
}
func testKeySignature(t *testing.T, sk PrivKey) {
pk := sk.GetPublic()
text := make([]byte, 16)
if _, err := rand.Read(text); err != nil {
t.Fatal(err)
}
sig, err := sk.Sign(text)
if err != nil {
t.Fatal(err)
}
valid, err := pk.Verify(text, sig)
if err != nil {
t.Fatal(err)
}
if !valid {
t.Fatal("Invalid signature.")
}
}
func testKeyEncoding(t *testing.T, sk PrivKey) {
skbm, err := MarshalPrivateKey(sk)
if err != nil {
t.Fatal(err)
}
sk2, err := UnmarshalPrivateKey(skbm)
if err != nil {
t.Fatal(err)
}
if !sk.Equals(sk2) {
t.Error("Unmarshaled private key didn't match original.\n")
}
skbm2, err := MarshalPrivateKey(sk2)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(skbm, skbm2) {
t.Error("skb -> marshal -> unmarshal -> skb failed.\n", skbm, "\n", skbm2)
}
pk := sk.GetPublic()
pkbm, err := MarshalPublicKey(pk)
if err != nil {
t.Fatal(err)
}
pk2, err := UnmarshalPublicKey(pkbm)
if err != nil {
t.Fatal(err)
}
if !pk.Equals(pk2) {
t.Error("Unmarshaled public key didn't match original.\n")
}
pkbm2, err := MarshalPublicKey(pk)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(pkbm, pkbm2) {
t.Error("skb -> marshal -> unmarshal -> skb failed.\n", pkbm, "\n", pkbm2)
}
}
func testKeyEquals(t *testing.T, k Key) {
// kb, err := k.Raw()
// if err != nil {
// t.Fatal(err)
// }
if !KeyEqual(k, k) {
t.Fatal("Key not equal to itself.")
}
// bad test, relies on deep internals..
// if !KeyEqual(k, testkey(kb)) {
// t.Fatal("Key not equal to key with same bytes.")
// }
sk, pk, err := test.RandTestKeyPair(RSA, 2048)
if err != nil {
t.Fatal(err)
}
if KeyEqual(k, sk) {
t.Fatal("Keys should not equal.")
}
if KeyEqual(k, pk) {
t.Fatal("Keys should not equal.")
}
}
func TestUnknownCurveErrors(t *testing.T) {
_, _, err := GenerateEKeyPair("P-256")
if err != nil {
t.Fatal(err)
}
_, _, err = GenerateEKeyPair("error-please")
if err == nil {
t.Fatal("expected invalid key type to error")
}
}

View File

@ -1,104 +0,0 @@
//go:build openssl
// +build openssl
package crypto
import (
"sync"
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
"github.com/libp2p/go-openssl"
)
// define these as separate types so we can add more key types later and reuse
// code.
type opensslPublicKey struct {
key openssl.PublicKey
cacheLk sync.Mutex
cached []byte
}
type opensslPrivateKey struct {
key openssl.PrivateKey
}
func unmarshalOpensslPrivateKey(b []byte) (opensslPrivateKey, error) {
sk, err := openssl.LoadPrivateKeyFromDER(b)
if err != nil {
return opensslPrivateKey{}, err
}
return opensslPrivateKey{sk}, nil
}
func unmarshalOpensslPublicKey(b []byte) (opensslPublicKey, error) {
sk, err := openssl.LoadPublicKeyFromDER(b)
if err != nil {
return opensslPublicKey{}, err
}
return opensslPublicKey{key: sk, cached: b}, nil
}
// Verify compares a signature against input data
func (pk *opensslPublicKey) Verify(data, sig []byte) (bool, error) {
err := pk.key.VerifyPKCS1v15(openssl.SHA256_Method, data, sig)
return err == nil, err
}
func (pk *opensslPublicKey) Type() pb.KeyType {
switch pk.key.KeyType() {
case openssl.KeyTypeRSA:
return pb.KeyType_RSA
default:
return -1
}
}
func (pk *opensslPublicKey) Raw() ([]byte, error) {
return pk.key.MarshalPKIXPublicKeyDER()
}
// Equals checks whether this key is equal to another
func (pk *opensslPublicKey) Equals(k Key) bool {
k0, ok := k.(*RsaPublicKey)
if !ok {
return basicEquals(pk, k)
}
return pk.key.Equal(k0.opensslPublicKey.key)
}
// Sign returns a signature of the input data
func (sk *opensslPrivateKey) Sign(message []byte) ([]byte, error) {
return sk.key.SignPKCS1v15(openssl.SHA256_Method, message)
}
// GetPublic returns a public key
func (sk *opensslPrivateKey) GetPublic() PubKey {
return &opensslPublicKey{key: sk.key}
}
func (sk *opensslPrivateKey) Type() pb.KeyType {
switch sk.key.KeyType() {
case openssl.KeyTypeRSA:
return pb.KeyType_RSA
default:
return -1
}
}
func (sk *opensslPrivateKey) Raw() ([]byte, error) {
return sk.key.MarshalPKCS1PrivateKeyDER()
}
// Equals checks whether this key is equal to another
func (sk *opensslPrivateKey) Equals(k Key) bool {
k0, ok := k.(*RsaPrivateKey)
if !ok {
return basicEquals(sk, k)
}
return sk.key.Equal(k0.opensslPrivateKey.key)
}

View File

@ -1,11 +0,0 @@
PB = $(wildcard *.proto)
GO = $(PB:.proto=.pb.go)
all: $(GO)
%.pb.go: %.proto
protoc --proto_path=$(PWD)/../..:. --gogofaster_out=. $<
clean:
rm -f *.pb.go
rm -f *.go

View File

@ -1,625 +0,0 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: crypto.proto
package crypto_pb
import (
fmt "fmt"
github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type KeyType int32
const (
KeyType_RSA KeyType = 0
KeyType_Ed25519 KeyType = 1
KeyType_Secp256k1 KeyType = 2
KeyType_ECDSA KeyType = 3
)
var KeyType_name = map[int32]string{
0: "RSA",
1: "Ed25519",
2: "Secp256k1",
3: "ECDSA",
}
var KeyType_value = map[string]int32{
"RSA": 0,
"Ed25519": 1,
"Secp256k1": 2,
"ECDSA": 3,
}
func (x KeyType) Enum() *KeyType {
p := new(KeyType)
*p = x
return p
}
func (x KeyType) String() string {
return proto.EnumName(KeyType_name, int32(x))
}
func (x *KeyType) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(KeyType_value, data, "KeyType")
if err != nil {
return err
}
*x = KeyType(value)
return nil
}
func (KeyType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_527278fb02d03321, []int{0}
}
type PublicKey struct {
Type KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type"`
Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data"`
}
func (m *PublicKey) Reset() { *m = PublicKey{} }
func (m *PublicKey) String() string { return proto.CompactTextString(m) }
func (*PublicKey) ProtoMessage() {}
func (*PublicKey) Descriptor() ([]byte, []int) {
return fileDescriptor_527278fb02d03321, []int{0}
}
func (m *PublicKey) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PublicKey) XXX_Merge(src proto.Message) {
xxx_messageInfo_PublicKey.Merge(m, src)
}
func (m *PublicKey) XXX_Size() int {
return m.Size()
}
func (m *PublicKey) XXX_DiscardUnknown() {
xxx_messageInfo_PublicKey.DiscardUnknown(m)
}
var xxx_messageInfo_PublicKey proto.InternalMessageInfo
func (m *PublicKey) GetType() KeyType {
if m != nil {
return m.Type
}
return KeyType_RSA
}
func (m *PublicKey) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
type PrivateKey struct {
Type KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type"`
Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data"`
}
func (m *PrivateKey) Reset() { *m = PrivateKey{} }
func (m *PrivateKey) String() string { return proto.CompactTextString(m) }
func (*PrivateKey) ProtoMessage() {}
func (*PrivateKey) Descriptor() ([]byte, []int) {
return fileDescriptor_527278fb02d03321, []int{1}
}
func (m *PrivateKey) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PrivateKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PrivateKey.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PrivateKey) XXX_Merge(src proto.Message) {
xxx_messageInfo_PrivateKey.Merge(m, src)
}
func (m *PrivateKey) XXX_Size() int {
return m.Size()
}
func (m *PrivateKey) XXX_DiscardUnknown() {
xxx_messageInfo_PrivateKey.DiscardUnknown(m)
}
var xxx_messageInfo_PrivateKey proto.InternalMessageInfo
func (m *PrivateKey) GetType() KeyType {
if m != nil {
return m.Type
}
return KeyType_RSA
}
func (m *PrivateKey) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
func init() {
proto.RegisterEnum("crypto.pb.KeyType", KeyType_name, KeyType_value)
proto.RegisterType((*PublicKey)(nil), "crypto.pb.PublicKey")
proto.RegisterType((*PrivateKey)(nil), "crypto.pb.PrivateKey")
}
func init() { proto.RegisterFile("crypto.proto", fileDescriptor_527278fb02d03321) }
var fileDescriptor_527278fb02d03321 = []byte{
// 203 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0x2e, 0xaa, 0x2c,
0x28, 0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xf1, 0x92, 0x94, 0x82, 0xb9,
0x38, 0x03, 0x4a, 0x93, 0x72, 0x32, 0x93, 0xbd, 0x53, 0x2b, 0x85, 0x74, 0xb8, 0x58, 0x42, 0x2a,
0x0b, 0x52, 0x25, 0x18, 0x15, 0x98, 0x34, 0xf8, 0x8c, 0x84, 0xf4, 0xe0, 0xca, 0xf4, 0xbc, 0x53,
0x2b, 0x41, 0x32, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x81, 0x55, 0x09, 0x49, 0x70, 0xb1,
0xb8, 0x24, 0x96, 0x24, 0x4a, 0x30, 0x29, 0x30, 0x69, 0xf0, 0xc0, 0x64, 0x40, 0x22, 0x4a, 0x21,
0x5c, 0x5c, 0x01, 0x45, 0x99, 0x65, 0x89, 0x25, 0xa9, 0x54, 0x34, 0x55, 0xcb, 0x92, 0x8b, 0x1d,
0xaa, 0x41, 0x88, 0x9d, 0x8b, 0x39, 0x28, 0xd8, 0x51, 0x80, 0x41, 0x88, 0x9b, 0x8b, 0xdd, 0x35,
0xc5, 0xc8, 0xd4, 0xd4, 0xd0, 0x52, 0x80, 0x51, 0x88, 0x97, 0x8b, 0x33, 0x38, 0x35, 0xb9, 0xc0,
0xc8, 0xd4, 0x2c, 0xdb, 0x50, 0x80, 0x49, 0x88, 0x93, 0x8b, 0xd5, 0xd5, 0xd9, 0x25, 0xd8, 0x51,
0x80, 0xd9, 0x49, 0xe2, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63,
0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0x00, 0x01, 0x00,
0x00, 0xff, 0xff, 0x13, 0xbe, 0xd4, 0xff, 0x19, 0x01, 0x00, 0x00,
}
func (m *PublicKey) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PublicKey) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Data != nil {
i -= len(m.Data)
copy(dAtA[i:], m.Data)
i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data)))
i--
dAtA[i] = 0x12
}
i = encodeVarintCrypto(dAtA, i, uint64(m.Type))
i--
dAtA[i] = 0x8
return len(dAtA) - i, nil
}
func (m *PrivateKey) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PrivateKey) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PrivateKey) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Data != nil {
i -= len(m.Data)
copy(dAtA[i:], m.Data)
i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data)))
i--
dAtA[i] = 0x12
}
i = encodeVarintCrypto(dAtA, i, uint64(m.Type))
i--
dAtA[i] = 0x8
return len(dAtA) - i, nil
}
func encodeVarintCrypto(dAtA []byte, offset int, v uint64) int {
offset -= sovCrypto(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *PublicKey) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
n += 1 + sovCrypto(uint64(m.Type))
if m.Data != nil {
l = len(m.Data)
n += 1 + l + sovCrypto(uint64(l))
}
return n
}
func (m *PrivateKey) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
n += 1 + sovCrypto(uint64(m.Type))
if m.Data != nil {
l = len(m.Data)
n += 1 + l + sovCrypto(uint64(l))
}
return n
}
func sovCrypto(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozCrypto(x uint64) (n int) {
return sovCrypto(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *PublicKey) Unmarshal(dAtA []byte) error {
var hasFields [1]uint64
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCrypto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PublicKey: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
m.Type = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCrypto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Type |= KeyType(b&0x7F) << shift
if b < 0x80 {
break
}
}
hasFields[0] |= uint64(0x00000001)
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCrypto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthCrypto
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthCrypto
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
if m.Data == nil {
m.Data = []byte{}
}
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
default:
iNdEx = preIndex
skippy, err := skipCrypto(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthCrypto
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthCrypto
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if hasFields[0]&uint64(0x00000001) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Type")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Data")
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *PrivateKey) Unmarshal(dAtA []byte) error {
var hasFields [1]uint64
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCrypto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PrivateKey: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PrivateKey: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
m.Type = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCrypto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Type |= KeyType(b&0x7F) << shift
if b < 0x80 {
break
}
}
hasFields[0] |= uint64(0x00000001)
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCrypto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthCrypto
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthCrypto
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
if m.Data == nil {
m.Data = []byte{}
}
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
default:
iNdEx = preIndex
skippy, err := skipCrypto(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthCrypto
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthCrypto
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if hasFields[0]&uint64(0x00000001) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Type")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Data")
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipCrypto(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowCrypto
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowCrypto
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowCrypto
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthCrypto
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupCrypto
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthCrypto
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthCrypto = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowCrypto = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupCrypto = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -1,22 +0,0 @@
syntax = "proto2";
package crypto.pb;
option go_package = "github.com/libp2p/go-libp2p-core/crypto/pb";
enum KeyType {
RSA = 0;
Ed25519 = 1;
Secp256k1 = 2;
ECDSA = 3;
}
message PublicKey {
required KeyType Type = 1;
required bytes Data = 2;
}
message PrivateKey {
required KeyType Type = 1;
required bytes Data = 2;
}

View File

@ -1,25 +1,19 @@
package crypto
import (
"fmt"
"os"
"github.com/libp2p/go-libp2p/core/crypto"
)
// WeakRsaKeyEnv is an environment variable which, when set, lowers the
// minimum required bits of RSA keys to 512. This should be used exclusively in
// test situations.
const WeakRsaKeyEnv = "LIBP2P_ALLOW_WEAK_RSA_KEYS"
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.WeakRsaKeyEnv instead
const WeakRsaKeyEnv = crypto.WeakRsaKeyEnv
var MinRsaKeyBits = 2048
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.MinRsaKeyBits instead
var MinRsaKeyBits = crypto.MinRsaKeyBits
// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key
// that's smaller than MinRsaKeyBits bits. In test
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.ErrRsaKeyTooSmall instead
var ErrRsaKeyTooSmall error
func init() {
if _, ok := os.LookupEnv(WeakRsaKeyEnv); ok {
MinRsaKeyBits = 512
}
ErrRsaKeyTooSmall = fmt.Errorf("rsa keys must be >= %d bits to be useful", MinRsaKeyBits)
}

View File

@ -4,146 +4,33 @@
package crypto
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"errors"
"io"
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
"github.com/libp2p/go-libp2p-core/internal/catch"
"github.com/minio/sha256-simd"
"github.com/libp2p/go-libp2p/core/crypto"
)
// RsaPrivateKey is an rsa private key
type RsaPrivateKey struct {
sk rsa.PrivateKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.RsaPrivateKey instead
type RsaPrivateKey = crypto.RsaPrivateKey
// RsaPublicKey is an rsa public key
type RsaPublicKey struct {
k rsa.PublicKey
cached []byte
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.RsaPublicKey instead
type RsaPublicKey = crypto.RsaPublicKey
// GenerateRSAKeyPair generates a new rsa private and public key
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateRSAKeyPair
func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
if bits < MinRsaKeyBits {
return nil, nil, ErrRsaKeyTooSmall
}
priv, err := rsa.GenerateKey(src, bits)
if err != nil {
return nil, nil, err
}
pk := priv.PublicKey
return &RsaPrivateKey{sk: *priv}, &RsaPublicKey{k: pk}, nil
}
// Verify compares a signature against input data
func (pk *RsaPublicKey) Verify(data, sig []byte) (success bool, err error) {
defer func() {
catch.HandlePanic(recover(), &err, "RSA signature verification")
// To be safe
if err != nil {
success = false
}
}()
hashed := sha256.Sum256(data)
err = rsa.VerifyPKCS1v15(&pk.k, crypto.SHA256, hashed[:], sig)
if err != nil {
return false, err
}
return true, nil
}
func (pk *RsaPublicKey) Type() pb.KeyType {
return pb.KeyType_RSA
}
func (pk *RsaPublicKey) Raw() (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "RSA public-key marshaling") }()
return x509.MarshalPKIXPublicKey(&pk.k)
}
// Equals checks whether this key is equal to another
func (pk *RsaPublicKey) Equals(k Key) bool {
// make sure this is an rsa public key
other, ok := (k).(*RsaPublicKey)
if !ok {
return basicEquals(pk, k)
}
return pk.k.N.Cmp(other.k.N) == 0 && pk.k.E == other.k.E
}
// Sign returns a signature of the input data
func (sk *RsaPrivateKey) Sign(message []byte) (sig []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "RSA signing") }()
hashed := sha256.Sum256(message)
return rsa.SignPKCS1v15(rand.Reader, &sk.sk, crypto.SHA256, hashed[:])
}
// GetPublic returns a public key
func (sk *RsaPrivateKey) GetPublic() PubKey {
return &RsaPublicKey{k: sk.sk.PublicKey}
}
func (sk *RsaPrivateKey) Type() pb.KeyType {
return pb.KeyType_RSA
}
func (sk *RsaPrivateKey) Raw() (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "RSA private-key marshaling") }()
b := x509.MarshalPKCS1PrivateKey(&sk.sk)
return b, nil
}
// Equals checks whether this key is equal to another
func (sk *RsaPrivateKey) Equals(k Key) bool {
// make sure this is an rsa public key
other, ok := (k).(*RsaPrivateKey)
if !ok {
return basicEquals(sk, k)
}
a := sk.sk
b := other.sk
// Don't care about constant time. We're only comparing the public half.
return a.PublicKey.N.Cmp(b.PublicKey.N) == 0 && a.PublicKey.E == b.PublicKey.E
return crypto.GenerateRSAKeyPair(bits, src)
}
// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalRsaPrivateKey
func UnmarshalRsaPrivateKey(b []byte) (key PrivKey, err error) {
defer func() { catch.HandlePanic(recover(), &err, "RSA private-key unmarshaling") }()
sk, err := x509.ParsePKCS1PrivateKey(b)
if err != nil {
return nil, err
}
if sk.N.BitLen() < MinRsaKeyBits {
return nil, ErrRsaKeyTooSmall
}
return &RsaPrivateKey{sk: *sk}, nil
return crypto.UnmarshalRsaPrivateKey(b)
}
// UnmarshalRsaPublicKey returns a public key from the input x509 bytes
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalRsaPublicKey
func UnmarshalRsaPublicKey(b []byte) (key PubKey, err error) {
defer func() { catch.HandlePanic(recover(), &err, "RSA public-key unmarshaling") }()
pub, err := x509.ParsePKIXPublicKey(b)
if err != nil {
return nil, err
}
pk, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, errors.New("not actually an rsa public key")
}
if pk.N.BitLen() < MinRsaKeyBits {
return nil, ErrRsaKeyTooSmall
}
return &RsaPublicKey{k: *pk}, nil
return crypto.UnmarshalRsaPublicKey(b)
}

View File

@ -4,66 +4,33 @@
package crypto
import (
"errors"
"io"
openssl "github.com/libp2p/go-openssl"
"github.com/libp2p/go-libp2p/core/crypto"
)
// RsaPrivateKey is an rsa private key
type RsaPrivateKey struct {
opensslPrivateKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.RsaPrivateKey instead
type RsaPrivateKey = crypto.RsaPrivateKey
// RsaPublicKey is an rsa public key
type RsaPublicKey struct {
opensslPublicKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.RsaPublicKey instead
type RsaPublicKey = crypto.RsaPublicKey
// GenerateRSAKeyPair generates a new rsa private and public key
func GenerateRSAKeyPair(bits int, _ io.Reader) (PrivKey, PubKey, error) {
if bits < MinRsaKeyBits {
return nil, nil, ErrRsaKeyTooSmall
}
key, err := openssl.GenerateRSAKey(bits)
if err != nil {
return nil, nil, err
}
return &RsaPrivateKey{opensslPrivateKey{key}}, &RsaPublicKey{opensslPublicKey{key: key}}, nil
}
// GetPublic returns a public key
func (sk *RsaPrivateKey) GetPublic() PubKey {
return &RsaPublicKey{opensslPublicKey{key: sk.opensslPrivateKey.key}}
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateRSAKeyPair instead
func GenerateRSAKeyPair(bits int, r io.Reader) (PrivKey, PubKey, error) {
return crypto.GenerateRSAKeyPair(bits, r)
}
// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalRsaPrivateKey instead
func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) {
key, err := unmarshalOpensslPrivateKey(b)
if err != nil {
return nil, err
}
if 8*key.key.Size() < MinRsaKeyBits {
return nil, ErrRsaKeyTooSmall
}
if key.Type() != RSA {
return nil, errors.New("not actually an rsa public key")
}
return &RsaPrivateKey{key}, nil
return crypto.UnmarshalRsaPrivateKey(b)
}
// UnmarshalRsaPublicKey returns a public key from the input x509 bytes
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalRsaPublicKey instead
func UnmarshalRsaPublicKey(b []byte) (PubKey, error) {
key, err := unmarshalOpensslPublicKey(b)
if err != nil {
return nil, err
}
if 8*key.key.Size() < MinRsaKeyBits {
return nil, ErrRsaKeyTooSmall
}
if key.Type() != RSA {
return nil, errors.New("not actually an rsa public key")
}
return &RsaPublicKey{key}, nil
return crypto.UnmarshalRsaPublicKey(b)
}

View File

@ -1,124 +0,0 @@
package crypto
import (
"crypto/rand"
"testing"
)
func TestRSABasicSignAndVerify(t *testing.T) {
priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader)
if err != nil {
t.Fatal(err)
}
data := []byte("hello! and welcome to some awesome crypto primitives")
sig, err := priv.Sign(data)
if err != nil {
t.Fatal(err)
}
ok, err := pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didnt match")
}
// change data
data[0] = ^data[0]
ok, err = pub.Verify(data, sig)
if err == nil {
t.Fatal("should have produced a verification error")
}
if ok {
t.Fatal("signature matched and shouldn't")
}
}
func TestRSASmallKey(t *testing.T) {
_, _, err := GenerateRSAKeyPair(MinRsaKeyBits/2, rand.Reader)
if err != ErrRsaKeyTooSmall {
t.Fatal("should have refused to create small RSA key")
}
MinRsaKeyBits /= 2
badPriv, badPub, err := GenerateRSAKeyPair(MinRsaKeyBits, rand.Reader)
if err != nil {
t.Fatalf("should have succeeded, got: %s", err)
}
pubBytes, err := MarshalPublicKey(badPub)
if err != nil {
t.Fatal(err)
}
privBytes, err := MarshalPrivateKey(badPriv)
if err != nil {
t.Fatal(err)
}
MinRsaKeyBits *= 2
_, err = UnmarshalPublicKey(pubBytes)
if err != ErrRsaKeyTooSmall {
t.Fatal("should have refused to unmarshal a weak key")
}
_, err = UnmarshalPrivateKey(privBytes)
if err != ErrRsaKeyTooSmall {
t.Fatal("should have refused to unmarshal a weak key")
}
}
func TestRSASignZero(t *testing.T) {
priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader)
if err != nil {
t.Fatal(err)
}
data := make([]byte, 0)
sig, err := priv.Sign(data)
if err != nil {
t.Fatal(err)
}
ok, err := pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didn't match")
}
}
func TestRSAMarshalLoop(t *testing.T) {
priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader)
if err != nil {
t.Fatal(err)
}
privB, err := MarshalPrivateKey(priv)
if err != nil {
t.Fatal(err)
}
privNew, err := UnmarshalPrivateKey(privB)
if err != nil {
t.Fatal(err)
}
if !priv.Equals(privNew) || !privNew.Equals(priv) {
t.Fatal("keys are not equal")
}
pubB, err := MarshalPublicKey(pub)
if err != nil {
t.Fatal(err)
}
pubNew, err := UnmarshalPublicKey(pubB)
if err != nil {
t.Fatal(err)
}
if !pub.Equals(pubNew) || !pubNew.Equals(pub) {
t.Fatal("keys are not equal")
}
}

View File

@ -1,127 +1,33 @@
package crypto
import (
"fmt"
"io"
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
"github.com/libp2p/go-libp2p-core/internal/catch"
btcec "github.com/btcsuite/btcd/btcec/v2"
btcececdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/minio/sha256-simd"
"github.com/libp2p/go-libp2p/core/crypto"
)
// Secp256k1PrivateKey is an Secp256k1 private key
type Secp256k1PrivateKey btcec.PrivateKey
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.Secp256k1PrivateKey instead
type Secp256k1PrivateKey = crypto.Secp256k1PrivateKey
// Secp256k1PublicKey is an Secp256k1 public key
type Secp256k1PublicKey btcec.PublicKey
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.Secp256k1PublicKey instead
type Secp256k1PublicKey = crypto.Secp256k1PublicKey
// GenerateSecp256k1Key generates a new Secp256k1 private and public key pair
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.GenerateSecp256k1Key instead
func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) {
privk, err := btcec.NewPrivateKey()
if err != nil {
return nil, nil, err
}
k := (*Secp256k1PrivateKey)(privk)
return k, k.GetPublic(), nil
return crypto.GenerateSecp256k1Key(src)
}
// UnmarshalSecp256k1PrivateKey returns a private key from bytes
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalSecp256k1PrivateKey instead
func UnmarshalSecp256k1PrivateKey(data []byte) (k PrivKey, err error) {
if len(data) != btcec.PrivKeyBytesLen {
return nil, fmt.Errorf("expected secp256k1 data size to be %d", btcec.PrivKeyBytesLen)
}
defer func() { catch.HandlePanic(recover(), &err, "secp256k1 private-key unmarshal") }()
privk, _ := btcec.PrivKeyFromBytes(data)
return (*Secp256k1PrivateKey)(privk), nil
return crypto.UnmarshalSecp256k1PrivateKey(data)
}
// UnmarshalSecp256k1PublicKey returns a public key from bytes
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalSecp256k1PublicKey instead
func UnmarshalSecp256k1PublicKey(data []byte) (_k PubKey, err error) {
defer func() { catch.HandlePanic(recover(), &err, "secp256k1 public-key unmarshal") }()
k, err := btcec.ParsePubKey(data)
if err != nil {
return nil, err
}
return (*Secp256k1PublicKey)(k), nil
}
// Type returns the private key type
func (k *Secp256k1PrivateKey) Type() pb.KeyType {
return pb.KeyType_Secp256k1
}
// Raw returns the bytes of the key
func (k *Secp256k1PrivateKey) Raw() ([]byte, error) {
return (*btcec.PrivateKey)(k).Serialize(), nil
}
// Equals compares two private keys
func (k *Secp256k1PrivateKey) Equals(o Key) bool {
sk, ok := o.(*Secp256k1PrivateKey)
if !ok {
return basicEquals(k, o)
}
return k.GetPublic().Equals(sk.GetPublic())
}
// Sign returns a signature from input data
func (k *Secp256k1PrivateKey) Sign(data []byte) (_sig []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "secp256k1 signing") }()
key := (*btcec.PrivateKey)(k)
hash := sha256.Sum256(data)
sig := btcececdsa.Sign(key, hash[:])
return sig.Serialize(), nil
}
// GetPublic returns a public key
func (k *Secp256k1PrivateKey) GetPublic() PubKey {
return (*Secp256k1PublicKey)((*btcec.PrivateKey)(k).PubKey())
}
// Type returns the public key type
func (k *Secp256k1PublicKey) Type() pb.KeyType {
return pb.KeyType_Secp256k1
}
// Raw returns the bytes of the key
func (k *Secp256k1PublicKey) Raw() (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "secp256k1 public key marshaling") }()
return (*btcec.PublicKey)(k).SerializeCompressed(), nil
}
// Equals compares two public keys
func (k *Secp256k1PublicKey) Equals(o Key) bool {
sk, ok := o.(*Secp256k1PublicKey)
if !ok {
return basicEquals(k, o)
}
return (*btcec.PublicKey)(k).IsEqual((*btcec.PublicKey)(sk))
}
// Verify compares a signature against the input data
func (k *Secp256k1PublicKey) Verify(data []byte, sigStr []byte) (success bool, err error) {
defer func() {
catch.HandlePanic(recover(), &err, "secp256k1 signature verification")
// To be extra safe.
if err != nil {
success = false
}
}()
sig, err := btcececdsa.ParseDERSignature(sigStr)
if err != nil {
return false, err
}
hash := sha256.Sum256(data)
return sig.Verify(hash[:], (*btcec.PublicKey)(k)), nil
return crypto.UnmarshalSecp256k1PublicKey(data)
}

View File

@ -1,96 +0,0 @@
package crypto
import (
"crypto/rand"
"testing"
)
func TestSecp256k1BasicSignAndVerify(t *testing.T) {
priv, pub, err := GenerateSecp256k1Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
data := []byte("hello! and welcome to some awesome crypto primitives")
sig, err := priv.Sign(data)
if err != nil {
t.Fatal(err)
}
ok, err := pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didnt match")
}
// change data
data[0] = ^data[0]
ok, err = pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if ok {
t.Fatal("signature matched and shouldn't")
}
}
func TestSecp256k1SignZero(t *testing.T) {
priv, pub, err := GenerateSecp256k1Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
data := make([]byte, 0)
sig, err := priv.Sign(data)
if err != nil {
t.Fatal(err)
}
ok, err := pub.Verify(data, sig)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("signature didn't match")
}
}
func TestSecp256k1MarshalLoop(t *testing.T) {
priv, pub, err := GenerateSecp256k1Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
privB, err := MarshalPrivateKey(priv)
if err != nil {
t.Fatal(err)
}
privNew, err := UnmarshalPrivateKey(privB)
if err != nil {
t.Fatal(err)
}
if !priv.Equals(privNew) || !privNew.Equals(priv) {
t.Fatal("keys are not equal")
}
pubB, err := MarshalPublicKey(pub)
if err != nil {
t.Fatal(err)
}
pubNew, err := UnmarshalPublicKey(pubB)
if err != nil {
t.Fatal(err)
}
if !pub.Equals(pubNew) || !pubNew.Equals(pub) {
t.Fatal("keys are not equal")
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
 1A½`jPLDò4”ØóNò[¹µ-ªÐX¾ƒ¶àF±X

View File

@ -1 +0,0 @@
!5@­„*ψ¤5Q©Mƒƒ¥U©&Pk<50>ωS<CF89>磡³ΦΆ

View File

@ -1 +0,0 @@
0D 1§Ö3ÂóäZŤCuú¨Ü›˘@ĹőłĘŇČţLó<4C>ň IęŤ!źE†<EFBFBD>ŇGuŐCꏲ<EFBFBD>pCGű5I<@;ÂÂY˛ťž

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,27 +1,20 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/discovery.
//
// Package discovery provides service advertisement and peer discovery interfaces for libp2p.
package discovery
import (
"context"
"time"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/discovery"
)
// Advertiser is an interface for advertising services
type Advertiser interface {
// Advertise advertises a service
Advertise(ctx context.Context, ns string, opts ...Option) (time.Duration, error)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/discovery.Advertiser instead
type Advertiser = discovery.Advertiser
// Discoverer is an interface for peer discovery
type Discoverer interface {
// FindPeers discovers peers providing a service
FindPeers(ctx context.Context, ns string, opts ...Option) (<-chan peer.AddrInfo, error)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/discovery.Discoverer instead
type Discoverer = discovery.Discoverer
// Discovery is an interface that combines service advertisement and peer discovery
type Discovery interface {
Advertiser
Discoverer
}
// Deprecated: use github.com/libp2p/go-libp2p/core/discovery.Discovery instead
type Discovery = discovery.Discovery

View File

@ -1,41 +1,27 @@
package discovery
import "time"
import (
"time"
"github.com/libp2p/go-libp2p/core/discovery"
)
// DiscoveryOpt is a single discovery option.
type Option func(opts *Options) error
// Deprecated: use github.com/libp2p/go-libp2p/core/discovery.Option instead
type Option = discovery.Option
// DiscoveryOpts is a set of discovery options.
type Options struct {
Ttl time.Duration
Limit int
// Other (implementation-specific) options
Other map[interface{}]interface{}
}
// Apply applies the given options to this DiscoveryOpts
func (opts *Options) Apply(options ...Option) error {
for _, o := range options {
if err := o(opts); err != nil {
return err
}
}
return nil
}
// Deprecated: use github.com/libp2p/go-libp2p/core/discovery.Options instead
type Options = discovery.Options
// TTL is an option that provides a hint for the duration of an advertisement
// Deprecated: use github.com/libp2p/go-libp2p/core/discovery.TTL instead
func TTL(ttl time.Duration) Option {
return func(opts *Options) error {
opts.Ttl = ttl
return nil
}
return discovery.TTL(ttl)
}
// Limit is an option that provides an upper bound on the peer count for discovery
// Deprecated: use github.com/libp2p/go-libp2p/core/discovery.Limit instead
func Limit(limit int) Option {
return func(opts *Options) error {
opts.Limit = limit
return nil
}
return discovery.Limit(limit)
}

View File

@ -1,40 +1,38 @@
package event
import (
"github.com/libp2p/go-libp2p-core/record"
ma "github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p/core/event"
)
// AddrAction represents an action taken on one of a Host's listen addresses.
// It is used to add context to address change events in EvtLocalAddressesUpdated.
type AddrAction int
// Deprecated: use github.com/libp2p/go-libp2p/core/event.AddrAction instead
type AddrAction = event.AddrAction
const (
// Unknown means that the event producer was unable to determine why the address
// is in the current state.
Unknown AddrAction = iota
// Deprecated: use github.com/libp2p/go-libp2p/core/event.Unknown instead
Unknown = event.Unknown
// Added means that the address is new and was not present prior to the event.
Added
// Deprecated: use github.com/libp2p/go-libp2p/core/event.Added instead
Added = event.Added
// Maintained means that the address was not altered between the current and
// previous states.
Maintained
// Deprecated: use github.com/libp2p/go-libp2p/core/event.Maintained instead
Maintained = event.Maintained
// Removed means that the address was removed from the Host.
Removed
// Deprecated: use github.com/libp2p/go-libp2p/core/event.Removed instead
Removed = event.Removed
)
// UpdatedAddress is used in the EvtLocalAddressesUpdated event to convey
// address change information.
type UpdatedAddress struct {
// Address contains the address that was updated.
Address ma.Multiaddr
// Action indicates what action was taken on the address during the
// event. May be Unknown if the event producer cannot produce diffs.
Action AddrAction
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.UpdatedAddress instead
type UpdatedAddress = event.UpdatedAddress
// EvtLocalAddressesUpdated should be emitted when the set of listen addresses for
// the local host changes. This may happen for a number of reasons. For example,
@ -60,23 +58,5 @@ type UpdatedAddress struct {
// for the Current set of listen addresses, wrapped in a record.Envelope and signed by the Host's private key.
// This record can be shared with other peers to inform them of what we believe are our diallable addresses
// a secure and authenticated way.
type EvtLocalAddressesUpdated struct {
// Diffs indicates whether this event contains a diff of the Host's previous
// address set.
Diffs bool
// Current contains all current listen addresses for the Host.
// If Diffs == true, the Action field of each UpdatedAddress will tell
// you whether an address was Added, or was Maintained from the previous
// state.
Current []UpdatedAddress
// Removed contains addresses that were removed from the Host.
// This field is only set when Diffs == true.
Removed []UpdatedAddress
// SignedPeerRecord contains our own updated peer.PeerRecord, listing the addresses enumerated in Current.
// wrapped in a record.Envelope and signed by the Host's private key.
SignedPeerRecord *record.Envelope
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EvtLocalAddressesUpdated instead
type EvtLocalAddressesUpdated = event.EvtLocalAddressesUpdated

View File

@ -1,97 +1,34 @@
package event
import (
"io"
"reflect"
"github.com/libp2p/go-libp2p/core/event"
)
// SubscriptionOpt represents a subscriber option. Use the options exposed by the implementation of choice.
type SubscriptionOpt = func(interface{}) error
// Deprecated: use github.com/libp2p/go-libp2p/core/event.SubscriptionOpt instead
type SubscriptionOpt = event.SubscriptionOpt
// EmitterOpt represents an emitter option. Use the options exposed by the implementation of choice.
type EmitterOpt = func(interface{}) error
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EmitterOpt instead
type EmitterOpt = event.EmitterOpt
// CancelFunc closes a subscriber.
type CancelFunc = func()
// wildcardSubscriptionType is a virtual type to represent wildcard
// subscriptions.
type wildcardSubscriptionType interface{}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.CancelFunc instead
type CancelFunc = event.CancelFunc
// WildcardSubscription is the type to subscribe to to receive all events
// emitted in the eventbus.
var WildcardSubscription = new(wildcardSubscriptionType)
// Deprecated: use github.com/libp2p/go-libp2p/core/event.WildcardSubscription instead
var WildcardSubscription = event.WildcardSubscription
// Emitter represents an actor that emits events onto the eventbus.
type Emitter interface {
io.Closer
// Emit emits an event onto the eventbus. If any channel subscribed to the topic is blocked,
// calls to Emit will block.
//
// Calling this function with wrong event type will cause a panic.
Emit(evt interface{}) error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.Emitter instead
type Emitter = event.Emitter
// Subscription represents a subscription to one or multiple event types.
type Subscription interface {
io.Closer
// Out returns the channel from which to consume events.
Out() <-chan interface{}
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.Subscription instead
type Subscription = event.Subscription
// Bus is an interface for a type-based event delivery system.
type Bus interface {
// Subscribe creates a new Subscription.
//
// eventType can be either a pointer to a single event type, or a slice of pointers to
// subscribe to multiple event types at once, under a single subscription (and channel).
//
// Failing to drain the channel may cause publishers to block.
//
// If you want to subscribe to ALL events emitted in the bus, use
// `WildcardSubscription` as the `eventType`:
//
// eventbus.Subscribe(WildcardSubscription)
//
// Simple example
//
// sub, err := eventbus.Subscribe(new(EventType))
// defer sub.Close()
// for e := range sub.Out() {
// event := e.(EventType) // guaranteed safe
// [...]
// }
//
// Multi-type example
//
// sub, err := eventbus.Subscribe([]interface{}{new(EventA), new(EventB)})
// defer sub.Close()
// for e := range sub.Out() {
// select e.(type):
// case EventA:
// [...]
// case EventB:
// [...]
// }
// }
Subscribe(eventType interface{}, opts ...SubscriptionOpt) (Subscription, error)
// Emitter creates a new event emitter.
//
// eventType accepts typed nil pointers, and uses the type information for wiring purposes.
//
// Example:
// em, err := eventbus.Emitter(new(EventT))
// defer em.Close() // MUST call this after being done with the emitter
// em.Emit(EventT{})
Emitter(eventType interface{}, opts ...EmitterOpt) (Emitter, error)
// GetAllEventTypes returns all the event types that this bus knows about
// (having emitters and subscribers). It omits the WildcardSubscription.
//
// The caller is guaranteed that this function will only return value types;
// no pointer types will be returned.
GetAllEventTypes() []reflect.Type
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.Bus instead
type Bus = event.Bus

View File

@ -1,7 +1,10 @@
package event
import "github.com/libp2p/go-libp2p/core/event"
// RawJSON is a type that contains a raw JSON string.
type RawJSON string
// Deprecated: use github.com/libp2p/go-libp2p/core/event.RawJSON instead
type RawJSON = event.RawJSON
// GenericDHTEvent is a type that encapsulates an actual DHT event by carrying
// its raw JSON.
@ -12,10 +15,5 @@ type RawJSON string
//
// EXPERIMENTAL: this will likely be removed if/when the DHT event types are
// hoisted to core, and the DHT event system is reconciled with the eventbus.
type GenericDHTEvent struct {
// Type is the type of the DHT event that occured.
Type string
// Raw is the raw JSON representation of the event payload.
Raw RawJSON
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.GenericDHTEvent instead
type GenericDHTEvent = event.GenericDHTEvent

View File

@ -1,11 +1,13 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/event.
//
// Package event contains the abstractions for a local event bus, along with the standard events
// that libp2p subsystems may emit.
//
// Source code is arranged as follows:
// * doc.go: this file.
// * bus.go: abstractions for the event bus.
// * rest: event structs, sensibly categorised in files by entity, and following this naming convention:
// Evt[Entity (noun)][Event (verb past tense / gerund)]
// The past tense is used to convey that something happened, whereas the gerund form of the verb (-ing)
// expresses that a process is in progress. Examples: EvtConnEstablishing, EvtConnEstablished.
// - doc.go: this file.
// - bus.go: abstractions for the event bus.
// - rest: event structs, sensibly categorised in files by entity, and following this naming convention:
// Evt[Entity (noun)][Event (verb past tense / gerund)]
// The past tense is used to convey that something happened, whereas the gerund form of the verb (-ing)
// expresses that a process is in progress. Examples: EvtConnEstablishing, EvtConnEstablished.
package event

View File

@ -1,17 +1,13 @@
package event
import "github.com/libp2p/go-libp2p-core/peer"
import (
"github.com/libp2p/go-libp2p/core/event"
)
// EvtPeerIdentificationCompleted is emitted when the initial identification round for a peer is completed.
type EvtPeerIdentificationCompleted struct {
// Peer is the ID of the peer whose identification succeeded.
Peer peer.ID
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EvtPeerIdentificationCompleted instead
type EvtPeerIdentificationCompleted = event.EvtPeerIdentificationCompleted
// EvtPeerIdentificationFailed is emitted when the initial identification round for a peer failed.
type EvtPeerIdentificationFailed struct {
// Peer is the ID of the peer whose identification failed.
Peer peer.ID
// Reason is the reason why identification failed.
Reason error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EvtPeerIdentificationFailed instead
type EvtPeerIdentificationFailed = event.EvtPeerIdentificationFailed

View File

@ -1,18 +1,13 @@
package event
import "github.com/libp2p/go-libp2p-core/network"
import (
"github.com/libp2p/go-libp2p/core/event"
)
// EvtNATDeviceTypeChanged is an event struct to be emitted when the type of the NAT device changes for a Transport Protocol.
//
// Note: This event is meaningful ONLY if the AutoNAT Reachability is Private.
// Consumers of this event should ALSO consume the `EvtLocalReachabilityChanged` event and interpret
// this event ONLY if the Reachability on the `EvtLocalReachabilityChanged` is Private.
type EvtNATDeviceTypeChanged struct {
// TransportProtocol is the Transport Protocol for which the NAT Device Type has been determined.
TransportProtocol network.NATTransportProtocol
// NatDeviceType indicates the type of the NAT Device for the Transport Protocol.
// Currently, it can be either a `Cone NAT` or a `Symmetric NAT`. Please see the detailed documentation
// on `network.NATDeviceType` enumerations for a better understanding of what these types mean and
// how they impact Connectivity and Hole Punching.
NatDeviceType network.NATDeviceType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EvtNATDeviceTypeChanged instead
type EvtNATDeviceTypeChanged = event.EvtNATDeviceTypeChanged

View File

@ -1,55 +1,50 @@
package event
import (
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/event"
)
// EvtPeerConnectednessChanged should be emitted every time the "connectedness" to a
// given peer changes. Specifically, this event is emitted in the following
// cases:
//
// * Connectedness = Connected: Every time we transition from having no
// connections to a peer to having at least one connection to the peer.
// * Connectedness = NotConnected: Every time we transition from having at least
// one connection to a peer to having no connections to the peer.
// - Connectedness = Connected: Every time we transition from having no
// connections to a peer to having at least one connection to the peer.
// - Connectedness = NotConnected: Every time we transition from having at least
// one connection to a peer to having no connections to the peer.
//
// Additional connectedness states may be added in the future. This list should
// not be considered exhaustive.
//
// Take note:
//
// * It's possible to have _multiple_ connections to a given peer.
// * Both libp2p and networks are asynchronous.
// - It's possible to have _multiple_ connections to a given peer.
// - Both libp2p and networks are asynchronous.
//
// This means that all of the following situations are possible:
//
// A connection is cut and is re-established:
//
// * Peer A observes a transition from Connected -> NotConnected -> Connected
// * Peer B observes a transition from Connected -> NotConnected -> Connected
// - Peer A observes a transition from Connected -> NotConnected -> Connected
// - Peer B observes a transition from Connected -> NotConnected -> Connected
//
// Explanation: Both peers observe the connection die. This is the "nice" case.
//
// A connection is cut and is re-established.
//
// * Peer A observes a transition from Connected -> NotConnected -> Connected.
// * Peer B observes no transition.
// - Peer A observes a transition from Connected -> NotConnected -> Connected.
// - Peer B observes no transition.
//
// Explanation: Peer A re-establishes the dead connection. Peer B observes the
// new connection form before it observes the old connection die.
//
// A connection is cut:
//
// * Peer A observes no transition.
// * Peer B observes no transition.
// - Peer A observes no transition.
// - Peer B observes no transition.
//
// Explanation: There were two connections and one was cut. This connection
// might have been in active use but neither peer will observe a change in
// "connectedness". Peers should always make sure to re-try network requests.
type EvtPeerConnectednessChanged struct {
// Peer is the remote peer who's connectedness has changed.
Peer peer.ID
// Connectedness is the new connectedness state.
Connectedness network.Connectedness
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EvtPeerConnectednessChanged instead
type EvtPeerConnectednessChanged = event.EvtPeerConnectednessChanged

View File

@ -1,26 +1,15 @@
package event
import (
peer "github.com/libp2p/go-libp2p-core/peer"
protocol "github.com/libp2p/go-libp2p-core/protocol"
"github.com/libp2p/go-libp2p/core/event"
)
// EvtPeerProtocolsUpdated should be emitted when a peer we're connected to adds or removes protocols from their stack.
type EvtPeerProtocolsUpdated struct {
// Peer is the peer whose protocols were updated.
Peer peer.ID
// Added enumerates the protocols that were added by this peer.
Added []protocol.ID
// Removed enumerates the protocols that were removed by this peer.
Removed []protocol.ID
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EvtPeerProtocolsUpdated instead
type EvtPeerProtocolsUpdated = event.EvtPeerProtocolsUpdated
// EvtLocalProtocolsUpdated should be emitted when stream handlers are attached or detached from the local host.
// For handlers attached with a matcher predicate (host.SetStreamHandlerMatch()), only the protocol ID will be
// included in this event.
type EvtLocalProtocolsUpdated struct {
// Added enumerates the protocols that were added locally.
Added []protocol.ID
// Removed enumerates the protocols that were removed locally.
Removed []protocol.ID
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EvtLocalProtocolsUpdated instead
type EvtLocalProtocolsUpdated = event.EvtLocalProtocolsUpdated

View File

@ -1,13 +1,12 @@
package event
import (
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p/core/event"
)
// EvtLocalReachabilityChanged is an event struct to be emitted when the local's
// node reachability changes state.
//
// This event is usually emitted by the AutoNAT subsystem.
type EvtLocalReachabilityChanged struct {
Reachability network.Reachability
}
// Deprecated: use github.com/libp2p/go-libp2p/core/event.EvtLocalReachabilityChanged instead
type EvtLocalReachabilityChanged = event.EvtLocalReachabilityChanged

57
go.mod
View File

@ -3,40 +3,37 @@ module github.com/libp2p/go-libp2p-core
go 1.17
require (
github.com/benbjohnson/clock v1.3.0
github.com/btcsuite/btcd/btcec/v2 v2.1.3
github.com/gogo/protobuf v1.3.1
github.com/ipfs/go-cid v0.2.0
github.com/ipfs/go-log/v2 v2.5.1
github.com/libp2p/go-buffer-pool v0.0.2
github.com/libp2p/go-flow-metrics v0.1.0
github.com/libp2p/go-msgio v0.0.6
github.com/libp2p/go-openssl v0.0.7
github.com/minio/sha256-simd v1.0.0
github.com/mr-tron/base58 v1.2.0
github.com/multiformats/go-multiaddr v0.4.1
github.com/multiformats/go-multicodec v0.4.1
github.com/multiformats/go-multihash v0.0.15
github.com/multiformats/go-varint v0.0.6
github.com/stretchr/testify v1.7.0
github.com/libp2p/go-libp2p v0.22.0
github.com/multiformats/go-multiaddr v0.6.0
)
require (
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/klauspost/cpuid/v2 v2.0.4 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/multiformats/go-base32 v0.0.3 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/klauspost/cpuid/v2 v2.1.0 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
github.com/libp2p/go-msgio v0.2.0 // indirect
github.com/libp2p/go-openssl v0.1.0 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.0.4 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-multibase v0.0.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/multiformats/go-multibase v0.1.1 // indirect
github.com/multiformats/go-multicodec v0.5.0 // indirect
github.com/multiformats/go-multihash v0.2.1 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.19.1 // indirect
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.22.0 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
lukechampine.com/blake3 v1.1.7 // indirect
)

839
go.sum
View File

@ -1,133 +1,918 @@
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=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
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/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
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/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/btcsuite/btcd/btcec/v2 v2.1.3 h1:xM/n3yIhHAhHy04z4i43C8p4ehixJZMsnrVJkgl+MTE=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
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/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE=
github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
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-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
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/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
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.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
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.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
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/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
github.com/ipfs/go-cid v0.2.0 h1:01JTiihFq9en9Vz0lc0VDWvZe/uBonGpzo4THP0vcQ0=
github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro=
github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk=
github.com/ipfs/go-datastore v0.5.1/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk=
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek=
github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ=
github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0=
github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
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/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs=
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
github.com/libp2p/go-msgio v0.0.6 h1:lQ7Uc0kS1wb1EfRxO2Eir/RJoHkHn7t6o+EiwsYIKJA=
github.com/libp2p/go-libp2p v0.22.0 h1:2Tce0kHOp5zASFKJbNzRElvh0iZwdtG5uZheNW8chIw=
github.com/libp2p/go-libp2p v0.22.0/go.mod h1:UDolmweypBSjQb2f7xutPnwZ/fxioLbMBxSjRksxxU4=
github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI=
github.com/libp2p/go-libp2p-core v0.19.0/go.mod h1:AkA+FUKQfYt1FLNef5fOPlo/naAWjKy/RCjkcPjqzYg=
github.com/libp2p/go-libp2p-testing v0.11.0/go.mod h1:qG4sF27dfKFoK9KlVzK2y52LQKhp0VEmLjV5aDqr1Hg=
github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU=
github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA=
github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw=
github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU=
github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY=
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.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI=
github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
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/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k=
github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k=
github.com/libp2p/go-yamux/v3 v3.1.2/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4=
github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs=
github.com/lucas-clemente/quic-go v0.28.1/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s=
github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
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.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms=
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU=
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s=
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 v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/mr-tron/base58 v1.1.3/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/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE=
github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM=
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
github.com/multiformats/go-multiaddr v0.4.1 h1:Pq37uLx3hsyNlTDir7FZyU8+cFCTqd5y1KiM2IzOutI=
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.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM=
github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
github.com/multiformats/go-multiaddr v0.6.0 h1:qMnoOPj2s8xxPU5kZ57Cqdr0hHhARz7mFsPMIiYNqzg=
github.com/multiformats/go-multiaddr v0.6.0/go.mod h1:F4IpaKZuPP360tOMn2Tpyu0At8w23aRyVqeK0DbFeGM=
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
github.com/multiformats/go-multicodec v0.4.1 h1:BSJbf+zpghcZMZrwTYBGwy0CPcVZGWiC72Cp8bBd4R4=
github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI=
github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8=
github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ=
github.com/multiformats/go-multicodec v0.5.0 h1:EgU6cBe/D7WRwQb1KmnBvU7lrcFGMggZVTPtOW9dDHs=
github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues=
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-multihash v0.0.15 h1:hWOPdrNqDjwHDx82vsYGSDZNyktOJJ2dzZJzFkOV1jM=
github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg=
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-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg=
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.5/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.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
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/sanitized_anchor_name v1.0.0/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/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
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/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
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.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
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.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/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
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/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0=
go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U=
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-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/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-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf h1:B2n+Zi5QeYRDAEodEu72OS36gmTWjgpXr2+cWcBW90o=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/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-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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-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-20181114220301-adae6a3d119a/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-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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/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-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
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/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/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-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/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-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/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-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/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-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/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-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/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.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-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-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/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
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/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
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/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
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.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
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/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
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=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
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=

View File

@ -1,11 +1,12 @@
package host
import "github.com/libp2p/go-libp2p-core/peer"
import (
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peer"
)
// InfoFromHost returns a peer.AddrInfo struct with the Host's ID and all of its Addrs.
// Deprecated: use github.com/libp2p/go-libp2p/core/host.InfoFromHost instead
func InfoFromHost(h Host) *peer.AddrInfo {
return &peer.AddrInfo{
ID: h.ID(),
Addrs: h.Addrs(),
}
return host.InfoFromHost(h)
}

View File

@ -1,20 +1,12 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/host.
//
// Package host provides the core Host interface for libp2p.
//
// Host represents a single libp2p node in a peer-to-peer network.
package host
import (
"context"
"github.com/libp2p/go-libp2p-core/connmgr"
"github.com/libp2p/go-libp2p-core/event"
"github.com/libp2p/go-libp2p-core/introspection"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/peerstore"
"github.com/libp2p/go-libp2p-core/protocol"
ma "github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p/core/host"
)
// Host is an object participating in a p2p network, which
@ -22,68 +14,10 @@ import (
// requests like a Server, and issues requests like a Client.
// It is called Host because it is both Server and Client (and Peer
// may be confusing).
type Host interface {
// ID returns the (local) peer.ID associated with this Host
ID() peer.ID
// Peerstore returns the Host's repository of Peer Addresses and Keys.
Peerstore() peerstore.Peerstore
// Returns the listen addresses of the Host
Addrs() []ma.Multiaddr
// Networks returns the Network interface of the Host
Network() network.Network
// Mux returns the Mux multiplexing incoming streams to protocol handlers
Mux() protocol.Switch
// Connect ensures there is a connection between this host and the peer with
// given peer.ID. Connect will absorb the addresses in pi into its internal
// peerstore. If there is not an active connection, Connect will issue a
// h.Network.Dial, and block until a connection is open, or an error is
// returned. // TODO: Relay + NAT.
Connect(ctx context.Context, pi peer.AddrInfo) error
// SetStreamHandler sets the protocol handler on the Host's Mux.
// This is equivalent to:
// host.Mux().SetHandler(proto, handler)
// (Threadsafe)
SetStreamHandler(pid protocol.ID, handler network.StreamHandler)
// SetStreamHandlerMatch sets the protocol handler on the Host's Mux
// using a matching function for protocol selection.
SetStreamHandlerMatch(protocol.ID, func(string) bool, network.StreamHandler)
// RemoveStreamHandler removes a handler on the mux that was set by
// SetStreamHandler
RemoveStreamHandler(pid protocol.ID)
// NewStream opens a new stream to given peer p, and writes a p2p/protocol
// header with given ProtocolID. If there is no connection to p, attempts
// to create one. If ProtocolID is "", writes no header.
// (Threadsafe)
NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (network.Stream, error)
// Close shuts down the host, its Network, and services.
Close() error
// ConnManager returns this hosts connection manager
ConnManager() connmgr.ConnManager
// EventBus returns the hosts eventbus
EventBus() event.Bus
}
// Deprecated: use github.com/libp2p/go-libp2p/core/host.Host instead
type Host = host.Host
// IntrospectableHost is implemented by Host implementations that are
// introspectable, that is, that may have introspection capability.
type IntrospectableHost interface {
// Introspector returns the introspector, or nil if one hasn't been
// registered. With it, the call can register data providers, and can fetch
// introspection data.
Introspector() introspection.Introspector
// IntrospectionEndpoint returns the introspection endpoint, or nil if one
// hasn't been registered.
IntrospectionEndpoint() introspection.Endpoint
}
// Deprecated: use github.com/libp2p/go-libp2p/core/host.IntrospectableHost instead
type IntrospectableHost = host.IntrospectableHost

View File

@ -1,18 +0,0 @@
package catch
import (
"fmt"
"io"
"os"
"runtime/debug"
)
var panicWriter io.Writer = os.Stderr
// HandlePanic handles and logs panics.
func HandlePanic(rerr interface{}, err *error, where string) {
if rerr != nil {
fmt.Fprintf(panicWriter, "caught panic: %s\n%s\n", rerr, debug.Stack())
*err = fmt.Errorf("panic in %s: %s", where, rerr)
}
}

View File

@ -1,28 +0,0 @@
package catch
import (
"bytes"
"testing"
"github.com/stretchr/testify/require"
)
func TestCatch(t *testing.T) {
buf := new(bytes.Buffer)
oldPanicWriter := panicWriter
t.Cleanup(func() { panicWriter = oldPanicWriter })
panicWriter = buf
panicAndCatch := func() (err error) {
defer func() { HandlePanic(recover(), &err, "somewhere") }()
panic("here")
}
err := panicAndCatch()
require.Error(t, err)
require.Contains(t, err.Error(), "panic in somewhere: here")
require.Contains(t, buf.String(), "caught panic: here")
}

View File

@ -1,3 +1,5 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/introspection.
//
// Package introspection is EXPERIMENTAL. It is subject to heavy change, and it
// WILL change. For now, it is the simplest implementation to power the
// proof-of-concept of the libp2p introspection framework.

View File

@ -1,30 +1,16 @@
package introspection
import "github.com/libp2p/go-libp2p/core/introspection"
// Endpoint is the interface to be implemented by introspection endpoints.
//
// An introspection endpoint makes introspection data accessible to external
// consumers, over, for example, WebSockets, or TCP, or libp2p itself.
//
// Experimental.
type Endpoint interface {
// Start starts the introspection endpoint. It must only be called once, and
// once the server is started, subsequent calls made without first calling
// Close will error.
Start() error
// Close stops the introspection endpoint. Calls to Close on an already
// closed endpoint (or an unstarted endpoint) must noop.
Close() error
// ListenAddrs returns the listen addresses of this endpoint.
ListenAddrs() []string
// Sessions returns the ongoing sessions of this endpoint.
Sessions() []*Session
}
// Deprecated: use github.com/libp2p/go-libp2p/core/introspection.Endpoint instead
type Endpoint = introspection.Endpoint
// Session represents an introspection session.
type Session struct {
// RemoteAddr is the remote address of the session.
RemoteAddr string
}
// Deprecated: use github.com/libp2p/go-libp2p/core/introspection.Session instead
type Session = introspection.Session

View File

@ -1,9 +1,7 @@
package introspection
import (
"io"
"github.com/libp2p/go-libp2p-core/introspection/pb"
"github.com/libp2p/go-libp2p/core/introspection"
)
// Introspector is the interface to be satisfied by components that are capable
@ -19,21 +17,5 @@ import (
// embedding or testing.
//
// Experimental.
type Introspector interface {
io.Closer
// FetchRuntime returns the runtime information of the system.
FetchRuntime() (*pb.Runtime, error)
// FetchFullState returns the full state cross-cut of the running system.
FetchFullState() (*pb.State, error)
// EventChan returns the channel where all eventbus events are dumped,
// decorated with their corresponding event metadata, ready to send over
// the wire.
EventChan() <-chan *pb.Event
// EventMetadata returns the metadata of all events known to the
// Introspector.
EventMetadata() []*pb.EventType
}
// Deprecated: use github.com/libp2p/go-libp2p/core/introspection.Introspector instead
type Introspector = introspection.Introspector

View File

@ -1,11 +0,0 @@
PB = $(wildcard *.proto)
GO = $(PB:.proto=.pb.go)
all: $(GO)
%.pb.go: %.proto
protoc --proto_path=$(PWD):$(PWD)/../..:$(GOPATH)/src --gogofaster_out=Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types:. $<
clean:
rm -f *.pb.go
rm -f *.go

View File

@ -1,3 +0,0 @@
// Package introspection/pb contains the protobuf definitions and objects for
// that form the libp2p introspection protocol.
package pb

File diff suppressed because it is too large Load Diff

View File

@ -1,421 +0,0 @@
syntax = "proto3";
package pb;
// Version of schema
message Version {
uint32 version = 1;
}
// ResultCounter is a monotonically increasing counter that reports an ok/err breakdown of the total.
message ResultCounter {
uint32 total = 1;
uint32 ok = 2;
uint32 err = 3;
}
// Moving totals over sliding time windows. Models sensible time windows,
// we don't have to populate them all at once.
//
// Graphical example:
//
// time past -> present an event 16 min ago
// ======================================================X================>>
// | | 1m
// | |---| 5m
// | |-------------| 15m
// |------------X---------------| 30m
// |------------------------------------------X---------------| 60m
message SlidingCounter {
uint32 over_1m = 1;
uint32 over_5m = 2;
uint32 over_15m = 3;
uint32 over_30m = 4;
uint32 over_1hr = 5;
uint32 over_2hr = 6;
uint32 over_4hr = 7;
uint32 over_8hr = 8;
uint32 over_12hr = 9;
uint32 over_24hr = 10;
}
// DataGauge reports stats for data traffic in a given direction.
message DataGauge {
// Cumulative bytes.
uint64 cum_bytes = 1;
// Cumulative packets.
uint64 cum_packets = 2;
// Instantaneous bandwidth measurement (bytes/second).
uint64 inst_bw = 3;
}
// describes a type of event
message EventType {
// metadata about content types in event's top-level content JSON
message EventProperty {
// tells client how to sort, filter or display known content properties
enum PropertyType {
// for properties to treat as a simple primitive
STRING = 0; // default
NUMBER = 1;
// for properties with special human-readable formatting
TIME = 10;
PEERID = 11;
MULTIADDR = 12;
// for complex structures like nested arrays, object trees etc
JSON = 90;
}
// property name of content e.g. openTs
string name = 1;
// type to interpret content value as
PropertyType type = 2;
// if true, expect an array of values of `type`; else, singular
bool has_multiple = 3;
}
// name of event type, e.g. PeerConnecting
string name = 1;
// for runtime, send property_types for all events already seen in events list
// for events, only send property_types in the first event of a type not in runtime
repeated EventProperty property_types = 2;
}
// Runtime encapsulates runtime info about a node.
message Runtime {
// e.g. go-libp2p, js-libp2p, rust-libp2p, etc.
string implementation = 1;
// e.g. 1.2.3.
string version = 2;
// e.g. Windows, Unix, macOS, Chrome, Mozilla, etc.
string platform = 3;
// our peer id - the peer id of the host system
string peer_id = 4;
// metadata describing configured event types
repeated EventType event_types = 7;
}
// EndpointPair is a pair of multiaddrs.
message EndpointPair {
// the source multiaddr.
string src_multiaddr = 1;
// the destination multiaddr.
string dst_multiaddr = 2;
}
// The status of a connection or stream.
enum Status {
ACTIVE = 0;
CLOSED = 1;
OPENING = 2;
CLOSING = 3;
ERROR = 4;
}
// Our role in a connection or stream.
enum Role {
INITIATOR = 0;
RESPONDER = 1;
}
// Traffic encloses data transfer statistics.
message Traffic {
// snapshot of the data in metrics.
DataGauge traffic_in = 1;
// snapshot of the data out metrics.
DataGauge traffic_out = 2;
}
// a list of streams, by reference or inlined.
message StreamList {
// NOTE: only one of the next 2 fields can appear, but proto3
// doesn't support combining oneof and repeated.
//
// streams within this connection by reference.
repeated bytes stream_ids = 1;
// streams within this connection by inlining.
repeated Stream streams = 2;
}
// Connection reports metrics and state of a libp2p connection.
message Connection {
// Timeline contains the timestamps (ms since epoch) of the well-known milestones of a connection.
message Timeline {
// the instant when a connection was opened on the wire.
uint64 open_ts = 1;
// the instant when the upgrade process (handshake, security, multiplexing) finished.
uint64 upgraded_ts = 2;
// the instant when this connection was terminated.
uint64 close_ts = 3;
}
// Attributes encapsulates the attributes of this connection.
message Attributes {
// the multiplexer being used.
string multiplexer = 1;
// the encryption method being used.
string encryption = 2;
}
// the id of this connection, not to be shown in user tooling,
// used for (cross)referencing connections (e.g. relay).
bytes id = 1;
// the peer id of the other party.
string peer_id = 2;
// the status of this connection.
Status status = 3;
// a reference to the transport managing this connection.
bytes transport_id = 4;
// the endpoints participating in this connection.
EndpointPair endpoints = 5;
// the timeline of the connection, see Connection.Timeline.
Timeline timeline = 6;
// our role in this connection.
Role role = 7;
// traffic statistics.
Traffic traffic = 8;
// properties of this connection.
Attributes attribs = 9;
// the instantaneous latency of this connection in nanoseconds.
uint64 latency_ns = 10;
// streams within this connection.
StreamList streams = 11;
reserved 12 to 15;
// if this is a relayed connection, this points to the relaying connection.
// a default value here (empty bytes) indicates this is not a relayed connection.
oneof relayed_over {
bytes conn_id = 16;
Connection conn = 17;
}
// user provided tags.
repeated string user_provided_tags = 99;
}
// Stream reports metrics and state of a libp2p stream.
message Stream {
message ConnectionRef {
oneof connection {
// the parent connection inlined.
Connection conn = 1;
// the parent connection by reference.
bytes conn_id = 2;
}
}
// Timeline contains the timestamps (ms since epoch) of the well-known milestones of a stream.
message Timeline {
// the instant when the stream was opened.
uint64 open_ts = 1;
// the instant when the stream was terminated.
uint64 close_ts = 2;
}
// the id of this stream, not to be shown in user tooling,
// used for (cross)referencing streams.
bytes id = 1;
// the protocol pinned to this stream.
string protocol = 2;
// our role in this stream.
Role role = 3;
// traffic statistics.
Traffic traffic = 4;
// the connection this stream is hosted under.
ConnectionRef conn = 5;
// the timeline of the stream, see Stream.Timeline.
Timeline timeline = 6;
// the status of this stream.
Status status = 7;
// the instantaneous latency of this stream in nanoseconds.
// TODO: this is hard to calculate.
uint64 latency_ns = 16;
// user provided tags.
repeated string user_provided_tags = 99;
}
// DHT metrics and state.
message DHT {
message Params {
// routing table bucket size.
uint64 k = 1;
// concurrency of asynchronous requests.
uint64 alpha = 2;
// number of disjoint paths to use.
uint64 disjoint_paths = 3;
// number of peers closest to a target that must have responded
// in order for a given query path to complete
uint64 beta = 4;
}
// Peer in DHT
message PeerInDHT {
// The DHT's relationship with this peer
enum Status {
// Connected, in a bucket, ready to send/receive queries
ACTIVE = 0;
// Not currently connected, still "in" a bucket (e.g. temporarily disconnected)
MISSING = 1;
// Removed from a bucket or candidate list (e.g. connection lost or too slow)
REJECTED = 2;
// Was reachable when last checked, waiting to join a currently-full bucket
CANDIDATE = 3;
}
// the peer id of the host system
string peer_id = 1;
// the peer's status when data snapshot is taken
Status status = 2;
// age in bucket (ms)
uint32 age_in_bucket = 3;
}
// A "k-bucket" containing peers of a certain kadamelia distance
message Bucket {
// CPL (Common Prefix Length) is the length of the common prefix
// between the ids of every peer in this bucket and the DHT peer id
uint32 cpl = 1;
// Peers associated with this bucket
repeated PeerInDHT peers = 2;
// Bucket may need more fields depending on WIP remodeling
}
// Counters of query events, by status
message QueryGauge {
// Cumulative counter of queries with "SUCCESS" status
uint64 success = 1;
// Cumulative counter of queries with "ERROR" status
uint64 error = 2;
// Cumulative counter of queries with "TIMEOUT" status
uint64 timeout = 3;
}
// DHT protocol name
string protocol = 1;
// protocol enabled.
bool enabled = 2;
// timestamp (ms since epoch) of start up.
uint64 start_ts = 3;
// params of the dht.
Params params = 4;
// existing, intantiated buckets and their contents
repeated Bucket buckets = 5;
// counts inbound queries received from other peers
QueryGauge incoming_queries = 6;
// counts outbound queries dispatched by this peer
QueryGauge outgoing_queries = 7;
}
// Subsystems encapsulates all instrumented subsystems for a libp2p host.
message Subsystems {
// connections data, source agnostic but currently only supports the Swarm subsystem
repeated Connection connections = 1;
// the DHT subsystem.
DHT dht = 2;
}
// Connections and streams output for a time interval is one of these.
message State {
// list of connections
Subsystems subsystems = 1;
// overall traffic for this peer
Traffic traffic = 2;
// moment this data snapshot and instantaneous values were taken
uint64 instant_ts = 3;
// start of included data collection (cumulative values counted from here)
uint64 start_ts = 4;
// length of time up to instant_ts covered by this data snapshot
uint32 snapshot_duration_ms = 5;
}
// Event
message Event {
// definition of event type, containing only `name` unless this is first encounter of novel event
EventType type = 1;
// time this event occurred (ms since epoch)
uint64 ts = 2;
// stringified json; top-level keys and value types match EventProperty definitions
string content = 3;
}
// ServerMessage wraps messages to be sent to clients to allow extension
// based on new types of data sources
message ServerMessage {
// Version of this protobuf.
Version version = 1;
// The payload this message contains.
oneof payload {
State state = 2;
Runtime runtime = 3;
Event event = 4;
CommandResponse response = 5;
ServerNotice notice = 6;
}
}
// Configuration encapsulates configuration fields for the protocol and commands.
message Configuration {
uint64 retention_period_ms = 1;
uint64 state_snapshot_interval_ms = 2;
}
// ClientCommand is a command sent from the client to the server.
message ClientCommand {
enum Source {
STATE = 0; // full state snapshot.
RUNTIME = 1; // runtime data message.
EVENTS = 2; // eventbus events.
}
enum Command {
// HELLO is the first command that a client must send to greet the server.
// Connections that do not respect this invariant will be terminated.
HELLO = 0;
// REQUEST is applicable to STATE and RUNTIME sources.
REQUEST = 1;
// PUSH streams can only be started for STATE and EVENTS sources.
PUSH_ENABLE = 2; // enables pushing for a given source.
PUSH_DISABLE = 3; // disables pushing for a given source.
PUSH_PAUSE = 4; // pauses pushing for all sources.
PUSH_RESUME = 5; // resumes pushing for all sources.
// UPDATE_CONFIG requests a configuration update. The config field is
// compulsory.
//
// The server reserves the right to override the requested values, and
// will return the effective configuration in the response.
UPDATE_CONFIG = 7;
}
Version version = 1;
uint64 id = 2; // a unique ID for this request.
Command command = 3;
Source source = 4;
Configuration config = 5;
}
// CommandResponse is a response to a command sent by the client.
message CommandResponse {
enum Result {
OK = 0;
ERR = 1;
}
uint64 id = 1; // for correlation with the request.
Result result = 2;
string error = 3;
// effective_config is the effective configuration the server holds for
// this connection. It is returned in response to HELLO and UPDATE_CONFIG
// commands.
Configuration effective_config = 4;
}
// ServerNotice represents a NOTICE sent from the server to the client.
message ServerNotice {
enum Kind {
DISCARDING_EVENTS = 0;
}
Kind kind = 1;
}

View File

@ -1,176 +1,20 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/metrics.
//
// Package metrics provides metrics collection and reporting interfaces for libp2p.
package metrics
import (
"time"
"github.com/libp2p/go-flow-metrics"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/libp2p/go-libp2p/core/metrics"
)
// BandwidthCounter tracks incoming and outgoing data transferred by the local peer.
// Metrics are available for total bandwidth across all peers / protocols, as well
// as segmented by remote peer ID and protocol ID.
type BandwidthCounter struct {
totalIn flow.Meter
totalOut flow.Meter
protocolIn flow.MeterRegistry
protocolOut flow.MeterRegistry
peerIn flow.MeterRegistry
peerOut flow.MeterRegistry
}
// Deprecated: use github.com/libp2p/go-libp2p/core/metrics.BandwidthCounter instead
type BandwidthCounter = metrics.BandwidthCounter
// NewBandwidthCounter creates a new BandwidthCounter.
// Deprecated: use github.com/libp2p/go-libp2p/core/metrics.NewBandwidthCounter instead
func NewBandwidthCounter() *BandwidthCounter {
return new(BandwidthCounter)
}
// LogSentMessage records the size of an outgoing message
// without associating the bandwidth to a specific peer or protocol.
func (bwc *BandwidthCounter) LogSentMessage(size int64) {
bwc.totalOut.Mark(uint64(size))
}
// LogRecvMessage records the size of an incoming message
// without associating the bandwith to a specific peer or protocol.
func (bwc *BandwidthCounter) LogRecvMessage(size int64) {
bwc.totalIn.Mark(uint64(size))
}
// LogSentMessageStream records the size of an outgoing message over a single logical stream.
// Bandwidth is associated with the given protocol.ID and peer.ID.
func (bwc *BandwidthCounter) LogSentMessageStream(size int64, proto protocol.ID, p peer.ID) {
bwc.protocolOut.Get(string(proto)).Mark(uint64(size))
bwc.peerOut.Get(string(p)).Mark(uint64(size))
}
// LogRecvMessageStream records the size of an incoming message over a single logical stream.
// Bandwidth is associated with the given protocol.ID and peer.ID.
func (bwc *BandwidthCounter) LogRecvMessageStream(size int64, proto protocol.ID, p peer.ID) {
bwc.protocolIn.Get(string(proto)).Mark(uint64(size))
bwc.peerIn.Get(string(p)).Mark(uint64(size))
}
// GetBandwidthForPeer returns a Stats struct with bandwidth metrics associated with the given peer.ID.
// The metrics returned include all traffic sent / received for the peer, regardless of protocol.
func (bwc *BandwidthCounter) GetBandwidthForPeer(p peer.ID) (out Stats) {
inSnap := bwc.peerIn.Get(string(p)).Snapshot()
outSnap := bwc.peerOut.Get(string(p)).Snapshot()
return Stats{
TotalIn: int64(inSnap.Total),
TotalOut: int64(outSnap.Total),
RateIn: inSnap.Rate,
RateOut: outSnap.Rate,
}
}
// GetBandwidthForProtocol returns a Stats struct with bandwidth metrics associated with the given protocol.ID.
// The metrics returned include all traffic sent / recieved for the protocol, regardless of which peers were
// involved.
func (bwc *BandwidthCounter) GetBandwidthForProtocol(proto protocol.ID) (out Stats) {
inSnap := bwc.protocolIn.Get(string(proto)).Snapshot()
outSnap := bwc.protocolOut.Get(string(proto)).Snapshot()
return Stats{
TotalIn: int64(inSnap.Total),
TotalOut: int64(outSnap.Total),
RateIn: inSnap.Rate,
RateOut: outSnap.Rate,
}
}
// GetBandwidthTotals returns a Stats struct with bandwidth metrics for all data sent / recieved by the
// local peer, regardless of protocol or remote peer IDs.
func (bwc *BandwidthCounter) GetBandwidthTotals() (out Stats) {
inSnap := bwc.totalIn.Snapshot()
outSnap := bwc.totalOut.Snapshot()
return Stats{
TotalIn: int64(inSnap.Total),
TotalOut: int64(outSnap.Total),
RateIn: inSnap.Rate,
RateOut: outSnap.Rate,
}
}
// GetBandwidthByPeer returns a map of all remembered peers and the bandwidth
// metrics with respect to each. This method may be very expensive.
func (bwc *BandwidthCounter) GetBandwidthByPeer() map[peer.ID]Stats {
peers := make(map[peer.ID]Stats)
bwc.peerIn.ForEach(func(p string, meter *flow.Meter) {
id := peer.ID(p)
snap := meter.Snapshot()
stat := peers[id]
stat.TotalIn = int64(snap.Total)
stat.RateIn = snap.Rate
peers[id] = stat
})
bwc.peerOut.ForEach(func(p string, meter *flow.Meter) {
id := peer.ID(p)
snap := meter.Snapshot()
stat := peers[id]
stat.TotalOut = int64(snap.Total)
stat.RateOut = snap.Rate
peers[id] = stat
})
return peers
}
// GetBandwidthByProtocol returns a map of all remembered protocols and
// the bandwidth metrics with respect to each. This method may be moderately
// expensive.
func (bwc *BandwidthCounter) GetBandwidthByProtocol() map[protocol.ID]Stats {
protocols := make(map[protocol.ID]Stats)
bwc.protocolIn.ForEach(func(p string, meter *flow.Meter) {
id := protocol.ID(p)
snap := meter.Snapshot()
stat := protocols[id]
stat.TotalIn = int64(snap.Total)
stat.RateIn = snap.Rate
protocols[id] = stat
})
bwc.protocolOut.ForEach(func(p string, meter *flow.Meter) {
id := protocol.ID(p)
snap := meter.Snapshot()
stat := protocols[id]
stat.TotalOut = int64(snap.Total)
stat.RateOut = snap.Rate
protocols[id] = stat
})
return protocols
}
// Reset clears all stats.
func (bwc *BandwidthCounter) Reset() {
bwc.totalIn.Reset()
bwc.totalOut.Reset()
bwc.protocolIn.Clear()
bwc.protocolOut.Clear()
bwc.peerIn.Clear()
bwc.peerOut.Clear()
}
// TrimIdle trims all timers idle since the given time.
func (bwc *BandwidthCounter) TrimIdle(since time.Time) {
bwc.peerIn.TrimIdle(since)
bwc.peerOut.TrimIdle(since)
bwc.protocolIn.TrimIdle(since)
bwc.protocolOut.TrimIdle(since)
return metrics.NewBandwidthCounter()
}

View File

@ -1,170 +0,0 @@
package metrics
import (
"fmt"
"sync"
"testing"
"time"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/libp2p/go-flow-metrics"
"github.com/benbjohnson/clock"
"github.com/stretchr/testify/require"
)
var cl = clock.NewMock()
func init() {
flow.SetClock(cl)
}
func BenchmarkBandwidthCounter(b *testing.B) {
b.StopTimer()
b.ResetTimer()
for i := 0; i < b.N; i++ {
bwc := NewBandwidthCounter()
round(bwc, b)
}
}
func round(bwc *BandwidthCounter, b *testing.B) {
start := make(chan struct{})
var wg sync.WaitGroup
wg.Add(10000)
for i := 0; i < 1000; i++ {
p := peer.ID(fmt.Sprintf("peer-%d", i))
for j := 0; j < 10; j++ {
proto := protocol.ID(fmt.Sprintf("bitswap-%d", j))
go func() {
defer wg.Done()
<-start
for i := 0; i < 1000; i++ {
bwc.LogSentMessage(100)
bwc.LogSentMessageStream(100, proto, p)
time.Sleep(1 * time.Millisecond)
}
}()
}
}
b.StartTimer()
close(start)
wg.Wait()
b.StopTimer()
}
func TestBandwidthCounter(t *testing.T) {
bwc := NewBandwidthCounter()
for i := 0; i < 40; i++ {
for i := 0; i < 100; i++ {
p := peer.ID(fmt.Sprintf("peer-%d", i))
for j := 0; j < 2; j++ {
proto := protocol.ID(fmt.Sprintf("proto-%d", j))
// make sure the bandwidth counters are active
bwc.LogSentMessage(100)
bwc.LogRecvMessage(50)
bwc.LogSentMessageStream(100, proto, p)
bwc.LogRecvMessageStream(50, proto, p)
// <-start
}
}
cl.Add(100 * time.Millisecond)
}
assertProtocols := func(check func(Stats)) {
byProtocol := bwc.GetBandwidthByProtocol()
require.Len(t, byProtocol, 2, "expected 2 protocols")
for i := 0; i < 2; i++ {
p := protocol.ID(fmt.Sprintf("proto-%d", i))
for _, stats := range [...]Stats{bwc.GetBandwidthForProtocol(p), byProtocol[p]} {
check(stats)
}
}
}
assertPeers := func(check func(Stats)) {
byPeer := bwc.GetBandwidthByPeer()
require.Len(t, byPeer, 100, "expected 100 peers")
for i := 0; i < 100; i++ {
p := peer.ID(fmt.Sprintf("peer-%d", i))
for _, stats := range [...]Stats{bwc.GetBandwidthForPeer(p), byPeer[p]} {
check(stats)
}
}
}
assertPeers(func(stats Stats) {
require.Equal(t, int64(8000), stats.TotalOut)
require.Equal(t, int64(4000), stats.TotalIn)
})
assertProtocols(func(stats Stats) {
require.Equal(t, int64(400000), stats.TotalOut)
require.Equal(t, int64(200000), stats.TotalIn)
})
stats := bwc.GetBandwidthTotals()
require.Equal(t, int64(800000), stats.TotalOut)
require.Equal(t, int64(400000), stats.TotalIn)
}
func TestResetBandwidthCounter(t *testing.T) {
bwc := NewBandwidthCounter()
p := peer.ID("peer-0")
proto := protocol.ID("proto-0")
// We don't calculate bandwidth till we've been active for a second.
bwc.LogSentMessage(42)
bwc.LogRecvMessage(24)
bwc.LogSentMessageStream(100, proto, p)
bwc.LogRecvMessageStream(50, proto, p)
time.Sleep(200 * time.Millisecond) // make sure the meters are registered with the sweeper
cl.Add(time.Second)
bwc.LogSentMessage(42)
bwc.LogRecvMessage(24)
bwc.LogSentMessageStream(100, proto, p)
bwc.LogRecvMessageStream(50, proto, p)
cl.Add(time.Second)
{
stats := bwc.GetBandwidthTotals()
require.Equal(t, int64(84), stats.TotalOut)
require.Equal(t, int64(48), stats.TotalIn)
}
{
stats := bwc.GetBandwidthByProtocol()
require.Len(t, stats, 1)
stat := stats[proto]
require.Equal(t, float64(100), stat.RateOut)
require.Equal(t, float64(50), stat.RateIn)
}
{
stats := bwc.GetBandwidthByPeer()
require.Len(t, stats, 1)
stat := stats[p]
require.Equal(t, float64(100), stat.RateOut)
require.Equal(t, float64(50), stat.RateIn)
}
bwc.Reset()
{
stats := bwc.GetBandwidthTotals()
require.Zero(t, stats.TotalOut)
require.Zero(t, stats.TotalIn)
require.Empty(t, bwc.GetBandwidthByProtocol(), "expected 0 protocols")
require.Empty(t, bwc.GetBandwidthByPeer(), "expected 0 peers")
}
}

View File

@ -2,30 +2,16 @@
package metrics
import (
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/libp2p/go-libp2p/core/metrics"
)
// Stats represents a point-in-time snapshot of bandwidth metrics.
//
// The TotalIn and TotalOut fields record cumulative bytes sent / received.
// The RateIn and RateOut fields record bytes sent / received per second.
type Stats struct {
TotalIn int64
TotalOut int64
RateIn float64
RateOut float64
}
// Deprecated: use github.com/libp2p/go-libp2p/core/metrics.Stats instead
type Stats = metrics.Stats
// Reporter provides methods for logging and retrieving metrics.
type Reporter interface {
LogSentMessage(int64)
LogRecvMessage(int64)
LogSentMessageStream(int64, protocol.ID, peer.ID)
LogRecvMessageStream(int64, protocol.ID, peer.ID)
GetBandwidthForPeer(peer.ID) Stats
GetBandwidthForProtocol(protocol.ID) Stats
GetBandwidthTotals() Stats
GetBandwidthByPeer() map[peer.ID]Stats
GetBandwidthByProtocol() map[protocol.ID]Stats
}
// Deprecated: use github.com/libp2p/go-libp2p/core/metrics.Reporter instead
type Reporter = metrics.Reporter

View File

@ -1,75 +1,33 @@
package network
import (
"context"
"io"
ic "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p/core/network"
)
// Conn is a connection to a remote peer. It multiplexes streams.
// Usually there is no need to use a Conn directly, but it may
// be useful to get information about the peer on the other side:
// stream.Conn().RemotePeer()
type Conn interface {
io.Closer
ConnSecurity
ConnMultiaddrs
ConnStat
ConnScoper
// ID returns an identifier that uniquely identifies this Conn within this
// host, during this run. Connection IDs may repeat across restarts.
ID() string
// NewStream constructs a new Stream over this conn.
NewStream(context.Context) (Stream, error)
// GetStreams returns all open streams over this conn.
GetStreams() []Stream
}
//
// stream.Conn().RemotePeer()
//
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Conn instead
type Conn = network.Conn
// ConnSecurity is the interface that one can mix into a connection interface to
// give it the security methods.
type ConnSecurity interface {
// LocalPeer returns our peer ID
LocalPeer() peer.ID
// LocalPrivateKey returns our private key
LocalPrivateKey() ic.PrivKey
// RemotePeer returns the peer ID of the remote peer.
RemotePeer() peer.ID
// RemotePublicKey returns the public key of the remote peer.
RemotePublicKey() ic.PubKey
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ConnSecurity instead
type ConnSecurity = network.ConnSecurity
// ConnMultiaddrs is an interface mixin for connection types that provide multiaddr
// addresses for the endpoints.
type ConnMultiaddrs interface {
// LocalMultiaddr returns the local Multiaddr associated
// with this connection
LocalMultiaddr() ma.Multiaddr
// RemoteMultiaddr returns the remote Multiaddr associated
// with this connection
RemoteMultiaddr() ma.Multiaddr
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ConnMultiaddrs instead
type ConnMultiaddrs = network.ConnMultiaddrs
// ConnStat is an interface mixin for connection types that provide connection statistics.
type ConnStat interface {
// Stat stores metadata pertaining to this conn.
Stat() ConnStats
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ConnStat instead
type ConnStat = network.ConnStats
// ConnScoper is the interface that one can mix into a connection interface to give it a resource
// management scope
type ConnScoper interface {
// Scope returns the user view of this connection's resource scope
Scope() ConnScope
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ConnScoper instead
type ConnScoper = network.ConnScoper

View File

@ -3,108 +3,83 @@ package network
import (
"context"
"time"
"github.com/libp2p/go-libp2p/core/network"
)
// DialPeerTimeout is the default timeout for a single call to `DialPeer`. When
// there are multiple concurrent calls to `DialPeer`, this timeout will apply to
// each independently.
var DialPeerTimeout = 60 * time.Second
type noDialCtxKey struct{}
type dialPeerTimeoutCtxKey struct{}
type forceDirectDialCtxKey struct{}
type useTransientCtxKey struct{}
type simConnectCtxKey struct{ isClient bool }
var noDial = noDialCtxKey{}
var forceDirectDial = forceDirectDialCtxKey{}
var useTransient = useTransientCtxKey{}
var simConnectIsServer = simConnectCtxKey{}
var simConnectIsClient = simConnectCtxKey{isClient: true}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.DialPeerTimeout instead
var DialPeerTimeout = network.DialPeerTimeout
// EXPERIMENTAL
// WithForceDirectDial constructs a new context with an option that instructs the network
// to attempt to force a direct connection to a peer via a dial even if a proxied connection to it already exists.
// Deprecated: use github.com/libp2p/go-libp2p/core/network.WithForceDirectDial instead
func WithForceDirectDial(ctx context.Context, reason string) context.Context {
return context.WithValue(ctx, forceDirectDial, reason)
return network.WithForceDirectDial(ctx, reason)
}
// EXPERIMENTAL
// GetForceDirectDial returns true if the force direct dial option is set in the context.
// Deprecated: use github.com/libp2p/go-libp2p/core/network.GetForceDirectDial instead
func GetForceDirectDial(ctx context.Context) (forceDirect bool, reason string) {
v := ctx.Value(forceDirectDial)
if v != nil {
return true, v.(string)
}
return false, ""
return network.GetForceDirectDial(ctx)
}
// WithSimultaneousConnect constructs a new context with an option that instructs the transport
// to apply hole punching logic where applicable.
// EXPERIMENTAL
// Deprecated: use github.com/libp2p/go-libp2p/core/network.WithSimultaneousConnect instead
func WithSimultaneousConnect(ctx context.Context, isClient bool, reason string) context.Context {
if isClient {
return context.WithValue(ctx, simConnectIsClient, reason)
}
return context.WithValue(ctx, simConnectIsServer, reason)
return network.WithSimultaneousConnect(ctx, isClient, reason)
}
// GetSimultaneousConnect returns true if the simultaneous connect option is set in the context.
// EXPERIMENTAL
// Deprecated: use github.com/libp2p/go-libp2p/core/network.GetSimultaneousConnect instead
func GetSimultaneousConnect(ctx context.Context) (simconnect bool, isClient bool, reason string) {
if v := ctx.Value(simConnectIsClient); v != nil {
return true, true, v.(string)
}
if v := ctx.Value(simConnectIsServer); v != nil {
return true, false, v.(string)
}
return false, false, ""
return network.GetSimultaneousConnect(ctx)
}
// WithNoDial constructs a new context with an option that instructs the network
// to not attempt a new dial when opening a stream.
// Deprecated: use github.com/libp2p/go-libp2p/core/network.WithNoDial instead
func WithNoDial(ctx context.Context, reason string) context.Context {
return context.WithValue(ctx, noDial, reason)
return network.WithNoDial(ctx, reason)
}
// GetNoDial returns true if the no dial option is set in the context.
// Deprecated: use github.com/libp2p/go-libp2p/core/network.GetNoDial instead
func GetNoDial(ctx context.Context) (nodial bool, reason string) {
v := ctx.Value(noDial)
if v != nil {
return true, v.(string)
}
return false, ""
return network.GetNoDial(ctx)
}
// GetDialPeerTimeout returns the current DialPeer timeout (or the default).
// Deprecated: use github.com/libp2p/go-libp2p/core/network.GetDialPeerTimeout instead
func GetDialPeerTimeout(ctx context.Context) time.Duration {
if to, ok := ctx.Value(dialPeerTimeoutCtxKey{}).(time.Duration); ok {
return to
}
return DialPeerTimeout
return network.GetDialPeerTimeout(ctx)
}
// WithDialPeerTimeout returns a new context with the DialPeer timeout applied.
//
// This timeout overrides the default DialPeerTimeout and applies per-dial
// independently.
// Deprecated: use github.com/libp2p/go-libp2p/core/network.WithDialPeerTimeout instead
func WithDialPeerTimeout(ctx context.Context, timeout time.Duration) context.Context {
return context.WithValue(ctx, dialPeerTimeoutCtxKey{}, timeout)
return network.WithDialPeerTimeout(ctx, timeout)
}
// WithUseTransient constructs a new context with an option that instructs the network
// that it is acceptable to use a transient connection when opening a new stream.
// Deprecated: use github.com/libp2p/go-libp2p/core/network.WithUseTransient instead
func WithUseTransient(ctx context.Context, reason string) context.Context {
return context.WithValue(ctx, useTransient, reason)
return network.WithUseTransient(ctx, reason)
}
// GetUseTransient returns true if the use transient option is set in the context.
// Deprecated: use github.com/libp2p/go-libp2p/core/network.GetUseTransient instead
func GetUseTransient(ctx context.Context) (usetransient bool, reason string) {
v := ctx.Value(useTransient)
if v != nil {
return true, v.(string)
}
return false, ""
return network.GetUseTransient(ctx)
}

View File

@ -1,59 +0,0 @@
package network
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestDefaultTimeout(t *testing.T) {
ctx := context.Background()
dur := GetDialPeerTimeout(ctx)
if dur != DialPeerTimeout {
t.Fatal("expected default peer timeout")
}
}
func TestNonDefaultTimeout(t *testing.T) {
customTimeout := time.Duration(1)
ctx := context.WithValue(
context.Background(),
dialPeerTimeoutCtxKey{},
customTimeout,
)
dur := GetDialPeerTimeout(ctx)
if dur != customTimeout {
t.Fatal("peer timeout doesn't match set timeout")
}
}
func TestSettingTimeout(t *testing.T) {
customTimeout := time.Duration(1)
ctx := WithDialPeerTimeout(
context.Background(),
customTimeout,
)
dur := GetDialPeerTimeout(ctx)
if dur != customTimeout {
t.Fatal("peer timeout doesn't match set timeout")
}
}
func TestSimultaneousConnect(t *testing.T) {
t.Run("for the server", func(t *testing.T) {
serverCtx := WithSimultaneousConnect(context.Background(), false, "foobar")
ok, isClient, reason := GetSimultaneousConnect(serverCtx)
require.True(t, ok)
require.False(t, isClient)
require.Equal(t, reason, "foobar")
})
t.Run("for the client", func(t *testing.T) {
serverCtx := WithSimultaneousConnect(context.Background(), true, "foo")
ok, isClient, reason := GetSimultaneousConnect(serverCtx)
require.True(t, ok)
require.True(t, isClient)
require.Equal(t, reason, "foo")
})
}

View File

@ -1,33 +1,29 @@
package network
import (
"errors"
"net"
"github.com/libp2p/go-libp2p/core/network"
)
type temporaryError string
func (e temporaryError) Error() string { return string(e) }
func (e temporaryError) Temporary() bool { return true }
func (e temporaryError) Timeout() bool { return false }
var _ net.Error = temporaryError("")
// ErrNoRemoteAddrs is returned when there are no addresses associated with a peer during a dial.
var ErrNoRemoteAddrs = errors.New("no remote addresses")
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ErrNoRemoteAddrs instead
var ErrNoRemoteAddrs = network.ErrNoRemoteAddrs
// ErrNoConn is returned when attempting to open a stream to a peer with the NoDial
// option and no usable connection is available.
var ErrNoConn = errors.New("no usable connection to peer")
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ErrNoConn instead
var ErrNoConn = network.ErrNoConn
// ErrTransientConn is returned when attempting to open a stream to a peer with only a transient
// connection, without specifying the UseTransient option.
var ErrTransientConn = errors.New("transient connection to peer")
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ErrTransientConn instead
var ErrTransientConn = network.ErrTransientConn
// ErrResourceLimitExceeded is returned when attempting to perform an operation that would
// exceed system resource limits.
var ErrResourceLimitExceeded = temporaryError("resource limit exceeded")
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ErrResourceLimitExceeded instead
var ErrResourceLimitExceeded = network.ErrResourceLimitExceeded
// ErrResourceScopeClosed is returned when attemptig to reserve resources in a closed resource
// scope.
var ErrResourceScopeClosed = errors.New("resource scope closed")
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ErrResourceScopeClosed instead
var ErrResourceScopeClosed = network.ErrResourceScopeClosed

View File

@ -1,65 +1,16 @@
package network
import (
"context"
"errors"
"io"
"net"
"time"
"github.com/libp2p/go-libp2p/core/network"
)
// ErrReset is returned when reading or writing on a reset stream.
var ErrReset = errors.New("stream reset")
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ErrReset instead
var ErrReset = network.ErrReset
// MuxedStream is a bidirectional io pipe within a connection.
type MuxedStream interface {
io.Reader
io.Writer
// Close closes the stream.
//
// * Any buffered data for writing will be flushed.
// * Future reads will fail.
// * Any in-progress reads/writes will be interrupted.
//
// Close may be asynchronous and _does not_ guarantee receipt of the
// data.
//
// Close closes the stream for both reading and writing.
// Close is equivalent to calling `CloseRead` and `CloseWrite`. Importantly, Close will not wait for any form of acknowledgment.
// If acknowledgment is required, the caller must call `CloseWrite`, then wait on the stream for a response (or an EOF),
// then call Close() to free the stream object.
//
// When done with a stream, the user must call either Close() or `Reset()` to discard the stream, even after calling `CloseRead` and/or `CloseWrite`.
io.Closer
// CloseWrite closes the stream for writing but leaves it open for
// reading.
//
// CloseWrite does not free the stream, users must still call Close or
// Reset.
CloseWrite() error
// CloseRead closes the stream for reading but leaves it open for
// writing.
//
// When CloseRead is called, all in-progress Read calls are interrupted with a non-EOF error and
// no further calls to Read will succeed.
//
// The handling of new incoming data on the stream after calling this function is implementation defined.
//
// CloseRead does not free the stream, users must still call Close or
// Reset.
CloseRead() error
// Reset closes both ends of the stream. Use this to tell the remote
// side to hang up and go away.
Reset() error
SetDeadline(time.Time) error
SetReadDeadline(time.Time) error
SetWriteDeadline(time.Time) error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.MuxedStream instead
type MuxedStream = network.MuxedStream
// MuxedConn represents a connection to a remote peer that has been
// extended to support stream multiplexing.
@ -71,25 +22,11 @@ type MuxedStream interface {
// transport.CapableConn interface, which represents a "raw" network
// connection that has been "upgraded" to support the libp2p capabilities
// of secure communication and stream multiplexing.
type MuxedConn interface {
// Close closes the stream muxer and the the underlying net.Conn.
io.Closer
// IsClosed returns whether a connection is fully closed, so it can
// be garbage collected.
IsClosed() bool
// OpenStream creates a new stream.
OpenStream(context.Context) (MuxedStream, error)
// AcceptStream accepts a stream opened by the other side.
AcceptStream() (MuxedStream, error)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.MuxedConn instead
type MuxedConn = network.MuxedConn
// Multiplexer wraps a net.Conn with a stream multiplexing
// implementation and returns a MuxedConn that supports opening
// multiple streams over the underlying net.Conn
type Multiplexer interface {
// NewConn constructs a new connection
NewConn(c net.Conn, isServer bool, scope PeerScope) (MuxedConn, error)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Multiplexer instead
type Multiplexer = network.Multiplexer

View File

@ -1,11 +1,15 @@
package network
import "github.com/libp2p/go-libp2p/core/network"
// NATDeviceType indicates the type of the NAT device.
type NATDeviceType int
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NATDeviceType instead
type NATDeviceType = network.NATDeviceType
const (
// NATDeviceTypeUnknown indicates that the type of the NAT device is unknown.
NATDeviceTypeUnknown NATDeviceType = iota
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NATDeviceTypeUnknown instead
NATDeviceTypeUnknown = network.NATDeviceTypeUnknown
// NATDeviceTypeCone indicates that the NAT device is a Cone NAT.
// A Cone NAT is a NAT where all outgoing connections from the same source IP address and port are mapped by the NAT device
@ -14,45 +18,26 @@ const (
// Port Restricted Cone NAT. However, we do NOT differentiate between them here and simply classify all such NATs as a Cone NAT.
// NAT traversal with hole punching is possible with a Cone NAT ONLY if the remote peer is ALSO behind a Cone NAT.
// If the remote peer is behind a Symmetric NAT, hole punching will fail.
NATDeviceTypeCone
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NATDeviceTypeConn instead
NATDeviceTypeCone = network.NATDeviceTypeCone
// NATDeviceTypeSymmetric indicates that the NAT device is a Symmetric NAT.
// A Symmetric NAT maps outgoing connections with different destination addresses to different IP addresses and ports,
// even if they originate from the same source IP address and port.
// NAT traversal with hole-punching is currently NOT possible in libp2p with Symmetric NATs irrespective of the remote peer's NAT type.
NATDeviceTypeSymmetric
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NATDeviceTypeSymmetric instead
NATDeviceTypeSymmetric = network.NATDeviceTypeSymmetric
)
func (r NATDeviceType) String() string {
switch r {
case 0:
return "Unknown"
case 1:
return "Cone"
case 2:
return "Symmetric"
default:
return "unrecognized"
}
}
// NATTransportProtocol is the transport protocol for which the NAT Device Type has been determined.
type NATTransportProtocol int
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NATTransportProtocol instead
type NATTransportProtocol = network.NATTransportProtocol
const (
// NATTransportUDP means that the NAT Device Type has been determined for the UDP Protocol.
NATTransportUDP NATTransportProtocol = iota
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NATTransportUDP instead
NATTransportUDP = network.NATTransportUDP
// NATTransportTCP means that the NAT Device Type has been determined for the TCP Protocol.
NATTransportTCP
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NATTransportTCP instead
NATTransportTCP = network.NATTransportTCP
)
func (n NATTransportProtocol) String() string {
switch n {
case 0:
return "UDP"
case 1:
return "TCP"
default:
return "unrecognized"
}
}

View File

@ -1,3 +1,5 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/network.
//
// Package network provides core networking abstractions for libp2p.
//
// The network package provides the high-level Network interface for interacting
@ -6,181 +8,100 @@
package network
import (
"context"
"io"
"time"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/peerstore"
ma "github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p/core/network"
)
// MessageSizeMax is a soft (recommended) maximum for network messages.
// One can write more, as the interface is a stream. But it is useful
// to bunch it up into multiple read/writes when the whole message is
// a single, large serialized object.
const MessageSizeMax = 1 << 22 // 4 MB
// Deprecated: use github.com/libp2p/go-libp2p/core/network.MessageSizeMax instead
const MessageSizeMax = network.MessageSizeMax
// Direction represents which peer in a stream initiated a connection.
type Direction int
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Direction instead
type Direction = network.Direction
const (
// DirUnknown is the default direction.
DirUnknown Direction = iota
// Deprecated: use github.com/libp2p/go-libp2p/core/network.DirUnknown instead
DirUnknown = network.DirUnknown
// DirInbound is for when the remote peer initiated a connection.
DirInbound
// Deprecated: use github.com/libp2p/go-libp2p/core/network.DirInbound instead
DirInbound = network.DirInbound
// DirOutbound is for when the local peer initiated a connection.
DirOutbound
// Deprecated: use github.com/libp2p/go-libp2p/core/network.DirOutbound instead
DirOutbound = network.DirOutbound
)
func (d Direction) String() string {
str := [...]string{"Unknown", "Inbound", "Outbound"}
if d < 0 || int(d) >= len(str) {
return "(unrecognized)"
}
return str[d]
}
// Connectedness signals the capacity for a connection with a given node.
// It is used to signal to services and other peers whether a node is reachable.
type Connectedness int
type Connectedness = network.Connectedness
const (
// NotConnected means no connection to peer, and no extra information (default)
NotConnected Connectedness = iota
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NotConnected instead
NotConnected = network.NotConnected
// Connected means has an open, live connection to peer
Connected
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Connected instead
Connected = network.Connected
// CanConnect means recently connected to peer, terminated gracefully
CanConnect
// Deprecated: use github.com/libp2p/go-libp2p/core/network.CanConnect instead
CanConnect = network.CanConnect
// CannotConnect means recently attempted connecting but failed to connect.
// (should signal "made effort, failed")
CannotConnect
// Deprecated: use github.com/libp2p/go-libp2p/core/network.CannotConnect instead
CannotConnect = network.CannotConnect
)
func (c Connectedness) String() string {
str := [...]string{"NotConnected", "Connected", "CanConnect", "CannotConnect"}
if c < 0 || int(c) >= len(str) {
return "(unrecognized)"
}
return str[c]
}
// Reachability indicates how reachable a node is.
type Reachability int
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Reachability instead
type Reachability = network.Reachability
const (
// ReachabilityUnknown indicates that the reachability status of the
// node is unknown.
ReachabilityUnknown Reachability = iota
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ReachabilityUnknown instead
ReachabilityUnknown = network.ReachabilityUnknown
// ReachabilityPublic indicates that the node is reachable from the
// public internet.
ReachabilityPublic
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ReachabilityPubic instead
ReachabilityPublic = network.ReachabilityPublic
// ReachabilityPrivate indicates that the node is not reachable from the
// public internet.
//
// NOTE: This node may _still_ be reachable via relays.
ReachabilityPrivate
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ReachabilityPrivate instead
ReachabilityPrivate = network.ReachabilityPrivate
)
func (r Reachability) String() string {
str := [...]string{"Unknown", "Public", "Private"}
if r < 0 || int(r) >= len(str) {
return "(unrecognized)"
}
return str[r]
}
// ConnStats stores metadata pertaining to a given Conn.
type ConnStats struct {
Stats
// NumStreams is the number of streams on the connection.
NumStreams int
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ConnStats instead
type ConnStats = network.ConnStats
// Stats stores metadata pertaining to a given Stream / Conn.
type Stats struct {
// Direction specifies whether this is an inbound or an outbound connection.
Direction Direction
// Opened is the timestamp when this connection was opened.
Opened time.Time
// Transient indicates that this connection is transient and may be closed soon.
Transient bool
// Extra stores additional metadata about this connection.
Extra map[interface{}]interface{}
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Stats instead
type Stats = network.Stats
// StreamHandler is the type of function used to listen for
// streams opened by the remote side.
type StreamHandler func(Stream)
// Deprecated: use github.com/libp2p/go-libp2p/core/network.StreamHandler instead
type StreamHandler = network.StreamHandler
// Network is the interface used to connect to the outside world.
// It dials and listens for connections. it uses a Swarm to pool
// connections (see swarm pkg, and peerstream.Swarm). Connections
// are encrypted with a TLS-like protocol.
type Network interface {
Dialer
io.Closer
// SetStreamHandler sets the handler for new streams opened by the
// remote side. This operation is threadsafe.
SetStreamHandler(StreamHandler)
// NewStream returns a new stream to given peer p.
// If there is no connection to p, attempts to create one.
NewStream(context.Context, peer.ID) (Stream, error)
// Listen tells the network to start listening on given multiaddrs.
Listen(...ma.Multiaddr) error
// ListenAddresses returns a list of addresses at which this network listens.
ListenAddresses() []ma.Multiaddr
// InterfaceListenAddresses returns a list of addresses at which this network
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
InterfaceListenAddresses() ([]ma.Multiaddr, error)
// ResourceManager returns the ResourceManager associated with this network
ResourceManager() ResourceManager
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Network instead
type Network = network.Network
// Dialer represents a service that can dial out to peers
// (this is usually just a Network, but other services may not need the whole
// stack, and thus it becomes easier to mock)
type Dialer interface {
// Peerstore returns the internal peerstore
// This is useful to tell the dialer about a new address for a peer.
// Or use one of the public keys found out over the network.
Peerstore() peerstore.Peerstore
// LocalPeer returns the local peer associated with this network
LocalPeer() peer.ID
// DialPeer establishes a connection to a given peer
DialPeer(context.Context, peer.ID) (Conn, error)
// ClosePeer closes the connection to a given peer
ClosePeer(peer.ID) error
// Connectedness returns a state signaling connection capabilities
Connectedness(peer.ID) Connectedness
// Peers returns the peers connected
Peers() []peer.ID
// Conns returns the connections in this Netowrk
Conns() []Conn
// ConnsToPeer returns the connections in this Netowrk for given peer.
ConnsToPeer(p peer.ID) []Conn
// Notify/StopNotify register and unregister a notifiee for signals
Notify(Notifiee)
StopNotify(Notifiee)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Dialer instead
type Dialer = network.Dialer

View File

@ -1,67 +1,23 @@
package network
import (
ma "github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p/core/network"
)
// Notifiee is an interface for an object wishing to receive
// notifications from a Network.
type Notifiee interface {
Listen(Network, ma.Multiaddr) // called when network starts listening on an addr
ListenClose(Network, ma.Multiaddr) // called when network stops listening on an addr
Connected(Network, Conn) // called when a connection opened
Disconnected(Network, Conn) // called when a connection closed
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Notifiee instead
type Notifiee = network.Notifiee
// NotifyBundle implements Notifiee by calling any of the functions set on it,
// and nop'ing if they are unset. This is the easy way to register for
// notifications.
type NotifyBundle struct {
ListenF func(Network, ma.Multiaddr)
ListenCloseF func(Network, ma.Multiaddr)
ConnectedF func(Network, Conn)
DisconnectedF func(Network, Conn)
}
var _ Notifiee = (*NotifyBundle)(nil)
// Listen calls ListenF if it is not null.
func (nb *NotifyBundle) Listen(n Network, a ma.Multiaddr) {
if nb.ListenF != nil {
nb.ListenF(n, a)
}
}
// ListenClose calls ListenCloseF if it is not null.
func (nb *NotifyBundle) ListenClose(n Network, a ma.Multiaddr) {
if nb.ListenCloseF != nil {
nb.ListenCloseF(n, a)
}
}
// Connected calls ConnectedF if it is not null.
func (nb *NotifyBundle) Connected(n Network, c Conn) {
if nb.ConnectedF != nil {
nb.ConnectedF(n, c)
}
}
// Disconnected calls DisconnectedF if it is not null.
func (nb *NotifyBundle) Disconnected(n Network, c Conn) {
if nb.DisconnectedF != nil {
nb.DisconnectedF(n, c)
}
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NotifyBundle instead
type NotifyBundle = network.NotifyBundle
// Global noop notifiee. Do not change.
var GlobalNoopNotifiee = &NoopNotifiee{}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.GlobalNoopNotifiee instead
var GlobalNoopNotifiee = network.GlobalNoopNotifiee
type NoopNotifiee struct{}
var _ Notifiee = (*NoopNotifiee)(nil)
func (nn *NoopNotifiee) Connected(n Network, c Conn) {}
func (nn *NoopNotifiee) Disconnected(n Network, c Conn) {}
func (nn *NoopNotifiee) Listen(n Network, addr ma.Multiaddr) {}
func (nn *NoopNotifiee) ListenClose(n Network, addr ma.Multiaddr) {}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NoopNotifiee instead
type NoopNotifiee = network.NoopNotifiee

View File

@ -1,87 +0,0 @@
package network
import (
"testing"
ma "github.com/multiformats/go-multiaddr"
)
func TestListen(T *testing.T) {
var notifee NotifyBundle
addr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
if err != nil {
T.Fatal("unexpected multiaddr error")
}
notifee.Listen(nil, addr)
called := false
notifee.ListenF = func(Network, ma.Multiaddr) {
called = true
}
if called {
T.Fatal("called should be false")
}
notifee.Listen(nil, addr)
if !called {
T.Fatal("Listen should have been called")
}
}
func TestListenClose(T *testing.T) {
var notifee NotifyBundle
addr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
if err != nil {
T.Fatal("unexpected multiaddr error")
}
notifee.ListenClose(nil, addr)
called := false
notifee.ListenCloseF = func(Network, ma.Multiaddr) {
called = true
}
if called {
T.Fatal("called should be false")
}
notifee.ListenClose(nil, addr)
if !called {
T.Fatal("ListenClose should have been called")
}
}
func TestConnected(T *testing.T) {
var notifee NotifyBundle
notifee.Connected(nil, nil)
called := false
notifee.ConnectedF = func(Network, Conn) {
called = true
}
if called {
T.Fatal("called should be false")
}
notifee.Connected(nil, nil)
if !called {
T.Fatal("Connected should have been called")
}
}
func TestDisconnected(T *testing.T) {
var notifee NotifyBundle
notifee.Disconnected(nil, nil)
called := false
notifee.DisconnectedF = func(Network, Conn) {
called = true
}
if called {
T.Fatal("called should be false")
}
notifee.Disconnected(nil, nil)
if !called {
T.Fatal("Disconnected should have been called")
}
}

View File

@ -1,9 +1,7 @@
package network
import (
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p/core/network"
)
// ResourceManager is the interface to the network resource management subsystem.
@ -15,16 +13,17 @@ import (
// Management Scopes, whereby resource usage is constrained by a DAG of scopes,
// The following diagram illustrates the structure of the resource constraint DAG:
// System
// +------------> Transient.............+................+
// | . .
// +------------> Service------------- . ----------+ .
// | . | .
// +-------------> Protocol----------- . ----------+ .
// | . | .
// +--------------> Peer \ | .
// +------------> Connection | .
// | \ \
// +---------------------------> Stream
//
// +------------> Transient.............+................+
// | . .
// +------------> Service------------- . ----------+ .
// | . | .
// +-------------> Protocol----------- . ----------+ .
// | . | .
// +--------------> Peer \ | .
// +------------> Connection | .
// | \ \
// +---------------------------> Stream
//
// The basic resources accounted by the ResourceManager include memory, streams, connections,
// and file descriptors. These account for both space and time used by
@ -59,16 +58,16 @@ import (
// scopes can form trees, with nested spans.
//
// Typical Usage:
// - Low level components of the system (transports, muxers) all have access to the resource
// manager and create connection and stream scopes through it. These scopes are accessible
// to the user, albeit with a narrower interface, through Conn and Stream objects who have
// a Scope method.
// - Services typically center around streams, where the programmer can attach streams to a
// particular service. They can also directly reserve memory for a service by accessing the
// service scope using the ResourceManager interface.
// - Applications that want to account for their network resource usage can reserve memory,
// typically using a span, directly in the System or a Service scope; they can also
// opt to use appropriate steam scopes for streams that they create or own.
// - Low level components of the system (transports, muxers) all have access to the resource
// manager and create connection and stream scopes through it. These scopes are accessible
// to the user, albeit with a narrower interface, through Conn and Stream objects who have
// a Scope method.
// - Services typically center around streams, where the programmer can attach streams to a
// particular service. They can also directly reserve memory for a service by accessing the
// service scope using the ResourceManager interface.
// - Applications that want to account for their network resource usage can reserve memory,
// typically using a span, directly in the System or a Service scope; they can also
// opt to use appropriate steam scopes for streams that they create or own.
//
// User Serviceable Parts: the user has the option to specify their own implementation of the
// interface. We provide a canonical implementation in the go-libp2p-resource-manager package.
@ -76,252 +75,92 @@ import (
// or dynamic.
//
// WARNING The ResourceManager interface is considered experimental and subject to change
// in subsequent releases.
type ResourceManager interface {
ResourceScopeViewer
// OpenConnection creates a new connection scope not yet associated with any peer; the connection
// is scoped at the transient scope.
// The caller owns the returned scope and is responsible for calling Done in order to signify
// the end of the scope's span.
OpenConnection(dir Direction, usefd bool, endpoint multiaddr.Multiaddr) (ConnManagementScope, error)
// OpenStream creates a new stream scope, initially unnegotiated.
// An unnegotiated stream will be initially unattached to any protocol scope
// and constrained by the transient scope.
// The caller owns the returned scope and is responsible for calling Done in order to signify
// the end of th scope's span.
OpenStream(p peer.ID, dir Direction) (StreamManagementScope, error)
// Close closes the resource manager
Close() error
}
//
// in subsequent releases.
//
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ResourceManager instead
type ResourceManager = network.ResourceManager
// ResourceScopeViewer is a mixin interface providing view methods for accessing top level
// scopes.
type ResourceScopeViewer interface {
// ViewSystem views the system wide resource scope.
// The system scope is the top level scope that accounts for global
// resource usage at all levels of the system. This scope constrains all
// other scopes and institutes global hard limits.
ViewSystem(func(ResourceScope) error) error
// ViewTransient views the transient (DMZ) resource scope.
// The transient scope accounts for resources that are in the process of
// full establishment. For instance, a new connection prior to the
// handshake does not belong to any peer, but it still needs to be
// constrained as this opens an avenue for attacks in transient resource
// usage. Similarly, a stream that has not negotiated a protocol yet is
// constrained by the transient scope.
ViewTransient(func(ResourceScope) error) error
// ViewService retrieves a service-specific scope.
ViewService(string, func(ServiceScope) error) error
// ViewProtocol views the resource management scope for a specific protocol.
ViewProtocol(protocol.ID, func(ProtocolScope) error) error
// ViewPeer views the resource management scope for a specific peer.
ViewPeer(peer.ID, func(PeerScope) error) error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ResourceScopeViewer instead
type ResourceScopeViewer = network.ResourceScopeViewer
const (
// ReservationPriorityLow is a reservation priority that indicates a reservation if the scope
// memory utilization is at 40% or less.
ReservationPriorityLow uint8 = 101
// Reservation PriorityMedium is a reservation priority that indicates a reservation if the scope
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ReservationPriorityLow instead
ReservationPriorityLow = network.ReservationPriorityLow
// ReservationPriorityMedium is a reservation priority that indicates a reservation if the scope
// memory utilization is at 60% or less.
ReservationPriorityMedium uint8 = 152
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ReservationPriorityMedium instead
ReservationPriorityMedium uint8 = network.ReservationPriorityMedium
// ReservationPriorityHigh is a reservation prioirity that indicates a reservation if the scope
// memory utilization is at 80% or less.
ReservationPriorityHigh uint8 = 203
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ReservationPriorityHigh instead
ReservationPriorityHigh uint8 = network.ReservationPriorityHigh
// ReservationPriorityAlways is a reservation priority that indicates a reservation if there is
// enough memory, regardless of scope utilization.
ReservationPriorityAlways uint8 = 255
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ReservationPriorityAlways instead
ReservationPriorityAlways = network.ReservationPriorityAlways
)
// ResourceScope is the interface for all scopes.
type ResourceScope interface {
// ReserveMemory reserves memory/buffer space in the scope; the unit is bytes.
//
// If ReserveMemory returns an error, then no memory was reserved and the caller should handle
// the failure condition.
//
// The priority argument indicates the priority of the memory reservation. A reservation
// will fail if the available memory is less than (1+prio)/256 of the scope limit, providing
// a mechanism to gracefully handle optional reservations that might overload the system.
// For instance, a muxer growing a window buffer will use a low priority and only grow the buffer
// if there is no memory pressure in the system.
//
// The are 4 predefined priority levels, Low, Medium, High and Always,
// capturing common patterns, but the user is free to use any granularity applicable to his case.
ReserveMemory(size int, prio uint8) error
// ReleaseMemory explicitly releases memory previously reserved with ReserveMemory
ReleaseMemory(size int)
// Stat retrieves current resource usage for the scope.
Stat() ScopeStat
// BeginSpan creates a new span scope rooted at this scope
BeginSpan() (ResourceScopeSpan, error)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ResourceScope instead
type ResourceScope = network.ResourceScope
// ResourceScopeSpan is a ResourceScope with a delimited span.
// Span scopes are control flow delimited and release all their associated resources
// when the programmer calls Done.
//
// Example:
// s, err := someScope.BeginSpan()
// if err != nil { ... }
// defer s.Done()
//
// if err := s.ReserveMemory(...); err != nil { ... }
// // ... use memory
type ResourceScopeSpan interface {
ResourceScope
// Done ends the span and releases associated resources.
Done()
}
// s, err := someScope.BeginSpan()
// if err != nil { ... }
// defer s.Done()
//
// if err := s.ReserveMemory(...); err != nil { ... }
// // ... use memory
//
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ResourceScopeSpan instead
type ResourceScopeSpan = network.ResourceScopeSpan
// ServiceScope is the interface for service resource scopes
type ServiceScope interface {
ResourceScope
// Name returns the name of this service
Name() string
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ServiceScope instead
type ServiceScope = network.ServiceScope
// ProtocolScope is the interface for protocol resource scopes.
type ProtocolScope interface {
ResourceScope
// Protocol returns the protocol for this scope
Protocol() protocol.ID
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ProtocolScope instead
type ProtocolScope = network.ProtocolScope
// PeerScope is the interface for peer resource scopes.
type PeerScope interface {
ResourceScope
// Peer returns the peer ID for this scope
Peer() peer.ID
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.PeerScope instead
type PeerScope = network.PeerScope
// ConnManagementScope is the low level interface for connection resource scopes.
// This interface is used by the low level components of the system who create and own
// the span of a connection scope.
type ConnManagementScope interface {
ResourceScopeSpan
// PeerScope returns the peer scope associated with this connection.
// It returns nil if the connection is not yet asociated with any peer.
PeerScope() PeerScope
// SetPeer sets the peer for a previously unassociated connection
SetPeer(peer.ID) error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ConnManagementScope instead
type ConnManagementScope = network.ConnManagementScope
// ConnScope is the user view of a connection scope
type ConnScope interface {
ResourceScope
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ConnScope instead
type ConnScope = network.ConnScope
// StreamManagementScope is the interface for stream resource scopes.
// This interface is used by the low level components of the system who create and own
// the span of a stream scope.
type StreamManagementScope interface {
ResourceScopeSpan
// ProtocolScope returns the protocol resource scope associated with this stream.
// It returns nil if the stream is not associated with any protocol scope.
ProtocolScope() ProtocolScope
// SetProtocol sets the protocol for a previously unnegotiated stream
SetProtocol(proto protocol.ID) error
// ServiceScope returns the service owning the stream, if any.
ServiceScope() ServiceScope
// SetService sets the service owning this stream.
SetService(srv string) error
// PeerScope returns the peer resource scope associated with this stream.
PeerScope() PeerScope
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.StreamManagementScope instead
type StreamManagementScope = network.StreamManagementScope
// StreamScope is the user view of a StreamScope.
type StreamScope interface {
ResourceScope
// SetService sets the service owning this stream.
SetService(srv string) error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.StreamScope instead
type StreamScope = network.StreamScope
// ScopeStat is a struct containing resource accounting information.
type ScopeStat struct {
NumStreamsInbound int
NumStreamsOutbound int
NumConnsInbound int
NumConnsOutbound int
NumFD int
Memory int64
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.ScopeStat instead
type ScopeStat = network.ScopeStat
// NullResourceManager is a stub for tests and initialization of default values
var NullResourceManager ResourceManager = &nullResourceManager{}
type nullResourceManager struct{}
type nullScope struct{}
var _ ResourceScope = (*nullScope)(nil)
var _ ResourceScopeSpan = (*nullScope)(nil)
var _ ServiceScope = (*nullScope)(nil)
var _ ProtocolScope = (*nullScope)(nil)
var _ PeerScope = (*nullScope)(nil)
var _ ConnManagementScope = (*nullScope)(nil)
var _ ConnScope = (*nullScope)(nil)
var _ StreamManagementScope = (*nullScope)(nil)
var _ StreamScope = (*nullScope)(nil)
// NullScope is a stub for tests and initialization of default values
var NullScope = &nullScope{}
func (n *nullResourceManager) ViewSystem(f func(ResourceScope) error) error {
return f(NullScope)
}
func (n *nullResourceManager) ViewTransient(f func(ResourceScope) error) error {
return f(NullScope)
}
func (n *nullResourceManager) ViewService(svc string, f func(ServiceScope) error) error {
return f(NullScope)
}
func (n *nullResourceManager) ViewProtocol(p protocol.ID, f func(ProtocolScope) error) error {
return f(NullScope)
}
func (n *nullResourceManager) ViewPeer(p peer.ID, f func(PeerScope) error) error {
return f(NullScope)
}
func (n *nullResourceManager) OpenConnection(dir Direction, usefd bool, endpoint multiaddr.Multiaddr) (ConnManagementScope, error) {
return NullScope, nil
}
func (n *nullResourceManager) OpenStream(p peer.ID, dir Direction) (StreamManagementScope, error) {
return NullScope, nil
}
func (n *nullResourceManager) Close() error {
return nil
}
func (n *nullScope) ReserveMemory(size int, prio uint8) error { return nil }
func (n *nullScope) ReleaseMemory(size int) {}
func (n *nullScope) Stat() ScopeStat { return ScopeStat{} }
func (n *nullScope) BeginSpan() (ResourceScopeSpan, error) { return NullScope, nil }
func (n *nullScope) Done() {}
func (n *nullScope) Name() string { return "" }
func (n *nullScope) Protocol() protocol.ID { return "" }
func (n *nullScope) Peer() peer.ID { return "" }
func (n *nullScope) PeerScope() PeerScope { return NullScope }
func (n *nullScope) SetPeer(peer.ID) error { return nil }
func (n *nullScope) ProtocolScope() ProtocolScope { return NullScope }
func (n *nullScope) SetProtocol(proto protocol.ID) error { return nil }
func (n *nullScope) ServiceScope() ServiceScope { return NullScope }
func (n *nullScope) SetService(srv string) error { return nil }
// Deprecated: use github.com/libp2p/go-libp2p/core/network.NullResourceManager instead
var NullResourceManager = network.NullResourceManager

View File

@ -1,7 +1,7 @@
package network
import (
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/libp2p/go-libp2p/core/network"
)
// Stream represents a bidirectional channel between two agents in
@ -9,22 +9,5 @@ import (
// being a "request -> reply" pair, or whole protocols.
//
// Streams are backed by a multiplexer underneath the hood.
type Stream interface {
MuxedStream
// ID returns an identifier that uniquely identifies this Stream within this
// host, during this run. Stream IDs may repeat across restarts.
ID() string
Protocol() protocol.ID
SetProtocol(id protocol.ID) error
// Stat returns metadata pertaining to this stream.
Stat() Stats
// Conn returns the connection this stream is part of.
Conn() Conn
// Scope returns the user's view of this stream's resource scope
Scope() StreamScope
}
// Deprecated: use github.com/libp2p/go-libp2p/core/network.Stream instead
type Stream = network.Stream

View File

@ -1,117 +1,54 @@
package peer
import (
"fmt"
"github.com/libp2p/go-libp2p/core/peer"
ma "github.com/multiformats/go-multiaddr"
)
// AddrInfo is a small struct used to pass around a peer with
// a set of addresses (and later, keys?).
type AddrInfo struct {
ID ID
Addrs []ma.Multiaddr
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.AddrInfo instead
type AddrInfo = peer.AddrInfo
var _ fmt.Stringer = AddrInfo{}
func (pi AddrInfo) String() string {
return fmt.Sprintf("{%v: %v}", pi.ID, pi.Addrs)
}
var ErrInvalidAddr = fmt.Errorf("invalid p2p multiaddr")
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.ErrInvalidAddr instead
var ErrInvalidAddr = peer.ErrInvalidAddr
// AddrInfosFromP2pAddrs converts a set of Multiaddrs to a set of AddrInfos.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.AddrInfosFromP2pAddrs instead
func AddrInfosFromP2pAddrs(maddrs ...ma.Multiaddr) ([]AddrInfo, error) {
m := make(map[ID][]ma.Multiaddr)
for _, maddr := range maddrs {
transport, id := SplitAddr(maddr)
if id == "" {
return nil, ErrInvalidAddr
}
if transport == nil {
if _, ok := m[id]; !ok {
m[id] = nil
}
} else {
m[id] = append(m[id], transport)
}
}
ais := make([]AddrInfo, 0, len(m))
for id, maddrs := range m {
ais = append(ais, AddrInfo{ID: id, Addrs: maddrs})
}
return ais, nil
return peer.AddrInfosFromP2pAddrs(maddrs...)
}
// SplitAddr splits a p2p Multiaddr into a transport multiaddr and a peer ID.
//
// * Returns a nil transport if the address only contains a /p2p part.
// * Returns a empty peer ID if the address doesn't contain a /p2p part.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.SplitAddr instead
func SplitAddr(m ma.Multiaddr) (transport ma.Multiaddr, id ID) {
if m == nil {
return nil, ""
}
transport, p2ppart := ma.SplitLast(m)
if p2ppart == nil || p2ppart.Protocol().Code != ma.P_P2P {
return m, ""
}
id = ID(p2ppart.RawValue()) // already validated by the multiaddr library.
return transport, id
return peer.SplitAddr(m)
}
// AddrInfoFromString builds an AddrInfo from the string representation of a Multiaddr
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.AddrInfoFromString instead
func AddrInfoFromString(s string) (*AddrInfo, error) {
a, err := ma.NewMultiaddr(s)
if err != nil {
return nil, err
}
return AddrInfoFromP2pAddr(a)
return peer.AddrInfoFromString(s)
}
// AddrInfoFromP2pAddr converts a Multiaddr to an AddrInfo.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.AddrInfoFromP2pAddr instead
func AddrInfoFromP2pAddr(m ma.Multiaddr) (*AddrInfo, error) {
transport, id := SplitAddr(m)
if id == "" {
return nil, ErrInvalidAddr
}
info := &AddrInfo{ID: id}
if transport != nil {
info.Addrs = []ma.Multiaddr{transport}
}
return info, nil
return peer.AddrInfoFromP2pAddr(m)
}
// AddrInfoToP2pAddrs converts an AddrInfo to a list of Multiaddrs.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.AddrInfoToP2pAddrs instead
func AddrInfoToP2pAddrs(pi *AddrInfo) ([]ma.Multiaddr, error) {
var addrs []ma.Multiaddr
p2ppart, err := ma.NewComponent("p2p", Encode(pi.ID))
if err != nil {
return nil, err
}
if len(pi.Addrs) == 0 {
return []ma.Multiaddr{p2ppart}, nil
}
for _, addr := range pi.Addrs {
addrs = append(addrs, addr.Encapsulate(p2ppart))
}
return addrs, nil
}
func (pi *AddrInfo) Loggable() map[string]interface{} {
return map[string]interface{}{
"peerID": pi.ID.Pretty(),
"addrs": pi.Addrs,
}
return peer.AddrInfoToP2pAddrs(pi)
}
// AddrInfosToIDs extracts the peer IDs from the passed AddrInfos and returns them in-order.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.AddrInfosToIDs instead
func AddrInfosToIDs(pis []AddrInfo) []ID {
ps := make([]ID, len(pis))
for i, pi := range pis {
ps[i] = pi.ID
}
return ps
return peer.AddrInfosToIDs(pis)
}

View File

@ -1,47 +0,0 @@
package peer
import (
"encoding/json"
"github.com/libp2p/go-libp2p-core/internal/catch"
ma "github.com/multiformats/go-multiaddr"
)
// Helper struct for decoding as we can't unmarshal into an interface (Multiaddr).
type addrInfoJson struct {
ID ID
Addrs []string
}
func (pi AddrInfo) MarshalJSON() (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "libp2p addr info marshal") }()
addrs := make([]string, len(pi.Addrs))
for i, addr := range pi.Addrs {
addrs[i] = addr.String()
}
return json.Marshal(&addrInfoJson{
ID: pi.ID,
Addrs: addrs,
})
}
func (pi *AddrInfo) UnmarshalJSON(b []byte) (err error) {
defer func() { catch.HandlePanic(recover(), &err, "libp2p addr info unmarshal") }()
var data addrInfoJson
if err := json.Unmarshal(b, &data); err != nil {
return err
}
addrs := make([]ma.Multiaddr, len(data.Addrs))
for i, addr := range data.Addrs {
maddr, err := ma.NewMultiaddr(addr)
if err != nil {
return err
}
addrs[i] = maddr
}
pi.ID = data.ID
pi.Addrs = addrs
return nil
}

View File

@ -1,152 +0,0 @@
package peer_test
import (
"testing"
ma "github.com/multiformats/go-multiaddr"
. "github.com/libp2p/go-libp2p-core/peer"
)
var (
testID ID
maddrFull, maddrTpt, maddrPeer ma.Multiaddr
)
func init() {
var err error
testID, err = Decode("QmS3zcG7LhYZYSJMhyRZvTddvbNUqtt8BJpaSs6mi1K5Va")
if err != nil {
panic(err)
}
maddrPeer = ma.StringCast("/p2p/" + Encode(testID))
maddrTpt = ma.StringCast("/ip4/127.0.0.1/tcp/1234")
maddrFull = maddrTpt.Encapsulate(maddrPeer)
}
func TestSplitAddr(t *testing.T) {
tpt, id := SplitAddr(maddrFull)
if !tpt.Equal(maddrTpt) {
t.Fatal("expected transport")
}
if id != testID {
t.Fatalf("%s != %s", id, testID)
}
tpt, id = SplitAddr(maddrPeer)
if tpt != nil {
t.Fatal("expected no transport")
}
if id != testID {
t.Fatalf("%s != %s", id, testID)
}
tpt, id = SplitAddr(maddrTpt)
if !tpt.Equal(maddrTpt) {
t.Fatal("expected a transport")
}
if id != "" {
t.Fatal("expected no peer ID")
}
}
func TestAddrInfoFromP2pAddr(t *testing.T) {
ai, err := AddrInfoFromP2pAddr(maddrFull)
if err != nil {
t.Fatal(err)
}
if len(ai.Addrs) != 1 || !ai.Addrs[0].Equal(maddrTpt) {
t.Fatal("expected transport")
}
if ai.ID != testID {
t.Fatalf("%s != %s", ai.ID, testID)
}
ai, err = AddrInfoFromP2pAddr(maddrPeer)
if err != nil {
t.Fatal(err)
}
if len(ai.Addrs) != 0 {
t.Fatal("expected transport")
}
if ai.ID != testID {
t.Fatalf("%s != %s", ai.ID, testID)
}
_, err = AddrInfoFromP2pAddr(maddrTpt)
if err != ErrInvalidAddr {
t.Fatalf("wrong error: %s", err)
}
}
func TestAddrInfosFromP2pAddrs(t *testing.T) {
infos, err := AddrInfosFromP2pAddrs()
if err != nil {
t.Fatal(err)
}
if len(infos) != 0 {
t.Fatal("expected no addrs")
}
if _, err = AddrInfosFromP2pAddrs(nil); err == nil {
t.Fatal("expected nil multiaddr to fail")
}
addrs := []ma.Multiaddr{
ma.StringCast("/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64"),
ma.StringCast("/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64"),
ma.StringCast("/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd"),
ma.StringCast("/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd"),
ma.StringCast("/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM"),
}
expected := map[string][]ma.Multiaddr{
"QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64": {
ma.StringCast("/ip4/128.199.219.111/tcp/4001"),
ma.StringCast("/ip4/104.236.76.40/tcp/4001"),
},
"QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd": {
ma.StringCast("/ip4/178.62.158.247/tcp/4001"),
},
"QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM": nil,
}
infos, err = AddrInfosFromP2pAddrs(addrs...)
if err != nil {
t.Fatal(err)
}
for _, info := range infos {
exaddrs, ok := expected[info.ID.Pretty()]
if !ok {
t.Fatalf("didn't expect peer %s", info.ID)
}
if len(info.Addrs) != len(exaddrs) {
t.Fatalf("got %d addrs, expected %d", len(info.Addrs), len(exaddrs))
}
// AddrInfosFromP2pAddrs preserves order. I'd like to keep this
// guarantee for now.
for i, addr := range info.Addrs {
if !exaddrs[i].Equal(addr) {
t.Fatalf("expected %s, got %s", exaddrs[i], addr)
}
}
delete(expected, info.ID.Pretty())
}
}
func TestAddrInfoJSON(t *testing.T) {
ai := AddrInfo{ID: testID, Addrs: []ma.Multiaddr{maddrFull}}
out, err := ai.MarshalJSON()
if err != nil {
t.Fatal(err)
}
var addrInfo AddrInfo
if err := addrInfo.UnmarshalJSON(out); err != nil {
t.Fatal(err)
}
if addrInfo.ID != testID {
t.Fatalf("expected ID to equal %s, got %s", testID.Pretty(), addrInfo.ID.Pretty())
}
if len(addrInfo.Addrs) != 1 || !addrInfo.Addrs[0].Equal(maddrFull) {
t.Fatalf("expected addrs to match %v, got %v", maddrFull, addrInfo.Addrs)
}
}

View File

@ -1,11 +0,0 @@
PB = $(wildcard *.proto)
GO = $(PB:.proto=.pb.go)
all: $(GO)
%.pb.go: %.proto
protoc --proto_path=$(PWD):$(PWD)/../.. --gogofaster_out=. $<
clean:
rm -f *.pb.go
rm -f *.go

View File

@ -1,606 +0,0 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: peer_record.proto
package peer_pb
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// PeerRecord messages contain information that is useful to share with other peers.
// Currently, a PeerRecord contains the public listen addresses for a peer, but this
// is expected to expand to include other information in the future.
//
// PeerRecords are designed to be serialized to bytes and placed inside of
// SignedEnvelopes before sharing with other peers.
// See https://github.com/libp2p/go-libp2p-core/record/pb/envelope.proto for
// the SignedEnvelope definition.
type PeerRecord struct {
// peer_id contains a libp2p peer id in its binary representation.
PeerId []byte `protobuf:"bytes,1,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"`
// seq contains a monotonically-increasing sequence counter to order PeerRecords in time.
Seq uint64 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq,omitempty"`
// addresses is a list of public listen addresses for the peer.
Addresses []*PeerRecord_AddressInfo `protobuf:"bytes,3,rep,name=addresses,proto3" json:"addresses,omitempty"`
}
func (m *PeerRecord) Reset() { *m = PeerRecord{} }
func (m *PeerRecord) String() string { return proto.CompactTextString(m) }
func (*PeerRecord) ProtoMessage() {}
func (*PeerRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_dc0d8059ab0ad14d, []int{0}
}
func (m *PeerRecord) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PeerRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PeerRecord.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PeerRecord) XXX_Merge(src proto.Message) {
xxx_messageInfo_PeerRecord.Merge(m, src)
}
func (m *PeerRecord) XXX_Size() int {
return m.Size()
}
func (m *PeerRecord) XXX_DiscardUnknown() {
xxx_messageInfo_PeerRecord.DiscardUnknown(m)
}
var xxx_messageInfo_PeerRecord proto.InternalMessageInfo
func (m *PeerRecord) GetPeerId() []byte {
if m != nil {
return m.PeerId
}
return nil
}
func (m *PeerRecord) GetSeq() uint64 {
if m != nil {
return m.Seq
}
return 0
}
func (m *PeerRecord) GetAddresses() []*PeerRecord_AddressInfo {
if m != nil {
return m.Addresses
}
return nil
}
// AddressInfo is a wrapper around a binary multiaddr. It is defined as a
// separate message to allow us to add per-address metadata in the future.
type PeerRecord_AddressInfo struct {
Multiaddr []byte `protobuf:"bytes,1,opt,name=multiaddr,proto3" json:"multiaddr,omitempty"`
}
func (m *PeerRecord_AddressInfo) Reset() { *m = PeerRecord_AddressInfo{} }
func (m *PeerRecord_AddressInfo) String() string { return proto.CompactTextString(m) }
func (*PeerRecord_AddressInfo) ProtoMessage() {}
func (*PeerRecord_AddressInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_dc0d8059ab0ad14d, []int{0, 0}
}
func (m *PeerRecord_AddressInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PeerRecord_AddressInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PeerRecord_AddressInfo.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PeerRecord_AddressInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_PeerRecord_AddressInfo.Merge(m, src)
}
func (m *PeerRecord_AddressInfo) XXX_Size() int {
return m.Size()
}
func (m *PeerRecord_AddressInfo) XXX_DiscardUnknown() {
xxx_messageInfo_PeerRecord_AddressInfo.DiscardUnknown(m)
}
var xxx_messageInfo_PeerRecord_AddressInfo proto.InternalMessageInfo
func (m *PeerRecord_AddressInfo) GetMultiaddr() []byte {
if m != nil {
return m.Multiaddr
}
return nil
}
func init() {
proto.RegisterType((*PeerRecord)(nil), "peer.pb.PeerRecord")
proto.RegisterType((*PeerRecord_AddressInfo)(nil), "peer.pb.PeerRecord.AddressInfo")
}
func init() { proto.RegisterFile("peer_record.proto", fileDescriptor_dc0d8059ab0ad14d) }
var fileDescriptor_dc0d8059ab0ad14d = []byte{
// 189 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2c, 0x48, 0x4d, 0x2d,
0x8a, 0x2f, 0x4a, 0x4d, 0xce, 0x2f, 0x4a, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x07,
0x09, 0xe9, 0x15, 0x24, 0x29, 0x2d, 0x66, 0xe4, 0xe2, 0x0a, 0x48, 0x4d, 0x2d, 0x0a, 0x02, 0xcb,
0x0a, 0x89, 0x73, 0x81, 0x65, 0xe2, 0x33, 0x53, 0x24, 0x18, 0x15, 0x18, 0x35, 0x78, 0x82, 0xd8,
0x40, 0x5c, 0xcf, 0x14, 0x21, 0x01, 0x2e, 0xe6, 0xe2, 0xd4, 0x42, 0x09, 0x26, 0x05, 0x46, 0x0d,
0x96, 0x20, 0x10, 0x53, 0xc8, 0x96, 0x8b, 0x33, 0x31, 0x25, 0xa5, 0x28, 0xb5, 0xb8, 0x38, 0xb5,
0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x5e, 0x0f, 0x6a, 0xac, 0x1e, 0xc2, 0x48, 0x3d,
0x47, 0x88, 0x22, 0xcf, 0xbc, 0xb4, 0xfc, 0x20, 0x84, 0x0e, 0x29, 0x6d, 0x2e, 0x6e, 0x24, 0x19,
0x21, 0x19, 0x2e, 0xce, 0xdc, 0xd2, 0x9c, 0x92, 0x4c, 0x90, 0x02, 0xa8, 0xd5, 0x08, 0x01, 0x27,
0x89, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63,
0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x48, 0x62, 0x03, 0xfb, 0xc7, 0x18,
0x10, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x99, 0x56, 0x19, 0xe4, 0x00, 0x00, 0x00,
}
func (m *PeerRecord) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PeerRecord) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PeerRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Addresses) > 0 {
for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Addresses[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintPeerRecord(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
if m.Seq != 0 {
i = encodeVarintPeerRecord(dAtA, i, uint64(m.Seq))
i--
dAtA[i] = 0x10
}
if len(m.PeerId) > 0 {
i -= len(m.PeerId)
copy(dAtA[i:], m.PeerId)
i = encodeVarintPeerRecord(dAtA, i, uint64(len(m.PeerId)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *PeerRecord_AddressInfo) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PeerRecord_AddressInfo) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PeerRecord_AddressInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Multiaddr) > 0 {
i -= len(m.Multiaddr)
copy(dAtA[i:], m.Multiaddr)
i = encodeVarintPeerRecord(dAtA, i, uint64(len(m.Multiaddr)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintPeerRecord(dAtA []byte, offset int, v uint64) int {
offset -= sovPeerRecord(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *PeerRecord) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.PeerId)
if l > 0 {
n += 1 + l + sovPeerRecord(uint64(l))
}
if m.Seq != 0 {
n += 1 + sovPeerRecord(uint64(m.Seq))
}
if len(m.Addresses) > 0 {
for _, e := range m.Addresses {
l = e.Size()
n += 1 + l + sovPeerRecord(uint64(l))
}
}
return n
}
func (m *PeerRecord_AddressInfo) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Multiaddr)
if l > 0 {
n += 1 + l + sovPeerRecord(uint64(l))
}
return n
}
func sovPeerRecord(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozPeerRecord(x uint64) (n int) {
return sovPeerRecord(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *PeerRecord) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PeerRecord: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PeerRecord: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PeerId", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthPeerRecord
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthPeerRecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.PeerId = append(m.PeerId[:0], dAtA[iNdEx:postIndex]...)
if m.PeerId == nil {
m.PeerId = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Seq", wireType)
}
m.Seq = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Seq |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthPeerRecord
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthPeerRecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Addresses = append(m.Addresses, &PeerRecord_AddressInfo{})
if err := m.Addresses[len(m.Addresses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPeerRecord(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPeerRecord
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthPeerRecord
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *PeerRecord_AddressInfo) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AddressInfo: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AddressInfo: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Multiaddr", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthPeerRecord
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthPeerRecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Multiaddr = append(m.Multiaddr[:0], dAtA[iNdEx:postIndex]...)
if m.Multiaddr == nil {
m.Multiaddr = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPeerRecord(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPeerRecord
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthPeerRecord
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipPeerRecord(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPeerRecord
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthPeerRecord
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupPeerRecord
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthPeerRecord
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthPeerRecord = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowPeerRecord = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupPeerRecord = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -1,29 +0,0 @@
syntax = "proto3";
package peer.pb;
// PeerRecord messages contain information that is useful to share with other peers.
// Currently, a PeerRecord contains the public listen addresses for a peer, but this
// is expected to expand to include other information in the future.
//
// PeerRecords are designed to be serialized to bytes and placed inside of
// SignedEnvelopes before sharing with other peers.
// See https://github.com/libp2p/go-libp2p-core/record/pb/envelope.proto for
// the SignedEnvelope definition.
message PeerRecord {
// AddressInfo is a wrapper around a binary multiaddr. It is defined as a
// separate message to allow us to add per-address metadata in the future.
message AddressInfo {
bytes multiaddr = 1;
}
// peer_id contains a libp2p peer id in its binary representation.
bytes peer_id = 1;
// seq contains a monotonically-increasing sequence counter to order PeerRecords in time.
uint64 seq = 2;
// addresses is a list of public listen addresses for the peer.
repeated AddressInfo addresses = 3;
}

View File

@ -1,23 +1,22 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/peer.
//
// Package peer implements an object used to represent peers in the libp2p network.
package peer
import (
"errors"
"fmt"
"strings"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/ipfs/go-cid"
ic "github.com/libp2p/go-libp2p-core/crypto"
b58 "github.com/mr-tron/base58/base58"
mc "github.com/multiformats/go-multicodec"
mh "github.com/multiformats/go-multihash"
)
var (
// ErrEmptyPeerID is an error for empty peer ID.
ErrEmptyPeerID = errors.New("empty peer ID")
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.ErrEmptyPeerID instead
ErrEmptyPeerID = peer.ErrEmptyPeerID
// ErrNoPublicKey is an error for peer IDs that don't embed public keys
ErrNoPublicKey = errors.New("public key is not embedded in peer ID")
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.ErrNoPublicKey instead
ErrNoPublicKey = peer.ErrNoPublicKey
)
// AdvancedEnableInlining enables automatically inlining keys shorter than
@ -31,7 +30,8 @@ var (
//
// This currently defaults to true for backwards compatibility but will likely
// be set to false by default when an upgrade path is determined.
var AdvancedEnableInlining = true
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.AdvancedEnableInlining instead
var AdvancedEnableInlining = peer.AdvancedEnableInlining
const maxInlineKeyLength = 42
@ -39,88 +39,14 @@ const maxInlineKeyLength = 42
//
// Peer IDs are derived by hashing a peer's public key and encoding the
// hash output as a multihash. See IDFromPublicKey for details.
type ID string
// Pretty returns a base58-encoded string representation of the ID.
// Deprecated: use String() instead.
func (id ID) Pretty() string {
return id.String()
}
// Loggable returns a pretty peer ID string in loggable JSON format.
func (id ID) Loggable() map[string]interface{} {
return map[string]interface{}{
"peerID": id.String(),
}
}
func (id ID) String() string {
return b58.Encode([]byte(id))
}
// ShortString prints out the peer ID.
//
// TODO(brian): ensure correctness at ID generation and
// enforce this by only exposing functions that generate
// IDs safely. Then any peer.ID type found in the
// codebase is known to be correct.
func (id ID) ShortString() string {
pid := id.String()
if len(pid) <= 10 {
return fmt.Sprintf("<peer.ID %s>", pid)
}
return fmt.Sprintf("<peer.ID %s*%s>", pid[:2], pid[len(pid)-6:])
}
// MatchesPrivateKey tests whether this ID was derived from the secret key sk.
func (id ID) MatchesPrivateKey(sk ic.PrivKey) bool {
return id.MatchesPublicKey(sk.GetPublic())
}
// MatchesPublicKey tests whether this ID was derived from the public key pk.
func (id ID) MatchesPublicKey(pk ic.PubKey) bool {
oid, err := IDFromPublicKey(pk)
if err != nil {
return false
}
return oid == id
}
// ExtractPublicKey attempts to extract the public key from an ID.
//
// This method returns ErrNoPublicKey if the peer ID looks valid but it can't extract
// the public key.
func (id ID) ExtractPublicKey() (ic.PubKey, error) {
decoded, err := mh.Decode([]byte(id))
if err != nil {
return nil, err
}
if decoded.Code != mh.IDENTITY {
return nil, ErrNoPublicKey
}
pk, err := ic.UnmarshalPublicKey(decoded.Digest)
if err != nil {
return nil, err
}
return pk, nil
}
// Validate checks if ID is empty or not.
func (id ID) Validate() error {
if id == ID("") {
return ErrEmptyPeerID
}
return nil
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.ID instead
type ID = peer.ID
// IDFromBytes casts a byte slice to the ID type, and validates
// the value to make sure it is a multihash.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.IDFromBytes instead
func IDFromBytes(b []byte) (ID, error) {
if _, err := mh.Cast(b); err != nil {
return ID(""), err
}
return ID(b), nil
return peer.IDFromBytes(b)
}
// Decode accepts an encoded peer ID and returns the decoded ID if the input is
@ -128,21 +54,9 @@ func IDFromBytes(b []byte) (ID, error) {
//
// The encoded peer ID can either be a CID of a key or a raw multihash (identity
// or sha256-256).
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.Decode instead
func Decode(s string) (ID, error) {
if strings.HasPrefix(s, "Qm") || strings.HasPrefix(s, "1") {
// base58 encoded sha256 or identity multihash
m, err := mh.FromB58String(s)
if err != nil {
return "", fmt.Errorf("failed to parse peer ID: %s", err)
}
return ID(m), nil
}
c, err := cid.Decode(s)
if err != nil {
return "", fmt.Errorf("failed to parse peer ID: %s", err)
}
return FromCid(c)
return peer.Decode(s)
}
// Encode encodes a peer ID as a string.
@ -150,61 +64,37 @@ func Decode(s string) (ID, error) {
// At the moment, it base58 encodes the peer ID but, in the future, it will
// switch to encoding it as a CID by default.
//
// Deprecated: use id.String instead.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.Encode instead
func Encode(id ID) string {
return id.String()
return peer.Encode(id)
}
// FromCid converts a CID to a peer ID, if possible.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.FromCid instead
func FromCid(c cid.Cid) (ID, error) {
code := mc.Code(c.Type())
if code != mc.Libp2pKey {
return "", fmt.Errorf("can't convert CID of type %q to a peer ID", code)
}
return ID(c.Hash()), nil
return peer.FromCid(c)
}
// ToCid encodes a peer ID as a CID of the public key.
//
// If the peer ID is invalid (e.g., empty), this will return the empty CID.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.ToCid instead
func ToCid(id ID) cid.Cid {
m, err := mh.Cast([]byte(id))
if err != nil {
return cid.Cid{}
}
return cid.NewCidV1(cid.Libp2pKey, m)
return peer.ToCid(id)
}
// IDFromPublicKey returns the Peer ID corresponding to the public key pk.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.IDFromPublicKey instead
func IDFromPublicKey(pk ic.PubKey) (ID, error) {
b, err := ic.MarshalPublicKey(pk)
if err != nil {
return "", err
}
var alg uint64 = mh.SHA2_256
if AdvancedEnableInlining && len(b) <= maxInlineKeyLength {
alg = mh.IDENTITY
}
hash, _ := mh.Sum(b, alg, -1)
return ID(hash), nil
return peer.IDFromPublicKey(pk)
}
// IDFromPrivateKey returns the Peer ID corresponding to the secret key sk.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.IDFromPrivateKey instead
func IDFromPrivateKey(sk ic.PrivKey) (ID, error) {
return IDFromPublicKey(sk.GetPublic())
return peer.IDFromPrivateKey(sk)
}
// IDSlice for sorting peers.
type IDSlice []ID
func (es IDSlice) Len() int { return len(es) }
func (es IDSlice) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
func (es IDSlice) Less(i, j int) bool { return string(es[i]) < string(es[j]) }
func (es IDSlice) String() string {
peersStrings := make([]string, len(es))
for i, id := range es {
peersStrings[i] = id.String()
}
return strings.Join(peersStrings, ", ")
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.IDSlice instead
type IDSlice = peer.IDSlice

View File

@ -1,75 +0,0 @@
// Package peer contains Protobuf and JSON serialization/deserialization methods for peer IDs.
package peer
import (
"encoding"
"encoding/json"
)
// Interface assertions commented out to avoid introducing hard dependencies to protobuf.
// var _ proto.Marshaler = (*ID)(nil)
// var _ proto.Unmarshaler = (*ID)(nil)
var _ json.Marshaler = (*ID)(nil)
var _ json.Unmarshaler = (*ID)(nil)
var _ encoding.BinaryMarshaler = (*ID)(nil)
var _ encoding.BinaryUnmarshaler = (*ID)(nil)
var _ encoding.TextMarshaler = (*ID)(nil)
var _ encoding.TextUnmarshaler = (*ID)(nil)
func (id ID) Marshal() ([]byte, error) {
return []byte(id), nil
}
// MarshalBinary returns the byte representation of the peer ID.
func (id ID) MarshalBinary() ([]byte, error) {
return id.Marshal()
}
func (id ID) MarshalTo(data []byte) (n int, err error) {
return copy(data, []byte(id)), nil
}
func (id *ID) Unmarshal(data []byte) (err error) {
*id, err = IDFromBytes(data)
return err
}
// UnmarshalBinary sets the ID from its binary representation.
func (id *ID) UnmarshalBinary(data []byte) error {
return id.Unmarshal(data)
}
// Size implements Gogo's proto.Sizer, but we omit the compile-time assertion to avoid introducing a hard
// dependency on gogo.
func (id ID) Size() int {
return len([]byte(id))
}
func (id ID) MarshalJSON() ([]byte, error) {
return json.Marshal(Encode(id))
}
func (id *ID) UnmarshalJSON(data []byte) (err error) {
var v string
if err = json.Unmarshal(data, &v); err != nil {
return err
}
*id, err = Decode(v)
return err
}
// MarshalText returns the text encoding of the ID.
func (id ID) MarshalText() ([]byte, error) {
return []byte(Encode(id)), nil
}
// UnmarshalText restores the ID from its text encoding.
func (id *ID) UnmarshalText(data []byte) error {
pid, err := Decode(string(data))
if err != nil {
return err
}
*id = pid
return nil
}

View File

@ -1,83 +0,0 @@
package peer_test
import (
"testing"
"github.com/libp2p/go-libp2p-core/peer"
. "github.com/libp2p/go-libp2p-core/test"
)
func TestPeerSerdePB(t *testing.T) {
id, err := RandPeerID()
if err != nil {
t.Fatal(err)
}
b, err := id.Marshal()
if err != nil {
t.Fatal(err)
}
var id2 peer.ID
if err = id2.Unmarshal(b); err != nil {
t.Fatal(err)
}
if id != id2 {
t.Error("expected equal ids in circular serde test")
}
}
func TestPeerSerdeJSON(t *testing.T) {
id, err := RandPeerID()
if err != nil {
t.Fatal(err)
}
b, err := id.MarshalJSON()
if err != nil {
t.Fatal(err)
}
var id2 peer.ID
if err = id2.UnmarshalJSON(b); err != nil {
t.Fatal(err)
}
if id != id2 {
t.Error("expected equal ids in circular serde test")
}
}
func TestBinaryMarshaler(t *testing.T) {
id, err := RandPeerID()
if err != nil {
t.Fatal(err)
}
b, err := id.MarshalBinary()
if err != nil {
t.Fatal(err)
}
var id2 peer.ID
if err = id2.UnmarshalBinary(b); err != nil {
t.Fatal(err)
}
if id != id2 {
t.Error("expected equal ids in circular serde test")
}
}
func TestTextMarshaler(t *testing.T) {
id, err := RandPeerID()
if err != nil {
t.Fatal(err)
}
b, err := id.MarshalText()
if err != nil {
t.Fatal(err)
}
var id2 peer.ID
if err = id2.UnmarshalText(b); err != nil {
t.Fatal(err)
}
if id != id2 {
t.Error("expected equal ids in circular serde test")
}
}

View File

@ -1,300 +0,0 @@
package peer_test
import (
"crypto/rand"
"encoding/base64"
"fmt"
"strings"
"testing"
ic "github.com/libp2p/go-libp2p-core/crypto"
. "github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/test"
b58 "github.com/mr-tron/base58/base58"
mh "github.com/multiformats/go-multihash"
)
var gen1 keyset // generated
var gen2 keyset // generated
var man keyset // manual
func hash(b []byte) []byte {
h, _ := mh.Sum(b, mh.SHA2_256, -1)
return []byte(h)
}
func init() {
if err := gen1.generate(); err != nil {
panic(err)
}
if err := gen2.generate(); err != nil {
panic(err)
}
skManBytes = strings.Replace(skManBytes, "\n", "", -1)
if err := man.load(hpkpMan, skManBytes); err != nil {
panic(err)
}
}
type keyset struct {
sk ic.PrivKey
pk ic.PubKey
hpk string
hpkp string
}
func (ks *keyset) generate() error {
var err error
ks.sk, ks.pk, err = test.RandTestKeyPair(ic.RSA, 2048)
if err != nil {
return err
}
bpk, err := ic.MarshalPublicKey(ks.pk)
if err != nil {
return err
}
ks.hpk = string(hash(bpk))
ks.hpkp = b58.Encode([]byte(ks.hpk))
return nil
}
func (ks *keyset) load(hpkp, skBytesStr string) error {
skBytes, err := base64.StdEncoding.DecodeString(skBytesStr)
if err != nil {
return err
}
ks.sk, err = ic.UnmarshalPrivateKey(skBytes)
if err != nil {
return err
}
ks.pk = ks.sk.GetPublic()
bpk, err := ic.MarshalPublicKey(ks.pk)
if err != nil {
return err
}
ks.hpk = string(hash(bpk))
ks.hpkp = b58.Encode([]byte(ks.hpk))
if ks.hpkp != hpkp {
return fmt.Errorf("hpkp doesn't match key. %s", hpkp)
}
return nil
}
func TestIDMatchesPublicKey(t *testing.T) {
test := func(ks keyset) {
p1, err := Decode(ks.hpkp)
if err != nil {
t.Fatal(err)
}
if ks.hpk != string(p1) {
t.Error("p1 and hpk differ")
}
if !p1.MatchesPublicKey(ks.pk) {
t.Fatal("p1 does not match pk")
}
p2, err := IDFromPublicKey(ks.pk)
if err != nil {
t.Fatal(err)
}
if p1 != p2 {
t.Error("p1 and p2 differ", p1.String(), p2.String())
}
if p2.String() != ks.hpkp {
t.Error("hpkp and p2.String differ", ks.hpkp, p2.String())
}
}
test(gen1)
test(gen2)
test(man)
}
func TestIDMatchesPrivateKey(t *testing.T) {
test := func(ks keyset) {
p1, err := Decode(ks.hpkp)
if err != nil {
t.Fatal(err)
}
if ks.hpk != string(p1) {
t.Error("p1 and hpk differ")
}
if !p1.MatchesPrivateKey(ks.sk) {
t.Fatal("p1 does not match sk")
}
p2, err := IDFromPrivateKey(ks.sk)
if err != nil {
t.Fatal(err)
}
if p1 != p2 {
t.Error("p1 and p2 differ", p1.String(), p2.String())
}
}
test(gen1)
test(gen2)
test(man)
}
func TestIDEncoding(t *testing.T) {
test := func(ks keyset) {
p1, err := Decode(ks.hpkp)
if err != nil {
t.Fatal(err)
}
if ks.hpk != string(p1) {
t.Error("p1 and hpk differ")
}
c := ToCid(p1)
p2, err := FromCid(c)
if err != nil || p1 != p2 {
t.Fatal("failed to round-trip through CID:", err)
}
p3, err := Decode(c.String())
if err != nil {
t.Fatal(err)
}
if p3 != p1 {
t.Fatal("failed to round trip through CID string")
}
if ks.hpkp != p1.String() {
t.Fatal("should always encode peer IDs as base58 by default")
}
}
test(gen1)
test(gen2)
test(man)
exampleCid := "bafkreifoybygix7fh3r3g5rqle3wcnhqldgdg4shzf4k3ulyw3gn7mabt4"
_, err := Decode(exampleCid)
if err == nil {
t.Fatal("should refuse to decode a non-peer ID CID")
}
c := ToCid("")
if c.Defined() {
t.Fatal("cid of empty peer ID should have been undefined")
}
}
func TestPublicKeyExtraction(t *testing.T) {
t.Skip("disabled until libp2p/go-libp2p-crypto#51 is fixed")
// Happy path
_, originalPub, err := ic.GenerateEd25519Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
id, err := IDFromPublicKey(originalPub)
if err != nil {
t.Fatal(err)
}
extractedPub, err := id.ExtractPublicKey()
if err != nil {
t.Fatal(err)
}
if extractedPub == nil {
t.Fatal("failed to extract public key")
}
if !originalPub.Equals(extractedPub) {
t.Fatal("extracted public key doesn't match")
}
// Test invalid multihash (invariant of the type of public key)
pk, err := ID("").ExtractPublicKey()
if err == nil {
t.Fatal("expected an error")
}
if pk != nil {
t.Fatal("expected a nil public key")
}
// Shouldn't work for, e.g. RSA keys (too large)
_, rsaPub, err := ic.GenerateKeyPair(ic.RSA, 2048)
if err != nil {
t.Fatal(err)
}
rsaId, err := IDFromPublicKey(rsaPub)
if err != nil {
t.Fatal(err)
}
extractedRsaPub, err := rsaId.ExtractPublicKey()
if err != ErrNoPublicKey {
t.Fatal(err)
}
if extractedRsaPub != nil {
t.Fatal("expected to fail to extract public key from rsa ID")
}
}
func TestValidate(t *testing.T) {
// Empty peer ID invalidates
err := ID("").Validate()
if err == nil {
t.Error("expected error")
} else if err != ErrEmptyPeerID {
t.Error("expected error message: " + ErrEmptyPeerID.Error())
}
// Non-empty peer ID validates
p, err := test.RandPeerID()
if err != nil {
t.Fatal(err)
}
err = p.Validate()
if err != nil {
t.Error("expected nil, but found " + err.Error())
}
}
var hpkpMan = `QmcJeseojbPW9hSejUM1sQ1a2QmbrryPK4Z8pWbRUPaYEn`
var skManBytes = `
CAASqAkwggSkAgEAAoIBAQC3hjPtPli71gFNzGJ6rUhYdb65BDwW7IrniEaZKi6z
tW4Iz0MouEJY8GPG1iQfqZKp5w9H2ENh4I1bk2dsezrJ7Nneg4Eqd78CmeHTAgaP
3PKsxohdMo/TOFNxwl8SkEF8FyVbio2TCoijYNHUuprZuq7MPEAJYr3Z1eEkM/xR
pMp3YI9S2SYsZQxbmmQ0/GfHOEvYajdow1qttreVTQkvmCppKtNLEU5InpX/W5fe
aQCj0pd7l74daZgM2WWz3juEUCVG7tdRUPg7ix1TYosbN96CKC3q2MJxe/wJ9gR5
Jvjnaaaoon+mci5vrKzxdKBDmZ/ZbLiHDfVljMkbdOQLAgMBAAECggEAEULaF3JJ
vkD+lmamzIsHxuosKhKv5CgTWHuEyFsjUVu7IbD8zBOoidzyRX1WoHO+i6Rj14oL
rGUGZpqSm61rdhqE01zjBS+GE6SNjN8f5uANIxr5MGrVBDTEBGsXrhNLVXSH2vhJ
II9ZEqTEl5GFhvz7+9Ge5EMZQCfRqSoKjVMdrs+Rueuusr9p0wNg9PH1myA+cXGt
iNZA17Rj2IiWVZLDgYNo4DVQUt4mFb+wTJW4NSspGKaFebpn0hf4z21laoGoJqTC
cNETJw+QwQ0uDaRoYotTLT2/55e8XBFTdcTg5cmbZoKgMyGqZEHfRyD9reVDAZlM
EZwKtrm41kz94QKBgQDmPp5zVtFXQNONmje1NE0IjCaUKcqURXk4ZiILztfT9XLC
OXAUCs3TCq21jirCkZZ6gLfo12Wx0xJYmsKlaUOGNTa8FI5Xa7OyheYKixUvV6FW
J95P/sNuWscTjh7oZHgZk/L3yKrNzNBz7awComwV6qciXW7EP1uACHf5fS/RdQKB
gQDMDa38W9OeegRDrhCeYGsniJK7btOCzhNooruQKPPXxk+O4dyJm7VBbC/3Ch55
a83W66T4k0Q7ysLVRT5Vqd5z3AM0sEM3ZoxUKCinG3NwPxVeXcoLasyEiq1vOFK6
GqZKCMThCj7ZpbkWy0DPJagnYfZGC62lammuj+XQx7mvfwKBgQCTKhka/bXmgD/3
9UeAIcLPIM2TzDZ4mQNHIjjGtVnMV8kXDaFung06xEuNjSYVoPq+qEFkqTCN/axv
R9P76BFJ2f93LehhRizggacsvAM5dFhh+i+lj+AYTBuMiz2EKpt9NcyJxhAuZKgk
QRi9wlU1mPtlArVG6HwylLcil3qV9QKBgQDJHtaU/KEY+2TGnIMuxxP2lEsjyLla
nOlOYc8C6Qpma8UwrHelfj5p7Eteb6/Xt6Tbp8kjZGuFj3T3plcpMdPbWEgkn3Kw
4TeBH0/qXUkrolHagBDLrglEvjbxf48ydV/fasM6l9GYzhofWFhZk+EoaArHwWz2
tGrTrmsynBjt2wKBgErdYe+zZ2Wo+wXQGAoZi4pfcwiw4a97Kdh0dx+WZz7acHms
h+V20VRmEHm5h8WnJ/Wv5uK94t6NY17wzjQ7y2BN5mY5cA2cZAcpeqtv/N06tH4S
cn1UEuRB8VpwkjaPUNZhqtYK40qff2OTdJy8taFtQiN7fz9euWTC78zjph2s
`

View File

@ -1,32 +1,20 @@
package peer
import (
"fmt"
"sync"
"time"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p-core/internal/catch"
pb "github.com/libp2p/go-libp2p-core/peer/pb"
"github.com/libp2p/go-libp2p-core/record"
ma "github.com/multiformats/go-multiaddr"
"github.com/gogo/protobuf/proto"
pb "github.com/libp2p/go-libp2p/core/peer/pb"
)
var _ record.Record = (*PeerRecord)(nil)
func init() {
record.RegisterType(&PeerRecord{})
}
// PeerRecordEnvelopeDomain is the domain string used for peer records contained in a Envelope.
const PeerRecordEnvelopeDomain = "libp2p-peer-record"
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.PeerRecordEnvelopeDomain instead
const PeerRecordEnvelopeDomain = peer.PeerRecordEnvelopeDomain
// PeerRecordEnvelopePayloadType is the type hint used to identify peer records in a Envelope.
// Defined in https://github.com/multiformats/multicodec/blob/master/table.csv
// with name "libp2p-peer-record".
var PeerRecordEnvelopePayloadType = []byte{0x03, 0x01}
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.PeerRecordEnvelopePayloadType instead
var PeerRecordEnvelopePayloadType = peer.PeerRecordEnvelopePayloadType
// PeerRecord contains information that is broadly useful to share with other peers,
// either through a direct exchange (as in the libp2p identify protocol), or through
@ -40,14 +28,14 @@ var PeerRecordEnvelopePayloadType = []byte{0x03, 0x01}
// a PeerRecord with a timestamp-based Seq value. The other PeerRecord fields should
// be set by the caller:
//
// rec := peer.NewPeerRecord()
// rec.PeerID = aPeerID
// rec.Addrs = someAddrs
// rec := peer.NewPeerRecord()
// rec.PeerID = aPeerID
// rec.Addrs = someAddrs
//
// Alternatively, you can construct a PeerRecord struct directly and use the TimestampSeq
// helper to set the Seq field:
//
// rec := peer.PeerRecord{PeerID: aPeerID, Addrs: someAddrs, Seq: peer.TimestampSeq()}
// rec := peer.PeerRecord{PeerID: aPeerID, Addrs: someAddrs, Seq: peer.TimestampSeq()}
//
// Failing to set the Seq field will not result in an error, however, a PeerRecord with a
// Seq value of zero may be ignored or rejected by other peers.
@ -59,194 +47,54 @@ var PeerRecordEnvelopePayloadType = []byte{0x03, 0x01}
// To share a PeerRecord, first call Sign to wrap the record in a Envelope
// and sign it with the local peer's private key:
//
// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs}
// envelope, err := rec.Sign(myPrivateKey)
// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs}
// envelope, err := rec.Sign(myPrivateKey)
//
// The resulting record.Envelope can be marshalled to a []byte and shared
// publicly. As a convenience, the MarshalSigned method will produce the
// Envelope and marshal it to a []byte in one go:
//
// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs}
// recordBytes, err := rec.MarshalSigned(myPrivateKey)
// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs}
// recordBytes, err := rec.MarshalSigned(myPrivateKey)
//
// To validate and unmarshal a signed PeerRecord from a remote peer,
// "consume" the containing envelope, which will return both the
// routing.Envelope and the inner Record. The Record must be cast to
// a PeerRecord pointer before use:
//
// envelope, untypedRecord, err := ConsumeEnvelope(envelopeBytes, PeerRecordEnvelopeDomain)
// if err != nil {
// handleError(err)
// return
// }
// peerRec := untypedRecord.(*PeerRecord)
// envelope, untypedRecord, err := ConsumeEnvelope(envelopeBytes, PeerRecordEnvelopeDomain)
// if err != nil {
// handleError(err)
// return
// }
// peerRec := untypedRecord.(*PeerRecord)
//
type PeerRecord struct {
// PeerID is the ID of the peer this record pertains to.
PeerID ID
// Addrs contains the public addresses of the peer this record pertains to.
Addrs []ma.Multiaddr
// Seq is a monotonically-increasing sequence counter that's used to order
// PeerRecords in time. The interval between Seq values is unspecified,
// but newer PeerRecords MUST have a greater Seq value than older records
// for the same peer.
Seq uint64
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.PeerRecord instead
type PeerRecord = peer.PeerRecord
// NewPeerRecord returns a PeerRecord with a timestamp-based sequence number.
// The returned record is otherwise empty and should be populated by the caller.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.NewPeerRecord instead
func NewPeerRecord() *PeerRecord {
return &PeerRecord{Seq: TimestampSeq()}
return peer.NewPeerRecord()
}
// PeerRecordFromAddrInfo creates a PeerRecord from an AddrInfo struct.
// The returned record will have a timestamp-based sequence number.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.PeerRecordFromAddrInfo instead
func PeerRecordFromAddrInfo(info AddrInfo) *PeerRecord {
rec := NewPeerRecord()
rec.PeerID = info.ID
rec.Addrs = info.Addrs
return rec
return peer.PeerRecordFromAddrInfo(info)
}
// PeerRecordFromProtobuf creates a PeerRecord from a protobuf PeerRecord
// struct.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.PeerRecordFromProtobuf instead
func PeerRecordFromProtobuf(msg *pb.PeerRecord) (*PeerRecord, error) {
record := &PeerRecord{}
var id ID
if err := id.UnmarshalBinary(msg.PeerId); err != nil {
return nil, err
}
record.PeerID = id
record.Addrs = addrsFromProtobuf(msg.Addresses)
record.Seq = msg.Seq
return record, nil
return peer.PeerRecordFromProtobuf(msg)
}
var (
lastTimestampMu sync.Mutex
lastTimestamp uint64
)
// TimestampSeq is a helper to generate a timestamp-based sequence number for a PeerRecord.
// Deprecated: use github.com/libp2p/go-libp2p/core/peer.TimestampSeq instead
func TimestampSeq() uint64 {
now := uint64(time.Now().UnixNano())
lastTimestampMu.Lock()
defer lastTimestampMu.Unlock()
// Not all clocks are strictly increasing, but we need these sequence numbers to be strictly
// increasing.
if now <= lastTimestamp {
now = lastTimestamp + 1
}
lastTimestamp = now
return now
}
// Domain is used when signing and validating PeerRecords contained in Envelopes.
// It is constant for all PeerRecord instances.
func (r *PeerRecord) Domain() string {
return PeerRecordEnvelopeDomain
}
// Codec is a binary identifier for the PeerRecord type. It is constant for all PeerRecord instances.
func (r *PeerRecord) Codec() []byte {
return PeerRecordEnvelopePayloadType
}
// UnmarshalRecord parses a PeerRecord from a byte slice.
// This method is called automatically when consuming a record.Envelope
// whose PayloadType indicates that it contains a PeerRecord.
// It is generally not necessary or recommended to call this method directly.
func (r *PeerRecord) UnmarshalRecord(bytes []byte) (err error) {
if r == nil {
return fmt.Errorf("cannot unmarshal PeerRecord to nil receiver")
}
defer func() { catch.HandlePanic(recover(), &err, "libp2p peer record unmarshal") }()
var msg pb.PeerRecord
err = proto.Unmarshal(bytes, &msg)
if err != nil {
return err
}
rPtr, err := PeerRecordFromProtobuf(&msg)
if err != nil {
return err
}
*r = *rPtr
return nil
}
// MarshalRecord serializes a PeerRecord to a byte slice.
// This method is called automatically when constructing a routing.Envelope
// using Seal or PeerRecord.Sign.
func (r *PeerRecord) MarshalRecord() (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "libp2p peer record marshal") }()
msg, err := r.ToProtobuf()
if err != nil {
return nil, err
}
return proto.Marshal(msg)
}
// Equal returns true if the other PeerRecord is identical to this one.
func (r *PeerRecord) Equal(other *PeerRecord) bool {
if other == nil {
return r == nil
}
if r.PeerID != other.PeerID {
return false
}
if r.Seq != other.Seq {
return false
}
if len(r.Addrs) != len(other.Addrs) {
return false
}
for i := range r.Addrs {
if !r.Addrs[i].Equal(other.Addrs[i]) {
return false
}
}
return true
}
// ToProtobuf returns the equivalent Protocol Buffer struct object of a PeerRecord.
func (r *PeerRecord) ToProtobuf() (*pb.PeerRecord, error) {
idBytes, err := r.PeerID.MarshalBinary()
if err != nil {
return nil, err
}
return &pb.PeerRecord{
PeerId: idBytes,
Addresses: addrsToProtobuf(r.Addrs),
Seq: r.Seq,
}, nil
}
func addrsFromProtobuf(addrs []*pb.PeerRecord_AddressInfo) []ma.Multiaddr {
var out []ma.Multiaddr
for _, addr := range addrs {
a, err := ma.NewMultiaddrBytes(addr.Multiaddr)
if err != nil {
continue
}
out = append(out, a)
}
return out
}
func addrsToProtobuf(addrs []ma.Multiaddr) []*pb.PeerRecord_AddressInfo {
var out []*pb.PeerRecord_AddressInfo
for _, addr := range addrs {
out = append(out, &pb.PeerRecord_AddressInfo{Multiaddr: addr.Bytes()})
}
return out
return peer.TimestampSeq()
}

View File

@ -1,67 +0,0 @@
package peer_test
import (
"bytes"
"testing"
"github.com/libp2p/go-libp2p-core/crypto"
. "github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/record"
"github.com/libp2p/go-libp2p-core/test"
)
func TestPeerRecordConstants(t *testing.T) {
msgf := "Changing the %s may cause peer records to be incompatible with older versions. " +
"If you've already thought that through, please update this test so that it passes with the new values."
rec := PeerRecord{}
if rec.Domain() != "libp2p-peer-record" {
t.Errorf(msgf, "signing domain")
}
if !bytes.Equal(rec.Codec(), []byte{0x03, 0x01}) {
t.Errorf(msgf, "codec value")
}
}
func TestSignedPeerRecordFromEnvelope(t *testing.T) {
priv, _, err := test.RandTestKeyPair(crypto.Ed25519, 256)
test.AssertNilError(t, err)
addrs := test.GenerateTestAddrs(10)
id, err := IDFromPrivateKey(priv)
test.AssertNilError(t, err)
rec := &PeerRecord{PeerID: id, Addrs: addrs, Seq: TimestampSeq()}
envelope, err := record.Seal(rec, priv)
test.AssertNilError(t, err)
t.Run("is unaltered after round-trip serde", func(t *testing.T) {
envBytes, err := envelope.Marshal()
test.AssertNilError(t, err)
env2, untypedRecord, err := record.ConsumeEnvelope(envBytes, PeerRecordEnvelopeDomain)
test.AssertNilError(t, err)
rec2, ok := untypedRecord.(*PeerRecord)
if !ok {
t.Error("unmarshaled record is not a *PeerRecord")
}
if !rec.Equal(rec2) {
t.Error("expected peer record to be unaltered after round-trip serde")
}
if !envelope.Equal(env2) {
t.Error("expected signed envelope to be unchanged after round-trip serde")
}
})
}
// This is pretty much guaranteed to pass on Linux no matter how we implement it, but Windows has
// low clock precision. This makes sure we never get a duplicate.
func TestTimestampSeq(t *testing.T) {
var last uint64
for i := 0; i < 1000; i++ {
next := TimestampSeq()
if next <= last {
t.Errorf("non-increasing timestamp found: %d <= %d", next, last)
}
last = next
}
}

View File

@ -1,14 +1,12 @@
package peerstore
import (
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/peerstore"
)
// AddrInfos returns an AddrInfo for each specified peer ID, in-order.
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.AddrInfos instead
func AddrInfos(ps Peerstore, peers []peer.ID) []peer.AddrInfo {
pi := make([]peer.AddrInfo, len(peers))
for i, p := range peers {
pi[i] = ps.PeerInfo(p)
}
return pi
return peerstore.AddrInfos(ps, peers)
}

View File

@ -1,74 +1,59 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/peerstore.
//
// Package peerstore provides types and interfaces for local storage of address information,
// metadata, and public key material about libp2p peers.
package peerstore
import (
"context"
"errors"
"io"
"math"
"time"
ic "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/record"
ma "github.com/multiformats/go-multiaddr"
"github.com/libp2p/go-libp2p/core/peerstore"
)
var ErrNotFound = errors.New("item not found")
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.ErrNotFound instead
var ErrNotFound = peerstore.ErrNotFound
var (
// AddressTTL is the expiration time of addresses.
AddressTTL = time.Hour
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.AddressTTL instead
AddressTTL = peerstore.AddressTTL
// TempAddrTTL is the ttl used for a short lived address.
TempAddrTTL = time.Minute * 2
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.TempAddrTTL instead
TempAddrTTL = peerstore.TempAddrTTL
// ProviderAddrTTL is the TTL of an address we've received from a provider.
// This is also a temporary address, but lasts longer. After this expires,
// the records we return will require an extra lookup.
ProviderAddrTTL = time.Minute * 30
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.ProviderAddrTTL instead
ProviderAddrTTL = peerstore.ProviderAddrTTL
// RecentlyConnectedAddrTTL is used when we recently connected to a peer.
// It means that we are reasonably certain of the peer's address.
RecentlyConnectedAddrTTL = time.Minute * 30
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.RecentlyConnectedAddrTTL instead
RecentlyConnectedAddrTTL = peerstore.RecentlyConnectedAddrTTL
// OwnObservedAddrTTL is used for our own external addresses observed by peers.
OwnObservedAddrTTL = time.Minute * 30
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.OwnObservedAddrTTL instead
OwnObservedAddrTTL = peerstore.OwnObservedAddrTTL
)
// Permanent TTLs (distinct so we can distinguish between them, constant as they
// are, in fact, permanent)
const (
// PermanentAddrTTL is the ttl for a "permanent address" (e.g. bootstrap nodes).
PermanentAddrTTL = math.MaxInt64 - iota
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.PermanentAddrTTL instead
PermanentAddrTTL = peerstore.PermanentAddrTTL
// ConnectedAddrTTL is the ttl used for the addresses of a peer to whom
// we're connected directly. This is basically permanent, as we will
// clear them + re-add under a TempAddrTTL after disconnecting.
ConnectedAddrTTL
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.ConnectedAddrTTL instead
ConnectedAddrTTL = peerstore.ConnectedAddrTTL
)
// Peerstore provides a threadsafe store of Peer related
// information.
type Peerstore interface {
io.Closer
AddrBook
KeyBook
PeerMetadata
Metrics
ProtoBook
// PeerInfo returns a peer.PeerInfo struct for given peer.ID.
// This is a small slice of the information Peerstore has on
// that peer, useful to other services.
PeerInfo(peer.ID) peer.AddrInfo
// Peers returns all of the peer IDs stored across all inner stores.
Peers() peer.IDSlice
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.Peerstore instead
type Peerstore = peerstore.Peerstore
// PeerMetadata can handle values of any type. Serializing values is
// up to the implementation. Dynamic type introspection may not be
@ -77,52 +62,12 @@ type Peerstore interface {
//
// Refer to the docs of the underlying implementation for more
// information.
type PeerMetadata interface {
// Get / Put is a simple registry for other peer-related key/value pairs.
// If we find something we use often, it should become its own set of
// methods. This is a last resort.
Get(p peer.ID, key string) (interface{}, error)
Put(p peer.ID, key string, val interface{}) error
// RemovePeer removes all values stored for a peer.
RemovePeer(peer.ID)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.PeerMetadata instead
type PeerMetadata = peerstore.PeerMetadata
// AddrBook holds the multiaddrs of peers.
type AddrBook interface {
// AddAddr calls AddAddrs(p, []ma.Multiaddr{addr}, ttl)
AddAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration)
// AddAddrs gives this AddrBook addresses to use, with a given ttl
// (time-to-live), after which the address is no longer valid.
// If the manager has a longer TTL, the operation is a no-op for that address
AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration)
// SetAddr calls mgr.SetAddrs(p, addr, ttl)
SetAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration)
// SetAddrs sets the ttl on addresses. This clears any TTL there previously.
// This is used when we receive the best estimate of the validity of an address.
SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration)
// UpdateAddrs updates the addresses associated with the given peer that have
// the given oldTTL to have the given newTTL.
UpdateAddrs(p peer.ID, oldTTL time.Duration, newTTL time.Duration)
// Addrs returns all known (and valid) addresses for a given peer.
Addrs(p peer.ID) []ma.Multiaddr
// AddrStream returns a channel that gets all addresses for a given
// peer sent on it. If new addresses are added after the call is made
// they will be sent along through the channel as well.
AddrStream(context.Context, peer.ID) <-chan ma.Multiaddr
// ClearAddresses removes all previously stored addresses.
ClearAddrs(p peer.ID)
// PeersWithAddrs returns all of the peer IDs stored in the AddrBook.
PeersWithAddrs() peer.IDSlice
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.AddrBook instead
type AddrBook = peerstore.AddrBook
// CertifiedAddrBook manages "self-certified" addresses for remote peers.
// Self-certified addresses are contained in peer.PeerRecords
@ -142,48 +87,12 @@ type AddrBook interface {
// certified addresses, callers should use the GetCertifiedAddrBook helper or
// type-assert on the CertifiedAddrBook interface:
//
// if cab, ok := aPeerstore.(CertifiedAddrBook); ok {
// cab.ConsumePeerRecord(signedPeerRecord, aTTL)
// }
// if cab, ok := aPeerstore.(CertifiedAddrBook); ok {
// cab.ConsumePeerRecord(signedPeerRecord, aTTL)
// }
//
type CertifiedAddrBook interface {
// ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in
// a record.Envelope), which will expire after the given TTL.
//
// The 'accepted' return value indicates that the record was successfully processed
// and integrated into the CertifiedAddrBook state. If 'accepted' is false but no
// error is returned, it means that the record was ignored, most likely because
// a newer record exists for the same peer.
//
// Signed records added via this method will be stored without
// alteration as long as the address TTLs remain valid. The Envelopes
// containing the PeerRecords can be retrieved by calling GetPeerRecord(peerID).
//
// If the signed PeerRecord belongs to a peer that already has certified
// addresses in the CertifiedAddrBook, the new addresses will replace the
// older ones, if the new record has a higher sequence number than the
// existing record. Attempting to add a peer record with a
// sequence number that's <= an existing record for the same peer will not
// result in an error, but the record will be ignored, and the 'accepted'
// bool return value will be false.
//
// If the CertifiedAddrBook is also an AddrBook (which is most likely the case),
// adding certified addresses for a peer will *replace* any
// existing non-certified addresses for that peer, and only the certified
// addresses will be returned from AddrBook.Addrs thereafter.
//
// Likewise, once certified addresses have been added for a given peer,
// any non-certified addresses added via AddrBook.AddAddrs or
// AddrBook.SetAddrs will be ignored. AddrBook.SetAddrs may still be used
// to update the TTL of certified addresses that have previously been
// added via ConsumePeerRecord.
ConsumePeerRecord(s *record.Envelope, ttl time.Duration) (accepted bool, err error)
// GetPeerRecord returns a Envelope containing a PeerRecord for the
// given peer id, if one exists.
// Returns nil if no signed PeerRecord exists for the peer.
GetPeerRecord(p peer.ID) *record.Envelope
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.CertifiedAddrBook instead
type CertifiedAddrBook = peerstore.CertifiedAddrBook
// GetCertifiedAddrBook is a helper to "upcast" an AddrBook to a
// CertifiedAddrBook by using type assertion. If the given AddrBook
@ -193,63 +102,19 @@ type CertifiedAddrBook interface {
//
// Note that since Peerstore embeds the AddrBook interface, you can also
// call GetCertifiedAddrBook(myPeerstore).
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.GetCertifiedAddrBook instead
func GetCertifiedAddrBook(ab AddrBook) (cab CertifiedAddrBook, ok bool) {
cab, ok = ab.(CertifiedAddrBook)
return cab, ok
return peerstore.GetCertifiedAddrBook(ab)
}
// KeyBook tracks the keys of Peers.
type KeyBook interface {
// PubKey stores the public key of a peer.
PubKey(peer.ID) ic.PubKey
// AddPubKey stores the public key of a peer.
AddPubKey(peer.ID, ic.PubKey) error
// PrivKey returns the private key of a peer, if known. Generally this might only be our own
// private key, see
// https://discuss.libp2p.io/t/what-is-the-purpose-of-having-map-peer-id-privatekey-in-peerstore/74.
PrivKey(peer.ID) ic.PrivKey
// AddPrivKey stores the private key of a peer.
AddPrivKey(peer.ID, ic.PrivKey) error
// PeersWithKeys returns all the peer IDs stored in the KeyBook.
PeersWithKeys() peer.IDSlice
// RemovePeer removes all keys associated with a peer.
RemovePeer(peer.ID)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.KeyBook instead
type KeyBook = peerstore.KeyBook
// Metrics tracks metrics across a set of peers.
type Metrics interface {
// RecordLatency records a new latency measurement
RecordLatency(peer.ID, time.Duration)
// LatencyEWMA returns an exponentially-weighted moving avg.
// of all measurements of a peer's latency.
LatencyEWMA(peer.ID) time.Duration
// RemovePeer removes all metrics stored for a peer.
RemovePeer(peer.ID)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.Metrics instead
type Metrics = peerstore.Metrics
// ProtoBook tracks the protocols supported by peers.
type ProtoBook interface {
GetProtocols(peer.ID) ([]string, error)
AddProtocols(peer.ID, ...string) error
SetProtocols(peer.ID, ...string) error
RemoveProtocols(peer.ID, ...string) error
// SupportsProtocols returns the set of protocols the peer supports from among the given protocols.
// If the returned error is not nil, the result is indeterminate.
SupportsProtocols(peer.ID, ...string) ([]string, error)
// FirstSupportedProtocol returns the first protocol that the peer supports among the given protocols.
// If the peer does not support any of the given protocols, this function will return an empty string and a nil error.
// If the returned error is not nil, the result is indeterminate.
FirstSupportedProtocol(peer.ID, ...string) (string, error)
// RemovePeer removes all protocols associated with a peer.
RemovePeer(peer.ID)
}
// Deprecated: use github.com/libp2p/go-libp2p/core/peerstore.ProtoBook instead
type ProtoBook = peerstore.ProtoBook

View File

@ -1,66 +1,13 @@
package pnet
import (
"bufio"
"bytes"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"github.com/libp2p/go-libp2p/core/pnet"
)
var (
pathPSKv1 = []byte("/key/swarm/psk/1.0.0/")
pathBin = "/bin/"
pathBase16 = "/base16/"
pathBase64 = "/base64/"
)
func readHeader(r *bufio.Reader) ([]byte, error) {
header, err := r.ReadBytes('\n')
if err != nil {
return nil, err
}
return bytes.TrimRight(header, "\r\n"), nil
}
func expectHeader(r *bufio.Reader, expected []byte) error {
header, err := readHeader(r)
if err != nil {
return err
}
if !bytes.Equal(header, expected) {
return fmt.Errorf("expected file header %s, got: %s", pathPSKv1, header)
}
return nil
}
// DecodeV1PSK reads a Multicodec encoded V1 PSK.
// Deprecated: use github.com/libp2p/go-libp2p/core/pnet.DecodeV1PSK instead
func DecodeV1PSK(in io.Reader) (PSK, error) {
reader := bufio.NewReader(in)
if err := expectHeader(reader, pathPSKv1); err != nil {
return nil, err
}
header, err := readHeader(reader)
if err != nil {
return nil, err
}
var decoder io.Reader
switch string(header) {
case pathBase16:
decoder = hex.NewDecoder(reader)
case pathBase64:
decoder = base64.NewDecoder(base64.StdEncoding, reader)
case pathBin:
decoder = reader
default:
return nil, fmt.Errorf("unknown encoding: %s", header)
}
out := make([]byte, 32)
if _, err = io.ReadFull(decoder, out[:]); err != nil {
return nil, err
}
return out, nil
return pnet.DecodeV1PSK(in)
}

View File

@ -1,122 +0,0 @@
package pnet
import (
"bytes"
"encoding/base64"
"testing"
)
func bufWithBase(base string, windows bool) *bytes.Buffer {
b := &bytes.Buffer{}
b.Write(pathPSKv1)
if windows {
b.WriteString("\r")
}
b.WriteString("\n")
b.WriteString(base)
if windows {
b.WriteString("\r")
}
b.WriteString("\n")
return b
}
func TestDecodeHex(t *testing.T) {
testDecodeHex(t, true)
testDecodeHex(t, false)
}
func TestDecodeBad(t *testing.T) {
testDecodeBad(t, true)
testDecodeBad(t, false)
}
func testDecodeBad(t *testing.T, windows bool) {
b := bufWithBase("/verybadbase/", windows)
b.WriteString("Have fun decoding that key")
_, err := DecodeV1PSK(b)
if err == nil {
t.Fatal("expected 'unknown encoding' got nil")
}
}
func testDecodeHex(t *testing.T, windows bool) {
b := bufWithBase("/base16/", windows)
for i := 0; i < 32; i++ {
b.WriteString("FF")
}
psk, err := DecodeV1PSK(b)
if err != nil {
t.Fatal(err)
}
for _, b := range psk {
if b != 255 {
t.Fatal("byte was wrong")
}
}
}
func TestDecodeB64(t *testing.T) {
testDecodeB64(t, true)
testDecodeB64(t, false)
}
func testDecodeB64(t *testing.T, windows bool) {
b := bufWithBase("/base64/", windows)
key := make([]byte, 32)
for i := 0; i < 32; i++ {
key[i] = byte(i)
}
e := base64.NewEncoder(base64.StdEncoding, b)
_, err := e.Write(key)
if err != nil {
t.Fatal(err)
}
err = e.Close()
if err != nil {
t.Fatal(err)
}
psk, err := DecodeV1PSK(b)
if err != nil {
t.Fatal(err)
}
for i, b := range psk {
if b != psk[i] {
t.Fatal("byte was wrong")
}
}
}
func TestDecodeBin(t *testing.T) {
testDecodeBin(t, true)
testDecodeBin(t, false)
}
func testDecodeBin(t *testing.T, windows bool) {
b := bufWithBase("/bin/", windows)
key := make([]byte, 32)
for i := 0; i < 32; i++ {
key[i] = byte(i)
}
b.Write(key)
psk, err := DecodeV1PSK(b)
if err != nil {
t.Fatal(err)
}
for i, b := range psk {
if b != psk[i] {
t.Fatal("byte was wrong")
}
}
}

View File

@ -1,19 +1,19 @@
package pnet
import "os"
import (
"github.com/libp2p/go-libp2p/core/pnet"
)
// EnvKey defines environment variable name for forcing usage of PNet in libp2p
// When environment variable of this name is set to "1" the ForcePrivateNetwork
// variable will be set to true.
const EnvKey = "LIBP2P_FORCE_PNET"
// Deprecated: use github.com/libp2p/go-libp2p/core/pnet.EnvKey instead
const EnvKey = pnet.EnvKey
// ForcePrivateNetwork is boolean variable that forces usage of PNet in libp2p
// Setting this variable to true or setting LIBP2P_FORCE_PNET environment variable
// to true will make libp2p to require private network protector.
// If no network protector is provided and this variable is set to true libp2p will
// refuse to connect.
var ForcePrivateNetwork = false
func init() {
ForcePrivateNetwork = os.Getenv(EnvKey) == "1"
}
// Deprecated: use github.com/libp2p/go-libp2p/core/pnet.ForcePrivateNetwork instead
var ForcePrivateNetwork = pnet.ForcePrivateNetwork

View File

@ -1,34 +1,24 @@
package pnet
import "github.com/libp2p/go-libp2p/core/pnet"
// ErrNotInPrivateNetwork is an error that should be returned by libp2p when it
// tries to dial with ForcePrivateNetwork set and no PNet Protector
var ErrNotInPrivateNetwork = NewError("private network was not configured but" +
" is enforced by the environment")
// Deprecated: use github.com/libp2p/go-libp2p/core/pnet.ErrNotInPrivateNetwork instead
var ErrNotInPrivateNetwork = pnet.ErrNotInPrivateNetwork
// Error is error type for ease of detecting PNet errors
type Error interface {
IsPNetError() bool
}
// Deprecated: use github.com/libp2p/go-libp2p/core/pnet.Error instead
type Error = pnet.Error
// NewError creates new Error
// Deprecated: use github.com/libp2p/go-libp2p/core/pnet.NewError instead
func NewError(err string) error {
return pnetErr("privnet: " + err)
return pnet.NewError(err)
}
// IsPNetError checks if given error is PNet Error
// Deprecated: use github.com/libp2p/go-libp2p/core/pnet.IsPNetError instead
func IsPNetError(err error) bool {
v, ok := err.(Error)
return ok && v.IsPNetError()
}
type pnetErr string
var _ Error = (*pnetErr)(nil)
func (p pnetErr) Error() string {
return string(p)
}
func (pnetErr) IsPNetError() bool {
return true
return pnet.IsPNetError(err)
}

View File

@ -1,20 +0,0 @@
package pnet
import (
"errors"
"testing"
)
func TestIsPnetErr(t *testing.T) {
err := NewError("test")
if err.Error() != "privnet: test" {
t.Fatalf("expected 'privnet: test' got '%s'", err.Error())
}
if !IsPNetError(err) {
t.Fatal("expected the pnetErr to be detected by IsPnetError")
}
if IsPNetError(errors.New("not pnet error")) {
t.Fatal("expected generic error not to be pnetError")
}
}

View File

@ -1,7 +1,12 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/pnet.
//
// Package pnet provides interfaces for private networking in libp2p.
package pnet
import "github.com/libp2p/go-libp2p/core/pnet"
// A PSK enables private network implementation to be transparent in libp2p.
// It is used to ensure that peers can only establish connections to other peers
// that are using the same PSK.
type PSK []byte
// Deprecated: use github.com/libp2p/go-libp2p/core/pnet.PSK instead
type PSK = pnet.PSK

View File

@ -1,29 +1,28 @@
// Deprecated: This package has moved into go-libp2p as a sub-package: github.com/libp2p/go-libp2p/core/protocol.
package protocol
import "github.com/libp2p/go-libp2p/core/protocol"
// ID is an identifier used to write protocol headers in streams.
type ID string
// Deprecated: use github.com/libp2p/go-libp2p/core/protocol.ID instead
type ID = protocol.ID
// These are reserved protocol.IDs.
const (
TestingID ID = "/p2p/_testing"
// Deprecated: use github.com/libp2p/go-libp2p/core/protocol.TestingID instead
TestingID ID = protocol.TestingID
)
// ConvertFromStrings is a convenience function that takes a slice of strings and
// converts it to a slice of protocol.ID.
// Deprecated: use github.com/libp2p/go-libp2p/core/protocol.ConvertFromStrings instead
func ConvertFromStrings(ids []string) (res []ID) {
res = make([]ID, 0, len(ids))
for _, id := range ids {
res = append(res, ID(id))
}
return res
return protocol.ConvertFromStrings(ids)
}
// ConvertToStrings is a convenience function that takes a slice of protocol.ID and
// converts it to a slice of strings.
// Deprecated: use github.com/libp2p/go-libp2p/core/protocol.ConvertToStrings instead
func ConvertToStrings(ids []ID) (res []string) {
res = make([]string, 0, len(ids))
for _, id := range ids {
res = append(res, string(id))
}
return res
return protocol.ConvertToStrings(ids)
}

View File

@ -2,7 +2,7 @@
package protocol
import (
"io"
"github.com/libp2p/go-libp2p/core/protocol"
)
// HandlerFunc is a user-provided function used by the Router to
@ -11,7 +11,8 @@ import (
// Will be invoked with the protocol ID string as the first argument,
// which may differ from the ID used for registration if the handler
// was registered using a match function.
type HandlerFunc = func(protocol string, rwc io.ReadWriteCloser) error
// Deprecated: use github.com/libp2p/go-libp2p/core/protocol.HandlerFunc instead
type HandlerFunc = protocol.HandlerFunc
// Router is an interface that allows users to add and remove protocol handlers,
// which will be invoked when incoming stream requests for registered protocols
@ -21,62 +22,15 @@ type HandlerFunc = func(protocol string, rwc io.ReadWriteCloser) error
// protocol handlers to determine which (if any) is capable of handling the stream.
// The handlers are checked in order of registration; if multiple handlers are
// eligible, only the first to be registered will be invoked.
type Router interface {
// AddHandler registers the given handler to be invoked for
// an exact literal match of the given protocol ID string.
AddHandler(protocol string, handler HandlerFunc)
// AddHandlerWithFunc registers the given handler to be invoked
// when the provided match function returns true.
//
// The match function will be invoked with an incoming protocol
// ID string, and should return true if the handler supports
// the protocol. Note that the protocol ID argument is not
// used for matching; if you want to match the protocol ID
// string exactly, you must check for it in your match function.
AddHandlerWithFunc(protocol string, match func(string) bool, handler HandlerFunc)
// RemoveHandler removes the registered handler (if any) for the
// given protocol ID string.
RemoveHandler(protocol string)
// Protocols returns a list of all registered protocol ID strings.
// Note that the Router may be able to handle protocol IDs not
// included in this list if handlers were added with match functions
// using AddHandlerWithFunc.
Protocols() []string
}
// Deprecated: use github.com/libp2p/go-libp2p/core/protocol.Router instead
type Router = protocol.Router
// Negotiator is a component capable of reaching agreement over what protocols
// to use for inbound streams of communication.
type Negotiator interface {
// NegotiateLazy will return the registered protocol handler to use
// for a given inbound stream, returning as soon as the protocol has been
// determined. Returns an error if negotiation fails.
//
// NegotiateLazy may return before all protocol negotiation responses have been
// written to the stream. This is in contrast to Negotiate, which will block until
// the Negotiator is finished with the stream.
//
// Deprecated: use Negotiate instead.
NegotiateLazy(rwc io.ReadWriteCloser) (io.ReadWriteCloser, string, HandlerFunc, error)
// Negotiate will return the registered protocol handler to use for a given
// inbound stream, returning after the protocol has been determined and the
// Negotiator has finished using the stream for negotiation. Returns an
// error if negotiation fails.
Negotiate(rwc io.ReadWriteCloser) (string, HandlerFunc, error)
// Handle calls Negotiate to determine which protocol handler to use for an
// inbound stream, then invokes the protocol handler function, passing it
// the protocol ID and the stream. Returns an error if negotiation fails.
Handle(rwc io.ReadWriteCloser) error
}
// Deprecated: use github.com/libp2p/go-libp2p/core/protocol.Negotiator instead
type Negotiator = protocol.Negotiator
// Switch is the component responsible for "dispatching" incoming stream requests to
// their corresponding stream handlers. It is both a Negotiator and a Router.
type Switch interface {
Router
Negotiator
}
// Deprecated: use github.com/libp2p/go-libp2p/core/protocol.Switch instead
type Switch = protocol.Switch

View File

@ -1,19 +1,8 @@
package record
import (
"bytes"
"errors"
"fmt"
"sync"
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/internal/catch"
pb "github.com/libp2p/go-libp2p-core/record/pb"
pool "github.com/libp2p/go-buffer-pool"
"github.com/gogo/protobuf/proto"
"github.com/multiformats/go-varint"
"github.com/libp2p/go-libp2p/core/record"
)
// Envelope contains an arbitrary []byte payload, signed by a libp2p peer.
@ -22,65 +11,23 @@ import (
// string specified when creating and verifying the envelope. You must know the
// domain string used to produce the envelope in order to verify the signature
// and access the payload.
type Envelope struct {
// The public key that can be used to verify the signature and derive the peer id of the signer.
PublicKey crypto.PubKey
// Deprecated: use github.com/libp2p/go-libp2p/core/record.Envelope instead
type Envelope = record.Envelope
// A binary identifier that indicates what kind of data is contained in the payload.
// TODO(yusef): enforce multicodec prefix
PayloadType []byte
// Deprecated: use github.com/libp2p/go-libp2p/core/record.ErrEmptyDomain instead
var ErrEmptyDomain = record.ErrEmptyDomain
// The envelope payload.
RawPayload []byte
// Deprecated: use github.com/libp2p/go-libp2p/core/record.ErrEmptyPayloadType instead
var ErrEmptyPayloadType = record.ErrEmptyPayloadType
// The signature of the domain string :: type hint :: payload.
signature []byte
// the unmarshalled payload as a Record, cached on first access via the Record accessor method
cached Record
unmarshalError error
unmarshalOnce sync.Once
}
var ErrEmptyDomain = errors.New("envelope domain must not be empty")
var ErrEmptyPayloadType = errors.New("payloadType must not be empty")
var ErrInvalidSignature = errors.New("invalid signature or incorrect domain")
// Deprecated: use github.com/libp2p/go-libp2p/core/record.ErrInvalidSignature instead
var ErrInvalidSignature = record.ErrInvalidSignature
// Seal marshals the given Record, places the marshaled bytes inside an Envelope,
// and signs with the given private key.
// Deprecated: use github.com/libp2p/go-libp2p/core/record.Seal instead
func Seal(rec Record, privateKey crypto.PrivKey) (*Envelope, error) {
payload, err := rec.MarshalRecord()
if err != nil {
return nil, fmt.Errorf("error marshaling record: %v", err)
}
domain := rec.Domain()
payloadType := rec.Codec()
if domain == "" {
return nil, ErrEmptyDomain
}
if len(payloadType) == 0 {
return nil, ErrEmptyPayloadType
}
unsigned, err := makeUnsigned(domain, payloadType, payload)
if err != nil {
return nil, err
}
defer pool.Put(unsigned)
sig, err := privateKey.Sign(unsigned)
if err != nil {
return nil, err
}
return &Envelope{
PublicKey: privateKey.GetPublic(),
PayloadType: payloadType,
RawPayload: payload,
signature: sig,
}, nil
return record.Seal(rec, privateKey)
}
// ConsumeEnvelope unmarshals a serialized Envelope and validates its
@ -94,15 +41,15 @@ func Seal(rec Record, privateKey crypto.PrivKey) (*Envelope, error) {
// You can type assert on the returned Record to convert it to an instance of the concrete
// Record type:
//
// envelope, rec, err := ConsumeEnvelope(envelopeBytes, peer.PeerRecordEnvelopeDomain)
// if err != nil {
// handleError(envelope, err) // envelope may be non-nil, even if errors occur!
// return
// }
// peerRec, ok := rec.(*peer.PeerRecord)
// if ok {
// doSomethingWithPeerRecord(peerRec)
// }
// envelope, rec, err := ConsumeEnvelope(envelopeBytes, peer.PeerRecordEnvelopeDomain)
// if err != nil {
// handleError(envelope, err) // envelope may be non-nil, even if errors occur!
// return
// }
// peerRec, ok := rec.(*peer.PeerRecord)
// if ok {
// doSomethingWithPeerRecord(peerRec)
// }
//
// Important: you MUST check the error value before using the returned Envelope. In some error
// cases, including when the envelope signature is invalid, both the Envelope and an error will
@ -112,22 +59,9 @@ func Seal(rec Record, privateKey crypto.PrivKey) (*Envelope, error) {
// If the Envelope signature is valid, but no Record type is registered for the Envelope's
// PayloadType, ErrPayloadTypeNotRegistered will be returned, along with the Envelope and
// a nil Record.
// Deprecated: use github.com/libp2p/go-libp2p/core/record.ConsumeEnvelope instead
func ConsumeEnvelope(data []byte, domain string) (envelope *Envelope, rec Record, err error) {
e, err := UnmarshalEnvelope(data)
if err != nil {
return nil, nil, fmt.Errorf("failed when unmarshalling the envelope: %w", err)
}
err = e.validate(domain)
if err != nil {
return e, nil, fmt.Errorf("failed to validate envelope: %w", err)
}
rec, err = e.Record()
if err != nil {
return e, nil, fmt.Errorf("failed to unmarshal envelope payload: %w", err)
}
return e, rec, nil
return record.ConsumeEnvelope(data, domain)
}
// ConsumeTypedEnvelope unmarshals a serialized Envelope and validates its
@ -140,160 +74,25 @@ func ConsumeEnvelope(data []byte, domain string) (envelope *Envelope, rec Record
// responsibility to determine whether the given Record type is able to unmarshal the payload
// correctly.
//
// rec := &MyRecordType{}
// envelope, err := ConsumeTypedEnvelope(envelopeBytes, rec)
// if err != nil {
// handleError(envelope, err)
// }
// doSomethingWithRecord(rec)
// rec := &MyRecordType{}
// envelope, err := ConsumeTypedEnvelope(envelopeBytes, rec)
// if err != nil {
// handleError(envelope, err)
// }
// doSomethingWithRecord(rec)
//
// Important: you MUST check the error value before using the returned Envelope. In some error
// cases, including when the envelope signature is invalid, both the Envelope and an error will
// be returned. This allows you to inspect the unmarshalled but invalid Envelope. As a result,
// you must not assume that any non-nil Envelope returned from this function is valid.
// Deprecated: use github.com/libp2p/go-libp2p/core/record.ConsumeTypedEnvelope instead
func ConsumeTypedEnvelope(data []byte, destRecord Record) (envelope *Envelope, err error) {
e, err := UnmarshalEnvelope(data)
if err != nil {
return nil, fmt.Errorf("failed when unmarshalling the envelope: %w", err)
}
err = e.validate(destRecord.Domain())
if err != nil {
return e, fmt.Errorf("failed to validate envelope: %w", err)
}
err = destRecord.UnmarshalRecord(e.RawPayload)
if err != nil {
return e, fmt.Errorf("failed to unmarshal envelope payload: %w", err)
}
e.cached = destRecord
return e, nil
return record.ConsumeTypedEnvelope(data, destRecord)
}
// UnmarshalEnvelope unmarshals a serialized Envelope protobuf message,
// without validating its contents. Most users should use ConsumeEnvelope.
// Deprecated: use github.com/libp2p/go-libp2p/core/record.UnmarshalEnvelope instead
func UnmarshalEnvelope(data []byte) (*Envelope, error) {
var e pb.Envelope
if err := proto.Unmarshal(data, &e); err != nil {
return nil, err
}
key, err := crypto.PublicKeyFromProto(e.PublicKey)
if err != nil {
return nil, err
}
return &Envelope{
PublicKey: key,
PayloadType: e.PayloadType,
RawPayload: e.Payload,
signature: e.Signature,
}, nil
}
// Marshal returns a byte slice containing a serialized protobuf representation
// of a Envelope.
func (e *Envelope) Marshal() (res []byte, err error) {
defer func() { catch.HandlePanic(recover(), &err, "libp2p envelope marshal") }()
key, err := crypto.PublicKeyToProto(e.PublicKey)
if err != nil {
return nil, err
}
msg := pb.Envelope{
PublicKey: key,
PayloadType: e.PayloadType,
Payload: e.RawPayload,
Signature: e.signature,
}
return proto.Marshal(&msg)
}
// Equal returns true if the other Envelope has the same public key,
// payload, payload type, and signature. This implies that they were also
// created with the same domain string.
func (e *Envelope) Equal(other *Envelope) bool {
if other == nil {
return e == nil
}
return e.PublicKey.Equals(other.PublicKey) &&
bytes.Equal(e.PayloadType, other.PayloadType) &&
bytes.Equal(e.signature, other.signature) &&
bytes.Equal(e.RawPayload, other.RawPayload)
}
// Record returns the Envelope's payload unmarshalled as a Record.
// The concrete type of the returned Record depends on which Record
// type was registered for the Envelope's PayloadType - see record.RegisterType.
//
// Once unmarshalled, the Record is cached for future access.
func (e *Envelope) Record() (Record, error) {
e.unmarshalOnce.Do(func() {
if e.cached != nil {
return
}
e.cached, e.unmarshalError = unmarshalRecordPayload(e.PayloadType, e.RawPayload)
})
return e.cached, e.unmarshalError
}
// TypedRecord unmarshals the Envelope's payload to the given Record instance.
// It is the caller's responsibility to ensure that the Record type is capable
// of unmarshalling the Envelope payload. Callers can inspect the Envelope's
// PayloadType field to determine the correct type of Record to use.
//
// This method will always unmarshal the Envelope payload even if a cached record
// exists.
func (e *Envelope) TypedRecord(dest Record) error {
return dest.UnmarshalRecord(e.RawPayload)
}
// validate returns nil if the envelope signature is valid for the given 'domain',
// or an error if signature validation fails.
func (e *Envelope) validate(domain string) error {
unsigned, err := makeUnsigned(domain, e.PayloadType, e.RawPayload)
if err != nil {
return err
}
defer pool.Put(unsigned)
valid, err := e.PublicKey.Verify(unsigned, e.signature)
if err != nil {
return fmt.Errorf("failed while verifying signature: %w", err)
}
if !valid {
return ErrInvalidSignature
}
return nil
}
// makeUnsigned is a helper function that prepares a buffer to sign or verify.
// It returns a byte slice from a pool. The caller MUST return this slice to the
// pool.
func makeUnsigned(domain string, payloadType []byte, payload []byte) ([]byte, error) {
var (
fields = [][]byte{[]byte(domain), payloadType, payload}
// fields are prefixed with their length as an unsigned varint. we
// compute the lengths before allocating the sig buffer so we know how
// much space to add for the lengths
flen = make([][]byte, len(fields))
size = 0
)
for i, f := range fields {
l := len(f)
flen[i] = varint.ToUvarint(uint64(l))
size += l + len(flen[i])
}
b := pool.Get(size)
var s int
for i, f := range fields {
s += copy(b[s:], flen[i])
s += copy(b[s:], f)
}
return b[:s], nil
return record.UnmarshalEnvelope(data)
}

Some files were not shown because too many files have changed in this diff Show More