mirror of
https://github.com/libp2p/go-libp2p-core.git
synced 2024-12-25 23:20:10 +08:00
deprecate this repo
This commit is contained in:
parent
1185a08119
commit
525c8942a9
@ -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)
|
||||
|
32
alias.go
32
alias.go
@ -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
|
||||
|
@ -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...)
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
164
crypto/ecdsa.go
164
crypto/ecdsa.go
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
229
crypto/key.go
229
crypto/key.go
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
@ -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")
|
||||
)
|
@ -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;
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
135
crypto/rsa_go.go
135
crypto/rsa_go.go
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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.
@ -1 +0,0 @@
|
||||
1A½`jPLDò4”ØóNò[¹µ-ªÐX¾ƒ¶àF±X
|
@ -1 +0,0 @@
|
||||
!5@„*ψ¤5Q©Mƒƒ¥U©’&Pk<50>ωS<CF89>磡³ΦΆ
|
@ -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.
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
93
event/bus.go
93
event/bus.go
@ -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
|
||||
|
14
event/dht.go
14
event/dht.go
@ -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
|
||||
|
14
event/doc.go
14
event/doc.go
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
57
go.mod
@ -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
839
go.sum
@ -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=
|
||||
|
@ -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)
|
||||
}
|
||||
|
80
host/host.go
80
host/host.go
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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")
|
||||
}
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
@ -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;
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
})
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
295
network/rcmgr.go
295
network/rcmgr.go
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
@ -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")
|
||||
)
|
@ -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;
|
||||
}
|
164
peer/peer.go
164
peer/peer.go
@ -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
|
||||
|
@ -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
|
||||
}
|
@ -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")
|
||||
}
|
||||
}
|
@ -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
|
||||
`
|
212
peer/record.go
212
peer/record.go
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
14
pnet/env.go
14
pnet/env.go
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user